diff options
Diffstat (limited to 'src/3rdparty/open62541/open62541.c')
-rw-r--r-- | src/3rdparty/open62541/open62541.c | 50830 |
1 files changed, 31008 insertions, 19822 deletions
diff --git a/src/3rdparty/open62541/open62541.c b/src/3rdparty/open62541/open62541.c index 411b267..f00780f 100644 --- a/src/3rdparty/open62541/open62541.c +++ b/src/3rdparty/open62541/open62541.c @@ -1,6 +1,6 @@ /* THIS IS A SINGLE-FILE DISTRIBUTION CONCATENATED FROM THE OPEN62541 SOURCES * visit http://open62541.org/ for information about this software - * Git-Revision: v0.3.0-1-g1bcad96 + * Git-Revision: v1.0-rc4 */ /* @@ -20,19 +20,6 @@ # define MDNSD_DYNAMIC_LINKING #endif -/* Enable POSIX features */ -#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL) -# define _XOPEN_SOURCE 600 -#endif -#ifndef _DEFAULT_SOURCE -# define _DEFAULT_SOURCE -#endif -/* On older systems we need to define _BSD_SOURCE. - * _DEFAULT_SOURCE is an alias for that. */ -#ifndef _BSD_SOURCE -# define _BSD_SOURCE -#endif - /* Disable security warnings for BSD sockets on MSVC */ #ifdef _MSC_VER # define _CRT_SECURE_NO_WARNINGS @@ -40,7 +27,7 @@ #include "open62541.h" -/*********************************** amalgamated original file "/home/jvoe/open62541/deps/queue.h" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/deps/open62541_queue.h" ***********************************/ /* $OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $ */ /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ @@ -141,11 +128,6 @@ struct name { \ #define SLIST_HEAD_INITIALIZER(head) \ { NULL } -/* Fix redefinition of SLIST_ENTRY on mingw winnt.h */ -# ifdef SLIST_ENTRY -# undef SLIST_ENTRY -# endif - #define SLIST_ENTRY(type) \ struct { \ struct type *sle_next; /* next element */ \ @@ -693,6 +675,245 @@ struct { \ } while (0) +/*********************************** amalgamated original file "/home/jvoe/open62541/deps/ziptree.h" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) Julius Pfrommer + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Reusable zip tree implementation. The style is inspired by the BSD + * sys/queue.h linked list definition. + * + * Zip trees were developed in: Tarjan, R. E., Levy, C. C., and Timmel, S. "Zip + * Trees." arXiv preprint arXiv:1806.06726 (2018). + * + * The ZIP_ENTRY definitions are to be contained in the tree entries themselves. + * Use ZIP_PROTTYPE to define the signature of the zip tree and ZIP_IMPL (in a + * .c compilation unit) for the method implementations. + * + * Zip trees are a probabilistic data structure. Entries are assigned a + * (nonzero) rank k with probability 1/2^{k+1}. This header file does not assume + * a specific random number generator. So the rank must be given when an entry + * is inserted. A fast way (with a single call to a pseudo random generator) to + * compute the rank is with ZIP_FFS32(random()). The ZIP_FFS32 returns the least + * significant nonzero bit of a 32bit number. */ + +#define ZIP_HEAD(name, type) \ +struct name { \ + struct type *zip_root; \ +} + +#define ZIP_INIT(head) do { (head)->zip_root = NULL; } while (0) +#define ZIP_ROOT(head) (head)->zip_root +#define ZIP_EMPTY(head) (ZIP_ROOT(head) == NULL) + +#define ZIP_ENTRY(type) \ +struct { \ + struct type *zip_left; \ + struct type *zip_right; \ + unsigned char rank; \ +} + +#define ZIP_LEFT(elm, field) (elm)->field.zip_left +#define ZIP_RIGHT(elm, field) (elm)->field.zip_right +#define ZIP_RANK(elm, field) (elm)->field.rank + +/* Shortcuts */ +#define ZIP_INSERT(name, head, elm, rank) name##_ZIP_INSERT(head, elm, rank) +#define ZIP_REMOVE(name, head, elm) name##_ZIP_REMOVE(head, elm) +#define ZIP_FIND(name, head, key) name##_ZIP_FIND(head, key) +#define ZIP_MIN(name, head) name##_ZIP_MIN(head) +#define ZIP_MAX(name, head) name##_ZIP_MAX(head) +#define ZIP_ITER(name, head, cb, d) name##_ZIP_ITER(head, cb, d) + +/* Zip tree method prototypes */ +#define ZIP_PROTTYPE(name, type, keytype) \ +void name##_ZIP_INSERT(struct name *head, struct type *elm, unsigned char rank); \ +void name##_ZIP_REMOVE(struct name *head, struct type *elm); \ +struct type *name##_ZIP_FIND(struct name *head, const keytype *key); \ +struct type *name##_ZIP_MIN(struct name *head); \ +struct type *name##_ZIP_MAX(struct name *head); \ +typedef void (*name##_cb)(struct type *elm, void *data); \ +void name##_ZIP_ITER(struct name *head, name##_cb cb, void *data); \ + +/* The comparison method "cmp" defined for every zip tree has the signature + * + * enum ZIP_CMP cmpDateTime(const keytype *a, const keytype *b); + * + * The entries need an absolute ordering. So ZIP_CMP_EQ must only be returned if + * a and b point to the same memory. (E.g. assured by unique identifiers.) */ +enum ZIP_CMP { + ZIP_CMP_LESS = -1, + ZIP_CMP_EQ = 0, + ZIP_CMP_MORE = 1 +}; + +/* Find the position of the first bit in an unsigned 32bit integer */ +#ifdef _MSC_VER +static __inline +#else +static inline +#endif +unsigned char +ZIP_FFS32(unsigned int v) { + unsigned int t = 1; + unsigned char r = 1; + if(v == 0) return 0; + while((v & t) == 0) { + t = t << 1; r++; + } + return r; +} + +/* Zip tree method implementations */ +#define ZIP_IMPL(name, type, field, keytype, keyfield, cmp) \ +static struct type * \ +__##name##_ZIP_INSERT(struct type *root, struct type *elm) { \ + if(!root) { \ + ZIP_LEFT(elm, field) = NULL; \ + ZIP_RIGHT(elm, field) = NULL; \ + return elm; \ + } \ + if((cmp)(&(elm)->keyfield, &(root)->keyfield) == ZIP_CMP_LESS) { \ + if(__##name##_ZIP_INSERT(ZIP_LEFT(root, field), elm) == elm) { \ + if(ZIP_RANK(elm, field) < ZIP_RANK(root, field)) { \ + ZIP_LEFT(root, field) = elm; \ + } else { \ + ZIP_LEFT(root, field) = ZIP_RIGHT(elm, field); \ + ZIP_RIGHT(elm, field) = root; \ + return elm; \ + } \ + } \ + } else { \ + if(__##name##_ZIP_INSERT(ZIP_RIGHT(root, field), elm) == elm) { \ + if(ZIP_RANK(elm, field) <= ZIP_RANK(root, field)) { \ + ZIP_RIGHT(root, field) = elm; \ + } else { \ + ZIP_RIGHT(root, field) = ZIP_LEFT(elm, field); \ + ZIP_LEFT(elm, field) = root; \ + return elm; \ + } \ + } \ + } \ + return root; \ +} \ + \ +void \ +name##_ZIP_INSERT(struct name *head, struct type *elm, \ + unsigned char rank) { \ + ZIP_RANK(elm, field) = rank; \ + ZIP_ROOT(head) = __##name##_ZIP_INSERT(ZIP_ROOT(head), elm); \ +} \ + \ +static struct type * \ +__##name##ZIP(struct type *x, struct type *y) { \ + if(!x) return y; \ + if(!y) return x; \ + if(ZIP_RANK(x, field) < ZIP_RANK(y, field)) { \ + ZIP_LEFT(y, field) = __##name##ZIP(x, ZIP_LEFT(y, field)); \ + return y; \ + } \ + ZIP_RIGHT(x, field) = __##name##ZIP(ZIP_RIGHT(x, field), y); \ + return x; \ +} \ + \ +static struct type * \ +__##name##_ZIP_REMOVE(struct type *root, struct type *elm) { \ + if(root == elm) \ + return __##name##ZIP(ZIP_LEFT(root, field), \ + ZIP_RIGHT(root, field)); \ + enum ZIP_CMP eq = (cmp)(&(elm)->keyfield, &(root)->keyfield); \ + if(eq == ZIP_CMP_LESS) { \ + struct type *left = ZIP_LEFT(root, field); \ + if(elm == left) \ + ZIP_LEFT(root, field) = \ + __##name##ZIP(ZIP_LEFT(left, field), \ + ZIP_RIGHT(left, field)); \ + else \ + __##name##_ZIP_REMOVE(left, elm); \ + } else { \ + struct type *right = ZIP_RIGHT(root, field); \ + if(elm == right) \ + ZIP_RIGHT(root, field) = \ + __##name##ZIP(ZIP_LEFT(right, field), \ + ZIP_RIGHT(right, field)); \ + else \ + __##name##_ZIP_REMOVE(right, elm); \ + } \ + return root; \ +} \ + \ +void \ +name##_ZIP_REMOVE(struct name *head, struct type *elm) { \ + ZIP_ROOT(head) = __##name##_ZIP_REMOVE(ZIP_ROOT(head), elm); \ +} \ + \ +static struct type * \ +__##name##_ZIP_FIND(struct type *root, const keytype *key) { \ + if(!root) \ + return NULL; \ + enum ZIP_CMP eq = (cmp)(key, &(root)->keyfield); \ + if(eq == ZIP_CMP_EQ) { \ + return root; \ + } \ + if(eq == ZIP_CMP_LESS) { \ + return __##name##_ZIP_FIND(ZIP_LEFT(root, field), key); \ + } \ + return __##name##_ZIP_FIND(ZIP_RIGHT(root, field), key); \ +} \ + \ +struct type * \ +name##_ZIP_FIND(struct name *head, const keytype *key) { \ + return __##name##_ZIP_FIND(ZIP_ROOT(head), key); \ +} \ + \ +struct type * \ +name##_ZIP_MIN(struct name *head) { \ + struct type *cur = ZIP_ROOT(head); \ + if(!cur) return NULL; \ + while(ZIP_LEFT(cur, field)) { \ + cur = ZIP_LEFT(cur, field); \ + } \ + return cur; \ +} \ + \ +struct type * \ +name##_ZIP_MAX(struct name *head) { \ + struct type *cur = ZIP_ROOT(head); \ + if(!cur) return NULL; \ + while(ZIP_RIGHT(cur, field)) { \ + cur = ZIP_RIGHT(cur, field); \ + } \ + return cur; \ +} \ + \ +static void \ +__##name##_ZIP_ITER(struct type *elm, name##_cb cb, void *data) { \ + if(!elm) \ + return; \ + __##name##_ZIP_ITER(ZIP_LEFT(elm, field), cb, data); \ + __##name##_ZIP_ITER(ZIP_RIGHT(elm, field), cb, data); \ + cb(elm, data); \ +} \ + \ +void \ +name##_ZIP_ITER(struct name *head, name##_cb cb, void *data) { \ + __##name##_ZIP_ITER(ZIP_ROOT(head), cb, data); \ +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + /*********************************** amalgamated original file "/home/jvoe/open62541/deps/pcg_basic.h" ***********************************/ /* @@ -719,11 +940,11 @@ struct { \ */ + #ifdef __cplusplus extern "C" { #endif - typedef struct pcg_state_setseq_64 { uint64_t state; /* RNG state. All values are possible. */ uint64_t inc; /* Controls which RNG sequence (stream) is selected. Must @@ -758,15 +979,67 @@ struct mytm { }; int __secs_to_tm(long long t, struct mytm *tm); +int __month_to_secs(int month, int is_leap); +long long __year_to_secs(long long year, int *is_leap); +long long __tm_to_secs(const struct mytm *tm); + + +/*********************************** amalgamated original file "/home/jvoe/open62541/deps/base64.h" ***********************************/ + +/* + + https://github.com/superwills/NibbleAndAHalf + base64.h -- Fast base64 encoding and decoding. + version 1.0.0, April 17, 2013 143a + + Copyright (C) 2013 William Sherif + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + William Sherif + will.sherif@gmail.com + + YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz +*/ +#ifndef UA_BASE64_H_ +#define UA_BASE64_H_ -/*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_util.h" ***********************************/ +#ifdef __cplusplus +extern "C" { +#endif + +char* UA_base64( const void* binaryData, int len, int *flen ); + +unsigned char* UA_unbase64( const char* ascii, int len, int *flen ); + +#ifdef __cplusplus +} +#endif + +#endif /* UA_BASE64_H_ */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_util_internal.h" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014, 2017 (c) Florian Palm * Copyright 2015 (c) LEvertz * Copyright 2015-2016 (c) Sten Grüner @@ -776,12 +1049,9 @@ int __secs_to_tm(long long t, struct mytm *tm); */ +#define UA_INTERNAL -#ifdef __cplusplus -extern "C" { -#endif - -/* BSD Queue Macros */ +_UA_BEGIN_DECLS /* Macro-Expand for MSVC workarounds */ #define UA_MACRO_EXPAND(x) x @@ -801,136 +1071,23 @@ typedef UA_UInt64 u64; typedef UA_Int64 i64; typedef UA_StatusCode status; -/* Atomic Operations - * ----------------- - * Atomic operations that synchronize across processor cores (for - * multithreading). Only the inline-functions defined next are used. Replace - * with architecture-specific operations if necessary. */ -#ifndef UA_ENABLE_MULTITHREADING -# define UA_atomic_sync() -#else -# ifdef _MSC_VER /* Visual Studio */ -# define UA_atomic_sync() _ReadWriteBarrier() -# else /* GCC/Clang */ -# define UA_atomic_sync() __sync_synchronize() -# endif -#endif - -static UA_INLINE void * -UA_atomic_xchg(void * volatile * addr, void *newptr) { -#ifndef UA_ENABLE_MULTITHREADING - void *old = *addr; - *addr = newptr; - return old; -#else -# ifdef _MSC_VER /* Visual Studio */ - return _InterlockedExchangePointer(addr, newptr); -# else /* GCC/Clang */ - return __sync_lock_test_and_set(addr, newptr); -# endif -#endif -} - -static UA_INLINE void * -UA_atomic_cmpxchg(void * volatile * addr, void *expected, void *newptr) { -#ifndef UA_ENABLE_MULTITHREADING - void *old = *addr; - if(old == expected) { - *addr = newptr; - } - return old; -#else -# ifdef _MSC_VER /* Visual Studio */ - return _InterlockedCompareExchangePointer(addr, expected, newptr); -# else /* GCC/Clang */ - return __sync_val_compare_and_swap(addr, expected, newptr); -# endif -#endif -} - -static UA_INLINE uint32_t -UA_atomic_addUInt32(volatile uint32_t *addr, uint32_t increase) { -#ifndef UA_ENABLE_MULTITHREADING - *addr += increase; - return *addr; -#else -# ifdef _MSC_VER /* Visual Studio */ - return _InterlockedExchangeAdd(addr, increase) + increase; -# else /* GCC/Clang */ - return __sync_add_and_fetch(addr, increase); -# endif -#endif -} - -static UA_INLINE size_t -UA_atomic_addSize(volatile size_t *addr, size_t increase) { -#ifndef UA_ENABLE_MULTITHREADING - *addr += increase; - return *addr; -#else -# ifdef _MSC_VER /* Visual Studio */ - return _InterlockedExchangeAdd(addr, increase) + increase; -# else /* GCC/Clang */ - return __sync_add_and_fetch(addr, increase); -# endif -#endif -} - -static UA_INLINE uint32_t -UA_atomic_subUInt32(volatile uint32_t *addr, uint32_t decrease) { -#ifndef UA_ENABLE_MULTITHREADING - *addr -= decrease; - return *addr; -#else -# ifdef _MSC_VER /* Visual Studio */ - return _InterlockedExchangeSub(addr, decrease) - decrease; -# else /* GCC/Clang */ - return __sync_sub_and_fetch(addr, decrease); -# endif -#endif -} - -static UA_INLINE size_t -UA_atomic_subSize(volatile size_t *addr, size_t decrease) { -#ifndef UA_ENABLE_MULTITHREADING - *addr -= decrease; - return *addr; -#else -# ifdef _MSC_VER /* Visual Studio */ - return _InterlockedExchangeSub(addr, decrease) - decrease; -# else /* GCC/Clang */ - return __sync_sub_and_fetch(addr, decrease); -# endif -#endif -} - /* Utility Functions * ----------------- */ -/* Convert given byte string to a positive number. Returns the number of valid - * digits. Stops if a non-digit char is found and returns the number of digits - * up to that point. */ -size_t UA_readNumber(u8 *buf, size_t buflen, u32 *number); - -#define UA_MIN(A,B) (A > B ? B : A) -#define UA_MAX(A,B) (A > B ? A : B) - #ifdef UA_DEBUG_DUMP_PKGS void UA_EXPORT UA_dump_hex_pkg(UA_Byte* buffer, size_t bufferLen); #endif -#ifdef __cplusplus -} // extern "C" -#endif +_UA_END_DECLS /*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_types_encoding_binary.h" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015 (c) Sten Grüner * Copyright 2014, 2017 (c) Florian Palm * Copyright 2017 (c) Stefan Profanter, fortiss GmbH @@ -938,10 +1095,8 @@ void UA_EXPORT UA_dump_hex_pkg(UA_Byte* buffer, size_t bufferLen); */ -#ifdef __cplusplus -extern "C" { -#endif +_UA_BEGIN_DECLS typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, const UA_Byte **bufEnd); @@ -964,7 +1119,7 @@ typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, Is ignored if NULL. * @param exchangeHandle Custom data passed into the exchangeCallback. * @return Returns a statuscode whether encoding succeeded. */ -UA_StatusCode +UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *type, UA_Byte **bufPos, const UA_Byte **bufEnd, UA_exchangeEncodeBuffer exchangeCallback, @@ -989,2034 +1144,2649 @@ UA_encodeBinary(const void *src, const UA_DataType *type, * @return Returns a statuscode whether decoding succeeded. */ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, - const UA_DataType *type, size_t customTypesSize, - const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + const UA_DataType *type, const UA_DataTypeArray *customTypes) + UA_FUNC_ATTR_WARN_UNUSED_RESULT; /* Returns the number of bytes the value p takes in binary encoding. Returns * zero if an error occurs. UA_calcSizeBinary is thread-safe and reentrant since * it does not access global (thread-local) variables. */ size_t -UA_calcSizeBinary(void *p, const UA_DataType *type); +UA_calcSizeBinary(const void *p, const UA_DataType *type); const UA_DataType * UA_findDataTypeByBinary(const UA_NodeId *typeId); -#ifdef __cplusplus -} -#endif +_UA_END_DECLS -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_types_generated_encoding_binary.h" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/types_generated_encoding_binary.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/jvoe/open62541/tools/generate_datatypes.py - * on host rigel by user jvoe at 2019-01-04 01:18:40 */ + * on host rigel by user jvoe at 2019-07-30 11:30:09 */ + +#ifdef UA_ENABLE_AMALGAMATION +#else +#endif + /* Boolean */ +static UA_INLINE size_t +UA_Boolean_calcSizeBinary(const UA_Boolean *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BOOLEAN]); +} static UA_INLINE UA_StatusCode -UA_Boolean_encodeBinary(const UA_Boolean *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BOOLEAN], bufPos, bufEnd, NULL, NULL); +UA_Boolean_encodeBinary(const UA_Boolean *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BOOLEAN], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Boolean_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Boolean *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BOOLEAN], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BOOLEAN], NULL); } /* SByte */ +static UA_INLINE size_t +UA_SByte_calcSizeBinary(const UA_SByte *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SBYTE]); +} static UA_INLINE UA_StatusCode -UA_SByte_encodeBinary(const UA_SByte *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SBYTE], bufPos, bufEnd, NULL, NULL); +UA_SByte_encodeBinary(const UA_SByte *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SBYTE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_SByte_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SByte *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SBYTE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SBYTE], NULL); } /* Byte */ +static UA_INLINE size_t +UA_Byte_calcSizeBinary(const UA_Byte *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BYTE]); +} static UA_INLINE UA_StatusCode -UA_Byte_encodeBinary(const UA_Byte *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BYTE], bufPos, bufEnd, NULL, NULL); +UA_Byte_encodeBinary(const UA_Byte *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BYTE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Byte_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Byte *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BYTE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BYTE], NULL); } /* Int16 */ +static UA_INLINE size_t +UA_Int16_calcSizeBinary(const UA_Int16 *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_INT16]); +} static UA_INLINE UA_StatusCode -UA_Int16_encodeBinary(const UA_Int16 *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_INT16], bufPos, bufEnd, NULL, NULL); +UA_Int16_encodeBinary(const UA_Int16 *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_INT16], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Int16_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Int16 *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_INT16], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_INT16], NULL); } /* UInt16 */ +static UA_INLINE size_t +UA_UInt16_calcSizeBinary(const UA_UInt16 *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_UINT16]); +} static UA_INLINE UA_StatusCode -UA_UInt16_encodeBinary(const UA_UInt16 *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UINT16], bufPos, bufEnd, NULL, NULL); +UA_UInt16_encodeBinary(const UA_UInt16 *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UINT16], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_UInt16_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UInt16 *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UINT16], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UINT16], NULL); } /* Int32 */ +static UA_INLINE size_t +UA_Int32_calcSizeBinary(const UA_Int32 *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_INT32]); +} static UA_INLINE UA_StatusCode -UA_Int32_encodeBinary(const UA_Int32 *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_INT32], bufPos, bufEnd, NULL, NULL); +UA_Int32_encodeBinary(const UA_Int32 *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_INT32], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Int32_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Int32 *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_INT32], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_INT32], NULL); } /* UInt32 */ +static UA_INLINE size_t +UA_UInt32_calcSizeBinary(const UA_UInt32 *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_UINT32]); +} static UA_INLINE UA_StatusCode -UA_UInt32_encodeBinary(const UA_UInt32 *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UINT32], bufPos, bufEnd, NULL, NULL); +UA_UInt32_encodeBinary(const UA_UInt32 *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UINT32], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_UInt32_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UInt32 *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UINT32], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UINT32], NULL); } /* Int64 */ +static UA_INLINE size_t +UA_Int64_calcSizeBinary(const UA_Int64 *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_INT64]); +} static UA_INLINE UA_StatusCode -UA_Int64_encodeBinary(const UA_Int64 *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_INT64], bufPos, bufEnd, NULL, NULL); +UA_Int64_encodeBinary(const UA_Int64 *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_INT64], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Int64_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Int64 *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_INT64], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_INT64], NULL); } /* UInt64 */ +static UA_INLINE size_t +UA_UInt64_calcSizeBinary(const UA_UInt64 *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_UINT64]); +} static UA_INLINE UA_StatusCode -UA_UInt64_encodeBinary(const UA_UInt64 *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UINT64], bufPos, bufEnd, NULL, NULL); +UA_UInt64_encodeBinary(const UA_UInt64 *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UINT64], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_UInt64_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UInt64 *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UINT64], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UINT64], NULL); } /* Float */ +static UA_INLINE size_t +UA_Float_calcSizeBinary(const UA_Float *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_FLOAT]); +} static UA_INLINE UA_StatusCode -UA_Float_encodeBinary(const UA_Float *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FLOAT], bufPos, bufEnd, NULL, NULL); +UA_Float_encodeBinary(const UA_Float *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FLOAT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Float_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Float *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FLOAT], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FLOAT], NULL); } /* Double */ +static UA_INLINE size_t +UA_Double_calcSizeBinary(const UA_Double *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DOUBLE]); +} static UA_INLINE UA_StatusCode -UA_Double_encodeBinary(const UA_Double *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DOUBLE], bufPos, bufEnd, NULL, NULL); +UA_Double_encodeBinary(const UA_Double *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DOUBLE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Double_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Double *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DOUBLE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DOUBLE], NULL); } /* String */ +static UA_INLINE size_t +UA_String_calcSizeBinary(const UA_String *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_STRING]); +} static UA_INLINE UA_StatusCode -UA_String_encodeBinary(const UA_String *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_STRING], bufPos, bufEnd, NULL, NULL); +UA_String_encodeBinary(const UA_String *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_STRING], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_String_decodeBinary(const UA_ByteString *src, size_t *offset, UA_String *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_STRING], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_STRING], NULL); } /* DateTime */ +static UA_INLINE size_t +UA_DateTime_calcSizeBinary(const UA_DateTime *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DATETIME]); +} static UA_INLINE UA_StatusCode -UA_DateTime_encodeBinary(const UA_DateTime *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATETIME], bufPos, bufEnd, NULL, NULL); +UA_DateTime_encodeBinary(const UA_DateTime *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATETIME], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_DateTime_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DateTime *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATETIME], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATETIME], NULL); } /* Guid */ +static UA_INLINE size_t +UA_Guid_calcSizeBinary(const UA_Guid *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_GUID]); +} static UA_INLINE UA_StatusCode -UA_Guid_encodeBinary(const UA_Guid *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_GUID], bufPos, bufEnd, NULL, NULL); +UA_Guid_encodeBinary(const UA_Guid *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_GUID], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Guid_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Guid *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_GUID], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_GUID], NULL); } /* ByteString */ +static UA_INLINE size_t +UA_ByteString_calcSizeBinary(const UA_ByteString *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BYTESTRING]); +} static UA_INLINE UA_StatusCode -UA_ByteString_encodeBinary(const UA_ByteString *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BYTESTRING], bufPos, bufEnd, NULL, NULL); +UA_ByteString_encodeBinary(const UA_ByteString *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BYTESTRING], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_ByteString_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ByteString *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BYTESTRING], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BYTESTRING], NULL); } /* XmlElement */ +static UA_INLINE size_t +UA_XmlElement_calcSizeBinary(const UA_XmlElement *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_XMLELEMENT]); +} static UA_INLINE UA_StatusCode -UA_XmlElement_encodeBinary(const UA_XmlElement *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_XMLELEMENT], bufPos, bufEnd, NULL, NULL); +UA_XmlElement_encodeBinary(const UA_XmlElement *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_XMLELEMENT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_XmlElement_decodeBinary(const UA_ByteString *src, size_t *offset, UA_XmlElement *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_XMLELEMENT], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_XMLELEMENT], NULL); } /* NodeId */ +static UA_INLINE size_t +UA_NodeId_calcSizeBinary(const UA_NodeId *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_NODEID]); +} static UA_INLINE UA_StatusCode -UA_NodeId_encodeBinary(const UA_NodeId *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODEID], bufPos, bufEnd, NULL, NULL); +UA_NodeId_encodeBinary(const UA_NodeId *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODEID], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_NodeId_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NodeId *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODEID], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODEID], NULL); } /* ExpandedNodeId */ +static UA_INLINE size_t +UA_ExpandedNodeId_calcSizeBinary(const UA_ExpandedNodeId *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); +} static UA_INLINE UA_StatusCode -UA_ExpandedNodeId_encodeBinary(const UA_ExpandedNodeId *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EXPANDEDNODEID], bufPos, bufEnd, NULL, NULL); +UA_ExpandedNodeId_encodeBinary(const UA_ExpandedNodeId *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EXPANDEDNODEID], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_ExpandedNodeId_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ExpandedNodeId *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EXPANDEDNODEID], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EXPANDEDNODEID], NULL); } /* StatusCode */ +static UA_INLINE size_t +UA_StatusCode_calcSizeBinary(const UA_StatusCode *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_STATUSCODE]); +} static UA_INLINE UA_StatusCode -UA_StatusCode_encodeBinary(const UA_StatusCode *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_STATUSCODE], bufPos, bufEnd, NULL, NULL); +UA_StatusCode_encodeBinary(const UA_StatusCode *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_STATUSCODE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_StatusCode_decodeBinary(const UA_ByteString *src, size_t *offset, UA_StatusCode *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_STATUSCODE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_STATUSCODE], NULL); } /* QualifiedName */ +static UA_INLINE size_t +UA_QualifiedName_calcSizeBinary(const UA_QualifiedName *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); +} static UA_INLINE UA_StatusCode -UA_QualifiedName_encodeBinary(const UA_QualifiedName *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_QUALIFIEDNAME], bufPos, bufEnd, NULL, NULL); +UA_QualifiedName_encodeBinary(const UA_QualifiedName *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_QUALIFIEDNAME], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_QualifiedName_decodeBinary(const UA_ByteString *src, size_t *offset, UA_QualifiedName *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_QUALIFIEDNAME], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_QUALIFIEDNAME], NULL); } /* LocalizedText */ +static UA_INLINE size_t +UA_LocalizedText_calcSizeBinary(const UA_LocalizedText *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +} static UA_INLINE UA_StatusCode -UA_LocalizedText_encodeBinary(const UA_LocalizedText *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], bufPos, bufEnd, NULL, NULL); +UA_LocalizedText_encodeBinary(const UA_LocalizedText *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_LocalizedText_decodeBinary(const UA_ByteString *src, size_t *offset, UA_LocalizedText *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], NULL); } /* ExtensionObject */ +static UA_INLINE size_t +UA_ExtensionObject_calcSizeBinary(const UA_ExtensionObject *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); +} static UA_INLINE UA_StatusCode -UA_ExtensionObject_encodeBinary(const UA_ExtensionObject *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], bufPos, bufEnd, NULL, NULL); +UA_ExtensionObject_encodeBinary(const UA_ExtensionObject *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_ExtensionObject_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ExtensionObject *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], NULL); } /* DataValue */ +static UA_INLINE size_t +UA_DataValue_calcSizeBinary(const UA_DataValue *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DATAVALUE]); +} static UA_INLINE UA_StatusCode -UA_DataValue_encodeBinary(const UA_DataValue *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATAVALUE], bufPos, bufEnd, NULL, NULL); +UA_DataValue_encodeBinary(const UA_DataValue *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATAVALUE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_DataValue_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataValue *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATAVALUE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATAVALUE], NULL); } /* Variant */ +static UA_INLINE size_t +UA_Variant_calcSizeBinary(const UA_Variant *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_VARIANT]); +} static UA_INLINE UA_StatusCode -UA_Variant_encodeBinary(const UA_Variant *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VARIANT], bufPos, bufEnd, NULL, NULL); +UA_Variant_encodeBinary(const UA_Variant *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VARIANT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_Variant_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Variant *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VARIANT], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VARIANT], NULL); } /* DiagnosticInfo */ +static UA_INLINE size_t +UA_DiagnosticInfo_calcSizeBinary(const UA_DiagnosticInfo *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO]); +} static UA_INLINE UA_StatusCode -UA_DiagnosticInfo_encodeBinary(const UA_DiagnosticInfo *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], bufPos, bufEnd, NULL, NULL); +UA_DiagnosticInfo_encodeBinary(const UA_DiagnosticInfo *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_DiagnosticInfo_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DiagnosticInfo *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], NULL); } -/* SignedSoftwareCertificate */ +/* ViewAttributes */ +static UA_INLINE size_t +UA_ViewAttributes_calcSizeBinary(const UA_ViewAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES]); +} static UA_INLINE UA_StatusCode -UA_SignedSoftwareCertificate_encodeBinary(const UA_SignedSoftwareCertificate *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE], bufPos, bufEnd, NULL, NULL); +UA_ViewAttributes_encodeBinary(const UA_ViewAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SignedSoftwareCertificate_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SignedSoftwareCertificate *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE], 0, NULL); +UA_ViewAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ViewAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES], NULL); } -/* SemanticChangeStructureDataType */ +/* ElementOperand */ +static UA_INLINE size_t +UA_ElementOperand_calcSizeBinary(const UA_ElementOperand *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ELEMENTOPERAND]); +} static UA_INLINE UA_StatusCode -UA_SemanticChangeStructureDataType_encodeBinary(const UA_SemanticChangeStructureDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_ElementOperand_encodeBinary(const UA_ElementOperand *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ELEMENTOPERAND], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SemanticChangeStructureDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SemanticChangeStructureDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE], 0, NULL); +UA_ElementOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ElementOperand *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ELEMENTOPERAND], NULL); } -/* StatusChangeNotification */ +/* VariableAttributes */ +static UA_INLINE size_t +UA_VariableAttributes_calcSizeBinary(const UA_VariableAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES]); +} static UA_INLINE UA_StatusCode -UA_StatusChangeNotification_encodeBinary(const UA_StatusChangeNotification *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION], bufPos, bufEnd, NULL, NULL); +UA_VariableAttributes_encodeBinary(const UA_VariableAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_StatusChangeNotification_decodeBinary(const UA_ByteString *src, size_t *offset, UA_StatusChangeNotification *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION], 0, NULL); +UA_VariableAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_VariableAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], NULL); } -/* BrowsePathTarget */ +/* EnumValueType */ +static UA_INLINE size_t +UA_EnumValueType_calcSizeBinary(const UA_EnumValueType *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +} static UA_INLINE UA_StatusCode -UA_BrowsePathTarget_encodeBinary(const UA_BrowsePathTarget *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET], bufPos, bufEnd, NULL, NULL); +UA_EnumValueType_encodeBinary(const UA_EnumValueType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ENUMVALUETYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowsePathTarget_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowsePathTarget *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET], 0, NULL); +UA_EnumValueType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EnumValueType *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ENUMVALUETYPE], NULL); } -/* ViewAttributes */ +/* EventFieldList */ +static UA_INLINE size_t +UA_EventFieldList_calcSizeBinary(const UA_EventFieldList *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_EVENTFIELDLIST]); +} static UA_INLINE UA_StatusCode -UA_ViewAttributes_encodeBinary(const UA_ViewAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_EventFieldList_encodeBinary(const UA_EventFieldList *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EVENTFIELDLIST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ViewAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ViewAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES], 0, NULL); +UA_EventFieldList_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EventFieldList *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EVENTFIELDLIST], NULL); } -/* RequestHeader */ +/* MonitoredItemCreateResult */ +static UA_INLINE size_t +UA_MonitoredItemCreateResult_calcSizeBinary(const UA_MonitoredItemCreateResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]); +} static UA_INLINE UA_StatusCode -UA_RequestHeader_encodeBinary(const UA_RequestHeader *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REQUESTHEADER], bufPos, bufEnd, NULL, NULL); +UA_MonitoredItemCreateResult_encodeBinary(const UA_MonitoredItemCreateResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RequestHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RequestHeader *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REQUESTHEADER], 0, NULL); +UA_MonitoredItemCreateResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemCreateResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT], NULL); } -/* MonitoredItemModifyResult */ +/* ServerDiagnosticsSummaryDataType */ +static UA_INLINE size_t +UA_ServerDiagnosticsSummaryDataType_calcSizeBinary(const UA_ServerDiagnosticsSummaryDataType *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); +} static UA_INLINE UA_StatusCode -UA_MonitoredItemModifyResult_encodeBinary(const UA_MonitoredItemModifyResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT], bufPos, bufEnd, NULL, NULL); +UA_ServerDiagnosticsSummaryDataType_encodeBinary(const UA_ServerDiagnosticsSummaryDataType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MonitoredItemModifyResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemModifyResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT], 0, NULL); +UA_ServerDiagnosticsSummaryDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServerDiagnosticsSummaryDataType *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE], NULL); } -/* ElementOperand */ +/* ContentFilterElementResult */ +static UA_INLINE size_t +UA_ContentFilterElementResult_calcSizeBinary(const UA_ContentFilterElementResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT]); +} static UA_INLINE UA_StatusCode -UA_ElementOperand_encodeBinary(const UA_ElementOperand *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ELEMENTOPERAND], bufPos, bufEnd, NULL, NULL); +UA_ContentFilterElementResult_encodeBinary(const UA_ContentFilterElementResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ElementOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ElementOperand *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ELEMENTOPERAND], 0, NULL); +UA_ContentFilterElementResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ContentFilterElementResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT], NULL); } -/* CloseSecureChannelRequest */ +/* LiteralOperand */ +static UA_INLINE size_t +UA_LiteralOperand_calcSizeBinary(const UA_LiteralOperand *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_LITERALOPERAND]); +} static UA_INLINE UA_StatusCode -UA_CloseSecureChannelRequest_encodeBinary(const UA_CloseSecureChannelRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST], bufPos, bufEnd, NULL, NULL); +UA_LiteralOperand_encodeBinary(const UA_LiteralOperand *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_LITERALOPERAND], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CloseSecureChannelRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CloseSecureChannelRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST], 0, NULL); +UA_LiteralOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_LiteralOperand *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_LITERALOPERAND], NULL); } -/* AddNodesResult */ +/* MessageSecurityMode */ +static UA_INLINE size_t +UA_MessageSecurityMode_calcSizeBinary(const UA_MessageSecurityMode *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE]); +} static UA_INLINE UA_StatusCode -UA_AddNodesResult_encodeBinary(const UA_AddNodesResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESRESULT], bufPos, bufEnd, NULL, NULL); +UA_MessageSecurityMode_encodeBinary(const UA_MessageSecurityMode *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AddNodesResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddNodesResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDNODESRESULT], 0, NULL); +UA_MessageSecurityMode_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MessageSecurityMode *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], NULL); } -/* VariableAttributes */ +/* UtcTime */ +static UA_INLINE size_t +UA_UtcTime_calcSizeBinary(const UA_UtcTime *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_UTCTIME]); +} static UA_INLINE UA_StatusCode -UA_VariableAttributes_encodeBinary(const UA_VariableAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_UtcTime_encodeBinary(const UA_UtcTime *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UTCTIME], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_VariableAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_VariableAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES], 0, NULL); +UA_UtcTime_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UtcTime *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UTCTIME], NULL); } -/* NotificationMessage */ +/* UserIdentityToken */ +static UA_INLINE size_t +UA_UserIdentityToken_calcSizeBinary(const UA_UserIdentityToken *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN]); +} static UA_INLINE UA_StatusCode -UA_NotificationMessage_encodeBinary(const UA_NotificationMessage *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE], bufPos, bufEnd, NULL, NULL); +UA_UserIdentityToken_encodeBinary(const UA_UserIdentityToken *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_NotificationMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NotificationMessage *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE], 0, NULL); +UA_UserIdentityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UserIdentityToken *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN], NULL); } -/* FindServersOnNetworkRequest */ +/* X509IdentityToken */ +static UA_INLINE size_t +UA_X509IdentityToken_calcSizeBinary(const UA_X509IdentityToken *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]); +} static UA_INLINE UA_StatusCode -UA_FindServersOnNetworkRequest_encodeBinary(const UA_FindServersOnNetworkRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST], bufPos, bufEnd, NULL, NULL); +UA_X509IdentityToken_encodeBinary(const UA_X509IdentityToken *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_FindServersOnNetworkRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FindServersOnNetworkRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST], 0, NULL); +UA_X509IdentityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_X509IdentityToken *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN], NULL); } -/* EventFieldList */ +/* MonitoredItemNotification */ +static UA_INLINE size_t +UA_MonitoredItemNotification_calcSizeBinary(const UA_MonitoredItemNotification *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]); +} static UA_INLINE UA_StatusCode -UA_EventFieldList_encodeBinary(const UA_EventFieldList *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EVENTFIELDLIST], bufPos, bufEnd, NULL, NULL); +UA_MonitoredItemNotification_encodeBinary(const UA_MonitoredItemNotification *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_EventFieldList_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EventFieldList *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EVENTFIELDLIST], 0, NULL); +UA_MonitoredItemNotification_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemNotification *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION], NULL); } -/* MonitoringMode */ +/* ResponseHeader */ +static UA_INLINE size_t +UA_ResponseHeader_calcSizeBinary(const UA_ResponseHeader *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_RESPONSEHEADER]); +} static UA_INLINE UA_StatusCode -UA_MonitoringMode_encodeBinary(const UA_MonitoringMode *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITORINGMODE], bufPos, bufEnd, NULL, NULL); +UA_ResponseHeader_encodeBinary(const UA_ResponseHeader *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_RESPONSEHEADER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MonitoringMode_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoringMode *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITORINGMODE], 0, NULL); +UA_ResponseHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ResponseHeader *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_RESPONSEHEADER], NULL); } -/* MdnsDiscoveryConfiguration */ +/* SignatureData */ +static UA_INLINE size_t +UA_SignatureData_calcSizeBinary(const UA_SignatureData *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SIGNATUREDATA]); +} static UA_INLINE UA_StatusCode -UA_MdnsDiscoveryConfiguration_encodeBinary(const UA_MdnsDiscoveryConfiguration *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION], bufPos, bufEnd, NULL, NULL); +UA_SignatureData_encodeBinary(const UA_SignatureData *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SIGNATUREDATA], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MdnsDiscoveryConfiguration_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MdnsDiscoveryConfiguration *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION], 0, NULL); +UA_SignatureData_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SignatureData *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SIGNATUREDATA], NULL); } -/* CallMethodResult */ +/* ModifySubscriptionResponse */ +static UA_INLINE size_t +UA_ModifySubscriptionResponse_calcSizeBinary(const UA_ModifySubscriptionResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_CallMethodResult_encodeBinary(const UA_CallMethodResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CALLMETHODRESULT], bufPos, bufEnd, NULL, NULL); +UA_ModifySubscriptionResponse_encodeBinary(const UA_ModifySubscriptionResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CallMethodResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CallMethodResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CALLMETHODRESULT], 0, NULL); +UA_ModifySubscriptionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModifySubscriptionResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE], NULL); } -/* ParsingResult */ +/* NodeAttributes */ +static UA_INLINE size_t +UA_NodeAttributes_calcSizeBinary(const UA_NodeAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_NODEATTRIBUTES]); +} static UA_INLINE UA_StatusCode -UA_ParsingResult_encodeBinary(const UA_ParsingResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_PARSINGRESULT], bufPos, bufEnd, NULL, NULL); +UA_NodeAttributes_encodeBinary(const UA_NodeAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODEATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ParsingResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ParsingResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_PARSINGRESULT], 0, NULL); +UA_NodeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NodeAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODEATTRIBUTES], NULL); } -/* RelativePathElement */ +/* ActivateSessionResponse */ +static UA_INLINE size_t +UA_ActivateSessionResponse_calcSizeBinary(const UA_ActivateSessionResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_RelativePathElement_encodeBinary(const UA_RelativePathElement *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT], bufPos, bufEnd, NULL, NULL); +UA_ActivateSessionResponse_encodeBinary(const UA_ActivateSessionResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RelativePathElement_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RelativePathElement *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT], 0, NULL); +UA_ActivateSessionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ActivateSessionResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE], NULL); } -/* BrowseDirection */ +/* VariableTypeAttributes */ +static UA_INLINE size_t +UA_VariableTypeAttributes_calcSizeBinary(const UA_VariableTypeAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]); +} static UA_INLINE UA_StatusCode -UA_BrowseDirection_encodeBinary(const UA_BrowseDirection *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEDIRECTION], bufPos, bufEnd, NULL, NULL); +UA_VariableTypeAttributes_encodeBinary(const UA_VariableTypeAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowseDirection_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseDirection *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEDIRECTION], 0, NULL); +UA_VariableTypeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_VariableTypeAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], NULL); } -/* CallMethodRequest */ +/* CallMethodResult */ +static UA_INLINE size_t +UA_CallMethodResult_calcSizeBinary(const UA_CallMethodResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CALLMETHODRESULT]); +} static UA_INLINE UA_StatusCode -UA_CallMethodRequest_encodeBinary(const UA_CallMethodRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST], bufPos, bufEnd, NULL, NULL); +UA_CallMethodResult_encodeBinary(const UA_CallMethodResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CALLMETHODRESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CallMethodRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CallMethodRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST], 0, NULL); +UA_CallMethodResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CallMethodResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CALLMETHODRESULT], NULL); } -/* RedundancySupport */ +/* MonitoringMode */ +static UA_INLINE size_t +UA_MonitoringMode_calcSizeBinary(const UA_MonitoringMode *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MONITORINGMODE]); +} static UA_INLINE UA_StatusCode -UA_RedundancySupport_encodeBinary(const UA_RedundancySupport *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT], bufPos, bufEnd, NULL, NULL); +UA_MonitoringMode_encodeBinary(const UA_MonitoringMode *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITORINGMODE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RedundancySupport_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RedundancySupport *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT], 0, NULL); +UA_MonitoringMode_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoringMode *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITORINGMODE], NULL); } -/* EventNotificationList */ +/* SetMonitoringModeResponse */ +static UA_INLINE size_t +UA_SetMonitoringModeResponse_calcSizeBinary(const UA_SetMonitoringModeResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]); +} static UA_INLINE UA_StatusCode -UA_EventNotificationList_encodeBinary(const UA_EventNotificationList *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST], bufPos, bufEnd, NULL, NULL); +UA_SetMonitoringModeResponse_encodeBinary(const UA_SetMonitoringModeResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_EventNotificationList_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EventNotificationList *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST], 0, NULL); +UA_SetMonitoringModeResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetMonitoringModeResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE], NULL); } -/* UnregisterNodesRequest */ +/* BrowseResultMask */ +static UA_INLINE size_t +UA_BrowseResultMask_calcSizeBinary(const UA_BrowseResultMask *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESULTMASK]); +} static UA_INLINE UA_StatusCode -UA_UnregisterNodesRequest_encodeBinary(const UA_UnregisterNodesRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST], bufPos, bufEnd, NULL, NULL); +UA_BrowseResultMask_encodeBinary(const UA_BrowseResultMask *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESULTMASK], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_UnregisterNodesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UnregisterNodesRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST], 0, NULL); +UA_BrowseResultMask_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseResultMask *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSERESULTMASK], NULL); } -/* ContentFilterElementResult */ +/* RequestHeader */ +static UA_INLINE size_t +UA_RequestHeader_calcSizeBinary(const UA_RequestHeader *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REQUESTHEADER]); +} static UA_INLINE UA_StatusCode -UA_ContentFilterElementResult_encodeBinary(const UA_ContentFilterElementResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT], bufPos, bufEnd, NULL, NULL); +UA_RequestHeader_encodeBinary(const UA_RequestHeader *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REQUESTHEADER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ContentFilterElementResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ContentFilterElementResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENTRESULT], 0, NULL); +UA_RequestHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RequestHeader *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REQUESTHEADER], NULL); } -/* SimpleAttributeOperand */ +/* MonitoredItemModifyResult */ +static UA_INLINE size_t +UA_MonitoredItemModifyResult_calcSizeBinary(const UA_MonitoredItemModifyResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT]); +} static UA_INLINE UA_StatusCode -UA_SimpleAttributeOperand_encodeBinary(const UA_SimpleAttributeOperand *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND], bufPos, bufEnd, NULL, NULL); +UA_MonitoredItemModifyResult_encodeBinary(const UA_MonitoredItemModifyResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SimpleAttributeOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SimpleAttributeOperand *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND], 0, NULL); +UA_MonitoredItemModifyResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemModifyResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYRESULT], NULL); } -/* LiteralOperand */ +/* CloseSecureChannelRequest */ +static UA_INLINE size_t +UA_CloseSecureChannelRequest_calcSizeBinary(const UA_CloseSecureChannelRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); +} static UA_INLINE UA_StatusCode -UA_LiteralOperand_encodeBinary(const UA_LiteralOperand *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_LITERALOPERAND], bufPos, bufEnd, NULL, NULL); +UA_CloseSecureChannelRequest_encodeBinary(const UA_CloseSecureChannelRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_LiteralOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_LiteralOperand *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_LITERALOPERAND], 0, NULL); +UA_CloseSecureChannelRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CloseSecureChannelRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST], NULL); } -/* QueryDataSet */ +/* NotificationMessage */ +static UA_INLINE size_t +UA_NotificationMessage_calcSizeBinary(const UA_NotificationMessage *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE]); +} static UA_INLINE UA_StatusCode -UA_QueryDataSet_encodeBinary(const UA_QueryDataSet *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_QUERYDATASET], bufPos, bufEnd, NULL, NULL); +UA_NotificationMessage_encodeBinary(const UA_NotificationMessage *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_QueryDataSet_decodeBinary(const UA_ByteString *src, size_t *offset, UA_QueryDataSet *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_QUERYDATASET], 0, NULL); +UA_NotificationMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NotificationMessage *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NOTIFICATIONMESSAGE], NULL); } -/* AnonymousIdentityToken */ +/* CreateSubscriptionResponse */ +static UA_INLINE size_t +UA_CreateSubscriptionResponse_calcSizeBinary(const UA_CreateSubscriptionResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_AnonymousIdentityToken_encodeBinary(const UA_AnonymousIdentityToken *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN], bufPos, bufEnd, NULL, NULL); +UA_CreateSubscriptionResponse_encodeBinary(const UA_CreateSubscriptionResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AnonymousIdentityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AnonymousIdentityToken *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN], 0, NULL); +UA_CreateSubscriptionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateSubscriptionResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE], NULL); } -/* SetPublishingModeRequest */ +/* MdnsDiscoveryConfiguration */ +static UA_INLINE size_t +UA_MdnsDiscoveryConfiguration_calcSizeBinary(const UA_MdnsDiscoveryConfiguration *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]); +} static UA_INLINE UA_StatusCode -UA_SetPublishingModeRequest_encodeBinary(const UA_SetPublishingModeRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST], bufPos, bufEnd, NULL, NULL); +UA_MdnsDiscoveryConfiguration_encodeBinary(const UA_MdnsDiscoveryConfiguration *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SetPublishingModeRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetPublishingModeRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST], 0, NULL); +UA_MdnsDiscoveryConfiguration_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MdnsDiscoveryConfiguration *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION], NULL); } -/* MonitoredItemCreateResult */ +/* BrowseDirection */ +static UA_INLINE size_t +UA_BrowseDirection_calcSizeBinary(const UA_BrowseDirection *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSEDIRECTION]); +} static UA_INLINE UA_StatusCode -UA_MonitoredItemCreateResult_encodeBinary(const UA_MonitoredItemCreateResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT], bufPos, bufEnd, NULL, NULL); +UA_BrowseDirection_encodeBinary(const UA_BrowseDirection *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEDIRECTION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MonitoredItemCreateResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemCreateResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT], 0, NULL); +UA_BrowseDirection_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseDirection *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEDIRECTION], NULL); } -/* TimestampsToReturn */ +/* CallMethodRequest */ +static UA_INLINE size_t +UA_CallMethodRequest_calcSizeBinary(const UA_CallMethodRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST]); +} static UA_INLINE UA_StatusCode -UA_TimestampsToReturn_encodeBinary(const UA_TimestampsToReturn *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN], bufPos, bufEnd, NULL, NULL); +UA_CallMethodRequest_encodeBinary(const UA_CallMethodRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_TimestampsToReturn_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TimestampsToReturn *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN], 0, NULL); +UA_CallMethodRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CallMethodRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CALLMETHODREQUEST], NULL); } -/* CallRequest */ +/* ReadResponse */ +static UA_INLINE size_t +UA_ReadResponse_calcSizeBinary(const UA_ReadResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_READRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_CallRequest_encodeBinary(const UA_CallRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CALLREQUEST], bufPos, bufEnd, NULL, NULL); +UA_ReadResponse_encodeBinary(const UA_ReadResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_READRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CallRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CallRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CALLREQUEST], 0, NULL); +UA_ReadResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReadResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_READRESPONSE], NULL); } -/* MethodAttributes */ +/* TimestampsToReturn */ +static UA_INLINE size_t +UA_TimestampsToReturn_calcSizeBinary(const UA_TimestampsToReturn *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN]); +} static UA_INLINE UA_StatusCode -UA_MethodAttributes_encodeBinary(const UA_MethodAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_METHODATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_TimestampsToReturn_encodeBinary(const UA_TimestampsToReturn *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MethodAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MethodAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_METHODATTRIBUTES], 0, NULL); +UA_TimestampsToReturn_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TimestampsToReturn *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_TIMESTAMPSTORETURN], NULL); } -/* DeleteReferencesItem */ +/* NodeClass */ +static UA_INLINE size_t +UA_NodeClass_calcSizeBinary(const UA_NodeClass *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_NODECLASS]); +} static UA_INLINE UA_StatusCode -UA_DeleteReferencesItem_encodeBinary(const UA_DeleteReferencesItem *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM], bufPos, bufEnd, NULL, NULL); +UA_NodeClass_encodeBinary(const UA_NodeClass *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODECLASS], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeleteReferencesItem_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteReferencesItem *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM], 0, NULL); +UA_NodeClass_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NodeClass *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODECLASS], NULL); } -/* WriteValue */ +/* ObjectTypeAttributes */ +static UA_INLINE size_t +UA_ObjectTypeAttributes_calcSizeBinary(const UA_ObjectTypeAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]); +} static UA_INLINE UA_StatusCode -UA_WriteValue_encodeBinary(const UA_WriteValue *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_WRITEVALUE], bufPos, bufEnd, NULL, NULL); +UA_ObjectTypeAttributes_encodeBinary(const UA_ObjectTypeAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_WriteValue_decodeBinary(const UA_ByteString *src, size_t *offset, UA_WriteValue *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_WRITEVALUE], 0, NULL); +UA_ObjectTypeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ObjectTypeAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], NULL); } -/* NodeAttributesMask */ +/* SecurityTokenRequestType */ +static UA_INLINE size_t +UA_SecurityTokenRequestType_calcSizeBinary(const UA_SecurityTokenRequestType *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE]); +} static UA_INLINE UA_StatusCode -UA_NodeAttributesMask_encodeBinary(const UA_NodeAttributesMask *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK], bufPos, bufEnd, NULL, NULL); +UA_SecurityTokenRequestType_encodeBinary(const UA_SecurityTokenRequestType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_NodeAttributesMask_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NodeAttributesMask *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK], 0, NULL); +UA_SecurityTokenRequestType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SecurityTokenRequestType *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE], NULL); } -/* MessageSecurityMode */ +/* CloseSessionResponse */ +static UA_INLINE size_t +UA_CloseSessionResponse_calcSizeBinary(const UA_CloseSessionResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_MessageSecurityMode_encodeBinary(const UA_MessageSecurityMode *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], bufPos, bufEnd, NULL, NULL); +UA_CloseSessionResponse_encodeBinary(const UA_CloseSessionResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MessageSecurityMode_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MessageSecurityMode *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MESSAGESECURITYMODE], 0, NULL); +UA_CloseSessionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CloseSessionResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE], NULL); } -/* MonitoringParameters */ +/* SetPublishingModeRequest */ +static UA_INLINE size_t +UA_SetPublishingModeRequest_calcSizeBinary(const UA_SetPublishingModeRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST]); +} static UA_INLINE UA_StatusCode -UA_MonitoringParameters_encodeBinary(const UA_MonitoringParameters *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS], bufPos, bufEnd, NULL, NULL); +UA_SetPublishingModeRequest_encodeBinary(const UA_SetPublishingModeRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MonitoringParameters_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoringParameters *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS], 0, NULL); +UA_SetPublishingModeRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetPublishingModeRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST], NULL); } -/* ReferenceNode */ +/* IssuedIdentityToken */ +static UA_INLINE size_t +UA_IssuedIdentityToken_calcSizeBinary(const UA_IssuedIdentityToken *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]); +} static UA_INLINE UA_StatusCode -UA_ReferenceNode_encodeBinary(const UA_ReferenceNode *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REFERENCENODE], bufPos, bufEnd, NULL, NULL); +UA_IssuedIdentityToken_encodeBinary(const UA_IssuedIdentityToken *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ReferenceNode_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReferenceNode *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REFERENCENODE], 0, NULL); +UA_IssuedIdentityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_IssuedIdentityToken *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN], NULL); } -/* Argument */ +/* ServerOnNetwork */ +static UA_INLINE size_t +UA_ServerOnNetwork_calcSizeBinary(const UA_ServerOnNetwork *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SERVERONNETWORK]); +} static UA_INLINE UA_StatusCode -UA_Argument_encodeBinary(const UA_Argument *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ARGUMENT], bufPos, bufEnd, NULL, NULL); +UA_ServerOnNetwork_encodeBinary(const UA_ServerOnNetwork *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVERONNETWORK], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_Argument_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Argument *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ARGUMENT], 0, NULL); +UA_ServerOnNetwork_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServerOnNetwork *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVERONNETWORK], NULL); } -/* ChannelSecurityToken */ +/* DeleteMonitoredItemsResponse */ +static UA_INLINE size_t +UA_DeleteMonitoredItemsResponse_calcSizeBinary(const UA_DeleteMonitoredItemsResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_ChannelSecurityToken_encodeBinary(const UA_ChannelSecurityToken *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN], bufPos, bufEnd, NULL, NULL); +UA_DeleteMonitoredItemsResponse_encodeBinary(const UA_DeleteMonitoredItemsResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ChannelSecurityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ChannelSecurityToken *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN], 0, NULL); +UA_DeleteMonitoredItemsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteMonitoredItemsResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE], NULL); } -/* UserIdentityToken */ +/* ApplicationType */ +static UA_INLINE size_t +UA_ApplicationType_calcSizeBinary(const UA_ApplicationType *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_APPLICATIONTYPE]); +} static UA_INLINE UA_StatusCode -UA_UserIdentityToken_encodeBinary(const UA_UserIdentityToken *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN], bufPos, bufEnd, NULL, NULL); +UA_ApplicationType_encodeBinary(const UA_ApplicationType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_APPLICATIONTYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_UserIdentityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UserIdentityToken *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_USERIDENTITYTOKEN], 0, NULL); +UA_ApplicationType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ApplicationType *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_APPLICATIONTYPE], NULL); } -/* SignatureData */ +/* DiscoveryConfiguration */ +static UA_INLINE size_t +UA_DiscoveryConfiguration_calcSizeBinary(const UA_DiscoveryConfiguration *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DISCOVERYCONFIGURATION]); +} static UA_INLINE UA_StatusCode -UA_SignatureData_encodeBinary(const UA_SignatureData *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SIGNATUREDATA], bufPos, bufEnd, NULL, NULL); +UA_DiscoveryConfiguration_encodeBinary(const UA_DiscoveryConfiguration *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DISCOVERYCONFIGURATION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SignatureData_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SignatureData *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SIGNATUREDATA], 0, NULL); +UA_DiscoveryConfiguration_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DiscoveryConfiguration *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DISCOVERYCONFIGURATION], NULL); } -/* ObjectTypeAttributes */ +/* BrowseNextRequest */ +static UA_INLINE size_t +UA_BrowseNextRequest_calcSizeBinary(const UA_BrowseNextRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST]); +} static UA_INLINE UA_StatusCode -UA_ObjectTypeAttributes_encodeBinary(const UA_ObjectTypeAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_BrowseNextRequest_encodeBinary(const UA_BrowseNextRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ObjectTypeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ObjectTypeAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES], 0, NULL); +UA_BrowseNextRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseNextRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST], NULL); } -/* DeadbandType */ +/* ModifySubscriptionRequest */ +static UA_INLINE size_t +UA_ModifySubscriptionRequest_calcSizeBinary(const UA_ModifySubscriptionRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST]); +} static UA_INLINE UA_StatusCode -UA_DeadbandType_encodeBinary(const UA_DeadbandType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DEADBANDTYPE], bufPos, bufEnd, NULL, NULL); +UA_ModifySubscriptionRequest_encodeBinary(const UA_ModifySubscriptionRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeadbandType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeadbandType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DEADBANDTYPE], 0, NULL); +UA_ModifySubscriptionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModifySubscriptionRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST], NULL); } -/* SecurityTokenRequestType */ +/* BrowseDescription */ +static UA_INLINE size_t +UA_BrowseDescription_calcSizeBinary(const UA_BrowseDescription *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION]); +} static UA_INLINE UA_StatusCode -UA_SecurityTokenRequestType_encodeBinary(const UA_SecurityTokenRequestType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE], bufPos, bufEnd, NULL, NULL); +UA_BrowseDescription_encodeBinary(const UA_BrowseDescription *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SecurityTokenRequestType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SecurityTokenRequestType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SECURITYTOKENREQUESTTYPE], 0, NULL); +UA_BrowseDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseDescription *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION], NULL); } -/* NodeAttributes */ +/* SignedSoftwareCertificate */ +static UA_INLINE size_t +UA_SignedSoftwareCertificate_calcSizeBinary(const UA_SignedSoftwareCertificate *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE]); +} static UA_INLINE UA_StatusCode -UA_NodeAttributes_encodeBinary(const UA_NodeAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODEATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_SignedSoftwareCertificate_encodeBinary(const UA_SignedSoftwareCertificate *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_NodeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NodeAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODEATTRIBUTES], 0, NULL); +UA_SignedSoftwareCertificate_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SignedSoftwareCertificate *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE], NULL); } -/* DataChangeTrigger */ +/* BrowsePathTarget */ +static UA_INLINE size_t +UA_BrowsePathTarget_calcSizeBinary(const UA_BrowsePathTarget *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET]); +} static UA_INLINE UA_StatusCode -UA_DataChangeTrigger_encodeBinary(const UA_DataChangeTrigger *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER], bufPos, bufEnd, NULL, NULL); +UA_BrowsePathTarget_encodeBinary(const UA_BrowsePathTarget *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DataChangeTrigger_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataChangeTrigger *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER], 0, NULL); +UA_BrowsePathTarget_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowsePathTarget *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET], NULL); } -/* BuildInfo */ +/* WriteResponse */ +static UA_INLINE size_t +UA_WriteResponse_calcSizeBinary(const UA_WriteResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_WRITERESPONSE]); +} static UA_INLINE UA_StatusCode -UA_BuildInfo_encodeBinary(const UA_BuildInfo *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BUILDINFO], bufPos, bufEnd, NULL, NULL); +UA_WriteResponse_encodeBinary(const UA_WriteResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_WRITERESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BuildInfo_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BuildInfo *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BUILDINFO], 0, NULL); +UA_WriteResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_WriteResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_WRITERESPONSE], NULL); } -/* NodeClass */ +/* AddNodesResult */ +static UA_INLINE size_t +UA_AddNodesResult_calcSizeBinary(const UA_AddNodesResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESRESULT]); +} static UA_INLINE UA_StatusCode -UA_NodeClass_encodeBinary(const UA_NodeClass *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODECLASS], bufPos, bufEnd, NULL, NULL); +UA_AddNodesResult_encodeBinary(const UA_AddNodesResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESRESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_NodeClass_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NodeClass *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODECLASS], 0, NULL); +UA_AddNodesResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddNodesResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDNODESRESULT], NULL); } -/* SubscriptionDiagnosticsDataType */ +/* RegisterServerResponse */ +static UA_INLINE size_t +UA_RegisterServerResponse_calcSizeBinary(const UA_RegisterServerResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_SubscriptionDiagnosticsDataType_encodeBinary(const UA_SubscriptionDiagnosticsDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_RegisterServerResponse_encodeBinary(const UA_RegisterServerResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SubscriptionDiagnosticsDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SubscriptionDiagnosticsDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE], 0, NULL); +UA_RegisterServerResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterServerResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE], NULL); } -/* FilterOperand */ +/* AddReferencesItem */ +static UA_INLINE size_t +UA_AddReferencesItem_calcSizeBinary(const UA_AddReferencesItem *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM]); +} static UA_INLINE UA_StatusCode -UA_FilterOperand_encodeBinary(const UA_FilterOperand *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FILTEROPERAND], bufPos, bufEnd, NULL, NULL); +UA_AddReferencesItem_encodeBinary(const UA_AddReferencesItem *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_FilterOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FilterOperand *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FILTEROPERAND], 0, NULL); +UA_AddReferencesItem_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddReferencesItem *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM], NULL); } -/* MonitoredItemNotification */ +/* RegisterServer2Response */ +static UA_INLINE size_t +UA_RegisterServer2Response_calcSizeBinary(const UA_RegisterServer2Response *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]); +} static UA_INLINE UA_StatusCode -UA_MonitoredItemNotification_encodeBinary(const UA_MonitoredItemNotification *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION], bufPos, bufEnd, NULL, NULL); +UA_RegisterServer2Response_encodeBinary(const UA_RegisterServer2Response *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MonitoredItemNotification_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemNotification *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION], 0, NULL); +UA_RegisterServer2Response_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterServer2Response *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE], NULL); } -/* DeleteNodesItem */ +/* DeleteReferencesResponse */ +static UA_INLINE size_t +UA_DeleteReferencesResponse_calcSizeBinary(const UA_DeleteReferencesResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_DeleteNodesItem_encodeBinary(const UA_DeleteNodesItem *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESITEM], bufPos, bufEnd, NULL, NULL); +UA_DeleteReferencesResponse_encodeBinary(const UA_DeleteReferencesResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeleteNodesItem_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteNodesItem *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETENODESITEM], 0, NULL); +UA_DeleteReferencesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteReferencesResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE], NULL); } -/* DeleteSubscriptionsRequest */ +/* RelativePathElement */ +static UA_INLINE size_t +UA_RelativePathElement_calcSizeBinary(const UA_RelativePathElement *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); +} static UA_INLINE UA_StatusCode -UA_DeleteSubscriptionsRequest_encodeBinary(const UA_DeleteSubscriptionsRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST], bufPos, bufEnd, NULL, NULL); +UA_RelativePathElement_encodeBinary(const UA_RelativePathElement *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeleteSubscriptionsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteSubscriptionsRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST], 0, NULL); +UA_RelativePathElement_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RelativePathElement *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT], NULL); } /* SubscriptionAcknowledgement */ +static UA_INLINE size_t +UA_SubscriptionAcknowledgement_calcSizeBinary(const UA_SubscriptionAcknowledgement *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT]); +} static UA_INLINE UA_StatusCode -UA_SubscriptionAcknowledgement_encodeBinary(const UA_SubscriptionAcknowledgement *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT], bufPos, bufEnd, NULL, NULL); +UA_SubscriptionAcknowledgement_encodeBinary(const UA_SubscriptionAcknowledgement *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_SubscriptionAcknowledgement_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SubscriptionAcknowledgement *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT], NULL); } -/* ReadValueId */ -static UA_INLINE UA_StatusCode -UA_ReadValueId_encodeBinary(const UA_ReadValueId *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_READVALUEID], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_ReadValueId_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReadValueId *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_READVALUEID], 0, NULL); +/* CreateMonitoredItemsResponse */ +static UA_INLINE size_t +UA_CreateMonitoredItemsResponse_calcSizeBinary(const UA_CreateMonitoredItemsResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE]); } - -/* DataTypeAttributes */ static UA_INLINE UA_StatusCode -UA_DataTypeAttributes_encodeBinary(const UA_DataTypeAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_CreateMonitoredItemsResponse_encodeBinary(const UA_CreateMonitoredItemsResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DataTypeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataTypeAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES], 0, NULL); +UA_CreateMonitoredItemsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateMonitoredItemsResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE], NULL); } -/* ResponseHeader */ -static UA_INLINE UA_StatusCode -UA_ResponseHeader_encodeBinary(const UA_ResponseHeader *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_RESPONSEHEADER], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_ResponseHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ResponseHeader *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_RESPONSEHEADER], 0, NULL); +/* DeleteReferencesItem */ +static UA_INLINE size_t +UA_DeleteReferencesItem_calcSizeBinary(const UA_DeleteReferencesItem *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM]); } - -/* DeleteMonitoredItemsRequest */ static UA_INLINE UA_StatusCode -UA_DeleteMonitoredItemsRequest_encodeBinary(const UA_DeleteMonitoredItemsRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST], bufPos, bufEnd, NULL, NULL); +UA_DeleteReferencesItem_encodeBinary(const UA_DeleteReferencesItem *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeleteMonitoredItemsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteMonitoredItemsRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST], 0, NULL); +UA_DeleteReferencesItem_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteReferencesItem *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM], NULL); } -/* ViewDescription */ +/* WriteValue */ +static UA_INLINE size_t +UA_WriteValue_calcSizeBinary(const UA_WriteValue *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_WRITEVALUE]); +} static UA_INLINE UA_StatusCode -UA_ViewDescription_encodeBinary(const UA_ViewDescription *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION], bufPos, bufEnd, NULL, NULL); +UA_WriteValue_encodeBinary(const UA_WriteValue *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_WRITEVALUE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ViewDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ViewDescription *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION], 0, NULL); +UA_WriteValue_decodeBinary(const UA_ByteString *src, size_t *offset, UA_WriteValue *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_WRITEVALUE], NULL); } -/* ServerOnNetwork */ +/* DataTypeAttributes */ +static UA_INLINE size_t +UA_DataTypeAttributes_calcSizeBinary(const UA_DataTypeAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]); +} static UA_INLINE UA_StatusCode -UA_ServerOnNetwork_encodeBinary(const UA_ServerOnNetwork *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVERONNETWORK], bufPos, bufEnd, NULL, NULL); +UA_DataTypeAttributes_encodeBinary(const UA_DataTypeAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ServerOnNetwork_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServerOnNetwork *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVERONNETWORK], 0, NULL); +UA_DataTypeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataTypeAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES], NULL); } -/* DeleteMonitoredItemsResponse */ +/* AddReferencesResponse */ +static UA_INLINE size_t +UA_AddReferencesResponse_calcSizeBinary(const UA_AddReferencesResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_DeleteMonitoredItemsResponse_encodeBinary(const UA_DeleteMonitoredItemsResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_AddReferencesResponse_encodeBinary(const UA_AddReferencesResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeleteMonitoredItemsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteMonitoredItemsResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSRESPONSE], 0, NULL); +UA_AddReferencesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddReferencesResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE], NULL); } -/* FindServersOnNetworkResponse */ +/* DeadbandType */ +static UA_INLINE size_t +UA_DeadbandType_calcSizeBinary(const UA_DeadbandType *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DEADBANDTYPE]); +} static UA_INLINE UA_StatusCode -UA_FindServersOnNetworkResponse_encodeBinary(const UA_FindServersOnNetworkResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_DeadbandType_encodeBinary(const UA_DeadbandType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DEADBANDTYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_FindServersOnNetworkResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FindServersOnNetworkResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE], 0, NULL); +UA_DeadbandType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeadbandType *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DEADBANDTYPE], NULL); } -/* RelativePath */ +/* DataChangeTrigger */ +static UA_INLINE size_t +UA_DataChangeTrigger_calcSizeBinary(const UA_DataChangeTrigger *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER]); +} static UA_INLINE UA_StatusCode -UA_RelativePath_encodeBinary(const UA_RelativePath *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_RELATIVEPATH], bufPos, bufEnd, NULL, NULL); +UA_DataChangeTrigger_encodeBinary(const UA_DataChangeTrigger *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RelativePath_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RelativePath *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_RELATIVEPATH], 0, NULL); +UA_DataChangeTrigger_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataChangeTrigger *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATACHANGETRIGGER], NULL); } -/* RegisterNodesRequest */ +/* BuildInfo */ +static UA_INLINE size_t +UA_BuildInfo_calcSizeBinary(const UA_BuildInfo *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BUILDINFO]); +} static UA_INLINE UA_StatusCode -UA_RegisterNodesRequest_encodeBinary(const UA_RegisterNodesRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST], bufPos, bufEnd, NULL, NULL); +UA_BuildInfo_encodeBinary(const UA_BuildInfo *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BUILDINFO], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RegisterNodesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterNodesRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST], 0, NULL); +UA_BuildInfo_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BuildInfo *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BUILDINFO], NULL); } -/* AggregateConfiguration */ +/* FilterOperand */ +static UA_INLINE size_t +UA_FilterOperand_calcSizeBinary(const UA_FilterOperand *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_FILTEROPERAND]); +} static UA_INLINE UA_StatusCode -UA_AggregateConfiguration_encodeBinary(const UA_AggregateConfiguration *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION], bufPos, bufEnd, NULL, NULL); +UA_FilterOperand_encodeBinary(const UA_FilterOperand *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FILTEROPERAND], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AggregateConfiguration_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AggregateConfiguration *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION], 0, NULL); +UA_FilterOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FilterOperand *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FILTEROPERAND], NULL); } -/* DeleteNodesRequest */ +/* MonitoringParameters */ +static UA_INLINE size_t +UA_MonitoringParameters_calcSizeBinary(const UA_MonitoringParameters *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS]); +} static UA_INLINE UA_StatusCode -UA_DeleteNodesRequest_encodeBinary(const UA_DeleteNodesRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESREQUEST], bufPos, bufEnd, NULL, NULL); +UA_MonitoringParameters_encodeBinary(const UA_MonitoringParameters *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeleteNodesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteNodesRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETENODESREQUEST], 0, NULL); +UA_MonitoringParameters_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoringParameters *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITORINGPARAMETERS], NULL); } -/* PublishResponse */ +/* DeleteNodesItem */ +static UA_INLINE size_t +UA_DeleteNodesItem_calcSizeBinary(const UA_DeleteNodesItem *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESITEM]); +} static UA_INLINE UA_StatusCode -UA_PublishResponse_encodeBinary(const UA_PublishResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_DeleteNodesItem_encodeBinary(const UA_DeleteNodesItem *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESITEM], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_PublishResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_PublishResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE], 0, NULL); +UA_DeleteNodesItem_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteNodesItem *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETENODESITEM], NULL); } -/* MonitoredItemModifyRequest */ +/* ReadValueId */ +static UA_INLINE size_t +UA_ReadValueId_calcSizeBinary(const UA_ReadValueId *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_READVALUEID]); +} static UA_INLINE UA_StatusCode -UA_MonitoredItemModifyRequest_encodeBinary(const UA_MonitoredItemModifyRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST], bufPos, bufEnd, NULL, NULL); +UA_ReadValueId_encodeBinary(const UA_ReadValueId *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_READVALUEID], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MonitoredItemModifyRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemModifyRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST], 0, NULL); +UA_ReadValueId_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReadValueId *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_READVALUEID], NULL); } -/* ServiceCounterDataType */ +/* CallRequest */ +static UA_INLINE size_t +UA_CallRequest_calcSizeBinary(const UA_CallRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CALLREQUEST]); +} static UA_INLINE UA_StatusCode -UA_ServiceCounterDataType_encodeBinary(const UA_ServiceCounterDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_CallRequest_encodeBinary(const UA_CallRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CALLREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ServiceCounterDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServiceCounterDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVICECOUNTERDATATYPE], 0, NULL); +UA_CallRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CallRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CALLREQUEST], NULL); } -/* ModelChangeStructureDataType */ +/* RelativePath */ +static UA_INLINE size_t +UA_RelativePath_calcSizeBinary(const UA_RelativePath *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_RELATIVEPATH]); +} static UA_INLINE UA_StatusCode -UA_ModelChangeStructureDataType_encodeBinary(const UA_ModelChangeStructureDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_RelativePath_encodeBinary(const UA_RelativePath *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_RELATIVEPATH], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ModelChangeStructureDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModelChangeStructureDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODELCHANGESTRUCTUREDATATYPE], 0, NULL); +UA_RelativePath_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RelativePath *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_RELATIVEPATH], NULL); } -/* UserNameIdentityToken */ +/* DeleteNodesRequest */ +static UA_INLINE size_t +UA_DeleteNodesRequest_calcSizeBinary(const UA_DeleteNodesRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESREQUEST]); +} static UA_INLINE UA_StatusCode -UA_UserNameIdentityToken_encodeBinary(const UA_UserNameIdentityToken *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN], bufPos, bufEnd, NULL, NULL); +UA_DeleteNodesRequest_encodeBinary(const UA_DeleteNodesRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_UserNameIdentityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UserNameIdentityToken *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN], 0, NULL); +UA_DeleteNodesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteNodesRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETENODESREQUEST], NULL); } -/* IdType */ +/* MonitoredItemModifyRequest */ +static UA_INLINE size_t +UA_MonitoredItemModifyRequest_calcSizeBinary(const UA_MonitoredItemModifyRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST]); +} static UA_INLINE UA_StatusCode -UA_IdType_encodeBinary(const UA_IdType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_IDTYPE], bufPos, bufEnd, NULL, NULL); +UA_MonitoredItemModifyRequest_encodeBinary(const UA_MonitoredItemModifyRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_IdType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_IdType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_IDTYPE], 0, NULL); +UA_MonitoredItemModifyRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemModifyRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMMODIFYREQUEST], NULL); } /* UserTokenType */ +static UA_INLINE size_t +UA_UserTokenType_calcSizeBinary(const UA_UserTokenType *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_USERTOKENTYPE]); +} static UA_INLINE UA_StatusCode -UA_UserTokenType_encodeBinary(const UA_UserTokenType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_USERTOKENTYPE], bufPos, bufEnd, NULL, NULL); +UA_UserTokenType_encodeBinary(const UA_UserTokenType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_USERTOKENTYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_UserTokenType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UserTokenType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_USERTOKENTYPE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_USERTOKENTYPE], NULL); } -/* SetTriggeringResponse */ +/* AggregateConfiguration */ +static UA_INLINE size_t +UA_AggregateConfiguration_calcSizeBinary(const UA_AggregateConfiguration *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION]); +} static UA_INLINE UA_StatusCode -UA_SetTriggeringResponse_encodeBinary(const UA_SetTriggeringResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_AggregateConfiguration_encodeBinary(const UA_AggregateConfiguration *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SetTriggeringResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetTriggeringResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE], 0, NULL); +UA_AggregateConfiguration_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AggregateConfiguration *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_AGGREGATECONFIGURATION], NULL); } -/* TimeZoneDataType */ +/* LocaleId */ +static UA_INLINE size_t +UA_LocaleId_calcSizeBinary(const UA_LocaleId *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_LOCALEID]); +} static UA_INLINE UA_StatusCode -UA_TimeZoneDataType_encodeBinary(const UA_TimeZoneDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_TIMEZONEDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_LocaleId_encodeBinary(const UA_LocaleId *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_LOCALEID], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_TimeZoneDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TimeZoneDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_TIMEZONEDATATYPE], 0, NULL); +UA_LocaleId_decodeBinary(const UA_ByteString *src, size_t *offset, UA_LocaleId *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_LOCALEID], NULL); } -/* ActivateSessionRequest */ +/* UnregisterNodesResponse */ +static UA_INLINE size_t +UA_UnregisterNodesResponse_calcSizeBinary(const UA_UnregisterNodesResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_ActivateSessionRequest_encodeBinary(const UA_ActivateSessionRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST], bufPos, bufEnd, NULL, NULL); +UA_UnregisterNodesResponse_encodeBinary(const UA_UnregisterNodesResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ActivateSessionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ActivateSessionRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST], 0, NULL); +UA_UnregisterNodesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UnregisterNodesResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE], NULL); } -/* OpenSecureChannelResponse */ +/* ContentFilterResult */ +static UA_INLINE size_t +UA_ContentFilterResult_calcSizeBinary(const UA_ContentFilterResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT]); +} static UA_INLINE UA_StatusCode -UA_OpenSecureChannelResponse_encodeBinary(const UA_OpenSecureChannelResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_ContentFilterResult_encodeBinary(const UA_ContentFilterResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_OpenSecureChannelResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_OpenSecureChannelResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE], 0, NULL); +UA_ContentFilterResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ContentFilterResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT], NULL); } -/* ApplicationType */ +/* UserTokenPolicy */ +static UA_INLINE size_t +UA_UserTokenPolicy_calcSizeBinary(const UA_UserTokenPolicy *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); +} static UA_INLINE UA_StatusCode -UA_ApplicationType_encodeBinary(const UA_ApplicationType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_APPLICATIONTYPE], bufPos, bufEnd, NULL, NULL); +UA_UserTokenPolicy_encodeBinary(const UA_UserTokenPolicy *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_USERTOKENPOLICY], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ApplicationType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ApplicationType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_APPLICATIONTYPE], 0, NULL); +UA_UserTokenPolicy_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UserTokenPolicy *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_USERTOKENPOLICY], NULL); } -/* ServerState */ +/* DeleteMonitoredItemsRequest */ +static UA_INLINE size_t +UA_DeleteMonitoredItemsRequest_calcSizeBinary(const UA_DeleteMonitoredItemsRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST]); +} static UA_INLINE UA_StatusCode -UA_ServerState_encodeBinary(const UA_ServerState *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVERSTATE], bufPos, bufEnd, NULL, NULL); +UA_DeleteMonitoredItemsRequest_encodeBinary(const UA_DeleteMonitoredItemsRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ServerState_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServerState *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVERSTATE], 0, NULL); +UA_DeleteMonitoredItemsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteMonitoredItemsRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEMONITOREDITEMSREQUEST], NULL); } -/* QueryNextResponse */ +/* SetMonitoringModeRequest */ +static UA_INLINE size_t +UA_SetMonitoringModeRequest_calcSizeBinary(const UA_SetMonitoringModeRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST]); +} static UA_INLINE UA_StatusCode -UA_QueryNextResponse_encodeBinary(const UA_QueryNextResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_QUERYNEXTRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_SetMonitoringModeRequest_encodeBinary(const UA_SetMonitoringModeRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_QueryNextResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_QueryNextResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_QUERYNEXTRESPONSE], 0, NULL); +UA_SetMonitoringModeRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetMonitoringModeRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], NULL); } -/* DiscoveryConfiguration */ +/* Duration */ +static UA_INLINE size_t +UA_Duration_calcSizeBinary(const UA_Duration *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DURATION]); +} static UA_INLINE UA_StatusCode -UA_DiscoveryConfiguration_encodeBinary(const UA_DiscoveryConfiguration *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DISCOVERYCONFIGURATION], bufPos, bufEnd, NULL, NULL); +UA_Duration_encodeBinary(const UA_Duration *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DURATION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DiscoveryConfiguration_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DiscoveryConfiguration *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DISCOVERYCONFIGURATION], 0, NULL); +UA_Duration_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Duration *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DURATION], NULL); } -/* ActivateSessionResponse */ +/* ReferenceTypeAttributes */ +static UA_INLINE size_t +UA_ReferenceTypeAttributes_calcSizeBinary(const UA_ReferenceTypeAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); +} static UA_INLINE UA_StatusCode -UA_ActivateSessionResponse_encodeBinary(const UA_ActivateSessionResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_ReferenceTypeAttributes_encodeBinary(const UA_ReferenceTypeAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ActivateSessionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ActivateSessionResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE], 0, NULL); +UA_ReferenceTypeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReferenceTypeAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], NULL); } -/* EndpointUrlListDataType */ +/* GetEndpointsRequest */ +static UA_INLINE size_t +UA_GetEndpointsRequest_calcSizeBinary(const UA_GetEndpointsRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST]); +} static UA_INLINE UA_StatusCode -UA_EndpointUrlListDataType_encodeBinary(const UA_EndpointUrlListDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_GetEndpointsRequest_encodeBinary(const UA_GetEndpointsRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_EndpointUrlListDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EndpointUrlListDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ENDPOINTURLLISTDATATYPE], 0, NULL); +UA_GetEndpointsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_GetEndpointsRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST], NULL); } -/* FilterOperator */ +/* CloseSecureChannelResponse */ +static UA_INLINE size_t +UA_CloseSecureChannelResponse_calcSizeBinary(const UA_CloseSecureChannelResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_FilterOperator_encodeBinary(const UA_FilterOperator *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FILTEROPERATOR], bufPos, bufEnd, NULL, NULL); +UA_CloseSecureChannelResponse_encodeBinary(const UA_CloseSecureChannelResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_FilterOperator_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FilterOperator *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FILTEROPERATOR], 0, NULL); +UA_CloseSecureChannelResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CloseSecureChannelResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE], NULL); } -/* QueryNextRequest */ +/* ViewDescription */ +static UA_INLINE size_t +UA_ViewDescription_calcSizeBinary(const UA_ViewDescription *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION]); +} static UA_INLINE UA_StatusCode -UA_QueryNextRequest_encodeBinary(const UA_QueryNextRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_QUERYNEXTREQUEST], bufPos, bufEnd, NULL, NULL); +UA_ViewDescription_encodeBinary(const UA_ViewDescription *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_QueryNextRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_QueryNextRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_QUERYNEXTREQUEST], 0, NULL); +UA_ViewDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ViewDescription *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VIEWDESCRIPTION], NULL); } -/* WriteResponse */ +/* SetPublishingModeResponse */ +static UA_INLINE size_t +UA_SetPublishingModeResponse_calcSizeBinary(const UA_SetPublishingModeResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]); +} static UA_INLINE UA_StatusCode -UA_WriteResponse_encodeBinary(const UA_WriteResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_WRITERESPONSE], bufPos, bufEnd, NULL, NULL); +UA_SetPublishingModeResponse_encodeBinary(const UA_SetPublishingModeResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_WriteResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_WriteResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_WRITERESPONSE], 0, NULL); +UA_SetPublishingModeResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetPublishingModeResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE], NULL); } -/* BrowseNextRequest */ +/* StatusChangeNotification */ +static UA_INLINE size_t +UA_StatusChangeNotification_calcSizeBinary(const UA_StatusChangeNotification *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]); +} static UA_INLINE UA_StatusCode -UA_BrowseNextRequest_encodeBinary(const UA_BrowseNextRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST], bufPos, bufEnd, NULL, NULL); +UA_StatusChangeNotification_encodeBinary(const UA_StatusChangeNotification *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowseNextRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseNextRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSENEXTREQUEST], 0, NULL); +UA_StatusChangeNotification_decodeBinary(const UA_ByteString *src, size_t *offset, UA_StatusChangeNotification *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION], NULL); } -/* CreateSubscriptionRequest */ +/* NodeAttributesMask */ +static UA_INLINE size_t +UA_NodeAttributesMask_calcSizeBinary(const UA_NodeAttributesMask *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK]); +} static UA_INLINE UA_StatusCode -UA_CreateSubscriptionRequest_encodeBinary(const UA_CreateSubscriptionRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST], bufPos, bufEnd, NULL, NULL); +UA_NodeAttributesMask_encodeBinary(const UA_NodeAttributesMask *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CreateSubscriptionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateSubscriptionRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST], 0, NULL); +UA_NodeAttributesMask_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NodeAttributesMask *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODEATTRIBUTESMASK], NULL); } -/* VariableTypeAttributes */ +/* EventFilterResult */ +static UA_INLINE size_t +UA_EventFilterResult_calcSizeBinary(const UA_EventFilterResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT]); +} static UA_INLINE UA_StatusCode -UA_VariableTypeAttributes_encodeBinary(const UA_VariableTypeAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_EventFilterResult_encodeBinary(const UA_EventFilterResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_VariableTypeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_VariableTypeAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES], 0, NULL); +UA_EventFilterResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EventFilterResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT], NULL); } -/* BrowsePathResult */ +/* MonitoredItemCreateRequest */ +static UA_INLINE size_t +UA_MonitoredItemCreateRequest_calcSizeBinary(const UA_MonitoredItemCreateRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST]); +} static UA_INLINE UA_StatusCode -UA_BrowsePathResult_encodeBinary(const UA_BrowsePathResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT], bufPos, bufEnd, NULL, NULL); +UA_MonitoredItemCreateRequest_encodeBinary(const UA_MonitoredItemCreateRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowsePathResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowsePathResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT], 0, NULL); +UA_MonitoredItemCreateRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemCreateRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST], NULL); } -/* ModifySubscriptionResponse */ +/* Range */ +static UA_INLINE size_t +UA_Range_calcSizeBinary(const UA_Range *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_RANGE]); +} static UA_INLINE UA_StatusCode -UA_ModifySubscriptionResponse_encodeBinary(const UA_ModifySubscriptionResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_Range_encodeBinary(const UA_Range *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_RANGE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ModifySubscriptionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModifySubscriptionResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE], 0, NULL); +UA_Range_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Range *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_RANGE], NULL); } -/* RedundantServerDataType */ +/* DataChangeNotification */ +static UA_INLINE size_t +UA_DataChangeNotification_calcSizeBinary(const UA_DataChangeNotification *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]); +} static UA_INLINE UA_StatusCode -UA_RedundantServerDataType_encodeBinary(const UA_RedundantServerDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REDUNDANTSERVERDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_DataChangeNotification_encodeBinary(const UA_DataChangeNotification *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RedundantServerDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RedundantServerDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REDUNDANTSERVERDATATYPE], 0, NULL); +UA_DataChangeNotification_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataChangeNotification *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION], NULL); } -/* RegisterNodesResponse */ +/* Argument */ +static UA_INLINE size_t +UA_Argument_calcSizeBinary(const UA_Argument *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ARGUMENT]); +} static UA_INLINE UA_StatusCode -UA_RegisterNodesResponse_encodeBinary(const UA_RegisterNodesResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_Argument_encodeBinary(const UA_Argument *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ARGUMENT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RegisterNodesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterNodesResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE], 0, NULL); +UA_Argument_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Argument *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ARGUMENT], NULL); } -/* CloseSessionRequest */ +/* ChannelSecurityToken */ +static UA_INLINE size_t +UA_ChannelSecurityToken_calcSizeBinary(const UA_ChannelSecurityToken *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN]); +} static UA_INLINE UA_StatusCode -UA_CloseSessionRequest_encodeBinary(const UA_CloseSessionRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST], bufPos, bufEnd, NULL, NULL); +UA_ChannelSecurityToken_encodeBinary(const UA_ChannelSecurityToken *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CloseSessionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CloseSessionRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST], 0, NULL); +UA_ChannelSecurityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ChannelSecurityToken *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CHANNELSECURITYTOKEN], NULL); } -/* ModifyMonitoredItemsResponse */ +/* ServerState */ +static UA_INLINE size_t +UA_ServerState_calcSizeBinary(const UA_ServerState *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SERVERSTATE]); +} static UA_INLINE UA_StatusCode -UA_ModifyMonitoredItemsResponse_encodeBinary(const UA_ModifyMonitoredItemsResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_ServerState_encodeBinary(const UA_ServerState *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVERSTATE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ModifyMonitoredItemsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModifyMonitoredItemsResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE], 0, NULL); +UA_ServerState_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServerState *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVERSTATE], NULL); } -/* ModifySubscriptionRequest */ +/* EventNotificationList */ +static UA_INLINE size_t +UA_EventNotificationList_calcSizeBinary(const UA_EventNotificationList *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]); +} static UA_INLINE UA_StatusCode -UA_ModifySubscriptionRequest_encodeBinary(const UA_ModifySubscriptionRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST], bufPos, bufEnd, NULL, NULL); +UA_EventNotificationList_encodeBinary(const UA_EventNotificationList *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ModifySubscriptionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModifySubscriptionRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODIFYSUBSCRIPTIONREQUEST], 0, NULL); +UA_EventNotificationList_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EventNotificationList *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST], NULL); } -/* ServerDiagnosticsSummaryDataType */ +/* AnonymousIdentityToken */ +static UA_INLINE size_t +UA_AnonymousIdentityToken_calcSizeBinary(const UA_AnonymousIdentityToken *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]); +} static UA_INLINE UA_StatusCode -UA_ServerDiagnosticsSummaryDataType_encodeBinary(const UA_ServerDiagnosticsSummaryDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_AnonymousIdentityToken_encodeBinary(const UA_AnonymousIdentityToken *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ServerDiagnosticsSummaryDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServerDiagnosticsSummaryDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE], 0, NULL); +UA_AnonymousIdentityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AnonymousIdentityToken *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN], NULL); } -/* UserTokenPolicy */ +/* FilterOperator */ +static UA_INLINE size_t +UA_FilterOperator_calcSizeBinary(const UA_FilterOperator *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_FILTEROPERATOR]); +} static UA_INLINE UA_StatusCode -UA_UserTokenPolicy_encodeBinary(const UA_UserTokenPolicy *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_USERTOKENPOLICY], bufPos, bufEnd, NULL, NULL); +UA_FilterOperator_encodeBinary(const UA_FilterOperator *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FILTEROPERATOR], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_UserTokenPolicy_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UserTokenPolicy *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_USERTOKENPOLICY], 0, NULL); +UA_FilterOperator_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FilterOperator *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FILTEROPERATOR], NULL); } -/* ReferenceTypeAttributes */ +/* AggregateFilter */ +static UA_INLINE size_t +UA_AggregateFilter_calcSizeBinary(const UA_AggregateFilter *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_AGGREGATEFILTER]); +} static UA_INLINE UA_StatusCode -UA_ReferenceTypeAttributes_encodeBinary(const UA_ReferenceTypeAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_AggregateFilter_encodeBinary(const UA_AggregateFilter *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_AGGREGATEFILTER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ReferenceTypeAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReferenceTypeAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES], 0, NULL); +UA_AggregateFilter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AggregateFilter *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_AGGREGATEFILTER], NULL); } -/* BrowsePath */ +/* RepublishResponse */ +static UA_INLINE size_t +UA_RepublishResponse_calcSizeBinary(const UA_RepublishResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_BrowsePath_encodeBinary(const UA_BrowsePath *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATH], bufPos, bufEnd, NULL, NULL); +UA_RepublishResponse_encodeBinary(const UA_RepublishResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowsePath_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowsePath *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEPATH], 0, NULL); +UA_RepublishResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RepublishResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE], NULL); } -/* SetMonitoringModeRequest */ +/* DeleteSubscriptionsResponse */ +static UA_INLINE size_t +UA_DeleteSubscriptionsResponse_calcSizeBinary(const UA_DeleteSubscriptionsResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_SetMonitoringModeRequest_encodeBinary(const UA_SetMonitoringModeRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], bufPos, bufEnd, NULL, NULL); +UA_DeleteSubscriptionsResponse_encodeBinary(const UA_DeleteSubscriptionsResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SetMonitoringModeRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetMonitoringModeRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], 0, NULL); +UA_DeleteSubscriptionsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteSubscriptionsResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE], NULL); } -/* UnregisterNodesResponse */ +/* RegisterNodesRequest */ +static UA_INLINE size_t +UA_RegisterNodesRequest_calcSizeBinary(const UA_RegisterNodesRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST]); +} static UA_INLINE UA_StatusCode -UA_UnregisterNodesResponse_encodeBinary(const UA_UnregisterNodesResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_RegisterNodesRequest_encodeBinary(const UA_RegisterNodesRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_UnregisterNodesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UnregisterNodesResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UNREGISTERNODESRESPONSE], 0, NULL); +UA_RegisterNodesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterNodesRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERNODESREQUEST], NULL); } -/* WriteRequest */ +/* MethodAttributes */ +static UA_INLINE size_t +UA_MethodAttributes_calcSizeBinary(const UA_MethodAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_METHODATTRIBUTES]); +} static UA_INLINE UA_StatusCode -UA_WriteRequest_encodeBinary(const UA_WriteRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_WRITEREQUEST], bufPos, bufEnd, NULL, NULL); +UA_MethodAttributes_encodeBinary(const UA_MethodAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_METHODATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_WriteRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_WriteRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_WRITEREQUEST], 0, NULL); +UA_MethodAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MethodAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_METHODATTRIBUTES], NULL); } -/* ObjectAttributes */ +/* UserNameIdentityToken */ +static UA_INLINE size_t +UA_UserNameIdentityToken_calcSizeBinary(const UA_UserNameIdentityToken *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]); +} static UA_INLINE UA_StatusCode -UA_ObjectAttributes_encodeBinary(const UA_ObjectAttributes *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], bufPos, bufEnd, NULL, NULL); +UA_UserNameIdentityToken_encodeBinary(const UA_UserNameIdentityToken *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ObjectAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ObjectAttributes *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], 0, NULL); +UA_UserNameIdentityToken_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UserNameIdentityToken *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN], NULL); } -/* BrowseResultMask */ +/* UnregisterNodesRequest */ +static UA_INLINE size_t +UA_UnregisterNodesRequest_calcSizeBinary(const UA_UnregisterNodesRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST]); +} static UA_INLINE UA_StatusCode -UA_BrowseResultMask_encodeBinary(const UA_BrowseResultMask *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESULTMASK], bufPos, bufEnd, NULL, NULL); +UA_UnregisterNodesRequest_encodeBinary(const UA_UnregisterNodesRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowseResultMask_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseResultMask *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSERESULTMASK], 0, NULL); +UA_UnregisterNodesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_UnregisterNodesRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_UNREGISTERNODESREQUEST], NULL); } -/* BrowseDescription */ +/* OpenSecureChannelResponse */ +static UA_INLINE size_t +UA_OpenSecureChannelResponse_calcSizeBinary(const UA_OpenSecureChannelResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_BrowseDescription_encodeBinary(const UA_BrowseDescription *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION], bufPos, bufEnd, NULL, NULL); +UA_OpenSecureChannelResponse_encodeBinary(const UA_OpenSecureChannelResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowseDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseDescription *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION], 0, NULL); +UA_OpenSecureChannelResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_OpenSecureChannelResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE], NULL); } -/* SetTriggeringRequest */ +/* SetTriggeringResponse */ +static UA_INLINE size_t +UA_SetTriggeringResponse_calcSizeBinary(const UA_SetTriggeringResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_SetTriggeringRequest_encodeBinary(const UA_SetTriggeringRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST], bufPos, bufEnd, NULL, NULL); +UA_SetTriggeringResponse_encodeBinary(const UA_SetTriggeringResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SetTriggeringRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetTriggeringRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST], 0, NULL); +UA_SetTriggeringResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetTriggeringResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE], NULL); } -/* SessionSecurityDiagnosticsDataType */ +/* SimpleAttributeOperand */ +static UA_INLINE size_t +UA_SimpleAttributeOperand_calcSizeBinary(const UA_SimpleAttributeOperand *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND]); +} static UA_INLINE UA_StatusCode -UA_SessionSecurityDiagnosticsDataType_encodeBinary(const UA_SessionSecurityDiagnosticsDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_SimpleAttributeOperand_encodeBinary(const UA_SimpleAttributeOperand *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SessionSecurityDiagnosticsDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SessionSecurityDiagnosticsDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE], 0, NULL); +UA_SimpleAttributeOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SimpleAttributeOperand *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SIMPLEATTRIBUTEOPERAND], NULL); } /* RepublishRequest */ +static UA_INLINE size_t +UA_RepublishRequest_calcSizeBinary(const UA_RepublishRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST]); +} static UA_INLINE UA_StatusCode -UA_RepublishRequest_encodeBinary(const UA_RepublishRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST], bufPos, bufEnd, NULL, NULL); +UA_RepublishRequest_encodeBinary(const UA_RepublishRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_RepublishRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RepublishRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REPUBLISHREQUEST], NULL); } -/* GetEndpointsRequest */ -static UA_INLINE UA_StatusCode -UA_GetEndpointsRequest_encodeBinary(const UA_GetEndpointsRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_GetEndpointsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_GetEndpointsRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST], 0, NULL); +/* RegisterNodesResponse */ +static UA_INLINE size_t +UA_RegisterNodesResponse_calcSizeBinary(const UA_RegisterNodesResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE]); } - -/* PublishRequest */ static UA_INLINE UA_StatusCode -UA_PublishRequest_encodeBinary(const UA_PublishRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_PUBLISHREQUEST], bufPos, bufEnd, NULL, NULL); +UA_RegisterNodesResponse_encodeBinary(const UA_RegisterNodesResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_PublishRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_PublishRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_PUBLISHREQUEST], 0, NULL); +UA_RegisterNodesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterNodesResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERNODESRESPONSE], NULL); } -/* DeleteSubscriptionsResponse */ -static UA_INLINE UA_StatusCode -UA_DeleteSubscriptionsResponse_encodeBinary(const UA_DeleteSubscriptionsResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_DeleteSubscriptionsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteSubscriptionsResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSRESPONSE], 0, NULL); +/* ModifyMonitoredItemsResponse */ +static UA_INLINE size_t +UA_ModifyMonitoredItemsResponse_calcSizeBinary(const UA_ModifyMonitoredItemsResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE]); } - -/* AddNodesResponse */ static UA_INLINE UA_StatusCode -UA_AddNodesResponse_encodeBinary(const UA_AddNodesResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_ModifyMonitoredItemsResponse_encodeBinary(const UA_ModifyMonitoredItemsResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AddNodesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddNodesResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE], 0, NULL); +UA_ModifyMonitoredItemsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModifyMonitoredItemsResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE], NULL); } -/* DataChangeNotification */ -static UA_INLINE UA_StatusCode -UA_DataChangeNotification_encodeBinary(const UA_DataChangeNotification *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_DataChangeNotification_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataChangeNotification *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION], 0, NULL); +/* DeleteSubscriptionsRequest */ +static UA_INLINE size_t +UA_DeleteSubscriptionsRequest_calcSizeBinary(const UA_DeleteSubscriptionsRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST]); } - -/* CloseSecureChannelResponse */ static UA_INLINE UA_StatusCode -UA_CloseSecureChannelResponse_encodeBinary(const UA_CloseSecureChannelResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_DeleteSubscriptionsRequest_encodeBinary(const UA_DeleteSubscriptionsRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CloseSecureChannelResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CloseSecureChannelResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELRESPONSE], 0, NULL); +UA_DeleteSubscriptionsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteSubscriptionsRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETESUBSCRIPTIONSREQUEST], NULL); } -/* ModifyMonitoredItemsRequest */ -static UA_INLINE UA_StatusCode -UA_ModifyMonitoredItemsRequest_encodeBinary(const UA_ModifyMonitoredItemsRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_ModifyMonitoredItemsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModifyMonitoredItemsRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST], 0, NULL); +/* RedundancySupport */ +static UA_INLINE size_t +UA_RedundancySupport_calcSizeBinary(const UA_RedundancySupport *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); } - -/* SetMonitoringModeResponse */ static UA_INLINE UA_StatusCode -UA_SetMonitoringModeResponse_encodeBinary(const UA_SetMonitoringModeResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE], bufPos, bufEnd, NULL, NULL); +UA_RedundancySupport_encodeBinary(const UA_RedundancySupport *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SetMonitoringModeResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetMonitoringModeResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE], 0, NULL); +UA_RedundancySupport_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RedundancySupport *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT], NULL); } -/* FindServersRequest */ -static UA_INLINE UA_StatusCode -UA_FindServersRequest_encodeBinary(const UA_FindServersRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_FindServersRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FindServersRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST], 0, NULL); +/* BrowsePath */ +static UA_INLINE size_t +UA_BrowsePath_calcSizeBinary(const UA_BrowsePath *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATH]); } - -/* ReferenceDescription */ static UA_INLINE UA_StatusCode -UA_ReferenceDescription_encodeBinary(const UA_ReferenceDescription *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION], bufPos, bufEnd, NULL, NULL); +UA_BrowsePath_encodeBinary(const UA_BrowsePath *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATH], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ReferenceDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReferenceDescription *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION], 0, NULL); +UA_BrowsePath_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowsePath *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEPATH], NULL); } -/* SetPublishingModeResponse */ -static UA_INLINE UA_StatusCode -UA_SetPublishingModeResponse_encodeBinary(const UA_SetPublishingModeResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_SetPublishingModeResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetPublishingModeResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE], 0, NULL); +/* ObjectAttributes */ +static UA_INLINE size_t +UA_ObjectAttributes_calcSizeBinary(const UA_ObjectAttributes *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES]); } - -/* ContentFilterResult */ static UA_INLINE UA_StatusCode -UA_ContentFilterResult_encodeBinary(const UA_ContentFilterResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT], bufPos, bufEnd, NULL, NULL); +UA_ObjectAttributes_encodeBinary(const UA_ObjectAttributes *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ContentFilterResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ContentFilterResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERRESULT], 0, NULL); +UA_ObjectAttributes_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ObjectAttributes *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], NULL); } -/* RegisterServerResponse */ -static UA_INLINE UA_StatusCode -UA_RegisterServerResponse_encodeBinary(const UA_RegisterServerResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_RegisterServerResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterServerResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE], 0, NULL); +/* PublishRequest */ +static UA_INLINE size_t +UA_PublishRequest_calcSizeBinary(const UA_PublishRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_PUBLISHREQUEST]); } - -/* AddReferencesItem */ static UA_INLINE UA_StatusCode -UA_AddReferencesItem_encodeBinary(const UA_AddReferencesItem *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM], bufPos, bufEnd, NULL, NULL); +UA_PublishRequest_encodeBinary(const UA_PublishRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_PUBLISHREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AddReferencesItem_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddReferencesItem *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM], 0, NULL); +UA_PublishRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_PublishRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_PUBLISHREQUEST], NULL); } -/* QueryDataDescription */ +/* FindServersRequest */ +static UA_INLINE size_t +UA_FindServersRequest_calcSizeBinary(const UA_FindServersRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST]); +} static UA_INLINE UA_StatusCode -UA_QueryDataDescription_encodeBinary(const UA_QueryDataDescription *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION], bufPos, bufEnd, NULL, NULL); +UA_FindServersRequest_encodeBinary(const UA_FindServersRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_QueryDataDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_QueryDataDescription *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_QUERYDATADESCRIPTION], 0, NULL); +UA_FindServersRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FindServersRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST], NULL); } -/* CreateSubscriptionResponse */ +/* FindServersOnNetworkResponse */ +static UA_INLINE size_t +UA_FindServersOnNetworkResponse_calcSizeBinary(const UA_FindServersOnNetworkResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_CreateSubscriptionResponse_encodeBinary(const UA_CreateSubscriptionResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_FindServersOnNetworkResponse_encodeBinary(const UA_FindServersOnNetworkResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CreateSubscriptionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateSubscriptionResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONRESPONSE], 0, NULL); +UA_FindServersOnNetworkResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FindServersOnNetworkResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE], NULL); } -/* NetworkGroupDataType */ +/* ReferenceDescription */ +static UA_INLINE size_t +UA_ReferenceDescription_calcSizeBinary(const UA_ReferenceDescription *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); +} static UA_INLINE UA_StatusCode -UA_NetworkGroupDataType_encodeBinary(const UA_NetworkGroupDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NETWORKGROUPDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_ReferenceDescription_encodeBinary(const UA_ReferenceDescription *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_NetworkGroupDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NetworkGroupDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NETWORKGROUPDATATYPE], 0, NULL); +UA_ReferenceDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReferenceDescription *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION], NULL); } -/* DeleteReferencesResponse */ +/* CreateSubscriptionRequest */ +static UA_INLINE size_t +UA_CreateSubscriptionRequest_calcSizeBinary(const UA_CreateSubscriptionRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST]); +} static UA_INLINE UA_StatusCode -UA_DeleteReferencesResponse_encodeBinary(const UA_DeleteReferencesResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_CreateSubscriptionRequest_encodeBinary(const UA_CreateSubscriptionRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeleteReferencesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteReferencesResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESRESPONSE], 0, NULL); +UA_CreateSubscriptionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateSubscriptionRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATESUBSCRIPTIONREQUEST], NULL); } -/* CreateMonitoredItemsResponse */ +/* FindServersOnNetworkRequest */ +static UA_INLINE size_t +UA_FindServersOnNetworkRequest_calcSizeBinary(const UA_FindServersOnNetworkRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST]); +} static UA_INLINE UA_StatusCode -UA_CreateMonitoredItemsResponse_encodeBinary(const UA_CreateMonitoredItemsResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_FindServersOnNetworkRequest_encodeBinary(const UA_FindServersOnNetworkRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CreateMonitoredItemsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateMonitoredItemsResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSRESPONSE], 0, NULL); +UA_FindServersOnNetworkRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FindServersOnNetworkRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKREQUEST], NULL); } /* CallResponse */ +static UA_INLINE size_t +UA_CallResponse_calcSizeBinary(const UA_CallResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CALLRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_CallResponse_encodeBinary(const UA_CallResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CALLRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_CallResponse_encodeBinary(const UA_CallResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CALLRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_CallResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CallResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CALLRESPONSE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CALLRESPONSE], NULL); } /* DeleteNodesResponse */ +static UA_INLINE size_t +UA_DeleteNodesResponse_calcSizeBinary(const UA_DeleteNodesResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_DeleteNodesResponse_encodeBinary(const UA_DeleteNodesResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_DeleteNodesResponse_encodeBinary(const UA_DeleteNodesResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_DeleteNodesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteNodesResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETENODESRESPONSE], NULL); } -/* RepublishResponse */ +/* ModifyMonitoredItemsRequest */ +static UA_INLINE size_t +UA_ModifyMonitoredItemsRequest_calcSizeBinary(const UA_ModifyMonitoredItemsRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST]); +} static UA_INLINE UA_StatusCode -UA_RepublishResponse_encodeBinary(const UA_RepublishResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_ModifyMonitoredItemsRequest_encodeBinary(const UA_ModifyMonitoredItemsRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RepublishResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RepublishResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REPUBLISHRESPONSE], 0, NULL); +UA_ModifyMonitoredItemsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ModifyMonitoredItemsRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST], NULL); } -/* MonitoredItemCreateRequest */ +/* ServiceFault */ +static UA_INLINE size_t +UA_ServiceFault_calcSizeBinary(const UA_ServiceFault *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SERVICEFAULT]); +} static UA_INLINE UA_StatusCode -UA_MonitoredItemCreateRequest_encodeBinary(const UA_MonitoredItemCreateRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST], bufPos, bufEnd, NULL, NULL); +UA_ServiceFault_encodeBinary(const UA_ServiceFault *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVICEFAULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_MonitoredItemCreateRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MonitoredItemCreateRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATEREQUEST], 0, NULL); +UA_ServiceFault_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServiceFault *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVICEFAULT], NULL); } -/* DeleteReferencesRequest */ +/* PublishResponse */ +static UA_INLINE size_t +UA_PublishResponse_calcSizeBinary(const UA_PublishResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_DeleteReferencesRequest_encodeBinary(const UA_DeleteReferencesRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST], bufPos, bufEnd, NULL, NULL); +UA_PublishResponse_encodeBinary(const UA_PublishResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DeleteReferencesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteReferencesRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST], 0, NULL); +UA_PublishResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_PublishResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE], NULL); } -/* ReadResponse */ +/* CreateMonitoredItemsRequest */ +static UA_INLINE size_t +UA_CreateMonitoredItemsRequest_calcSizeBinary(const UA_CreateMonitoredItemsRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST]); +} static UA_INLINE UA_StatusCode -UA_ReadResponse_encodeBinary(const UA_ReadResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_READRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_CreateMonitoredItemsRequest_encodeBinary(const UA_CreateMonitoredItemsRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ReadResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReadResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_READRESPONSE], 0, NULL); +UA_CreateMonitoredItemsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateMonitoredItemsRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST], NULL); } -/* AddReferencesRequest */ +/* OpenSecureChannelRequest */ +static UA_INLINE size_t +UA_OpenSecureChannelRequest_calcSizeBinary(const UA_OpenSecureChannelRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]); +} static UA_INLINE UA_StatusCode -UA_AddReferencesRequest_encodeBinary(const UA_AddReferencesRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST], bufPos, bufEnd, NULL, NULL); +UA_OpenSecureChannelRequest_encodeBinary(const UA_OpenSecureChannelRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AddReferencesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddReferencesRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST], 0, NULL); +UA_OpenSecureChannelRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_OpenSecureChannelRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST], NULL); } -/* ReadRequest */ +/* CloseSessionRequest */ +static UA_INLINE size_t +UA_CloseSessionRequest_calcSizeBinary(const UA_CloseSessionRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]); +} static UA_INLINE UA_StatusCode -UA_ReadRequest_encodeBinary(const UA_ReadRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_READREQUEST], bufPos, bufEnd, NULL, NULL); +UA_CloseSessionRequest_encodeBinary(const UA_CloseSessionRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ReadRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReadRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_READREQUEST], 0, NULL); +UA_CloseSessionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CloseSessionRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST], NULL); } -/* OpenSecureChannelRequest */ +/* SetTriggeringRequest */ +static UA_INLINE size_t +UA_SetTriggeringRequest_calcSizeBinary(const UA_SetTriggeringRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST]); +} static UA_INLINE UA_StatusCode -UA_OpenSecureChannelRequest_encodeBinary(const UA_OpenSecureChannelRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST], bufPos, bufEnd, NULL, NULL); +UA_SetTriggeringRequest_encodeBinary(const UA_SetTriggeringRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_OpenSecureChannelRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_OpenSecureChannelRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST], 0, NULL); +UA_SetTriggeringRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SetTriggeringRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST], NULL); } -/* RegisterServer2Response */ +/* BrowseResult */ +static UA_INLINE size_t +UA_BrowseResult_calcSizeBinary(const UA_BrowseResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESULT]); +} static UA_INLINE UA_StatusCode -UA_RegisterServer2Response_encodeBinary(const UA_RegisterServer2Response *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE], bufPos, bufEnd, NULL, NULL); +UA_BrowseResult_encodeBinary(const UA_BrowseResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RegisterServer2Response_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterServer2Response *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE], 0, NULL); +UA_BrowseResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSERESULT], NULL); } -/* AddNodesItem */ +/* AddReferencesRequest */ +static UA_INLINE size_t +UA_AddReferencesRequest_calcSizeBinary(const UA_AddReferencesRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST]); +} static UA_INLINE UA_StatusCode -UA_AddNodesItem_encodeBinary(const UA_AddNodesItem *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESITEM], bufPos, bufEnd, NULL, NULL); +UA_AddReferencesRequest_encodeBinary(const UA_AddReferencesRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AddNodesItem_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddNodesItem *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDNODESITEM], 0, NULL); +UA_AddReferencesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddReferencesRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESREQUEST], NULL); } -/* NodeTypeDescription */ +/* AddNodesItem */ +static UA_INLINE size_t +UA_AddNodesItem_calcSizeBinary(const UA_AddNodesItem *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESITEM]); +} static UA_INLINE UA_StatusCode -UA_NodeTypeDescription_encodeBinary(const UA_NodeTypeDescription *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION], bufPos, bufEnd, NULL, NULL); +UA_AddNodesItem_encodeBinary(const UA_AddNodesItem *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESITEM], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_NodeTypeDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NodeTypeDescription *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_NODETYPEDESCRIPTION], 0, NULL); +UA_AddNodesItem_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddNodesItem *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDNODESITEM], NULL); } /* ServerStatusDataType */ +static UA_INLINE size_t +UA_ServerStatusDataType_calcSizeBinary(const UA_ServerStatusDataType *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]); +} static UA_INLINE UA_StatusCode -UA_ServerStatusDataType_encodeBinary(const UA_ServerStatusDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_ServerStatusDataType_encodeBinary(const UA_ServerStatusDataType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_ServerStatusDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServerStatusDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE], NULL); } -/* AttributeOperand */ -static UA_INLINE UA_StatusCode -UA_AttributeOperand_encodeBinary(const UA_AttributeOperand *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_AttributeOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AttributeOperand *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND], 0, NULL); +/* BrowseNextResponse */ +static UA_INLINE size_t +UA_BrowseNextResponse_calcSizeBinary(const UA_BrowseNextResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE]); } - -/* AddReferencesResponse */ static UA_INLINE UA_StatusCode -UA_AddReferencesResponse_encodeBinary(const UA_AddReferencesResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_BrowseNextResponse_encodeBinary(const UA_BrowseNextResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AddReferencesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddReferencesResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDREFERENCESRESPONSE], 0, NULL); +UA_BrowseNextResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseNextResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE], NULL); } -/* EventFilterResult */ +/* RegisteredServer */ +static UA_INLINE size_t +UA_RegisteredServer_calcSizeBinary(const UA_RegisteredServer *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REGISTEREDSERVER]); +} static UA_INLINE UA_StatusCode -UA_EventFilterResult_encodeBinary(const UA_EventFilterResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT], bufPos, bufEnd, NULL, NULL); +UA_RegisteredServer_encodeBinary(const UA_RegisteredServer *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTEREDSERVER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_EventFilterResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EventFilterResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EVENTFILTERRESULT], 0, NULL); +UA_RegisteredServer_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisteredServer *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTEREDSERVER], NULL); } -/* TranslateBrowsePathsToNodeIdsResponse */ +/* ApplicationDescription */ +static UA_INLINE size_t +UA_ApplicationDescription_calcSizeBinary(const UA_ApplicationDescription *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); +} static UA_INLINE UA_StatusCode -UA_TranslateBrowsePathsToNodeIdsResponse_encodeBinary(const UA_TranslateBrowsePathsToNodeIdsResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_ApplicationDescription_encodeBinary(const UA_ApplicationDescription *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_TranslateBrowsePathsToNodeIdsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TranslateBrowsePathsToNodeIdsResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE], 0, NULL); +UA_ApplicationDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ApplicationDescription *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION], NULL); } -/* DataChangeFilter */ +/* ReadRequest */ +static UA_INLINE size_t +UA_ReadRequest_calcSizeBinary(const UA_ReadRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_READREQUEST]); +} static UA_INLINE UA_StatusCode -UA_DataChangeFilter_encodeBinary(const UA_DataChangeFilter *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGEFILTER], bufPos, bufEnd, NULL, NULL); +UA_ReadRequest_encodeBinary(const UA_ReadRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_READREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_DataChangeFilter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataChangeFilter *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATACHANGEFILTER], 0, NULL); +UA_ReadRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ReadRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_READREQUEST], NULL); } -/* ContentFilterElement */ +/* ActivateSessionRequest */ +static UA_INLINE size_t +UA_ActivateSessionRequest_calcSizeBinary(const UA_ActivateSessionRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]); +} static UA_INLINE UA_StatusCode -UA_ContentFilterElement_encodeBinary(const UA_ContentFilterElement *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT], bufPos, bufEnd, NULL, NULL); +UA_ActivateSessionRequest_encodeBinary(const UA_ActivateSessionRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ContentFilterElement_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ContentFilterElement *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT], 0, NULL); +UA_ActivateSessionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ActivateSessionRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST], NULL); } -/* TranslateBrowsePathsToNodeIdsRequest */ +/* BrowsePathResult */ +static UA_INLINE size_t +UA_BrowsePathResult_calcSizeBinary(const UA_BrowsePathResult *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT]); +} static UA_INLINE UA_StatusCode -UA_TranslateBrowsePathsToNodeIdsRequest_encodeBinary(const UA_TranslateBrowsePathsToNodeIdsRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST], bufPos, bufEnd, NULL, NULL); +UA_BrowsePathResult_encodeBinary(const UA_BrowsePathResult *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_TranslateBrowsePathsToNodeIdsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TranslateBrowsePathsToNodeIdsRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST], 0, NULL); +UA_BrowsePathResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowsePathResult *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT], NULL); } -/* CloseSessionResponse */ +/* AddNodesRequest */ +static UA_INLINE size_t +UA_AddNodesRequest_calcSizeBinary(const UA_AddNodesRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESREQUEST]); +} static UA_INLINE UA_StatusCode -UA_CloseSessionResponse_encodeBinary(const UA_CloseSessionResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_AddNodesRequest_encodeBinary(const UA_AddNodesRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CloseSessionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CloseSessionResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE], 0, NULL); +UA_AddNodesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddNodesRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDNODESREQUEST], NULL); } -/* ApplicationDescription */ +/* BrowseRequest */ +static UA_INLINE size_t +UA_BrowseRequest_calcSizeBinary(const UA_BrowseRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSEREQUEST]); +} static UA_INLINE UA_StatusCode -UA_ApplicationDescription_encodeBinary(const UA_ApplicationDescription *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION], bufPos, bufEnd, NULL, NULL); +UA_BrowseRequest_encodeBinary(const UA_BrowseRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ApplicationDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ApplicationDescription *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION], 0, NULL); +UA_BrowseRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEREQUEST], NULL); } -/* SessionDiagnosticsDataType */ +/* WriteRequest */ +static UA_INLINE size_t +UA_WriteRequest_calcSizeBinary(const UA_WriteRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_WRITEREQUEST]); +} static UA_INLINE UA_StatusCode -UA_SessionDiagnosticsDataType_encodeBinary(const UA_SessionDiagnosticsDataType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE], bufPos, bufEnd, NULL, NULL); +UA_WriteRequest_encodeBinary(const UA_WriteRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_WRITEREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_SessionDiagnosticsDataType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SessionDiagnosticsDataType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SESSIONDIAGNOSTICSDATATYPE], 0, NULL); +UA_WriteRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_WriteRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_WRITEREQUEST], NULL); } -/* ServiceFault */ +/* AddNodesResponse */ +static UA_INLINE size_t +UA_AddNodesResponse_calcSizeBinary(const UA_AddNodesResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_ServiceFault_encodeBinary(const UA_ServiceFault *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_SERVICEFAULT], bufPos, bufEnd, NULL, NULL); +UA_AddNodesResponse_encodeBinary(const UA_AddNodesResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ServiceFault_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ServiceFault *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_SERVICEFAULT], 0, NULL); +UA_AddNodesResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddNodesResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDNODESRESPONSE], NULL); } -/* RegisteredServer */ +/* RegisterServer2Request */ +static UA_INLINE size_t +UA_RegisterServer2Request_calcSizeBinary(const UA_RegisterServer2Request *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST]); +} static UA_INLINE UA_StatusCode -UA_RegisteredServer_encodeBinary(const UA_RegisteredServer *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTEREDSERVER], bufPos, bufEnd, NULL, NULL); +UA_RegisterServer2Request_encodeBinary(const UA_RegisterServer2Request *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RegisteredServer_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisteredServer *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTEREDSERVER], 0, NULL); +UA_RegisterServer2Request_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterServer2Request *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST], NULL); } -/* AggregateFilter */ +/* AttributeOperand */ +static UA_INLINE size_t +UA_AttributeOperand_calcSizeBinary(const UA_AttributeOperand *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]); +} static UA_INLINE UA_StatusCode -UA_AggregateFilter_encodeBinary(const UA_AggregateFilter *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_AGGREGATEFILTER], bufPos, bufEnd, NULL, NULL); +UA_AttributeOperand_encodeBinary(const UA_AttributeOperand *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AggregateFilter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AggregateFilter *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_AGGREGATEFILTER], 0, NULL); +UA_AttributeOperand_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AttributeOperand *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND], NULL); } -/* RegisterServerRequest */ +/* DataChangeFilter */ +static UA_INLINE size_t +UA_DataChangeFilter_calcSizeBinary(const UA_DataChangeFilter *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGEFILTER]); +} static UA_INLINE UA_StatusCode -UA_RegisterServerRequest_encodeBinary(const UA_RegisterServerRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST], bufPos, bufEnd, NULL, NULL); +UA_DataChangeFilter_encodeBinary(const UA_DataChangeFilter *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DATACHANGEFILTER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RegisterServerRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterServerRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST], 0, NULL); +UA_DataChangeFilter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataChangeFilter *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DATACHANGEFILTER], NULL); } /* EndpointDescription */ +static UA_INLINE size_t +UA_EndpointDescription_calcSizeBinary(const UA_EndpointDescription *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); +} static UA_INLINE UA_StatusCode -UA_EndpointDescription_encodeBinary(const UA_EndpointDescription *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], bufPos, bufEnd, NULL, NULL); +UA_EndpointDescription_encodeBinary(const UA_EndpointDescription *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_EndpointDescription_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EndpointDescription *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], NULL); } -/* CreateMonitoredItemsRequest */ -static UA_INLINE UA_StatusCode -UA_CreateMonitoredItemsRequest_encodeBinary(const UA_CreateMonitoredItemsRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_CreateMonitoredItemsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateMonitoredItemsRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATEMONITOREDITEMSREQUEST], 0, NULL); +/* DeleteReferencesRequest */ +static UA_INLINE size_t +UA_DeleteReferencesRequest_calcSizeBinary(const UA_DeleteReferencesRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST]); } - -/* ContentFilter */ static UA_INLINE UA_StatusCode -UA_ContentFilter_encodeBinary(const UA_ContentFilter *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTER], bufPos, bufEnd, NULL, NULL); +UA_DeleteReferencesRequest_encodeBinary(const UA_DeleteReferencesRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_ContentFilter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ContentFilter *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CONTENTFILTER], 0, NULL); +UA_DeleteReferencesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DeleteReferencesRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_DELETEREFERENCESREQUEST], NULL); } -/* QueryFirstResponse */ -static UA_INLINE UA_StatusCode -UA_QueryFirstResponse_encodeBinary(const UA_QueryFirstResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_QueryFirstResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_QueryFirstResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_QUERYFIRSTRESPONSE], 0, NULL); +/* TranslateBrowsePathsToNodeIdsRequest */ +static UA_INLINE size_t +UA_TranslateBrowsePathsToNodeIdsRequest_calcSizeBinary(const UA_TranslateBrowsePathsToNodeIdsRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST]); } - -/* AddNodesRequest */ static UA_INLINE UA_StatusCode -UA_AddNodesRequest_encodeBinary(const UA_AddNodesRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_ADDNODESREQUEST], bufPos, bufEnd, NULL, NULL); +UA_TranslateBrowsePathsToNodeIdsRequest_encodeBinary(const UA_TranslateBrowsePathsToNodeIdsRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_AddNodesRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AddNodesRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_ADDNODESREQUEST], 0, NULL); +UA_TranslateBrowsePathsToNodeIdsRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TranslateBrowsePathsToNodeIdsRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST], NULL); } -/* BrowseRequest */ -static UA_INLINE UA_StatusCode -UA_BrowseRequest_encodeBinary(const UA_BrowseRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSEREQUEST], bufPos, bufEnd, NULL, NULL); -} -static UA_INLINE UA_StatusCode -UA_BrowseRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSEREQUEST], 0, NULL); +/* FindServersResponse */ +static UA_INLINE size_t +UA_FindServersResponse_calcSizeBinary(const UA_FindServersResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); } - -/* BrowseResult */ static UA_INLINE UA_StatusCode -UA_BrowseResult_encodeBinary(const UA_BrowseResult *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESULT], bufPos, bufEnd, NULL, NULL); +UA_FindServersResponse_encodeBinary(const UA_FindServersResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowseResult_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseResult *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSERESULT], 0, NULL); +UA_FindServersResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FindServersResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE], NULL); } -/* RegisterServer2Request */ +/* CreateSessionRequest */ +static UA_INLINE size_t +UA_CreateSessionRequest_calcSizeBinary(const UA_CreateSessionRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]); +} static UA_INLINE UA_StatusCode -UA_RegisterServer2Request_encodeBinary(const UA_RegisterServer2Request *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST], bufPos, bufEnd, NULL, NULL); +UA_CreateSessionRequest_encodeBinary(const UA_CreateSessionRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_RegisterServer2Request_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterServer2Request *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST], 0, NULL); +UA_CreateSessionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateSessionRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST], NULL); } -/* CreateSessionRequest */ +/* ContentFilterElement */ +static UA_INLINE size_t +UA_ContentFilterElement_calcSizeBinary(const UA_ContentFilterElement *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT]); +} static UA_INLINE UA_StatusCode -UA_CreateSessionRequest_encodeBinary(const UA_CreateSessionRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST], bufPos, bufEnd, NULL, NULL); +UA_ContentFilterElement_encodeBinary(const UA_ContentFilterElement *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CreateSessionRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateSessionRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST], 0, NULL); +UA_ContentFilterElement_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ContentFilterElement *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CONTENTFILTERELEMENT], NULL); } -/* EventFilter */ +/* RegisterServerRequest */ +static UA_INLINE size_t +UA_RegisterServerRequest_calcSizeBinary(const UA_RegisterServerRequest *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST]); +} static UA_INLINE UA_StatusCode -UA_EventFilter_encodeBinary(const UA_EventFilter *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EVENTFILTER], bufPos, bufEnd, NULL, NULL); +UA_RegisterServerRequest_encodeBinary(const UA_RegisterServerRequest *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_EventFilter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EventFilter *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EVENTFILTER], 0, NULL); +UA_RegisterServerRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_RegisterServerRequest *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST], NULL); } -/* GetEndpointsResponse */ +/* TranslateBrowsePathsToNodeIdsResponse */ +static UA_INLINE size_t +UA_TranslateBrowsePathsToNodeIdsResponse_calcSizeBinary(const UA_TranslateBrowsePathsToNodeIdsResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_GetEndpointsResponse_encodeBinary(const UA_GetEndpointsResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_TranslateBrowsePathsToNodeIdsResponse_encodeBinary(const UA_TranslateBrowsePathsToNodeIdsResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_GetEndpointsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_GetEndpointsResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE], 0, NULL); +UA_TranslateBrowsePathsToNodeIdsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TranslateBrowsePathsToNodeIdsResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE], NULL); } -/* FindServersResponse */ +/* BrowseResponse */ +static UA_INLINE size_t +UA_BrowseResponse_calcSizeBinary(const UA_BrowseResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESPONSE]); +} static UA_INLINE UA_StatusCode -UA_FindServersResponse_encodeBinary(const UA_FindServersResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_BrowseResponse_encodeBinary(const UA_BrowseResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_FindServersResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_FindServersResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE], 0, NULL); +UA_BrowseResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSERESPONSE], NULL); } -/* BrowseNextResponse */ +/* CreateSessionResponse */ +static UA_INLINE size_t +UA_CreateSessionResponse_calcSizeBinary(const UA_CreateSessionResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_BrowseNextResponse_encodeBinary(const UA_BrowseNextResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_CreateSessionResponse_encodeBinary(const UA_CreateSessionResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowseNextResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseNextResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSENEXTRESPONSE], 0, NULL); +UA_CreateSessionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateSessionResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE], NULL); } -/* BrowseResponse */ +/* ContentFilter */ +static UA_INLINE size_t +UA_ContentFilter_calcSizeBinary(const UA_ContentFilter *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTER]); +} static UA_INLINE UA_StatusCode -UA_BrowseResponse_encodeBinary(const UA_BrowseResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_BROWSERESPONSE], bufPos, bufEnd, NULL, NULL); +UA_ContentFilter_encodeBinary(const UA_ContentFilter *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CONTENTFILTER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_BrowseResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_BrowseResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_BROWSERESPONSE], 0, NULL); +UA_ContentFilter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ContentFilter *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CONTENTFILTER], NULL); } -/* CreateSessionResponse */ +/* GetEndpointsResponse */ +static UA_INLINE size_t +UA_GetEndpointsResponse_calcSizeBinary(const UA_GetEndpointsResponse *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); +} static UA_INLINE UA_StatusCode -UA_CreateSessionResponse_encodeBinary(const UA_CreateSessionResponse *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE], bufPos, bufEnd, NULL, NULL); +UA_GetEndpointsResponse_encodeBinary(const UA_GetEndpointsResponse *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_CreateSessionResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_CreateSessionResponse *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE], 0, NULL); +UA_GetEndpointsResponse_decodeBinary(const UA_ByteString *src, size_t *offset, UA_GetEndpointsResponse *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE], NULL); } -/* QueryFirstRequest */ +/* EventFilter */ +static UA_INLINE size_t +UA_EventFilter_calcSizeBinary(const UA_EventFilter *src) { + return UA_calcSizeBinary(src, &UA_TYPES[UA_TYPES_EVENTFILTER]); +} static UA_INLINE UA_StatusCode -UA_QueryFirstRequest_encodeBinary(const UA_QueryFirstRequest *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST], bufPos, bufEnd, NULL, NULL); +UA_EventFilter_encodeBinary(const UA_EventFilter *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TYPES[UA_TYPES_EVENTFILTER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode -UA_QueryFirstRequest_decodeBinary(const UA_ByteString *src, size_t *offset, UA_QueryFirstRequest *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_QUERYFIRSTREQUEST], 0, NULL); +UA_EventFilter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_EventFilter *dst) { + return UA_decodeBinary(src, offset, dst, &UA_TYPES[UA_TYPES_EVENTFILTER], NULL); } -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_transport_generated.h" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/transport_generated.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/jvoe/open62541/tools/generate_datatypes.py - * on host rigel by user jvoe at 2019-01-04 01:18:40 */ - - -#ifdef __cplusplus -extern "C" { -#endif + * on host rigel by user jvoe at 2019-07-30 11:30:09 */ -#ifdef UA_NO_AMALGAMATION +#ifdef UA_ENABLE_AMALGAMATION #else + #endif +_UA_BEGIN_DECLS + /** * Every type is assigned an index in an array containing the type descriptions. @@ -3174,21 +3944,18 @@ typedef struct { #define UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER 11 -#ifdef __cplusplus -} // extern "C" -#endif + +_UA_END_DECLS -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_transport_generated_handling.h" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/transport_generated_handling.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/jvoe/open62541/tools/generate_datatypes.py - * on host rigel by user jvoe at 2019-01-04 01:18:40 */ + * on host rigel by user jvoe at 2019-07-30 11:30:09 */ -#ifdef __cplusplus -extern "C" { -#endif +_UA_BEGIN_DECLS #if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 # pragma GCC diagnostic push @@ -3215,7 +3982,12 @@ UA_SecureConversationMessageAbortBody_copy(const UA_SecureConversationMessageAbo static UA_INLINE void UA_SecureConversationMessageAbortBody_deleteMembers(UA_SecureConversationMessageAbortBody *p) { - UA_deleteMembers(p, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY]); + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY]); +} + +static UA_INLINE void +UA_SecureConversationMessageAbortBody_clear(UA_SecureConversationMessageAbortBody *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY]); } static UA_INLINE void @@ -3241,7 +4013,12 @@ UA_SecureConversationMessageFooter_copy(const UA_SecureConversationMessageFooter static UA_INLINE void UA_SecureConversationMessageFooter_deleteMembers(UA_SecureConversationMessageFooter *p) { - UA_deleteMembers(p, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER]); + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER]); +} + +static UA_INLINE void +UA_SecureConversationMessageFooter_clear(UA_SecureConversationMessageFooter *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER]); } static UA_INLINE void @@ -3267,7 +4044,12 @@ UA_TcpHelloMessage_copy(const UA_TcpHelloMessage *src, UA_TcpHelloMessage *dst) static UA_INLINE void UA_TcpHelloMessage_deleteMembers(UA_TcpHelloMessage *p) { - UA_deleteMembers(p, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); +} + +static UA_INLINE void +UA_TcpHelloMessage_clear(UA_TcpHelloMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); } static UA_INLINE void @@ -3293,7 +4075,12 @@ UA_TcpErrorMessage_copy(const UA_TcpErrorMessage *src, UA_TcpErrorMessage *dst) static UA_INLINE void UA_TcpErrorMessage_deleteMembers(UA_TcpErrorMessage *p) { - UA_deleteMembers(p, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); +} + +static UA_INLINE void +UA_TcpErrorMessage_clear(UA_TcpErrorMessage *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); } static UA_INLINE void @@ -3319,7 +4106,14 @@ UA_MessageType_copy(const UA_MessageType *src, UA_MessageType *dst) { } static UA_INLINE void -UA_MessageType_deleteMembers(UA_MessageType *p) { } +UA_MessageType_deleteMembers(UA_MessageType *p) { + memset(p, 0, sizeof(UA_MessageType)); +} + +static UA_INLINE void +UA_MessageType_clear(UA_MessageType *p) { + memset(p, 0, sizeof(UA_MessageType)); +} static UA_INLINE void UA_MessageType_delete(UA_MessageType *p) { @@ -3344,7 +4138,12 @@ UA_AsymmetricAlgorithmSecurityHeader_copy(const UA_AsymmetricAlgorithmSecurityHe static UA_INLINE void UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorithmSecurityHeader *p) { - UA_deleteMembers(p, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); +} + +static UA_INLINE void +UA_AsymmetricAlgorithmSecurityHeader_clear(UA_AsymmetricAlgorithmSecurityHeader *p) { + UA_clear(p, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); } static UA_INLINE void @@ -3370,7 +4169,14 @@ UA_TcpAcknowledgeMessage_copy(const UA_TcpAcknowledgeMessage *src, UA_TcpAcknowl } static UA_INLINE void -UA_TcpAcknowledgeMessage_deleteMembers(UA_TcpAcknowledgeMessage *p) { } +UA_TcpAcknowledgeMessage_deleteMembers(UA_TcpAcknowledgeMessage *p) { + memset(p, 0, sizeof(UA_TcpAcknowledgeMessage)); +} + +static UA_INLINE void +UA_TcpAcknowledgeMessage_clear(UA_TcpAcknowledgeMessage *p) { + memset(p, 0, sizeof(UA_TcpAcknowledgeMessage)); +} static UA_INLINE void UA_TcpAcknowledgeMessage_delete(UA_TcpAcknowledgeMessage *p) { @@ -3395,7 +4201,14 @@ UA_SequenceHeader_copy(const UA_SequenceHeader *src, UA_SequenceHeader *dst) { } static UA_INLINE void -UA_SequenceHeader_deleteMembers(UA_SequenceHeader *p) { } +UA_SequenceHeader_deleteMembers(UA_SequenceHeader *p) { + memset(p, 0, sizeof(UA_SequenceHeader)); +} + +static UA_INLINE void +UA_SequenceHeader_clear(UA_SequenceHeader *p) { + memset(p, 0, sizeof(UA_SequenceHeader)); +} static UA_INLINE void UA_SequenceHeader_delete(UA_SequenceHeader *p) { @@ -3420,7 +4233,14 @@ UA_TcpMessageHeader_copy(const UA_TcpMessageHeader *src, UA_TcpMessageHeader *ds } static UA_INLINE void -UA_TcpMessageHeader_deleteMembers(UA_TcpMessageHeader *p) { } +UA_TcpMessageHeader_deleteMembers(UA_TcpMessageHeader *p) { + memset(p, 0, sizeof(UA_TcpMessageHeader)); +} + +static UA_INLINE void +UA_TcpMessageHeader_clear(UA_TcpMessageHeader *p) { + memset(p, 0, sizeof(UA_TcpMessageHeader)); +} static UA_INLINE void UA_TcpMessageHeader_delete(UA_TcpMessageHeader *p) { @@ -3445,7 +4265,14 @@ UA_ChunkType_copy(const UA_ChunkType *src, UA_ChunkType *dst) { } static UA_INLINE void -UA_ChunkType_deleteMembers(UA_ChunkType *p) { } +UA_ChunkType_deleteMembers(UA_ChunkType *p) { + memset(p, 0, sizeof(UA_ChunkType)); +} + +static UA_INLINE void +UA_ChunkType_clear(UA_ChunkType *p) { + memset(p, 0, sizeof(UA_ChunkType)); +} static UA_INLINE void UA_ChunkType_delete(UA_ChunkType *p) { @@ -3470,7 +4297,14 @@ UA_SymmetricAlgorithmSecurityHeader_copy(const UA_SymmetricAlgorithmSecurityHead } static UA_INLINE void -UA_SymmetricAlgorithmSecurityHeader_deleteMembers(UA_SymmetricAlgorithmSecurityHeader *p) { } +UA_SymmetricAlgorithmSecurityHeader_deleteMembers(UA_SymmetricAlgorithmSecurityHeader *p) { + memset(p, 0, sizeof(UA_SymmetricAlgorithmSecurityHeader)); +} + +static UA_INLINE void +UA_SymmetricAlgorithmSecurityHeader_clear(UA_SymmetricAlgorithmSecurityHeader *p) { + memset(p, 0, sizeof(UA_SymmetricAlgorithmSecurityHeader)); +} static UA_INLINE void UA_SymmetricAlgorithmSecurityHeader_delete(UA_SymmetricAlgorithmSecurityHeader *p) { @@ -3495,7 +4329,14 @@ UA_SecureConversationMessageHeader_copy(const UA_SecureConversationMessageHeader } static UA_INLINE void -UA_SecureConversationMessageHeader_deleteMembers(UA_SecureConversationMessageHeader *p) { } +UA_SecureConversationMessageHeader_deleteMembers(UA_SecureConversationMessageHeader *p) { + memset(p, 0, sizeof(UA_SecureConversationMessageHeader)); +} + +static UA_INLINE void +UA_SecureConversationMessageHeader_clear(UA_SecureConversationMessageHeader *p) { + memset(p, 0, sizeof(UA_SecureConversationMessageHeader)); +} static UA_INLINE void UA_SecureConversationMessageHeader_delete(UA_SecureConversationMessageHeader *p) { @@ -3506,135 +4347,186 @@ UA_SecureConversationMessageHeader_delete(UA_SecureConversationMessageHeader *p) # pragma GCC diagnostic pop #endif -#ifdef __cplusplus -} // extern "C" -#endif +_UA_END_DECLS -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_transport_generated_encoding_binary.h" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/transport_generated_encoding_binary.h" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/jvoe/open62541/tools/generate_datatypes.py - * on host rigel by user jvoe at 2019-01-04 01:18:40 */ + * on host rigel by user jvoe at 2019-07-30 11:30:09 */ + +#ifdef UA_ENABLE_AMALGAMATION +#else +#endif + /* SecureConversationMessageAbortBody */ +static UA_INLINE size_t +UA_SecureConversationMessageAbortBody_calcSizeBinary(const UA_SecureConversationMessageAbortBody *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY]); +} static UA_INLINE UA_StatusCode -UA_SecureConversationMessageAbortBody_encodeBinary(const UA_SecureConversationMessageAbortBody *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY], bufPos, bufEnd, NULL, NULL); +UA_SecureConversationMessageAbortBody_encodeBinary(const UA_SecureConversationMessageAbortBody *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_SecureConversationMessageAbortBody_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SecureConversationMessageAbortBody *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY], NULL); } /* SecureConversationMessageFooter */ +static UA_INLINE size_t +UA_SecureConversationMessageFooter_calcSizeBinary(const UA_SecureConversationMessageFooter *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER]); +} static UA_INLINE UA_StatusCode -UA_SecureConversationMessageFooter_encodeBinary(const UA_SecureConversationMessageFooter *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER], bufPos, bufEnd, NULL, NULL); +UA_SecureConversationMessageFooter_encodeBinary(const UA_SecureConversationMessageFooter *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_SecureConversationMessageFooter_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SecureConversationMessageFooter *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER], NULL); } /* TcpHelloMessage */ +static UA_INLINE size_t +UA_TcpHelloMessage_calcSizeBinary(const UA_TcpHelloMessage *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE]); +} static UA_INLINE UA_StatusCode -UA_TcpHelloMessage_encodeBinary(const UA_TcpHelloMessage *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE], bufPos, bufEnd, NULL, NULL); +UA_TcpHelloMessage_encodeBinary(const UA_TcpHelloMessage *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_TcpHelloMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TcpHelloMessage *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPHELLOMESSAGE], NULL); } /* TcpErrorMessage */ +static UA_INLINE size_t +UA_TcpErrorMessage_calcSizeBinary(const UA_TcpErrorMessage *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE]); +} static UA_INLINE UA_StatusCode -UA_TcpErrorMessage_encodeBinary(const UA_TcpErrorMessage *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE], bufPos, bufEnd, NULL, NULL); +UA_TcpErrorMessage_encodeBinary(const UA_TcpErrorMessage *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_TcpErrorMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TcpErrorMessage *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPERRORMESSAGE], NULL); } /* MessageType */ +static UA_INLINE size_t +UA_MessageType_calcSizeBinary(const UA_MessageType *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE]); +} static UA_INLINE UA_StatusCode -UA_MessageType_encodeBinary(const UA_MessageType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE], bufPos, bufEnd, NULL, NULL); +UA_MessageType_encodeBinary(const UA_MessageType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_MessageType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_MessageType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_MESSAGETYPE], NULL); } /* AsymmetricAlgorithmSecurityHeader */ +static UA_INLINE size_t +UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(const UA_AsymmetricAlgorithmSecurityHeader *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER]); +} static UA_INLINE UA_StatusCode -UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(const UA_AsymmetricAlgorithmSecurityHeader *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER], bufPos, bufEnd, NULL, NULL); +UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(const UA_AsymmetricAlgorithmSecurityHeader *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_AsymmetricAlgorithmSecurityHeader *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER], NULL); } /* TcpAcknowledgeMessage */ +static UA_INLINE size_t +UA_TcpAcknowledgeMessage_calcSizeBinary(const UA_TcpAcknowledgeMessage *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE]); +} static UA_INLINE UA_StatusCode -UA_TcpAcknowledgeMessage_encodeBinary(const UA_TcpAcknowledgeMessage *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE], bufPos, bufEnd, NULL, NULL); +UA_TcpAcknowledgeMessage_encodeBinary(const UA_TcpAcknowledgeMessage *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_TcpAcknowledgeMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TcpAcknowledgeMessage *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE], NULL); } /* SequenceHeader */ +static UA_INLINE size_t +UA_SequenceHeader_calcSizeBinary(const UA_SequenceHeader *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER]); +} static UA_INLINE UA_StatusCode -UA_SequenceHeader_encodeBinary(const UA_SequenceHeader *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], bufPos, bufEnd, NULL, NULL); +UA_SequenceHeader_encodeBinary(const UA_SequenceHeader *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_SequenceHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SequenceHeader *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], NULL); } /* TcpMessageHeader */ +static UA_INLINE size_t +UA_TcpMessageHeader_calcSizeBinary(const UA_TcpMessageHeader *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER]); +} static UA_INLINE UA_StatusCode -UA_TcpMessageHeader_encodeBinary(const UA_TcpMessageHeader *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER], bufPos, bufEnd, NULL, NULL); +UA_TcpMessageHeader_encodeBinary(const UA_TcpMessageHeader *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_TcpMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_TcpMessageHeader *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_TCPMESSAGEHEADER], NULL); } /* ChunkType */ +static UA_INLINE size_t +UA_ChunkType_calcSizeBinary(const UA_ChunkType *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE]); +} static UA_INLINE UA_StatusCode -UA_ChunkType_encodeBinary(const UA_ChunkType *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE], bufPos, bufEnd, NULL, NULL); +UA_ChunkType_encodeBinary(const UA_ChunkType *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_ChunkType_decodeBinary(const UA_ByteString *src, size_t *offset, UA_ChunkType *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_CHUNKTYPE], NULL); } /* SymmetricAlgorithmSecurityHeader */ +static UA_INLINE size_t +UA_SymmetricAlgorithmSecurityHeader_calcSizeBinary(const UA_SymmetricAlgorithmSecurityHeader *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SYMMETRICALGORITHMSECURITYHEADER]); +} static UA_INLINE UA_StatusCode -UA_SymmetricAlgorithmSecurityHeader_encodeBinary(const UA_SymmetricAlgorithmSecurityHeader *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SYMMETRICALGORITHMSECURITYHEADER], bufPos, bufEnd, NULL, NULL); +UA_SymmetricAlgorithmSecurityHeader_encodeBinary(const UA_SymmetricAlgorithmSecurityHeader *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SYMMETRICALGORITHMSECURITYHEADER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_SymmetricAlgorithmSecurityHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SymmetricAlgorithmSecurityHeader *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SYMMETRICALGORITHMSECURITYHEADER], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SYMMETRICALGORITHMSECURITYHEADER], NULL); } /* SecureConversationMessageHeader */ +static UA_INLINE size_t +UA_SecureConversationMessageHeader_calcSizeBinary(const UA_SecureConversationMessageHeader *src) { + return UA_calcSizeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER]); +} static UA_INLINE UA_StatusCode -UA_SecureConversationMessageHeader_encodeBinary(const UA_SecureConversationMessageHeader *src, UA_Byte **bufPos, const UA_Byte **bufEnd) { - return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER], bufPos, bufEnd, NULL, NULL); +UA_SecureConversationMessageHeader_encodeBinary(const UA_SecureConversationMessageHeader *src, UA_Byte **bufPos, const UA_Byte *bufEnd) { + return UA_encodeBinary(src, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER], bufPos, &bufEnd, NULL, NULL); } static UA_INLINE UA_StatusCode UA_SecureConversationMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset, UA_SecureConversationMessageHeader *dst) { - return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER], 0, NULL); + return UA_decodeBinary(src, offset, dst, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER], NULL); } /*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_connection_internal.h" ***********************************/ @@ -3643,39 +4535,43 @@ UA_SecureConversationMessageHeader_decodeBinary(const UA_ByteString *src, size_t * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH * Copyright 2017 (c) Florian Palm * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB */ -#ifdef __cplusplus -extern "C" { -#endif +_UA_BEGIN_DECLS + +/* Process the remote configuration in the HEL/ACK handshake. The connection + * config is initialized with the local settings. */ +UA_StatusCode +UA_Connection_processHELACK(UA_Connection *connection, + const UA_ConnectionConfig *localConfig, + const UA_ConnectionConfig *remoteConfig); /* The application can be the client or the server */ typedef UA_StatusCode (*UA_Connection_processChunk)(void *application, UA_Connection *connection, UA_ByteString *chunk); -/* The network layer may receive chopped up messages since TCP is a streaming - * protocol. This method calls the processChunk callback on all full chunks that - * were received. Dangling half-complete chunks are buffered in the connection - * and considered for the next received packet. +/* The network layer may receive several chunks in one packet since TCP is a + * streaming protocol. The last chunk in the packet may be only partial. This + * method calls the processChunk callback on all full chunks that were received. + * The last incomplete chunk is buffered in the connection for the next + * iteration. * - * If an entire chunk is received, it is forwarded directly. But the memory - * needs to be freed with the networklayer-specific mechanism. If a half message - * is received, we copy it into a local buffer. Then, the stack-specific free - * needs to be used. + * The packet itself is not edited in this method. But possibly in the callback + * that is executed on complete chunks. * * @param connection The connection * @param application The client or server application * @param processCallback The function pointer for processing each chunk * @param packet The received packet. * @return Returns UA_STATUSCODE_GOOD or an error code. When an error occurs, - * the ingoing message and the current buffer in the connection are + * the current buffer in the connection are * freed. */ UA_StatusCode UA_Connection_processChunks(UA_Connection *connection, void *application, @@ -3696,6 +4592,10 @@ UA_Connection_receiveChunksBlocking(UA_Connection *connection, void *application UA_Connection_processChunk processCallback, UA_UInt32 timeout); +UA_StatusCode +UA_Connection_receiveChunksNonBlocking(UA_Connection *connection, void *application, + UA_Connection_processChunk processCallback); + /* When a fatal error occurs the Server shall send an Error Message to the * Client and close the socket. When a Client encounters one of these errors, it * shall also close the socket but does not send an Error Message. After the @@ -3709,9 +4609,7 @@ void UA_Connection_detachSecureChannel(UA_Connection *connection); void UA_Connection_attachSecureChannel(UA_Connection *connection, UA_SecureChannel *channel); -#ifdef __cplusplus -} // extern "C" -#endif +_UA_END_DECLS /*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_securechannel.h" ***********************************/ @@ -3720,18 +4618,17 @@ void UA_Connection_attachSecureChannel(UA_Connection *connection, * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Florian Palm * Copyright 2017 (c) Stefan Profanter, fortiss GmbH * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB */ -#ifdef __cplusplus -extern "C" { -#endif +_UA_BEGIN_DECLS + #define UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH 12 #define UA_SECURE_MESSAGE_HEADER_LENGTH 24 @@ -3754,17 +4651,25 @@ typedef struct UA_SessionHeader { } UA_SessionHeader; /* For chunked requests */ -struct ChunkPayload { - SIMPLEQ_ENTRY(ChunkPayload) pointers; +typedef struct UA_ChunkPayload { + SIMPLEQ_ENTRY(UA_ChunkPayload) pointers; UA_ByteString bytes; -}; - -struct MessageEntry { - LIST_ENTRY(MessageEntry) pointers; + UA_Boolean copied; /* Do the bytes point to a buffer from the network or was + memory allocated for the chunk separately */ +} UA_ChunkPayload; + +/* Receieved messages. Process them only in order. The Chunk payload has all + * headers and the padding stripped out. The payload begins at the + * ExtensionObject prefix.*/ +typedef struct UA_Message { + TAILQ_ENTRY(UA_Message) pointers; UA_UInt32 requestId; - SIMPLEQ_HEAD(chunkpayload_pointerlist, ChunkPayload) chunkPayload; - size_t chunkPayloadSize; -}; + UA_MessageType messageType; + SIMPLEQ_HEAD(pp, UA_ChunkPayload) chunkPayloads; + size_t chunkPayloadsSize; /* No of chunks received so far */ + size_t messageSize; /* Total length of the chunks received so far */ + UA_Boolean final; /* All chunks for the message have been received */ +} UA_Message; typedef enum { UA_SECURECHANNELSTATE_FRESH, @@ -3772,10 +4677,11 @@ typedef enum { UA_SECURECHANNELSTATE_CLOSED } UA_SecureChannelState; +typedef TAILQ_HEAD(UA_MessageQueue, UA_Message) UA_MessageQueue; + struct UA_SecureChannel { UA_SecureChannelState state; UA_MessageSecurityMode securityMode; - UA_ChannelSecurityToken securityToken; /* the channelId is contained in the securityToken */ /* We use three tokens because when switching tokens the client is allowed to accept * messages with the old token for up to 25% of the lifetime after the token would have timed out. * For messages that are sent, the new token is already used, which is contained in the securityToken @@ -3783,6 +4689,7 @@ struct UA_SecureChannel { * revolved into the securityToken variable. This could be done with two variables, but would require * greater changes to the current code. This could be done in the future after the client and networking * structure has been reworked, which would make this easier to implement. */ + UA_ChannelSecurityToken securityToken; /* the channelId is contained in the securityToken */ UA_ChannelSecurityToken nextSecurityToken; UA_ChannelSecurityToken previousSecurityToken; @@ -3802,15 +4709,23 @@ struct UA_SecureChannel { UA_UInt32 receiveSequenceNumber; UA_UInt32 sendSequenceNumber; - LIST_HEAD(session_pointerlist, UA_SessionHeader) sessions; - LIST_HEAD(chunk_pointerlist, MessageEntry) chunks; + LIST_HEAD(, UA_SessionHeader) sessions; + UA_MessageQueue messages; }; +void UA_SecureChannel_init(UA_SecureChannel *channel); + +void UA_SecureChannel_close(UA_SecureChannel *channel); + UA_StatusCode -UA_SecureChannel_init(UA_SecureChannel *channel, - const UA_SecurityPolicy *securityPolicy, - const UA_ByteString *remoteCertificate); -void UA_SecureChannel_deleteMembersCleanup(UA_SecureChannel *channel); +UA_SecureChannel_setSecurityPolicy(UA_SecureChannel *channel, + const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *remoteCertificate); + +/* Remove (partially) received unprocessed messages */ +void UA_SecureChannel_deleteMessages(UA_SecureChannel *channel); + +void UA_SecureChannel_deleteMembers(UA_SecureChannel *channel); /* Generates new keys and sets them in the channel context */ UA_StatusCode @@ -3884,32 +4799,40 @@ void UA_MessageContext_abort(UA_MessageContext *mc); /** - * Process Received Chunks - * ----------------------- */ + * Receive Message + * --------------- */ -typedef UA_StatusCode +/* Decrypt a chunk and add it to the message. Create a new message if necessary. */ +UA_StatusCode +UA_SecureChannel_decryptAddChunk(UA_SecureChannel *channel, const UA_ByteString *chunk, + UA_Boolean allowPreviousToken); + +/* The network buffer is about to be cleared. Copy all chunks that point into + * the network buffer into dedicated memory. */ +UA_StatusCode +UA_SecureChannel_persistIncompleteMessages(UA_SecureChannel *channel); + +typedef void (UA_ProcessMessageCallback)(void *application, UA_SecureChannel *channel, UA_MessageType messageType, UA_UInt32 requestId, const UA_ByteString *message); -/* Process a single chunk. This also decrypts the chunk if required. The - * callback function is called with the complete message body if the message is - * complete. +/* Process received complete messages in-order. The callback function is called + * with the complete message body if the message is complete. The message is + * removed afterwards. * * Symmetric callback is ERR, MSG, CLO only * Asymmetric callback is OPN only * * @param channel the channel the chunks were received on. - * @param chunks the memory region where the chunks are stored. + * @param application data pointer to application specific data that gets passed + * on to the callback function. * @param callback the callback function that gets called with the complete * message body, once a final chunk is processed. - * @param application data pointer to application specific data that gets passed - * on to the callback function. */ + * @return Returns if an irrecoverable error occured. Maybe close the channel. */ UA_StatusCode -UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, - UA_ProcessMessageCallback callback, - void *application, - UA_Boolean allowPreviousToken); +UA_SecureChannel_processCompleteMessages(UA_SecureChannel *channel, void *application, + UA_ProcessMessageCallback callback); /** * Log Helper @@ -3926,7 +4849,7 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, #define UA_LOG_TRACE_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \ UA_LOG_TRACE(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \ "Connection %i | SecureChannel %i | " MSG "%.0s", \ - ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \ + ((CHANNEL)->connection ? (int)((CHANNEL)->connection->sockfd) : 0), \ (CHANNEL)->securityToken.channelId, __VA_ARGS__) #define UA_LOG_TRACE_CHANNEL(LOGGER, CHANNEL, ...) \ @@ -3935,7 +4858,7 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, #define UA_LOG_DEBUG_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \ UA_LOG_DEBUG(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \ "Connection %i | SecureChannel %i | " MSG "%.0s", \ - ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \ + ((CHANNEL)->connection ? (int)((CHANNEL)->connection->sockfd) : 0), \ (CHANNEL)->securityToken.channelId, __VA_ARGS__) #define UA_LOG_DEBUG_CHANNEL(LOGGER, CHANNEL, ...) \ @@ -3944,7 +4867,7 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, #define UA_LOG_INFO_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \ UA_LOG_INFO(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \ "Connection %i | SecureChannel %i | " MSG "%.0s", \ - ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \ + ((CHANNEL)->connection ? (int)((CHANNEL)->connection->sockfd) : 0), \ (CHANNEL)->securityToken.channelId, __VA_ARGS__) #define UA_LOG_INFO_CHANNEL(LOGGER, CHANNEL, ...) \ @@ -3953,7 +4876,7 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, #define UA_LOG_WARNING_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \ UA_LOG_WARNING(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \ "Connection %i | SecureChannel %i | " MSG "%.0s", \ - ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \ + ((CHANNEL)->connection ? (int)((CHANNEL)->connection->sockfd) : 0), \ (CHANNEL)->securityToken.channelId, __VA_ARGS__) #define UA_LOG_WARNING_CHANNEL(LOGGER, CHANNEL, ...) \ @@ -3962,7 +4885,7 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, #define UA_LOG_ERROR_CHANNEL_INTERNAL(LOGGER, CHANNEL, MSG, ...) \ UA_LOG_ERROR(LOGGER, UA_LOGCATEGORY_SECURECHANNEL, \ "Connection %i | SecureChannel %i | " MSG "%.0s", \ - ((CHANNEL)->connection ? (CHANNEL)->connection->sockfd : 0), \ + ((CHANNEL)->connection ? (int)((CHANNEL)->connection->sockfd) : 0), \ (CHANNEL)->securityToken.channelId, __VA_ARGS__) #define UA_LOG_ERROR_CHANNEL(LOGGER, CHANNEL, ...) \ @@ -3977,98 +4900,371 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, #define UA_LOG_FATAL_CHANNEL(LOGGER, CHANNEL, ...) \ UA_MACRO_EXPAND(UA_LOG_FATAL_CHANNEL_INTERNAL(LOGGER, CHANNEL, __VA_ARGS__, "")) -#ifdef __cplusplus -} // extern "C" +_UA_END_DECLS + + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_discovery_manager.h" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2014, 2017 (c) Florian Palm + * Copyright 2015-2016 (c) Sten Grüner + * Copyright 2015 (c) Chris Iatrou + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Julian Grothoff + */ + + + + +_UA_BEGIN_DECLS + +#ifdef UA_ENABLE_DISCOVERY + +typedef struct registeredServer_list_entry { +#ifdef UA_ENABLE_MULTITHREADING + UA_DelayedCallback delayedCleanup; #endif + LIST_ENTRY(registeredServer_list_entry) pointers; + UA_RegisteredServer registeredServer; + UA_DateTime lastSeen; +} registeredServer_list_entry; +typedef struct periodicServerRegisterCallback_entry { +#ifdef UA_ENABLE_MULTITHREADING + UA_DelayedCallback delayedCleanup; +#endif + LIST_ENTRY(periodicServerRegisterCallback_entry) pointers; + struct PeriodicServerRegisterCallback *callback; +} periodicServerRegisterCallback_entry; -/*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_timer.h" ***********************************/ +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + + +/** + * TXT record: + * [servername]-[hostname]._opcua-tcp._tcp.local. TXT path=/ caps=NA,DA,... + * + * A/AAAA record for all ip addresses: + * [servername]-[hostname]._opcua-tcp._tcp.local. A [ip]. + * [hostname]. A [ip]. + */ + +typedef struct serverOnNetwork_list_entry { +#ifdef UA_ENABLE_MULTITHREADING + UA_DelayedCallback delayedCleanup; +#endif + LIST_ENTRY(serverOnNetwork_list_entry) pointers; + UA_ServerOnNetwork serverOnNetwork; + UA_DateTime created; + UA_DateTime lastSeen; + UA_Boolean txtSet; + UA_Boolean srvSet; + char* pathTmp; +} serverOnNetwork_list_entry; + +#define SERVER_ON_NETWORK_HASH_PRIME 1009 +typedef struct serverOnNetwork_hash_entry { + serverOnNetwork_list_entry* entry; + struct serverOnNetwork_hash_entry* next; +} serverOnNetwork_hash_entry; + +#endif + +typedef struct { + LIST_HEAD(, periodicServerRegisterCallback_entry) periodicServerRegisterCallbacks; + LIST_HEAD(, registeredServer_list_entry) registeredServers; + size_t registeredServersSize; + UA_Server_registerServerCallback registerServerCallback; + void* registerServerCallbackData; + +# ifdef UA_ENABLE_DISCOVERY_MULTICAST + mdns_daemon_t *mdnsDaemon; + UA_SOCKET mdnsSocket; + UA_Boolean mdnsMainSrvAdded; + + LIST_HEAD(, serverOnNetwork_list_entry) serverOnNetwork; + size_t serverOnNetworkSize; + + UA_UInt32 serverOnNetworkRecordIdCounter; + UA_DateTime serverOnNetworkRecordIdLastReset; + + /* hash mapping domain name to serverOnNetwork list entry */ + struct serverOnNetwork_hash_entry* serverOnNetworkHash[SERVER_ON_NETWORK_HASH_PRIME]; + + UA_Server_serverOnNetworkCallback serverOnNetworkCallback; + void* serverOnNetworkCallbackData; + +# ifdef UA_ENABLE_MULTITHREADING + pthread_t mdnsThread; + UA_Boolean mdnsRunning; +# endif +# endif /* UA_ENABLE_DISCOVERY_MULTICAST */ +} UA_DiscoveryManager; + +void UA_DiscoveryManager_init(UA_DiscoveryManager *dm, UA_Server *server); +void UA_DiscoveryManager_deleteMembers(UA_DiscoveryManager *dm, UA_Server *server); + +/* Checks if a registration timed out and removes that registration. + * Should be called periodically in main loop */ +void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic); + +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + +void +UA_Server_updateMdnsForDiscoveryUrl(UA_Server *server, const UA_String *serverName, + const UA_MdnsDiscoveryConfiguration *mdnsConfig, + const UA_String *discoveryUrl, + UA_Boolean isOnline, UA_Boolean updateTxt); + +void mdns_record_received(const struct resource *r, void *data); + +void mdns_create_txt(UA_Server *server, const char *fullServiceDomain, + const char *path, const UA_String *capabilites, + const size_t capabilitiesSize, + void (*conflict)(char *host, int type, void *arg)); + +void mdns_set_address_record(UA_Server *server, + const char *fullServiceDomain, + const char *localDomain); + +mdns_record_t * +mdns_find_record(mdns_daemon_t *mdnsDaemon, unsigned short type, + const char *host, const char *rdname); + +void startMulticastDiscoveryServer(UA_Server *server); + +void stopMulticastDiscoveryServer(UA_Server *server); + +UA_StatusCode +iterateMulticastDiscoveryServer(UA_Server* server, UA_DateTime *nextRepeat, + UA_Boolean processIn); + +typedef enum { + UA_DISCOVERY_TCP, /* OPC UA TCP mapping */ + UA_DISCOVERY_TLS /* OPC UA HTTPS mapping */ +} UA_DiscoveryProtocol; + +/* Send a multicast probe to find any other OPC UA server on the network through mDNS. */ +UA_StatusCode +UA_Discovery_multicastQuery(UA_Server* server); + +UA_StatusCode +UA_Discovery_addRecord(UA_Server *server, const UA_String *servername, + const UA_String *hostname, UA_UInt16 port, + const UA_String *path, const UA_DiscoveryProtocol protocol, + UA_Boolean createTxt, const UA_String* capabilites, + const size_t capabilitiesSize); +UA_StatusCode +UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername, + const UA_String *hostname, UA_UInt16 port, + UA_Boolean removeTxt); + +#endif /* UA_ENABLE_DISCOVERY_MULTICAST */ + +#endif /* UA_ENABLE_DISCOVERY */ + +_UA_END_DECLS + + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_workqueue.h" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2014-2016 (c) Sten Grüner + * Copyright 2015 (c) Chris Iatrou + * Copyright 2015 (c) Nick Goossens + * Copyright 2015 (c) Jörg Schüler-Maroldt + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2016-2017 (c) Florian Palm * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2016 (c) Lorenz Haas + * Copyright 2017 (c) Jonas Green */ -#ifdef __cplusplus -extern "C" { + +#ifdef UA_ENABLE_MULTITHREADING +#include <pthread.h> #endif +_UA_BEGIN_DECLS -/* An (event) timer triggers callbacks with a recurring interval. Adding, - * removing and changing repeated callbacks can be done from independent - * threads. Processing the changes and dispatching callbacks must be done by a - * single "mainloop" process. - * Timer callbacks with the same recurring interval are batched into blocks in - * order to reduce linear search for re-entry to the sorted list after processing. - * Callbacks are inserted in reversed order (last callback are put first in the block) - * to allow the monitored items of a subscription (if created in a sequence with the - * same publish/sample interval) to be executed before the subscription publish the - * notifications. When callbacks are entered to the timer list after execution they - * are added in the same order as before execution. */ +/* Callback where the application is either a client or a server */ +typedef void (*UA_ApplicationCallback)(void *application, void *data); -/* Forward declaration */ -struct UA_TimerCallbackEntry; -typedef struct UA_TimerCallbackEntry UA_TimerCallbackEntry; +/* Delayed callbacks are executed when all previously enqueue work is finished. + * This is used to free memory that might used by a parallel worker or where the + * current threat has remaining pointers to until the current operation + * finishes. */ +typedef struct UA_DelayedCallback { + SIMPLEQ_ENTRY(UA_DelayedCallback) next; + UA_ApplicationCallback callback; + void *application; + void *data; +} UA_DelayedCallback; + +struct UA_WorkQueue; +typedef struct UA_WorkQueue UA_WorkQueue; -/* Linked-list definition */ -typedef SLIST_HEAD(UA_TimerCallbackList, UA_TimerCallbackEntry) UA_TimerCallbackList; +#ifdef UA_ENABLE_MULTITHREADING +/* Workers take out callbacks from the work queue and execute them. + * + * Future Plans: Use work-stealing to load-balance between cores. + * Le, Nhat Minh, et al. "Correct and efficient work-stealing for weak memory + * models." ACM SIGPLAN Notices. Vol. 48. No. 8. ACM, 2013. */ typedef struct { - /* The linked list of callbacks is sorted according to the execution timestamp. */ - UA_TimerCallbackList repeatedCallbacks; + pthread_t thread; + volatile UA_Boolean running; + UA_WorkQueue *queue; + UA_UInt32 counter; + UA_UInt32 checkpointCounter; /* Counter when the last checkpoint was made + * for the delayed callbacks */ + + /* separate cache lines */ + char padding[64 - sizeof(void*) - sizeof(pthread_t) - + sizeof(UA_UInt32) - sizeof(UA_Boolean)]; +} UA_Worker; + +#endif + +struct UA_WorkQueue { + /* Worker threads and work queue. Without multithreading, work is executed + immediately. */ +#ifdef UA_ENABLE_MULTITHREADING + UA_Worker *workers; + size_t workersSize; + + /* Work queue */ + SIMPLEQ_HEAD(, UA_DelayedCallback) dispatchQueue; /* Dispatch queue for the worker threads */ + pthread_mutex_t dispatchQueue_accessMutex; /* mutex for access to queue */ + pthread_cond_t dispatchQueue_condition; /* so the workers don't spin if the queue is empty */ + pthread_mutex_t dispatchQueue_conditionMutex; /* mutex for access to condition variable */ +#endif - /* Changes to the repeated callbacks in a multi-producer single-consumer queue */ - UA_TimerCallbackEntry * volatile changes_head; - UA_TimerCallbackEntry *changes_tail; - UA_TimerCallbackEntry *changes_stub; + /* Delayed callbacks + * To be executed after all curretly dispatched works has finished */ + SIMPLEQ_HEAD(, UA_DelayedCallback) delayedCallbacks; +#ifdef UA_ENABLE_MULTITHREADING + pthread_mutex_t delayedCallbacks_accessMutex; + UA_DelayedCallback *delayedCallbacks_checkpoint; + size_t delayedCallbacks_sinceDispatch; /* How many have been added since we + * tried to dispatch callbacks? */ +#endif +}; + +void UA_WorkQueue_init(UA_WorkQueue *wq); + +/* Enqueue a delayed callback. It is executed when all previous work in the + * queue has been finished. The ``cb`` pointer is freed afterwards. ``cb`` can + * have a NULL callback that is not executed. + * + * This method checks internally if existing delayed work can be moved from the + * delayed queue to the worker dispatch queue. */ +void UA_WorkQueue_enqueueDelayed(UA_WorkQueue *wq, UA_DelayedCallback *cb); + +/* Stop the workers, process all enqueued work in the calling thread, clean up + * mutexes etc. */ +void UA_WorkQueue_cleanup(UA_WorkQueue *wq); + +#ifndef UA_ENABLE_MULTITHREADING + +/* Process all enqueued delayed work. This is not needed when workers are + * running for the multithreading case. (UA_WorkQueue_cleanup still calls this + * method during cleanup when the workers are shut down.) */ +void UA_WorkQueue_manuallyProcessDelayed(UA_WorkQueue *wq); + +#else +/* Spin up a number of worker threads that listen on the work queue */ +UA_StatusCode UA_WorkQueue_start(UA_WorkQueue *wq, size_t workersCount); + +void UA_WorkQueue_stop(UA_WorkQueue *wq); + +/* Enqueue work for the worker threads */ +void UA_WorkQueue_enqueue(UA_WorkQueue *wq, UA_ApplicationCallback cb, + void *application, void *data); + +#endif + +_UA_END_DECLS + + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_timer.h" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2017, 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + */ + + + +_UA_BEGIN_DECLS + +struct UA_TimerEntry; +typedef struct UA_TimerEntry UA_TimerEntry; + +ZIP_HEAD(UA_TimerZip, UA_TimerEntry); +typedef struct UA_TimerZip UA_TimerZip; + +ZIP_HEAD(UA_TimerIdZip, UA_TimerEntry); +typedef struct UA_TimerIdZip UA_TimerIdZip; + +/* Only for a single thread. Protect by a mutex if required. */ +typedef struct { + UA_TimerZip root; /* The root of the time-sorted zip tree */ + UA_TimerIdZip idRoot; /* The root of the id-sorted zip tree */ UA_UInt64 idCounter; } UA_Timer; -/* Initialize the Timer. Not thread-safe. */ void UA_Timer_init(UA_Timer *t); -/* Add a repated callback. Thread-safe, can be used in parallel and in parallel - * with UA_Timer_process. */ -typedef void (*UA_TimerCallback)(void *application, void *data); +UA_StatusCode +UA_Timer_addTimedCallback(UA_Timer *t, UA_ApplicationCallback callback, + void *application, void *data, UA_DateTime date, + UA_UInt64 *callbackId); UA_StatusCode -UA_Timer_addRepeatedCallback(UA_Timer *t, UA_TimerCallback callback, void *data, - UA_UInt32 interval, UA_UInt64 *callbackId); +UA_Timer_addRepeatedCallback(UA_Timer *t, UA_ApplicationCallback callback, + void *application, void *data, UA_Double interval_ms, + UA_UInt64 *callbackId); /* Change the callback interval. If this is called from within the callback. The * adjustment is made during the next _process call. */ UA_StatusCode UA_Timer_changeRepeatedCallbackInterval(UA_Timer *t, UA_UInt64 callbackId, - UA_UInt32 interval); + UA_Double interval_ms); -/* Remove a repated callback. Thread-safe, can be used in parallel and in - * parallel with UA_Timer_process. */ -UA_StatusCode -UA_Timer_removeRepeatedCallback(UA_Timer *t, UA_UInt64 callbackId); +void +UA_Timer_removeCallback(UA_Timer *t, UA_UInt64 callbackId); /* Process (dispatch) the repeated callbacks that have timed out. Returns the * timestamp of the next scheduled repeated callback. Not thread-safe. * Application is a pointer to the client / server environment for the callback. * Dispatched is set to true when at least one callback was run / dispatched. */ -typedef void (*UA_TimerDispatchCallback)(void *application, UA_TimerCallback callback, - void *data); +typedef void +(*UA_TimerExecutionCallback)(void *executionApplication, UA_ApplicationCallback cb, + void *callbackApplication, void *data); UA_DateTime UA_Timer_process(UA_Timer *t, UA_DateTime nowMonotonic, - UA_TimerDispatchCallback dispatchCallback, - void *application); + UA_TimerExecutionCallback executionCallback, + void *executionApplication); -/* Remove all repeated callbacks. Not thread-safe. */ void UA_Timer_deleteMembers(UA_Timer *t); -#ifdef __cplusplus -} // extern "C" -#endif +_UA_END_DECLS /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_session.h" ***********************************/ @@ -4077,27 +5273,22 @@ void UA_Timer_deleteMembers(UA_Timer *t); * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) */ -#ifdef __cplusplus -extern "C" { -#endif +_UA_BEGIN_DECLS + #define UA_MAXCONTINUATIONPOINTS 5 -typedef struct ContinuationPointEntry { - LIST_ENTRY(ContinuationPointEntry) pointers; - UA_ByteString identifier; - UA_BrowseDescription browseDescription; - UA_UInt32 maxReferences; +struct ContinuationPoint; +typedef struct ContinuationPoint ContinuationPoint; - /* The last point in the node references? */ - size_t referenceKindIndex; - size_t targetIndex; -} ContinuationPointEntry; +/* Returns the next entry in the linked list */ +ContinuationPoint * +ContinuationPoint_clear(ContinuationPoint *cp); struct UA_Subscription; typedef struct UA_Subscription UA_Subscription; @@ -4123,7 +5314,7 @@ typedef struct { UA_DateTime validTill; UA_ByteString serverNonce; UA_UInt16 availableContinuationPoints; - LIST_HEAD(ContinuationPointList, ContinuationPointEntry) continuationPoints; + ContinuationPoint *continuationPoints; #ifdef UA_ENABLE_SUBSCRIPTIONS UA_UInt32 lastSubscriptionId; UA_UInt32 lastSeenSubscriptionId; @@ -4154,11 +5345,26 @@ void UA_Session_updateLifetime(UA_Session *session); #ifdef UA_ENABLE_SUBSCRIPTIONS -void UA_Session_addSubscription(UA_Session *session, UA_Subscription *newSubscription); -UA_Subscription * UA_Session_getSubscriptionById(UA_Session *session, UA_UInt32 subscriptionId); -UA_StatusCode UA_Session_deleteSubscription(UA_Server *server, UA_Session *session, UA_UInt32 subscriptionId); -void UA_Session_queuePublishReq(UA_Session *session, UA_PublishResponseEntry* entry, UA_Boolean head); -UA_PublishResponseEntry* UA_Session_dequeuePublishReq(UA_Session *session); +void +UA_Session_addSubscription(UA_Server *server, + UA_Session *session, + UA_Subscription *newSubscription); + +UA_Subscription * +UA_Session_getSubscriptionById(UA_Session *session, + UA_UInt32 subscriptionId); + +UA_StatusCode +UA_Session_deleteSubscription(UA_Server *server, UA_Session *session, + UA_UInt32 subscriptionId); + +void +UA_Session_queuePublishReq(UA_Session *session, + UA_PublishResponseEntry* entry, + UA_Boolean head); + +UA_PublishResponseEntry * +UA_Session_dequeuePublishReq(UA_Session *session); #endif @@ -4170,78 +5376,72 @@ UA_PublishResponseEntry* UA_Session_dequeuePublishReq(UA_Session *session); * zero arguments. So we add a dummy argument that is not printed (%.0s is * string of length zero). */ -#define UA_LOG_TRACE_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...) \ - UA_LOG_TRACE(LOGGER, UA_LOGCATEGORY_SESSION, \ - "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \ - ((SESSION)->header.channel ? ((SESSION)->header.channel->connection ? (SESSION)->header.channel->connection->sockfd : 0) : 0), \ - ((SESSION)->header.channel ? (SESSION)->header.channel->securityToken.channelId : 0), \ - UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__) - +#define UA_LOG_SESSION_INTERNAL(LOGGER, LEVEL, SESSION, MSG, ...) do { \ + UA_String idString = UA_STRING_NULL; \ + UA_NodeId_toString(&(SESSION)->sessionId, &idString); \ + UA_LOG_##LEVEL(LOGGER, UA_LOGCATEGORY_SESSION, \ + "Connection %i | SecureChannel %i | Session %.*s | " MSG "%.0s", \ + ((SESSION)->header.channel ? \ + ((SESSION)->header.channel->connection ? \ + (int)((SESSION)->header.channel->connection->sockfd) : 0) : 0), \ + ((SESSION)->header.channel ? \ + (SESSION)->header.channel->securityToken.channelId : 0), \ + (int)idString.length, idString.data, __VA_ARGS__); \ + UA_String_deleteMembers(&idString); \ + } while(0) + +#if UA_LOGLEVEL <= 100 #define UA_LOG_TRACE_SESSION(LOGGER, SESSION, ...) \ - UA_MACRO_EXPAND(UA_LOG_TRACE_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, "")) - -#define UA_LOG_DEBUG_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...) \ - UA_LOG_DEBUG(LOGGER, UA_LOGCATEGORY_SESSION, \ - "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \ - ((SESSION)->header.channel ? ((SESSION)->header.channel->connection ? (SESSION)->header.channel->connection->sockfd : 0) : 0), \ - ((SESSION)->header.channel ? (SESSION)->header.channel->securityToken.channelId : 0), \ - UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__) + UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, TRACE, SESSION, __VA_ARGS__, "")) +#else +#define UA_LOG_TRACE_SESSION(LOGGER, SESSION, ...) do {} while(0) +#endif +#if UA_LOGLEVEL <= 200 #define UA_LOG_DEBUG_SESSION(LOGGER, SESSION, ...) \ - UA_MACRO_EXPAND(UA_LOG_DEBUG_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, "")) - -#define UA_LOG_INFO_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...) \ - UA_LOG_INFO(LOGGER, UA_LOGCATEGORY_SESSION, \ - "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \ - ((SESSION)->header.channel ? ((SESSION)->header.channel->connection ? (SESSION)->header.channel->connection->sockfd : 0) : 0), \ - ((SESSION)->header.channel ? (SESSION)->header.channel->securityToken.channelId : 0), \ - UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__) + UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, DEBUG, SESSION, __VA_ARGS__, "")) +#else +#define UA_LOG_DEBUG_SESSION(LOGGER, SESSION, ...) do {} while(0) +#endif +#if UA_LOGLEVEL <= 300 #define UA_LOG_INFO_SESSION(LOGGER, SESSION, ...) \ - UA_MACRO_EXPAND(UA_LOG_INFO_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, "")) - -#define UA_LOG_WARNING_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...) \ - UA_LOG_WARNING(LOGGER, UA_LOGCATEGORY_SESSION, \ - "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \ - ((SESSION)->header.channel ? ((SESSION)->header.channel->connection ? (SESSION)->header.channel->connection->sockfd : 0) : 0), \ - ((SESSION)->header.channel ? (SESSION)->header.channel->securityToken.channelId : 0), \ - UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__) + UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, INFO, SESSION, __VA_ARGS__, "")) +#else +#define UA_LOG_INFO_SESSION(LOGGER, SESSION, ...) do {} while(0) +#endif +#if UA_LOGLEVEL <= 400 #define UA_LOG_WARNING_SESSION(LOGGER, SESSION, ...) \ - UA_MACRO_EXPAND(UA_LOG_WARNING_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, "")) - -#define UA_LOG_ERROR_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...) \ - UA_LOG_ERROR(LOGGER, UA_LOGCATEGORY_SESSION, \ - "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \ - ((SESSION)->header.channel ? ((SESSION)->header.channel->connection ? (SESSION)->header.channel->connection->sockfd : 0) : 0), \ - ((SESSION)->header.channel ? (SESSION)->header.channel->securityToken.channelId : 0), \ - UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__) + UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, WARNING, SESSION, __VA_ARGS__, "")) +#else +#define UA_LOG_WARNING_SESSION(LOGGER, SESSION, ...) do {} while(0) +#endif +#if UA_LOGLEVEL <= 500 #define UA_LOG_ERROR_SESSION(LOGGER, SESSION, ...) \ - UA_MACRO_EXPAND(UA_LOG_ERROR_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, "")) - -#define UA_LOG_FATAL_SESSION_INTERNAL(LOGGER, SESSION, MSG, ...) \ - UA_LOG_FATAL(LOGGER, UA_LOGCATEGORY_SESSION, \ - "Connection %i | SecureChannel %i | Session " UA_PRINTF_GUID_FORMAT " | " MSG "%.0s", \ - ((SESSION)->header.channel ? ((SESSION)->header.channel->connection ? (SESSION)->header.channel->connection->sockfd : 0) : 0), \ - ((SESSION)->header.channel ? (SESSION)->header.channel->securityToken.channelId : 0), \ - UA_PRINTF_GUID_DATA((SESSION)->sessionId.identifier.guid), __VA_ARGS__) + UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, ERROR, SESSION, __VA_ARGS__, "")) +#else +#define UA_LOG_ERROR_SESSION(LOGGER, SESSION, ...) do {} while(0) +#endif +#if UA_LOGLEVEL <= 600 #define UA_LOG_FATAL_SESSION(LOGGER, SESSION, ...) \ - UA_MACRO_EXPAND(UA_LOG_FATAL_SESSION_INTERNAL(LOGGER, SESSION, __VA_ARGS__, "")) - -#ifdef __cplusplus -} // extern "C" + UA_MACRO_EXPAND(UA_LOG_SESSION_INTERNAL(LOGGER, FATAL, SESSION, __VA_ARGS__, "")) +#else +#define UA_LOG_FATAL_SESSION(LOGGER, SESSION, ...) do {} while(0) #endif +_UA_END_DECLS + /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_subscription.h" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015 (c) Chris Iatrou * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015 (c) Oleksiy Vasylyev @@ -4252,6 +5452,21 @@ UA_PublishResponseEntry* UA_Session_dequeuePublishReq(UA_Session *session); + +_UA_BEGIN_DECLS + +#ifdef UA_ENABLE_SUBSCRIPTIONS + +#define UA_BOUNDEDVALUE_SETWBOUNDS(BOUNDS, SRC, DST) { \ + if(SRC > BOUNDS.max) DST = BOUNDS.max; \ + else if(SRC < BOUNDS.min) DST = BOUNDS.min; \ + else DST = SRC; \ + } + +/* Set to the TAILQ_NEXT pointer of a notification, the sentinel that the + * notification was not added to the global queue */ +#define UA_SUBSCRIPTION_QUEUE_SENTINEL ((UA_Notification*)0x01) + /** * MonitoredItems create Notifications. Subscriptions collect Notifications from * (several) MonitoredItems and publish them to the client. @@ -4268,54 +5483,71 @@ UA_PublishResponseEntry* UA_Session_dequeuePublishReq(UA_Session *session); /* MonitoredItem */ /*****************/ -typedef enum { - UA_MONITOREDITEMTYPE_CHANGENOTIFY = 1, - UA_MONITOREDITEMTYPE_STATUSNOTIFY = 2, - UA_MONITOREDITEMTYPE_EVENTNOTIFY = 4 -} UA_MonitoredItemType; - -/* Not used yet. Placeholder for a future event implementation. */ -typedef struct UA_Event { - UA_Int32 eventId; -} UA_Event; - struct UA_MonitoredItem; typedef struct UA_MonitoredItem UA_MonitoredItem; +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS +typedef struct UA_EventNotification { + UA_EventFieldList fields; + /* EventFilterResult currently isn't being used + UA_EventFilterResult result; */ +} UA_EventNotification; +#endif + typedef struct UA_Notification { - TAILQ_ENTRY(UA_Notification) listEntry; - TAILQ_ENTRY(UA_Notification) globalEntry; + TAILQ_ENTRY(UA_Notification) listEntry; /* Notification list for the MonitoredItem */ + TAILQ_ENTRY(UA_Notification) globalEntry; /* Notification list for the Subscription */ UA_MonitoredItem *mon; /* See the monitoredItemType of the MonitoredItem */ union { - UA_Event event; +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + UA_EventNotification event; +#endif UA_DataValue value; } data; } UA_Notification; +/* Ensure enough space is available; Add notification to the linked lists; + * Increase the counters */ +void UA_Notification_enqueue(UA_Server *server, UA_Subscription *sub, + UA_MonitoredItem *mon, UA_Notification *n); + +/* Remove the notification from the MonitoredItem's queue and the Subscriptions + * global queue. Reduce the respective counters. */ +void UA_Notification_dequeue(UA_Server *server, UA_Notification *n); + +/* Delete the notification. Must be dequeued first. */ +void UA_Notification_delete(UA_Notification *n); + typedef TAILQ_HEAD(NotificationQueue, UA_Notification) NotificationQueue; struct UA_MonitoredItem { + UA_DelayedCallback delayedFreePointers; LIST_ENTRY(UA_MonitoredItem) listEntry; - UA_Subscription *subscription; + UA_Subscription *subscription; /* Local MonitoredItem if the subscription is NULL */ UA_UInt32 monitoredItemId; UA_UInt32 clientHandle; + UA_Boolean registered; /* Was the MonitoredItem registered in Userland with + the callback? */ /* Settings */ - UA_MonitoredItemType monitoredItemType; UA_TimestampsToReturn timestampsToReturn; UA_MonitoringMode monitoringMode; UA_NodeId monitoredNodeId; UA_UInt32 attributeId; UA_String indexRange; UA_Double samplingInterval; // [ms] - UA_UInt32 maxQueueSize; UA_Boolean discardOldest; - // TODO: dataEncoding is hardcoded to UA binary - UA_DataChangeFilter filter; + union { +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + UA_EventFilter eventFilter; /* If attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER */ +#endif + UA_DataChangeFilter dataChangeFilter; + } filter; UA_Variant lastValue; + // TODO: dataEncoding is hardcoded to UA binary /* Sample Callback */ UA_UInt64 sampleCallbackId; @@ -4324,18 +5556,33 @@ struct UA_MonitoredItem { /* Notification Queue */ NotificationQueue queue; + UA_UInt32 maxQueueSize; /* The max number of enqueued notifications (not + * counting overflow events) */ UA_UInt32 queueSize; + UA_UInt32 eventOverflows; /* Separate counter for the queue. Can at most + * double the queue size */ + +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + UA_MonitoredItem *next; +#endif + +#ifdef UA_ENABLE_DA + UA_StatusCode lastStatus; +#endif }; -UA_MonitoredItem * UA_MonitoredItem_new(UA_MonitoredItemType); -void MonitoredItem_delete(UA_Server *server, UA_MonitoredItem *monitoredItem); -void UA_MonitoredItem_SampleCallback(UA_Server *server, UA_MonitoredItem *monitoredItem); -UA_StatusCode MonitoredItem_registerSampleCallback(UA_Server *server, UA_MonitoredItem *mon); -UA_StatusCode MonitoredItem_unregisterSampleCallback(UA_Server *server, UA_MonitoredItem *mon); +void UA_MonitoredItem_init(UA_MonitoredItem *mon, UA_Subscription *sub); +void UA_MonitoredItem_delete(UA_Server *server, UA_MonitoredItem *monitoredItem); +void UA_MonitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *monitoredItem); +UA_StatusCode UA_MonitoredItem_registerSampleCallback(UA_Server *server, UA_MonitoredItem *mon); +void UA_MonitoredItem_unregisterSampleCallback(UA_Server *server, UA_MonitoredItem *mon); /* Remove entries until mon->maxQueueSize is reached. Sets infobits for lost * data if required. */ -void MonitoredItem_ensureQueueSpace(UA_MonitoredItem *mon); +UA_StatusCode UA_MonitoredItem_ensureQueueSpace(UA_Server *server, UA_MonitoredItem *mon); + +UA_StatusCode UA_MonitoredItem_removeNodeEventCallback(UA_Server *server, UA_Session *session, + UA_Node *node, void *data); /****************/ /* Subscription */ @@ -4358,6 +5605,7 @@ typedef enum { typedef TAILQ_HEAD(ListOfNotificationMessages, UA_NotificationMessageEntry) ListOfNotificationMessages; struct UA_Subscription { + UA_DelayedCallback delayedFreePointers; LIST_ENTRY(UA_Subscription) listEntry; UA_Session *session; UA_UInt32 subscriptionId; @@ -4382,13 +5630,21 @@ struct UA_Subscription { /* MonitoredItems */ UA_UInt32 lastMonitoredItemId; /* increase the identifiers */ - LIST_HEAD(UA_ListOfUAMonitoredItems, UA_MonitoredItem) monitoredItems; + LIST_HEAD(, UA_MonitoredItem) monitoredItems; UA_UInt32 monitoredItemsSize; /* Global list of notifications from the MonitoredItems */ NotificationQueue notificationQueue; - UA_UInt32 notificationQueueSize; - UA_UInt32 readyNotifications; /* Notifications to be sent out now (already late) */ + UA_UInt32 notificationQueueSize; /* Total queue size */ + UA_UInt32 dataChangeNotifications; + UA_UInt32 eventNotifications; + UA_UInt32 statusChangeNotifications; + + /* Notifications to be sent out now (already late). In a regular publish + * callback, all queued notifications are sent out. In a late publish + * response, only the notifications left from the last regular publish + * callback are sent. */ + UA_UInt32 readyNotifications; /* Retransmission Queue */ ListOfNotificationMessages retransmissionQueue; @@ -4398,8 +5654,8 @@ struct UA_Subscription { UA_Subscription * UA_Subscription_new(UA_Session *session, UA_UInt32 subscriptionId); void UA_Subscription_deleteMembers(UA_Server *server, UA_Subscription *sub); UA_StatusCode Subscription_registerPublishCallback(UA_Server *server, UA_Subscription *sub); -UA_StatusCode Subscription_unregisterPublishCallback(UA_Server *server, UA_Subscription *sub); -void UA_Subscription_addMonitoredItem(UA_Subscription *sub, UA_MonitoredItem *newMon); +void Subscription_unregisterPublishCallback(UA_Server *server, UA_Subscription *sub); +void UA_Subscription_addMonitoredItem(UA_Server *server, UA_Subscription *sub, UA_MonitoredItem *newMon); UA_MonitoredItem * UA_Subscription_getMonitoredItem(UA_Subscription *sub, UA_UInt32 monitoredItemId); UA_StatusCode @@ -4407,10 +5663,15 @@ UA_Subscription_deleteMonitoredItem(UA_Server *server, UA_Subscription *sub, UA_UInt32 monitoredItemId); void UA_Subscription_publish(UA_Server *server, UA_Subscription *sub); -UA_StatusCode UA_Subscription_removeRetransmissionMessage(UA_Subscription *sub, UA_UInt32 sequenceNumber); +UA_StatusCode UA_Subscription_removeRetransmissionMessage(UA_Subscription *sub, + UA_UInt32 sequenceNumber); void UA_Subscription_answerPublishRequestsNoSubscription(UA_Server *server, UA_Session *session); UA_Boolean UA_Subscription_reachedPublishReqLimit(UA_Server *server, UA_Session *session); +#endif /* UA_ENABLE_SUBSCRIPTIONS */ + +_UA_END_DECLS + /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_session_manager.h" ***********************************/ @@ -4418,7 +5679,7 @@ UA_Boolean UA_Subscription_reachedPublishReqLimit(UA_Server *server, UA_Session * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014, 2017 (c) Florian Palm * Copyright 2015 (c) Sten Grüner * Copyright 2015 (c) Oleksiy Vasylyev @@ -4426,12 +5687,12 @@ UA_Boolean UA_Subscription_reachedPublishReqLimit(UA_Server *server, UA_Session */ -#ifdef __cplusplus -extern "C" { -#endif +_UA_BEGIN_DECLS + typedef struct session_list_entry { + UA_DelayedCallback cleanupCallback; LIST_ENTRY(session_list_entry) pointers; UA_Session session; } session_list_entry; @@ -4467,9 +5728,7 @@ UA_SessionManager_getSessionByToken(UA_SessionManager *sm, const UA_NodeId *toke UA_Session * UA_SessionManager_getSessionById(UA_SessionManager *sm, const UA_NodeId *sessionId); -#ifdef __cplusplus -} // extern "C" -#endif +_UA_END_DECLS /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_securechannel_manager.h" ***********************************/ @@ -4478,21 +5737,21 @@ UA_SessionManager_getSessionById(UA_SessionManager *sm, const UA_NodeId *session * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014, 2017 (c) Florian Palm * Copyright 2015 (c) Oleksiy Vasylyev * Copyright 2017 (c) Stefan Profanter, fortiss GmbH */ -#ifdef __cplusplus -extern "C" { -#endif +_UA_BEGIN_DECLS + typedef struct channel_entry { - UA_SecureChannel channel; + UA_DelayedCallback cleanupCallback; TAILQ_ENTRY(channel_entry) pointers; + UA_SecureChannel channel; } channel_entry; typedef struct { @@ -4537,123 +5796,657 @@ UA_SecureChannelManager_get(UA_SecureChannelManager *cm, UA_UInt32 channelId); UA_StatusCode UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId); -#ifdef __cplusplus -} // extern "C" +_UA_END_DECLS + + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/pubsub/ua_pubsub_networkmessage.h" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2017 - 2018 Fraunhofer IOSB (Author: Tino Bischoff) + */ + + + +_UA_BEGIN_DECLS + +/* DataSet Payload Header */ +typedef struct { + UA_Byte count; + UA_UInt16* dataSetWriterIds; +} UA_DataSetPayloadHeader; + +/* FieldEncoding Enum */ +typedef enum { + UA_FIELDENCODING_VARIANT = 0, + UA_FIELDENCODING_RAWDATA = 1, + UA_FIELDENCODING_DATAVALUE = 2 +} UA_FieldEncoding; + +/* DataSetMessage Type */ +typedef enum { + UA_DATASETMESSAGE_DATAKEYFRAME = 0, + UA_DATASETMESSAGE_DATADELTAFRAME = 1, + UA_DATASETMESSAGE_EVENT = 2, + UA_DATASETMESSAGE_KEEPALIVE = 3 +} UA_DataSetMessageType; + +/* DataSetMessage Header */ +typedef struct { + UA_Boolean dataSetMessageValid; + UA_FieldEncoding fieldEncoding; + UA_Boolean dataSetMessageSequenceNrEnabled; + UA_Boolean timestampEnabled; + UA_Boolean statusEnabled; + UA_Boolean configVersionMajorVersionEnabled; + UA_Boolean configVersionMinorVersionEnabled; + UA_DataSetMessageType dataSetMessageType; + UA_Boolean picoSecondsIncluded; + UA_UInt16 dataSetMessageSequenceNr; + UA_UtcTime timestamp; + UA_UInt16 picoSeconds; + UA_UInt16 status; + UA_UInt32 configVersionMajorVersion; + UA_UInt32 configVersionMinorVersion; +} UA_DataSetMessageHeader; + +UA_StatusCode +UA_DataSetMessageHeader_encodeBinary(const UA_DataSetMessageHeader* src, + UA_Byte **bufPos, const UA_Byte *bufEnd); + +UA_StatusCode +UA_DataSetMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset, + UA_DataSetMessageHeader* dst); + +size_t +UA_DataSetMessageHeader_calcSizeBinary(const UA_DataSetMessageHeader* p); + +/** + * DataSetMessage + * ^^^^^^^^^^^^^^ */ + +typedef struct { + UA_UInt16 fieldCount; + UA_DataValue* dataSetFields; + /* Json keys for the dataSetFields: TODO: own dataSetMessageType for json? */ + UA_String* fieldNames; +} UA_DataSetMessage_DataKeyFrameData; + +typedef struct { + UA_UInt16 fieldIndex; + UA_DataValue fieldValue; +} UA_DataSetMessage_DeltaFrameField; + +typedef struct { + UA_UInt16 fieldCount; + UA_DataSetMessage_DeltaFrameField* deltaFrameFields; +} UA_DataSetMessage_DataDeltaFrameData; + +typedef struct { + UA_DataSetMessageHeader header; + union { + UA_DataSetMessage_DataKeyFrameData keyFrameData; + UA_DataSetMessage_DataDeltaFrameData deltaFrameData; + } data; +} UA_DataSetMessage; + +UA_StatusCode +UA_DataSetMessage_encodeBinary(const UA_DataSetMessage* src, UA_Byte **bufPos, + const UA_Byte *bufEnd); + +UA_StatusCode +UA_DataSetMessage_decodeBinary(const UA_ByteString *src, size_t *offset, + UA_DataSetMessage* dst); + +size_t +UA_DataSetMessage_calcSizeBinary(const UA_DataSetMessage* p); + +void UA_DataSetMessage_free(const UA_DataSetMessage* p); + +typedef struct { + UA_UInt16* sizes; + UA_DataSetMessage* dataSetMessages; +} UA_DataSetPayload; + +typedef enum { + UA_PUBLISHERDATATYPE_BYTE = 0, + UA_PUBLISHERDATATYPE_UINT16 = 1, + UA_PUBLISHERDATATYPE_UINT32 = 2, + UA_PUBLISHERDATATYPE_UINT64 = 3, + UA_PUBLISHERDATATYPE_STRING = 4 +} UA_PublisherIdDatatype; + +typedef enum { + UA_NETWORKMESSAGE_DATASET = 0, + UA_NETWORKMESSAGE_DISCOVERY_REQUEST = 1, + UA_NETWORKMESSAGE_DISCOVERY_RESPONSE = 2 +} UA_NetworkMessageType; + +/** + * UA_NetworkMessageGroupHeader + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ +typedef struct { + UA_Boolean writerGroupIdEnabled; + UA_Boolean groupVersionEnabled; + UA_Boolean networkMessageNumberEnabled; + UA_Boolean sequenceNumberEnabled; + UA_UInt16 writerGroupId; + UA_UInt32 groupVersion; // spec: type "VersionTime" + UA_UInt16 networkMessageNumber; + UA_UInt16 sequenceNumber; +} UA_NetworkMessageGroupHeader; + +/** + * UA_NetworkMessageSecurityHeader + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ +typedef struct { + UA_Boolean networkMessageSigned; + UA_Boolean networkMessageEncrypted; + UA_Boolean securityFooterEnabled; + UA_Boolean forceKeyReset; + UA_UInt32 securityTokenId; // spec: IntegerId + UA_Byte nonceLength; + UA_ByteString messageNonce; + UA_UInt16 securityFooterSize; +} UA_NetworkMessageSecurityHeader; + +/** + * UA_NetworkMessage + * ^^^^^^^^^^^^^^^^^ */ +typedef struct { + UA_Byte version; + UA_Boolean messageIdEnabled; + UA_String messageId; /* For Json NetworkMessage */ + UA_Boolean publisherIdEnabled; + UA_Boolean groupHeaderEnabled; + UA_Boolean payloadHeaderEnabled; + UA_PublisherIdDatatype publisherIdType; + UA_Boolean dataSetClassIdEnabled; + UA_Boolean securityEnabled; + UA_Boolean timestampEnabled; + UA_Boolean picosecondsEnabled; + UA_Boolean chunkMessage; + UA_Boolean promotedFieldsEnabled; + UA_NetworkMessageType networkMessageType; + union { + UA_Byte publisherIdByte; + UA_UInt16 publisherIdUInt16; + UA_UInt32 publisherIdUInt32; + UA_UInt64 publisherIdUInt64; + UA_Guid publisherIdGuid; + UA_String publisherIdString; + } publisherId; + UA_Guid dataSetClassId; + + UA_NetworkMessageGroupHeader groupHeader; + + union { + UA_DataSetPayloadHeader dataSetPayloadHeader; + } payloadHeader; + + UA_DateTime timestamp; + UA_UInt16 picoseconds; + UA_UInt16 promotedFieldsSize; + UA_Variant* promotedFields; /* BaseDataType */ + + UA_NetworkMessageSecurityHeader securityHeader; + + union { + UA_DataSetPayload dataSetPayload; + } payload; + + UA_ByteString securityFooter; + UA_ByteString signature; +} UA_NetworkMessage; + +UA_StatusCode +UA_NetworkMessage_encodeBinary(const UA_NetworkMessage* src, + UA_Byte **bufPos, const UA_Byte *bufEnd); + +UA_StatusCode +UA_NetworkMessage_decodeBinary(const UA_ByteString *src, size_t *offset, + UA_NetworkMessage* dst); + +size_t +UA_NetworkMessage_calcSizeBinary(const UA_NetworkMessage* p); + +void +UA_NetworkMessage_deleteMembers(UA_NetworkMessage* p); + +#define UA_NetworkMessage_clear(p) UA_NetworkMessage_deleteMembers(p) + +void +UA_NetworkMessage_delete(UA_NetworkMessage* p); + + +#ifdef UA_ENABLE_JSON_ENCODING +UA_StatusCode +UA_NetworkMessage_encodeJson(const UA_NetworkMessage *src, + UA_Byte **bufPos, const UA_Byte **bufEnd, UA_String *namespaces, + size_t namespaceSize, UA_String *serverUris, + size_t serverUriSize, UA_Boolean useReversible); + +size_t +UA_NetworkMessage_calcSizeJson(const UA_NetworkMessage *src, + UA_String *namespaces, size_t namespaceSize, + UA_String *serverUris, size_t serverUriSize, + UA_Boolean useReversible); + +UA_StatusCode UA_NetworkMessage_decodeJson(UA_NetworkMessage *dst, const UA_ByteString *src); #endif +_UA_END_DECLS -/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_server_internal.h" ***********************************/ + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/pubsub/ua_pubsub.h" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB - * Copyright 2014, 2017 (c) Florian Palm - * Copyright 2015-2016 (c) Sten Grüner - * Copyright 2015 (c) Chris Iatrou - * Copyright 2015-2016 (c) Oleksiy Vasylyev - * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH - * Copyright 2017 (c) Julian Grothoff + * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner) + * Copyright (c) 2019 Kalycito Infotech Private Limited */ -#ifdef __cplusplus -extern "C" { + + +_UA_BEGIN_DECLS + +#ifdef UA_ENABLE_PUBSUB /* conditional compilation */ + +/* forward declarations */ +struct UA_WriterGroup; +typedef struct UA_WriterGroup UA_WriterGroup; + +/* Declaration for ReaderGroup */ +struct UA_ReaderGroup; +typedef struct UA_ReaderGroup UA_ReaderGroup; + +/* The configuration structs (public part of PubSub entities) are defined in include/ua_plugin_pubsub.h */ + +/**********************************************/ +/* PublishedDataSet */ +/**********************************************/ +typedef struct{ + UA_PublishedDataSetConfig config; + UA_DataSetMetaDataType dataSetMetaData; + LIST_HEAD(UA_ListOfDataSetField, UA_DataSetField) fields; + UA_NodeId identifier; + UA_UInt16 fieldSize; + UA_UInt16 promotedFieldsCount; +} UA_PublishedDataSet; + +UA_StatusCode +UA_PublishedDataSetConfig_copy(const UA_PublishedDataSetConfig *src, UA_PublishedDataSetConfig *dst); +UA_PublishedDataSet * +UA_PublishedDataSet_findPDSbyId(UA_Server *server, UA_NodeId identifier); +void +UA_PublishedDataSet_deleteMembers(UA_Server *server, UA_PublishedDataSet *publishedDataSet); + +/**********************************************/ +/* Connection */ +/**********************************************/ +//the connection config (public part of connection) object is defined in include/ua_plugin_pubsub.h +typedef struct{ + UA_PubSubConnectionConfig *config; + //internal fields + UA_PubSubChannel *channel; + UA_NodeId identifier; + LIST_HEAD(UA_ListOfWriterGroup, UA_WriterGroup) writerGroups; + LIST_HEAD(UA_ListOfPubSubReaderGroup, UA_ReaderGroup) readerGroups; + size_t readerGroupsSize; +} UA_PubSubConnection; + +UA_StatusCode +UA_PubSubConnectionConfig_copy(const UA_PubSubConnectionConfig *src, UA_PubSubConnectionConfig *dst); +UA_PubSubConnection * +UA_PubSubConnection_findConnectionbyId(UA_Server *server, UA_NodeId connectionIdentifier); +void +UA_PubSubConnectionConfig_deleteMembers(UA_PubSubConnectionConfig *connectionConfig); +void +UA_PubSubConnection_deleteMembers(UA_Server *server, UA_PubSubConnection *connection); + +/**********************************************/ +/* DataSetWriter */ +/**********************************************/ + +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES +typedef struct UA_DataSetWriterSample{ + UA_Boolean valueChanged; + UA_DataValue value; +} UA_DataSetWriterSample; #endif +typedef struct UA_DataSetWriter{ + UA_DataSetWriterConfig config; + //internal fields + LIST_ENTRY(UA_DataSetWriter) listEntry; + UA_NodeId identifier; + UA_NodeId linkedWriterGroup; + UA_NodeId connectedDataSet; + UA_ConfigurationVersionDataType connectedDataSetVersion; +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES + UA_UInt16 deltaFrameCounter; //actual count of sent deltaFrames + size_t lastSamplesCount; + UA_DataSetWriterSample *lastSamples; +#endif + UA_UInt16 actualDataSetMessageSequenceCount; +} UA_DataSetWriter; -#ifdef UA_ENABLE_MULTITHREADING +UA_StatusCode +UA_DataSetWriterConfig_copy(const UA_DataSetWriterConfig *src, UA_DataSetWriterConfig *dst); +UA_DataSetWriter * +UA_DataSetWriter_findDSWbyId(UA_Server *server, UA_NodeId identifier); + +/**********************************************/ +/* WriterGroup */ +/**********************************************/ + +struct UA_WriterGroup{ + UA_WriterGroupConfig config; + //internal fields + LIST_ENTRY(UA_WriterGroup) listEntry; + UA_NodeId identifier; + UA_NodeId linkedConnection; + LIST_HEAD(UA_ListOfDataSetWriter, UA_DataSetWriter) writers; + UA_UInt32 writersCount; + UA_UInt64 publishCallbackId; + UA_Boolean publishCallbackIsRegistered; +}; -#include <pthread.h> +UA_StatusCode +UA_WriterGroupConfig_copy(const UA_WriterGroupConfig *src, UA_WriterGroupConfig *dst); +UA_WriterGroup * +UA_WriterGroup_findWGbyId(UA_Server *server, UA_NodeId identifier); + +/**********************************************/ +/* DataSetField */ +/**********************************************/ + +typedef struct UA_DataSetField{ + UA_DataSetFieldConfig config; + //internal fields + LIST_ENTRY(UA_DataSetField) listEntry; + UA_NodeId identifier; + UA_NodeId publishedDataSet; //ref to parent pds + UA_FieldMetaData fieldMetaData; + UA_UInt64 sampleCallbackId; + UA_Boolean sampleCallbackIsRegistered; +} UA_DataSetField; -struct UA_Worker; -typedef struct UA_Worker UA_Worker; +UA_StatusCode +UA_DataSetFieldConfig_copy(const UA_DataSetFieldConfig *src, UA_DataSetFieldConfig *dst); +UA_DataSetField * +UA_DataSetField_findDSFbyId(UA_Server *server, UA_NodeId identifier); -struct UA_WorkerCallback; -typedef struct UA_WorkerCallback UA_WorkerCallback; +/**********************************************/ +/* DataSetReader */ +/**********************************************/ -SIMPLEQ_HEAD(UA_DispatchQueue, UA_WorkerCallback); -typedef struct UA_DispatchQueue UA_DispatchQueue; +/* SubscribedDataSetDataType Definition */ +typedef enum { + UA_PUBSUB_SDS_TARGET, + UA_PUBSUB_SDS_MIRROR +}UA_SubscribedDataSetEnumType; + +/* DataSetReader Type definition */ +typedef struct UA_DataSetReader { + UA_DataSetReaderConfig config; + /* implementation defined fields */ + UA_NodeId identifier; + UA_NodeId linkedReaderGroup; + LIST_ENTRY(UA_DataSetReader) listEntry; + UA_SubscribedDataSetEnumType subscribedDataSetType; + UA_TargetVariablesDataType subscribedDataSetTarget; + /* To Do UA_SubscribedDataSetMirrorDataType subscribedDataSetMirror */ +}UA_DataSetReader; + +/* Delete DataSetReader */ +void UA_DataSetReader_delete(UA_Server *server, UA_DataSetReader *dataSetReader); + +/* Process Network Message using DataSetReader */ +void UA_Server_DataSetReader_process(UA_Server *server, UA_DataSetReader *dataSetReader, UA_DataSetMessage* dataSetMsg); + +/* Copy the configuration of DataSetReader */ +UA_StatusCode UA_DataSetReaderConfig_copy(const UA_DataSetReaderConfig *src, UA_DataSetReaderConfig *dst); + +/* Add TargetVariables */ +UA_StatusCode +UA_Server_DataSetReader_addTargetVariables(UA_Server* server, UA_NodeId* parentNode, UA_NodeId dataSetReaderIdentifier, UA_SubscribedDataSetEnumType sdsType); + +/**********************************************/ +/* ReaderGroup */ +/**********************************************/ +/* ReaderGroup Type Definition*/ + +struct UA_ReaderGroup { + UA_ReaderGroupConfig config; + UA_NodeId identifier; + UA_NodeId linkedConnection; + LIST_ENTRY(UA_ReaderGroup) listEntry; + LIST_HEAD(UA_ListOfPubSubDataSetReader, UA_DataSetReader) readers; + /* for simplified information access */ + UA_UInt32 readersCount; + UA_UInt64 subscribeCallbackId; + UA_Boolean subscribeCallbackIsRegistered; +}; -#endif /* UA_ENABLE_MULTITHREADING */ +/* Delete ReaderGroup */ +void UA_Server_ReaderGroup_delete(UA_Server *server, UA_ReaderGroup *readerGroup); -#ifdef UA_ENABLE_DISCOVERY +/* Copy configuration of ReaderGroup */ +UA_StatusCode +UA_ReaderGroupConfig_copy(const UA_ReaderGroupConfig *src, UA_ReaderGroupConfig *dst); -typedef struct registeredServer_list_entry { - LIST_ENTRY(registeredServer_list_entry) pointers; - UA_RegisteredServer registeredServer; - UA_DateTime lastSeen; -} registeredServer_list_entry; +/* Process Network Message */ +UA_StatusCode +UA_Server_processNetworkMessage(UA_Server *server, UA_NetworkMessage* pMsg, UA_PubSubConnection *pConnection); -typedef struct periodicServerRegisterCallback_entry { - LIST_ENTRY(periodicServerRegisterCallback_entry) pointers; - struct PeriodicServerRegisterCallback *callback; -} periodicServerRegisterCallback_entry; +/* Prototypes for internal util functions - some functions maybe removed later + *(currently moved from public to internal)*/ +UA_ReaderGroup *UA_ReaderGroup_findRGbyId(UA_Server *server, UA_NodeId identifier); +UA_DataSetReader *UA_ReaderGroup_findDSRbyId(UA_Server *server, UA_NodeId identifier); -#ifdef UA_ENABLE_DISCOVERY_MULTICAST +/*********************************************************/ +/* PublishValues handling */ +/*********************************************************/ +UA_StatusCode +UA_WriterGroup_addPublishCallback(UA_Server *server, UA_WriterGroup *writerGroup); +void +UA_WriterGroup_publishCallback(UA_Server *server, UA_WriterGroup *writerGroup); -typedef struct serverOnNetwork_list_entry { - LIST_ENTRY(serverOnNetwork_list_entry) pointers; - UA_ServerOnNetwork serverOnNetwork; - UA_DateTime created; - UA_DateTime lastSeen; - UA_Boolean txtSet; - UA_Boolean srvSet; - char* pathTmp; -} serverOnNetwork_list_entry; +/*********************************************************/ +/* SubscribeValues handling */ +/*********************************************************/ -#define SERVER_ON_NETWORK_HASH_PRIME 1009 -typedef struct serverOnNetwork_hash_entry { - serverOnNetwork_list_entry* entry; - struct serverOnNetwork_hash_entry* next; -} serverOnNetwork_hash_entry; +UA_StatusCode +UA_ReaderGroup_addSubscribeCallback(UA_Server *server, UA_ReaderGroup *readerGroup); +void +UA_ReaderGroup_subscribeCallback(UA_Server *server, UA_ReaderGroup *readerGroup); -#endif /* UA_ENABLE_DISCOVERY_MULTICAST */ -#endif /* UA_ENABLE_DISCOVERY */ +#endif /* UA_ENABLE_PUBSUB */ -struct UA_Server { - /* Meta */ - UA_DateTime startTime; +_UA_END_DECLS - /* Security */ - UA_SecureChannelManager secureChannelManager; - UA_SessionManager sessionManager; + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/pubsub/ua_pubsub_manager.h" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner) + */ + + + + +_UA_BEGIN_DECLS + +#ifdef UA_ENABLE_PUBSUB /* conditional compilation */ + +typedef struct UA_PubSubManager{ + //Connections and PublishedDataSets can exist alone (own lifecycle) -> top level components + size_t connectionsSize; + UA_PubSubConnection *connections; + size_t publishedDataSetsSize; + UA_PublishedDataSet *publishedDataSets; +} UA_PubSubManager; + +void +UA_PubSubManager_delete(UA_Server *server, UA_PubSubManager *pubSubManager); + +void +UA_PubSubManager_generateUniqueNodeId(UA_Server *server, UA_NodeId *nodeId); + +UA_UInt32 +UA_PubSubConfigurationVersionTimeDifference(void); + +/***********************************/ +/* PubSub Jobs abstraction */ +/***********************************/ +UA_StatusCode +UA_PubSubManager_addRepeatedCallback(UA_Server *server, UA_ServerCallback callback, + void *data, UA_Double interval_ms, UA_UInt64 *callbackId); +UA_StatusCode +UA_PubSubManager_changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId, + UA_Double interval_ms); +void +UA_PubSubManager_removeRepeatedPubSubCallback(UA_Server *server, UA_UInt64 callbackId); + +#endif /* UA_ENABLE_PUBSUB */ + +_UA_END_DECLS + + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/pubsub/ua_pubsub_ns0.h" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner) + * Copyright (c) 2019 Kalycito Infotech Private Limited + */ + +#ifndef UA_PUBSUB_NS0_H_ +#define UA_PUBSUB_NS0_H_ + + +_UA_BEGIN_DECLS + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL /* conditional compilation */ + +UA_StatusCode +UA_Server_initPubSubNS0(UA_Server *server); + +UA_StatusCode +addPubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connection); + +UA_StatusCode +removePubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connection); + +UA_StatusCode +addWriterGroupRepresentation(UA_Server *server, UA_WriterGroup *writerGroup); + +UA_StatusCode +addReaderGroupRepresentation(UA_Server *server, UA_ReaderGroup *readerGroup); + +UA_StatusCode +removeGroupRepresentation(UA_Server *server, UA_WriterGroup *writerGroup); + +UA_StatusCode +addDataSetWriterRepresentation(UA_Server *server, UA_DataSetWriter *dataSetWriter); + +UA_StatusCode +removeDataSetWriterRepresentation(UA_Server *server, UA_DataSetWriter *dataSetWriter); + +UA_StatusCode +addPublishedDataItemsRepresentation(UA_Server *server, UA_PublishedDataSet *publishedDataSet); + +UA_StatusCode +removePublishedDataSetRepresentation(UA_Server *server, UA_PublishedDataSet *publishedDataSet); + +UA_StatusCode +addDataSetReaderRepresentation(UA_Server *server, UA_DataSetReader *dataSetReader); + +UA_StatusCode +removeDataSetReaderRepresentation(UA_Server *server, UA_DataSetReader *dataSetReader); + +#endif /* UA_ENABLE_PUBSUB_INFORMATIONMODEL */ + +_UA_END_DECLS + +#endif /* UA_PUBSUB_NS0_H_ */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_server_internal.h" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2014, 2017 (c) Florian Palm + * Copyright 2015-2016 (c) Sten Grüner + * Copyright 2015 (c) Chris Iatrou + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Julian Grothoff + * Copyright 2019 (c) Kalycito Infotech Private Limited + */ + + + + +_UA_BEGIN_DECLS + +#ifdef UA_ENABLE_PUBSUB +#endif #ifdef UA_ENABLE_DISCOVERY - /* Discovery */ - LIST_HEAD(registeredServer_list, registeredServer_list_entry) registeredServers; // doubly-linked list of registered servers - size_t registeredServersSize; - LIST_HEAD(periodicServerRegisterCallback_list, periodicServerRegisterCallback_entry) periodicServerRegisterCallbacks; // doubly-linked list of current register callbacks - UA_Server_registerServerCallback registerServerCallback; - void* registerServerCallbackData; -# ifdef UA_ENABLE_DISCOVERY_MULTICAST - mdns_daemon_t *mdnsDaemon; -#ifdef _WIN32 - SOCKET mdnsSocket; -#else - int mdnsSocket; #endif - UA_Boolean mdnsMainSrvAdded; -# ifdef UA_ENABLE_MULTITHREADING - pthread_t mdnsThread; - UA_Boolean mdnsRunning; -# endif - LIST_HEAD(serverOnNetwork_list, serverOnNetwork_list_entry) serverOnNetwork; // doubly-linked list of servers on the network (from mDNS) - size_t serverOnNetworkSize; - UA_UInt32 serverOnNetworkRecordIdCounter; - UA_DateTime serverOnNetworkRecordIdLastReset; - // hash mapping domain name to serverOnNetwork list entry - struct serverOnNetwork_hash_entry* serverOnNetworkHash[SERVER_ON_NETWORK_HASH_PRIME]; +#ifdef UA_ENABLE_SUBSCRIPTIONS - UA_Server_serverOnNetworkCallback serverOnNetworkCallback; - void* serverOnNetworkCallbackData; +typedef struct { + UA_MonitoredItem monitoredItem; + void *context; + union { + UA_Server_DataChangeNotificationCallback dataChangeCallback; + /* UA_Server_EventNotificationCallback eventCallback; */ + } callback; +} UA_LocalMonitoredItem; -# endif #endif +typedef enum { + UA_SERVERLIFECYCLE_FRESH, + UA_SERVERLIFECYLE_RUNNING +} UA_ServerLifecycle; + +struct UA_Server { + /* Config */ + UA_ServerConfig config; + UA_DateTime startTime; + UA_DateTime endTime; /* Zeroed out. If a time is set, then the server shuts + * down once the time has been reached */ + + /* Nodestore */ + void *nsCtx; + + UA_ServerLifecycle state; + + /* Security */ + UA_SecureChannelManager secureChannelManager; + UA_SessionManager sessionManager; + UA_Session adminSession; /* Local access to the services (for startup and + * maintenance) uses this Session with all possible + * access rights (Session Id: 1) */ + /* Namespaces */ size_t namespacesSize; UA_String *namespaces; @@ -4661,54 +6454,44 @@ struct UA_Server { /* Callbacks with a repetition interval */ UA_Timer timer; - /* Delayed callbacks */ - SLIST_HEAD(DelayedCallbacksList, UA_DelayedCallback) delayedCallbacks; - - /* Worker threads */ -#ifdef UA_ENABLE_MULTITHREADING - UA_Worker *workers; /* there are nThread workers in a running server */ - UA_DispatchQueue dispatchQueue; /* Dispatch queue for the worker threads */ - pthread_mutex_t dispatchQueue_accessMutex; /* mutex for access to queue */ - pthread_cond_t dispatchQueue_condition; /* so the workers don't spin if the queue is empty */ - pthread_mutex_t dispatchQueue_conditionMutex; /* mutex for access to condition variable */ -#endif + /* WorkQueue and worker threads */ + UA_WorkQueue workQueue; /* For bootstrapping, omit some consistency checks, creating a reference to * the parent and member instantiation */ UA_Boolean bootstrapNS0; - /* Config */ - UA_ServerConfig config; + /* Discovery */ +#ifdef UA_ENABLE_DISCOVERY + UA_DiscoveryManager discoveryManager; +#endif - /* Local access to the services (for startup and maintenance) uses this - * Session with all possible access rights (Session Id: 1) */ - UA_Session adminSession; + /* DataChange Subscriptions */ +#ifdef UA_ENABLE_SUBSCRIPTIONS + /* Num active subscriptions */ + UA_UInt32 numSubscriptions; + /* Num active monitored items */ + UA_UInt32 numMonitoredItems; + /* To be cast to UA_LocalMonitoredItem to get the callback and context */ + LIST_HEAD(LocalMonitoredItems, UA_MonitoredItem) localMonitoredItems; + UA_UInt32 lastLocalMonitoredItemId; +#endif + + /* Publish/Subscribe */ +#ifdef UA_ENABLE_PUBSUB + UA_PubSubManager pubSubManager; +#endif }; /*****************/ /* Node Handling */ /*****************/ -#define UA_Nodestore_get(SERVER, NODEID) \ - (SERVER)->config.nodestore.getNode((SERVER)->config.nodestore.context, NODEID) - -#define UA_Nodestore_release(SERVER, NODEID) \ - (SERVER)->config.nodestore.releaseNode((SERVER)->config.nodestore.context, NODEID) - -#define UA_Nodestore_new(SERVER, NODECLASS) \ - (SERVER)->config.nodestore.newNode((SERVER)->config.nodestore.context, NODECLASS) - -#define UA_Nodestore_getCopy(SERVER, NODEID, OUTNODE) \ - (SERVER)->config.nodestore.getNodeCopy((SERVER)->config.nodestore.context, NODEID, OUTNODE) - -#define UA_Nodestore_insert(SERVER, NODE, OUTNODEID) \ - (SERVER)->config.nodestore.insertNode((SERVER)->config.nodestore.context, NODE, OUTNODEID) - -#define UA_Nodestore_delete(SERVER, NODE) \ - (SERVER)->config.nodestore.deleteNode((SERVER)->config.nodestore.context, NODE) - -#define UA_Nodestore_remove(SERVER, NODEID) \ - (SERVER)->config.nodestore.removeNode((SERVER)->config.nodestore.context, NODEID) +/* Deletes references from the node which are not matching any type in the given + * array. Could be used to e.g. delete all the references, except + * 'HASMODELINGRULE' */ +void UA_Node_deleteReferencesSubset(UA_Node *node, size_t referencesSkipSize, + UA_NodeId* referencesSkip); /* Calls the callback with the node retrieved from the nodestore on top of the * stack. Either a copy or the original node for in-situ editing. Depends on @@ -4720,41 +6503,15 @@ UA_StatusCode UA_Server_editNode(UA_Server *server, UA_Session *session, UA_EditNodeCallback callback, void *data); -/*************/ -/* Callbacks */ -/*************/ - -/* Delayed callbacks are executed when all previously dispatched callbacks are - * finished */ -UA_StatusCode -UA_Server_delayedCallback(UA_Server *server, UA_ServerCallback callback, void *data); - -UA_StatusCode -UA_Server_delayedFree(UA_Server *server, void *data); - -#ifndef UA_ENABLE_MULTITHREADING -/* Execute all delayed callbacks regardless of whether the worker threads have - * finished previous work */ -void UA_Server_cleanupDelayedCallbacks(UA_Server *server); -#else -void UA_Server_cleanupDispatchQueue(UA_Server *server); -#endif - -/* Callback is executed in the same thread or, if possible, dispatched to one of - * the worker threads. */ -void -UA_Server_workerCallback(UA_Server *server, UA_ServerCallback callback, void *data); - /*********************/ /* Utility Functions */ /*********************/ /* A few global NodeId definitions */ extern const UA_NodeId subtypeId; +extern const UA_NodeId hierarchicalReferences; -UA_StatusCode -UA_NumericRange_parseFromString(UA_NumericRange *range, const UA_String *str); - +void setupNs1Uri(UA_Server *server); UA_UInt16 addNamespace(UA_Server *server, const UA_String name); UA_Boolean @@ -4762,33 +6519,52 @@ UA_Node_hasSubTypeOrInstances(const UA_Node *node); /* Recursively searches "upwards" in the tree following specific reference types */ UA_Boolean -isNodeInTree(UA_Nodestore *ns, const UA_NodeId *leafNode, +isNodeInTree(void *nsCtx, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind, const UA_NodeId *referenceTypeIds, size_t referenceTypeIdsSize); -/* Returns an array with the hierarchy of type nodes. The returned array starts - * at the leaf and continues "upwards" in the hierarchy based on the - * ``hasSubType`` references. Since multiple-inheritance is possible in general, - * duplicate entries are removed. */ +/* Returns an array with the hierarchy of nodes. The start nodes are returned as + * well. The returned array starts at the leaf and continues "upwards" or + * "downwards". Duplicate entries are removed. The parameter `walkDownwards` + * indicates the direction of search. */ UA_StatusCode -getTypeHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType, - UA_NodeId **typeHierarchy, size_t *typeHierarchySize); +browseRecursive(UA_Server *server, + size_t startNodesSize, const UA_NodeId *startNodes, + size_t refTypesSize, const UA_NodeId *refTypes, + UA_BrowseDirection browseDirection, UA_Boolean includeStartNodes, + size_t *resultsSize, UA_ExpandedNodeId **results); + +/* If refTypes is non-NULL, tries to realloc and increase the length */ +UA_StatusCode +referenceSubtypes(UA_Server *server, const UA_NodeId *refType, + size_t *refTypesSize, UA_NodeId **refTypes); + +/* Returns the recursive type and interface hierarchy of the node */ +UA_StatusCode +getParentTypeAndInterfaceHierarchy(UA_Server *server, const UA_NodeId *typeNode, + UA_NodeId **typeHierarchy, size_t *typeHierarchySize); /* Returns the type node from the node on the stack top. The type node is pushed * on the stack and returned. */ const UA_Node * getNodeType(UA_Server *server, const UA_Node *node); +/* Write a node attribute with a defined session */ +UA_StatusCode +UA_Server_writeWithSession(UA_Server *server, UA_Session *session, + const UA_WriteValue *value); + + /* Many services come as an array of operations. This function generalizes the * processing of the operations. */ typedef void (*UA_ServiceOperation)(UA_Server *server, UA_Session *session, - void *context, + const void *context, const void *requestOperation, void *responseOperation); UA_StatusCode UA_Server_processServiceOperations(UA_Server *server, UA_Session *session, UA_ServiceOperation operationCallback, - void *context, + const void *context, const size_t *requestOperations, const UA_DataType *requestOperationsType, size_t *responseOperations, @@ -4799,6 +6575,14 @@ UA_Server_processServiceOperations(UA_Server *server, UA_Session *session, /* Check Information Model Consistency */ /***************************************/ +/* Read a node attribute in the context of a "checked-out" node. So the + * attribute will not be copied when possible. The variant then points into the + * node and has UA_VARIANT_DATA_NODELETE set. */ +void +ReadWithNode(const UA_Node *node, UA_Server *server, UA_Session *session, + UA_TimestampsToReturn timestampsToReturn, + const UA_ReadValueId *id, UA_DataValue *v); + UA_StatusCode readValueAttribute(UA_Server *server, UA_Session *session, const UA_VariableNode *vn, UA_DataValue *v); @@ -4837,8 +6621,13 @@ compatibleDataType(UA_Server *server, const UA_NodeId *dataType, UA_Boolean compatibleValueRanks(UA_Int32 valueRank, UA_Int32 constraintValueRank); +struct BrowseOpts { + UA_UInt32 maxReferences; + UA_Boolean recursive; +}; + void -Operation_Browse(UA_Server *server, UA_Session *session, UA_UInt32 *maxrefs, +Operation_Browse(UA_Server *server, UA_Session *session, const UA_UInt32 *maxrefs, const UA_BrowseDescription *descr, UA_BrowseResult *result); UA_DataValue @@ -4846,62 +6635,24 @@ UA_Server_readWithSession(UA_Server *server, UA_Session *session, const UA_ReadValueId *item, UA_TimestampsToReturn timestampsToReturn); -/* Checks if a registration timed out and removes that registration. - * Should be called periodically in main loop */ -void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic); - -# ifdef UA_ENABLE_DISCOVERY_MULTICAST - -UA_StatusCode -initMulticastDiscoveryServer(UA_Server* server); - -void startMulticastDiscoveryServer(UA_Server *server); - -void stopMulticastDiscoveryServer(UA_Server *server); - -UA_StatusCode -iterateMulticastDiscoveryServer(UA_Server* server, UA_DateTime *nextRepeat, - UA_Boolean processIn); - -void destroyMulticastDiscoveryServer(UA_Server* server); - -typedef enum { - UA_DISCOVERY_TCP, /* OPC UA TCP mapping */ - UA_DISCOVERY_TLS /* OPC UA HTTPS mapping */ -} UA_DiscoveryProtocol; - -/* Send a multicast probe to find any other OPC UA server on the network through mDNS. */ -UA_StatusCode -UA_Discovery_multicastQuery(UA_Server* server); - -UA_StatusCode -UA_Discovery_addRecord(UA_Server *server, const UA_String *servername, - const UA_String *hostname, UA_UInt16 port, - const UA_String *path, const UA_DiscoveryProtocol protocol, - UA_Boolean createTxt, const UA_String* capabilites, - size_t *capabilitiesSize); -UA_StatusCode -UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername, - const UA_String *hostname, UA_UInt16 port, - UA_Boolean removeTxt); - -# endif - /*****************************/ /* AddNodes Begin and Finish */ /*****************************/ /* Creates a new node in the nodestore. */ UA_StatusCode -Operation_addNode_begin(UA_Server *server, UA_Session *session, void *nodeContext, - const UA_AddNodesItem *item, const UA_NodeId *parentNodeId, - const UA_NodeId *referenceTypeId, - UA_NodeId *outNewNodeId); +AddNode_raw(UA_Server *server, UA_Session *session, void *nodeContext, + const UA_AddNodesItem *item, UA_NodeId *outNewNodeId); -/* Children, references, type-checking, constructors. */ +/* Check the reference to the parent node; Add references. */ UA_StatusCode -Operation_addNode_finish(UA_Server *server, UA_Session *session, - const UA_NodeId *nodeId); +AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId, + const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId, + const UA_NodeId *typeDefinitionId); + +/* Type-check type-definition; Run the constructors */ +UA_StatusCode +AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId); /**********************/ /* Create Namespace 0 */ @@ -4909,9 +6660,10 @@ Operation_addNode_finish(UA_Server *server, UA_Session *session, UA_StatusCode UA_Server_initNS0(UA_Server *server); -#ifdef __cplusplus -} // extern "C" -#endif +UA_StatusCode writeNs0VariableArray(UA_Server *server, UA_UInt32 id, void *v, + size_t length, const UA_DataType *type); + +_UA_END_DECLS /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_services.h" ***********************************/ @@ -4920,7 +6672,7 @@ UA_StatusCode UA_Server_initNS0(UA_Server *server); * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2017 (c) Florian Palm * Copyright 2015 (c) Sten Grüner * Copyright 2014 (c) LEvertz @@ -4931,11 +6683,10 @@ UA_StatusCode UA_Server_initNS0(UA_Server *server); */ -#ifdef __cplusplus -extern "C" { -#endif +_UA_BEGIN_DECLS + /** * .. _services: * @@ -4962,9 +6713,6 @@ extern "C" { typedef void (*UA_Service)(UA_Server*, UA_Session*, const void *request, void *response); -typedef UA_StatusCode (*UA_InSituService)(UA_Server*, UA_Session*, UA_MessageContext *mc, - const void *request, UA_ResponseHeader *rh); - /** * Discovery Service Set * --------------------- @@ -4997,7 +6745,7 @@ void Service_GetEndpoints(UA_Server *server, UA_Session *session, * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * Returns the Servers known to a Discovery Server. Unlike FindServer, * this Service is only implemented by Discovery Servers. It additionally - * Returns servery which may have been detected trough Multicast */ + * returns servers which may have been detected through Multicast. */ void Service_FindServersOnNetwork(UA_Server *server, UA_Session *session, const UA_FindServersOnNetworkRequest *request, UA_FindServersOnNetworkResponse *response); @@ -5220,8 +6968,8 @@ void Service_UnregisterNodes(UA_Server *server, UA_Session *session, * elements are indexed, such as an array, this Service allows Clients to read * the entire set of indexed values as a composite, to read individual elements * or to read ranges of elements of the composite. */ -UA_StatusCode Service_Read(UA_Server *server, UA_Session *session, UA_MessageContext *mc, - const UA_ReadRequest *request, UA_ResponseHeader *responseHeader); +void Service_Read(UA_Server *server, UA_Session *session, + const UA_ReadRequest *request, UA_ReadResponse *response); /** * Write Service @@ -5231,8 +6979,7 @@ UA_StatusCode Service_Read(UA_Server *server, UA_Session *session, UA_MessageCon * the entire set of indexed values as a composite, to write individual elements * or to write ranges of elements of the composite. */ void Service_Write(UA_Server *server, UA_Session *session, - const UA_WriteRequest *request, - UA_WriteResponse *response); + const UA_WriteRequest *request, UA_WriteResponse *response); /** * HistoryRead Service @@ -5240,7 +6987,10 @@ void Service_Write(UA_Server *server, UA_Session *session, * Used to read historical values or Events of one or more Nodes. Servers may * make historical values available to Clients using this Service, although the * historical values themselves are not visible in the AddressSpace. */ -/* Not Implemented */ +#ifdef UA_ENABLE_HISTORIZING +void Service_HistoryRead(UA_Server *server, UA_Session *session, + const UA_HistoryReadRequest *request, + UA_HistoryReadResponse *response); /** * HistoryUpdate Service @@ -5248,7 +6998,11 @@ void Service_Write(UA_Server *server, UA_Session *session, * Used to update historical values or Events of one or more Nodes. Several * request parameters indicate how the Server is to update the historical value * or Event. Valid actions are Insert, Replace or Delete. */ -/* Not Implemented */ +void +Service_HistoryUpdate(UA_Server *server, UA_Session *session, + const UA_HistoryUpdateRequest *request, + UA_HistoryUpdateResponse *response); +#endif /** * .. _method-services: @@ -5264,9 +7018,13 @@ void Service_Write(UA_Server *server, UA_Session *session, * Used to call (invoke) a methods. Each method call is invoked within the * context of an existing Session. If the Session is terminated, the results of * the method's execution cannot be returned to the Client and are discarded. */ +#ifdef UA_ENABLE_METHODCALLS void Service_Call(UA_Server *server, UA_Session *session, const UA_CallRequest *request, UA_CallResponse *response); +#endif + +#ifdef UA_ENABLE_SUBSCRIPTIONS /** * MonitoredItem Service Set @@ -5396,65 +7154,10 @@ void Service_DeleteSubscriptions(UA_Server *server, UA_Session *session, * its Session. */ /* Not Implemented */ -#ifdef __cplusplus -} // extern "C" -#endif - - -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_namespace0.h" ***********************************/ - -/* WARNING: This is a generated file. - * Any manual changes will be overwritten. */ - -#ifndef UA_NAMESPACE0_H_ -#define UA_NAMESPACE0_H_ - - -#ifdef UA_NO_AMALGAMATION -#else - -/* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */ - -# ifndef UA_Nodestore_remove //this definition is needed to hide this code in the amalgamated .c file - -typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, - const UA_Byte **bufEnd); - -UA_StatusCode -UA_encodeBinary(const void *src, const UA_DataType *type, - UA_Byte **bufPos, const UA_Byte **bufEnd, - UA_exchangeEncodeBuffer exchangeCallback, - void *exchangeHandle) UA_FUNC_ATTR_WARN_UNUSED_RESULT; - -UA_StatusCode -UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, - const UA_DataType *type, size_t customTypesSize, - const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT; - -size_t -UA_calcSizeBinary(void *p, const UA_DataType *type); - -const UA_DataType * -UA_findDataTypeByBinary(const UA_NodeId *typeId); - -# endif // UA_Nodestore_remove - -#endif - - - +#endif /* UA_ENABLE_SUBSCRIPTIONS */ -#ifdef __cplusplus -extern "C" { -#endif - -extern UA_StatusCode ua_namespace0(UA_Server *server); +_UA_END_DECLS -#ifdef __cplusplus -} -#endif - -#endif /* UA_NAMESPACE0_H_ */ /*********************************** amalgamated original file "/home/jvoe/open62541/src/client/ua_client_internal.h" ***********************************/ @@ -5463,7 +7166,7 @@ extern UA_StatusCode ua_namespace0(UA_Server *server); * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2015-2016 (c) Sten Grüner - * Copyright 2015-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2015-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015 (c) Oleksiy Vasylyev * Copyright 2016-2017 (c) Florian Palm * Copyright 2017 (c) Stefan Profanter, fortiss GmbH @@ -5471,6 +7174,10 @@ extern UA_StatusCode ua_namespace0(UA_Server *server); */ +#define UA_INTERNAL + + +_UA_BEGIN_DECLS /**************************/ /* Subscriptions Handling */ @@ -5532,6 +7239,13 @@ UA_Client_Subscriptions_backgroundPublishInactivityCheck(UA_Client *client); #endif /* UA_ENABLE_SUBSCRIPTIONS */ +/**************/ +/* Encryption */ +/**************/ + +UA_StatusCode +signActivateSessionRequest(UA_SecureChannel *channel, + UA_ActivateSessionRequest *request); /**********/ /* Client */ /**********/ @@ -5544,6 +7258,7 @@ typedef struct AsyncServiceCall { void *userdata; UA_DateTime start; UA_UInt32 timeout; + void *responsedata; } AsyncServiceCall; void UA_Client_AsyncService_cancel(UA_Client *client, AsyncServiceCall *ac, @@ -5551,45 +7266,55 @@ void UA_Client_AsyncService_cancel(UA_Client *client, AsyncServiceCall *ac, void UA_Client_AsyncService_removeAll(UA_Client *client, UA_StatusCode statusCode); -typedef enum { - UA_CLIENTAUTHENTICATION_NONE, - UA_CLIENTAUTHENTICATION_USERNAME -} UA_Client_Authentication; +typedef struct CustomCallback { + LIST_ENTRY(CustomCallback) + pointers; + //to find the correct callback + UA_UInt32 callbackId; + + UA_ClientAsyncServiceCallback callback; + + UA_AttributeId attributeId; + const UA_DataType *outDataType; +} CustomCallback; struct UA_Client { /* State */ UA_ClientState state; UA_ClientConfig config; + UA_Timer timer; + UA_StatusCode connectStatus; /* Connection */ UA_Connection connection; - UA_String endpointUrl; /* SecureChannel */ - UA_SecurityPolicy securityPolicy; /* TODO: Move supported policies to the config */ UA_SecureChannel channel; UA_UInt32 requestId; UA_DateTime nextChannelRenewal; - /* Authentication */ - UA_Client_Authentication authenticationMethod; - UA_String username; - UA_String password; - /* Session */ - UA_UserTokenPolicy token; UA_NodeId authenticationToken; UA_UInt32 requestHandle; + UA_Boolean endpointsHandshake; + UA_String endpointUrl; /* Only for the async connect */ + /* Async Service */ + AsyncServiceCall asyncConnectCall; LIST_HEAD(ListOfAsyncServiceCall, AsyncServiceCall) asyncServiceCalls; + /*When using highlevel functions these are the callbacks that can be accessed by the user*/ + LIST_HEAD(ListOfCustomCallback, CustomCallback) customCallbacks; + + /* Work queue */ + UA_WorkQueue workQueue; /* Subscriptions */ #ifdef UA_ENABLE_SUBSCRIPTIONS UA_UInt32 monitoredItemHandles; - LIST_HEAD(ListOfUnacknowledgedNotifications, UA_Client_NotificationsAckNumber) pendingNotificationsAcks; - LIST_HEAD(ListOfClientSubscriptionItems, UA_Client_Subscription) subscriptions; + LIST_HEAD(, UA_Client_NotificationsAckNumber) pendingNotificationsAcks; + LIST_HEAD(, UA_Client_Subscription) subscriptions; UA_UInt16 currentlyOutStandingPublishRequests; #endif @@ -5601,20 +7326,115 @@ struct UA_Client { void setClientState(UA_Client *client, UA_ClientState state); +/* The endpointUrl must be set in the configuration. If the complete + * endpointdescription is not set, a GetEndpoints is performed. */ +UA_StatusCode +UA_Client_connectInternal(UA_Client *client, const UA_String endpointUrl); + +UA_StatusCode +UA_Client_connectTCPSecureChannel(UA_Client *client, const UA_String endpointUrl); + UA_StatusCode -UA_Client_connectInternal(UA_Client *client, const char *endpointUrl, - UA_Boolean endpointsHandshake, UA_Boolean createNewSession); +UA_Client_connectSession(UA_Client *client); UA_StatusCode -UA_Client_getEndpointsInternal(UA_Client *client, size_t* endpointDescriptionsSize, - UA_EndpointDescription** endpointDescriptions); +UA_Client_getEndpointsInternal(UA_Client *client, const UA_String endpointUrl, + size_t *endpointDescriptionsSize, + UA_EndpointDescription **endpointDescriptions); /* Receive and process messages until a synchronous message arrives or the * timout finishes */ UA_StatusCode -receiveServiceResponse(UA_Client *client, void *response, const UA_DataType *responseType, - UA_DateTime maxDate, UA_UInt32 *synchronousRequestId); +receivePacketAsync(UA_Client *client); + +UA_StatusCode +processACKResponseAsync(void *application, UA_Connection *connection, + UA_ByteString *chunk); + +UA_StatusCode +processOPNResponseAsync(void *application, UA_Connection *connection, + UA_ByteString *chunk); + +UA_StatusCode +openSecureChannel(UA_Client *client, UA_Boolean renew); + +UA_StatusCode +receiveServiceResponse(UA_Client *client, void *response, + const UA_DataType *responseType, UA_DateTime maxDate, + const UA_UInt32 *synchronousRequestId); +UA_StatusCode +receiveServiceResponseAsync(UA_Client *client, void *response, + const UA_DataType *responseType); + +UA_StatusCode +UA_Client_connect_iterate (UA_Client *client); + +void +setUserIdentityPolicyId(const UA_EndpointDescription *endpoint, + const UA_DataType *tokenType, + UA_String *policyId, UA_String *securityPolicyUri); + +UA_SecurityPolicy * +getSecurityPolicy(UA_Client *client, UA_String policyUri); + +UA_StatusCode +encryptUserIdentityToken(UA_Client *client, const UA_String *userTokenSecurityPolicy, + UA_ExtensionObject *userIdentityToken); + +_UA_END_DECLS + + +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/namespace0_generated.h" ***********************************/ + +/* WARNING: This is a generated file. + * Any manual changes will be overwritten. */ + +#ifndef NAMESPACE0_GENERATED_H_ +#define NAMESPACE0_GENERATED_H_ + + +#ifdef UA_ENABLE_AMALGAMATION + +/* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */ + +# ifndef UA_INTERNAL //this definition is needed to hide this code in the amalgamated .c file + +typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, + const UA_Byte **bufEnd); + +UA_StatusCode +UA_encodeBinary(const void *src, const UA_DataType *type, + UA_Byte **bufPos, const UA_Byte **bufEnd, + UA_exchangeEncodeBuffer exchangeCallback, + void *exchangeHandle) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +UA_StatusCode +UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, + const UA_DataType *type, size_t customTypesSize, + const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT; + +size_t +UA_calcSizeBinary(void *p, const UA_DataType *type); + +const UA_DataType * +UA_findDataTypeByBinary(const UA_NodeId *typeId); + +# endif // UA_INTERNAL + +#else // UA_ENABLE_AMALGAMATION +#endif + + + + +_UA_BEGIN_DECLS + +extern UA_StatusCode namespace0_generated(UA_Server *server); + +_UA_END_DECLS + +#endif /* NAMESPACE0_GENERATED_H_ */ /*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_types.c" ***********************************/ @@ -5622,7 +7442,7 @@ receiveServiceResponse(UA_Client *client, void *response, const UA_DataType *res * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014, 2016-2017 (c) Florian Palm * Copyright 2014-2016 (c) Sten Grüner * Copyright 2014 (c) Leon Urbas @@ -5636,6 +7456,7 @@ receiveServiceResponse(UA_Client *client, void *response, const UA_DataType *res + /* Datatype Handling * ----------------- * This file contains handling functions for the builtin types and functions @@ -5651,6 +7472,13 @@ const UA_Guid UA_GUID_NULL = {0, 0, 0, {0,0,0,0,0,0,0,0}}; const UA_NodeId UA_NODEID_NULL = {0, UA_NODEIDTYPE_NUMERIC, {0}}; const UA_ExpandedNodeId UA_EXPANDEDNODEID_NULL = {{0, UA_NODEIDTYPE_NUMERIC, {0}}, {0, NULL}, 0}; +typedef UA_StatusCode (*UA_copySignature)(const void *src, void *dst, + const UA_DataType *type); +typedef void (*UA_clearSignature)(void *p, const UA_DataType *type); + +extern const UA_copySignature copyJumpTable[UA_DATATYPEKINDS]; +extern const UA_clearSignature clearJumpTable[UA_DATATYPEKINDS]; + /* TODO: The standard-defined types are ordered. See if binary search is * more efficient. */ const UA_DataType * @@ -5702,36 +7530,60 @@ UA_UInt32_random(void) { /* Builtin Types */ /*****************/ -static void deleteMembers_noInit(void *p, const UA_DataType *type); -static UA_StatusCode copy_noInit(const void *src, void *dst, const UA_DataType *type); - UA_String -UA_String_fromChars(char const src[]) { - UA_String str; - str.length = strlen(src); - if(str.length > 0) { - str.data = (u8*)UA_malloc(str.length); - if(!str.data) - return UA_STRING_NULL; - memcpy(str.data, src, str.length); +UA_String_fromChars(const char *src) { + UA_String s; s.length = 0; s.data = NULL; + if(!src) + return s; + s.length = strlen(src); + if(s.length > 0) { + s.data = (u8*)UA_malloc(s.length); + if(!s.data) { + s.length = 0; + return s; + } + memcpy(s.data, src, s.length); } else { - str.data = (u8*)UA_EMPTY_ARRAY_SENTINEL; + s.data = (u8*)UA_EMPTY_ARRAY_SENTINEL; } - return str; + return s; } UA_Boolean UA_String_equal(const UA_String *s1, const UA_String *s2) { if(s1->length != s2->length) return false; + if(s1->length == 0) + return true; i32 is = memcmp((char const*)s1->data, (char const*)s2->data, s1->length); return (is == 0) ? true : false; } +static UA_StatusCode +String_copy(UA_String const *src, UA_String *dst, const UA_DataType *_) { + UA_StatusCode retval = UA_Array_copy(src->data, src->length, (void**)&dst->data, + &UA_TYPES[UA_TYPES_BYTE]); + if(retval == UA_STATUSCODE_GOOD) + dst->length = src->length; + return retval; +} + +static void +String_clear(UA_String *s, const UA_DataType *_) { + UA_Array_delete(s->data, s->length, &UA_TYPES[UA_TYPES_BYTE]); +} + +/* QualifiedName */ +static UA_StatusCode +QualifiedName_copy(const UA_QualifiedName *src, UA_QualifiedName *dst, const UA_DataType *_) { + dst->namespaceIndex = src->namespaceIndex; + return String_copy(&src->name, &dst->name, NULL); +} + static void -String_deleteMembers(UA_String *s, const UA_DataType *_) { - UA_free((void*)((uintptr_t)s->data & ~(uintptr_t)UA_EMPTY_ARRAY_SENTINEL)); +QualifiedName_clear(UA_QualifiedName *p, const UA_DataType *_) { + String_clear(&p->name, NULL); } UA_Boolean @@ -5771,41 +7623,6 @@ UA_DateTime_toStruct(UA_DateTime t) { return dateTimeStruct; } -static void -printNumber(u16 n, u8 *pos, size_t digits) { - for(size_t i = digits; i > 0; --i) { - pos[i-1] = (u8)((n % 10) + '0'); - n = n / 10; - } -} - -UA_String -UA_DateTime_toString(UA_DateTime t) { - /* length of the string is 31 (plus \0 at the end) */ - UA_String str = {31, (u8*)UA_malloc(32)}; - if(!str.data) - return UA_STRING_NULL; - UA_DateTimeStruct tSt = UA_DateTime_toStruct(t); - printNumber(tSt.month, str.data, 2); - str.data[2] = '/'; - printNumber(tSt.day, &str.data[3], 2); - str.data[5] = '/'; - printNumber(tSt.year, &str.data[6], 4); - str.data[10] = ' '; - printNumber(tSt.hour, &str.data[11], 2); - str.data[13] = ':'; - printNumber(tSt.min, &str.data[14], 2); - str.data[16] = ':'; - printNumber(tSt.sec, &str.data[17], 2); - str.data[19] = '.'; - printNumber(tSt.milliSec, &str.data[20], 3); - str.data[23] = '.'; - printNumber(tSt.microSec, &str.data[24], 3); - str.data[27] = '.'; - printNumber(tSt.nanoSec, &str.data[28], 3); - return str; -} - /* Guid */ UA_Boolean UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2) { @@ -5849,11 +7666,11 @@ UA_ByteString_allocBuffer(UA_ByteString *bs, size_t length) { /* NodeId */ static void -NodeId_deleteMembers(UA_NodeId *p, const UA_DataType *_) { +NodeId_clear(UA_NodeId *p, const UA_DataType *_) { switch(p->identifierType) { case UA_NODEIDTYPE_STRING: case UA_NODEIDTYPE_BYTESTRING: - String_deleteMembers(&p->identifier.string, NULL); + String_clear(&p->identifier.string, NULL); break; default: break; } @@ -5889,7 +7706,7 @@ UA_Boolean UA_NodeId_isNull(const UA_NodeId *p) { if(p->namespaceIndex != 0) return false; - switch(p->identifierType) { + switch (p->identifierType) { case UA_NODEIDTYPE_NUMERIC: return (p->identifier.numeric == 0); case UA_NODEIDTYPE_STRING: @@ -5902,38 +7719,73 @@ UA_NodeId_isNull(const UA_NodeId *p) { return false; } -UA_Boolean -UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) { - if(n1 == NULL || n2 == NULL) - return false; - if(n1->namespaceIndex != n2->namespaceIndex || - n1->identifierType!=n2->identifierType) - return false; +/* Absolute ordering for NodeIds */ +UA_Order +UA_NodeId_order(const UA_NodeId *n1, const UA_NodeId *n2) { + /* Compare namespaceIndex */ + if(n1->namespaceIndex < n2->namespaceIndex) + return UA_ORDER_LESS; + if(n1->namespaceIndex > n2->namespaceIndex) + return UA_ORDER_MORE; + + /* Compare identifierType */ + if(n1->identifierType < n2->identifierType) + return UA_ORDER_LESS; + if(n1->identifierType > n2->identifierType) + return UA_ORDER_MORE; + + /* Compare the identifier */ switch(n1->identifierType) { case UA_NODEIDTYPE_NUMERIC: - return (n1->identifier.numeric == n2->identifier.numeric); - case UA_NODEIDTYPE_STRING: - return UA_String_equal(&n1->identifier.string, - &n2->identifier.string); + if(n1->identifier.numeric < n2->identifier.numeric) + return UA_ORDER_LESS; + if(n1->identifier.numeric > n2->identifier.numeric) + return UA_ORDER_MORE; + break; case UA_NODEIDTYPE_GUID: - return UA_Guid_equal(&n1->identifier.guid, - &n2->identifier.guid); - case UA_NODEIDTYPE_BYTESTRING: - return UA_ByteString_equal(&n1->identifier.byteString, - &n2->identifier.byteString); + if(n1->identifier.guid.data1 < n2->identifier.guid.data1) { + return UA_ORDER_LESS; + } else if(n1->identifier.guid.data1 > n2->identifier.guid.data1) { + return UA_ORDER_MORE; + } else if(n1->identifier.guid.data2 < n2->identifier.guid.data2) { + return UA_ORDER_LESS; + } else if(n1->identifier.guid.data2 > n2->identifier.guid.data2) { + return UA_ORDER_MORE; + } else if(n1->identifier.guid.data3 < n2->identifier.guid.data3) { + return UA_ORDER_LESS; + } else if(n1->identifier.guid.data3 > n2->identifier.guid.data3) { + return UA_ORDER_MORE; + } else { + int cmp = memcmp(n1->identifier.guid.data4, n2->identifier.guid.data4, 8); + + if(cmp < 0) return UA_ORDER_LESS; + if(cmp > 0) return UA_ORDER_MORE; + + } + + break; + case UA_NODEIDTYPE_STRING: + case UA_NODEIDTYPE_BYTESTRING: { + size_t minLength = UA_MIN(n1->identifier.string.length, n2->identifier.string.length); + int cmp = strncmp((const char*)n1->identifier.string.data, + (const char*)n2->identifier.string.data, + minLength); + if(cmp < 0) + return UA_ORDER_LESS; + if(cmp > 0) + return UA_ORDER_MORE; + + if(n1->identifier.string.length < n2->identifier.string.length) + return UA_ORDER_LESS; + if(n1->identifier.string.length > n2->identifier.string.length) + return UA_ORDER_MORE; + break; + } + default: + break; } - return false; -} -UA_Boolean -UA_ExpandedNodeId_equal(const UA_ExpandedNodeId *n1, const UA_ExpandedNodeId *n2) { - if(n1 == NULL || n2 == NULL) - return false; - if(n1->serverIndex != n2->serverIndex) - return false; - if(!UA_String_equal(&n1->namespaceUri, &n2->namespaceUri)) - return false; - return UA_NodeId_equal(&n1->nodeId, &n2->nodeId); + return UA_ORDER_EQ; } /* FNV non-cryptographic hash function. See @@ -5965,9 +7817,9 @@ UA_NodeId_hash(const UA_NodeId *n) { /* ExpandedNodeId */ static void -ExpandedNodeId_deleteMembers(UA_ExpandedNodeId *p, const UA_DataType *_) { - NodeId_deleteMembers(&p->nodeId, _); - String_deleteMembers(&p->namespaceUri, NULL); +ExpandedNodeId_clear(UA_ExpandedNodeId *p, const UA_DataType *_) { + NodeId_clear(&p->nodeId, _); + String_clear(&p->namespaceUri, NULL); } static UA_StatusCode @@ -5979,15 +7831,45 @@ ExpandedNodeId_copy(UA_ExpandedNodeId const *src, UA_ExpandedNodeId *dst, return retval; } +UA_Order +UA_ExpandedNodeId_order(const UA_ExpandedNodeId *n1, + const UA_ExpandedNodeId *n2) { + if(n1->serverIndex > n2->serverIndex) + return UA_ORDER_MORE; + if(n1->serverIndex < n2->serverIndex) + return UA_ORDER_LESS; + if(n1->namespaceUri.length > 0) { + if(n1->namespaceUri.length > n2->namespaceUri.length) + return UA_ORDER_MORE; + if(n1->namespaceUri.length < n2->namespaceUri.length) + return UA_ORDER_LESS; + int cmp = strncmp((const char*)n1->namespaceUri.data, + (const char*)n2->namespaceUri.data, + n1->namespaceUri.length); + if(cmp < 0) + return UA_ORDER_LESS; + if(cmp > 0) + return UA_ORDER_MORE; + } + return UA_NodeId_order(&n1->nodeId, &n2->nodeId); +} + +u32 +UA_ExpandedNodeId_hash(const UA_ExpandedNodeId *n) { + u32 h = UA_NodeId_hash(&n->nodeId); + h = fnv32(h, (const UA_Byte*)&n->serverIndex, 4); + return fnv32(h, n->namespaceUri.data, n->namespaceUri.length); +} + /* ExtensionObject */ static void -ExtensionObject_deleteMembers(UA_ExtensionObject *p, const UA_DataType *_) { +ExtensionObject_clear(UA_ExtensionObject *p, const UA_DataType *_) { switch(p->encoding) { case UA_EXTENSIONOBJECT_ENCODED_NOBODY: case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING: case UA_EXTENSIONOBJECT_ENCODED_XML: - NodeId_deleteMembers(&p->content.encoded.typeId, NULL); - String_deleteMembers(&p->content.encoded.body, NULL); + NodeId_clear(&p->content.encoded.typeId, NULL); + String_clear(&p->content.encoded.body, NULL); break; case UA_EXTENSIONOBJECT_DECODED: if(p->content.decoded.data) @@ -6029,7 +7911,7 @@ ExtensionObject_copy(UA_ExtensionObject const *src, UA_ExtensionObject *dst, /* Variant */ static void -Variant_deletemembers(UA_Variant *p, const UA_DataType *_) { +Variant_clear(UA_Variant *p, const UA_DataType *_) { if(p->storageType != UA_VARIANT_DATA) return; if(p->type && p->data > UA_EMPTY_ARRAY_SENTINEL) { @@ -6172,7 +8054,7 @@ computeStrides(const UA_Variant *v, const UA_NumericRange range, *stride = v->arrayLength; /* So it can be copied as a contiguous block. */ *first = 0; size_t running_dimssize = 1; - bool found_contiguous = false; + UA_Boolean found_contiguous = false; for(size_t k = dims_count; k > 0;) { --k; size_t dimrange = 1 + realmax[k] - range.dimensions[k].min; @@ -6189,11 +8071,11 @@ computeStrides(const UA_Variant *v, const UA_NumericRange range, } /* Is the type string-like? */ -static bool +static UA_Boolean isStringLike(const UA_DataType *type) { - if(type->membersSize == 1 && type->members[0].isArray && - type->members[0].namespaceZero && - type->members[0].memberTypeIndex == UA_TYPES_BYTE) + if(type == &UA_TYPES[UA_TYPES_STRING] || + type == &UA_TYPES[UA_TYPES_BYTESTRING] || + type == &UA_TYPES[UA_TYPES_XMLELEMENT]) return true; return false; } @@ -6226,8 +8108,8 @@ UA_Variant_copyRange(const UA_Variant *src, UA_Variant *dst, const UA_NumericRange range) { if(!src->type) return UA_STATUSCODE_BADINVALIDARGUMENT; - bool isScalar = UA_Variant_isScalar(src); - bool stringLike = isStringLike(src->type); + UA_Boolean isScalar = UA_Variant_isScalar(src); + UA_Boolean stringLike = isStringLike(src->type); UA_Variant arraySrc; /* Extract the range for copying at this level. The remaining range is dealt @@ -6340,7 +8222,7 @@ UA_Variant_copyRange(const UA_Variant *src, UA_Variant *dst, dst->arrayDimensions = (u32*)UA_Array_new(thisrange.dimensionsSize, &UA_TYPES[UA_TYPES_UINT32]); if(!dst->arrayDimensions) { - Variant_deletemembers(dst, NULL); + Variant_clear(dst, NULL); return UA_STATUSCODE_BADOUTOFMEMORY; } dst->arrayDimensionsSize = thisrange.dimensionsSize; @@ -6355,7 +8237,7 @@ UA_Variant_copyRange(const UA_Variant *src, UA_Variant *dst, * variant and strings. This is already possible for reading... */ static UA_StatusCode Variant_setRange(UA_Variant *v, void *array, size_t arraySize, - const UA_NumericRange range, bool copy) { + const UA_NumericRange range, UA_Boolean copy) { /* Compute the strides */ size_t count, block, stride, first; UA_StatusCode retval = computeStrides(v, range, &count, @@ -6379,7 +8261,7 @@ Variant_setRange(UA_Variant *v, void *array, size_t arraySize, } else { for(size_t i = 0; i < block_count; ++i) { for(size_t j = 0; j < block; ++j) { - deleteMembers_noInit((void*)nextdst, v->type); + clearJumpTable[v->type->typeKind]((void*)nextdst, v->type); retval |= UA_copy((void*)nextsrc, (void*)nextdst, v->type); nextdst += elem_size; nextsrc += elem_size; @@ -6410,9 +8292,9 @@ UA_Variant_setRangeCopy(UA_Variant *v, const void *array, /* LocalizedText */ static void -LocalizedText_deleteMembers(UA_LocalizedText *p, const UA_DataType *_) { - String_deleteMembers(&p->locale, NULL); - String_deleteMembers(&p->text, NULL); +LocalizedText_clear(UA_LocalizedText *p, const UA_DataType *_) { + String_clear(&p->locale, NULL); + String_clear(&p->text, NULL); } static UA_StatusCode @@ -6425,8 +8307,8 @@ LocalizedText_copy(UA_LocalizedText const *src, UA_LocalizedText *dst, /* DataValue */ static void -DataValue_deleteMembers(UA_DataValue *p, const UA_DataType *_) { - Variant_deletemembers(&p->value, NULL); +DataValue_clear(UA_DataValue *p, const UA_DataType *_) { + Variant_clear(&p->value, NULL); } static UA_StatusCode @@ -6436,16 +8318,16 @@ DataValue_copy(UA_DataValue const *src, UA_DataValue *dst, UA_Variant_init(&dst->value); UA_StatusCode retval = Variant_copy(&src->value, &dst->value, NULL); if(retval != UA_STATUSCODE_GOOD) - DataValue_deleteMembers(dst, NULL); + DataValue_clear(dst, NULL); return retval; } /* DiagnosticInfo */ static void -DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p, const UA_DataType *_) { - String_deleteMembers(&p->additionalInfo, NULL); +DiagnosticInfo_clear(UA_DiagnosticInfo *p, const UA_DataType *_) { + String_clear(&p->additionalInfo, NULL); if(p->hasInnerDiagnosticInfo && p->innerDiagnosticInfo) { - DiagnosticInfo_deleteMembers(p->innerDiagnosticInfo, NULL); + DiagnosticInfo_clear(p->innerDiagnosticInfo, NULL); UA_free(p->innerDiagnosticInfo); } } @@ -6513,53 +8395,19 @@ copyGuid(const UA_Guid *src, UA_Guid *dst, const UA_DataType *_) { return UA_STATUSCODE_GOOD; } -typedef UA_StatusCode -(*UA_copySignature)(const void *src, void *dst, const UA_DataType *type); - -static const UA_copySignature copyJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = { - (UA_copySignature)copyByte, // Boolean - (UA_copySignature)copyByte, // SByte - (UA_copySignature)copyByte, // Byte - (UA_copySignature)copy2Byte, // Int16 - (UA_copySignature)copy2Byte, // UInt16 - (UA_copySignature)copy4Byte, // Int32 - (UA_copySignature)copy4Byte, // UInt32 - (UA_copySignature)copy8Byte, // Int64 - (UA_copySignature)copy8Byte, // UInt64 - (UA_copySignature)copy4Byte, // Float - (UA_copySignature)copy8Byte, // Double - (UA_copySignature)copy_noInit, // String - (UA_copySignature)copy8Byte, // DateTime - (UA_copySignature)copyGuid, // Guid - (UA_copySignature)copy_noInit, // ByteString - (UA_copySignature)copy_noInit, // XmlElement - (UA_copySignature)NodeId_copy, - (UA_copySignature)ExpandedNodeId_copy, - (UA_copySignature)copy4Byte, // StatusCode - (UA_copySignature)copy_noInit, // QualifiedName - (UA_copySignature)LocalizedText_copy, // LocalizedText - (UA_copySignature)ExtensionObject_copy, - (UA_copySignature)DataValue_copy, - (UA_copySignature)Variant_copy, - (UA_copySignature)DiagnosticInfo_copy, - (UA_copySignature)copy_noInit // all others -}; - static UA_StatusCode -copy_noInit(const void *src, void *dst, const UA_DataType *type) { +copyStructure(const void *src, void *dst, const UA_DataType *type) { UA_StatusCode retval = UA_STATUSCODE_GOOD; uintptr_t ptrs = (uintptr_t)src; uintptr_t ptrd = (uintptr_t)dst; - u8 membersSize = type->membersSize; - for(size_t i = 0; i < membersSize; ++i) { + const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; + for(size_t i = 0; i < type->membersSize; ++i) { const UA_DataTypeMember *m= &type->members[i]; - const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; const UA_DataType *mt = &typelists[!m->namespaceZero][m->memberTypeIndex]; if(!m->isArray) { ptrs += m->padding; ptrd += m->padding; - size_t fi = mt->builtin ? mt->typeIndex : UA_BUILTIN_TYPES_COUNT; - retval |= copyJumpTable[fi]((const void*)ptrs, (void*)ptrd, mt); + retval |= copyJumpTable[mt->typeKind]((const void*)ptrs, (void*)ptrd, mt); ptrs += mt->memSize; ptrd += mt->memSize; } else { @@ -6581,61 +8429,64 @@ copy_noInit(const void *src, void *dst, const UA_DataType *type) { return retval; } +static UA_StatusCode +copyNotImplemented(const void *src, void *dst, const UA_DataType *type) { + return UA_STATUSCODE_BADNOTIMPLEMENTED; +} + +const UA_copySignature copyJumpTable[UA_DATATYPEKINDS] = { + (UA_copySignature)copyByte, /* Boolean */ + (UA_copySignature)copyByte, /* SByte */ + (UA_copySignature)copyByte, /* Byte */ + (UA_copySignature)copy2Byte, /* Int16 */ + (UA_copySignature)copy2Byte, /* UInt16 */ + (UA_copySignature)copy4Byte, /* Int32 */ + (UA_copySignature)copy4Byte, /* UInt32 */ + (UA_copySignature)copy8Byte, /* Int64 */ + (UA_copySignature)copy8Byte, /* UInt64 */ + (UA_copySignature)copy4Byte, /* Float */ + (UA_copySignature)copy8Byte, /* Double */ + (UA_copySignature)String_copy, + (UA_copySignature)copy8Byte, /* DateTime */ + (UA_copySignature)copyGuid, /* Guid */ + (UA_copySignature)String_copy, /* ByteString */ + (UA_copySignature)String_copy, /* XmlElement */ + (UA_copySignature)NodeId_copy, + (UA_copySignature)ExpandedNodeId_copy, + (UA_copySignature)copy4Byte, /* StatusCode */ + (UA_copySignature)QualifiedName_copy, + (UA_copySignature)LocalizedText_copy, + (UA_copySignature)ExtensionObject_copy, + (UA_copySignature)DataValue_copy, + (UA_copySignature)Variant_copy, + (UA_copySignature)DiagnosticInfo_copy, + (UA_copySignature)copyNotImplemented, /* Decimal */ + (UA_copySignature)copy4Byte, /* Enumeration */ + (UA_copySignature)copyStructure, + (UA_copySignature)copyNotImplemented, /* Structure with Optional Fields */ + (UA_copySignature)copyNotImplemented, /* Union */ + (UA_copySignature)copyNotImplemented /* BitfieldCluster*/ +}; + UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *type) { memset(dst, 0, type->memSize); /* init */ - UA_StatusCode retval = copy_noInit(src, dst, type); + UA_StatusCode retval = copyJumpTable[type->typeKind](src, dst, type); if(retval != UA_STATUSCODE_GOOD) - UA_deleteMembers(dst, type); + UA_clear(dst, type); return retval; } -static void nopDeleteMembers(void *p, const UA_DataType *type) { } - -typedef void (*UA_deleteMembersSignature)(void *p, const UA_DataType *type); - -static const -UA_deleteMembersSignature deleteMembersJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = { - (UA_deleteMembersSignature)nopDeleteMembers, // Boolean - (UA_deleteMembersSignature)nopDeleteMembers, // SByte - (UA_deleteMembersSignature)nopDeleteMembers, // Byte - (UA_deleteMembersSignature)nopDeleteMembers, // Int16 - (UA_deleteMembersSignature)nopDeleteMembers, // UInt16 - (UA_deleteMembersSignature)nopDeleteMembers, // Int32 - (UA_deleteMembersSignature)nopDeleteMembers, // UInt32 - (UA_deleteMembersSignature)nopDeleteMembers, // Int64 - (UA_deleteMembersSignature)nopDeleteMembers, // UInt64 - (UA_deleteMembersSignature)nopDeleteMembers, // Float - (UA_deleteMembersSignature)nopDeleteMembers, // Double - (UA_deleteMembersSignature)String_deleteMembers, // String - (UA_deleteMembersSignature)nopDeleteMembers, // DateTime - (UA_deleteMembersSignature)nopDeleteMembers, // Guid - (UA_deleteMembersSignature)String_deleteMembers, // ByteString - (UA_deleteMembersSignature)String_deleteMembers, // XmlElement - (UA_deleteMembersSignature)NodeId_deleteMembers, - (UA_deleteMembersSignature)ExpandedNodeId_deleteMembers, // ExpandedNodeId - (UA_deleteMembersSignature)nopDeleteMembers, // StatusCode - (UA_deleteMembersSignature)deleteMembers_noInit, // QualifiedName - (UA_deleteMembersSignature)LocalizedText_deleteMembers, // LocalizedText - (UA_deleteMembersSignature)ExtensionObject_deleteMembers, - (UA_deleteMembersSignature)DataValue_deleteMembers, - (UA_deleteMembersSignature)Variant_deletemembers, - (UA_deleteMembersSignature)DiagnosticInfo_deleteMembers, - (UA_deleteMembersSignature)deleteMembers_noInit, -}; - static void -deleteMembers_noInit(void *p, const UA_DataType *type) { +clearStructure(void *p, const UA_DataType *type) { uintptr_t ptr = (uintptr_t)p; - u8 membersSize = type->membersSize; - for(size_t i = 0; i < membersSize; ++i) { - const UA_DataTypeMember *m= &type->members[i]; - const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; + const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; + for(size_t i = 0; i < type->membersSize; ++i) { + const UA_DataTypeMember *m = &type->members[i]; const UA_DataType *mt = &typelists[!m->namespaceZero][m->memberTypeIndex]; if(!m->isArray) { ptr += m->padding; - size_t fi = mt->builtin ? mt->typeIndex : UA_BUILTIN_TYPES_COUNT; - deleteMembersJumpTable[fi]((void*)ptr, mt); + clearJumpTable[mt->typeKind]((void*)ptr, mt); ptr += mt->memSize; } else { ptr += m->padding; @@ -6647,15 +8498,52 @@ deleteMembers_noInit(void *p, const UA_DataType *type) { } } +static void nopClear(void *p, const UA_DataType *type) { } + +const +UA_clearSignature clearJumpTable[UA_DATATYPEKINDS] = { + (UA_clearSignature)nopClear, /* Boolean */ + (UA_clearSignature)nopClear, /* SByte */ + (UA_clearSignature)nopClear, /* Byte */ + (UA_clearSignature)nopClear, /* Int16 */ + (UA_clearSignature)nopClear, /* UInt16 */ + (UA_clearSignature)nopClear, /* Int32 */ + (UA_clearSignature)nopClear, /* UInt32 */ + (UA_clearSignature)nopClear, /* Int64 */ + (UA_clearSignature)nopClear, /* UInt64 */ + (UA_clearSignature)nopClear, /* Float */ + (UA_clearSignature)nopClear, /* Double */ + (UA_clearSignature)String_clear, /* String */ + (UA_clearSignature)nopClear, /* DateTime */ + (UA_clearSignature)nopClear, /* Guid */ + (UA_clearSignature)String_clear, /* ByteString */ + (UA_clearSignature)String_clear, /* XmlElement */ + (UA_clearSignature)NodeId_clear, + (UA_clearSignature)ExpandedNodeId_clear, + (UA_clearSignature)nopClear, /* StatusCode */ + (UA_clearSignature)QualifiedName_clear, + (UA_clearSignature)LocalizedText_clear, + (UA_clearSignature)ExtensionObject_clear, + (UA_clearSignature)DataValue_clear, + (UA_clearSignature)Variant_clear, + (UA_clearSignature)DiagnosticInfo_clear, + (UA_clearSignature)nopClear, /* Decimal, not implemented */ + (UA_clearSignature)nopClear, /* Enumeration */ + (UA_clearSignature)clearStructure, + (UA_clearSignature)nopClear, /* Struct with Optional Fields, not implemented*/ + (UA_clearSignature)nopClear, /* Union, not implemented*/ + (UA_clearSignature)nopClear /* BitfieldCluster, not implemented*/ +}; + void -UA_deleteMembers(void *p, const UA_DataType *type) { - deleteMembers_noInit(p, type); +UA_clear(void *p, const UA_DataType *type) { + clearJumpTable[type->typeKind](p, type); memset(p, 0, type->memSize); /* init */ } void UA_delete(void *p, const UA_DataType *type) { - deleteMembers_noInit(p, type); + clearJumpTable[type->typeKind](p, type); UA_free(p); } @@ -6716,7 +8604,7 @@ UA_Array_delete(void *p, size_t size, const UA_DataType *type) { if(!type->pointerFree) { uintptr_t ptr = (uintptr_t)p; for(size_t i = 0; i < size; ++i) { - UA_deleteMembers((void*)ptr, type); + UA_clear((void*)ptr, type); ptr += type->memSize; } } @@ -6724,21 +8612,98 @@ UA_Array_delete(void *p, size_t size, const UA_DataType *type) { } UA_Boolean -isDataTypeNumeric(const UA_DataType *type) { - // All data types ids between UA_TYPES_BOOLEAN and UA_TYPES_DOUBLE are numeric - for (int i = UA_TYPES_BOOLEAN; i <= UA_TYPES_DOUBLE; ++i) - if (&UA_TYPES[i] == type) +UA_DataType_isNumeric(const UA_DataType *type) { + /* All data types between UA_TYPES_BOOLEAN and UA_TYPES_DOUBLE are numeric */ + for(size_t i = UA_TYPES_BOOLEAN; i <= UA_TYPES_DOUBLE; ++i) + if(&UA_TYPES[i] == type) return true; return false; } +/**********************/ +/* Parse NumericRange */ +/**********************/ + +static size_t +readDimension(UA_Byte *buf, size_t buflen, UA_NumericRangeDimension *dim) { + size_t progress = UA_readNumber(buf, buflen, &dim->min); + if(progress == 0) + return 0; + if(buflen <= progress + 1 || buf[progress] != ':') { + dim->max = dim->min; + return progress; + } + + ++progress; + size_t progress2 = UA_readNumber(&buf[progress], buflen - progress, &dim->max); + if(progress2 == 0) + return 0; + + /* invalid range */ + if(dim->min >= dim->max) + return 0; + + return progress + progress2; +} + +UA_StatusCode +UA_NumericRange_parseFromString(UA_NumericRange *range, const UA_String *str) { + size_t idx = 0; + size_t dimensionsMax = 0; + UA_NumericRangeDimension *dimensions = NULL; + UA_StatusCode retval = UA_STATUSCODE_GOOD; + size_t offset = 0; + while(true) { + /* alloc dimensions */ + if(idx >= dimensionsMax) { + UA_NumericRangeDimension *newds; + size_t newdssize = sizeof(UA_NumericRangeDimension) * (dimensionsMax + 2); + newds = (UA_NumericRangeDimension*)UA_realloc(dimensions, newdssize); + if(!newds) { + retval = UA_STATUSCODE_BADOUTOFMEMORY; + break; + } + dimensions = newds; + dimensionsMax = dimensionsMax + 2; + } + + /* read the dimension */ + size_t progress = readDimension(&str->data[offset], str->length - offset, + &dimensions[idx]); + if(progress == 0) { + retval = UA_STATUSCODE_BADINDEXRANGEINVALID; + break; + } + offset += progress; + ++idx; + + /* loop into the next dimension */ + if(offset >= str->length) + break; + + if(str->data[offset] != ',') { + retval = UA_STATUSCODE_BADINDEXRANGEINVALID; + break; + } + ++offset; + } + + if(retval == UA_STATUSCODE_GOOD && idx > 0) { + range->dimensions = dimensions; + range->dimensionsSize = idx; + } else + UA_free(dimensions); + + return retval; +} + /*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_types_encoding_binary.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2017 (c) Florian Palm * Copyright 2014-2016 (c) Sten Grüner * Copyright 2014 (c) Leon Urbas @@ -6752,6 +8717,8 @@ isDataTypeNumeric(const UA_DataType *type) { */ + + /** * Type Encoding and Decoding * -------------------------- @@ -6766,96 +8733,83 @@ isDataTypeNumeric(const UA_DataType *type) { * is "looped through" every method call. The ``_``-macro accesses either the * thread-local or the "looped through" context . */ -#define UA_ENCODING_MAX_RECURSION 20 +/* Part 6 §5.1.5: Decoders shall support at least 100 nesting levels */ +#define UA_ENCODING_MAX_RECURSION 100 typedef struct { /* Pointers to the current position and the last position in the buffer */ u8 *pos; const u8 *end; - u16 depth; /* How often did we en-/decoding recurse? */ - - size_t customTypesArraySize; - const UA_DataType *customTypesArray; + u8 **oldpos; /* Sentinel for a lower stacktrace exchanging the buffer */ + u16 depth; /* How often did we en-/decoding recurse? */ + const UA_DataTypeArray *customTypes; UA_exchangeEncodeBuffer exchangeBufferCallback; void *exchangeBufferCallbackHandle; } Ctx; -typedef status (*encodeBinarySignature)(const void *UA_RESTRICT src, const UA_DataType *type, - Ctx *UA_RESTRICT ctx); -typedef status (*decodeBinarySignature)(void *UA_RESTRICT dst, const UA_DataType *type, - Ctx *UA_RESTRICT ctx); -typedef size_t (*calcSizeBinarySignature)(const void *UA_RESTRICT p, const UA_DataType *contenttype); - -#define ENCODE_BINARY(TYPE) static status \ - TYPE##_encodeBinary(const UA_##TYPE *UA_RESTRICT src, const UA_DataType *type, Ctx *UA_RESTRICT ctx) -#define DECODE_BINARY(TYPE) static status \ - TYPE##_decodeBinary(UA_##TYPE *UA_RESTRICT dst, const UA_DataType *type, Ctx *UA_RESTRICT ctx) -#define CALCSIZE_BINARY(TYPE) static size_t \ - TYPE##_calcSizeBinary(const UA_##TYPE *UA_RESTRICT src, const UA_DataType *_) +typedef status +(*encodeBinarySignature)(const void *UA_RESTRICT src, const UA_DataType *type, + Ctx *UA_RESTRICT ctx); +typedef status +(*decodeBinarySignature)(void *UA_RESTRICT dst, const UA_DataType *type, + Ctx *UA_RESTRICT ctx); +typedef size_t +(*calcSizeBinarySignature)(const void *UA_RESTRICT p, const UA_DataType *contenttype); + +#define ENCODE_BINARY(TYPE) static status \ + TYPE##_encodeBinary(const UA_##TYPE *UA_RESTRICT src, \ + const UA_DataType *type, Ctx *UA_RESTRICT ctx) +#define DECODE_BINARY(TYPE) static status \ + TYPE##_decodeBinary(UA_##TYPE *UA_RESTRICT dst, \ + const UA_DataType *type, Ctx *UA_RESTRICT ctx) +#define CALCSIZE_BINARY(TYPE) static size_t \ + TYPE##_calcSizeBinary(const UA_##TYPE *UA_RESTRICT src, \ + const UA_DataType *_) #define ENCODE_DIRECT(SRC, TYPE) TYPE##_encodeBinary((const UA_##TYPE*)SRC, NULL, ctx) #define DECODE_DIRECT(DST, TYPE) TYPE##_decodeBinary((UA_##TYPE*)DST, NULL, ctx) /* Jumptables for de-/encoding and computing the buffer length. The methods in * the decoding jumptable do not all clean up their allocated memory when an - * error occurs. So a final _deleteMembers needs to be called before returning - * to the user. */ -extern const encodeBinarySignature encodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1]; -extern const decodeBinarySignature decodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1]; -extern const calcSizeBinarySignature calcSizeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1]; -static status encodeBinaryInternal(const void *src, const UA_DataType *type, Ctx *ctx); -static status decodeBinaryInternal(void *dst, const UA_DataType *type, Ctx *ctx); + * error occurs. So a final _clear needs to be called before returning to the + * user. */ +extern const encodeBinarySignature encodeBinaryJumpTable[UA_DATATYPEKINDS]; +extern const decodeBinarySignature decodeBinaryJumpTable[UA_DATATYPEKINDS]; +extern const calcSizeBinarySignature calcSizeBinaryJumpTable[UA_DATATYPEKINDS]; -/** - * Chunking - * ^^^^^^^^ - * Breaking a message into chunks is integrated with the encoding. When the end - * of a buffer is reached, a callback is executed that sends the current buffer - * as a chunk and exchanges the encoding buffer "underneath" the ongoing - * encoding. This reduces the RAM requirements and unnecessary copying. - * - * In encodeBinaryInternal and Array_encodeBinary, we store a pointer to the - * last "good position" in the buffer. If we reach the end of the buffer, the - * encoding until that point is sent out. Afterwards the "good position" pointer - * is no longer valid. In order to prevent reuse, no method must return - * UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED after having called exchangeBuffer(). - * This needs to be ensured for the following methods: - * - * encodeBinaryInternal - * Array_encodeBinary - * NodeId_encodeBinary - * ExpandedNodeId_encodeBinary - * LocalizedText_encodeBinary - * ExtensionObject_encodeBinary - * Variant_encodeBinary - * DataValue_encodeBinary - * DiagnosticInfo_encodeBinary */ +/* Breaking a message up into chunks is integrated with the encoding. When the + * end of a buffer is reached, a callback is executed that sends the current + * buffer as a chunk and exchanges the encoding buffer "underneath" the ongoing + * encoding. This reduces the RAM requirements and unnecessary copying. */ /* Send the current chunk and replace the buffer */ static status exchangeBuffer(Ctx *ctx) { if(!ctx->exchangeBufferCallback) return UA_STATUSCODE_BADENCODINGERROR; - return ctx->exchangeBufferCallback(ctx->exchangeBufferCallbackHandle, &ctx->pos, &ctx->end); + return ctx->exchangeBufferCallback(ctx->exchangeBufferCallbackHandle, + &ctx->pos, &ctx->end); } -/* If encoding fails, exchange the buffer and try again. It is assumed that the - * following encoding never fails on a fresh buffer. This is true for numerical - * types. */ +/* If encoding fails, exchange the buffer and try again. */ static status -encodeWithExchangeBuffer(const void *ptr, encodeBinarySignature encodeFunc, Ctx *ctx) { - status ret = encodeFunc(ptr, NULL, ctx); - if(ret == UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED) { +encodeWithExchangeBuffer(const void *ptr, const UA_DataType *type, Ctx *ctx) { + u8 *oldpos = ctx->pos; /* Last known good position */ + ctx->oldpos = &oldpos; + status ret = encodeBinaryJumpTable[type->typeKind](ptr, type, ctx); + if(ret == UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED && ctx->oldpos == &oldpos) { + ctx->pos = oldpos; /* Send the position to the last known good position + * and switch */ ret = exchangeBuffer(ctx); if(ret != UA_STATUSCODE_GOOD) return ret; - ret = encodeFunc(ptr, NULL, ctx); + ret = encodeBinaryJumpTable[type->typeKind](ptr, type, ctx); } return ret; } #define ENCODE_WITHEXCHANGE(VAR, TYPE) \ - encodeWithExchangeBuffer((const void*)VAR, (encodeBinarySignature)TYPE##_encodeBinary, ctx) + encodeWithExchangeBuffer((const void*)VAR, &UA_TYPES[TYPE], ctx) /*****************/ /* Integer Types */ @@ -6914,8 +8868,10 @@ UA_decode64(const u8 buf[8], u64 *v) { #endif /* !UA_BINARY_OVERLAYABLE_INTEGER */ /* Boolean */ +/* Note that sizeof(bool) != 1 on some platforms. Overlayable integer encoding + * is disabled in those cases. */ ENCODE_BINARY(Boolean) { - if(ctx->pos + sizeof(bool) > ctx->end) + if(ctx->pos + 1 > ctx->end) return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED; *ctx->pos = *(const u8*)src; ++ctx->pos; @@ -6923,7 +8879,7 @@ ENCODE_BINARY(Boolean) { } DECODE_BINARY(Boolean) { - if(ctx->pos + sizeof(bool) > ctx->end) + if(ctx->pos + 1 > ctx->end) return UA_STATUSCODE_BADDECODINGERROR; *dst = (*ctx->pos > 0) ? true : false; ++ctx->pos; @@ -7026,7 +8982,9 @@ DECODE_BINARY(UInt64) { /* Floating Point Types */ /************************/ -#if UA_BINARY_OVERLAYABLE_FLOAT +/* Can we reuse the integer encoding mechanism by casting floating point + * values? */ +#if (UA_FLOAT_IEEE754 == 1) && (UA_LITTLE_ENDIAN == UA_FLOAT_LITTLE_ENDIAN) # define Float_encodeBinary UInt32_encodeBinary # define Float_decodeBinary UInt32_decodeBinary # define Double_encodeBinary UInt64_encodeBinary @@ -7141,7 +9099,8 @@ DECODE_BINARY(Double) { /******************/ static status -Array_encodeBinaryOverlayable(uintptr_t ptr, size_t length, size_t elementMemSize, Ctx *ctx) { +Array_encodeBinaryOverlayable(uintptr_t ptr, size_t length, + size_t elementMemSize, Ctx *ctx) { /* Store the number of already encoded elements */ size_t finished = 0; @@ -7154,6 +9113,9 @@ Array_encodeBinaryOverlayable(uintptr_t ptr, size_t length, size_t elementMemSiz ptr += possibleMem; finished += possible; status ret = exchangeBuffer(ctx); + ctx->oldpos = NULL; /* Set the sentinel so that no upper stack frame + * with a saved pos attempts to exchange from an + * invalid position in the old buffer. */ if(ret != UA_STATUSCODE_GOOD) return ret; } @@ -7165,35 +9127,23 @@ Array_encodeBinaryOverlayable(uintptr_t ptr, size_t length, size_t elementMemSiz } static status -Array_encodeBinaryComplex(uintptr_t ptr, size_t length, const UA_DataType *type, Ctx *ctx) { - /* Get the encoding function for the data type. The jumptable at - * UA_BUILTIN_TYPES_COUNT points to the generic UA_encodeBinary method */ - size_t encode_index = type->builtin ? type->typeIndex : UA_BUILTIN_TYPES_COUNT; - encodeBinarySignature encodeType = encodeBinaryJumpTable[encode_index]; - +Array_encodeBinaryComplex(uintptr_t ptr, size_t length, + const UA_DataType *type, Ctx *ctx) { /* Encode every element */ for(size_t i = 0; i < length; ++i) { - u8 *oldpos = ctx->pos; - status ret = encodeType((const void*)ptr, type, ctx); + status ret = encodeWithExchangeBuffer((const void*)ptr, type, ctx); ptr += type->memSize; - /* Encoding failed, switch to the next chunk when possible */ - if(ret != UA_STATUSCODE_GOOD) { - if(ret == UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED) { - ctx->pos = oldpos; /* Set buffer position to the end of the last encoded element */ - ret = exchangeBuffer(ctx); - ptr -= type->memSize; /* Undo to retry encoding the ith element */ - --i; - } - UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); - if(ret != UA_STATUSCODE_GOOD) - return ret; /* Unrecoverable fail */ - } + + if(ret != UA_STATUSCODE_GOOD) + return ret; /* Unrecoverable fail */ } + return UA_STATUSCODE_GOOD; } static status -Array_encodeBinary(const void *src, size_t length, const UA_DataType *type, Ctx *ctx) { +Array_encodeBinary(const void *src, size_t length, + const UA_DataType *type, Ctx *ctx) { /* Check and convert the array length to int32 */ i32 signed_length = -1; if(length > UA_INT32_MAX) @@ -7204,7 +9154,7 @@ Array_encodeBinary(const void *src, size_t length, const UA_DataType *type, Ctx signed_length = 0; /* Encode the array length */ - status ret = ENCODE_WITHEXCHANGE(&signed_length, UInt32); + status ret = ENCODE_WITHEXCHANGE(&signed_length, UA_TYPES_INT32); /* Quit early? */ if(ret != UA_STATUSCODE_GOOD || length == 0) @@ -7259,9 +9209,8 @@ Array_decodeBinary(void *UA_RESTRICT *UA_RESTRICT dst, size_t *out_length, } else { /* Decode array members */ uintptr_t ptr = (uintptr_t)*dst; - size_t decode_index = type->builtin ? type->typeIndex : UA_BUILTIN_TYPES_COUNT; for(size_t i = 0; i < length; ++i) { - ret = decodeBinaryJumpTable[decode_index]((void*)ptr, type, ctx); + ret = decodeBinaryJumpTable[type->typeKind]((void*)ptr, type, ctx); if(ret != UA_STATUSCODE_GOOD) { /* +1 because last element is also already initialized */ UA_Array_delete(*dst, i+1, type); @@ -7313,16 +9262,14 @@ DECODE_BINARY(Guid) { } /* NodeId */ -#define UA_NODEIDTYPE_NUMERIC_TWOBYTE 0 -#define UA_NODEIDTYPE_NUMERIC_FOURBYTE 1 -#define UA_NODEIDTYPE_NUMERIC_COMPLETE 2 +#define UA_NODEIDTYPE_NUMERIC_TWOBYTE 0u +#define UA_NODEIDTYPE_NUMERIC_FOURBYTE 1u +#define UA_NODEIDTYPE_NUMERIC_COMPLETE 2u -#define UA_EXPANDEDNODEID_SERVERINDEX_FLAG 0x40 -#define UA_EXPANDEDNODEID_NAMESPACEURI_FLAG 0x80 +#define UA_EXPANDEDNODEID_SERVERINDEX_FLAG 0x40u +#define UA_EXPANDEDNODEID_NAMESPACEURI_FLAG 0x80u -/* For ExpandedNodeId, we prefill the encoding mask. We can return - * UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED before encoding the string, as the - * buffer is not replaced. */ +/* For ExpandedNodeId, we prefill the encoding mask. */ static status NodeId_encodeBinaryWithEncodingMask(UA_NodeId const *src, u8 encoding, Ctx *ctx) { status ret = UA_STATUSCODE_GOOD; @@ -7347,22 +9294,19 @@ NodeId_encodeBinaryWithEncodingMask(UA_NodeId const *src, u8 encoding, Ctx *ctx) ret |= ENCODE_DIRECT(&identifier8, Byte); } break; - case UA_NODEIDTYPE_STRING: - encoding |= UA_NODEIDTYPE_STRING; + case UA_NODEIDTYPE_STRING:encoding |= (u8)UA_NODEIDTYPE_STRING; ret |= ENCODE_DIRECT(&encoding, Byte); ret |= ENCODE_DIRECT(&src->namespaceIndex, UInt16); if(ret != UA_STATUSCODE_GOOD) return ret; ret = ENCODE_DIRECT(&src->identifier.string, String); break; - case UA_NODEIDTYPE_GUID: - encoding |= UA_NODEIDTYPE_GUID; + case UA_NODEIDTYPE_GUID:encoding |= (u8)UA_NODEIDTYPE_GUID; ret |= ENCODE_DIRECT(&encoding, Byte); ret |= ENCODE_DIRECT(&src->namespaceIndex, UInt16); ret |= ENCODE_DIRECT(&src->identifier.guid, Guid); break; - case UA_NODEIDTYPE_BYTESTRING: - encoding |= UA_NODEIDTYPE_BYTESTRING; + case UA_NODEIDTYPE_BYTESTRING:encoding |= (u8)UA_NODEIDTYPE_BYTESTRING; ret |= ENCODE_DIRECT(&encoding, Byte); ret |= ENCODE_DIRECT(&src->namespaceIndex, UInt16); if(ret != UA_STATUSCODE_GOOD) @@ -7389,8 +9333,8 @@ DECODE_BINARY(NodeId) { return ret; /* Filter out the bits used only for ExpandedNodeIds */ - encodingByte &= (u8)~(UA_EXPANDEDNODEID_SERVERINDEX_FLAG | - UA_EXPANDEDNODEID_NAMESPACEURI_FLAG); + encodingByte &= (u8)~(u8)(UA_EXPANDEDNODEID_SERVERINDEX_FLAG | + UA_EXPANDEDNODEID_NAMESPACEURI_FLAG); /* Decode the namespace and identifier */ switch(encodingByte) { @@ -7448,19 +9392,16 @@ ENCODE_BINARY(ExpandedNodeId) { if(ret != UA_STATUSCODE_GOOD) return ret; - /* Encode the namespace. Do not return - * UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED afterwards. */ + /* Encode the namespace. */ if((void*)src->namespaceUri.data > UA_EMPTY_ARRAY_SENTINEL) { ret = ENCODE_DIRECT(&src->namespaceUri, String); - UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); if(ret != UA_STATUSCODE_GOOD) return ret; } /* Encode the serverIndex */ if(src->serverIndex > 0) - ret = ENCODE_WITHEXCHANGE(&src->serverIndex, UInt32); - UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); + ret = ENCODE_WITHEXCHANGE(&src->serverIndex, UA_TYPES_UINT32); return ret; } @@ -7485,9 +9426,22 @@ DECODE_BINARY(ExpandedNodeId) { return ret; } +/* QualifiedName */ +ENCODE_BINARY(QualifiedName) { + status ret = ENCODE_DIRECT(&src->namespaceIndex, UInt16); + ret |= ENCODE_DIRECT(&src->name, String); + return ret; +} + +DECODE_BINARY(QualifiedName) { + status ret = DECODE_DIRECT(&dst->namespaceIndex, UInt16); + ret |= DECODE_DIRECT(&dst->name, String); + return ret; +} + /* LocalizedText */ -#define UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE 0x01 -#define UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT 0x02 +#define UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE 0x01u +#define UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT 0x02u ENCODE_BINARY(LocalizedText) { /* Set up the encoding mask */ @@ -7507,7 +9461,6 @@ ENCODE_BINARY(LocalizedText) { ret |= ENCODE_DIRECT(&src->locale, String); if(encoding & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT) ret |= ENCODE_DIRECT(&src->text, String); - UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); return ret; } @@ -7540,13 +9493,14 @@ UA_findDataTypeByBinaryInternal(const UA_NodeId *typeId, Ctx *ctx) { return &UA_TYPES[i]; } - /* When other namespace look in custom types, too */ - if(typeId->namespaceIndex != 0) { - for(size_t i = 0; i < ctx->customTypesArraySize; ++i) { - if(ctx->customTypesArray[i].binaryEncodingId == typeId->identifier.numeric && - ctx->customTypesArray[i].typeId.namespaceIndex == typeId->namespaceIndex) - return &ctx->customTypesArray[i]; + const UA_DataTypeArray *customTypes = ctx->customTypes; + while(customTypes) { + for(size_t i = 0; i < customTypes->typesSize; ++i) { + if(customTypes->types[i].binaryEncodingId == typeId->identifier.numeric && + customTypes->types[i].typeId.namespaceIndex == typeId->namespaceIndex) + return &customTypes->types[i]; } + customTypes = customTypes->next; } return NULL; @@ -7555,8 +9509,7 @@ UA_findDataTypeByBinaryInternal(const UA_NodeId *typeId, Ctx *ctx) { const UA_DataType * UA_findDataTypeByBinary(const UA_NodeId *typeId) { Ctx ctx; - ctx.customTypesArraySize = 0; - ctx.customTypesArray = NULL; + ctx.customTypes = NULL; return UA_findDataTypeByBinaryInternal(typeId, &ctx); } @@ -7564,13 +9517,12 @@ UA_findDataTypeByBinary(const UA_NodeId *typeId) { ENCODE_BINARY(ExtensionObject) { u8 encoding = (u8)src->encoding; - /* No content or already encoded content. Do not return - * UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED after encoding the NodeId. */ + /* No content or already encoded content. */ if(encoding <= UA_EXTENSIONOBJECT_ENCODED_XML) { status ret = ENCODE_DIRECT(&src->content.encoded.typeId, NodeId); if(ret != UA_STATUSCODE_GOOD) return ret; - ret = ENCODE_WITHEXCHANGE(&encoding, Byte); + ret = ENCODE_WITHEXCHANGE(&encoding, UA_TYPES_BYTE); if(ret != UA_STATUSCODE_GOOD) return ret; switch(src->encoding) { @@ -7617,7 +9569,7 @@ ENCODE_BINARY(ExtensionObject) { return ret; /* Encode the content */ - return encodeBinaryInternal(src->content.decoded.data, contentType, ctx); + return encodeWithExchangeBuffer(src->content.decoded.data, contentType, ctx); } static status @@ -7643,8 +9595,7 @@ ExtensionObject_decodeBinaryContent(UA_ExtensionObject *dst, const UA_NodeId *ty /* Decode */ dst->encoding = UA_EXTENSIONOBJECT_DECODED; dst->content.decoded.type = type; - size_t decode_index = type->builtin ? type->typeIndex : UA_BUILTIN_TYPES_COUNT; - return decodeBinaryJumpTable[decode_index](dst->content.decoded.data, type, ctx); + return decodeBinaryJumpTable[type->typeKind](dst->content.decoded.data, type, ctx); } DECODE_BINARY(ExtensionObject) { @@ -7659,26 +9610,31 @@ DECODE_BINARY(ExtensionObject) { ret |= DECODE_DIRECT(&binTypeId, NodeId); ret |= DECODE_DIRECT(&encoding, Byte); if(ret != UA_STATUSCODE_GOOD) { - UA_NodeId_deleteMembers(&binTypeId); + UA_NodeId_clear(&binTypeId); return ret; } - if(encoding == UA_EXTENSIONOBJECT_ENCODED_BYTESTRING) { + switch(encoding) { + case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING: ret = ExtensionObject_decodeBinaryContent(dst, &binTypeId, ctx); UA_NodeId_deleteMembers(&binTypeId); - } else if(encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY) { + break; + case UA_EXTENSIONOBJECT_ENCODED_NOBODY: dst->encoding = (UA_ExtensionObjectEncoding)encoding; dst->content.encoded.typeId = binTypeId; /* move to dst */ dst->content.encoded.body = UA_BYTESTRING_NULL; - } else if(encoding == UA_EXTENSIONOBJECT_ENCODED_XML) { + break; + case UA_EXTENSIONOBJECT_ENCODED_XML: dst->encoding = (UA_ExtensionObjectEncoding)encoding; dst->content.encoded.typeId = binTypeId; /* move to dst */ ret = DECODE_DIRECT(&dst->content.encoded.body, String); /* ByteString */ if(ret != UA_STATUSCODE_GOOD) - UA_NodeId_deleteMembers(&dst->content.encoded.typeId); - } else { - UA_NodeId_deleteMembers(&binTypeId); + UA_NodeId_clear(&dst->content.encoded.typeId); + break; + default: + UA_NodeId_clear(&binTypeId); ret = UA_STATUSCODE_BADDECODINGERROR; + break; } return ret; @@ -7686,9 +9642,9 @@ DECODE_BINARY(ExtensionObject) { /* Variant */ -/* Never returns UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED */ static status -Variant_encodeBinaryWrapExtensionObject(const UA_Variant *src, const bool isArray, Ctx *ctx) { +Variant_encodeBinaryWrapExtensionObject(const UA_Variant *src, + const UA_Boolean isArray, Ctx *ctx) { /* Default to 1 for a scalar. */ size_t length = 1; @@ -7715,20 +9671,18 @@ Variant_encodeBinaryWrapExtensionObject(const UA_Variant *src, const bool isArra /* Iterate over the array */ for(size_t i = 0; i < length && ret == UA_STATUSCODE_GOOD; ++i) { eo.content.decoded.data = (void*)ptr; - ret = encodeBinaryInternal(&eo, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], ctx); + ret = encodeWithExchangeBuffer(&eo, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT], ctx); ptr += memSize; } return ret; } enum UA_VARIANT_ENCODINGMASKTYPE { - UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK = 0x3F, /* bits 0:5 */ - UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS = (0x01 << 6), /* bit 6 */ - UA_VARIANT_ENCODINGMASKTYPE_ARRAY = (0x01 << 7) /* bit 7 */ + UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK = 0x3Fu, /* bits 0:5 */ + UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS = (u8)(0x01u << 6u), /* bit 6 */ + UA_VARIANT_ENCODINGMASKTYPE_ARRAY = (u8)(0x01u << 7u) /* bit 7 */ }; - - ENCODE_BINARY(Variant) { /* Quit early for the empty variant */ u8 encoding = 0; @@ -7736,23 +9690,22 @@ ENCODE_BINARY(Variant) { return ENCODE_DIRECT(&encoding, Byte); /* Set the content type in the encoding mask */ - const bool isBuiltin = src->type->builtin; - const bool isAlias = src->type->membersSize == 1 - && UA_TYPES[src->type->members[0].memberTypeIndex].builtin; + const UA_Boolean isBuiltin = (src->type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO); + const UA_Boolean isEnum = (src->type->typeKind == UA_DATATYPEKIND_ENUM); if(isBuiltin) - encoding |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(src->type->typeIndex + 1); - else if(isAlias) - encoding |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(src->type->members[0].memberTypeIndex + 1); + encoding = (u8)(encoding | (u8)((u8)UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(src->type->typeKind + 1u))); + else if(isEnum) + encoding = (u8)(encoding | (u8)((u8)UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(UA_TYPES_INT32 + 1u))); else - encoding |= UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(UA_TYPES_EXTENSIONOBJECT + 1); + encoding = (u8)(encoding | (u8)((u8)UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK & (u8)(UA_TYPES_EXTENSIONOBJECT + 1u))); /* Set the array type in the encoding mask */ - const bool isArray = src->arrayLength > 0 || src->data <= UA_EMPTY_ARRAY_SENTINEL; - const bool hasDimensions = isArray && src->arrayDimensionsSize > 0; + const UA_Boolean isArray = src->arrayLength > 0 || src->data <= UA_EMPTY_ARRAY_SENTINEL; + const UA_Boolean hasDimensions = isArray && src->arrayDimensionsSize > 0; if(isArray) { - encoding |= UA_VARIANT_ENCODINGMASKTYPE_ARRAY; + encoding |= (u8)UA_VARIANT_ENCODINGMASKTYPE_ARRAY; if(hasDimensions) - encoding |= UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS; + encoding |= (u8)UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS; } /* Encode the encoding byte */ @@ -7761,10 +9714,10 @@ ENCODE_BINARY(Variant) { return ret; /* Encode the content */ - if(!isBuiltin && !isAlias) + if(!isBuiltin && !isEnum) ret = Variant_encodeBinaryWrapExtensionObject(src, isArray, ctx); else if(!isArray) - ret = encodeBinaryInternal(src->data, src->type, ctx); + ret = encodeWithExchangeBuffer(src->data, src->type, ctx); else ret = Array_encodeBinary(src->data, src->arrayLength, src->type, ctx); @@ -7792,7 +9745,7 @@ Variant_decodeBinaryUnwrapExtensionObject(UA_Variant *dst, Ctx *ctx) { u8 encoding; ret = DECODE_DIRECT(&encoding, Byte); if(ret != UA_STATUSCODE_GOOD) { - UA_NodeId_deleteMembers(&typeId); + UA_NodeId_clear(&typeId); return ret; } @@ -7805,7 +9758,7 @@ Variant_decodeBinaryUnwrapExtensionObject(UA_Variant *dst, Ctx *ctx) { /* Reset and decode as ExtensionObject */ dst->type = &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]; ctx->pos = old_pos; - UA_NodeId_deleteMembers(&typeId); + UA_NodeId_clear(&typeId); } /* Allocate memory */ @@ -7814,8 +9767,7 @@ Variant_decodeBinaryUnwrapExtensionObject(UA_Variant *dst, Ctx *ctx) { return UA_STATUSCODE_BADOUTOFMEMORY; /* Decode the content */ - size_t decode_index = dst->type->builtin ? dst->type->typeIndex : UA_BUILTIN_TYPES_COUNT; - return decodeBinaryJumpTable[decode_index](dst->data, dst->type, ctx); + return decodeBinaryJumpTable[dst->type->typeKind](dst->data, dst->type, ctx); } /* The resulting variant always has the storagetype UA_VARIANT_DATA. */ @@ -7831,17 +9783,19 @@ DECODE_BINARY(Variant) { return UA_STATUSCODE_GOOD; /* Does the variant contain an array? */ - const bool isArray = (encodingByte & UA_VARIANT_ENCODINGMASKTYPE_ARRAY) > 0; + const UA_Boolean isArray = (encodingByte & (u8)UA_VARIANT_ENCODINGMASKTYPE_ARRAY) > 0; /* Get the datatype of the content. The type must be a builtin data type. - * All not-builtin types are wrapped in an ExtensionObject. */ - size_t typeIndex = (size_t)((encodingByte & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK) - 1); - if(typeIndex > UA_TYPES_DIAGNOSTICINFO) + * All not-builtin types are wrapped in an ExtensionObject. The "type kind" + * for types up to DiagnsticInfo equals to the index in the encoding + * byte. */ + size_t typeKind = (size_t)((encodingByte & (u8)UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK) - 1); + if(typeKind > UA_DATATYPEKIND_DIAGNOSTICINFO) return UA_STATUSCODE_BADDECODINGERROR; /* A variant cannot contain a variant. But it can contain an array of * variants */ - if(typeIndex == UA_TYPES_VARIANT && !isArray) + if(typeKind == UA_DATATYPEKIND_VARIANT && !isArray) return UA_STATUSCODE_BADDECODINGERROR; /* Check the recursion limit */ @@ -7850,20 +9804,20 @@ DECODE_BINARY(Variant) { ctx->depth++; /* Decode the content */ - dst->type = &UA_TYPES[typeIndex]; + dst->type = &UA_TYPES[typeKind]; if(isArray) { ret = Array_decodeBinary(&dst->data, &dst->arrayLength, dst->type, ctx); - } else if(typeIndex != UA_TYPES_EXTENSIONOBJECT) { + } else if(typeKind != UA_DATATYPEKIND_EXTENSIONOBJECT) { dst->data = UA_new(dst->type); if(!dst->data) return UA_STATUSCODE_BADOUTOFMEMORY; - ret = decodeBinaryJumpTable[typeIndex](dst->data, dst->type, ctx); + ret = decodeBinaryJumpTable[typeKind](dst->data, dst->type, ctx); } else { ret = Variant_decodeBinaryUnwrapExtensionObject(dst, ctx); } /* Decode array dimensions */ - if(isArray && (encodingByte & UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS) > 0) + if(isArray && (encodingByte & (u8)UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS) > 0) ret |= Array_decodeBinary((void**)&dst->arrayDimensions, &dst->arrayDimensionsSize, &UA_TYPES[UA_TYPES_INT32], ctx); @@ -7874,22 +9828,19 @@ DECODE_BINARY(Variant) { /* DataValue */ ENCODE_BINARY(DataValue) { /* Set up the encoding mask */ - u8 encodingMask = (u8) - (((u8)src->hasValue) | - ((u8)src->hasStatus << 1) | - ((u8)src->hasSourceTimestamp << 2) | - ((u8)src->hasServerTimestamp << 3) | - ((u8)src->hasSourcePicoseconds << 4) | - ((u8)src->hasServerPicoseconds << 5)); + u8 encodingMask = src->hasValue; + encodingMask |= (u8)(src->hasStatus << 1u); + encodingMask |= (u8)(src->hasSourceTimestamp << 2u); + encodingMask |= (u8)(src->hasServerTimestamp << 3u); + encodingMask |= (u8)(src->hasSourcePicoseconds << 4u); + encodingMask |= (u8)(src->hasServerPicoseconds << 5u); /* Encode the encoding byte */ status ret = ENCODE_DIRECT(&encodingMask, Byte); if(ret != UA_STATUSCODE_GOOD) return ret; - /* Encode the variant. Afterwards, do not return - * UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED, as the buffer might have been - * exchanged during encoding of the variant. */ + /* Encode the variant. */ if(src->hasValue) { ret = ENCODE_DIRECT(&src->value, Variant); if(ret != UA_STATUSCODE_GOOD) @@ -7897,16 +9848,15 @@ ENCODE_BINARY(DataValue) { } if(src->hasStatus) - ret |= ENCODE_WITHEXCHANGE(&src->status, UInt32); + ret |= ENCODE_WITHEXCHANGE(&src->status, UA_TYPES_STATUSCODE); if(src->hasSourceTimestamp) - ret |= ENCODE_WITHEXCHANGE(&src->sourceTimestamp, UInt64); + ret |= ENCODE_WITHEXCHANGE(&src->sourceTimestamp, UA_TYPES_DATETIME); if(src->hasSourcePicoseconds) - ret |= ENCODE_WITHEXCHANGE(&src->sourcePicoseconds, UInt16); + ret |= ENCODE_WITHEXCHANGE(&src->sourcePicoseconds, UA_TYPES_UINT16); if(src->hasServerTimestamp) - ret |= ENCODE_WITHEXCHANGE(&src->serverTimestamp, UInt64); + ret |= ENCODE_WITHEXCHANGE(&src->serverTimestamp, UA_TYPES_DATETIME); if(src->hasServerPicoseconds) - ret |= ENCODE_WITHEXCHANGE(&src->serverPicoseconds, UInt16); - UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); + ret |= ENCODE_WITHEXCHANGE(&src->serverPicoseconds, UA_TYPES_UINT16); return ret; } @@ -7924,31 +9874,30 @@ DECODE_BINARY(DataValue) { return UA_STATUSCODE_BADENCODINGERROR; ctx->depth++; - /* Decode the content */ - if(encodingMask & 0x01) { + if(encodingMask & 0x01u) { dst->hasValue = true; ret |= DECODE_DIRECT(&dst->value, Variant); } - if(encodingMask & 0x02) { + if(encodingMask & 0x02u) { dst->hasStatus = true; ret |= DECODE_DIRECT(&dst->status, UInt32); /* StatusCode */ } - if(encodingMask & 0x04) { + if(encodingMask & 0x04u) { dst->hasSourceTimestamp = true; ret |= DECODE_DIRECT(&dst->sourceTimestamp, UInt64); /* DateTime */ } - if(encodingMask & 0x10) { + if(encodingMask & 0x10u) { dst->hasSourcePicoseconds = true; ret |= DECODE_DIRECT(&dst->sourcePicoseconds, UInt16); if(dst->sourcePicoseconds > MAX_PICO_SECONDS) dst->sourcePicoseconds = MAX_PICO_SECONDS; } - if(encodingMask & 0x08) { + if(encodingMask & 0x08u) { dst->hasServerTimestamp = true; ret |= DECODE_DIRECT(&dst->serverTimestamp, UInt64); /* DateTime */ } - if(encodingMask & 0x20) { + if(encodingMask & 0x20u) { dst->hasServerPicoseconds = true; ret |= DECODE_DIRECT(&dst->serverPicoseconds, UInt16); if(dst->serverPicoseconds > MAX_PICO_SECONDS) @@ -7963,10 +9912,12 @@ DECODE_BINARY(DataValue) { /* DiagnosticInfo */ ENCODE_BINARY(DiagnosticInfo) { /* Set up the encoding mask */ - u8 encodingMask = (u8) - ((u8)src->hasSymbolicId | ((u8)src->hasNamespaceUri << 1) | - ((u8)src->hasLocalizedText << 2) | ((u8)src->hasLocale << 3) | - ((u8)src->hasAdditionalInfo << 4) | ((u8)src->hasInnerDiagnosticInfo << 5)); + u8 encodingMask = src->hasSymbolicId; + encodingMask |= (u8)(src->hasNamespaceUri << 1u); + encodingMask |= (u8)(src->hasLocalizedText << 2u); + encodingMask |= (u8)(src->hasLocale << 3u); + encodingMask |= (u8)(src->hasAdditionalInfo << 4u); + encodingMask |= (u8)(src->hasInnerDiagnosticInfo << 5u); /* Encode the numeric content */ status ret = ENCODE_DIRECT(&encodingMask, Byte); @@ -7988,22 +9939,19 @@ ENCODE_BINARY(DiagnosticInfo) { return ret; } - /* From here on, do not return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED, as - * the buffer might have been exchanged during encoding of the string. */ - /* Encode the inner status code */ if(src->hasInnerStatusCode) { - ret = ENCODE_WITHEXCHANGE(&src->innerStatusCode, UInt32); - UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); + ret = ENCODE_WITHEXCHANGE(&src->innerStatusCode, UA_TYPES_UINT32); if(ret != UA_STATUSCODE_GOOD) return ret; } /* Encode the inner diagnostic info */ if(src->hasInnerDiagnosticInfo) - ret = encodeBinaryInternal(src->innerDiagnosticInfo, &UA_TYPES[UA_TYPES_DIAGNOSTICINFO], ctx); + // innerDiagnosticInfo is already a pointer, so don't use the & reference here + ret = ENCODE_WITHEXCHANGE(src->innerDiagnosticInfo, + UA_TYPES_DIAGNOSTICINFO); - UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); return ret; } @@ -8015,31 +9963,31 @@ DECODE_BINARY(DiagnosticInfo) { return ret; /* Decode the content */ - if(encodingMask & 0x01) { + if(encodingMask & 0x01u) { dst->hasSymbolicId = true; ret |= DECODE_DIRECT(&dst->symbolicId, UInt32); /* Int32 */ } - if(encodingMask & 0x02) { + if(encodingMask & 0x02u) { dst->hasNamespaceUri = true; ret |= DECODE_DIRECT(&dst->namespaceUri, UInt32); /* Int32 */ } - if(encodingMask & 0x04) { + if(encodingMask & 0x04u) { dst->hasLocalizedText = true; ret |= DECODE_DIRECT(&dst->localizedText, UInt32); /* Int32 */ } - if(encodingMask & 0x08) { + if(encodingMask & 0x08u) { dst->hasLocale = true; ret |= DECODE_DIRECT(&dst->locale, UInt32); /* Int32 */ } - if(encodingMask & 0x10) { + if(encodingMask & 0x10u) { dst->hasAdditionalInfo = true; ret |= DECODE_DIRECT(&dst->additionalInfo, String); } - if(encodingMask & 0x20) { + if(encodingMask & 0x20u) { dst->hasInnerStatusCode = true; ret |= DECODE_DIRECT(&dst->innerStatusCode, UInt32); /* StatusCode */ } - if(encodingMask & 0x40) { + if(encodingMask & 0x40u) { /* innerDiagnosticInfo is allocated on the heap */ dst->innerDiagnosticInfo = (UA_DiagnosticInfo*) UA_calloc(1, sizeof(UA_DiagnosticInfo)); @@ -8058,11 +10006,53 @@ DECODE_BINARY(DiagnosticInfo) { return ret; } +static status +encodeBinaryStruct(const void *src, const UA_DataType *type, Ctx *ctx) { + /* Check the recursion limit */ + if(ctx->depth > UA_ENCODING_MAX_RECURSION) + return UA_STATUSCODE_BADENCODINGERROR; + ctx->depth++; + + uintptr_t ptr = (uintptr_t)src; + status ret = UA_STATUSCODE_GOOD; + u8 membersSize = type->membersSize; + const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; + + /* Loop over members */ + for(size_t i = 0; i < membersSize; ++i) { + const UA_DataTypeMember *m = &type->members[i]; + const UA_DataType *mt = &typelists[!m->namespaceZero][m->memberTypeIndex]; + ptr += m->padding; + + /* Array. Buffer-exchange is done inside Array_encodeBinary if required. */ + if(m->isArray) { + const size_t length = *((const size_t*)ptr); + ptr += sizeof(size_t); + ret = Array_encodeBinary(*(void *UA_RESTRICT const *)ptr, length, mt, ctx); + ptr += sizeof(void*); + continue; + } + + /* Scalar */ + ret = encodeWithExchangeBuffer((const void*)ptr, mt, ctx); + ptr += mt->memSize; + } + + ctx->depth--; + return ret; +} + +static status +encodeBinaryNotImplemented(const void *src, const UA_DataType *type, Ctx *ctx) { + (void)src, (void)type, (void)ctx; + return UA_STATUSCODE_BADNOTIMPLEMENTED; +} + /********************/ /* Structured Types */ /********************/ -const encodeBinarySignature encodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = { +const encodeBinarySignature encodeBinaryJumpTable[UA_DATATYPEKINDS] = { (encodeBinarySignature)Boolean_encodeBinary, (encodeBinarySignature)Byte_encodeBinary, /* SByte */ (encodeBinarySignature)Byte_encodeBinary, @@ -8082,61 +10072,20 @@ const encodeBinarySignature encodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = (encodeBinarySignature)NodeId_encodeBinary, (encodeBinarySignature)ExpandedNodeId_encodeBinary, (encodeBinarySignature)UInt32_encodeBinary, /* StatusCode */ - (encodeBinarySignature)encodeBinaryInternal, /* QualifiedName */ + (encodeBinarySignature)QualifiedName_encodeBinary, (encodeBinarySignature)LocalizedText_encodeBinary, (encodeBinarySignature)ExtensionObject_encodeBinary, (encodeBinarySignature)DataValue_encodeBinary, (encodeBinarySignature)Variant_encodeBinary, (encodeBinarySignature)DiagnosticInfo_encodeBinary, - (encodeBinarySignature)encodeBinaryInternal, + (encodeBinarySignature)encodeBinaryNotImplemented, /* Decimal */ + (encodeBinarySignature)UInt32_encodeBinary, /* Enumeration */ + (encodeBinarySignature)encodeBinaryStruct, + (encodeBinarySignature)encodeBinaryNotImplemented, /* Structure with Optional Fields */ + (encodeBinarySignature)encodeBinaryStruct, /* Union */ + (encodeBinarySignature)encodeBinaryStruct /* BitfieldCluster */ }; -static status -encodeBinaryInternal(const void *src, const UA_DataType *type, Ctx *ctx) { - /* Check the recursion limit */ - if(ctx->depth > UA_ENCODING_MAX_RECURSION) - return UA_STATUSCODE_BADENCODINGERROR; - ctx->depth++; - - uintptr_t ptr = (uintptr_t)src; - status ret = UA_STATUSCODE_GOOD; - u8 membersSize = type->membersSize; - const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; - for(size_t i = 0; i < membersSize && ret == UA_STATUSCODE_GOOD; ++i) { - const UA_DataTypeMember *member = &type->members[i]; - const UA_DataType *membertype = &typelists[!member->namespaceZero][member->memberTypeIndex]; - if(!member->isArray) { - ptr += member->padding; - size_t encode_index = membertype->builtin ? membertype->typeIndex : UA_BUILTIN_TYPES_COUNT; - size_t memSize = membertype->memSize; - u8 *oldpos = ctx->pos; - ret = encodeBinaryJumpTable[encode_index]((const void*)ptr, membertype, ctx); - ptr += memSize; - if(ret == UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED) { - ctx->pos = oldpos; /* exchange/send the buffer */ - ret = exchangeBuffer(ctx); - ptr -= member->padding + memSize; /* encode the same member in the next iteration */ - if(ret == UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED || ctx->pos + memSize > ctx->end) { - /* the send buffer is too small to encode the member, even after exchangeBuffer */ - ret = UA_STATUSCODE_BADRESPONSETOOLARGE; - break; - } - --i; - } - } else { - ptr += member->padding; - const size_t length = *((const size_t*)ptr); - ptr += sizeof(size_t); - ret = Array_encodeBinary(*(void *UA_RESTRICT const *)ptr, length, membertype, ctx); - ptr += sizeof(void*); - } - } - - UA_assert(ret != UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED); - ctx->depth--; - return ret; -} - status UA_encodeBinary(const void *src, const UA_DataType *type, u8 **bufPos, const u8 **bufEnd, @@ -8149,11 +10098,11 @@ UA_encodeBinary(const void *src, const UA_DataType *type, ctx.exchangeBufferCallback = exchangeCallback; ctx.exchangeBufferCallbackHandle = exchangeHandle; - if (!ctx.pos) + if(!ctx.pos) return UA_STATUSCODE_BADINVALIDARGUMENT; /* Encode */ - status ret = encodeBinaryInternal(src, type, &ctx); + status ret = encodeWithExchangeBuffer(src, type, &ctx); /* Set the new buffer position for the output. Beware that the buffer might * have been exchanged internally. */ @@ -8162,7 +10111,49 @@ UA_encodeBinary(const void *src, const UA_DataType *type, return ret; } -const decodeBinarySignature decodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = { +static status +decodeBinaryNotImplemented(void *dst, const UA_DataType *type, Ctx *ctx) { + (void)dst, (void)type, (void)ctx; + return UA_STATUSCODE_BADNOTIMPLEMENTED; +} + +static status +decodeBinaryStructure(void *dst, const UA_DataType *type, Ctx *ctx) { + /* Check the recursion limit */ + if(ctx->depth > UA_ENCODING_MAX_RECURSION) + return UA_STATUSCODE_BADENCODINGERROR; + ctx->depth++; + + uintptr_t ptr = (uintptr_t)dst; + status ret = UA_STATUSCODE_GOOD; + u8 membersSize = type->membersSize; + const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; + + /* Loop over members */ + for(size_t i = 0; i < membersSize && ret == UA_STATUSCODE_GOOD; ++i) { + const UA_DataTypeMember *m = &type->members[i]; + const UA_DataType *mt = &typelists[!m->namespaceZero][m->memberTypeIndex]; + ptr += m->padding; + + /* Array */ + if(m->isArray) { + size_t *length = (size_t*)ptr; + ptr += sizeof(size_t); + ret = Array_decodeBinary((void *UA_RESTRICT *UA_RESTRICT)ptr, length, mt , ctx); + ptr += sizeof(void*); + continue; + } + + /* Scalar */ + ret = decodeBinaryJumpTable[mt->typeKind]((void *UA_RESTRICT)ptr, mt, ctx); + ptr += mt->memSize; + } + + ctx->depth--; + return ret; +} + +const decodeBinarySignature decodeBinaryJumpTable[UA_DATATYPEKINDS] = { (decodeBinarySignature)Boolean_decodeBinary, (decodeBinarySignature)Byte_decodeBinary, /* SByte */ (decodeBinarySignature)Byte_decodeBinary, @@ -8182,70 +10173,40 @@ const decodeBinarySignature decodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = (decodeBinarySignature)NodeId_decodeBinary, (decodeBinarySignature)ExpandedNodeId_decodeBinary, (decodeBinarySignature)UInt32_decodeBinary, /* StatusCode */ - (decodeBinarySignature)decodeBinaryInternal, /* QualifiedName */ + (decodeBinarySignature)QualifiedName_decodeBinary, (decodeBinarySignature)LocalizedText_decodeBinary, (decodeBinarySignature)ExtensionObject_decodeBinary, (decodeBinarySignature)DataValue_decodeBinary, (decodeBinarySignature)Variant_decodeBinary, (decodeBinarySignature)DiagnosticInfo_decodeBinary, - (decodeBinarySignature)decodeBinaryInternal + (decodeBinarySignature)decodeBinaryNotImplemented, /* Decimal */ + (decodeBinarySignature)UInt32_decodeBinary, /* Enumeration */ + (decodeBinarySignature)decodeBinaryStructure, + (decodeBinarySignature)decodeBinaryNotImplemented, /* Structure with optional fields */ + (decodeBinarySignature)decodeBinaryNotImplemented, /* Union */ + (decodeBinarySignature)decodeBinaryNotImplemented /* BitfieldCluster */ }; -static status -decodeBinaryInternal(void *dst, const UA_DataType *type, Ctx *ctx) { - /* Check the recursion limit */ - if(ctx->depth > UA_ENCODING_MAX_RECURSION) - return UA_STATUSCODE_BADENCODINGERROR; - ctx->depth++; - - uintptr_t ptr = (uintptr_t)dst; - status ret = UA_STATUSCODE_GOOD; - u8 membersSize = type->membersSize; - const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; - for(size_t i = 0; i < membersSize && ret == UA_STATUSCODE_GOOD; ++i) { - const UA_DataTypeMember *member = &type->members[i]; - const UA_DataType *membertype = &typelists[!member->namespaceZero][member->memberTypeIndex]; - if(!member->isArray) { - ptr += member->padding; - size_t fi = membertype->builtin ? membertype->typeIndex : UA_BUILTIN_TYPES_COUNT; - size_t memSize = membertype->memSize; - ret |= decodeBinaryJumpTable[fi]((void *UA_RESTRICT)ptr, membertype, ctx); - ptr += memSize; - } else { - ptr += member->padding; - size_t *length = (size_t*)ptr; - ptr += sizeof(size_t); - ret |= Array_decodeBinary((void *UA_RESTRICT *UA_RESTRICT)ptr, length, membertype, ctx); - ptr += sizeof(void*); - } - } - - ctx->depth--; - return ret; -} - status UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, - const UA_DataType *type, size_t customTypesSize, - const UA_DataType *customTypes) { + const UA_DataType *type, const UA_DataTypeArray *customTypes) { /* Set up the context */ Ctx ctx; ctx.pos = &src->data[*offset]; ctx.end = &src->data[src->length]; ctx.depth = 0; - ctx.customTypesArraySize = customTypesSize; - ctx.customTypesArray = customTypes; + ctx.customTypes = customTypes; /* Decode */ memset(dst, 0, type->memSize); /* Initialize the value */ - status ret = decodeBinaryInternal(dst, type, &ctx); + status ret = decodeBinaryJumpTable[type->typeKind](dst, type, &ctx); if(ret == UA_STATUSCODE_GOOD) { /* Set the new offset */ *offset = (size_t)(ctx.pos - src->data) / sizeof(u8); } else { /* Clean up */ - UA_deleteMembers(dst, type); + UA_clear(dst, type); memset(dst, 0, type->memSize); } return ret; @@ -8265,29 +10226,24 @@ Array_calcSizeBinary(const void *src, size_t length, const UA_DataType *type) { return s; } uintptr_t ptr = (uintptr_t)src; - size_t encode_index = type->builtin ? type->typeIndex : UA_BUILTIN_TYPES_COUNT; for(size_t i = 0; i < length; ++i) { - s += calcSizeBinaryJumpTable[encode_index]((const void*)ptr, type); + s += calcSizeBinaryJumpTable[type->typeKind]((const void*)ptr, type); ptr += type->memSize; } return s; } -static size_t -calcSizeBinaryMemSize(const void *UA_RESTRICT p, const UA_DataType *type) { - return type->memSize; -} +static size_t calcSizeBinary1(const void *_, const UA_DataType *__) { (void)_, (void)__; return 1; } +static size_t calcSizeBinary2(const void *_, const UA_DataType *__) { (void)_, (void)__; return 2; } +static size_t calcSizeBinary4(const void *_, const UA_DataType *__) { (void)_, (void)__; return 4; } +static size_t calcSizeBinary8(const void *_, const UA_DataType *__) { (void)_, (void)__; return 8; } -CALCSIZE_BINARY(String) { - return 4 + src->length; -} +CALCSIZE_BINARY(String) { return 4 + src->length; } -CALCSIZE_BINARY(Guid) { - return 16; -} +CALCSIZE_BINARY(Guid) { return 16; } CALCSIZE_BINARY(NodeId) { - size_t s = 1; /* encoding byte */ + size_t s = 1; /* Encoding byte */ switch(src->identifierType) { case UA_NODEIDTYPE_NUMERIC: if(src->identifier.numeric > UA_UINT16_MAX || src->namespaceIndex > UA_BYTE_MAX) { @@ -8321,8 +10277,12 @@ CALCSIZE_BINARY(ExpandedNodeId) { return s; } +CALCSIZE_BINARY(QualifiedName) { + return 2 + String_calcSizeBinary(&src->name, NULL); +} + CALCSIZE_BINARY(LocalizedText) { - size_t s = 1; /* encoding byte */ + size_t s = 1; /* Encoding byte */ if(src->locale.data) s += String_calcSizeBinary(&src->locale, NULL); if(src->text.data) @@ -8331,18 +10291,10 @@ CALCSIZE_BINARY(LocalizedText) { } CALCSIZE_BINARY(ExtensionObject) { - size_t s = 1; /* encoding byte */ - if(src->encoding > UA_EXTENSIONOBJECT_ENCODED_XML) { - if(!src->content.decoded.type || !src->content.decoded.data) - return 0; - if(src->content.decoded.type->typeId.identifierType != UA_NODEIDTYPE_NUMERIC) - return 0; - s += NodeId_calcSizeBinary(&src->content.decoded.type->typeId, NULL); - s += 4; /* length */ - const UA_DataType *type = src->content.decoded.type; - size_t encode_index = type->builtin ? type->typeIndex : UA_BUILTIN_TYPES_COUNT; - s += calcSizeBinaryJumpTable[encode_index](src->content.decoded.data, type); - } else { + size_t s = 1; /* Encoding byte */ + + /* Encoded content */ + if(src->encoding <= UA_EXTENSIONOBJECT_ENCODED_XML) { s += NodeId_calcSizeBinary(&src->content.encoded.typeId, NULL); switch(src->encoding) { case UA_EXTENSIONOBJECT_ENCODED_NOBODY: @@ -8354,40 +10306,43 @@ CALCSIZE_BINARY(ExtensionObject) { default: return 0; } + return s; } + + /* Decoded content */ + if(!src->content.decoded.type || !src->content.decoded.data) + return 0; + if(src->content.decoded.type->typeId.identifierType != UA_NODEIDTYPE_NUMERIC) + return 0; + + s += NodeId_calcSizeBinary(&src->content.decoded.type->typeId, NULL); /* Type encoding length */ + s += 4; /* Encoding length field */ + const UA_DataType *type = src->content.decoded.type; + s += calcSizeBinaryJumpTable[type->typeKind](src->content.decoded.data, type); /* Encoding length */ return s; } CALCSIZE_BINARY(Variant) { - size_t s = 1; /* encoding byte */ + size_t s = 1; /* Encoding byte */ if(!src->type) return s; - bool isArray = src->arrayLength > 0 || src->data <= UA_EMPTY_ARRAY_SENTINEL; - bool hasDimensions = isArray && src->arrayDimensionsSize > 0; - bool isBuiltin = src->type->builtin; - - - size_t encode_index = src->type->typeIndex; - if(!isBuiltin) { - encode_index = UA_BUILTIN_TYPES_COUNT; - if(src->type->typeId.identifierType != UA_NODEIDTYPE_NUMERIC) - return 0; - } - - uintptr_t ptr = (uintptr_t)src->data; - size_t length = isArray ? src->arrayLength : 1; - if (isArray) - s += Array_calcSizeBinary((const void*)ptr, length, src->type); + const UA_Boolean isArray = src->arrayLength > 0 || src->data <= UA_EMPTY_ARRAY_SENTINEL; + if(isArray) + s += Array_calcSizeBinary(src->data, src->arrayLength, src->type); else - s += calcSizeBinaryJumpTable[encode_index]((const void*)ptr, src->type); + s += calcSizeBinaryJumpTable[src->type->typeKind](src->data, src->type); - if (!isBuiltin) { + const UA_Boolean isBuiltin = (src->type->typeKind <= UA_DATATYPEKIND_DIAGNOSTICINFO); + const UA_Boolean isEnum = (src->type->typeKind == UA_DATATYPEKIND_ENUM); + if(!isBuiltin && !isEnum) { /* The type is wrapped inside an extensionobject */ /* (NodeId + encoding byte + extension object length) * array length */ + size_t length = isArray ? src->arrayLength : 1; s += (NodeId_calcSizeBinary(&src->type->typeId, NULL) + 1 + 4) * length; } + const UA_Boolean hasDimensions = isArray && src->arrayDimensionsSize > 0; if(hasDimensions) s += Array_calcSizeBinary(src->arrayDimensions, src->arrayDimensionsSize, &UA_TYPES[UA_TYPES_INT32]); @@ -8395,7 +10350,7 @@ CALCSIZE_BINARY(Variant) { } CALCSIZE_BINARY(DataValue) { - size_t s = 1; /* encoding byte */ + size_t s = 1; /* Encoding byte */ if(src->hasValue) s += Variant_calcSizeBinary(&src->value, NULL); if(src->hasStatus) @@ -8412,7 +10367,7 @@ CALCSIZE_BINARY(DataValue) { } CALCSIZE_BINARY(DiagnosticInfo) { - size_t s = 1; /* encoding byte */ + size_t s = 1; /* Encoding byte */ if(src->hasSymbolicId) s += 4; if(src->hasNamespaceUri) @@ -8430,5471 +10385,4312 @@ CALCSIZE_BINARY(DiagnosticInfo) { return s; } -const calcSizeBinarySignature calcSizeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = { - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* Boolean */ - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* Byte */ - (calcSizeBinarySignature)calcSizeBinaryMemSize, - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* Int16 */ - (calcSizeBinarySignature)calcSizeBinaryMemSize, - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* Int32 */ - (calcSizeBinarySignature)calcSizeBinaryMemSize, - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* Int64 */ - (calcSizeBinarySignature)calcSizeBinaryMemSize, - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* Float */ - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* Double */ - (calcSizeBinarySignature)String_calcSizeBinary, - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* DateTime */ - (calcSizeBinarySignature)Guid_calcSizeBinary, - (calcSizeBinarySignature)String_calcSizeBinary, /* ByteString */ - (calcSizeBinarySignature)String_calcSizeBinary, /* XmlElement */ - (calcSizeBinarySignature)NodeId_calcSizeBinary, - (calcSizeBinarySignature)ExpandedNodeId_calcSizeBinary, - (calcSizeBinarySignature)calcSizeBinaryMemSize, /* StatusCode */ - (calcSizeBinarySignature)UA_calcSizeBinary, /* QualifiedName */ - (calcSizeBinarySignature)LocalizedText_calcSizeBinary, - (calcSizeBinarySignature)ExtensionObject_calcSizeBinary, - (calcSizeBinarySignature)DataValue_calcSizeBinary, - (calcSizeBinarySignature)Variant_calcSizeBinary, - (calcSizeBinarySignature)DiagnosticInfo_calcSizeBinary, - (calcSizeBinarySignature)UA_calcSizeBinary -}; - -size_t -UA_calcSizeBinary(void *p, const UA_DataType *type) { +static size_t +calcSizeBinaryStructure(const void *p, const UA_DataType *type) { size_t s = 0; uintptr_t ptr = (uintptr_t)p; u8 membersSize = type->membersSize; const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] }; + + /* Loop over members */ for(size_t i = 0; i < membersSize; ++i) { const UA_DataTypeMember *member = &type->members[i]; const UA_DataType *membertype = &typelists[!member->namespaceZero][member->memberTypeIndex]; - if(!member->isArray) { - ptr += member->padding; - size_t encode_index = membertype->builtin ? membertype->typeIndex : UA_BUILTIN_TYPES_COUNT; - s += calcSizeBinaryJumpTable[encode_index]((const void*)ptr, membertype); - ptr += membertype->memSize; - } else { - ptr += member->padding; + ptr += member->padding; + + /* Array */ + if(member->isArray) { const size_t length = *((const size_t*)ptr); ptr += sizeof(size_t); s += Array_calcSizeBinary(*(void *UA_RESTRICT const *)ptr, length, membertype); ptr += sizeof(void*); + continue; } + + /* Scalar */ + s += calcSizeBinaryJumpTable[membertype->typeKind]((const void*)ptr, membertype); + ptr += membertype->memSize; } + return s; } -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_types_generated.c" ***********************************/ +static size_t +calcSizeBinaryNotImplemented(const void *p, const UA_DataType *type) { + (void)p, (void)type; + return 0; +} + +const calcSizeBinarySignature calcSizeBinaryJumpTable[UA_DATATYPEKINDS] = { + (calcSizeBinarySignature)calcSizeBinary1, /* Boolean */ + (calcSizeBinarySignature)calcSizeBinary1, /* SByte */ + (calcSizeBinarySignature)calcSizeBinary1, /* Byte */ + (calcSizeBinarySignature)calcSizeBinary2, /* Int16 */ + (calcSizeBinarySignature)calcSizeBinary2, /* UInt16 */ + (calcSizeBinarySignature)calcSizeBinary4, /* Int32 */ + (calcSizeBinarySignature)calcSizeBinary4, /* UInt32 */ + (calcSizeBinarySignature)calcSizeBinary8, /* Int64 */ + (calcSizeBinarySignature)calcSizeBinary8, /* UInt64 */ + (calcSizeBinarySignature)calcSizeBinary4, /* Float */ + (calcSizeBinarySignature)calcSizeBinary8, /* Double */ + (calcSizeBinarySignature)String_calcSizeBinary, + (calcSizeBinarySignature)calcSizeBinary8, /* DateTime */ + (calcSizeBinarySignature)Guid_calcSizeBinary, + (calcSizeBinarySignature)String_calcSizeBinary, /* ByteString */ + (calcSizeBinarySignature)String_calcSizeBinary, /* XmlElement */ + (calcSizeBinarySignature)NodeId_calcSizeBinary, + (calcSizeBinarySignature)ExpandedNodeId_calcSizeBinary, + (calcSizeBinarySignature)calcSizeBinary4, /* StatusCode */ + (calcSizeBinarySignature)QualifiedName_calcSizeBinary, + (calcSizeBinarySignature)LocalizedText_calcSizeBinary, + (calcSizeBinarySignature)ExtensionObject_calcSizeBinary, + (calcSizeBinarySignature)DataValue_calcSizeBinary, + (calcSizeBinarySignature)Variant_calcSizeBinary, + (calcSizeBinarySignature)DiagnosticInfo_calcSizeBinary, + (calcSizeBinarySignature)calcSizeBinaryNotImplemented, /* Decimal */ + (calcSizeBinarySignature)calcSizeBinary4, /* Enumeration */ + (calcSizeBinarySignature)calcSizeBinaryStructure, + (calcSizeBinarySignature)calcSizeBinaryNotImplemented, /* Structure with Optional Fields */ + (calcSizeBinarySignature)calcSizeBinaryNotImplemented, /* Union */ + (calcSizeBinarySignature)calcSizeBinaryNotImplemented /* BitfieldCluster */ +}; + +size_t +UA_calcSizeBinary(const void *p, const UA_DataType *type) { + return calcSizeBinaryJumpTable[type->typeKind](p, type); +} + +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/types_generated.c" ***********************************/ /* Generated from Opc.Ua.Types.bsd with script /home/jvoe/open62541/tools/generate_datatypes.py - * on host rigel by user jvoe at 2019-01-04 01:18:40 */ + * on host rigel by user jvoe at 2019-07-30 11:30:09 */ /* Boolean */ -static UA_DataTypeMember Boolean_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Boolean_members NULL /* SByte */ -static UA_DataTypeMember SByte_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_SBYTE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define SByte_members NULL /* Byte */ -static UA_DataTypeMember Byte_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Byte_members NULL /* Int16 */ -static UA_DataTypeMember Int16_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT16, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Int16_members NULL /* UInt16 */ -static UA_DataTypeMember UInt16_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_UINT16, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define UInt16_members NULL /* Int32 */ -static UA_DataTypeMember Int32_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Int32_members NULL /* UInt32 */ -static UA_DataTypeMember UInt32_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define UInt32_members NULL /* Int64 */ -static UA_DataTypeMember Int64_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT64, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Int64_members NULL /* UInt64 */ -static UA_DataTypeMember UInt64_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_UINT64, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define UInt64_members NULL /* Float */ -static UA_DataTypeMember Float_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_FLOAT, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Float_members NULL /* Double */ -static UA_DataTypeMember Double_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Double_members NULL /* String */ -static UA_DataTypeMember String_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +#define String_members NULL /* DateTime */ -static UA_DataTypeMember DateTime_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define DateTime_members NULL /* Guid */ -static UA_DataTypeMember Guid_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_GUID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Guid_members NULL /* ByteString */ -static UA_DataTypeMember ByteString_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +#define ByteString_members NULL /* XmlElement */ -static UA_DataTypeMember XmlElement_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +#define XmlElement_members NULL /* NodeId */ -static UA_DataTypeMember NodeId_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define NodeId_members NULL /* ExpandedNodeId */ -static UA_DataTypeMember ExpandedNodeId_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define ExpandedNodeId_members NULL /* StatusCode */ -static UA_DataTypeMember StatusCode_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define StatusCode_members NULL /* QualifiedName */ -static UA_DataTypeMember QualifiedName_members[2] = { -{ - UA_TYPENAME("namespaceIndex") /* .memberName */ - UA_TYPES_INT16, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("name") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_QualifiedName, name) - offsetof(UA_QualifiedName, namespaceIndex) - sizeof(UA_Int16), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define QualifiedName_members NULL /* LocalizedText */ -static UA_DataTypeMember LocalizedText_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define LocalizedText_members NULL /* ExtensionObject */ -static UA_DataTypeMember ExtensionObject_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define ExtensionObject_members NULL /* DataValue */ -static UA_DataTypeMember DataValue_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_DATAVALUE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define DataValue_members NULL /* Variant */ -static UA_DataTypeMember Variant_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_VARIANT, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define Variant_members NULL /* DiagnosticInfo */ -static UA_DataTypeMember DiagnosticInfo_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* SignedSoftwareCertificate */ -static UA_DataTypeMember SignedSoftwareCertificate_members[2] = { -{ - UA_TYPENAME("certificateData") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("signature") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_SignedSoftwareCertificate, signature) - offsetof(UA_SignedSoftwareCertificate, certificateData) - sizeof(UA_ByteString), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* SemanticChangeStructureDataType */ -static UA_DataTypeMember SemanticChangeStructureDataType_members[2] = { -{ - UA_TYPENAME("affected") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("affectedType") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_SemanticChangeStructureDataType, affectedType) - offsetof(UA_SemanticChangeStructureDataType, affected) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* StatusChangeNotification */ -static UA_DataTypeMember StatusChangeNotification_members[2] = { -{ - UA_TYPENAME("status") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfo") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_StatusChangeNotification, diagnosticInfo) - offsetof(UA_StatusChangeNotification, status) - sizeof(UA_StatusCode), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* BrowsePathTarget */ -static UA_DataTypeMember BrowsePathTarget_members[2] = { -{ - UA_TYPENAME("targetId") /* .memberName */ - UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("remainingPathIndex") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_BrowsePathTarget, remainingPathIndex) - offsetof(UA_BrowsePathTarget, targetId) - sizeof(UA_ExpandedNodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define DiagnosticInfo_members NULL /* ViewAttributes */ static UA_DataTypeMember ViewAttributes_members[7] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ + UA_TYPENAME("DisplayName") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ offsetof(UA_ViewAttributes, displayName) - offsetof(UA_ViewAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("description") /* .memberName */ + UA_TYPENAME("Description") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ offsetof(UA_ViewAttributes, description) - offsetof(UA_ViewAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ + UA_TYPENAME("WriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_ViewAttributes, writeMask) - offsetof(UA_ViewAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userWriteMask") /* .memberName */ + UA_TYPENAME("UserWriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_ViewAttributes, userWriteMask) - offsetof(UA_ViewAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("containsNoLoops") /* .memberName */ + UA_TYPENAME("ContainsNoLoops") /* .memberName */ UA_TYPES_BOOLEAN, /* .memberTypeIndex */ offsetof(UA_ViewAttributes, containsNoLoops) - offsetof(UA_ViewAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("eventNotifier") /* .memberName */ + UA_TYPENAME("EventNotifier") /* .memberName */ UA_TYPES_BYTE, /* .memberTypeIndex */ offsetof(UA_ViewAttributes, eventNotifier) - offsetof(UA_ViewAttributes, containsNoLoops) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* RequestHeader */ -static UA_DataTypeMember RequestHeader_members[7] = { -{ - UA_TYPENAME("authenticationToken") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("timestamp") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ - offsetof(UA_RequestHeader, timestamp) - offsetof(UA_RequestHeader, authenticationToken) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("requestHandle") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_RequestHeader, requestHandle) - offsetof(UA_RequestHeader, timestamp) - sizeof(UA_DateTime), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("returnDiagnostics") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_RequestHeader, returnDiagnostics) - offsetof(UA_RequestHeader, requestHandle) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("auditEntryId") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_RequestHeader, auditEntryId) - offsetof(UA_RequestHeader, returnDiagnostics) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("timeoutHint") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_RequestHeader, timeoutHint) - offsetof(UA_RequestHeader, auditEntryId) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("additionalHeader") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_RequestHeader, additionalHeader) - offsetof(UA_RequestHeader, timeoutHint) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* MonitoredItemModifyResult */ -static UA_DataTypeMember MonitoredItemModifyResult_members[4] = { -{ - UA_TYPENAME("statusCode") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("revisedSamplingInterval") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemModifyResult, revisedSamplingInterval) - offsetof(UA_MonitoredItemModifyResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("revisedQueueSize") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemModifyResult, revisedQueueSize) - offsetof(UA_MonitoredItemModifyResult, revisedSamplingInterval) - sizeof(UA_Double), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("filterResult") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemModifyResult, filterResult) - offsetof(UA_MonitoredItemModifyResult, revisedQueueSize) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +},}; /* ElementOperand */ static UA_DataTypeMember ElementOperand_members[1] = { { - UA_TYPENAME("index") /* .memberName */ + UA_TYPENAME("Index") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* CloseSecureChannelRequest */ -static UA_DataTypeMember CloseSecureChannelRequest_members[1] = { -{ - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* AddNodesResult */ -static UA_DataTypeMember AddNodesResult_members[2] = { -{ - UA_TYPENAME("statusCode") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("addedNodeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_AddNodesResult, addedNodeId) - offsetof(UA_AddNodesResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +},}; /* VariableAttributes */ static UA_DataTypeMember VariableAttributes_members[13] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ + UA_TYPENAME("DisplayName") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, displayName) - offsetof(UA_VariableAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("description") /* .memberName */ + UA_TYPENAME("Description") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, description) - offsetof(UA_VariableAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ + UA_TYPENAME("WriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, writeMask) - offsetof(UA_VariableAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userWriteMask") /* .memberName */ + UA_TYPENAME("UserWriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, userWriteMask) - offsetof(UA_VariableAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("value") /* .memberName */ + UA_TYPENAME("Value") /* .memberName */ UA_TYPES_VARIANT, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, value) - offsetof(UA_VariableAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("dataType") /* .memberName */ + UA_TYPENAME("DataType") /* .memberName */ UA_TYPES_NODEID, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, dataType) - offsetof(UA_VariableAttributes, value) - sizeof(UA_Variant), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("valueRank") /* .memberName */ + UA_TYPENAME("ValueRank") /* .memberName */ UA_TYPES_INT32, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, valueRank) - offsetof(UA_VariableAttributes, dataType) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("arrayDimensions") /* .memberName */ + UA_TYPENAME("ArrayDimensions") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, arrayDimensionsSize) - offsetof(UA_VariableAttributes, valueRank) - sizeof(UA_Int32), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("accessLevel") /* .memberName */ + UA_TYPENAME("AccessLevel") /* .memberName */ UA_TYPES_BYTE, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, accessLevel) - offsetof(UA_VariableAttributes, arrayDimensions) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userAccessLevel") /* .memberName */ + UA_TYPENAME("UserAccessLevel") /* .memberName */ UA_TYPES_BYTE, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, userAccessLevel) - offsetof(UA_VariableAttributes, accessLevel) - sizeof(UA_Byte), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("minimumSamplingInterval") /* .memberName */ + UA_TYPENAME("MinimumSamplingInterval") /* .memberName */ UA_TYPES_DOUBLE, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, minimumSamplingInterval) - offsetof(UA_VariableAttributes, userAccessLevel) - sizeof(UA_Byte), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("historizing") /* .memberName */ + UA_TYPENAME("Historizing") /* .memberName */ UA_TYPES_BOOLEAN, /* .memberTypeIndex */ offsetof(UA_VariableAttributes, historizing) - offsetof(UA_VariableAttributes, minimumSamplingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* NotificationMessage */ -static UA_DataTypeMember NotificationMessage_members[3] = { -{ - UA_TYPENAME("sequenceNumber") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("publishTime") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ - offsetof(UA_NotificationMessage, publishTime) - offsetof(UA_NotificationMessage, sequenceNumber) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("notificationData") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_NotificationMessage, notificationDataSize) - offsetof(UA_NotificationMessage, publishTime) - sizeof(UA_DateTime), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +},}; -/* FindServersOnNetworkRequest */ -static UA_DataTypeMember FindServersOnNetworkRequest_members[4] = { +/* EnumValueType */ +static UA_DataTypeMember EnumValueType_members[3] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("Value") /* .memberName */ + UA_TYPES_INT64, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("startingRecordId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_FindServersOnNetworkRequest, startingRecordId) - offsetof(UA_FindServersOnNetworkRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("DisplayName") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_EnumValueType, displayName) - offsetof(UA_EnumValueType, value) - sizeof(UA_Int64), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxRecordsToReturn") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_FindServersOnNetworkRequest, maxRecordsToReturn) - offsetof(UA_FindServersOnNetworkRequest, startingRecordId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Description") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_EnumValueType, description) - offsetof(UA_EnumValueType, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, -{ - UA_TYPENAME("serverCapabilityFilter") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_FindServersOnNetworkRequest, serverCapabilityFilterSize) - offsetof(UA_FindServersOnNetworkRequest, maxRecordsToReturn) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +},}; /* EventFieldList */ static UA_DataTypeMember EventFieldList_members[2] = { { - UA_TYPENAME("clientHandle") /* .memberName */ + UA_TYPENAME("ClientHandle") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("eventFields") /* .memberName */ + UA_TYPENAME("EventFields") /* .memberName */ UA_TYPES_VARIANT, /* .memberTypeIndex */ offsetof(UA_EventFieldList, eventFieldsSize) - offsetof(UA_EventFieldList, clientHandle) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* MonitoringMode */ -static UA_DataTypeMember MonitoringMode_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* MdnsDiscoveryConfiguration */ -static UA_DataTypeMember MdnsDiscoveryConfiguration_members[2] = { +/* MonitoredItemCreateResult */ +static UA_DataTypeMember MonitoredItemCreateResult_members[5] = { { - UA_TYPENAME("mdnsServerName") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ + UA_TYPENAME("StatusCode") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverCapabilities") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_MdnsDiscoveryConfiguration, serverCapabilitiesSize) - offsetof(UA_MdnsDiscoveryConfiguration, mdnsServerName) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* CallMethodResult */ -static UA_DataTypeMember CallMethodResult_members[4] = { -{ - UA_TYPENAME("statusCode") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("MonitoredItemId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemCreateResult, monitoredItemId) - offsetof(UA_MonitoredItemCreateResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("inputArgumentResults") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_CallMethodResult, inputArgumentResultsSize) - offsetof(UA_CallMethodResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ + UA_TYPENAME("RevisedSamplingInterval") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemCreateResult, revisedSamplingInterval) - offsetof(UA_MonitoredItemCreateResult, monitoredItemId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("inputArgumentDiagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_CallMethodResult, inputArgumentDiagnosticInfosSize) - offsetof(UA_CallMethodResult, inputArgumentResults) - sizeof(void*), /* .padding */ + UA_TYPENAME("RevisedQueueSize") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemCreateResult, revisedQueueSize) - offsetof(UA_MonitoredItemCreateResult, revisedSamplingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("outputArguments") /* .memberName */ - UA_TYPES_VARIANT, /* .memberTypeIndex */ - offsetof(UA_CallMethodResult, outputArgumentsSize) - offsetof(UA_CallMethodResult, inputArgumentDiagnosticInfos) - sizeof(void*), /* .padding */ + UA_TYPENAME("FilterResult") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemCreateResult, filterResult) - offsetof(UA_MonitoredItemCreateResult, revisedQueueSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* ParsingResult */ -static UA_DataTypeMember ParsingResult_members[3] = { +/* ServerDiagnosticsSummaryDataType */ +static UA_DataTypeMember ServerDiagnosticsSummaryDataType_members[12] = { { - UA_TYPENAME("statusCode") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + UA_TYPENAME("ServerViewCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("dataStatusCodes") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_ParsingResult, dataStatusCodesSize) - offsetof(UA_ParsingResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ + UA_TYPENAME("CurrentSessionCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, serverViewCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("dataDiagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_ParsingResult, dataDiagnosticInfosSize) - offsetof(UA_ParsingResult, dataStatusCodes) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* RelativePathElement */ -static UA_DataTypeMember RelativePathElement_members[4] = { -{ - UA_TYPENAME("referenceTypeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("CumulatedSessionCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("isInverse") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_RelativePathElement, isInverse) - offsetof(UA_RelativePathElement, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("SecurityRejectedSessionCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("includeSubtypes") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_RelativePathElement, includeSubtypes) - offsetof(UA_RelativePathElement, isInverse) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("RejectedSessionCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("targetName") /* .memberName */ - UA_TYPES_QUALIFIEDNAME, /* .memberTypeIndex */ - offsetof(UA_RelativePathElement, targetName) - offsetof(UA_RelativePathElement, includeSubtypes) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("SessionTimeoutCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* BrowseDirection */ -static UA_DataTypeMember BrowseDirection_members[1] = { +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("SessionAbortCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* CallMethodRequest */ -static UA_DataTypeMember CallMethodRequest_members[3] = { +}, { - UA_TYPENAME("objectId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("CurrentSubscriptionCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("methodId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_CallMethodRequest, methodId) - offsetof(UA_CallMethodRequest, objectId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("CumulatedSubscriptionCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("inputArguments") /* .memberName */ - UA_TYPES_VARIANT, /* .memberTypeIndex */ - offsetof(UA_CallMethodRequest, inputArgumentsSize) - offsetof(UA_CallMethodRequest, methodId) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* RedundancySupport */ -static UA_DataTypeMember RedundancySupport_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("PublishingIntervalCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* EventNotificationList */ -static UA_DataTypeMember EventNotificationList_members[1] = { -{ - UA_TYPENAME("events") /* .memberName */ - UA_TYPES_EVENTFIELDLIST, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* UnregisterNodesRequest */ -static UA_DataTypeMember UnregisterNodesRequest_members[2] = { +}, { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("SecurityRejectedRequestsCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodesToUnregister") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_UnregisterNodesRequest, nodesToUnregisterSize) - offsetof(UA_UnregisterNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("RejectedRequestsCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedRequestsCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; /* ContentFilterElementResult */ static UA_DataTypeMember ContentFilterElementResult_members[3] = { { - UA_TYPENAME("statusCode") /* .memberName */ + UA_TYPENAME("StatusCode") /* .memberName */ UA_TYPES_STATUSCODE, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("operandStatusCodes") /* .memberName */ + UA_TYPENAME("OperandStatusCodes") /* .memberName */ UA_TYPES_STATUSCODE, /* .memberTypeIndex */ offsetof(UA_ContentFilterElementResult, operandStatusCodesSize) - offsetof(UA_ContentFilterElementResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("operandDiagnosticInfos") /* .memberName */ + UA_TYPENAME("OperandDiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ offsetof(UA_ContentFilterElementResult, operandDiagnosticInfosSize) - offsetof(UA_ContentFilterElementResult, operandStatusCodes) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; - -/* SimpleAttributeOperand */ -static UA_DataTypeMember SimpleAttributeOperand_members[4] = { -{ - UA_TYPENAME("typeDefinitionId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("browsePath") /* .memberName */ - UA_TYPES_QUALIFIEDNAME, /* .memberTypeIndex */ - offsetof(UA_SimpleAttributeOperand, browsePathSize) - offsetof(UA_SimpleAttributeOperand, typeDefinitionId) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("attributeId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SimpleAttributeOperand, attributeId) - offsetof(UA_SimpleAttributeOperand, browsePath) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("indexRange") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SimpleAttributeOperand, indexRange) - offsetof(UA_SimpleAttributeOperand, attributeId) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +},}; /* LiteralOperand */ static UA_DataTypeMember LiteralOperand_members[1] = { { - UA_TYPENAME("value") /* .memberName */ + UA_TYPENAME("Value") /* .memberName */ UA_TYPES_VARIANT, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; + +/* MessageSecurityMode */ +#define MessageSecurityMode_members NULL -/* QueryDataSet */ -static UA_DataTypeMember QueryDataSet_members[3] = { +/* UtcTime */ +#define UtcTime_members NULL + +/* UserIdentityToken */ +static UA_DataTypeMember UserIdentityToken_members[1] = { { - UA_TYPENAME("nodeId") /* .memberName */ - UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ + UA_TYPENAME("PolicyId") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* X509IdentityToken */ +static UA_DataTypeMember X509IdentityToken_members[2] = { { - UA_TYPENAME("typeDefinitionNode") /* .memberName */ - UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ - offsetof(UA_QueryDataSet, typeDefinitionNode) - offsetof(UA_QueryDataSet, nodeId) - sizeof(UA_ExpandedNodeId), /* .padding */ + UA_TYPENAME("PolicyId") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("values") /* .memberName */ - UA_TYPES_VARIANT, /* .memberTypeIndex */ - offsetof(UA_QueryDataSet, valuesSize) - offsetof(UA_QueryDataSet, typeDefinitionNode) - sizeof(UA_ExpandedNodeId), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* AnonymousIdentityToken */ -static UA_DataTypeMember AnonymousIdentityToken_members[1] = { -{ - UA_TYPENAME("policyId") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("CertificateData") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_X509IdentityToken, certificateData) - offsetof(UA_X509IdentityToken, policyId) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* SetPublishingModeRequest */ -static UA_DataTypeMember SetPublishingModeRequest_members[3] = { +/* MonitoredItemNotification */ +static UA_DataTypeMember MonitoredItemNotification_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ClientHandle") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("publishingEnabled") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_SetPublishingModeRequest, publishingEnabled) - offsetof(UA_SetPublishingModeRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("Value") /* .memberName */ + UA_TYPES_DATAVALUE, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemNotification, value) - offsetof(UA_MonitoredItemNotification, clientHandle) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, -{ - UA_TYPENAME("subscriptionIds") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SetPublishingModeRequest, subscriptionIdsSize) - offsetof(UA_SetPublishingModeRequest, publishingEnabled) - sizeof(UA_Boolean), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +},}; -/* MonitoredItemCreateResult */ -static UA_DataTypeMember MonitoredItemCreateResult_members[5] = { +/* ResponseHeader */ +static UA_DataTypeMember ResponseHeader_members[6] = { { - UA_TYPENAME("statusCode") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + UA_TYPENAME("Timestamp") /* .memberName */ + UA_TYPES_DATETIME, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("monitoredItemId") /* .memberName */ + UA_TYPENAME("RequestHandle") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemCreateResult, monitoredItemId) - offsetof(UA_MonitoredItemCreateResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ + offsetof(UA_ResponseHeader, requestHandle) - offsetof(UA_ResponseHeader, timestamp) - sizeof(UA_DateTime), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("revisedSamplingInterval") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemCreateResult, revisedSamplingInterval) - offsetof(UA_MonitoredItemCreateResult, monitoredItemId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ServiceResult") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_ResponseHeader, serviceResult) - offsetof(UA_ResponseHeader, requestHandle) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("revisedQueueSize") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemCreateResult, revisedQueueSize) - offsetof(UA_MonitoredItemCreateResult, revisedSamplingInterval) - sizeof(UA_Double), /* .padding */ + UA_TYPENAME("ServiceDiagnostics") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_ResponseHeader, serviceDiagnostics) - offsetof(UA_ResponseHeader, serviceResult) - sizeof(UA_StatusCode), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("filterResult") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemCreateResult, filterResult) - offsetof(UA_MonitoredItemCreateResult, revisedQueueSize) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("StringTable") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_ResponseHeader, stringTableSize) - offsetof(UA_ResponseHeader, serviceDiagnostics) - sizeof(UA_DiagnosticInfo), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* TimestampsToReturn */ -static UA_DataTypeMember TimestampsToReturn_members[1] = { + true /* .isArray */ +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("AdditionalHeader") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_ResponseHeader, additionalHeader) - offsetof(UA_ResponseHeader, stringTable) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* CallRequest */ -static UA_DataTypeMember CallRequest_members[2] = { +/* SignatureData */ +static UA_DataTypeMember SignatureData_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("Algorithm") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("methodsToCall") /* .memberName */ - UA_TYPES_CALLMETHODREQUEST, /* .memberTypeIndex */ - offsetof(UA_CallRequest, methodsToCallSize) - offsetof(UA_CallRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("Signature") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_SignatureData, signature) - offsetof(UA_SignatureData, algorithm) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* MethodAttributes */ -static UA_DataTypeMember MethodAttributes_members[7] = { +/* ModifySubscriptionResponse */ +static UA_DataTypeMember ModifySubscriptionResponse_members[4] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_MethodAttributes, displayName) - offsetof(UA_MethodAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("description") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_MethodAttributes, description) - offsetof(UA_MethodAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ + UA_TYPENAME("RevisedPublishingInterval") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + offsetof(UA_ModifySubscriptionResponse, revisedPublishingInterval) - offsetof(UA_ModifySubscriptionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ + UA_TYPENAME("RevisedLifetimeCount") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_MethodAttributes, writeMask) - offsetof(UA_MethodAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ + offsetof(UA_ModifySubscriptionResponse, revisedLifetimeCount) - offsetof(UA_ModifySubscriptionResponse, revisedPublishingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userWriteMask") /* .memberName */ + UA_TYPENAME("RevisedMaxKeepAliveCount") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_MethodAttributes, userWriteMask) - offsetof(UA_MethodAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("executable") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_MethodAttributes, executable) - offsetof(UA_MethodAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("userExecutable") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_MethodAttributes, userExecutable) - offsetof(UA_MethodAttributes, executable) - sizeof(UA_Boolean), /* .padding */ + offsetof(UA_ModifySubscriptionResponse, revisedMaxKeepAliveCount) - offsetof(UA_ModifySubscriptionResponse, revisedLifetimeCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* DeleteReferencesItem */ -static UA_DataTypeMember DeleteReferencesItem_members[5] = { +/* NodeAttributes */ +static UA_DataTypeMember NodeAttributes_members[5] = { { - UA_TYPENAME("sourceNodeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("referenceTypeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_DeleteReferencesItem, referenceTypeId) - offsetof(UA_DeleteReferencesItem, sourceNodeId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("DisplayName") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_NodeAttributes, displayName) - offsetof(UA_NodeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("isForward") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_DeleteReferencesItem, isForward) - offsetof(UA_DeleteReferencesItem, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("Description") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_NodeAttributes, description) - offsetof(UA_NodeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("targetNodeId") /* .memberName */ - UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ - offsetof(UA_DeleteReferencesItem, targetNodeId) - offsetof(UA_DeleteReferencesItem, isForward) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("WriteMask") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_NodeAttributes, writeMask) - offsetof(UA_NodeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("deleteBidirectional") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_DeleteReferencesItem, deleteBidirectional) - offsetof(UA_DeleteReferencesItem, targetNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */ + UA_TYPENAME("UserWriteMask") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_NodeAttributes, userWriteMask) - offsetof(UA_NodeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* WriteValue */ -static UA_DataTypeMember WriteValue_members[4] = { +/* ActivateSessionResponse */ +static UA_DataTypeMember ActivateSessionResponse_members[4] = { { - UA_TYPENAME("nodeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("attributeId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_WriteValue, attributeId) - offsetof(UA_WriteValue, nodeId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("ServerNonce") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_ActivateSessionResponse, serverNonce) - offsetof(UA_ActivateSessionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("indexRange") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_WriteValue, indexRange) - offsetof(UA_WriteValue, attributeId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_ActivateSessionResponse, resultsSize) - offsetof(UA_ActivateSessionResponse, serverNonce) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("value") /* .memberName */ - UA_TYPES_DATAVALUE, /* .memberTypeIndex */ - offsetof(UA_WriteValue, value) - offsetof(UA_WriteValue, indexRange) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* NodeAttributesMask */ -static UA_DataTypeMember NodeAttributesMask_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* MessageSecurityMode */ -static UA_DataTypeMember MessageSecurityMode_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_ActivateSessionResponse, diagnosticInfosSize) - offsetof(UA_ActivateSessionResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* MonitoringParameters */ -static UA_DataTypeMember MonitoringParameters_members[5] = { +/* VariableTypeAttributes */ +static UA_DataTypeMember VariableTypeAttributes_members[10] = { { - UA_TYPENAME("clientHandle") /* .memberName */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("samplingInterval") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_MonitoringParameters, samplingInterval) - offsetof(UA_MonitoringParameters, clientHandle) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DisplayName") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_VariableTypeAttributes, displayName) - offsetof(UA_VariableTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("filter") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_MonitoringParameters, filter) - offsetof(UA_MonitoringParameters, samplingInterval) - sizeof(UA_Double), /* .padding */ + UA_TYPENAME("Description") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_VariableTypeAttributes, description) - offsetof(UA_VariableTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("queueSize") /* .memberName */ + UA_TYPENAME("WriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_MonitoringParameters, queueSize) - offsetof(UA_MonitoringParameters, filter) - sizeof(UA_ExtensionObject), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("discardOldest") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_MonitoringParameters, discardOldest) - offsetof(UA_MonitoringParameters, queueSize) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* ReferenceNode */ -static UA_DataTypeMember ReferenceNode_members[3] = { -{ - UA_TYPENAME("referenceTypeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ + offsetof(UA_VariableTypeAttributes, writeMask) - offsetof(UA_VariableTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("isInverse") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_ReferenceNode, isInverse) - offsetof(UA_ReferenceNode, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("UserWriteMask") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_VariableTypeAttributes, userWriteMask) - offsetof(UA_VariableTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("targetId") /* .memberName */ - UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ - offsetof(UA_ReferenceNode, targetId) - offsetof(UA_ReferenceNode, isInverse) - sizeof(UA_Boolean), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* Argument */ -static UA_DataTypeMember Argument_members[5] = { -{ - UA_TYPENAME("name") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("Value") /* .memberName */ + UA_TYPES_VARIANT, /* .memberTypeIndex */ + offsetof(UA_VariableTypeAttributes, value) - offsetof(UA_VariableTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("dataType") /* .memberName */ + UA_TYPENAME("DataType") /* .memberName */ UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_Argument, dataType) - offsetof(UA_Argument, name) - sizeof(UA_String), /* .padding */ + offsetof(UA_VariableTypeAttributes, dataType) - offsetof(UA_VariableTypeAttributes, value) - sizeof(UA_Variant), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("valueRank") /* .memberName */ + UA_TYPENAME("ValueRank") /* .memberName */ UA_TYPES_INT32, /* .memberTypeIndex */ - offsetof(UA_Argument, valueRank) - offsetof(UA_Argument, dataType) - sizeof(UA_NodeId), /* .padding */ + offsetof(UA_VariableTypeAttributes, valueRank) - offsetof(UA_VariableTypeAttributes, dataType) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("arrayDimensions") /* .memberName */ + UA_TYPENAME("ArrayDimensions") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_Argument, arrayDimensionsSize) - offsetof(UA_Argument, valueRank) - sizeof(UA_Int32), /* .padding */ + offsetof(UA_VariableTypeAttributes, arrayDimensionsSize) - offsetof(UA_VariableTypeAttributes, valueRank) - sizeof(UA_Int32), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("description") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_Argument, description) - offsetof(UA_Argument, arrayDimensions) - sizeof(void*), /* .padding */ + UA_TYPENAME("IsAbstract") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_VariableTypeAttributes, isAbstract) - offsetof(UA_VariableTypeAttributes, arrayDimensions) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* ChannelSecurityToken */ -static UA_DataTypeMember ChannelSecurityToken_members[4] = { +/* CallMethodResult */ +static UA_DataTypeMember CallMethodResult_members[4] = { { - UA_TYPENAME("channelId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("StatusCode") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("tokenId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ChannelSecurityToken, tokenId) - offsetof(UA_ChannelSecurityToken, channelId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("InputArgumentResults") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_CallMethodResult, inputArgumentResultsSize) - offsetof(UA_CallMethodResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("createdAt") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ - offsetof(UA_ChannelSecurityToken, createdAt) - offsetof(UA_ChannelSecurityToken, tokenId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("InputArgumentDiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_CallMethodResult, inputArgumentDiagnosticInfosSize) - offsetof(UA_CallMethodResult, inputArgumentResults) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("revisedLifetime") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ChannelSecurityToken, revisedLifetime) - offsetof(UA_ChannelSecurityToken, createdAt) - sizeof(UA_DateTime), /* .padding */ + UA_TYPENAME("OutputArguments") /* .memberName */ + UA_TYPES_VARIANT, /* .memberTypeIndex */ + offsetof(UA_CallMethodResult, outputArgumentsSize) - offsetof(UA_CallMethodResult, inputArgumentDiagnosticInfos) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* UserIdentityToken */ -static UA_DataTypeMember UserIdentityToken_members[1] = { +/* MonitoringMode */ +#define MonitoringMode_members NULL + +/* SetMonitoringModeResponse */ +static UA_DataTypeMember SetMonitoringModeResponse_members[3] = { { - UA_TYPENAME("policyId") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* SignatureData */ -static UA_DataTypeMember SignatureData_members[2] = { +}, { - UA_TYPENAME("algorithm") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_SetMonitoringModeResponse, resultsSize) - offsetof(UA_SetMonitoringModeResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("signature") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_SignatureData, signature) - offsetof(UA_SignatureData, algorithm) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_SetMonitoringModeResponse, diagnosticInfosSize) - offsetof(UA_SetMonitoringModeResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* ObjectTypeAttributes */ -static UA_DataTypeMember ObjectTypeAttributes_members[6] = { +/* BrowseResultMask */ +#define BrowseResultMask_members NULL + +/* RequestHeader */ +static UA_DataTypeMember RequestHeader_members[7] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("AuthenticationToken") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_ObjectTypeAttributes, displayName) - offsetof(UA_ObjectTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("description") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_ObjectTypeAttributes, description) - offsetof(UA_ObjectTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ + UA_TYPENAME("Timestamp") /* .memberName */ + UA_TYPES_DATETIME, /* .memberTypeIndex */ + offsetof(UA_RequestHeader, timestamp) - offsetof(UA_RequestHeader, authenticationToken) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ + UA_TYPENAME("RequestHandle") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ObjectTypeAttributes, writeMask) - offsetof(UA_ObjectTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ + offsetof(UA_RequestHeader, requestHandle) - offsetof(UA_RequestHeader, timestamp) - sizeof(UA_DateTime), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userWriteMask") /* .memberName */ + UA_TYPENAME("ReturnDiagnostics") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ObjectTypeAttributes, userWriteMask) - offsetof(UA_ObjectTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_RequestHeader, returnDiagnostics) - offsetof(UA_RequestHeader, requestHandle) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("isAbstract") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_ObjectTypeAttributes, isAbstract) - offsetof(UA_ObjectTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("AuditEntryId") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_RequestHeader, auditEntryId) - offsetof(UA_RequestHeader, returnDiagnostics) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* DeadbandType */ -static UA_DataTypeMember DeadbandType_members[1] = { +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("TimeoutHint") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_RequestHeader, timeoutHint) - offsetof(UA_RequestHeader, auditEntryId) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* SecurityTokenRequestType */ -static UA_DataTypeMember SecurityTokenRequestType_members[1] = { +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("AdditionalHeader") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_RequestHeader, additionalHeader) - offsetof(UA_RequestHeader, timeoutHint) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* NodeAttributes */ -static UA_DataTypeMember NodeAttributes_members[5] = { +/* MonitoredItemModifyResult */ +static UA_DataTypeMember MonitoredItemModifyResult_members[4] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("StatusCode") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_NodeAttributes, displayName) - offsetof(UA_NodeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("description") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_NodeAttributes, description) - offsetof(UA_NodeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ + UA_TYPENAME("RevisedSamplingInterval") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemModifyResult, revisedSamplingInterval) - offsetof(UA_MonitoredItemModifyResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ + UA_TYPENAME("RevisedQueueSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_NodeAttributes, writeMask) - offsetof(UA_NodeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ + offsetof(UA_MonitoredItemModifyResult, revisedQueueSize) - offsetof(UA_MonitoredItemModifyResult, revisedSamplingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userWriteMask") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_NodeAttributes, userWriteMask) - offsetof(UA_NodeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("FilterResult") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemModifyResult, filterResult) - offsetof(UA_MonitoredItemModifyResult, revisedQueueSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* DataChangeTrigger */ -static UA_DataTypeMember DataChangeTrigger_members[1] = { +/* CloseSecureChannelRequest */ +static UA_DataTypeMember CloseSecureChannelRequest_members[1] = { { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* BuildInfo */ -static UA_DataTypeMember BuildInfo_members[6] = { +/* NotificationMessage */ +static UA_DataTypeMember NotificationMessage_members[3] = { { - UA_TYPENAME("productUri") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ + UA_TYPENAME("SequenceNumber") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("manufacturerName") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_BuildInfo, manufacturerName) - offsetof(UA_BuildInfo, productUri) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("productName") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_BuildInfo, productName) - offsetof(UA_BuildInfo, manufacturerName) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("softwareVersion") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_BuildInfo, softwareVersion) - offsetof(UA_BuildInfo, productName) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("buildNumber") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_BuildInfo, buildNumber) - offsetof(UA_BuildInfo, softwareVersion) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("buildDate") /* .memberName */ + UA_TYPENAME("PublishTime") /* .memberName */ UA_TYPES_DATETIME, /* .memberTypeIndex */ - offsetof(UA_BuildInfo, buildDate) - offsetof(UA_BuildInfo, buildNumber) - sizeof(UA_String), /* .padding */ + offsetof(UA_NotificationMessage, publishTime) - offsetof(UA_NotificationMessage, sequenceNumber) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* NodeClass */ -static UA_DataTypeMember NodeClass_members[1] = { +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("NotificationData") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_NotificationMessage, notificationDataSize) - offsetof(UA_NotificationMessage, publishTime) - sizeof(UA_DateTime), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* SubscriptionDiagnosticsDataType */ -static UA_DataTypeMember SubscriptionDiagnosticsDataType_members[31] = { +/* CreateSubscriptionResponse */ +static UA_DataTypeMember CreateSubscriptionResponse_members[5] = { { - UA_TYPENAME("sessionId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionId") /* .memberName */ + UA_TYPENAME("SubscriptionId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, subscriptionId) - offsetof(UA_SubscriptionDiagnosticsDataType, sessionId) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("priority") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, priority) - offsetof(UA_SubscriptionDiagnosticsDataType, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_CreateSubscriptionResponse, subscriptionId) - offsetof(UA_CreateSubscriptionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("publishingInterval") /* .memberName */ + UA_TYPENAME("RevisedPublishingInterval") /* .memberName */ UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, publishingInterval) - offsetof(UA_SubscriptionDiagnosticsDataType, priority) - sizeof(UA_Byte), /* .padding */ + offsetof(UA_CreateSubscriptionResponse, revisedPublishingInterval) - offsetof(UA_CreateSubscriptionResponse, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxKeepAliveCount") /* .memberName */ + UA_TYPENAME("RevisedLifetimeCount") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, maxKeepAliveCount) - offsetof(UA_SubscriptionDiagnosticsDataType, publishingInterval) - sizeof(UA_Double), /* .padding */ + offsetof(UA_CreateSubscriptionResponse, revisedLifetimeCount) - offsetof(UA_CreateSubscriptionResponse, revisedPublishingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxLifetimeCount") /* .memberName */ + UA_TYPENAME("RevisedMaxKeepAliveCount") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, maxLifetimeCount) - offsetof(UA_SubscriptionDiagnosticsDataType, maxKeepAliveCount) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_CreateSubscriptionResponse, revisedMaxKeepAliveCount) - offsetof(UA_CreateSubscriptionResponse, revisedLifetimeCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* MdnsDiscoveryConfiguration */ +static UA_DataTypeMember MdnsDiscoveryConfiguration_members[2] = { { - UA_TYPENAME("maxNotificationsPerPublish") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, maxNotificationsPerPublish) - offsetof(UA_SubscriptionDiagnosticsDataType, maxLifetimeCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("MdnsServerName") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("publishingEnabled") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, publishingEnabled) - offsetof(UA_SubscriptionDiagnosticsDataType, maxNotificationsPerPublish) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ServerCapabilities") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_MdnsDiscoveryConfiguration, serverCapabilitiesSize) - offsetof(UA_MdnsDiscoveryConfiguration, mdnsServerName) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* BrowseDirection */ +#define BrowseDirection_members NULL + +/* CallMethodRequest */ +static UA_DataTypeMember CallMethodRequest_members[3] = { { - UA_TYPENAME("modifyCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, modifyCount) - offsetof(UA_SubscriptionDiagnosticsDataType, publishingEnabled) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("ObjectId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("enableCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, enableCount) - offsetof(UA_SubscriptionDiagnosticsDataType, modifyCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("MethodId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_CallMethodRequest, methodId) - offsetof(UA_CallMethodRequest, objectId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("disableCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, disableCount) - offsetof(UA_SubscriptionDiagnosticsDataType, enableCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("InputArguments") /* .memberName */ + UA_TYPES_VARIANT, /* .memberTypeIndex */ + offsetof(UA_CallMethodRequest, inputArgumentsSize) - offsetof(UA_CallMethodRequest, methodId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* ReadResponse */ +static UA_DataTypeMember ReadResponse_members[3] = { { - UA_TYPENAME("republishRequestCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, republishRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, disableCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("republishMessageRequestCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, republishMessageRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, republishRequestCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_DATAVALUE, /* .memberTypeIndex */ + offsetof(UA_ReadResponse, resultsSize) - offsetof(UA_ReadResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("republishMessageCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, republishMessageCount) - offsetof(UA_SubscriptionDiagnosticsDataType, republishMessageRequestCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_ReadResponse, diagnosticInfosSize) - offsetof(UA_ReadResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* TimestampsToReturn */ +#define TimestampsToReturn_members NULL + +/* NodeClass */ +#define NodeClass_members NULL + +/* ObjectTypeAttributes */ +static UA_DataTypeMember ObjectTypeAttributes_members[6] = { { - UA_TYPENAME("transferRequestCount") /* .memberName */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, transferRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, republishMessageCount) - sizeof(UA_UInt32), /* .padding */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("transferredToAltClientCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, transferredToAltClientCount) - offsetof(UA_SubscriptionDiagnosticsDataType, transferRequestCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DisplayName") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_ObjectTypeAttributes, displayName) - offsetof(UA_ObjectTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("transferredToSameClientCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, transferredToSameClientCount) - offsetof(UA_SubscriptionDiagnosticsDataType, transferredToAltClientCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Description") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_ObjectTypeAttributes, description) - offsetof(UA_ObjectTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("publishRequestCount") /* .memberName */ + UA_TYPENAME("WriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, publishRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, transferredToSameClientCount) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_ObjectTypeAttributes, writeMask) - offsetof(UA_ObjectTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("dataChangeNotificationsCount") /* .memberName */ + UA_TYPENAME("UserWriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, dataChangeNotificationsCount) - offsetof(UA_SubscriptionDiagnosticsDataType, publishRequestCount) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_ObjectTypeAttributes, userWriteMask) - offsetof(UA_ObjectTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("eventNotificationsCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, eventNotificationsCount) - offsetof(UA_SubscriptionDiagnosticsDataType, dataChangeNotificationsCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("IsAbstract") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_ObjectTypeAttributes, isAbstract) - offsetof(UA_ObjectTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* SecurityTokenRequestType */ +#define SecurityTokenRequestType_members NULL + +/* CloseSessionResponse */ +static UA_DataTypeMember CloseSessionResponse_members[1] = { { - UA_TYPENAME("notificationsCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, notificationsCount) - offsetof(UA_SubscriptionDiagnosticsDataType, eventNotificationsCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* SetPublishingModeRequest */ +static UA_DataTypeMember SetPublishingModeRequest_members[3] = { { - UA_TYPENAME("latePublishRequestCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, latePublishRequestCount) - offsetof(UA_SubscriptionDiagnosticsDataType, notificationsCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("currentKeepAliveCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, currentKeepAliveCount) - offsetof(UA_SubscriptionDiagnosticsDataType, latePublishRequestCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("PublishingEnabled") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_SetPublishingModeRequest, publishingEnabled) - offsetof(UA_SetPublishingModeRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("currentLifetimeCount") /* .memberName */ + UA_TYPENAME("SubscriptionIds") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, currentLifetimeCount) - offsetof(UA_SubscriptionDiagnosticsDataType, currentKeepAliveCount) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_SetPublishingModeRequest, subscriptionIdsSize) - offsetof(UA_SetPublishingModeRequest, publishingEnabled) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* IssuedIdentityToken */ +static UA_DataTypeMember IssuedIdentityToken_members[3] = { { - UA_TYPENAME("unacknowledgedMessageCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, unacknowledgedMessageCount) - offsetof(UA_SubscriptionDiagnosticsDataType, currentLifetimeCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("PolicyId") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("discardedMessageCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, discardedMessageCount) - offsetof(UA_SubscriptionDiagnosticsDataType, unacknowledgedMessageCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("TokenData") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_IssuedIdentityToken, tokenData) - offsetof(UA_IssuedIdentityToken, policyId) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("monitoredItemCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, monitoredItemCount) - offsetof(UA_SubscriptionDiagnosticsDataType, discardedMessageCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("EncryptionAlgorithm") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_IssuedIdentityToken, encryptionAlgorithm) - offsetof(UA_IssuedIdentityToken, tokenData) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* ServerOnNetwork */ +static UA_DataTypeMember ServerOnNetwork_members[4] = { { - UA_TYPENAME("disabledMonitoredItemCount") /* .memberName */ + UA_TYPENAME("RecordId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, disabledMonitoredItemCount) - offsetof(UA_SubscriptionDiagnosticsDataType, monitoredItemCount) - sizeof(UA_UInt32), /* .padding */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("monitoringQueueOverflowCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, monitoringQueueOverflowCount) - offsetof(UA_SubscriptionDiagnosticsDataType, disabledMonitoredItemCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ServerName") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_ServerOnNetwork, serverName) - offsetof(UA_ServerOnNetwork, recordId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nextSequenceNumber") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, nextSequenceNumber) - offsetof(UA_SubscriptionDiagnosticsDataType, monitoringQueueOverflowCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DiscoveryUrl") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_ServerOnNetwork, discoveryUrl) - offsetof(UA_ServerOnNetwork, serverName) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("eventQueueOverFlowCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionDiagnosticsDataType, eventQueueOverFlowCount) - offsetof(UA_SubscriptionDiagnosticsDataType, nextSequenceNumber) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ServerCapabilities") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_ServerOnNetwork, serverCapabilitiesSize) - offsetof(UA_ServerOnNetwork, discoveryUrl) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* FilterOperand */ -#define FilterOperand_members NULL + true /* .isArray */ +},}; -/* MonitoredItemNotification */ -static UA_DataTypeMember MonitoredItemNotification_members[2] = { +/* DeleteMonitoredItemsResponse */ +static UA_DataTypeMember DeleteMonitoredItemsResponse_members[3] = { { - UA_TYPENAME("clientHandle") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("value") /* .memberName */ - UA_TYPES_DATAVALUE, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemNotification, value) - offsetof(UA_MonitoredItemNotification, clientHandle) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_DeleteMonitoredItemsResponse, resultsSize) - offsetof(UA_DeleteMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +}, +{ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_DeleteMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_DeleteMonitoredItemsResponse, results) - sizeof(void*), /* .padding */ + true, /* .namespaceZero */ + true /* .isArray */ +},}; -/* DeleteNodesItem */ -static UA_DataTypeMember DeleteNodesItem_members[2] = { +/* ApplicationType */ +#define ApplicationType_members NULL + +/* DiscoveryConfiguration */ +#define DiscoveryConfiguration_members NULL + +/* BrowseNextRequest */ +static UA_DataTypeMember BrowseNextRequest_members[3] = { { - UA_TYPENAME("nodeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("deleteTargetReferences") /* .memberName */ + UA_TYPENAME("ReleaseContinuationPoints") /* .memberName */ UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_DeleteNodesItem, deleteTargetReferences) - offsetof(UA_DeleteNodesItem, nodeId) - sizeof(UA_NodeId), /* .padding */ + offsetof(UA_BrowseNextRequest, releaseContinuationPoints) - offsetof(UA_BrowseNextRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +}, +{ + UA_TYPENAME("ContinuationPoints") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_BrowseNextRequest, continuationPointsSize) - offsetof(UA_BrowseNextRequest, releaseContinuationPoints) - sizeof(UA_Boolean), /* .padding */ + true, /* .namespaceZero */ + true /* .isArray */ +},}; -/* DeleteSubscriptionsRequest */ -static UA_DataTypeMember DeleteSubscriptionsRequest_members[2] = { +/* ModifySubscriptionRequest */ +static UA_DataTypeMember ModifySubscriptionRequest_members[7] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionIds") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_DeleteSubscriptionsRequest, subscriptionIdsSize) - offsetof(UA_DeleteSubscriptionsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* SubscriptionAcknowledgement */ -static UA_DataTypeMember SubscriptionAcknowledgement_members[2] = { -{ - UA_TYPENAME("subscriptionId") /* .memberName */ + UA_TYPENAME("SubscriptionId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - 0, /* .padding */ + offsetof(UA_ModifySubscriptionRequest, subscriptionId) - offsetof(UA_ModifySubscriptionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("sequenceNumber") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SubscriptionAcknowledgement, sequenceNumber) - offsetof(UA_SubscriptionAcknowledgement, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("RequestedPublishingInterval") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + offsetof(UA_ModifySubscriptionRequest, requestedPublishingInterval) - offsetof(UA_ModifySubscriptionRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* ReadValueId */ -static UA_DataTypeMember ReadValueId_members[4] = { +}, { - UA_TYPENAME("nodeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("RequestedLifetimeCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ModifySubscriptionRequest, requestedLifetimeCount) - offsetof(UA_ModifySubscriptionRequest, requestedPublishingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("attributeId") /* .memberName */ + UA_TYPENAME("RequestedMaxKeepAliveCount") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ReadValueId, attributeId) - offsetof(UA_ReadValueId, nodeId) - sizeof(UA_NodeId), /* .padding */ + offsetof(UA_ModifySubscriptionRequest, requestedMaxKeepAliveCount) - offsetof(UA_ModifySubscriptionRequest, requestedLifetimeCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("indexRange") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_ReadValueId, indexRange) - offsetof(UA_ReadValueId, attributeId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("MaxNotificationsPerPublish") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ModifySubscriptionRequest, maxNotificationsPerPublish) - offsetof(UA_ModifySubscriptionRequest, requestedMaxKeepAliveCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("dataEncoding") /* .memberName */ - UA_TYPES_QUALIFIEDNAME, /* .memberTypeIndex */ - offsetof(UA_ReadValueId, dataEncoding) - offsetof(UA_ReadValueId, indexRange) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("Priority") /* .memberName */ + UA_TYPES_BYTE, /* .memberTypeIndex */ + offsetof(UA_ModifySubscriptionRequest, priority) - offsetof(UA_ModifySubscriptionRequest, maxNotificationsPerPublish) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* DataTypeAttributes */ -static UA_DataTypeMember DataTypeAttributes_members[6] = { +/* BrowseDescription */ +static UA_DataTypeMember BrowseDescription_members[6] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("NodeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_DataTypeAttributes, displayName) - offsetof(UA_DataTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("BrowseDirection") /* .memberName */ + UA_TYPES_BROWSEDIRECTION, /* .memberTypeIndex */ + offsetof(UA_BrowseDescription, browseDirection) - offsetof(UA_BrowseDescription, nodeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("description") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_DataTypeAttributes, description) - offsetof(UA_DataTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ + UA_TYPENAME("ReferenceTypeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_BrowseDescription, referenceTypeId) - offsetof(UA_BrowseDescription, browseDirection) - sizeof(UA_BrowseDirection), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_DataTypeAttributes, writeMask) - offsetof(UA_DataTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ + UA_TYPENAME("IncludeSubtypes") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_BrowseDescription, includeSubtypes) - offsetof(UA_BrowseDescription, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userWriteMask") /* .memberName */ + UA_TYPENAME("NodeClassMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_DataTypeAttributes, userWriteMask) - offsetof(UA_DataTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_BrowseDescription, nodeClassMask) - offsetof(UA_BrowseDescription, includeSubtypes) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("isAbstract") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_DataTypeAttributes, isAbstract) - offsetof(UA_DataTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ResultMask") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_BrowseDescription, resultMask) - offsetof(UA_BrowseDescription, nodeClassMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* ResponseHeader */ -static UA_DataTypeMember ResponseHeader_members[6] = { +/* SignedSoftwareCertificate */ +static UA_DataTypeMember SignedSoftwareCertificate_members[2] = { { - UA_TYPENAME("timestamp") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ + UA_TYPENAME("CertificateData") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestHandle") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ResponseHeader, requestHandle) - offsetof(UA_ResponseHeader, timestamp) - sizeof(UA_DateTime), /* .padding */ + UA_TYPENAME("Signature") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_SignedSoftwareCertificate, signature) - offsetof(UA_SignedSoftwareCertificate, certificateData) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* BrowsePathTarget */ +static UA_DataTypeMember BrowsePathTarget_members[2] = { { - UA_TYPENAME("serviceResult") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_ResponseHeader, serviceResult) - offsetof(UA_ResponseHeader, requestHandle) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("TargetId") /* .memberName */ + UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serviceDiagnostics") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_ResponseHeader, serviceDiagnostics) - offsetof(UA_ResponseHeader, serviceResult) - sizeof(UA_StatusCode), /* .padding */ + UA_TYPENAME("RemainingPathIndex") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_BrowsePathTarget, remainingPathIndex) - offsetof(UA_BrowsePathTarget, targetId) - sizeof(UA_ExpandedNodeId), /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +},}; + +/* WriteResponse */ +static UA_DataTypeMember WriteResponse_members[3] = { +{ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("stringTable") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_ResponseHeader, stringTableSize) - offsetof(UA_ResponseHeader, serviceDiagnostics) - sizeof(UA_DiagnosticInfo), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_WriteResponse, resultsSize) - offsetof(UA_WriteResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("additionalHeader") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_ResponseHeader, additionalHeader) - offsetof(UA_ResponseHeader, stringTable) - sizeof(void*), /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_WriteResponse, diagnosticInfosSize) - offsetof(UA_WriteResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* DeleteMonitoredItemsRequest */ -static UA_DataTypeMember DeleteMonitoredItemsRequest_members[3] = { +/* AddNodesResult */ +static UA_DataTypeMember AddNodesResult_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("StatusCode") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_DeleteMonitoredItemsRequest, subscriptionId) - offsetof(UA_DeleteMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("AddedNodeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_AddNodesResult, addedNodeId) - offsetof(UA_AddNodesResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* RegisterServerResponse */ +static UA_DataTypeMember RegisterServerResponse_members[1] = { { - UA_TYPENAME("monitoredItemIds") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_DeleteMonitoredItemsRequest, monitoredItemIdsSize) - offsetof(UA_DeleteMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* ViewDescription */ -static UA_DataTypeMember ViewDescription_members[3] = { +/* AddReferencesItem */ +static UA_DataTypeMember AddReferencesItem_members[6] = { { - UA_TYPENAME("viewId") /* .memberName */ + UA_TYPENAME("SourceNodeId") /* .memberName */ UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("timestamp") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ - offsetof(UA_ViewDescription, timestamp) - offsetof(UA_ViewDescription, viewId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("ReferenceTypeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_AddReferencesItem, referenceTypeId) - offsetof(UA_AddReferencesItem, sourceNodeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("viewVersion") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ViewDescription, viewVersion) - offsetof(UA_ViewDescription, timestamp) - sizeof(UA_DateTime), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* ServerOnNetwork */ -static UA_DataTypeMember ServerOnNetwork_members[4] = { -{ - UA_TYPENAME("recordId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("IsForward") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_AddReferencesItem, isForward) - offsetof(UA_AddReferencesItem, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverName") /* .memberName */ + UA_TYPENAME("TargetServerUri") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_ServerOnNetwork, serverName) - offsetof(UA_ServerOnNetwork, recordId) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_AddReferencesItem, targetServerUri) - offsetof(UA_AddReferencesItem, isForward) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("discoveryUrl") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_ServerOnNetwork, discoveryUrl) - offsetof(UA_ServerOnNetwork, serverName) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("TargetNodeId") /* .memberName */ + UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ + offsetof(UA_AddReferencesItem, targetNodeId) - offsetof(UA_AddReferencesItem, targetServerUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverCapabilities") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_ServerOnNetwork, serverCapabilitiesSize) - offsetof(UA_ServerOnNetwork, discoveryUrl) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("TargetNodeClass") /* .memberName */ + UA_TYPES_NODECLASS, /* .memberTypeIndex */ + offsetof(UA_AddReferencesItem, targetNodeClass) - offsetof(UA_AddReferencesItem, targetNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* DeleteMonitoredItemsResponse */ -static UA_DataTypeMember DeleteMonitoredItemsResponse_members[3] = { +/* RegisterServer2Response */ +static UA_DataTypeMember RegisterServer2Response_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ + UA_TYPENAME("ConfigurationResults") /* .memberName */ UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_DeleteMonitoredItemsResponse, resultsSize) - offsetof(UA_DeleteMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + offsetof(UA_RegisterServer2Response, configurationResultsSize) - offsetof(UA_RegisterServer2Response, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_DeleteMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_DeleteMonitoredItemsResponse, results) - sizeof(void*), /* .padding */ + offsetof(UA_RegisterServer2Response, diagnosticInfosSize) - offsetof(UA_RegisterServer2Response, configurationResults) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* FindServersOnNetworkResponse */ -static UA_DataTypeMember FindServersOnNetworkResponse_members[3] = { +/* DeleteReferencesResponse */ +static UA_DataTypeMember DeleteReferencesResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("lastCounterResetTime") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ - offsetof(UA_FindServersOnNetworkResponse, lastCounterResetTime) - offsetof(UA_FindServersOnNetworkResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("servers") /* .memberName */ - UA_TYPES_SERVERONNETWORK, /* .memberTypeIndex */ - offsetof(UA_FindServersOnNetworkResponse, serversSize) - offsetof(UA_FindServersOnNetworkResponse, lastCounterResetTime) - sizeof(UA_DateTime), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* RelativePath */ -static UA_DataTypeMember RelativePath_members[1] = { -{ - UA_TYPENAME("elements") /* .memberName */ - UA_TYPES_RELATIVEPATHELEMENT, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_DeleteReferencesResponse, resultsSize) - offsetof(UA_DeleteReferencesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; - -/* RegisterNodesRequest */ -static UA_DataTypeMember RegisterNodesRequest_members[2] = { -{ - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ }, { - UA_TYPENAME("nodesToRegister") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_RegisterNodesRequest, nodesToRegisterSize) - offsetof(UA_RegisterNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_DeleteReferencesResponse, diagnosticInfosSize) - offsetof(UA_DeleteReferencesResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* AggregateConfiguration */ -static UA_DataTypeMember AggregateConfiguration_members[5] = { +/* RelativePathElement */ +static UA_DataTypeMember RelativePathElement_members[4] = { { - UA_TYPENAME("useServerCapabilitiesDefaults") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + UA_TYPENAME("ReferenceTypeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("treatUncertainAsBad") /* .memberName */ + UA_TYPENAME("IsInverse") /* .memberName */ UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_AggregateConfiguration, treatUncertainAsBad) - offsetof(UA_AggregateConfiguration, useServerCapabilitiesDefaults) - sizeof(UA_Boolean), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("percentDataBad") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - offsetof(UA_AggregateConfiguration, percentDataBad) - offsetof(UA_AggregateConfiguration, treatUncertainAsBad) - sizeof(UA_Boolean), /* .padding */ + offsetof(UA_RelativePathElement, isInverse) - offsetof(UA_RelativePathElement, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("percentDataGood") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - offsetof(UA_AggregateConfiguration, percentDataGood) - offsetof(UA_AggregateConfiguration, percentDataBad) - sizeof(UA_Byte), /* .padding */ + UA_TYPENAME("IncludeSubtypes") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_RelativePathElement, includeSubtypes) - offsetof(UA_RelativePathElement, isInverse) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("useSlopedExtrapolation") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_AggregateConfiguration, useSlopedExtrapolation) - offsetof(UA_AggregateConfiguration, percentDataGood) - sizeof(UA_Byte), /* .padding */ + UA_TYPENAME("TargetName") /* .memberName */ + UA_TYPES_QUALIFIEDNAME, /* .memberTypeIndex */ + offsetof(UA_RelativePathElement, targetName) - offsetof(UA_RelativePathElement, includeSubtypes) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* DeleteNodesRequest */ -static UA_DataTypeMember DeleteNodesRequest_members[2] = { +/* SubscriptionAcknowledgement */ +static UA_DataTypeMember SubscriptionAcknowledgement_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("SubscriptionId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodesToDelete") /* .memberName */ - UA_TYPES_DELETENODESITEM, /* .memberTypeIndex */ - offsetof(UA_DeleteNodesRequest, nodesToDeleteSize) - offsetof(UA_DeleteNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("SequenceNumber") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_SubscriptionAcknowledgement, sequenceNumber) - offsetof(UA_SubscriptionAcknowledgement, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* PublishResponse */ -static UA_DataTypeMember PublishResponse_members[7] = { +/* CreateMonitoredItemsResponse */ +static UA_DataTypeMember CreateMonitoredItemsResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_PublishResponse, subscriptionId) - offsetof(UA_PublishResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_MONITOREDITEMCREATERESULT, /* .memberTypeIndex */ + offsetof(UA_CreateMonitoredItemsResponse, resultsSize) - offsetof(UA_CreateMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("availableSequenceNumbers") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_PublishResponse, availableSequenceNumbersSize) - offsetof(UA_PublishResponse, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_CreateMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_CreateMonitoredItemsResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}, +},}; + +/* DeleteReferencesItem */ +static UA_DataTypeMember DeleteReferencesItem_members[5] = { { - UA_TYPENAME("moreNotifications") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_PublishResponse, moreNotifications) - offsetof(UA_PublishResponse, availableSequenceNumbers) - sizeof(void*), /* .padding */ + UA_TYPENAME("SourceNodeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("notificationMessage") /* .memberName */ - UA_TYPES_NOTIFICATIONMESSAGE, /* .memberTypeIndex */ - offsetof(UA_PublishResponse, notificationMessage) - offsetof(UA_PublishResponse, moreNotifications) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("ReferenceTypeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_DeleteReferencesItem, referenceTypeId) - offsetof(UA_DeleteReferencesItem, sourceNodeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_PublishResponse, resultsSize) - offsetof(UA_PublishResponse, notificationMessage) - sizeof(UA_NotificationMessage), /* .padding */ + UA_TYPENAME("IsForward") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_DeleteReferencesItem, isForward) - offsetof(UA_DeleteReferencesItem, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_PublishResponse, diagnosticInfosSize) - offsetof(UA_PublishResponse, results) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* MonitoredItemModifyRequest */ -static UA_DataTypeMember MonitoredItemModifyRequest_members[2] = { -{ - UA_TYPENAME("monitoredItemId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("TargetNodeId") /* .memberName */ + UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ + offsetof(UA_DeleteReferencesItem, targetNodeId) - offsetof(UA_DeleteReferencesItem, isForward) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedParameters") /* .memberName */ - UA_TYPES_MONITORINGPARAMETERS, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemModifyRequest, requestedParameters) - offsetof(UA_MonitoredItemModifyRequest, monitoredItemId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DeleteBidirectional") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_DeleteReferencesItem, deleteBidirectional) - offsetof(UA_DeleteReferencesItem, targetNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* ServiceCounterDataType */ -static UA_DataTypeMember ServiceCounterDataType_members[2] = { +/* WriteValue */ +static UA_DataTypeMember WriteValue_members[4] = { { - UA_TYPENAME("totalCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("NodeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("errorCount") /* .memberName */ + UA_TYPENAME("AttributeId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServiceCounterDataType, errorCount) - offsetof(UA_ServiceCounterDataType, totalCount) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* ModelChangeStructureDataType */ -static UA_DataTypeMember ModelChangeStructureDataType_members[3] = { -{ - UA_TYPENAME("affected") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ + offsetof(UA_WriteValue, attributeId) - offsetof(UA_WriteValue, nodeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("affectedType") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_ModelChangeStructureDataType, affectedType) - offsetof(UA_ModelChangeStructureDataType, affected) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("IndexRange") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_WriteValue, indexRange) - offsetof(UA_WriteValue, attributeId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("verb") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - offsetof(UA_ModelChangeStructureDataType, verb) - offsetof(UA_ModelChangeStructureDataType, affectedType) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("Value") /* .memberName */ + UA_TYPES_DATAVALUE, /* .memberTypeIndex */ + offsetof(UA_WriteValue, value) - offsetof(UA_WriteValue, indexRange) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* UserNameIdentityToken */ -static UA_DataTypeMember UserNameIdentityToken_members[4] = { +/* DataTypeAttributes */ +static UA_DataTypeMember DataTypeAttributes_members[6] = { { - UA_TYPENAME("policyId") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userName") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_UserNameIdentityToken, userName) - offsetof(UA_UserNameIdentityToken, policyId) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("DisplayName") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_DataTypeAttributes, displayName) - offsetof(UA_DataTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("password") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_UserNameIdentityToken, password) - offsetof(UA_UserNameIdentityToken, userName) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("Description") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_DataTypeAttributes, description) - offsetof(UA_DataTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("encryptionAlgorithm") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_UserNameIdentityToken, encryptionAlgorithm) - offsetof(UA_UserNameIdentityToken, password) - sizeof(UA_ByteString), /* .padding */ + UA_TYPENAME("WriteMask") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_DataTypeAttributes, writeMask) - offsetof(UA_DataTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* IdType */ -static UA_DataTypeMember IdType_members[1] = { +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("UserWriteMask") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_DataTypeAttributes, userWriteMask) - offsetof(UA_DataTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* UserTokenType */ -static UA_DataTypeMember UserTokenType_members[1] = { +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("IsAbstract") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_DataTypeAttributes, isAbstract) - offsetof(UA_DataTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* SetTriggeringResponse */ -static UA_DataTypeMember SetTriggeringResponse_members[5] = { +/* AddReferencesResponse */ +static UA_DataTypeMember AddReferencesResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("addResults") /* .memberName */ + UA_TYPENAME("Results") /* .memberName */ UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_SetTriggeringResponse, addResultsSize) - offsetof(UA_SetTriggeringResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("addDiagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_SetTriggeringResponse, addDiagnosticInfosSize) - offsetof(UA_SetTriggeringResponse, addResults) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("removeResults") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_SetTriggeringResponse, removeResultsSize) - offsetof(UA_SetTriggeringResponse, addDiagnosticInfos) - sizeof(void*), /* .padding */ + offsetof(UA_AddReferencesResponse, resultsSize) - offsetof(UA_AddReferencesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("removeDiagnosticInfos") /* .memberName */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_SetTriggeringResponse, removeDiagnosticInfosSize) - offsetof(UA_SetTriggeringResponse, removeResults) - sizeof(void*), /* .padding */ + offsetof(UA_AddReferencesResponse, diagnosticInfosSize) - offsetof(UA_AddReferencesResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* TimeZoneDataType */ -static UA_DataTypeMember TimeZoneDataType_members[2] = { -{ - UA_TYPENAME("offset") /* .memberName */ - UA_TYPES_INT16, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("daylightSavingInOffset") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_TimeZoneDataType, daylightSavingInOffset) - offsetof(UA_TimeZoneDataType, offset) - sizeof(UA_Int16), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +/* DeadbandType */ +#define DeadbandType_members NULL -/* ActivateSessionRequest */ -static UA_DataTypeMember ActivateSessionRequest_members[6] = { +/* DataChangeTrigger */ +#define DataChangeTrigger_members NULL + +/* BuildInfo */ +static UA_DataTypeMember BuildInfo_members[6] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ProductUri") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientSignature") /* .memberName */ - UA_TYPES_SIGNATUREDATA, /* .memberTypeIndex */ - offsetof(UA_ActivateSessionRequest, clientSignature) - offsetof(UA_ActivateSessionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("ManufacturerName") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_BuildInfo, manufacturerName) - offsetof(UA_BuildInfo, productUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientSoftwareCertificates") /* .memberName */ - UA_TYPES_SIGNEDSOFTWARECERTIFICATE, /* .memberTypeIndex */ - offsetof(UA_ActivateSessionRequest, clientSoftwareCertificatesSize) - offsetof(UA_ActivateSessionRequest, clientSignature) - sizeof(UA_SignatureData), /* .padding */ + UA_TYPENAME("ProductName") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_BuildInfo, productName) - offsetof(UA_BuildInfo, manufacturerName) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("localeIds") /* .memberName */ + UA_TYPENAME("SoftwareVersion") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_ActivateSessionRequest, localeIdsSize) - offsetof(UA_ActivateSessionRequest, clientSoftwareCertificates) - sizeof(void*), /* .padding */ + offsetof(UA_BuildInfo, softwareVersion) - offsetof(UA_BuildInfo, productName) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("userIdentityToken") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_ActivateSessionRequest, userIdentityToken) - offsetof(UA_ActivateSessionRequest, localeIds) - sizeof(void*), /* .padding */ + UA_TYPENAME("BuildNumber") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_BuildInfo, buildNumber) - offsetof(UA_BuildInfo, softwareVersion) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userTokenSignature") /* .memberName */ - UA_TYPES_SIGNATUREDATA, /* .memberTypeIndex */ - offsetof(UA_ActivateSessionRequest, userTokenSignature) - offsetof(UA_ActivateSessionRequest, userIdentityToken) - sizeof(UA_ExtensionObject), /* .padding */ + UA_TYPENAME("BuildDate") /* .memberName */ + UA_TYPES_DATETIME, /* .memberTypeIndex */ + offsetof(UA_BuildInfo, buildDate) - offsetof(UA_BuildInfo, buildNumber) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* OpenSecureChannelResponse */ -static UA_DataTypeMember OpenSecureChannelResponse_members[4] = { +/* FilterOperand */ +#define FilterOperand_members NULL + +/* MonitoringParameters */ +static UA_DataTypeMember MonitoringParameters_members[5] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ClientHandle") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverProtocolVersion") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_OpenSecureChannelResponse, serverProtocolVersion) - offsetof(UA_OpenSecureChannelResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("SamplingInterval") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + offsetof(UA_MonitoringParameters, samplingInterval) - offsetof(UA_MonitoringParameters, clientHandle) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("securityToken") /* .memberName */ - UA_TYPES_CHANNELSECURITYTOKEN, /* .memberTypeIndex */ - offsetof(UA_OpenSecureChannelResponse, securityToken) - offsetof(UA_OpenSecureChannelResponse, serverProtocolVersion) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Filter") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_MonitoringParameters, filter) - offsetof(UA_MonitoringParameters, samplingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverNonce") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_OpenSecureChannelResponse, serverNonce) - offsetof(UA_OpenSecureChannelResponse, securityToken) - sizeof(UA_ChannelSecurityToken), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* ApplicationType */ -static UA_DataTypeMember ApplicationType_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("QueueSize") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_MonitoringParameters, queueSize) - offsetof(UA_MonitoringParameters, filter) - sizeof(UA_ExtensionObject), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* ServerState */ -static UA_DataTypeMember ServerState_members[1] = { +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("DiscardOldest") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_MonitoringParameters, discardOldest) - offsetof(UA_MonitoringParameters, queueSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* QueryNextResponse */ -static UA_DataTypeMember QueryNextResponse_members[3] = { +/* DeleteNodesItem */ +static UA_DataTypeMember DeleteNodesItem_members[2] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("NodeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("queryDataSets") /* .memberName */ - UA_TYPES_QUERYDATASET, /* .memberTypeIndex */ - offsetof(UA_QueryNextResponse, queryDataSetsSize) - offsetof(UA_QueryNextResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("revisedContinuationPoint") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_QueryNextResponse, revisedContinuationPoint) - offsetof(UA_QueryNextResponse, queryDataSets) - sizeof(void*), /* .padding */ + UA_TYPENAME("DeleteTargetReferences") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_DeleteNodesItem, deleteTargetReferences) - offsetof(UA_DeleteNodesItem, nodeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* DiscoveryConfiguration */ -#define DiscoveryConfiguration_members NULL - -/* ActivateSessionResponse */ -static UA_DataTypeMember ActivateSessionResponse_members[4] = { +/* ReadValueId */ +static UA_DataTypeMember ReadValueId_members[4] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("NodeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverNonce") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_ActivateSessionResponse, serverNonce) - offsetof(UA_ActivateSessionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("AttributeId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ReadValueId, attributeId) - offsetof(UA_ReadValueId, nodeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_ActivateSessionResponse, resultsSize) - offsetof(UA_ActivateSessionResponse, serverNonce) - sizeof(UA_ByteString), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_ActivateSessionResponse, diagnosticInfosSize) - offsetof(UA_ActivateSessionResponse, results) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* EndpointUrlListDataType */ -static UA_DataTypeMember EndpointUrlListDataType_members[1] = { -{ - UA_TYPENAME("endpointUrlList") /* .memberName */ + UA_TYPENAME("IndexRange") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ - 0, /* .padding */ + offsetof(UA_ReadValueId, indexRange) - offsetof(UA_ReadValueId, attributeId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* FilterOperator */ -static UA_DataTypeMember FilterOperator_members[1] = { + false /* .isArray */ +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("DataEncoding") /* .memberName */ + UA_TYPES_QUALIFIEDNAME, /* .memberTypeIndex */ + offsetof(UA_ReadValueId, dataEncoding) - offsetof(UA_ReadValueId, indexRange) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* QueryNextRequest */ -static UA_DataTypeMember QueryNextRequest_members[3] = { +/* CallRequest */ +static UA_DataTypeMember CallRequest_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("releaseContinuationPoint") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_QueryNextRequest, releaseContinuationPoint) - offsetof(UA_QueryNextRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("MethodsToCall") /* .memberName */ + UA_TYPES_CALLMETHODREQUEST, /* .memberTypeIndex */ + offsetof(UA_CallRequest, methodsToCallSize) - offsetof(UA_CallRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* RelativePath */ +static UA_DataTypeMember RelativePath_members[1] = { { - UA_TYPENAME("continuationPoint") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_QueryNextRequest, continuationPoint) - offsetof(UA_QueryNextRequest, releaseContinuationPoint) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("Elements") /* .memberName */ + UA_TYPES_RELATIVEPATHELEMENT, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* WriteResponse */ -static UA_DataTypeMember WriteResponse_members[3] = { +/* DeleteNodesRequest */ +static UA_DataTypeMember DeleteNodesRequest_members[2] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_WriteResponse, resultsSize) - offsetof(UA_WriteResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_WriteResponse, diagnosticInfosSize) - offsetof(UA_WriteResponse, results) - sizeof(void*), /* .padding */ + UA_TYPENAME("NodesToDelete") /* .memberName */ + UA_TYPES_DELETENODESITEM, /* .memberTypeIndex */ + offsetof(UA_DeleteNodesRequest, nodesToDeleteSize) - offsetof(UA_DeleteNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* BrowseNextRequest */ -static UA_DataTypeMember BrowseNextRequest_members[3] = { +/* MonitoredItemModifyRequest */ +static UA_DataTypeMember MonitoredItemModifyRequest_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("MonitoredItemId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("releaseContinuationPoints") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_BrowseNextRequest, releaseContinuationPoints) - offsetof(UA_BrowseNextRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("RequestedParameters") /* .memberName */ + UA_TYPES_MONITORINGPARAMETERS, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemModifyRequest, requestedParameters) - offsetof(UA_MonitoredItemModifyRequest, monitoredItemId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, -{ - UA_TYPENAME("continuationPoints") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_BrowseNextRequest, continuationPointsSize) - offsetof(UA_BrowseNextRequest, releaseContinuationPoints) - sizeof(UA_Boolean), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +},}; -/* CreateSubscriptionRequest */ -static UA_DataTypeMember CreateSubscriptionRequest_members[7] = { +/* UserTokenType */ +#define UserTokenType_members NULL + +/* AggregateConfiguration */ +static UA_DataTypeMember AggregateConfiguration_members[5] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("UseServerCapabilitiesDefaults") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedPublishingInterval") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionRequest, requestedPublishingInterval) - offsetof(UA_CreateSubscriptionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("requestedLifetimeCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionRequest, requestedLifetimeCount) - offsetof(UA_CreateSubscriptionRequest, requestedPublishingInterval) - sizeof(UA_Double), /* .padding */ + UA_TYPENAME("TreatUncertainAsBad") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_AggregateConfiguration, treatUncertainAsBad) - offsetof(UA_AggregateConfiguration, useServerCapabilitiesDefaults) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedMaxKeepAliveCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionRequest, requestedMaxKeepAliveCount) - offsetof(UA_CreateSubscriptionRequest, requestedLifetimeCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("PercentDataBad") /* .memberName */ + UA_TYPES_BYTE, /* .memberTypeIndex */ + offsetof(UA_AggregateConfiguration, percentDataBad) - offsetof(UA_AggregateConfiguration, treatUncertainAsBad) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxNotificationsPerPublish") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionRequest, maxNotificationsPerPublish) - offsetof(UA_CreateSubscriptionRequest, requestedMaxKeepAliveCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("PercentDataGood") /* .memberName */ + UA_TYPES_BYTE, /* .memberTypeIndex */ + offsetof(UA_AggregateConfiguration, percentDataGood) - offsetof(UA_AggregateConfiguration, percentDataBad) - sizeof(UA_Byte), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("publishingEnabled") /* .memberName */ + UA_TYPENAME("UseSlopedExtrapolation") /* .memberName */ UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionRequest, publishingEnabled) - offsetof(UA_CreateSubscriptionRequest, maxNotificationsPerPublish) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_AggregateConfiguration, useSlopedExtrapolation) - offsetof(UA_AggregateConfiguration, percentDataGood) - sizeof(UA_Byte), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* LocaleId */ +#define LocaleId_members NULL + +/* UnregisterNodesResponse */ +static UA_DataTypeMember UnregisterNodesResponse_members[1] = { { - UA_TYPENAME("priority") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionRequest, priority) - offsetof(UA_CreateSubscriptionRequest, publishingEnabled) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* VariableTypeAttributes */ -static UA_DataTypeMember VariableTypeAttributes_members[10] = { +/* ContentFilterResult */ +static UA_DataTypeMember ContentFilterResult_members[2] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("ElementResults") /* .memberName */ + UA_TYPES_CONTENTFILTERELEMENTRESULT, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, displayName) - offsetof(UA_VariableTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ElementDiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_ContentFilterResult, elementDiagnosticInfosSize) - offsetof(UA_ContentFilterResult, elementResults) - sizeof(void*), /* .padding */ + true, /* .namespaceZero */ + true /* .isArray */ +},}; + +/* UserTokenPolicy */ +static UA_DataTypeMember UserTokenPolicy_members[5] = { +{ + UA_TYPENAME("PolicyId") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("description") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, description) - offsetof(UA_VariableTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ + UA_TYPENAME("TokenType") /* .memberName */ + UA_TYPES_USERTOKENTYPE, /* .memberTypeIndex */ + offsetof(UA_UserTokenPolicy, tokenType) - offsetof(UA_UserTokenPolicy, policyId) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, writeMask) - offsetof(UA_VariableTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ + UA_TYPENAME("IssuedTokenType") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_UserTokenPolicy, issuedTokenType) - offsetof(UA_UserTokenPolicy, tokenType) - sizeof(UA_UserTokenType), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userWriteMask") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, userWriteMask) - offsetof(UA_VariableTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("IssuerEndpointUrl") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_UserTokenPolicy, issuerEndpointUrl) - offsetof(UA_UserTokenPolicy, issuedTokenType) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("value") /* .memberName */ - UA_TYPES_VARIANT, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, value) - offsetof(UA_VariableTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("SecurityPolicyUri") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_UserTokenPolicy, securityPolicyUri) - offsetof(UA_UserTokenPolicy, issuerEndpointUrl) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* DeleteMonitoredItemsRequest */ +static UA_DataTypeMember DeleteMonitoredItemsRequest_members[3] = { { - UA_TYPENAME("dataType") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, dataType) - offsetof(UA_VariableTypeAttributes, value) - sizeof(UA_Variant), /* .padding */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("valueRank") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, valueRank) - offsetof(UA_VariableTypeAttributes, dataType) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("SubscriptionId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_DeleteMonitoredItemsRequest, subscriptionId) - offsetof(UA_DeleteMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("arrayDimensions") /* .memberName */ + UA_TYPENAME("MonitoredItemIds") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, arrayDimensionsSize) - offsetof(UA_VariableTypeAttributes, valueRank) - sizeof(UA_Int32), /* .padding */ + offsetof(UA_DeleteMonitoredItemsRequest, monitoredItemIdsSize) - offsetof(UA_DeleteMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ +},}; + +/* SetMonitoringModeRequest */ +static UA_DataTypeMember SetMonitoringModeRequest_members[4] = { +{ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ }, { - UA_TYPENAME("isAbstract") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_VariableTypeAttributes, isAbstract) - offsetof(UA_VariableTypeAttributes, arrayDimensions) - sizeof(void*), /* .padding */ + UA_TYPENAME("SubscriptionId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_SetMonitoringModeRequest, subscriptionId) - offsetof(UA_SetMonitoringModeRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* BrowsePathResult */ -static UA_DataTypeMember BrowsePathResult_members[2] = { +}, { - UA_TYPENAME("statusCode") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("MonitoringMode") /* .memberName */ + UA_TYPES_MONITORINGMODE, /* .memberTypeIndex */ + offsetof(UA_SetMonitoringModeRequest, monitoringMode) - offsetof(UA_SetMonitoringModeRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("targets") /* .memberName */ - UA_TYPES_BROWSEPATHTARGET, /* .memberTypeIndex */ - offsetof(UA_BrowsePathResult, targetsSize) - offsetof(UA_BrowsePathResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ + UA_TYPENAME("MonitoredItemIds") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_SetMonitoringModeRequest, monitoredItemIdsSize) - offsetof(UA_SetMonitoringModeRequest, monitoringMode) - sizeof(UA_MonitoringMode), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* ModifySubscriptionResponse */ -static UA_DataTypeMember ModifySubscriptionResponse_members[4] = { +/* Duration */ +#define Duration_members NULL + +/* ReferenceTypeAttributes */ +static UA_DataTypeMember ReferenceTypeAttributes_members[8] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("revisedPublishingInterval") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionResponse, revisedPublishingInterval) - offsetof(UA_ModifySubscriptionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("DisplayName") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_ReferenceTypeAttributes, displayName) - offsetof(UA_ReferenceTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("revisedLifetimeCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionResponse, revisedLifetimeCount) - offsetof(UA_ModifySubscriptionResponse, revisedPublishingInterval) - sizeof(UA_Double), /* .padding */ + UA_TYPENAME("Description") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_ReferenceTypeAttributes, description) - offsetof(UA_ReferenceTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("revisedMaxKeepAliveCount") /* .memberName */ + UA_TYPENAME("WriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionResponse, revisedMaxKeepAliveCount) - offsetof(UA_ModifySubscriptionResponse, revisedLifetimeCount) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* RedundantServerDataType */ -static UA_DataTypeMember RedundantServerDataType_members[3] = { -{ - UA_TYPENAME("serverId") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - 0, /* .padding */ + offsetof(UA_ReferenceTypeAttributes, writeMask) - offsetof(UA_ReferenceTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serviceLevel") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - offsetof(UA_RedundantServerDataType, serviceLevel) - offsetof(UA_RedundantServerDataType, serverId) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("UserWriteMask") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ReferenceTypeAttributes, userWriteMask) - offsetof(UA_ReferenceTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverState") /* .memberName */ - UA_TYPES_SERVERSTATE, /* .memberTypeIndex */ - offsetof(UA_RedundantServerDataType, serverState) - offsetof(UA_RedundantServerDataType, serviceLevel) - sizeof(UA_Byte), /* .padding */ + UA_TYPENAME("IsAbstract") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_ReferenceTypeAttributes, isAbstract) - offsetof(UA_ReferenceTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* RegisterNodesResponse */ -static UA_DataTypeMember RegisterNodesResponse_members[2] = { +}, { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("Symmetric") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_ReferenceTypeAttributes, symmetric) - offsetof(UA_ReferenceTypeAttributes, isAbstract) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("registeredNodeIds") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_RegisterNodesResponse, registeredNodeIdsSize) - offsetof(UA_RegisterNodesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("InverseName") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_ReferenceTypeAttributes, inverseName) - offsetof(UA_ReferenceTypeAttributes, symmetric) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* CloseSessionRequest */ -static UA_DataTypeMember CloseSessionRequest_members[2] = { +/* GetEndpointsRequest */ +static UA_DataTypeMember GetEndpointsRequest_members[4] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("deleteSubscriptions") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_CloseSessionRequest, deleteSubscriptions) - offsetof(UA_CloseSessionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* ModifyMonitoredItemsResponse */ -static UA_DataTypeMember ModifyMonitoredItemsResponse_members[3] = { -{ - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("EndpointUrl") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_GetEndpointsRequest, endpointUrl) - offsetof(UA_GetEndpointsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_MONITOREDITEMMODIFYRESULT, /* .memberTypeIndex */ - offsetof(UA_ModifyMonitoredItemsResponse, resultsSize) - offsetof(UA_ModifyMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("LocaleIds") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_GetEndpointsRequest, localeIdsSize) - offsetof(UA_GetEndpointsRequest, endpointUrl) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_ModifyMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_ModifyMonitoredItemsResponse, results) - sizeof(void*), /* .padding */ + UA_TYPENAME("ProfileUris") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_GetEndpointsRequest, profileUrisSize) - offsetof(UA_GetEndpointsRequest, localeIds) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* ModifySubscriptionRequest */ -static UA_DataTypeMember ModifySubscriptionRequest_members[7] = { +/* CloseSecureChannelResponse */ +static UA_DataTypeMember CloseSecureChannelResponse_members[1] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* ViewDescription */ +static UA_DataTypeMember ViewDescription_members[3] = { { - UA_TYPENAME("subscriptionId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionRequest, subscriptionId) - offsetof(UA_ModifySubscriptionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("ViewId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedPublishingInterval") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionRequest, requestedPublishingInterval) - offsetof(UA_ModifySubscriptionRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Timestamp") /* .memberName */ + UA_TYPES_DATETIME, /* .memberTypeIndex */ + offsetof(UA_ViewDescription, timestamp) - offsetof(UA_ViewDescription, viewId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedLifetimeCount") /* .memberName */ + UA_TYPENAME("ViewVersion") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionRequest, requestedLifetimeCount) - offsetof(UA_ModifySubscriptionRequest, requestedPublishingInterval) - sizeof(UA_Double), /* .padding */ + offsetof(UA_ViewDescription, viewVersion) - offsetof(UA_ViewDescription, timestamp) - sizeof(UA_DateTime), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* SetPublishingModeResponse */ +static UA_DataTypeMember SetPublishingModeResponse_members[3] = { { - UA_TYPENAME("requestedMaxKeepAliveCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionRequest, requestedMaxKeepAliveCount) - offsetof(UA_ModifySubscriptionRequest, requestedLifetimeCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxNotificationsPerPublish") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionRequest, maxNotificationsPerPublish) - offsetof(UA_ModifySubscriptionRequest, requestedMaxKeepAliveCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_SetPublishingModeResponse, resultsSize) - offsetof(UA_SetPublishingModeResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("priority") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - offsetof(UA_ModifySubscriptionRequest, priority) - offsetof(UA_ModifySubscriptionRequest, maxNotificationsPerPublish) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_SetPublishingModeResponse, diagnosticInfosSize) - offsetof(UA_SetPublishingModeResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* ServerDiagnosticsSummaryDataType */ -static UA_DataTypeMember ServerDiagnosticsSummaryDataType_members[12] = { +/* StatusChangeNotification */ +static UA_DataTypeMember StatusChangeNotification_members[2] = { { - UA_TYPENAME("serverViewCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ + UA_TYPENAME("Status") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("currentSessionCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, serverViewCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DiagnosticInfo") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_StatusChangeNotification, diagnosticInfo) - offsetof(UA_StatusChangeNotification, status) - sizeof(UA_StatusCode), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* NodeAttributesMask */ +#define NodeAttributesMask_members NULL + +/* EventFilterResult */ +static UA_DataTypeMember EventFilterResult_members[3] = { { - UA_TYPENAME("cumulatedSessionCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("SelectClauseResults") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("securityRejectedSessionCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("SelectClauseDiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_EventFilterResult, selectClauseDiagnosticInfosSize) - offsetof(UA_EventFilterResult, selectClauseResults) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("rejectedSessionCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("WhereClauseResult") /* .memberName */ + UA_TYPES_CONTENTFILTERRESULT, /* .memberTypeIndex */ + offsetof(UA_EventFilterResult, whereClauseResult) - offsetof(UA_EventFilterResult, selectClauseDiagnosticInfos) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* MonitoredItemCreateRequest */ +static UA_DataTypeMember MonitoredItemCreateRequest_members[3] = { { - UA_TYPENAME("sessionTimeoutCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ItemToMonitor") /* .memberName */ + UA_TYPES_READVALUEID, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("sessionAbortCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("MonitoringMode") /* .memberName */ + UA_TYPES_MONITORINGMODE, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemCreateRequest, monitoringMode) - offsetof(UA_MonitoredItemCreateRequest, itemToMonitor) - sizeof(UA_ReadValueId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("currentSubscriptionCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("RequestedParameters") /* .memberName */ + UA_TYPES_MONITORINGPARAMETERS, /* .memberTypeIndex */ + offsetof(UA_MonitoredItemCreateRequest, requestedParameters) - offsetof(UA_MonitoredItemCreateRequest, monitoringMode) - sizeof(UA_MonitoringMode), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* Range */ +static UA_DataTypeMember Range_members[2] = { { - UA_TYPENAME("cumulatedSubscriptionCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Low") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("publishingIntervalCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("High") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + offsetof(UA_Range, high) - offsetof(UA_Range, low) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* DataChangeNotification */ +static UA_DataTypeMember DataChangeNotification_members[2] = { { - UA_TYPENAME("securityRejectedRequestsCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("MonitoredItems") /* .memberName */ + UA_TYPES_MONITOREDITEMNOTIFICATION, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("rejectedRequestsCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedRequestsCount) - offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_DataChangeNotification, diagnosticInfosSize) - offsetof(UA_DataChangeNotification, monitoredItems) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* UserTokenPolicy */ -static UA_DataTypeMember UserTokenPolicy_members[5] = { +/* Argument */ +static UA_DataTypeMember Argument_members[5] = { { - UA_TYPENAME("policyId") /* .memberName */ + UA_TYPENAME("Name") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("tokenType") /* .memberName */ - UA_TYPES_USERTOKENTYPE, /* .memberTypeIndex */ - offsetof(UA_UserTokenPolicy, tokenType) - offsetof(UA_UserTokenPolicy, policyId) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("DataType") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_Argument, dataType) - offsetof(UA_Argument, name) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("issuedTokenType") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_UserTokenPolicy, issuedTokenType) - offsetof(UA_UserTokenPolicy, tokenType) - sizeof(UA_UserTokenType), /* .padding */ + UA_TYPENAME("ValueRank") /* .memberName */ + UA_TYPES_INT32, /* .memberTypeIndex */ + offsetof(UA_Argument, valueRank) - offsetof(UA_Argument, dataType) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("issuerEndpointUrl") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_UserTokenPolicy, issuerEndpointUrl) - offsetof(UA_UserTokenPolicy, issuedTokenType) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("ArrayDimensions") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_Argument, arrayDimensionsSize) - offsetof(UA_Argument, valueRank) - sizeof(UA_Int32), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("securityPolicyUri") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_UserTokenPolicy, securityPolicyUri) - offsetof(UA_UserTokenPolicy, issuerEndpointUrl) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("Description") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_Argument, description) - offsetof(UA_Argument, arrayDimensions) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* ReferenceTypeAttributes */ -static UA_DataTypeMember ReferenceTypeAttributes_members[8] = { +/* ChannelSecurityToken */ +static UA_DataTypeMember ChannelSecurityToken_members[4] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ + UA_TYPENAME("ChannelId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_ReferenceTypeAttributes, displayName) - offsetof(UA_ReferenceTypeAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("TokenId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ChannelSecurityToken, tokenId) - offsetof(UA_ChannelSecurityToken, channelId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("description") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_ReferenceTypeAttributes, description) - offsetof(UA_ReferenceTypeAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ + UA_TYPENAME("CreatedAt") /* .memberName */ + UA_TYPES_DATETIME, /* .memberTypeIndex */ + offsetof(UA_ChannelSecurityToken, createdAt) - offsetof(UA_ChannelSecurityToken, tokenId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ + UA_TYPENAME("RevisedLifetime") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ReferenceTypeAttributes, writeMask) - offsetof(UA_ReferenceTypeAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ + offsetof(UA_ChannelSecurityToken, revisedLifetime) - offsetof(UA_ChannelSecurityToken, createdAt) - sizeof(UA_DateTime), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* ServerState */ +#define ServerState_members NULL + +/* EventNotificationList */ +static UA_DataTypeMember EventNotificationList_members[1] = { { - UA_TYPENAME("userWriteMask") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ReferenceTypeAttributes, userWriteMask) - offsetof(UA_ReferenceTypeAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Events") /* .memberName */ + UA_TYPES_EVENTFIELDLIST, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* AnonymousIdentityToken */ +static UA_DataTypeMember AnonymousIdentityToken_members[1] = { { - UA_TYPENAME("isAbstract") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_ReferenceTypeAttributes, isAbstract) - offsetof(UA_ReferenceTypeAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("PolicyId") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* FilterOperator */ +#define FilterOperator_members NULL + +/* AggregateFilter */ +static UA_DataTypeMember AggregateFilter_members[4] = { { - UA_TYPENAME("symmetric") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_ReferenceTypeAttributes, symmetric) - offsetof(UA_ReferenceTypeAttributes, isAbstract) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("StartTime") /* .memberName */ + UA_TYPES_DATETIME, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("inverseName") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_ReferenceTypeAttributes, inverseName) - offsetof(UA_ReferenceTypeAttributes, symmetric) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("AggregateType") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_AggregateFilter, aggregateType) - offsetof(UA_AggregateFilter, startTime) - sizeof(UA_DateTime), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* BrowsePath */ -static UA_DataTypeMember BrowsePath_members[2] = { +}, { - UA_TYPENAME("startingNode") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("ProcessingInterval") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + offsetof(UA_AggregateFilter, processingInterval) - offsetof(UA_AggregateFilter, aggregateType) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("relativePath") /* .memberName */ - UA_TYPES_RELATIVEPATH, /* .memberTypeIndex */ - offsetof(UA_BrowsePath, relativePath) - offsetof(UA_BrowsePath, startingNode) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("AggregateConfiguration") /* .memberName */ + UA_TYPES_AGGREGATECONFIGURATION, /* .memberTypeIndex */ + offsetof(UA_AggregateFilter, aggregateConfiguration) - offsetof(UA_AggregateFilter, processingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* SetMonitoringModeRequest */ -static UA_DataTypeMember SetMonitoringModeRequest_members[4] = { +/* RepublishResponse */ +static UA_DataTypeMember RepublishResponse_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SetMonitoringModeRequest, subscriptionId) - offsetof(UA_SetMonitoringModeRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("NotificationMessage") /* .memberName */ + UA_TYPES_NOTIFICATIONMESSAGE, /* .memberTypeIndex */ + offsetof(UA_RepublishResponse, notificationMessage) - offsetof(UA_RepublishResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* DeleteSubscriptionsResponse */ +static UA_DataTypeMember DeleteSubscriptionsResponse_members[3] = { { - UA_TYPENAME("monitoringMode") /* .memberName */ - UA_TYPES_MONITORINGMODE, /* .memberTypeIndex */ - offsetof(UA_SetMonitoringModeRequest, monitoringMode) - offsetof(UA_SetMonitoringModeRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("monitoredItemIds") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SetMonitoringModeRequest, monitoredItemIdsSize) - offsetof(UA_SetMonitoringModeRequest, monitoringMode) - sizeof(UA_MonitoringMode), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_DeleteSubscriptionsResponse, resultsSize) - offsetof(UA_DeleteSubscriptionsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; - -/* UnregisterNodesResponse */ -static UA_DataTypeMember UnregisterNodesResponse_members[1] = { +}, { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_DeleteSubscriptionsResponse, diagnosticInfosSize) - offsetof(UA_DeleteSubscriptionsResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* WriteRequest */ -static UA_DataTypeMember WriteRequest_members[2] = { +/* RegisterNodesRequest */ +static UA_DataTypeMember RegisterNodesRequest_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodesToWrite") /* .memberName */ - UA_TYPES_WRITEVALUE, /* .memberTypeIndex */ - offsetof(UA_WriteRequest, nodesToWriteSize) - offsetof(UA_WriteRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("NodesToRegister") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_RegisterNodesRequest, nodesToRegisterSize) - offsetof(UA_RegisterNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* ObjectAttributes */ -static UA_DataTypeMember ObjectAttributes_members[6] = { +/* MethodAttributes */ +static UA_DataTypeMember MethodAttributes_members[7] = { { - UA_TYPENAME("specifiedAttributes") /* .memberName */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ + UA_TYPENAME("DisplayName") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_ObjectAttributes, displayName) - offsetof(UA_ObjectAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_MethodAttributes, displayName) - offsetof(UA_MethodAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("description") /* .memberName */ + UA_TYPENAME("Description") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_ObjectAttributes, description) - offsetof(UA_ObjectAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ + offsetof(UA_MethodAttributes, description) - offsetof(UA_MethodAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("writeMask") /* .memberName */ + UA_TYPENAME("WriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ObjectAttributes, writeMask) - offsetof(UA_ObjectAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ + offsetof(UA_MethodAttributes, writeMask) - offsetof(UA_MethodAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userWriteMask") /* .memberName */ + UA_TYPENAME("UserWriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ObjectAttributes, userWriteMask) - offsetof(UA_ObjectAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_MethodAttributes, userWriteMask) - offsetof(UA_MethodAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("eventNotifier") /* .memberName */ - UA_TYPES_BYTE, /* .memberTypeIndex */ - offsetof(UA_ObjectAttributes, eventNotifier) - offsetof(UA_ObjectAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Executable") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_MethodAttributes, executable) - offsetof(UA_MethodAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* BrowseResultMask */ -static UA_DataTypeMember BrowseResultMask_members[1] = { +}, { - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("UserExecutable") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_MethodAttributes, userExecutable) - offsetof(UA_MethodAttributes, executable) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* BrowseDescription */ -static UA_DataTypeMember BrowseDescription_members[6] = { +/* UserNameIdentityToken */ +static UA_DataTypeMember UserNameIdentityToken_members[4] = { { - UA_TYPENAME("nodeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ + UA_TYPENAME("PolicyId") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("browseDirection") /* .memberName */ - UA_TYPES_BROWSEDIRECTION, /* .memberTypeIndex */ - offsetof(UA_BrowseDescription, browseDirection) - offsetof(UA_BrowseDescription, nodeId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("UserName") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_UserNameIdentityToken, userName) - offsetof(UA_UserNameIdentityToken, policyId) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("referenceTypeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_BrowseDescription, referenceTypeId) - offsetof(UA_BrowseDescription, browseDirection) - sizeof(UA_BrowseDirection), /* .padding */ + UA_TYPENAME("Password") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_UserNameIdentityToken, password) - offsetof(UA_UserNameIdentityToken, userName) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("includeSubtypes") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_BrowseDescription, includeSubtypes) - offsetof(UA_BrowseDescription, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("EncryptionAlgorithm") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_UserNameIdentityToken, encryptionAlgorithm) - offsetof(UA_UserNameIdentityToken, password) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* UnregisterNodesRequest */ +static UA_DataTypeMember UnregisterNodesRequest_members[2] = { { - UA_TYPENAME("nodeClassMask") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_BrowseDescription, nodeClassMask) - offsetof(UA_BrowseDescription, includeSubtypes) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("resultMask") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_BrowseDescription, resultMask) - offsetof(UA_BrowseDescription, nodeClassMask) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("NodesToUnregister") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_UnregisterNodesRequest, nodesToUnregisterSize) - offsetof(UA_UnregisterNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* SetTriggeringRequest */ -static UA_DataTypeMember SetTriggeringRequest_members[5] = { +/* OpenSecureChannelResponse */ +static UA_DataTypeMember OpenSecureChannelResponse_members[4] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionId") /* .memberName */ + UA_TYPENAME("ServerProtocolVersion") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SetTriggeringRequest, subscriptionId) - offsetof(UA_SetTriggeringRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + offsetof(UA_OpenSecureChannelResponse, serverProtocolVersion) - offsetof(UA_OpenSecureChannelResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("triggeringItemId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SetTriggeringRequest, triggeringItemId) - offsetof(UA_SetTriggeringRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("SecurityToken") /* .memberName */ + UA_TYPES_CHANNELSECURITYTOKEN, /* .memberTypeIndex */ + offsetof(UA_OpenSecureChannelResponse, securityToken) - offsetof(UA_OpenSecureChannelResponse, serverProtocolVersion) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("linksToAdd") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SetTriggeringRequest, linksToAddSize) - offsetof(UA_SetTriggeringRequest, triggeringItemId) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("linksToRemove") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SetTriggeringRequest, linksToRemoveSize) - offsetof(UA_SetTriggeringRequest, linksToAdd) - sizeof(void*), /* .padding */ + UA_TYPENAME("ServerNonce") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_OpenSecureChannelResponse, serverNonce) - offsetof(UA_OpenSecureChannelResponse, securityToken) - sizeof(UA_ChannelSecurityToken), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* SessionSecurityDiagnosticsDataType */ -static UA_DataTypeMember SessionSecurityDiagnosticsDataType_members[9] = { +/* SetTriggeringResponse */ +static UA_DataTypeMember SetTriggeringResponse_members[5] = { { - UA_TYPENAME("sessionId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientUserIdOfSession") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionSecurityDiagnosticsDataType, clientUserIdOfSession) - offsetof(UA_SessionSecurityDiagnosticsDataType, sessionId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("AddResults") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_SetTriggeringResponse, addResultsSize) - offsetof(UA_SetTriggeringResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("clientUserIdHistory") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionSecurityDiagnosticsDataType, clientUserIdHistorySize) - offsetof(UA_SessionSecurityDiagnosticsDataType, clientUserIdOfSession) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("AddDiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_SetTriggeringResponse, addDiagnosticInfosSize) - offsetof(UA_SetTriggeringResponse, addResults) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("authenticationMechanism") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionSecurityDiagnosticsDataType, authenticationMechanism) - offsetof(UA_SessionSecurityDiagnosticsDataType, clientUserIdHistory) - sizeof(void*), /* .padding */ + UA_TYPENAME("RemoveResults") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_SetTriggeringResponse, removeResultsSize) - offsetof(UA_SetTriggeringResponse, addDiagnosticInfos) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("encoding") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionSecurityDiagnosticsDataType, encoding) - offsetof(UA_SessionSecurityDiagnosticsDataType, authenticationMechanism) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("RemoveDiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_SetTriggeringResponse, removeDiagnosticInfosSize) - offsetof(UA_SetTriggeringResponse, removeResults) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* SimpleAttributeOperand */ +static UA_DataTypeMember SimpleAttributeOperand_members[4] = { { - UA_TYPENAME("transportProtocol") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionSecurityDiagnosticsDataType, transportProtocol) - offsetof(UA_SessionSecurityDiagnosticsDataType, encoding) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("TypeDefinitionId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("securityMode") /* .memberName */ - UA_TYPES_MESSAGESECURITYMODE, /* .memberTypeIndex */ - offsetof(UA_SessionSecurityDiagnosticsDataType, securityMode) - offsetof(UA_SessionSecurityDiagnosticsDataType, transportProtocol) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("BrowsePath") /* .memberName */ + UA_TYPES_QUALIFIEDNAME, /* .memberTypeIndex */ + offsetof(UA_SimpleAttributeOperand, browsePathSize) - offsetof(UA_SimpleAttributeOperand, typeDefinitionId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("securityPolicyUri") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionSecurityDiagnosticsDataType, securityPolicyUri) - offsetof(UA_SessionSecurityDiagnosticsDataType, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */ + UA_TYPENAME("AttributeId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_SimpleAttributeOperand, attributeId) - offsetof(UA_SimpleAttributeOperand, browsePath) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientCertificate") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_SessionSecurityDiagnosticsDataType, clientCertificate) - offsetof(UA_SessionSecurityDiagnosticsDataType, securityPolicyUri) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("IndexRange") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_SimpleAttributeOperand, indexRange) - offsetof(UA_SimpleAttributeOperand, attributeId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* RepublishRequest */ static UA_DataTypeMember RepublishRequest_members[3] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionId") /* .memberName */ + UA_TYPENAME("SubscriptionId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_RepublishRequest, subscriptionId) - offsetof(UA_RepublishRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("retransmitSequenceNumber") /* .memberName */ + UA_TYPENAME("RetransmitSequenceNumber") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_RepublishRequest, retransmitSequenceNumber) - offsetof(UA_RepublishRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* GetEndpointsRequest */ -static UA_DataTypeMember GetEndpointsRequest_members[4] = { -{ - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("endpointUrl") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_GetEndpointsRequest, endpointUrl) - offsetof(UA_GetEndpointsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("localeIds") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_GetEndpointsRequest, localeIdsSize) - offsetof(UA_GetEndpointsRequest, endpointUrl) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("profileUris") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_GetEndpointsRequest, profileUrisSize) - offsetof(UA_GetEndpointsRequest, localeIds) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +},}; -/* PublishRequest */ -static UA_DataTypeMember PublishRequest_members[2] = { +/* RegisterNodesResponse */ +static UA_DataTypeMember RegisterNodesResponse_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionAcknowledgements") /* .memberName */ - UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT, /* .memberTypeIndex */ - offsetof(UA_PublishRequest, subscriptionAcknowledgementsSize) - offsetof(UA_PublishRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("RegisteredNodeIds") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ + offsetof(UA_RegisterNodesResponse, registeredNodeIdsSize) - offsetof(UA_RegisterNodesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* DeleteSubscriptionsResponse */ -static UA_DataTypeMember DeleteSubscriptionsResponse_members[3] = { +/* ModifyMonitoredItemsResponse */ +static UA_DataTypeMember ModifyMonitoredItemsResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_DeleteSubscriptionsResponse, resultsSize) - offsetof(UA_DeleteSubscriptionsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_MONITOREDITEMMODIFYRESULT, /* .memberTypeIndex */ + offsetof(UA_ModifyMonitoredItemsResponse, resultsSize) - offsetof(UA_ModifyMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_DeleteSubscriptionsResponse, diagnosticInfosSize) - offsetof(UA_DeleteSubscriptionsResponse, results) - sizeof(void*), /* .padding */ + offsetof(UA_ModifyMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_ModifyMonitoredItemsResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* AddNodesResponse */ -static UA_DataTypeMember AddNodesResponse_members[3] = { +/* DeleteSubscriptionsRequest */ +static UA_DataTypeMember DeleteSubscriptionsRequest_members[2] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_ADDNODESRESULT, /* .memberTypeIndex */ - offsetof(UA_AddNodesResponse, resultsSize) - offsetof(UA_AddNodesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_AddNodesResponse, diagnosticInfosSize) - offsetof(UA_AddNodesResponse, results) - sizeof(void*), /* .padding */ + UA_TYPENAME("SubscriptionIds") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_DeleteSubscriptionsRequest, subscriptionIdsSize) - offsetof(UA_DeleteSubscriptionsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* DataChangeNotification */ -static UA_DataTypeMember DataChangeNotification_members[2] = { +/* RedundancySupport */ +#define RedundancySupport_members NULL + +/* BrowsePath */ +static UA_DataTypeMember BrowsePath_members[2] = { { - UA_TYPENAME("monitoredItems") /* .memberName */ - UA_TYPES_MONITOREDITEMNOTIFICATION, /* .memberTypeIndex */ + UA_TYPENAME("StartingNode") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_DataChangeNotification, diagnosticInfosSize) - offsetof(UA_DataChangeNotification, monitoredItems) - sizeof(void*), /* .padding */ + UA_TYPENAME("RelativePath") /* .memberName */ + UA_TYPES_RELATIVEPATH, /* .memberTypeIndex */ + offsetof(UA_BrowsePath, relativePath) - offsetof(UA_BrowsePath, startingNode) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* CloseSecureChannelResponse */ -static UA_DataTypeMember CloseSecureChannelResponse_members[1] = { +/* ObjectAttributes */ +static UA_DataTypeMember ObjectAttributes_members[6] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("SpecifiedAttributes") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* ModifyMonitoredItemsRequest */ -static UA_DataTypeMember ModifyMonitoredItemsRequest_members[4] = { +}, { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("DisplayName") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_ObjectAttributes, displayName) - offsetof(UA_ObjectAttributes, specifiedAttributes) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionId") /* .memberName */ + UA_TYPENAME("Description") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_ObjectAttributes, description) - offsetof(UA_ObjectAttributes, displayName) - sizeof(UA_LocalizedText), /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("WriteMask") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_ModifyMonitoredItemsRequest, subscriptionId) - offsetof(UA_ModifyMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + offsetof(UA_ObjectAttributes, writeMask) - offsetof(UA_ObjectAttributes, description) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("timestampsToReturn") /* .memberName */ - UA_TYPES_TIMESTAMPSTORETURN, /* .memberTypeIndex */ - offsetof(UA_ModifyMonitoredItemsRequest, timestampsToReturn) - offsetof(UA_ModifyMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("UserWriteMask") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ObjectAttributes, userWriteMask) - offsetof(UA_ObjectAttributes, writeMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("itemsToModify") /* .memberName */ - UA_TYPES_MONITOREDITEMMODIFYREQUEST, /* .memberTypeIndex */ - offsetof(UA_ModifyMonitoredItemsRequest, itemsToModifySize) - offsetof(UA_ModifyMonitoredItemsRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */ + UA_TYPENAME("EventNotifier") /* .memberName */ + UA_TYPES_BYTE, /* .memberTypeIndex */ + offsetof(UA_ObjectAttributes, eventNotifier) - offsetof(UA_ObjectAttributes, userWriteMask) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* SetMonitoringModeResponse */ -static UA_DataTypeMember SetMonitoringModeResponse_members[3] = { +/* PublishRequest */ +static UA_DataTypeMember PublishRequest_members[2] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_SetMonitoringModeResponse, resultsSize) - offsetof(UA_SetMonitoringModeResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_SetMonitoringModeResponse, diagnosticInfosSize) - offsetof(UA_SetMonitoringModeResponse, results) - sizeof(void*), /* .padding */ + UA_TYPENAME("SubscriptionAcknowledgements") /* .memberName */ + UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT, /* .memberTypeIndex */ + offsetof(UA_PublishRequest, subscriptionAcknowledgementsSize) - offsetof(UA_PublishRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; /* FindServersRequest */ static UA_DataTypeMember FindServersRequest_members[4] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("endpointUrl") /* .memberName */ + UA_TYPENAME("EndpointUrl") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_FindServersRequest, endpointUrl) - offsetof(UA_FindServersRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("localeIds") /* .memberName */ + UA_TYPENAME("LocaleIds") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_FindServersRequest, localeIdsSize) - offsetof(UA_FindServersRequest, endpointUrl) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("serverUris") /* .memberName */ + UA_TYPENAME("ServerUris") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_FindServersRequest, serverUrisSize) - offsetof(UA_FindServersRequest, localeIds) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; + +/* FindServersOnNetworkResponse */ +static UA_DataTypeMember FindServersOnNetworkResponse_members[3] = { +{ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("LastCounterResetTime") /* .memberName */ + UA_TYPES_DATETIME, /* .memberTypeIndex */ + offsetof(UA_FindServersOnNetworkResponse, lastCounterResetTime) - offsetof(UA_FindServersOnNetworkResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("Servers") /* .memberName */ + UA_TYPES_SERVERONNETWORK, /* .memberTypeIndex */ + offsetof(UA_FindServersOnNetworkResponse, serversSize) - offsetof(UA_FindServersOnNetworkResponse, lastCounterResetTime) - sizeof(UA_DateTime), /* .padding */ + true, /* .namespaceZero */ + true /* .isArray */ +},}; /* ReferenceDescription */ static UA_DataTypeMember ReferenceDescription_members[7] = { { - UA_TYPENAME("referenceTypeId") /* .memberName */ + UA_TYPENAME("ReferenceTypeId") /* .memberName */ UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("isForward") /* .memberName */ + UA_TYPENAME("IsForward") /* .memberName */ UA_TYPES_BOOLEAN, /* .memberTypeIndex */ offsetof(UA_ReferenceDescription, isForward) - offsetof(UA_ReferenceDescription, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodeId") /* .memberName */ + UA_TYPENAME("NodeId") /* .memberName */ UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ offsetof(UA_ReferenceDescription, nodeId) - offsetof(UA_ReferenceDescription, isForward) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("browseName") /* .memberName */ + UA_TYPENAME("BrowseName") /* .memberName */ UA_TYPES_QUALIFIEDNAME, /* .memberTypeIndex */ offsetof(UA_ReferenceDescription, browseName) - offsetof(UA_ReferenceDescription, nodeId) - sizeof(UA_ExpandedNodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("displayName") /* .memberName */ + UA_TYPENAME("DisplayName") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ offsetof(UA_ReferenceDescription, displayName) - offsetof(UA_ReferenceDescription, browseName) - sizeof(UA_QualifiedName), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodeClass") /* .memberName */ + UA_TYPENAME("NodeClass") /* .memberName */ UA_TYPES_NODECLASS, /* .memberTypeIndex */ offsetof(UA_ReferenceDescription, nodeClass) - offsetof(UA_ReferenceDescription, displayName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("typeDefinition") /* .memberName */ + UA_TYPENAME("TypeDefinition") /* .memberName */ UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ offsetof(UA_ReferenceDescription, typeDefinition) - offsetof(UA_ReferenceDescription, nodeClass) - sizeof(UA_NodeClass), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* SetPublishingModeResponse */ -static UA_DataTypeMember SetPublishingModeResponse_members[3] = { -{ - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_SetPublishingModeResponse, resultsSize) - offsetof(UA_SetPublishingModeResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_SetPublishingModeResponse, diagnosticInfosSize) - offsetof(UA_SetPublishingModeResponse, results) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* ContentFilterResult */ -static UA_DataTypeMember ContentFilterResult_members[2] = { -{ - UA_TYPENAME("elementResults") /* .memberName */ - UA_TYPES_CONTENTFILTERELEMENTRESULT, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("elementDiagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_ContentFilterResult, elementDiagnosticInfosSize) - offsetof(UA_ContentFilterResult, elementResults) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* RegisterServerResponse */ -static UA_DataTypeMember RegisterServerResponse_members[1] = { -{ - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* AddReferencesItem */ -static UA_DataTypeMember AddReferencesItem_members[6] = { +/* CreateSubscriptionRequest */ +static UA_DataTypeMember CreateSubscriptionRequest_members[7] = { { - UA_TYPENAME("sourceNodeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("referenceTypeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_AddReferencesItem, referenceTypeId) - offsetof(UA_AddReferencesItem, sourceNodeId) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("isForward") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_AddReferencesItem, isForward) - offsetof(UA_AddReferencesItem, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ + UA_TYPENAME("RequestedPublishingInterval") /* .memberName */ + UA_TYPES_DOUBLE, /* .memberTypeIndex */ + offsetof(UA_CreateSubscriptionRequest, requestedPublishingInterval) - offsetof(UA_CreateSubscriptionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("targetServerUri") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_AddReferencesItem, targetServerUri) - offsetof(UA_AddReferencesItem, isForward) - sizeof(UA_Boolean), /* .padding */ + UA_TYPENAME("RequestedLifetimeCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_CreateSubscriptionRequest, requestedLifetimeCount) - offsetof(UA_CreateSubscriptionRequest, requestedPublishingInterval) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("targetNodeId") /* .memberName */ - UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ - offsetof(UA_AddReferencesItem, targetNodeId) - offsetof(UA_AddReferencesItem, targetServerUri) - sizeof(UA_String), /* .padding */ + UA_TYPENAME("RequestedMaxKeepAliveCount") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_CreateSubscriptionRequest, requestedMaxKeepAliveCount) - offsetof(UA_CreateSubscriptionRequest, requestedLifetimeCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("targetNodeClass") /* .memberName */ - UA_TYPES_NODECLASS, /* .memberTypeIndex */ - offsetof(UA_AddReferencesItem, targetNodeClass) - offsetof(UA_AddReferencesItem, targetNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* QueryDataDescription */ -static UA_DataTypeMember QueryDataDescription_members[3] = { -{ - UA_TYPENAME("relativePath") /* .memberName */ - UA_TYPES_RELATIVEPATH, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("MaxNotificationsPerPublish") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_CreateSubscriptionRequest, maxNotificationsPerPublish) - offsetof(UA_CreateSubscriptionRequest, requestedMaxKeepAliveCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("attributeId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_QueryDataDescription, attributeId) - offsetof(UA_QueryDataDescription, relativePath) - sizeof(UA_RelativePath), /* .padding */ + UA_TYPENAME("PublishingEnabled") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_CreateSubscriptionRequest, publishingEnabled) - offsetof(UA_CreateSubscriptionRequest, maxNotificationsPerPublish) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("indexRange") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_QueryDataDescription, indexRange) - offsetof(UA_QueryDataDescription, attributeId) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("Priority") /* .memberName */ + UA_TYPES_BYTE, /* .memberTypeIndex */ + offsetof(UA_CreateSubscriptionRequest, priority) - offsetof(UA_CreateSubscriptionRequest, publishingEnabled) - sizeof(UA_Boolean), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* CreateSubscriptionResponse */ -static UA_DataTypeMember CreateSubscriptionResponse_members[5] = { +/* FindServersOnNetworkRequest */ +static UA_DataTypeMember FindServersOnNetworkRequest_members[4] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("subscriptionId") /* .memberName */ + UA_TYPENAME("StartingRecordId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionResponse, subscriptionId) - offsetof(UA_CreateSubscriptionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("revisedPublishingInterval") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionResponse, revisedPublishingInterval) - offsetof(UA_CreateSubscriptionResponse, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + offsetof(UA_FindServersOnNetworkRequest, startingRecordId) - offsetof(UA_FindServersOnNetworkRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("revisedLifetimeCount") /* .memberName */ + UA_TYPENAME("MaxRecordsToReturn") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionResponse, revisedLifetimeCount) - offsetof(UA_CreateSubscriptionResponse, revisedPublishingInterval) - sizeof(UA_Double), /* .padding */ + offsetof(UA_FindServersOnNetworkRequest, maxRecordsToReturn) - offsetof(UA_FindServersOnNetworkRequest, startingRecordId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("revisedMaxKeepAliveCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_CreateSubscriptionResponse, revisedMaxKeepAliveCount) - offsetof(UA_CreateSubscriptionResponse, revisedLifetimeCount) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* NetworkGroupDataType */ -static UA_DataTypeMember NetworkGroupDataType_members[2] = { -{ - UA_TYPENAME("serverUri") /* .memberName */ + UA_TYPENAME("ServerCapabilityFilter") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("networkPaths") /* .memberName */ - UA_TYPES_ENDPOINTURLLISTDATATYPE, /* .memberTypeIndex */ - offsetof(UA_NetworkGroupDataType, networkPathsSize) - offsetof(UA_NetworkGroupDataType, serverUri) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* DeleteReferencesResponse */ -static UA_DataTypeMember DeleteReferencesResponse_members[3] = { -{ - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_DeleteReferencesResponse, resultsSize) - offsetof(UA_DeleteReferencesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_DeleteReferencesResponse, diagnosticInfosSize) - offsetof(UA_DeleteReferencesResponse, results) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* CreateMonitoredItemsResponse */ -static UA_DataTypeMember CreateMonitoredItemsResponse_members[3] = { -{ - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_MONITOREDITEMCREATERESULT, /* .memberTypeIndex */ - offsetof(UA_CreateMonitoredItemsResponse, resultsSize) - offsetof(UA_CreateMonitoredItemsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_CreateMonitoredItemsResponse, diagnosticInfosSize) - offsetof(UA_CreateMonitoredItemsResponse, results) - sizeof(void*), /* .padding */ + offsetof(UA_FindServersOnNetworkRequest, serverCapabilityFilterSize) - offsetof(UA_FindServersOnNetworkRequest, maxRecordsToReturn) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; /* CallResponse */ static UA_DataTypeMember CallResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ + UA_TYPENAME("Results") /* .memberName */ UA_TYPES_CALLMETHODRESULT, /* .memberTypeIndex */ offsetof(UA_CallResponse, resultsSize) - offsetof(UA_CallResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ offsetof(UA_CallResponse, diagnosticInfosSize) - offsetof(UA_CallResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; /* DeleteNodesResponse */ static UA_DataTypeMember DeleteNodesResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ + UA_TYPENAME("Results") /* .memberName */ UA_TYPES_STATUSCODE, /* .memberTypeIndex */ offsetof(UA_DeleteNodesResponse, resultsSize) - offsetof(UA_DeleteNodesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ offsetof(UA_DeleteNodesResponse, diagnosticInfosSize) - offsetof(UA_DeleteNodesResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* RepublishResponse */ -static UA_DataTypeMember RepublishResponse_members[2] = { +/* ModifyMonitoredItemsRequest */ +static UA_DataTypeMember ModifyMonitoredItemsRequest_members[4] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("notificationMessage") /* .memberName */ - UA_TYPES_NOTIFICATIONMESSAGE, /* .memberTypeIndex */ - offsetof(UA_RepublishResponse, notificationMessage) - offsetof(UA_RepublishResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* MonitoredItemCreateRequest */ -static UA_DataTypeMember MonitoredItemCreateRequest_members[3] = { -{ - UA_TYPENAME("itemToMonitor") /* .memberName */ - UA_TYPES_READVALUEID, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("SubscriptionId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_ModifyMonitoredItemsRequest, subscriptionId) - offsetof(UA_ModifyMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("monitoringMode") /* .memberName */ - UA_TYPES_MONITORINGMODE, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemCreateRequest, monitoringMode) - offsetof(UA_MonitoredItemCreateRequest, itemToMonitor) - sizeof(UA_ReadValueId), /* .padding */ + UA_TYPENAME("TimestampsToReturn") /* .memberName */ + UA_TYPES_TIMESTAMPSTORETURN, /* .memberTypeIndex */ + offsetof(UA_ModifyMonitoredItemsRequest, timestampsToReturn) - offsetof(UA_ModifyMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedParameters") /* .memberName */ - UA_TYPES_MONITORINGPARAMETERS, /* .memberTypeIndex */ - offsetof(UA_MonitoredItemCreateRequest, requestedParameters) - offsetof(UA_MonitoredItemCreateRequest, monitoringMode) - sizeof(UA_MonitoringMode), /* .padding */ + UA_TYPENAME("ItemsToModify") /* .memberName */ + UA_TYPES_MONITOREDITEMMODIFYREQUEST, /* .memberTypeIndex */ + offsetof(UA_ModifyMonitoredItemsRequest, itemsToModifySize) - offsetof(UA_ModifyMonitoredItemsRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* DeleteReferencesRequest */ -static UA_DataTypeMember DeleteReferencesRequest_members[2] = { +/* ServiceFault */ +static UA_DataTypeMember ServiceFault_members[1] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, -{ - UA_TYPENAME("referencesToDelete") /* .memberName */ - UA_TYPES_DELETEREFERENCESITEM, /* .memberTypeIndex */ - offsetof(UA_DeleteReferencesRequest, referencesToDeleteSize) - offsetof(UA_DeleteReferencesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +},}; -/* ReadResponse */ -static UA_DataTypeMember ReadResponse_members[3] = { +/* PublishResponse */ +static UA_DataTypeMember PublishResponse_members[7] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_DATAVALUE, /* .memberTypeIndex */ - offsetof(UA_ReadResponse, resultsSize) - offsetof(UA_ReadResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("SubscriptionId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_PublishResponse, subscriptionId) - offsetof(UA_PublishResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_ReadResponse, diagnosticInfosSize) - offsetof(UA_ReadResponse, results) - sizeof(void*), /* .padding */ + UA_TYPENAME("AvailableSequenceNumbers") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_PublishResponse, availableSequenceNumbersSize) - offsetof(UA_PublishResponse, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; - -/* AddReferencesRequest */ -static UA_DataTypeMember AddReferencesRequest_members[2] = { +}, { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("MoreNotifications") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_PublishResponse, moreNotifications) - offsetof(UA_PublishResponse, availableSequenceNumbers) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("referencesToAdd") /* .memberName */ - UA_TYPES_ADDREFERENCESITEM, /* .memberTypeIndex */ - offsetof(UA_AddReferencesRequest, referencesToAddSize) - offsetof(UA_AddReferencesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("NotificationMessage") /* .memberName */ + UA_TYPES_NOTIFICATIONMESSAGE, /* .memberTypeIndex */ + offsetof(UA_PublishResponse, notificationMessage) - offsetof(UA_PublishResponse, moreNotifications) - sizeof(UA_Boolean), /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + offsetof(UA_PublishResponse, resultsSize) - offsetof(UA_PublishResponse, notificationMessage) - sizeof(UA_NotificationMessage), /* .padding */ + true, /* .namespaceZero */ + true /* .isArray */ +}, +{ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_PublishResponse, diagnosticInfosSize) - offsetof(UA_PublishResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* ReadRequest */ -static UA_DataTypeMember ReadRequest_members[4] = { +/* CreateMonitoredItemsRequest */ +static UA_DataTypeMember CreateMonitoredItemsRequest_members[4] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxAge") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_ReadRequest, maxAge) - offsetof(UA_ReadRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("SubscriptionId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_CreateMonitoredItemsRequest, subscriptionId) - offsetof(UA_CreateMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("timestampsToReturn") /* .memberName */ + UA_TYPENAME("TimestampsToReturn") /* .memberName */ UA_TYPES_TIMESTAMPSTORETURN, /* .memberTypeIndex */ - offsetof(UA_ReadRequest, timestampsToReturn) - offsetof(UA_ReadRequest, maxAge) - sizeof(UA_Double), /* .padding */ + offsetof(UA_CreateMonitoredItemsRequest, timestampsToReturn) - offsetof(UA_CreateMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodesToRead") /* .memberName */ - UA_TYPES_READVALUEID, /* .memberTypeIndex */ - offsetof(UA_ReadRequest, nodesToReadSize) - offsetof(UA_ReadRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */ + UA_TYPENAME("ItemsToCreate") /* .memberName */ + UA_TYPES_MONITOREDITEMCREATEREQUEST, /* .memberTypeIndex */ + offsetof(UA_CreateMonitoredItemsRequest, itemsToCreateSize) - offsetof(UA_CreateMonitoredItemsRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; /* OpenSecureChannelRequest */ static UA_DataTypeMember OpenSecureChannelRequest_members[6] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientProtocolVersion") /* .memberName */ + UA_TYPENAME("ClientProtocolVersion") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_OpenSecureChannelRequest, clientProtocolVersion) - offsetof(UA_OpenSecureChannelRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestType") /* .memberName */ + UA_TYPENAME("RequestType") /* .memberName */ UA_TYPES_SECURITYTOKENREQUESTTYPE, /* .memberTypeIndex */ offsetof(UA_OpenSecureChannelRequest, requestType) - offsetof(UA_OpenSecureChannelRequest, clientProtocolVersion) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("securityMode") /* .memberName */ + UA_TYPENAME("SecurityMode") /* .memberName */ UA_TYPES_MESSAGESECURITYMODE, /* .memberTypeIndex */ offsetof(UA_OpenSecureChannelRequest, securityMode) - offsetof(UA_OpenSecureChannelRequest, requestType) - sizeof(UA_SecurityTokenRequestType), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientNonce") /* .memberName */ + UA_TYPENAME("ClientNonce") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ offsetof(UA_OpenSecureChannelRequest, clientNonce) - offsetof(UA_OpenSecureChannelRequest, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedLifetime") /* .memberName */ + UA_TYPENAME("RequestedLifetime") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_OpenSecureChannelRequest, requestedLifetime) - offsetof(UA_OpenSecureChannelRequest, clientNonce) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* RegisterServer2Response */ -static UA_DataTypeMember RegisterServer2Response_members[3] = { +/* CloseSessionRequest */ +static UA_DataTypeMember CloseSessionRequest_members[2] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("configurationResults") /* .memberName */ + UA_TYPENAME("DeleteSubscriptions") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_CloseSessionRequest, deleteSubscriptions) - offsetof(UA_CloseSessionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +},}; + +/* SetTriggeringRequest */ +static UA_DataTypeMember SetTriggeringRequest_members[5] = { +{ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("SubscriptionId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_SetTriggeringRequest, subscriptionId) - offsetof(UA_SetTriggeringRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("TriggeringItemId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_SetTriggeringRequest, triggeringItemId) - offsetof(UA_SetTriggeringRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("LinksToAdd") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_SetTriggeringRequest, linksToAddSize) - offsetof(UA_SetTriggeringRequest, triggeringItemId) - sizeof(UA_UInt32), /* .padding */ + true, /* .namespaceZero */ + true /* .isArray */ +}, +{ + UA_TYPENAME("LinksToRemove") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_SetTriggeringRequest, linksToRemoveSize) - offsetof(UA_SetTriggeringRequest, linksToAdd) - sizeof(void*), /* .padding */ + true, /* .namespaceZero */ + true /* .isArray */ +},}; + +/* BrowseResult */ +static UA_DataTypeMember BrowseResult_members[3] = { +{ + UA_TYPENAME("StatusCode") /* .memberName */ UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_RegisterServer2Response, configurationResultsSize) - offsetof(UA_RegisterServer2Response, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + 0, /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("ContinuationPoint") /* .memberName */ + UA_TYPES_BYTESTRING, /* .memberTypeIndex */ + offsetof(UA_BrowseResult, continuationPoint) - offsetof(UA_BrowseResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ +}, +{ + UA_TYPENAME("References") /* .memberName */ + UA_TYPES_REFERENCEDESCRIPTION, /* .memberTypeIndex */ + offsetof(UA_BrowseResult, referencesSize) - offsetof(UA_BrowseResult, continuationPoint) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ +},}; + +/* AddReferencesRequest */ +static UA_DataTypeMember AddReferencesRequest_members[2] = { +{ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ + true, /* .namespaceZero */ + false /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_RegisterServer2Response, diagnosticInfosSize) - offsetof(UA_RegisterServer2Response, configurationResults) - sizeof(void*), /* .padding */ + UA_TYPENAME("ReferencesToAdd") /* .memberName */ + UA_TYPES_ADDREFERENCESITEM, /* .memberTypeIndex */ + offsetof(UA_AddReferencesRequest, referencesToAddSize) - offsetof(UA_AddReferencesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; /* AddNodesItem */ static UA_DataTypeMember AddNodesItem_members[7] = { { - UA_TYPENAME("parentNodeId") /* .memberName */ + UA_TYPENAME("ParentNodeId") /* .memberName */ UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("referenceTypeId") /* .memberName */ + UA_TYPENAME("ReferenceTypeId") /* .memberName */ UA_TYPES_NODEID, /* .memberTypeIndex */ offsetof(UA_AddNodesItem, referenceTypeId) - offsetof(UA_AddNodesItem, parentNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedNewNodeId") /* .memberName */ + UA_TYPENAME("RequestedNewNodeId") /* .memberName */ UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ offsetof(UA_AddNodesItem, requestedNewNodeId) - offsetof(UA_AddNodesItem, referenceTypeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("browseName") /* .memberName */ + UA_TYPENAME("BrowseName") /* .memberName */ UA_TYPES_QUALIFIEDNAME, /* .memberTypeIndex */ offsetof(UA_AddNodesItem, browseName) - offsetof(UA_AddNodesItem, requestedNewNodeId) - sizeof(UA_ExpandedNodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodeClass") /* .memberName */ + UA_TYPENAME("NodeClass") /* .memberName */ UA_TYPES_NODECLASS, /* .memberTypeIndex */ offsetof(UA_AddNodesItem, nodeClass) - offsetof(UA_AddNodesItem, browseName) - sizeof(UA_QualifiedName), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodeAttributes") /* .memberName */ + UA_TYPENAME("NodeAttributes") /* .memberName */ UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ offsetof(UA_AddNodesItem, nodeAttributes) - offsetof(UA_AddNodesItem, nodeClass) - sizeof(UA_NodeClass), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("typeDefinition") /* .memberName */ + UA_TYPENAME("TypeDefinition") /* .memberName */ UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ offsetof(UA_AddNodesItem, typeDefinition) - offsetof(UA_AddNodesItem, nodeAttributes) - sizeof(UA_ExtensionObject), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* NodeTypeDescription */ -static UA_DataTypeMember NodeTypeDescription_members[3] = { -{ - UA_TYPENAME("typeDefinitionNode") /* .memberName */ - UA_TYPES_EXPANDEDNODEID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("includeSubTypes") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_NodeTypeDescription, includeSubTypes) - offsetof(UA_NodeTypeDescription, typeDefinitionNode) - sizeof(UA_ExpandedNodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("dataToReturn") /* .memberName */ - UA_TYPES_QUERYDATADESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_NodeTypeDescription, dataToReturnSize) - offsetof(UA_NodeTypeDescription, includeSubTypes) - sizeof(UA_Boolean), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; +},}; /* ServerStatusDataType */ static UA_DataTypeMember ServerStatusDataType_members[6] = { { - UA_TYPENAME("startTime") /* .memberName */ + UA_TYPENAME("StartTime") /* .memberName */ UA_TYPES_DATETIME, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("currentTime") /* .memberName */ + UA_TYPENAME("CurrentTime") /* .memberName */ UA_TYPES_DATETIME, /* .memberTypeIndex */ offsetof(UA_ServerStatusDataType, currentTime) - offsetof(UA_ServerStatusDataType, startTime) - sizeof(UA_DateTime), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("state") /* .memberName */ + UA_TYPENAME("State") /* .memberName */ UA_TYPES_SERVERSTATE, /* .memberTypeIndex */ offsetof(UA_ServerStatusDataType, state) - offsetof(UA_ServerStatusDataType, currentTime) - sizeof(UA_DateTime), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("buildInfo") /* .memberName */ + UA_TYPENAME("BuildInfo") /* .memberName */ UA_TYPES_BUILDINFO, /* .memberTypeIndex */ offsetof(UA_ServerStatusDataType, buildInfo) - offsetof(UA_ServerStatusDataType, state) - sizeof(UA_ServerState), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("secondsTillShutdown") /* .memberName */ + UA_TYPENAME("SecondsTillShutdown") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_ServerStatusDataType, secondsTillShutdown) - offsetof(UA_ServerStatusDataType, buildInfo) - sizeof(UA_BuildInfo), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("shutdownReason") /* .memberName */ + UA_TYPENAME("ShutdownReason") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ offsetof(UA_ServerStatusDataType, shutdownReason) - offsetof(UA_ServerStatusDataType, secondsTillShutdown) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* AttributeOperand */ -static UA_DataTypeMember AttributeOperand_members[5] = { -{ - UA_TYPENAME("nodeId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("alias") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_AttributeOperand, alias) - offsetof(UA_AttributeOperand, nodeId) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("browsePath") /* .memberName */ - UA_TYPES_RELATIVEPATH, /* .memberTypeIndex */ - offsetof(UA_AttributeOperand, browsePath) - offsetof(UA_AttributeOperand, alias) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("attributeId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_AttributeOperand, attributeId) - offsetof(UA_AttributeOperand, browsePath) - sizeof(UA_RelativePath), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("indexRange") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_AttributeOperand, indexRange) - offsetof(UA_AttributeOperand, attributeId) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +},}; -/* AddReferencesResponse */ -static UA_DataTypeMember AddReferencesResponse_members[3] = { +/* BrowseNextResponse */ +static UA_DataTypeMember BrowseNextResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - offsetof(UA_AddReferencesResponse, resultsSize) - offsetof(UA_AddReferencesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_AddReferencesResponse, diagnosticInfosSize) - offsetof(UA_AddReferencesResponse, results) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* EventFilterResult */ -static UA_DataTypeMember EventFilterResult_members[3] = { -{ - UA_TYPENAME("selectClauseResults") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_BROWSERESULT, /* .memberTypeIndex */ + offsetof(UA_BrowseNextResponse, resultsSize) - offsetof(UA_BrowseNextResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("selectClauseDiagnosticInfos") /* .memberName */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_EventFilterResult, selectClauseDiagnosticInfosSize) - offsetof(UA_EventFilterResult, selectClauseResults) - sizeof(void*), /* .padding */ + offsetof(UA_BrowseNextResponse, diagnosticInfosSize) - offsetof(UA_BrowseNextResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}, -{ - UA_TYPENAME("whereClauseResult") /* .memberName */ - UA_TYPES_CONTENTFILTERRESULT, /* .memberTypeIndex */ - offsetof(UA_EventFilterResult, whereClauseResult) - offsetof(UA_EventFilterResult, selectClauseDiagnosticInfos) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +},}; -/* TranslateBrowsePathsToNodeIdsResponse */ -static UA_DataTypeMember TranslateBrowsePathsToNodeIdsResponse_members[3] = { +/* RegisteredServer */ +static UA_DataTypeMember RegisteredServer_members[8] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ServerUri") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_BROWSEPATHRESULT, /* .memberTypeIndex */ - offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, resultsSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("ProductUri") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_RegisteredServer, productUri) - offsetof(UA_RegisteredServer, serverUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ + false /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, diagnosticInfosSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, results) - sizeof(void*), /* .padding */ + UA_TYPENAME("ServerNames") /* .memberName */ + UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ + offsetof(UA_RegisteredServer, serverNamesSize) - offsetof(UA_RegisteredServer, productUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; - -/* DataChangeFilter */ -static UA_DataTypeMember DataChangeFilter_members[3] = { -{ - UA_TYPENAME("trigger") /* .memberName */ - UA_TYPES_DATACHANGETRIGGER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ }, { - UA_TYPENAME("deadbandType") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_DataChangeFilter, deadbandType) - offsetof(UA_DataChangeFilter, trigger) - sizeof(UA_DataChangeTrigger), /* .padding */ + UA_TYPENAME("ServerType") /* .memberName */ + UA_TYPES_APPLICATIONTYPE, /* .memberTypeIndex */ + offsetof(UA_RegisteredServer, serverType) - offsetof(UA_RegisteredServer, serverNames) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("deadbandValue") /* .memberName */ - UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_DataChangeFilter, deadbandValue) - offsetof(UA_DataChangeFilter, deadbandType) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* ContentFilterElement */ -static UA_DataTypeMember ContentFilterElement_members[2] = { -{ - UA_TYPENAME("filterOperator") /* .memberName */ - UA_TYPES_FILTEROPERATOR, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("GatewayServerUri") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_RegisteredServer, gatewayServerUri) - offsetof(UA_RegisteredServer, serverType) - sizeof(UA_ApplicationType), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("filterOperands") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_ContentFilterElement, filterOperandsSize) - offsetof(UA_ContentFilterElement, filterOperator) - sizeof(UA_FilterOperator), /* .padding */ + UA_TYPENAME("DiscoveryUrls") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_RegisteredServer, discoveryUrlsSize) - offsetof(UA_RegisteredServer, gatewayServerUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; - -/* TranslateBrowsePathsToNodeIdsRequest */ -static UA_DataTypeMember TranslateBrowsePathsToNodeIdsRequest_members[2] = { +}, { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("SemaphoreFilePath") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_RegisteredServer, semaphoreFilePath) - offsetof(UA_RegisteredServer, discoveryUrls) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("browsePaths") /* .memberName */ - UA_TYPES_BROWSEPATH, /* .memberTypeIndex */ - offsetof(UA_TranslateBrowsePathsToNodeIdsRequest, browsePathsSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* CloseSessionResponse */ -static UA_DataTypeMember CloseSessionResponse_members[1] = { -{ - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("IsOnline") /* .memberName */ + UA_TYPES_BOOLEAN, /* .memberTypeIndex */ + offsetof(UA_RegisteredServer, isOnline) - offsetof(UA_RegisteredServer, semaphoreFilePath) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* ApplicationDescription */ static UA_DataTypeMember ApplicationDescription_members[7] = { { - UA_TYPENAME("applicationUri") /* .memberName */ + UA_TYPENAME("ApplicationUri") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("productUri") /* .memberName */ + UA_TYPENAME("ProductUri") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_ApplicationDescription, productUri) - offsetof(UA_ApplicationDescription, applicationUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("applicationName") /* .memberName */ + UA_TYPENAME("ApplicationName") /* .memberName */ UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ offsetof(UA_ApplicationDescription, applicationName) - offsetof(UA_ApplicationDescription, productUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("applicationType") /* .memberName */ + UA_TYPENAME("ApplicationType") /* .memberName */ UA_TYPES_APPLICATIONTYPE, /* .memberTypeIndex */ offsetof(UA_ApplicationDescription, applicationType) - offsetof(UA_ApplicationDescription, applicationName) - sizeof(UA_LocalizedText), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("gatewayServerUri") /* .memberName */ + UA_TYPENAME("GatewayServerUri") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_ApplicationDescription, gatewayServerUri) - offsetof(UA_ApplicationDescription, applicationType) - sizeof(UA_ApplicationType), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("discoveryProfileUri") /* .memberName */ + UA_TYPENAME("DiscoveryProfileUri") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_ApplicationDescription, discoveryProfileUri) - offsetof(UA_ApplicationDescription, gatewayServerUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("discoveryUrls") /* .memberName */ + UA_TYPENAME("DiscoveryUrls") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_ApplicationDescription, discoveryUrlsSize) - offsetof(UA_ApplicationDescription, discoveryProfileUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* SessionDiagnosticsDataType */ -static UA_DataTypeMember SessionDiagnosticsDataType_members[43] = { +/* ReadRequest */ +static UA_DataTypeMember ReadRequest_members[4] = { { - UA_TYPENAME("sessionId") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("sessionName") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, sessionName) - offsetof(UA_SessionDiagnosticsDataType, sessionId) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("clientDescription") /* .memberName */ - UA_TYPES_APPLICATIONDESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, clientDescription) - offsetof(UA_SessionDiagnosticsDataType, sessionName) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("serverUri") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, serverUri) - offsetof(UA_SessionDiagnosticsDataType, clientDescription) - sizeof(UA_ApplicationDescription), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("endpointUrl") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, endpointUrl) - offsetof(UA_SessionDiagnosticsDataType, serverUri) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("localeIds") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, localeIdsSize) - offsetof(UA_SessionDiagnosticsDataType, endpointUrl) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("actualSessionTimeout") /* .memberName */ + UA_TYPENAME("MaxAge") /* .memberName */ UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, actualSessionTimeout) - offsetof(UA_SessionDiagnosticsDataType, localeIds) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("maxResponseMessageSize") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, maxResponseMessageSize) - offsetof(UA_SessionDiagnosticsDataType, actualSessionTimeout) - sizeof(UA_Double), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("clientConnectionTime") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, clientConnectionTime) - offsetof(UA_SessionDiagnosticsDataType, maxResponseMessageSize) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("clientLastContactTime") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, clientLastContactTime) - offsetof(UA_SessionDiagnosticsDataType, clientConnectionTime) - sizeof(UA_DateTime), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("currentSubscriptionsCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, currentSubscriptionsCount) - offsetof(UA_SessionDiagnosticsDataType, clientLastContactTime) - sizeof(UA_DateTime), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("currentMonitoredItemsCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, currentMonitoredItemsCount) - offsetof(UA_SessionDiagnosticsDataType, currentSubscriptionsCount) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("currentPublishRequestsInQueue") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, currentPublishRequestsInQueue) - offsetof(UA_SessionDiagnosticsDataType, currentMonitoredItemsCount) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("totalRequestCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, totalRequestCount) - offsetof(UA_SessionDiagnosticsDataType, currentPublishRequestsInQueue) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("unauthorizedRequestCount") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, unauthorizedRequestCount) - offsetof(UA_SessionDiagnosticsDataType, totalRequestCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("readCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, readCount) - offsetof(UA_SessionDiagnosticsDataType, unauthorizedRequestCount) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("historyReadCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, historyReadCount) - offsetof(UA_SessionDiagnosticsDataType, readCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("writeCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, writeCount) - offsetof(UA_SessionDiagnosticsDataType, historyReadCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("historyUpdateCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, historyUpdateCount) - offsetof(UA_SessionDiagnosticsDataType, writeCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + offsetof(UA_ReadRequest, maxAge) - offsetof(UA_ReadRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("callCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, callCount) - offsetof(UA_SessionDiagnosticsDataType, historyUpdateCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("TimestampsToReturn") /* .memberName */ + UA_TYPES_TIMESTAMPSTORETURN, /* .memberTypeIndex */ + offsetof(UA_ReadRequest, timestampsToReturn) - offsetof(UA_ReadRequest, maxAge) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("createMonitoredItemsCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, createMonitoredItemsCount) - offsetof(UA_SessionDiagnosticsDataType, callCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("NodesToRead") /* .memberName */ + UA_TYPES_READVALUEID, /* .memberTypeIndex */ + offsetof(UA_ReadRequest, nodesToReadSize) - offsetof(UA_ReadRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* ActivateSessionRequest */ +static UA_DataTypeMember ActivateSessionRequest_members[6] = { { - UA_TYPENAME("modifyMonitoredItemsCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, modifyMonitoredItemsCount) - offsetof(UA_SessionDiagnosticsDataType, createMonitoredItemsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("setMonitoringModeCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, setMonitoringModeCount) - offsetof(UA_SessionDiagnosticsDataType, modifyMonitoredItemsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("ClientSignature") /* .memberName */ + UA_TYPES_SIGNATUREDATA, /* .memberTypeIndex */ + offsetof(UA_ActivateSessionRequest, clientSignature) - offsetof(UA_ActivateSessionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("setTriggeringCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, setTriggeringCount) - offsetof(UA_SessionDiagnosticsDataType, setMonitoringModeCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("ClientSoftwareCertificates") /* .memberName */ + UA_TYPES_SIGNEDSOFTWARECERTIFICATE, /* .memberTypeIndex */ + offsetof(UA_ActivateSessionRequest, clientSoftwareCertificatesSize) - offsetof(UA_ActivateSessionRequest, clientSignature) - sizeof(UA_SignatureData), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("deleteMonitoredItemsCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, deleteMonitoredItemsCount) - offsetof(UA_SessionDiagnosticsDataType, setTriggeringCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("LocaleIds") /* .memberName */ + UA_TYPES_STRING, /* .memberTypeIndex */ + offsetof(UA_ActivateSessionRequest, localeIdsSize) - offsetof(UA_ActivateSessionRequest, clientSoftwareCertificates) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("createSubscriptionCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, createSubscriptionCount) - offsetof(UA_SessionDiagnosticsDataType, deleteMonitoredItemsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("UserIdentityToken") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_ActivateSessionRequest, userIdentityToken) - offsetof(UA_ActivateSessionRequest, localeIds) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("modifySubscriptionCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, modifySubscriptionCount) - offsetof(UA_SessionDiagnosticsDataType, createSubscriptionCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("UserTokenSignature") /* .memberName */ + UA_TYPES_SIGNATUREDATA, /* .memberTypeIndex */ + offsetof(UA_ActivateSessionRequest, userTokenSignature) - offsetof(UA_ActivateSessionRequest, userIdentityToken) - sizeof(UA_ExtensionObject), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}, +},}; + +/* BrowsePathResult */ +static UA_DataTypeMember BrowsePathResult_members[2] = { { - UA_TYPENAME("setPublishingModeCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, setPublishingModeCount) - offsetof(UA_SessionDiagnosticsDataType, modifySubscriptionCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("StatusCode") /* .memberName */ + UA_TYPES_STATUSCODE, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("publishCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, publishCount) - offsetof(UA_SessionDiagnosticsDataType, setPublishingModeCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("Targets") /* .memberName */ + UA_TYPES_BROWSEPATHTARGET, /* .memberTypeIndex */ + offsetof(UA_BrowsePathResult, targetsSize) - offsetof(UA_BrowsePathResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* AddNodesRequest */ +static UA_DataTypeMember AddNodesRequest_members[2] = { { - UA_TYPENAME("republishCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, republishCount) - offsetof(UA_SessionDiagnosticsDataType, publishCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("transferSubscriptionsCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, transferSubscriptionsCount) - offsetof(UA_SessionDiagnosticsDataType, republishCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("NodesToAdd") /* .memberName */ + UA_TYPES_ADDNODESITEM, /* .memberTypeIndex */ + offsetof(UA_AddNodesRequest, nodesToAddSize) - offsetof(UA_AddNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* BrowseRequest */ +static UA_DataTypeMember BrowseRequest_members[4] = { { - UA_TYPENAME("deleteSubscriptionsCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, deleteSubscriptionsCount) - offsetof(UA_SessionDiagnosticsDataType, transferSubscriptionsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("addNodesCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, addNodesCount) - offsetof(UA_SessionDiagnosticsDataType, deleteSubscriptionsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("View") /* .memberName */ + UA_TYPES_VIEWDESCRIPTION, /* .memberTypeIndex */ + offsetof(UA_BrowseRequest, view) - offsetof(UA_BrowseRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("addReferencesCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, addReferencesCount) - offsetof(UA_SessionDiagnosticsDataType, addNodesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("RequestedMaxReferencesPerNode") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_BrowseRequest, requestedMaxReferencesPerNode) - offsetof(UA_BrowseRequest, view) - sizeof(UA_ViewDescription), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("deleteNodesCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, deleteNodesCount) - offsetof(UA_SessionDiagnosticsDataType, addReferencesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("NodesToBrowse") /* .memberName */ + UA_TYPES_BROWSEDESCRIPTION, /* .memberTypeIndex */ + offsetof(UA_BrowseRequest, nodesToBrowseSize) - offsetof(UA_BrowseRequest, requestedMaxReferencesPerNode) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* WriteRequest */ +static UA_DataTypeMember WriteRequest_members[2] = { { - UA_TYPENAME("deleteReferencesCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, deleteReferencesCount) - offsetof(UA_SessionDiagnosticsDataType, deleteNodesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("browseCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, browseCount) - offsetof(UA_SessionDiagnosticsDataType, deleteReferencesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("NodesToWrite") /* .memberName */ + UA_TYPES_WRITEVALUE, /* .memberTypeIndex */ + offsetof(UA_WriteRequest, nodesToWriteSize) - offsetof(UA_WriteRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* AddNodesResponse */ +static UA_DataTypeMember AddNodesResponse_members[3] = { { - UA_TYPENAME("browseNextCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, browseNextCount) - offsetof(UA_SessionDiagnosticsDataType, browseCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("translateBrowsePathsToNodeIdsCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, translateBrowsePathsToNodeIdsCount) - offsetof(UA_SessionDiagnosticsDataType, browseNextCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_ADDNODESRESULT, /* .memberTypeIndex */ + offsetof(UA_AddNodesResponse, resultsSize) - offsetof(UA_AddNodesResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("queryFirstCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, queryFirstCount) - offsetof(UA_SessionDiagnosticsDataType, translateBrowsePathsToNodeIdsCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ + UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ + offsetof(UA_AddNodesResponse, diagnosticInfosSize) - offsetof(UA_AddNodesResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* RegisterServer2Request */ +static UA_DataTypeMember RegisterServer2Request_members[3] = { { - UA_TYPENAME("queryNextCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, queryNextCount) - offsetof(UA_SessionDiagnosticsDataType, queryFirstCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("registerNodesCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, registerNodesCount) - offsetof(UA_SessionDiagnosticsDataType, queryNextCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ + UA_TYPENAME("Server") /* .memberName */ + UA_TYPES_REGISTEREDSERVER, /* .memberTypeIndex */ + offsetof(UA_RegisterServer2Request, server) - offsetof(UA_RegisterServer2Request, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("unregisterNodesCount") /* .memberName */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .memberTypeIndex */ - offsetof(UA_SessionDiagnosticsDataType, unregisterNodesCount) - offsetof(UA_SessionDiagnosticsDataType, registerNodesCount) - sizeof(UA_ServiceCounterDataType), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* ServiceFault */ -static UA_DataTypeMember ServiceFault_members[1] = { -{ - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ + UA_TYPENAME("DiscoveryConfiguration") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_RegisterServer2Request, discoveryConfigurationSize) - offsetof(UA_RegisterServer2Request, server) - sizeof(UA_RegisteredServer), /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}}; + true /* .isArray */ +},}; -/* RegisteredServer */ -static UA_DataTypeMember RegisteredServer_members[8] = { +/* AttributeOperand */ +static UA_DataTypeMember AttributeOperand_members[5] = { { - UA_TYPENAME("serverUri") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ + UA_TYPENAME("NodeId") /* .memberName */ + UA_TYPES_NODEID, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("productUri") /* .memberName */ + UA_TYPENAME("Alias") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_RegisteredServer, productUri) - offsetof(UA_RegisteredServer, serverUri) - sizeof(UA_String), /* .padding */ + offsetof(UA_AttributeOperand, alias) - offsetof(UA_AttributeOperand, nodeId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverNames") /* .memberName */ - UA_TYPES_LOCALIZEDTEXT, /* .memberTypeIndex */ - offsetof(UA_RegisteredServer, serverNamesSize) - offsetof(UA_RegisteredServer, productUri) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("serverType") /* .memberName */ - UA_TYPES_APPLICATIONTYPE, /* .memberTypeIndex */ - offsetof(UA_RegisteredServer, serverType) - offsetof(UA_RegisteredServer, serverNames) - sizeof(void*), /* .padding */ + UA_TYPENAME("BrowsePath") /* .memberName */ + UA_TYPES_RELATIVEPATH, /* .memberTypeIndex */ + offsetof(UA_AttributeOperand, browsePath) - offsetof(UA_AttributeOperand, alias) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("gatewayServerUri") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_RegisteredServer, gatewayServerUri) - offsetof(UA_RegisteredServer, serverType) - sizeof(UA_ApplicationType), /* .padding */ + UA_TYPENAME("AttributeId") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_AttributeOperand, attributeId) - offsetof(UA_AttributeOperand, browsePath) - sizeof(UA_RelativePath), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("discoveryUrls") /* .memberName */ + UA_TYPENAME("IndexRange") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_RegisteredServer, discoveryUrlsSize) - offsetof(UA_RegisteredServer, gatewayServerUri) - sizeof(UA_String), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("semaphoreFilePath") /* .memberName */ - UA_TYPES_STRING, /* .memberTypeIndex */ - offsetof(UA_RegisteredServer, semaphoreFilePath) - offsetof(UA_RegisteredServer, discoveryUrls) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("isOnline") /* .memberName */ - UA_TYPES_BOOLEAN, /* .memberTypeIndex */ - offsetof(UA_RegisteredServer, isOnline) - offsetof(UA_RegisteredServer, semaphoreFilePath) - sizeof(UA_String), /* .padding */ + offsetof(UA_AttributeOperand, indexRange) - offsetof(UA_AttributeOperand, attributeId) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* AggregateFilter */ -static UA_DataTypeMember AggregateFilter_members[4] = { +/* DataChangeFilter */ +static UA_DataTypeMember DataChangeFilter_members[3] = { { - UA_TYPENAME("startTime") /* .memberName */ - UA_TYPES_DATETIME, /* .memberTypeIndex */ + UA_TYPENAME("Trigger") /* .memberName */ + UA_TYPES_DATACHANGETRIGGER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("aggregateType") /* .memberName */ - UA_TYPES_NODEID, /* .memberTypeIndex */ - offsetof(UA_AggregateFilter, aggregateType) - offsetof(UA_AggregateFilter, startTime) - sizeof(UA_DateTime), /* .padding */ + UA_TYPENAME("DeadbandType") /* .memberName */ + UA_TYPES_UINT32, /* .memberTypeIndex */ + offsetof(UA_DataChangeFilter, deadbandType) - offsetof(UA_DataChangeFilter, trigger) - sizeof(UA_DataChangeTrigger), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("processingInterval") /* .memberName */ + UA_TYPENAME("DeadbandValue") /* .memberName */ UA_TYPES_DOUBLE, /* .memberTypeIndex */ - offsetof(UA_AggregateFilter, processingInterval) - offsetof(UA_AggregateFilter, aggregateType) - sizeof(UA_NodeId), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("aggregateConfiguration") /* .memberName */ - UA_TYPES_AGGREGATECONFIGURATION, /* .memberTypeIndex */ - offsetof(UA_AggregateFilter, aggregateConfiguration) - offsetof(UA_AggregateFilter, processingInterval) - sizeof(UA_Double), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* RegisterServerRequest */ -static UA_DataTypeMember RegisterServerRequest_members[2] = { -{ - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("server") /* .memberName */ - UA_TYPES_REGISTEREDSERVER, /* .memberTypeIndex */ - offsetof(UA_RegisterServerRequest, server) - offsetof(UA_RegisterServerRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + offsetof(UA_DataChangeFilter, deadbandValue) - offsetof(UA_DataChangeFilter, deadbandType) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* EndpointDescription */ static UA_DataTypeMember EndpointDescription_members[8] = { { - UA_TYPENAME("endpointUrl") /* .memberName */ + UA_TYPENAME("EndpointUrl") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("server") /* .memberName */ + UA_TYPENAME("Server") /* .memberName */ UA_TYPES_APPLICATIONDESCRIPTION, /* .memberTypeIndex */ offsetof(UA_EndpointDescription, server) - offsetof(UA_EndpointDescription, endpointUrl) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverCertificate") /* .memberName */ + UA_TYPENAME("ServerCertificate") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ offsetof(UA_EndpointDescription, serverCertificate) - offsetof(UA_EndpointDescription, server) - sizeof(UA_ApplicationDescription), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("securityMode") /* .memberName */ + UA_TYPENAME("SecurityMode") /* .memberName */ UA_TYPES_MESSAGESECURITYMODE, /* .memberTypeIndex */ offsetof(UA_EndpointDescription, securityMode) - offsetof(UA_EndpointDescription, serverCertificate) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("securityPolicyUri") /* .memberName */ + UA_TYPENAME("SecurityPolicyUri") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_EndpointDescription, securityPolicyUri) - offsetof(UA_EndpointDescription, securityMode) - sizeof(UA_MessageSecurityMode), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("userIdentityTokens") /* .memberName */ + UA_TYPENAME("UserIdentityTokens") /* .memberName */ UA_TYPES_USERTOKENPOLICY, /* .memberTypeIndex */ offsetof(UA_EndpointDescription, userIdentityTokensSize) - offsetof(UA_EndpointDescription, securityPolicyUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("transportProfileUri") /* .memberName */ + UA_TYPENAME("TransportProfileUri") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_EndpointDescription, transportProfileUri) - offsetof(UA_EndpointDescription, userIdentityTokens) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("securityLevel") /* .memberName */ + UA_TYPENAME("SecurityLevel") /* .memberName */ UA_TYPES_BYTE, /* .memberTypeIndex */ offsetof(UA_EndpointDescription, securityLevel) - offsetof(UA_EndpointDescription, transportProfileUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; - -/* CreateMonitoredItemsRequest */ -static UA_DataTypeMember CreateMonitoredItemsRequest_members[4] = { -{ - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("subscriptionId") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_CreateMonitoredItemsRequest, subscriptionId) - offsetof(UA_CreateMonitoredItemsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("timestampsToReturn") /* .memberName */ - UA_TYPES_TIMESTAMPSTORETURN, /* .memberTypeIndex */ - offsetof(UA_CreateMonitoredItemsRequest, timestampsToReturn) - offsetof(UA_CreateMonitoredItemsRequest, subscriptionId) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("itemsToCreate") /* .memberName */ - UA_TYPES_MONITOREDITEMCREATEREQUEST, /* .memberTypeIndex */ - offsetof(UA_CreateMonitoredItemsRequest, itemsToCreateSize) - offsetof(UA_CreateMonitoredItemsRequest, timestampsToReturn) - sizeof(UA_TimestampsToReturn), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* ContentFilter */ -static UA_DataTypeMember ContentFilter_members[1] = { -{ - UA_TYPENAME("elements") /* .memberName */ - UA_TYPES_CONTENTFILTERELEMENT, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* QueryFirstResponse */ -static UA_DataTypeMember QueryFirstResponse_members[6] = { -{ - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("queryDataSets") /* .memberName */ - UA_TYPES_QUERYDATASET, /* .memberTypeIndex */ - offsetof(UA_QueryFirstResponse, queryDataSetsSize) - offsetof(UA_QueryFirstResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("continuationPoint") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_QueryFirstResponse, continuationPoint) - offsetof(UA_QueryFirstResponse, queryDataSets) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("parsingResults") /* .memberName */ - UA_TYPES_PARSINGRESULT, /* .memberTypeIndex */ - offsetof(UA_QueryFirstResponse, parsingResultsSize) - offsetof(UA_QueryFirstResponse, continuationPoint) - sizeof(UA_ByteString), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("diagnosticInfos") /* .memberName */ - UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_QueryFirstResponse, diagnosticInfosSize) - offsetof(UA_QueryFirstResponse, parsingResults) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("filterResult") /* .memberName */ - UA_TYPES_CONTENTFILTERRESULT, /* .memberTypeIndex */ - offsetof(UA_QueryFirstResponse, filterResult) - offsetof(UA_QueryFirstResponse, diagnosticInfos) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +},}; -/* AddNodesRequest */ -static UA_DataTypeMember AddNodesRequest_members[2] = { +/* DeleteReferencesRequest */ +static UA_DataTypeMember DeleteReferencesRequest_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodesToAdd") /* .memberName */ - UA_TYPES_ADDNODESITEM, /* .memberTypeIndex */ - offsetof(UA_AddNodesRequest, nodesToAddSize) - offsetof(UA_AddNodesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("ReferencesToDelete") /* .memberName */ + UA_TYPES_DELETEREFERENCESITEM, /* .memberTypeIndex */ + offsetof(UA_DeleteReferencesRequest, referencesToDeleteSize) - offsetof(UA_DeleteReferencesRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* BrowseRequest */ -static UA_DataTypeMember BrowseRequest_members[4] = { +/* TranslateBrowsePathsToNodeIdsRequest */ +static UA_DataTypeMember TranslateBrowsePathsToNodeIdsRequest_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("view") /* .memberName */ - UA_TYPES_VIEWDESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_BrowseRequest, view) - offsetof(UA_BrowseRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("requestedMaxReferencesPerNode") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_BrowseRequest, requestedMaxReferencesPerNode) - offsetof(UA_BrowseRequest, view) - sizeof(UA_ViewDescription), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("nodesToBrowse") /* .memberName */ - UA_TYPES_BROWSEDESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_BrowseRequest, nodesToBrowseSize) - offsetof(UA_BrowseRequest, requestedMaxReferencesPerNode) - sizeof(UA_UInt32), /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}}; - -/* BrowseResult */ -static UA_DataTypeMember BrowseResult_members[3] = { -{ - UA_TYPENAME("statusCode") /* .memberName */ - UA_TYPES_STATUSCODE, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("continuationPoint") /* .memberName */ - UA_TYPES_BYTESTRING, /* .memberTypeIndex */ - offsetof(UA_BrowseResult, continuationPoint) - offsetof(UA_BrowseResult, statusCode) - sizeof(UA_StatusCode), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("references") /* .memberName */ - UA_TYPES_REFERENCEDESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_BrowseResult, referencesSize) - offsetof(UA_BrowseResult, continuationPoint) - sizeof(UA_ByteString), /* .padding */ + UA_TYPENAME("BrowsePaths") /* .memberName */ + UA_TYPES_BROWSEPATH, /* .memberTypeIndex */ + offsetof(UA_TranslateBrowsePathsToNodeIdsRequest, browsePathsSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* RegisterServer2Request */ -static UA_DataTypeMember RegisterServer2Request_members[3] = { +/* FindServersResponse */ +static UA_DataTypeMember FindServersResponse_members[2] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("server") /* .memberName */ - UA_TYPES_REGISTEREDSERVER, /* .memberTypeIndex */ - offsetof(UA_RegisterServer2Request, server) - offsetof(UA_RegisterServer2Request, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, -{ - UA_TYPENAME("discoveryConfiguration") /* .memberName */ - UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ - offsetof(UA_RegisterServer2Request, discoveryConfigurationSize) - offsetof(UA_RegisterServer2Request, server) - sizeof(UA_RegisteredServer), /* .padding */ + UA_TYPENAME("Servers") /* .memberName */ + UA_TYPES_APPLICATIONDESCRIPTION, /* .memberTypeIndex */ + offsetof(UA_FindServersResponse, serversSize) - offsetof(UA_FindServersResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; /* CreateSessionRequest */ static UA_DataTypeMember CreateSessionRequest_members[9] = { { - UA_TYPENAME("requestHeader") /* .memberName */ + UA_TYPENAME("RequestHeader") /* .memberName */ UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientDescription") /* .memberName */ + UA_TYPENAME("ClientDescription") /* .memberName */ UA_TYPES_APPLICATIONDESCRIPTION, /* .memberTypeIndex */ offsetof(UA_CreateSessionRequest, clientDescription) - offsetof(UA_CreateSessionRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverUri") /* .memberName */ + UA_TYPENAME("ServerUri") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_CreateSessionRequest, serverUri) - offsetof(UA_CreateSessionRequest, clientDescription) - sizeof(UA_ApplicationDescription), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("endpointUrl") /* .memberName */ + UA_TYPENAME("EndpointUrl") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_CreateSessionRequest, endpointUrl) - offsetof(UA_CreateSessionRequest, serverUri) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("sessionName") /* .memberName */ + UA_TYPENAME("SessionName") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_CreateSessionRequest, sessionName) - offsetof(UA_CreateSessionRequest, endpointUrl) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientNonce") /* .memberName */ + UA_TYPENAME("ClientNonce") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ offsetof(UA_CreateSessionRequest, clientNonce) - offsetof(UA_CreateSessionRequest, sessionName) - sizeof(UA_String), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("clientCertificate") /* .memberName */ + UA_TYPENAME("ClientCertificate") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ offsetof(UA_CreateSessionRequest, clientCertificate) - offsetof(UA_CreateSessionRequest, clientNonce) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestedSessionTimeout") /* .memberName */ + UA_TYPENAME("RequestedSessionTimeout") /* .memberName */ UA_TYPES_DOUBLE, /* .memberTypeIndex */ offsetof(UA_CreateSessionRequest, requestedSessionTimeout) - offsetof(UA_CreateSessionRequest, clientCertificate) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxResponseMessageSize") /* .memberName */ + UA_TYPENAME("MaxResponseMessageSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_CreateSessionRequest, maxResponseMessageSize) - offsetof(UA_CreateSessionRequest, requestedSessionTimeout) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* EventFilter */ -static UA_DataTypeMember EventFilter_members[2] = { -{ - UA_TYPENAME("selectClauses") /* .memberName */ - UA_TYPES_SIMPLEATTRIBUTEOPERAND, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - true /* .isArray */ -}, -{ - UA_TYPENAME("whereClause") /* .memberName */ - UA_TYPES_CONTENTFILTER, /* .memberTypeIndex */ - offsetof(UA_EventFilter, whereClause) - offsetof(UA_EventFilter, selectClauses) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; - -/* GetEndpointsResponse */ -static UA_DataTypeMember GetEndpointsResponse_members[2] = { +/* ContentFilterElement */ +static UA_DataTypeMember ContentFilterElement_members[2] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("FilterOperator") /* .memberName */ + UA_TYPES_FILTEROPERATOR, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("endpoints") /* .memberName */ - UA_TYPES_ENDPOINTDESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_GetEndpointsResponse, endpointsSize) - offsetof(UA_GetEndpointsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("FilterOperands") /* .memberName */ + UA_TYPES_EXTENSIONOBJECT, /* .memberTypeIndex */ + offsetof(UA_ContentFilterElement, filterOperandsSize) - offsetof(UA_ContentFilterElement, filterOperator) - sizeof(UA_FilterOperator), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; -/* FindServersResponse */ -static UA_DataTypeMember FindServersResponse_members[2] = { +/* RegisterServerRequest */ +static UA_DataTypeMember RegisterServerRequest_members[2] = { { - UA_TYPENAME("responseHeader") /* .memberName */ - UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + UA_TYPENAME("RequestHeader") /* .memberName */ + UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("servers") /* .memberName */ - UA_TYPES_APPLICATIONDESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_FindServersResponse, serversSize) - offsetof(UA_FindServersResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("Server") /* .memberName */ + UA_TYPES_REGISTEREDSERVER, /* .memberTypeIndex */ + offsetof(UA_RegisterServerRequest, server) - offsetof(UA_RegisterServerRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ true, /* .namespaceZero */ - true /* .isArray */ -}}; + false /* .isArray */ +},}; -/* BrowseNextResponse */ -static UA_DataTypeMember BrowseNextResponse_members[3] = { +/* TranslateBrowsePathsToNodeIdsResponse */ +static UA_DataTypeMember TranslateBrowsePathsToNodeIdsResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ - UA_TYPES_BROWSERESULT, /* .memberTypeIndex */ - offsetof(UA_BrowseNextResponse, resultsSize) - offsetof(UA_BrowseNextResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ + UA_TYPENAME("Results") /* .memberName */ + UA_TYPES_BROWSEPATHRESULT, /* .memberTypeIndex */ + offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, resultsSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ - offsetof(UA_BrowseNextResponse, diagnosticInfosSize) - offsetof(UA_BrowseNextResponse, results) - sizeof(void*), /* .padding */ + offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, diagnosticInfosSize) - offsetof(UA_TranslateBrowsePathsToNodeIdsResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; /* BrowseResponse */ static UA_DataTypeMember BrowseResponse_members[3] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("results") /* .memberName */ + UA_TYPENAME("Results") /* .memberName */ UA_TYPES_BROWSERESULT, /* .memberTypeIndex */ offsetof(UA_BrowseResponse, resultsSize) - offsetof(UA_BrowseResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("diagnosticInfos") /* .memberName */ + UA_TYPENAME("DiagnosticInfos") /* .memberName */ UA_TYPES_DIAGNOSTICINFO, /* .memberTypeIndex */ offsetof(UA_BrowseResponse, diagnosticInfosSize) - offsetof(UA_BrowseResponse, results) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}}; +},}; /* CreateSessionResponse */ static UA_DataTypeMember CreateSessionResponse_members[10] = { { - UA_TYPENAME("responseHeader") /* .memberName */ + UA_TYPENAME("ResponseHeader") /* .memberName */ UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("sessionId") /* .memberName */ + UA_TYPENAME("SessionId") /* .memberName */ UA_TYPES_NODEID, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, sessionId) - offsetof(UA_CreateSessionResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("authenticationToken") /* .memberName */ + UA_TYPENAME("AuthenticationToken") /* .memberName */ UA_TYPES_NODEID, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, authenticationToken) - offsetof(UA_CreateSessionResponse, sessionId) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("revisedSessionTimeout") /* .memberName */ + UA_TYPENAME("RevisedSessionTimeout") /* .memberName */ UA_TYPES_DOUBLE, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, revisedSessionTimeout) - offsetof(UA_CreateSessionResponse, authenticationToken) - sizeof(UA_NodeId), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverNonce") /* .memberName */ + UA_TYPENAME("ServerNonce") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, serverNonce) - offsetof(UA_CreateSessionResponse, revisedSessionTimeout) - sizeof(UA_Double), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverCertificate") /* .memberName */ + UA_TYPENAME("ServerCertificate") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, serverCertificate) - offsetof(UA_CreateSessionResponse, serverNonce) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("serverEndpoints") /* .memberName */ + UA_TYPENAME("ServerEndpoints") /* .memberName */ UA_TYPES_ENDPOINTDESCRIPTION, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, serverEndpointsSize) - offsetof(UA_CreateSessionResponse, serverCertificate) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("serverSoftwareCertificates") /* .memberName */ + UA_TYPENAME("ServerSoftwareCertificates") /* .memberName */ UA_TYPES_SIGNEDSOFTWARECERTIFICATE, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, serverSoftwareCertificatesSize) - offsetof(UA_CreateSessionResponse, serverEndpoints) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("serverSignature") /* .memberName */ + UA_TYPENAME("ServerSignature") /* .memberName */ UA_TYPES_SIGNATUREDATA, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, serverSignature) - offsetof(UA_CreateSessionResponse, serverSoftwareCertificates) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxRequestMessageSize") /* .memberName */ + UA_TYPENAME("MaxRequestMessageSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_CreateSessionResponse, maxRequestMessageSize) - offsetof(UA_CreateSessionResponse, serverSignature) - sizeof(UA_SignatureData), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; -/* QueryFirstRequest */ -static UA_DataTypeMember QueryFirstRequest_members[6] = { +/* ContentFilter */ +static UA_DataTypeMember ContentFilter_members[1] = { { - UA_TYPENAME("requestHeader") /* .memberName */ - UA_TYPES_REQUESTHEADER, /* .memberTypeIndex */ + UA_TYPENAME("Elements") /* .memberName */ + UA_TYPES_CONTENTFILTERELEMENT, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ -}, + true /* .isArray */ +},}; + +/* GetEndpointsResponse */ +static UA_DataTypeMember GetEndpointsResponse_members[2] = { { - UA_TYPENAME("view") /* .memberName */ - UA_TYPES_VIEWDESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_QueryFirstRequest, view) - offsetof(UA_QueryFirstRequest, requestHeader) - sizeof(UA_RequestHeader), /* .padding */ + UA_TYPENAME("ResponseHeader") /* .memberName */ + UA_TYPES_RESPONSEHEADER, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("nodeTypes") /* .memberName */ - UA_TYPES_NODETYPEDESCRIPTION, /* .memberTypeIndex */ - offsetof(UA_QueryFirstRequest, nodeTypesSize) - offsetof(UA_QueryFirstRequest, view) - sizeof(UA_ViewDescription), /* .padding */ + UA_TYPENAME("Endpoints") /* .memberName */ + UA_TYPES_ENDPOINTDESCRIPTION, /* .memberTypeIndex */ + offsetof(UA_GetEndpointsResponse, endpointsSize) - offsetof(UA_GetEndpointsResponse, responseHeader) - sizeof(UA_ResponseHeader), /* .padding */ true, /* .namespaceZero */ true /* .isArray */ -}, -{ - UA_TYPENAME("filter") /* .memberName */ - UA_TYPES_CONTENTFILTER, /* .memberTypeIndex */ - offsetof(UA_QueryFirstRequest, filter) - offsetof(UA_QueryFirstRequest, nodeTypes) - sizeof(void*), /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}, +},}; + +/* EventFilter */ +static UA_DataTypeMember EventFilter_members[2] = { { - UA_TYPENAME("maxDataSetsToReturn") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_QueryFirstRequest, maxDataSetsToReturn) - offsetof(UA_QueryFirstRequest, filter) - sizeof(UA_ContentFilter), /* .padding */ + UA_TYPENAME("SelectClauses") /* .memberName */ + UA_TYPES_SIMPLEATTRIBUTEOPERAND, /* .memberTypeIndex */ + 0, /* .padding */ true, /* .namespaceZero */ - false /* .isArray */ + true /* .isArray */ }, { - UA_TYPENAME("maxReferencesToReturn") /* .memberName */ - UA_TYPES_UINT32, /* .memberTypeIndex */ - offsetof(UA_QueryFirstRequest, maxReferencesToReturn) - offsetof(UA_QueryFirstRequest, maxDataSetsToReturn) - sizeof(UA_UInt32), /* .padding */ + UA_TYPENAME("WhereClause") /* .memberName */ + UA_TYPES_CONTENTFILTER, /* .memberTypeIndex */ + offsetof(UA_EventFilter, whereClause) - offsetof(UA_EventFilter, selectClauses) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { /* Boolean */ { @@ -13902,10 +14698,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {1}}, /* .typeId */ sizeof(UA_Boolean), /* .memSize */ UA_TYPES_BOOLEAN, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_BOOLEAN, /* .typeKind */ true, /* .pointerFree */ true, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Boolean_members /* .members */ }, @@ -13915,10 +14711,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {2}}, /* .typeId */ sizeof(UA_SByte), /* .memSize */ UA_TYPES_SBYTE, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_SBYTE, /* .typeKind */ true, /* .pointerFree */ true, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ SByte_members /* .members */ }, @@ -13928,10 +14724,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {3}}, /* .typeId */ sizeof(UA_Byte), /* .memSize */ UA_TYPES_BYTE, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_BYTE, /* .typeKind */ true, /* .pointerFree */ true, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Byte_members /* .members */ }, @@ -13941,10 +14737,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {4}}, /* .typeId */ sizeof(UA_Int16), /* .memSize */ UA_TYPES_INT16, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_INT16, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Int16_members /* .members */ }, @@ -13954,10 +14750,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {5}}, /* .typeId */ sizeof(UA_UInt16), /* .memSize */ UA_TYPES_UINT16, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_UINT16, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ UInt16_members /* .members */ }, @@ -13967,10 +14763,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {6}}, /* .typeId */ sizeof(UA_Int32), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_INT32, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Int32_members /* .members */ }, @@ -13980,10 +14776,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {7}}, /* .typeId */ sizeof(UA_UInt32), /* .memSize */ UA_TYPES_UINT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_UINT32, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ UInt32_members /* .members */ }, @@ -13993,10 +14789,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {8}}, /* .typeId */ sizeof(UA_Int64), /* .memSize */ UA_TYPES_INT64, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_INT64, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Int64_members /* .members */ }, @@ -14006,10 +14802,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {9}}, /* .typeId */ sizeof(UA_UInt64), /* .memSize */ UA_TYPES_UINT64, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_UINT64, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ UInt64_members /* .members */ }, @@ -14019,10 +14815,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {10}}, /* .typeId */ sizeof(UA_Float), /* .memSize */ UA_TYPES_FLOAT, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_FLOAT, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_FLOAT, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Float_members /* .members */ }, @@ -14032,10 +14828,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {11}}, /* .typeId */ sizeof(UA_Double), /* .memSize */ UA_TYPES_DOUBLE, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_DOUBLE, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_FLOAT, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Double_members /* .members */ }, @@ -14045,10 +14841,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {12}}, /* .typeId */ sizeof(UA_String), /* .memSize */ UA_TYPES_STRING, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_STRING, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ String_members /* .members */ }, @@ -14058,10 +14854,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {13}}, /* .typeId */ sizeof(UA_DateTime), /* .memSize */ UA_TYPES_DATETIME, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_DATETIME, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ DateTime_members /* .members */ }, @@ -14071,10 +14867,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {14}}, /* .typeId */ sizeof(UA_Guid), /* .memSize */ UA_TYPES_GUID, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_GUID, /* .typeKind */ true, /* .pointerFree */ (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 */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Guid_members /* .members */ }, @@ -14084,10 +14880,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {15}}, /* .typeId */ sizeof(UA_ByteString), /* .memSize */ UA_TYPES_BYTESTRING, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_BYTESTRING, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ ByteString_members /* .members */ }, @@ -14097,10 +14893,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {16}}, /* .typeId */ sizeof(UA_XmlElement), /* .memSize */ UA_TYPES_XMLELEMENT, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_XMLELEMENT, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ XmlElement_members /* .members */ }, @@ -14110,10 +14906,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {17}}, /* .typeId */ sizeof(UA_NodeId), /* .memSize */ UA_TYPES_NODEID, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_NODEID, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ NodeId_members /* .members */ }, @@ -14123,10 +14919,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {18}}, /* .typeId */ sizeof(UA_ExpandedNodeId), /* .memSize */ UA_TYPES_EXPANDEDNODEID, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_EXPANDEDNODEID, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ ExpandedNodeId_members /* .members */ }, @@ -14136,10 +14932,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {19}}, /* .typeId */ sizeof(UA_StatusCode), /* .memSize */ UA_TYPES_STATUSCODE, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_STATUSCODE, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ StatusCode_members /* .members */ }, @@ -14149,10 +14945,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {20}}, /* .typeId */ sizeof(UA_QualifiedName), /* .memSize */ UA_TYPES_QUALIFIEDNAME, /* .typeIndex */ - 2, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_QUALIFIEDNAME, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ QualifiedName_members /* .members */ }, @@ -14162,10 +14958,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {21}}, /* .typeId */ sizeof(UA_LocalizedText), /* .memSize */ UA_TYPES_LOCALIZEDTEXT, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_LOCALIZEDTEXT, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ LocalizedText_members /* .members */ }, @@ -14175,10 +14971,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {22}}, /* .typeId */ sizeof(UA_ExtensionObject), /* .memSize */ UA_TYPES_EXTENSIONOBJECT, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_EXTENSIONOBJECT, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ ExtensionObject_members /* .members */ }, @@ -14188,10 +14984,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {23}}, /* .typeId */ sizeof(UA_DataValue), /* .memSize */ UA_TYPES_DATAVALUE, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_DATAVALUE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ DataValue_members /* .members */ }, @@ -14201,10 +14997,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {24}}, /* .typeId */ sizeof(UA_Variant), /* .memSize */ UA_TYPES_VARIANT, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_VARIANT, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ Variant_members /* .members */ }, @@ -14214,195 +15010,309 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {25}}, /* .typeId */ sizeof(UA_DiagnosticInfo), /* .memSize */ UA_TYPES_DIAGNOSTICINFO, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_DIAGNOSTICINFO, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ DiagnosticInfo_members /* .members */ }, -/* SignedSoftwareCertificate */ +/* ViewAttributes */ { - UA_TYPENAME("SignedSoftwareCertificate") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {344}}, /* .typeId */ - sizeof(UA_SignedSoftwareCertificate), /* .memSize */ - UA_TYPES_SIGNEDSOFTWARECERTIFICATE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ViewAttributes") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {373}}, /* .typeId */ + sizeof(UA_ViewAttributes), /* .memSize */ + UA_TYPES_VIEWATTRIBUTES, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 346, /* .binaryEncodingId */ - SignedSoftwareCertificate_members /* .members */ + 7, /* .membersSize */ + 375, /* .binaryEncodingId */ + ViewAttributes_members /* .members */ }, -/* SemanticChangeStructureDataType */ +/* ElementOperand */ { - UA_TYPENAME("SemanticChangeStructureDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {897}}, /* .typeId */ - sizeof(UA_SemanticChangeStructureDataType), /* .memSize */ - UA_TYPES_SEMANTICCHANGESTRUCTUREDATATYPE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ElementOperand") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {592}}, /* .typeId */ + sizeof(UA_ElementOperand), /* .memSize */ + UA_TYPES_ELEMENTOPERAND, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + true, /* .pointerFree */ + true + && UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 1, /* .membersSize */ + 594, /* .binaryEncodingId */ + ElementOperand_members /* .members */ +}, +/* VariableAttributes */ +{ + UA_TYPENAME("VariableAttributes") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {355}}, /* .typeId */ + sizeof(UA_VariableAttributes), /* .memSize */ + UA_TYPES_VARIABLEATTRIBUTES, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 899, /* .binaryEncodingId */ - SemanticChangeStructureDataType_members /* .members */ + 13, /* .membersSize */ + 357, /* .binaryEncodingId */ + VariableAttributes_members /* .members */ }, -/* StatusChangeNotification */ +/* EnumValueType */ { - UA_TYPENAME("StatusChangeNotification") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {818}}, /* .typeId */ - sizeof(UA_StatusChangeNotification), /* .memSize */ - UA_TYPES_STATUSCHANGENOTIFICATION, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("EnumValueType") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {7594}}, /* .typeId */ + sizeof(UA_EnumValueType), /* .memSize */ + UA_TYPES_ENUMVALUETYPE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 820, /* .binaryEncodingId */ - StatusChangeNotification_members /* .members */ + 3, /* .membersSize */ + 8251, /* .binaryEncodingId */ + EnumValueType_members /* .members */ }, -/* BrowsePathTarget */ +/* EventFieldList */ { - UA_TYPENAME("BrowsePathTarget") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {546}}, /* .typeId */ - sizeof(UA_BrowsePathTarget), /* .memSize */ - UA_TYPES_BROWSEPATHTARGET, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("EventFieldList") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {917}}, /* .typeId */ + sizeof(UA_EventFieldList), /* .memSize */ + UA_TYPES_EVENTFIELDLIST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 548, /* .binaryEncodingId */ - BrowsePathTarget_members /* .members */ + 2, /* .membersSize */ + 919, /* .binaryEncodingId */ + EventFieldList_members /* .members */ }, -/* ViewAttributes */ +/* MonitoredItemCreateResult */ { - UA_TYPENAME("ViewAttributes") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {373}}, /* .typeId */ - sizeof(UA_ViewAttributes), /* .memSize */ - UA_TYPES_VIEWATTRIBUTES, /* .typeIndex */ - 7, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("MonitoredItemCreateResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {746}}, /* .typeId */ + sizeof(UA_MonitoredItemCreateResult), /* .memSize */ + UA_TYPES_MONITOREDITEMCREATERESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 375, /* .binaryEncodingId */ - ViewAttributes_members /* .members */ + 5, /* .membersSize */ + 748, /* .binaryEncodingId */ + MonitoredItemCreateResult_members /* .members */ }, -/* RequestHeader */ +/* ServerDiagnosticsSummaryDataType */ { - UA_TYPENAME("RequestHeader") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {389}}, /* .typeId */ - sizeof(UA_RequestHeader), /* .memSize */ - UA_TYPES_REQUESTHEADER, /* .typeIndex */ - 7, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ServerDiagnosticsSummaryDataType") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {859}}, /* .typeId */ + sizeof(UA_ServerDiagnosticsSummaryDataType), /* .memSize */ + UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + true, /* .pointerFree */ + true + && UA_BINARY_OVERLAYABLE_INTEGER + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, serverViewCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedRequestsCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) + sizeof(UA_UInt32)), /* .overlayable */ + 12, /* .membersSize */ + 861, /* .binaryEncodingId */ + ServerDiagnosticsSummaryDataType_members /* .members */ +}, +/* ContentFilterElementResult */ +{ + UA_TYPENAME("ContentFilterElementResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {604}}, /* .typeId */ + sizeof(UA_ContentFilterElementResult), /* .memSize */ + UA_TYPES_CONTENTFILTERELEMENTRESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 391, /* .binaryEncodingId */ - RequestHeader_members /* .members */ + 3, /* .membersSize */ + 606, /* .binaryEncodingId */ + ContentFilterElementResult_members /* .members */ }, -/* MonitoredItemModifyResult */ +/* LiteralOperand */ { - UA_TYPENAME("MonitoredItemModifyResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {758}}, /* .typeId */ - sizeof(UA_MonitoredItemModifyResult), /* .memSize */ - UA_TYPES_MONITOREDITEMMODIFYRESULT, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("LiteralOperand") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {595}}, /* .typeId */ + sizeof(UA_LiteralOperand), /* .memSize */ + UA_TYPES_LITERALOPERAND, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 760, /* .binaryEncodingId */ - MonitoredItemModifyResult_members /* .members */ + 1, /* .membersSize */ + 597, /* .binaryEncodingId */ + LiteralOperand_members /* .members */ }, -/* ElementOperand */ +/* MessageSecurityMode */ { - UA_TYPENAME("ElementOperand") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {592}}, /* .typeId */ - sizeof(UA_ElementOperand), /* .memSize */ - UA_TYPES_ELEMENTOPERAND, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("MessageSecurityMode") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {302}}, /* .typeId */ + sizeof(UA_MessageSecurityMode), /* .memSize */ + UA_TYPES_INT32, /* .typeIndex */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ - true - && UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ - 594, /* .binaryEncodingId */ - ElementOperand_members /* .members */ + UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + MessageSecurityMode_members /* .members */ }, -/* CloseSecureChannelRequest */ +/* UtcTime */ { - UA_TYPENAME("CloseSecureChannelRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {450}}, /* .typeId */ - sizeof(UA_CloseSecureChannelRequest), /* .memSize */ - UA_TYPES_CLOSESECURECHANNELREQUEST, /* .typeIndex */ + UA_TYPENAME("UtcTime") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {294}}, /* .typeId */ + sizeof(UA_UtcTime), /* .memSize */ + UA_TYPES_UTCTIME, /* .typeIndex */ + UA_DATATYPEKIND_DATETIME, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + UtcTime_members /* .members */ +}, +/* UserIdentityToken */ +{ + UA_TYPENAME("UserIdentityToken") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {316}}, /* .typeId */ + sizeof(UA_UserIdentityToken), /* .memSize */ + UA_TYPES_USERIDENTITYTOKEN, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 1, /* .membersSize */ - false, /* .builtin */ + 318, /* .binaryEncodingId */ + UserIdentityToken_members /* .members */ +}, +/* X509IdentityToken */ +{ + UA_TYPENAME("X509IdentityToken") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {325}}, /* .typeId */ + sizeof(UA_X509IdentityToken), /* .memSize */ + UA_TYPES_X509IDENTITYTOKEN, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 452, /* .binaryEncodingId */ - CloseSecureChannelRequest_members /* .members */ + 2, /* .membersSize */ + 327, /* .binaryEncodingId */ + X509IdentityToken_members /* .members */ }, -/* AddNodesResult */ +/* MonitoredItemNotification */ { - UA_TYPENAME("AddNodesResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {483}}, /* .typeId */ - sizeof(UA_AddNodesResult), /* .memSize */ - UA_TYPES_ADDNODESRESULT, /* .typeIndex */ + UA_TYPENAME("MonitoredItemNotification") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {806}}, /* .typeId */ + sizeof(UA_MonitoredItemNotification), /* .memSize */ + UA_TYPES_MONITOREDITEMNOTIFICATION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 2, /* .membersSize */ - false, /* .builtin */ + 808, /* .binaryEncodingId */ + MonitoredItemNotification_members /* .members */ +}, +/* ResponseHeader */ +{ + UA_TYPENAME("ResponseHeader") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {392}}, /* .typeId */ + sizeof(UA_ResponseHeader), /* .memSize */ + UA_TYPES_RESPONSEHEADER, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 485, /* .binaryEncodingId */ - AddNodesResult_members /* .members */ + 6, /* .membersSize */ + 394, /* .binaryEncodingId */ + ResponseHeader_members /* .members */ }, -/* VariableAttributes */ +/* SignatureData */ { - UA_TYPENAME("VariableAttributes") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {355}}, /* .typeId */ - sizeof(UA_VariableAttributes), /* .memSize */ - UA_TYPES_VARIABLEATTRIBUTES, /* .typeIndex */ - 13, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("SignatureData") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {456}}, /* .typeId */ + sizeof(UA_SignatureData), /* .memSize */ + UA_TYPES_SIGNATUREDATA, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 357, /* .binaryEncodingId */ - VariableAttributes_members /* .members */ + 2, /* .membersSize */ + 458, /* .binaryEncodingId */ + SignatureData_members /* .members */ }, -/* NotificationMessage */ +/* ModifySubscriptionResponse */ { - UA_TYPENAME("NotificationMessage") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {803}}, /* .typeId */ - sizeof(UA_NotificationMessage), /* .memSize */ - UA_TYPES_NOTIFICATIONMESSAGE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ModifySubscriptionResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {794}}, /* .typeId */ + sizeof(UA_ModifySubscriptionResponse), /* .memSize */ + UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 805, /* .binaryEncodingId */ - NotificationMessage_members /* .members */ + 4, /* .membersSize */ + 796, /* .binaryEncodingId */ + ModifySubscriptionResponse_members /* .members */ }, -/* FindServersOnNetworkRequest */ +/* NodeAttributes */ { - UA_TYPENAME("FindServersOnNetworkRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {12190}}, /* .typeId */ - sizeof(UA_FindServersOnNetworkRequest), /* .memSize */ - UA_TYPES_FINDSERVERSONNETWORKREQUEST, /* .typeIndex */ + UA_TYPENAME("NodeAttributes") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {349}}, /* .typeId */ + sizeof(UA_NodeAttributes), /* .memSize */ + UA_TYPES_NODEATTRIBUTES, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 5, /* .membersSize */ + 351, /* .binaryEncodingId */ + NodeAttributes_members /* .members */ +}, +/* ActivateSessionResponse */ +{ + UA_TYPENAME("ActivateSessionResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {468}}, /* .typeId */ + sizeof(UA_ActivateSessionResponse), /* .memSize */ + UA_TYPES_ACTIVATESESSIONRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 4, /* .membersSize */ - false, /* .builtin */ + 470, /* .binaryEncodingId */ + ActivateSessionResponse_members /* .members */ +}, +/* VariableTypeAttributes */ +{ + UA_TYPENAME("VariableTypeAttributes") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {364}}, /* .typeId */ + sizeof(UA_VariableTypeAttributes), /* .memSize */ + UA_TYPES_VARIABLETYPEATTRIBUTES, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 12208, /* .binaryEncodingId */ - FindServersOnNetworkRequest_members /* .members */ + 10, /* .membersSize */ + 366, /* .binaryEncodingId */ + VariableTypeAttributes_members /* .members */ }, -/* EventFieldList */ +/* CallMethodResult */ { - UA_TYPENAME("EventFieldList") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {917}}, /* .typeId */ - sizeof(UA_EventFieldList), /* .memSize */ - UA_TYPES_EVENTFIELDLIST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("CallMethodResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {707}}, /* .typeId */ + sizeof(UA_CallMethodResult), /* .memSize */ + UA_TYPES_CALLMETHODRESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 919, /* .binaryEncodingId */ - EventFieldList_members /* .members */ + 4, /* .membersSize */ + 709, /* .binaryEncodingId */ + CallMethodResult_members /* .members */ }, /* MonitoringMode */ { @@ -14410,64 +15320,116 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {716}}, /* .typeId */ sizeof(UA_MonitoringMode), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ MonitoringMode_members /* .members */ }, -/* MdnsDiscoveryConfiguration */ +/* SetMonitoringModeResponse */ { - UA_TYPENAME("MdnsDiscoveryConfiguration") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {12891}}, /* .typeId */ - sizeof(UA_MdnsDiscoveryConfiguration), /* .memSize */ - UA_TYPES_MDNSDISCOVERYCONFIGURATION, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("SetMonitoringModeResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {770}}, /* .typeId */ + sizeof(UA_SetMonitoringModeResponse), /* .memSize */ + UA_TYPES_SETMONITORINGMODERESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 12901, /* .binaryEncodingId */ - MdnsDiscoveryConfiguration_members /* .members */ + 3, /* .membersSize */ + 772, /* .binaryEncodingId */ + SetMonitoringModeResponse_members /* .members */ }, -/* CallMethodResult */ +/* BrowseResultMask */ { - UA_TYPENAME("CallMethodResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {707}}, /* .typeId */ - sizeof(UA_CallMethodResult), /* .memSize */ - UA_TYPES_CALLMETHODRESULT, /* .typeIndex */ + UA_TYPENAME("BrowseResultMask") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {517}}, /* .typeId */ + sizeof(UA_BrowseResultMask), /* .memSize */ + UA_TYPES_INT32, /* .typeIndex */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ + true, /* .pointerFree */ + UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + BrowseResultMask_members /* .members */ +}, +/* RequestHeader */ +{ + UA_TYPENAME("RequestHeader") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {389}}, /* .typeId */ + sizeof(UA_RequestHeader), /* .memSize */ + UA_TYPES_REQUESTHEADER, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 7, /* .membersSize */ + 391, /* .binaryEncodingId */ + RequestHeader_members /* .members */ +}, +/* MonitoredItemModifyResult */ +{ + UA_TYPENAME("MonitoredItemModifyResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {758}}, /* .typeId */ + sizeof(UA_MonitoredItemModifyResult), /* .memSize */ + UA_TYPES_MONITOREDITEMMODIFYRESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 4, /* .membersSize */ - false, /* .builtin */ + 760, /* .binaryEncodingId */ + MonitoredItemModifyResult_members /* .members */ +}, +/* CloseSecureChannelRequest */ +{ + UA_TYPENAME("CloseSecureChannelRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {450}}, /* .typeId */ + sizeof(UA_CloseSecureChannelRequest), /* .memSize */ + UA_TYPES_CLOSESECURECHANNELREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 709, /* .binaryEncodingId */ - CallMethodResult_members /* .members */ + 1, /* .membersSize */ + 452, /* .binaryEncodingId */ + CloseSecureChannelRequest_members /* .members */ }, -/* ParsingResult */ +/* NotificationMessage */ { - UA_TYPENAME("ParsingResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {610}}, /* .typeId */ - sizeof(UA_ParsingResult), /* .memSize */ - UA_TYPES_PARSINGRESULT, /* .typeIndex */ + UA_TYPENAME("NotificationMessage") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {803}}, /* .typeId */ + sizeof(UA_NotificationMessage), /* .memSize */ + UA_TYPES_NOTIFICATIONMESSAGE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 3, /* .membersSize */ - false, /* .builtin */ + 805, /* .binaryEncodingId */ + NotificationMessage_members /* .members */ +}, +/* CreateSubscriptionResponse */ +{ + UA_TYPENAME("CreateSubscriptionResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {788}}, /* .typeId */ + sizeof(UA_CreateSubscriptionResponse), /* .memSize */ + UA_TYPES_CREATESUBSCRIPTIONRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 612, /* .binaryEncodingId */ - ParsingResult_members /* .members */ + 5, /* .membersSize */ + 790, /* .binaryEncodingId */ + CreateSubscriptionResponse_members /* .members */ }, -/* RelativePathElement */ +/* MdnsDiscoveryConfiguration */ { - UA_TYPENAME("RelativePathElement") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {537}}, /* .typeId */ - sizeof(UA_RelativePathElement), /* .memSize */ - UA_TYPES_RELATIVEPATHELEMENT, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("MdnsDiscoveryConfiguration") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {12891}}, /* .typeId */ + sizeof(UA_MdnsDiscoveryConfiguration), /* .memSize */ + UA_TYPES_MDNSDISCOVERYCONFIGURATION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 539, /* .binaryEncodingId */ - RelativePathElement_members /* .members */ + 2, /* .membersSize */ + 12901, /* .binaryEncodingId */ + MdnsDiscoveryConfiguration_members /* .members */ }, /* BrowseDirection */ { @@ -14475,10 +15437,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {510}}, /* .typeId */ sizeof(UA_BrowseDirection), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ BrowseDirection_members /* .members */ }, @@ -14488,331 +15450,405 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {704}}, /* .typeId */ sizeof(UA_CallMethodRequest), /* .memSize */ UA_TYPES_CALLMETHODREQUEST, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 3, /* .membersSize */ 706, /* .binaryEncodingId */ CallMethodRequest_members /* .members */ }, -/* RedundancySupport */ +/* ReadResponse */ { - UA_TYPENAME("RedundancySupport") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {851}}, /* .typeId */ - sizeof(UA_RedundancySupport), /* .memSize */ + UA_TYPENAME("ReadResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {632}}, /* .typeId */ + sizeof(UA_ReadResponse), /* .memSize */ + UA_TYPES_READRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 3, /* .membersSize */ + 634, /* .binaryEncodingId */ + ReadResponse_members /* .members */ +}, +/* TimestampsToReturn */ +{ + UA_TYPENAME("TimestampsToReturn") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {625}}, /* .typeId */ + sizeof(UA_TimestampsToReturn), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ - RedundancySupport_members /* .members */ + TimestampsToReturn_members /* .members */ }, -/* EventNotificationList */ +/* NodeClass */ { - UA_TYPENAME("EventNotificationList") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {914}}, /* .typeId */ - sizeof(UA_EventNotificationList), /* .memSize */ - UA_TYPES_EVENTNOTIFICATIONLIST, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 916, /* .binaryEncodingId */ - EventNotificationList_members /* .members */ + UA_TYPENAME("NodeClass") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {257}}, /* .typeId */ + sizeof(UA_NodeClass), /* .memSize */ + UA_TYPES_INT32, /* .typeIndex */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ + true, /* .pointerFree */ + UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + NodeClass_members /* .members */ }, -/* UnregisterNodesRequest */ +/* ObjectTypeAttributes */ { - UA_TYPENAME("UnregisterNodesRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {564}}, /* .typeId */ - sizeof(UA_UnregisterNodesRequest), /* .memSize */ - UA_TYPES_UNREGISTERNODESREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ObjectTypeAttributes") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {361}}, /* .typeId */ + sizeof(UA_ObjectTypeAttributes), /* .memSize */ + UA_TYPES_OBJECTTYPEATTRIBUTES, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 566, /* .binaryEncodingId */ - UnregisterNodesRequest_members /* .members */ + 6, /* .membersSize */ + 363, /* .binaryEncodingId */ + ObjectTypeAttributes_members /* .members */ }, -/* ContentFilterElementResult */ +/* SecurityTokenRequestType */ { - UA_TYPENAME("ContentFilterElementResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {604}}, /* .typeId */ - sizeof(UA_ContentFilterElementResult), /* .memSize */ - UA_TYPES_CONTENTFILTERELEMENTRESULT, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 606, /* .binaryEncodingId */ - ContentFilterElementResult_members /* .members */ + UA_TYPENAME("SecurityTokenRequestType") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {315}}, /* .typeId */ + sizeof(UA_SecurityTokenRequestType), /* .memSize */ + UA_TYPES_INT32, /* .typeIndex */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ + true, /* .pointerFree */ + UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + SecurityTokenRequestType_members /* .members */ }, -/* SimpleAttributeOperand */ +/* CloseSessionResponse */ { - UA_TYPENAME("SimpleAttributeOperand") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {601}}, /* .typeId */ - sizeof(UA_SimpleAttributeOperand), /* .memSize */ - UA_TYPES_SIMPLEATTRIBUTEOPERAND, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("CloseSessionResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {474}}, /* .typeId */ + sizeof(UA_CloseSessionResponse), /* .memSize */ + UA_TYPES_CLOSESESSIONRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 603, /* .binaryEncodingId */ - SimpleAttributeOperand_members /* .members */ -}, -/* LiteralOperand */ -{ - UA_TYPENAME("LiteralOperand") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {595}}, /* .typeId */ - sizeof(UA_LiteralOperand), /* .memSize */ - UA_TYPES_LITERALOPERAND, /* .typeIndex */ 1, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 597, /* .binaryEncodingId */ - LiteralOperand_members /* .members */ + 476, /* .binaryEncodingId */ + CloseSessionResponse_members /* .members */ }, -/* QueryDataSet */ +/* SetPublishingModeRequest */ { - UA_TYPENAME("QueryDataSet") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {577}}, /* .typeId */ - sizeof(UA_QueryDataSet), /* .memSize */ - UA_TYPES_QUERYDATASET, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("SetPublishingModeRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {797}}, /* .typeId */ + sizeof(UA_SetPublishingModeRequest), /* .memSize */ + UA_TYPES_SETPUBLISHINGMODEREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 579, /* .binaryEncodingId */ - QueryDataSet_members /* .members */ + 3, /* .membersSize */ + 799, /* .binaryEncodingId */ + SetPublishingModeRequest_members /* .members */ }, -/* AnonymousIdentityToken */ +/* IssuedIdentityToken */ { - UA_TYPENAME("AnonymousIdentityToken") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {319}}, /* .typeId */ - sizeof(UA_AnonymousIdentityToken), /* .memSize */ - UA_TYPES_ANONYMOUSIDENTITYTOKEN, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("IssuedIdentityToken") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {938}}, /* .typeId */ + sizeof(UA_IssuedIdentityToken), /* .memSize */ + UA_TYPES_ISSUEDIDENTITYTOKEN, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 321, /* .binaryEncodingId */ - AnonymousIdentityToken_members /* .members */ + 3, /* .membersSize */ + 940, /* .binaryEncodingId */ + IssuedIdentityToken_members /* .members */ }, -/* SetPublishingModeRequest */ +/* ServerOnNetwork */ { - UA_TYPENAME("SetPublishingModeRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {797}}, /* .typeId */ - sizeof(UA_SetPublishingModeRequest), /* .memSize */ - UA_TYPES_SETPUBLISHINGMODEREQUEST, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ServerOnNetwork") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {12189}}, /* .typeId */ + sizeof(UA_ServerOnNetwork), /* .memSize */ + UA_TYPES_SERVERONNETWORK, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 799, /* .binaryEncodingId */ - SetPublishingModeRequest_members /* .members */ + 4, /* .membersSize */ + 12207, /* .binaryEncodingId */ + ServerOnNetwork_members /* .members */ }, -/* MonitoredItemCreateResult */ +/* DeleteMonitoredItemsResponse */ { - UA_TYPENAME("MonitoredItemCreateResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {746}}, /* .typeId */ - sizeof(UA_MonitoredItemCreateResult), /* .memSize */ - UA_TYPES_MONITOREDITEMCREATERESULT, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("DeleteMonitoredItemsResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {782}}, /* .typeId */ + sizeof(UA_DeleteMonitoredItemsResponse), /* .memSize */ + UA_TYPES_DELETEMONITOREDITEMSRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 748, /* .binaryEncodingId */ - MonitoredItemCreateResult_members /* .members */ + 3, /* .membersSize */ + 784, /* .binaryEncodingId */ + DeleteMonitoredItemsResponse_members /* .members */ }, -/* TimestampsToReturn */ +/* ApplicationType */ { - UA_TYPENAME("TimestampsToReturn") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {625}}, /* .typeId */ - sizeof(UA_TimestampsToReturn), /* .memSize */ + UA_TYPENAME("ApplicationType") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {307}}, /* .typeId */ + sizeof(UA_ApplicationType), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ - TimestampsToReturn_members /* .members */ + ApplicationType_members /* .members */ }, -/* CallRequest */ +/* DiscoveryConfiguration */ { - UA_TYPENAME("CallRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {710}}, /* .typeId */ - sizeof(UA_CallRequest), /* .memSize */ - UA_TYPES_CALLREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("DiscoveryConfiguration") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {12890}}, /* .typeId */ + sizeof(UA_DiscoveryConfiguration), /* .memSize */ + UA_TYPES_DISCOVERYCONFIGURATION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + true, /* .pointerFree */ + true, /* .overlayable */ + 0, /* .membersSize */ + 12900, /* .binaryEncodingId */ + DiscoveryConfiguration_members /* .members */ +}, +/* BrowseNextRequest */ +{ + UA_TYPENAME("BrowseNextRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {531}}, /* .typeId */ + sizeof(UA_BrowseNextRequest), /* .memSize */ + UA_TYPES_BROWSENEXTREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 712, /* .binaryEncodingId */ - CallRequest_members /* .members */ + 3, /* .membersSize */ + 533, /* .binaryEncodingId */ + BrowseNextRequest_members /* .members */ }, -/* MethodAttributes */ +/* ModifySubscriptionRequest */ { - UA_TYPENAME("MethodAttributes") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {358}}, /* .typeId */ - sizeof(UA_MethodAttributes), /* .memSize */ - UA_TYPES_METHODATTRIBUTES, /* .typeIndex */ + UA_TYPENAME("ModifySubscriptionRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {791}}, /* .typeId */ + sizeof(UA_ModifySubscriptionRequest), /* .memSize */ + UA_TYPES_MODIFYSUBSCRIPTIONREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 7, /* .membersSize */ - false, /* .builtin */ + 793, /* .binaryEncodingId */ + ModifySubscriptionRequest_members /* .members */ +}, +/* BrowseDescription */ +{ + UA_TYPENAME("BrowseDescription") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {514}}, /* .typeId */ + sizeof(UA_BrowseDescription), /* .memSize */ + UA_TYPES_BROWSEDESCRIPTION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 360, /* .binaryEncodingId */ - MethodAttributes_members /* .members */ + 6, /* .membersSize */ + 516, /* .binaryEncodingId */ + BrowseDescription_members /* .members */ }, -/* DeleteReferencesItem */ +/* SignedSoftwareCertificate */ { - UA_TYPENAME("DeleteReferencesItem") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {385}}, /* .typeId */ - sizeof(UA_DeleteReferencesItem), /* .memSize */ - UA_TYPES_DELETEREFERENCESITEM, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("SignedSoftwareCertificate") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {344}}, /* .typeId */ + sizeof(UA_SignedSoftwareCertificate), /* .memSize */ + UA_TYPES_SIGNEDSOFTWARECERTIFICATE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 387, /* .binaryEncodingId */ - DeleteReferencesItem_members /* .members */ + 2, /* .membersSize */ + 346, /* .binaryEncodingId */ + SignedSoftwareCertificate_members /* .members */ }, -/* WriteValue */ +/* BrowsePathTarget */ { - UA_TYPENAME("WriteValue") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {668}}, /* .typeId */ - sizeof(UA_WriteValue), /* .memSize */ - UA_TYPES_WRITEVALUE, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("BrowsePathTarget") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {546}}, /* .typeId */ + sizeof(UA_BrowsePathTarget), /* .memSize */ + UA_TYPES_BROWSEPATHTARGET, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 670, /* .binaryEncodingId */ - WriteValue_members /* .members */ + 2, /* .membersSize */ + 548, /* .binaryEncodingId */ + BrowsePathTarget_members /* .members */ }, -/* NodeAttributesMask */ +/* WriteResponse */ { - UA_TYPENAME("NodeAttributesMask") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {348}}, /* .typeId */ - sizeof(UA_NodeAttributesMask), /* .memSize */ - UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ - true, /* .pointerFree */ - UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ - 0, /* .binaryEncodingId */ - NodeAttributesMask_members /* .members */ + UA_TYPENAME("WriteResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {674}}, /* .typeId */ + sizeof(UA_WriteResponse), /* .memSize */ + UA_TYPES_WRITERESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 3, /* .membersSize */ + 676, /* .binaryEncodingId */ + WriteResponse_members /* .members */ }, -/* MessageSecurityMode */ +/* AddNodesResult */ { - UA_TYPENAME("MessageSecurityMode") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {302}}, /* .typeId */ - sizeof(UA_MessageSecurityMode), /* .memSize */ - UA_TYPES_INT32, /* .typeIndex */ + UA_TYPENAME("AddNodesResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {483}}, /* .typeId */ + sizeof(UA_AddNodesResult), /* .memSize */ + UA_TYPES_ADDNODESRESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 2, /* .membersSize */ + 485, /* .binaryEncodingId */ + AddNodesResult_members /* .members */ +}, +/* RegisterServerResponse */ +{ + UA_TYPENAME("RegisterServerResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {438}}, /* .typeId */ + sizeof(UA_RegisterServerResponse), /* .memSize */ + UA_TYPES_REGISTERSERVERRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 1, /* .membersSize */ - true, /* .builtin */ - true, /* .pointerFree */ - UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ - 0, /* .binaryEncodingId */ - MessageSecurityMode_members /* .members */ + 440, /* .binaryEncodingId */ + RegisterServerResponse_members /* .members */ }, -/* MonitoringParameters */ +/* AddReferencesItem */ { - UA_TYPENAME("MonitoringParameters") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {740}}, /* .typeId */ - sizeof(UA_MonitoringParameters), /* .memSize */ - UA_TYPES_MONITORINGPARAMETERS, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("AddReferencesItem") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {379}}, /* .typeId */ + sizeof(UA_AddReferencesItem), /* .memSize */ + UA_TYPES_ADDREFERENCESITEM, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 742, /* .binaryEncodingId */ - MonitoringParameters_members /* .members */ + 6, /* .membersSize */ + 381, /* .binaryEncodingId */ + AddReferencesItem_members /* .members */ }, -/* ReferenceNode */ +/* RegisterServer2Response */ { - UA_TYPENAME("ReferenceNode") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {285}}, /* .typeId */ - sizeof(UA_ReferenceNode), /* .memSize */ - UA_TYPES_REFERENCENODE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("RegisterServer2Response") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {12194}}, /* .typeId */ + sizeof(UA_RegisterServer2Response), /* .memSize */ + UA_TYPES_REGISTERSERVER2RESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 287, /* .binaryEncodingId */ - ReferenceNode_members /* .members */ + 3, /* .membersSize */ + 12212, /* .binaryEncodingId */ + RegisterServer2Response_members /* .members */ }, -/* Argument */ +/* DeleteReferencesResponse */ { - UA_TYPENAME("Argument") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {296}}, /* .typeId */ - sizeof(UA_Argument), /* .memSize */ - UA_TYPES_ARGUMENT, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("DeleteReferencesResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {507}}, /* .typeId */ + sizeof(UA_DeleteReferencesResponse), /* .memSize */ + UA_TYPES_DELETEREFERENCESRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 298, /* .binaryEncodingId */ - Argument_members /* .members */ + 3, /* .membersSize */ + 509, /* .binaryEncodingId */ + DeleteReferencesResponse_members /* .members */ }, -/* ChannelSecurityToken */ +/* RelativePathElement */ { - UA_TYPENAME("ChannelSecurityToken") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {441}}, /* .typeId */ - sizeof(UA_ChannelSecurityToken), /* .memSize */ - UA_TYPES_CHANNELSECURITYTOKEN, /* .typeIndex */ + UA_TYPENAME("RelativePathElement") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {537}}, /* .typeId */ + sizeof(UA_RelativePathElement), /* .memSize */ + UA_TYPES_RELATIVEPATHELEMENT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 4, /* .membersSize */ - false, /* .builtin */ + 539, /* .binaryEncodingId */ + RelativePathElement_members /* .members */ +}, +/* SubscriptionAcknowledgement */ +{ + UA_TYPENAME("SubscriptionAcknowledgement") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {821}}, /* .typeId */ + sizeof(UA_SubscriptionAcknowledgement), /* .memSize */ + UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true && UA_BINARY_OVERLAYABLE_INTEGER && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ChannelSecurityToken, tokenId) == (offsetof(UA_ChannelSecurityToken, channelId) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ChannelSecurityToken, createdAt) == (offsetof(UA_ChannelSecurityToken, tokenId) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ChannelSecurityToken, revisedLifetime) == (offsetof(UA_ChannelSecurityToken, createdAt) + sizeof(UA_DateTime)), /* .overlayable */ - 443, /* .binaryEncodingId */ - ChannelSecurityToken_members /* .members */ + && offsetof(UA_SubscriptionAcknowledgement, sequenceNumber) == (offsetof(UA_SubscriptionAcknowledgement, subscriptionId) + sizeof(UA_UInt32)), /* .overlayable */ + 2, /* .membersSize */ + 823, /* .binaryEncodingId */ + SubscriptionAcknowledgement_members /* .members */ }, -/* UserIdentityToken */ +/* CreateMonitoredItemsResponse */ { - UA_TYPENAME("UserIdentityToken") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {316}}, /* .typeId */ - sizeof(UA_UserIdentityToken), /* .memSize */ - UA_TYPES_USERIDENTITYTOKEN, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("CreateMonitoredItemsResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {752}}, /* .typeId */ + sizeof(UA_CreateMonitoredItemsResponse), /* .memSize */ + UA_TYPES_CREATEMONITOREDITEMSRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 318, /* .binaryEncodingId */ - UserIdentityToken_members /* .members */ + 3, /* .membersSize */ + 754, /* .binaryEncodingId */ + CreateMonitoredItemsResponse_members /* .members */ }, -/* SignatureData */ +/* DeleteReferencesItem */ { - UA_TYPENAME("SignatureData") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {456}}, /* .typeId */ - sizeof(UA_SignatureData), /* .memSize */ - UA_TYPES_SIGNATUREDATA, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("DeleteReferencesItem") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {385}}, /* .typeId */ + sizeof(UA_DeleteReferencesItem), /* .memSize */ + UA_TYPES_DELETEREFERENCESITEM, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 458, /* .binaryEncodingId */ - SignatureData_members /* .members */ + 5, /* .membersSize */ + 387, /* .binaryEncodingId */ + DeleteReferencesItem_members /* .members */ }, -/* ObjectTypeAttributes */ +/* WriteValue */ { - UA_TYPENAME("ObjectTypeAttributes") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {361}}, /* .typeId */ - sizeof(UA_ObjectTypeAttributes), /* .memSize */ - UA_TYPES_OBJECTTYPEATTRIBUTES, /* .typeIndex */ + UA_TYPENAME("WriteValue") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {668}}, /* .typeId */ + sizeof(UA_WriteValue), /* .memSize */ + UA_TYPES_WRITEVALUE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 4, /* .membersSize */ + 670, /* .binaryEncodingId */ + WriteValue_members /* .members */ +}, +/* DataTypeAttributes */ +{ + UA_TYPENAME("DataTypeAttributes") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {370}}, /* .typeId */ + sizeof(UA_DataTypeAttributes), /* .memSize */ + UA_TYPES_DATATYPEATTRIBUTES, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 6, /* .membersSize */ - false, /* .builtin */ + 372, /* .binaryEncodingId */ + DataTypeAttributes_members /* .members */ +}, +/* AddReferencesResponse */ +{ + UA_TYPENAME("AddReferencesResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {495}}, /* .typeId */ + sizeof(UA_AddReferencesResponse), /* .memSize */ + UA_TYPES_ADDREFERENCESRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 363, /* .binaryEncodingId */ - ObjectTypeAttributes_members /* .members */ + 3, /* .membersSize */ + 497, /* .binaryEncodingId */ + AddReferencesResponse_members /* .members */ }, /* DeadbandType */ { @@ -14820,49 +15856,23 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {718}}, /* .typeId */ sizeof(UA_DeadbandType), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ DeadbandType_members /* .members */ }, -/* SecurityTokenRequestType */ -{ - UA_TYPENAME("SecurityTokenRequestType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {315}}, /* .typeId */ - sizeof(UA_SecurityTokenRequestType), /* .memSize */ - UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ - true, /* .pointerFree */ - UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ - 0, /* .binaryEncodingId */ - SecurityTokenRequestType_members /* .members */ -}, -/* NodeAttributes */ -{ - UA_TYPENAME("NodeAttributes") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {349}}, /* .typeId */ - sizeof(UA_NodeAttributes), /* .memSize */ - UA_TYPES_NODEATTRIBUTES, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 351, /* .binaryEncodingId */ - NodeAttributes_members /* .members */ -}, /* DataChangeTrigger */ { UA_TYPENAME("DataChangeTrigger") /* .typeName */ {0, UA_NODEIDTYPE_NUMERIC, {717}}, /* .typeId */ sizeof(UA_DataChangeTrigger), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ DataChangeTrigger_members /* .members */ }, @@ -14872,64 +15882,38 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {338}}, /* .typeId */ sizeof(UA_BuildInfo), /* .memSize */ UA_TYPES_BUILDINFO, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 6, /* .membersSize */ 340, /* .binaryEncodingId */ BuildInfo_members /* .members */ }, -/* NodeClass */ -{ - UA_TYPENAME("NodeClass") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {257}}, /* .typeId */ - sizeof(UA_NodeClass), /* .memSize */ - UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ - true, /* .pointerFree */ - UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ - 0, /* .binaryEncodingId */ - NodeClass_members /* .members */ -}, -/* SubscriptionDiagnosticsDataType */ -{ - UA_TYPENAME("SubscriptionDiagnosticsDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {874}}, /* .typeId */ - sizeof(UA_SubscriptionDiagnosticsDataType), /* .memSize */ - UA_TYPES_SUBSCRIPTIONDIAGNOSTICSDATATYPE, /* .typeIndex */ - 31, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 876, /* .binaryEncodingId */ - SubscriptionDiagnosticsDataType_members /* .members */ -}, /* FilterOperand */ { UA_TYPENAME("FilterOperand") /* .typeName */ {0, UA_NODEIDTYPE_NUMERIC, {589}}, /* .typeId */ sizeof(UA_FilterOperand), /* .memSize */ UA_TYPES_FILTEROPERAND, /* .typeIndex */ - 0, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true, /* .overlayable */ + 0, /* .membersSize */ 591, /* .binaryEncodingId */ FilterOperand_members /* .members */ }, -/* MonitoredItemNotification */ +/* MonitoringParameters */ { - UA_TYPENAME("MonitoredItemNotification") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {806}}, /* .typeId */ - sizeof(UA_MonitoredItemNotification), /* .memSize */ - UA_TYPES_MONITOREDITEMNOTIFICATION, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("MonitoringParameters") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {740}}, /* .typeId */ + sizeof(UA_MonitoringParameters), /* .memSize */ + UA_TYPES_MONITORINGPARAMETERS, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 808, /* .binaryEncodingId */ - MonitoredItemNotification_members /* .members */ + 5, /* .membersSize */ + 742, /* .binaryEncodingId */ + MonitoringParameters_members /* .members */ }, /* DeleteNodesItem */ { @@ -14937,145 +15921,38 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {382}}, /* .typeId */ sizeof(UA_DeleteNodesItem), /* .memSize */ UA_TYPES_DELETENODESITEM, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 384, /* .binaryEncodingId */ DeleteNodesItem_members /* .members */ }, -/* DeleteSubscriptionsRequest */ -{ - UA_TYPENAME("DeleteSubscriptionsRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {845}}, /* .typeId */ - sizeof(UA_DeleteSubscriptionsRequest), /* .memSize */ - UA_TYPES_DELETESUBSCRIPTIONSREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 847, /* .binaryEncodingId */ - DeleteSubscriptionsRequest_members /* .members */ -}, -/* SubscriptionAcknowledgement */ -{ - UA_TYPENAME("SubscriptionAcknowledgement") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {821}}, /* .typeId */ - sizeof(UA_SubscriptionAcknowledgement), /* .memSize */ - UA_TYPES_SUBSCRIPTIONACKNOWLEDGEMENT, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - true, /* .pointerFree */ - true - && UA_BINARY_OVERLAYABLE_INTEGER - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_SubscriptionAcknowledgement, sequenceNumber) == (offsetof(UA_SubscriptionAcknowledgement, subscriptionId) + sizeof(UA_UInt32)), /* .overlayable */ - 823, /* .binaryEncodingId */ - SubscriptionAcknowledgement_members /* .members */ -}, /* ReadValueId */ { UA_TYPENAME("ReadValueId") /* .typeName */ {0, UA_NODEIDTYPE_NUMERIC, {626}}, /* .typeId */ sizeof(UA_ReadValueId), /* .memSize */ UA_TYPES_READVALUEID, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 4, /* .membersSize */ 628, /* .binaryEncodingId */ ReadValueId_members /* .members */ }, -/* DataTypeAttributes */ -{ - UA_TYPENAME("DataTypeAttributes") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {370}}, /* .typeId */ - sizeof(UA_DataTypeAttributes), /* .memSize */ - UA_TYPES_DATATYPEATTRIBUTES, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 372, /* .binaryEncodingId */ - DataTypeAttributes_members /* .members */ -}, -/* ResponseHeader */ -{ - UA_TYPENAME("ResponseHeader") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {392}}, /* .typeId */ - sizeof(UA_ResponseHeader), /* .memSize */ - UA_TYPES_RESPONSEHEADER, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 394, /* .binaryEncodingId */ - ResponseHeader_members /* .members */ -}, -/* DeleteMonitoredItemsRequest */ -{ - UA_TYPENAME("DeleteMonitoredItemsRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {779}}, /* .typeId */ - sizeof(UA_DeleteMonitoredItemsRequest), /* .memSize */ - UA_TYPES_DELETEMONITOREDITEMSREQUEST, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 781, /* .binaryEncodingId */ - DeleteMonitoredItemsRequest_members /* .members */ -}, -/* ViewDescription */ -{ - UA_TYPENAME("ViewDescription") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {511}}, /* .typeId */ - sizeof(UA_ViewDescription), /* .memSize */ - UA_TYPES_VIEWDESCRIPTION, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 513, /* .binaryEncodingId */ - ViewDescription_members /* .members */ -}, -/* ServerOnNetwork */ -{ - UA_TYPENAME("ServerOnNetwork") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {12189}}, /* .typeId */ - sizeof(UA_ServerOnNetwork), /* .memSize */ - UA_TYPES_SERVERONNETWORK, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 12207, /* .binaryEncodingId */ - ServerOnNetwork_members /* .members */ -}, -/* DeleteMonitoredItemsResponse */ -{ - UA_TYPENAME("DeleteMonitoredItemsResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {782}}, /* .typeId */ - sizeof(UA_DeleteMonitoredItemsResponse), /* .memSize */ - UA_TYPES_DELETEMONITOREDITEMSRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 784, /* .binaryEncodingId */ - DeleteMonitoredItemsResponse_members /* .members */ -}, -/* FindServersOnNetworkResponse */ +/* CallRequest */ { - UA_TYPENAME("FindServersOnNetworkResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {12191}}, /* .typeId */ - sizeof(UA_FindServersOnNetworkResponse), /* .memSize */ - UA_TYPES_FINDSERVERSONNETWORKRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("CallRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {710}}, /* .typeId */ + sizeof(UA_CallRequest), /* .memSize */ + UA_TYPES_CALLREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 12209, /* .binaryEncodingId */ - FindServersOnNetworkResponse_members /* .members */ + 2, /* .membersSize */ + 712, /* .binaryEncodingId */ + CallRequest_members /* .members */ }, /* RelativePath */ { @@ -15083,25 +15960,51 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {540}}, /* .typeId */ sizeof(UA_RelativePath), /* .memSize */ UA_TYPES_RELATIVEPATH, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 1, /* .membersSize */ 542, /* .binaryEncodingId */ RelativePath_members /* .members */ }, -/* RegisterNodesRequest */ +/* DeleteNodesRequest */ { - UA_TYPENAME("RegisterNodesRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {558}}, /* .typeId */ - sizeof(UA_RegisterNodesRequest), /* .memSize */ - UA_TYPES_REGISTERNODESREQUEST, /* .typeIndex */ + UA_TYPENAME("DeleteNodesRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {498}}, /* .typeId */ + sizeof(UA_DeleteNodesRequest), /* .memSize */ + UA_TYPES_DELETENODESREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 2, /* .membersSize */ - false, /* .builtin */ + 500, /* .binaryEncodingId */ + DeleteNodesRequest_members /* .members */ +}, +/* MonitoredItemModifyRequest */ +{ + UA_TYPENAME("MonitoredItemModifyRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {755}}, /* .typeId */ + sizeof(UA_MonitoredItemModifyRequest), /* .memSize */ + UA_TYPES_MONITOREDITEMMODIFYREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 560, /* .binaryEncodingId */ - RegisterNodesRequest_members /* .members */ + 2, /* .membersSize */ + 757, /* .binaryEncodingId */ + MonitoredItemModifyRequest_members /* .members */ +}, +/* UserTokenType */ +{ + UA_TYPENAME("UserTokenType") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {303}}, /* .typeId */ + sizeof(UA_UserTokenType), /* .memSize */ + UA_TYPES_INT32, /* .typeIndex */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ + true, /* .pointerFree */ + UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + UserTokenType_members /* .members */ }, /* AggregateConfiguration */ { @@ -15109,8 +16012,7 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {948}}, /* .typeId */ sizeof(UA_AggregateConfiguration), /* .memSize */ UA_TYPES_AGGREGATECONFIGURATION, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true && true @@ -15122,183 +16024,279 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { && offsetof(UA_AggregateConfiguration, percentDataGood) == (offsetof(UA_AggregateConfiguration, percentDataBad) + sizeof(UA_Byte)) && true && offsetof(UA_AggregateConfiguration, useSlopedExtrapolation) == (offsetof(UA_AggregateConfiguration, percentDataGood) + sizeof(UA_Byte)), /* .overlayable */ + 5, /* .membersSize */ 950, /* .binaryEncodingId */ AggregateConfiguration_members /* .members */ }, -/* DeleteNodesRequest */ +/* LocaleId */ { - UA_TYPENAME("DeleteNodesRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {498}}, /* .typeId */ - sizeof(UA_DeleteNodesRequest), /* .memSize */ - UA_TYPES_DELETENODESREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("LocaleId") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {295}}, /* .typeId */ + sizeof(UA_LocaleId), /* .memSize */ + UA_TYPES_LOCALEID, /* .typeIndex */ + UA_DATATYPEKIND_STRING, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 500, /* .binaryEncodingId */ - DeleteNodesRequest_members /* .members */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + LocaleId_members /* .members */ }, -/* PublishResponse */ +/* UnregisterNodesResponse */ { - UA_TYPENAME("PublishResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {827}}, /* .typeId */ - sizeof(UA_PublishResponse), /* .memSize */ - UA_TYPES_PUBLISHRESPONSE, /* .typeIndex */ - 7, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("UnregisterNodesResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {567}}, /* .typeId */ + sizeof(UA_UnregisterNodesResponse), /* .memSize */ + UA_TYPES_UNREGISTERNODESRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 829, /* .binaryEncodingId */ - PublishResponse_members /* .members */ + 1, /* .membersSize */ + 569, /* .binaryEncodingId */ + UnregisterNodesResponse_members /* .members */ }, -/* MonitoredItemModifyRequest */ +/* ContentFilterResult */ { - UA_TYPENAME("MonitoredItemModifyRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {755}}, /* .typeId */ - sizeof(UA_MonitoredItemModifyRequest), /* .memSize */ - UA_TYPES_MONITOREDITEMMODIFYREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ContentFilterResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {607}}, /* .typeId */ + sizeof(UA_ContentFilterResult), /* .memSize */ + UA_TYPES_CONTENTFILTERRESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 757, /* .binaryEncodingId */ - MonitoredItemModifyRequest_members /* .members */ + 2, /* .membersSize */ + 609, /* .binaryEncodingId */ + ContentFilterResult_members /* .members */ }, -/* ServiceCounterDataType */ +/* UserTokenPolicy */ { - UA_TYPENAME("ServiceCounterDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {871}}, /* .typeId */ - sizeof(UA_ServiceCounterDataType), /* .memSize */ - UA_TYPES_SERVICECOUNTERDATATYPE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - true, /* .pointerFree */ - true - && UA_BINARY_OVERLAYABLE_INTEGER - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServiceCounterDataType, errorCount) == (offsetof(UA_ServiceCounterDataType, totalCount) + sizeof(UA_UInt32)), /* .overlayable */ - 873, /* .binaryEncodingId */ - ServiceCounterDataType_members /* .members */ + UA_TYPENAME("UserTokenPolicy") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {304}}, /* .typeId */ + sizeof(UA_UserTokenPolicy), /* .memSize */ + UA_TYPES_USERTOKENPOLICY, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 5, /* .membersSize */ + 306, /* .binaryEncodingId */ + UserTokenPolicy_members /* .members */ }, -/* ModelChangeStructureDataType */ +/* DeleteMonitoredItemsRequest */ { - UA_TYPENAME("ModelChangeStructureDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {877}}, /* .typeId */ - sizeof(UA_ModelChangeStructureDataType), /* .memSize */ - UA_TYPES_MODELCHANGESTRUCTUREDATATYPE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("DeleteMonitoredItemsRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {779}}, /* .typeId */ + sizeof(UA_DeleteMonitoredItemsRequest), /* .memSize */ + UA_TYPES_DELETEMONITOREDITEMSREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 879, /* .binaryEncodingId */ - ModelChangeStructureDataType_members /* .members */ + 3, /* .membersSize */ + 781, /* .binaryEncodingId */ + DeleteMonitoredItemsRequest_members /* .members */ }, -/* UserNameIdentityToken */ +/* SetMonitoringModeRequest */ { - UA_TYPENAME("UserNameIdentityToken") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {322}}, /* .typeId */ - sizeof(UA_UserNameIdentityToken), /* .memSize */ - UA_TYPES_USERNAMEIDENTITYTOKEN, /* .typeIndex */ + UA_TYPENAME("SetMonitoringModeRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {767}}, /* .typeId */ + sizeof(UA_SetMonitoringModeRequest), /* .memSize */ + UA_TYPES_SETMONITORINGMODEREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 4, /* .membersSize */ - false, /* .builtin */ + 769, /* .binaryEncodingId */ + SetMonitoringModeRequest_members /* .members */ +}, +/* Duration */ +{ + UA_TYPENAME("Duration") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {290}}, /* .typeId */ + sizeof(UA_Duration), /* .memSize */ + UA_TYPES_DURATION, /* .typeIndex */ + UA_DATATYPEKIND_DOUBLE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 324, /* .binaryEncodingId */ - UserNameIdentityToken_members /* .members */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + Duration_members /* .members */ }, -/* IdType */ +/* ReferenceTypeAttributes */ { - UA_TYPENAME("IdType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {256}}, /* .typeId */ - sizeof(UA_IdType), /* .memSize */ - UA_TYPES_INT32, /* .typeIndex */ + UA_TYPENAME("ReferenceTypeAttributes") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {367}}, /* .typeId */ + sizeof(UA_ReferenceTypeAttributes), /* .memSize */ + UA_TYPES_REFERENCETYPEATTRIBUTES, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 8, /* .membersSize */ + 369, /* .binaryEncodingId */ + ReferenceTypeAttributes_members /* .members */ +}, +/* GetEndpointsRequest */ +{ + UA_TYPENAME("GetEndpointsRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {426}}, /* .typeId */ + sizeof(UA_GetEndpointsRequest), /* .memSize */ + UA_TYPES_GETENDPOINTSREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 4, /* .membersSize */ + 428, /* .binaryEncodingId */ + GetEndpointsRequest_members /* .members */ +}, +/* CloseSecureChannelResponse */ +{ + UA_TYPENAME("CloseSecureChannelResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {453}}, /* .typeId */ + sizeof(UA_CloseSecureChannelResponse), /* .memSize */ + UA_TYPES_CLOSESECURECHANNELRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 1, /* .membersSize */ - true, /* .builtin */ - true, /* .pointerFree */ - UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ - 0, /* .binaryEncodingId */ - IdType_members /* .members */ + 455, /* .binaryEncodingId */ + CloseSecureChannelResponse_members /* .members */ }, -/* UserTokenType */ +/* ViewDescription */ { - UA_TYPENAME("UserTokenType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {303}}, /* .typeId */ - sizeof(UA_UserTokenType), /* .memSize */ + UA_TYPENAME("ViewDescription") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {511}}, /* .typeId */ + sizeof(UA_ViewDescription), /* .memSize */ + UA_TYPES_VIEWDESCRIPTION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 3, /* .membersSize */ + 513, /* .binaryEncodingId */ + ViewDescription_members /* .members */ +}, +/* SetPublishingModeResponse */ +{ + UA_TYPENAME("SetPublishingModeResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {800}}, /* .typeId */ + sizeof(UA_SetPublishingModeResponse), /* .memSize */ + UA_TYPES_SETPUBLISHINGMODERESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 3, /* .membersSize */ + 802, /* .binaryEncodingId */ + SetPublishingModeResponse_members /* .members */ +}, +/* StatusChangeNotification */ +{ + UA_TYPENAME("StatusChangeNotification") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {818}}, /* .typeId */ + sizeof(UA_StatusChangeNotification), /* .memSize */ + UA_TYPES_STATUSCHANGENOTIFICATION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 2, /* .membersSize */ + 820, /* .binaryEncodingId */ + StatusChangeNotification_members /* .members */ +}, +/* NodeAttributesMask */ +{ + UA_TYPENAME("NodeAttributesMask") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {348}}, /* .typeId */ + sizeof(UA_NodeAttributesMask), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ - UserTokenType_members /* .members */ + NodeAttributesMask_members /* .members */ }, -/* SetTriggeringResponse */ +/* EventFilterResult */ { - UA_TYPENAME("SetTriggeringResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {776}}, /* .typeId */ - sizeof(UA_SetTriggeringResponse), /* .memSize */ - UA_TYPES_SETTRIGGERINGRESPONSE, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("EventFilterResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {734}}, /* .typeId */ + sizeof(UA_EventFilterResult), /* .memSize */ + UA_TYPES_EVENTFILTERRESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 778, /* .binaryEncodingId */ - SetTriggeringResponse_members /* .members */ + 3, /* .membersSize */ + 736, /* .binaryEncodingId */ + EventFilterResult_members /* .members */ }, -/* TimeZoneDataType */ +/* MonitoredItemCreateRequest */ { - UA_TYPENAME("TimeZoneDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {8912}}, /* .typeId */ - sizeof(UA_TimeZoneDataType), /* .memSize */ - UA_TYPES_TIMEZONEDATATYPE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("MonitoredItemCreateRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {743}}, /* .typeId */ + sizeof(UA_MonitoredItemCreateRequest), /* .memSize */ + UA_TYPES_MONITOREDITEMCREATEREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 3, /* .membersSize */ + 745, /* .binaryEncodingId */ + MonitoredItemCreateRequest_members /* .members */ +}, +/* Range */ +{ + UA_TYPENAME("Range") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {884}}, /* .typeId */ + sizeof(UA_Range), /* .memSize */ + UA_TYPES_RANGE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true - && UA_BINARY_OVERLAYABLE_INTEGER - && true - && offsetof(UA_TimeZoneDataType, daylightSavingInOffset) == (offsetof(UA_TimeZoneDataType, offset) + sizeof(UA_Int16)), /* .overlayable */ - 8917, /* .binaryEncodingId */ - TimeZoneDataType_members /* .members */ + && UA_BINARY_OVERLAYABLE_FLOAT + && UA_BINARY_OVERLAYABLE_FLOAT + && offsetof(UA_Range, high) == (offsetof(UA_Range, low) + sizeof(UA_Double)), /* .overlayable */ + 2, /* .membersSize */ + 886, /* .binaryEncodingId */ + Range_members /* .members */ }, -/* ActivateSessionRequest */ +/* DataChangeNotification */ { - UA_TYPENAME("ActivateSessionRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {465}}, /* .typeId */ - sizeof(UA_ActivateSessionRequest), /* .memSize */ - UA_TYPES_ACTIVATESESSIONREQUEST, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("DataChangeNotification") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {809}}, /* .typeId */ + sizeof(UA_DataChangeNotification), /* .memSize */ + UA_TYPES_DATACHANGENOTIFICATION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 467, /* .binaryEncodingId */ - ActivateSessionRequest_members /* .members */ + 2, /* .membersSize */ + 811, /* .binaryEncodingId */ + DataChangeNotification_members /* .members */ }, -/* OpenSecureChannelResponse */ +/* Argument */ { - UA_TYPENAME("OpenSecureChannelResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {447}}, /* .typeId */ - sizeof(UA_OpenSecureChannelResponse), /* .memSize */ - UA_TYPES_OPENSECURECHANNELRESPONSE, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("Argument") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {296}}, /* .typeId */ + sizeof(UA_Argument), /* .memSize */ + UA_TYPES_ARGUMENT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 449, /* .binaryEncodingId */ - OpenSecureChannelResponse_members /* .members */ + 5, /* .membersSize */ + 298, /* .binaryEncodingId */ + Argument_members /* .members */ }, -/* ApplicationType */ +/* ChannelSecurityToken */ { - UA_TYPENAME("ApplicationType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {307}}, /* .typeId */ - sizeof(UA_ApplicationType), /* .memSize */ - UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_TYPENAME("ChannelSecurityToken") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {441}}, /* .typeId */ + sizeof(UA_ChannelSecurityToken), /* .memSize */ + UA_TYPES_CHANNELSECURITYTOKEN, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ - UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ - 0, /* .binaryEncodingId */ - ApplicationType_members /* .members */ + true + && UA_BINARY_OVERLAYABLE_INTEGER + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ChannelSecurityToken, tokenId) == (offsetof(UA_ChannelSecurityToken, channelId) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ChannelSecurityToken, createdAt) == (offsetof(UA_ChannelSecurityToken, tokenId) + sizeof(UA_UInt32)) + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_ChannelSecurityToken, revisedLifetime) == (offsetof(UA_ChannelSecurityToken, createdAt) + sizeof(UA_DateTime)), /* .overlayable */ + 4, /* .membersSize */ + 443, /* .binaryEncodingId */ + ChannelSecurityToken_members /* .members */ }, /* ServerState */ { @@ -15306,64 +16304,38 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {852}}, /* .typeId */ sizeof(UA_ServerState), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ ServerState_members /* .members */ }, -/* QueryNextResponse */ +/* EventNotificationList */ { - UA_TYPENAME("QueryNextResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {622}}, /* .typeId */ - sizeof(UA_QueryNextResponse), /* .memSize */ - UA_TYPES_QUERYNEXTRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("EventNotificationList") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {914}}, /* .typeId */ + sizeof(UA_EventNotificationList), /* .memSize */ + UA_TYPES_EVENTNOTIFICATIONLIST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 624, /* .binaryEncodingId */ - QueryNextResponse_members /* .members */ -}, -/* DiscoveryConfiguration */ -{ - UA_TYPENAME("DiscoveryConfiguration") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {12890}}, /* .typeId */ - sizeof(UA_DiscoveryConfiguration), /* .memSize */ - UA_TYPES_DISCOVERYCONFIGURATION, /* .typeIndex */ - 0, /* .membersSize */ - false, /* .builtin */ - true, /* .pointerFree */ - true, /* .overlayable */ - 12900, /* .binaryEncodingId */ - DiscoveryConfiguration_members /* .members */ + 1, /* .membersSize */ + 916, /* .binaryEncodingId */ + EventNotificationList_members /* .members */ }, -/* ActivateSessionResponse */ +/* AnonymousIdentityToken */ { - UA_TYPENAME("ActivateSessionResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {468}}, /* .typeId */ - sizeof(UA_ActivateSessionResponse), /* .memSize */ - UA_TYPES_ACTIVATESESSIONRESPONSE, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("AnonymousIdentityToken") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {319}}, /* .typeId */ + sizeof(UA_AnonymousIdentityToken), /* .memSize */ + UA_TYPES_ANONYMOUSIDENTITYTOKEN, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 470, /* .binaryEncodingId */ - ActivateSessionResponse_members /* .members */ -}, -/* EndpointUrlListDataType */ -{ - UA_TYPENAME("EndpointUrlListDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {11943}}, /* .typeId */ - sizeof(UA_EndpointUrlListDataType), /* .memSize */ - UA_TYPES_ENDPOINTURLLISTDATATYPE, /* .typeIndex */ 1, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 11957, /* .binaryEncodingId */ - EndpointUrlListDataType_members /* .members */ + 321, /* .binaryEncodingId */ + AnonymousIdentityToken_members /* .members */ }, /* FilterOperator */ { @@ -15371,116 +16343,155 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {576}}, /* .typeId */ sizeof(UA_FilterOperator), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ FilterOperator_members /* .members */ }, -/* QueryNextRequest */ +/* AggregateFilter */ { - UA_TYPENAME("QueryNextRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {619}}, /* .typeId */ - sizeof(UA_QueryNextRequest), /* .memSize */ - UA_TYPES_QUERYNEXTREQUEST, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("AggregateFilter") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {728}}, /* .typeId */ + sizeof(UA_AggregateFilter), /* .memSize */ + UA_TYPES_AGGREGATEFILTER, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 621, /* .binaryEncodingId */ - QueryNextRequest_members /* .members */ + 4, /* .membersSize */ + 730, /* .binaryEncodingId */ + AggregateFilter_members /* .members */ }, -/* WriteResponse */ +/* RepublishResponse */ { - UA_TYPENAME("WriteResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {674}}, /* .typeId */ - sizeof(UA_WriteResponse), /* .memSize */ - UA_TYPES_WRITERESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("RepublishResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {833}}, /* .typeId */ + sizeof(UA_RepublishResponse), /* .memSize */ + UA_TYPES_REPUBLISHRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 676, /* .binaryEncodingId */ - WriteResponse_members /* .members */ + 2, /* .membersSize */ + 835, /* .binaryEncodingId */ + RepublishResponse_members /* .members */ }, -/* BrowseNextRequest */ +/* DeleteSubscriptionsResponse */ { - UA_TYPENAME("BrowseNextRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {531}}, /* .typeId */ - sizeof(UA_BrowseNextRequest), /* .memSize */ - UA_TYPES_BROWSENEXTREQUEST, /* .typeIndex */ + UA_TYPENAME("DeleteSubscriptionsResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {848}}, /* .typeId */ + sizeof(UA_DeleteSubscriptionsResponse), /* .memSize */ + UA_TYPES_DELETESUBSCRIPTIONSRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 3, /* .membersSize */ - false, /* .builtin */ + 850, /* .binaryEncodingId */ + DeleteSubscriptionsResponse_members /* .members */ +}, +/* RegisterNodesRequest */ +{ + UA_TYPENAME("RegisterNodesRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {558}}, /* .typeId */ + sizeof(UA_RegisterNodesRequest), /* .memSize */ + UA_TYPES_REGISTERNODESREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 533, /* .binaryEncodingId */ - BrowseNextRequest_members /* .members */ + 2, /* .membersSize */ + 560, /* .binaryEncodingId */ + RegisterNodesRequest_members /* .members */ }, -/* CreateSubscriptionRequest */ +/* MethodAttributes */ { - UA_TYPENAME("CreateSubscriptionRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {785}}, /* .typeId */ - sizeof(UA_CreateSubscriptionRequest), /* .memSize */ - UA_TYPES_CREATESUBSCRIPTIONREQUEST, /* .typeIndex */ - 7, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("MethodAttributes") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {358}}, /* .typeId */ + sizeof(UA_MethodAttributes), /* .memSize */ + UA_TYPES_METHODATTRIBUTES, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 787, /* .binaryEncodingId */ - CreateSubscriptionRequest_members /* .members */ + 7, /* .membersSize */ + 360, /* .binaryEncodingId */ + MethodAttributes_members /* .members */ }, -/* VariableTypeAttributes */ +/* UserNameIdentityToken */ { - UA_TYPENAME("VariableTypeAttributes") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {364}}, /* .typeId */ - sizeof(UA_VariableTypeAttributes), /* .memSize */ - UA_TYPES_VARIABLETYPEATTRIBUTES, /* .typeIndex */ - 10, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("UserNameIdentityToken") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {322}}, /* .typeId */ + sizeof(UA_UserNameIdentityToken), /* .memSize */ + UA_TYPES_USERNAMEIDENTITYTOKEN, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 366, /* .binaryEncodingId */ - VariableTypeAttributes_members /* .members */ + 4, /* .membersSize */ + 324, /* .binaryEncodingId */ + UserNameIdentityToken_members /* .members */ }, -/* BrowsePathResult */ +/* UnregisterNodesRequest */ { - UA_TYPENAME("BrowsePathResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {549}}, /* .typeId */ - sizeof(UA_BrowsePathResult), /* .memSize */ - UA_TYPES_BROWSEPATHRESULT, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("UnregisterNodesRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {564}}, /* .typeId */ + sizeof(UA_UnregisterNodesRequest), /* .memSize */ + UA_TYPES_UNREGISTERNODESREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 551, /* .binaryEncodingId */ - BrowsePathResult_members /* .members */ + 2, /* .membersSize */ + 566, /* .binaryEncodingId */ + UnregisterNodesRequest_members /* .members */ }, -/* ModifySubscriptionResponse */ +/* OpenSecureChannelResponse */ { - UA_TYPENAME("ModifySubscriptionResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {794}}, /* .typeId */ - sizeof(UA_ModifySubscriptionResponse), /* .memSize */ - UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE, /* .typeIndex */ + UA_TYPENAME("OpenSecureChannelResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {447}}, /* .typeId */ + sizeof(UA_OpenSecureChannelResponse), /* .memSize */ + UA_TYPES_OPENSECURECHANNELRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 4, /* .membersSize */ - false, /* .builtin */ + 449, /* .binaryEncodingId */ + OpenSecureChannelResponse_members /* .members */ +}, +/* SetTriggeringResponse */ +{ + UA_TYPENAME("SetTriggeringResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {776}}, /* .typeId */ + sizeof(UA_SetTriggeringResponse), /* .memSize */ + UA_TYPES_SETTRIGGERINGRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 796, /* .binaryEncodingId */ - ModifySubscriptionResponse_members /* .members */ + 5, /* .membersSize */ + 778, /* .binaryEncodingId */ + SetTriggeringResponse_members /* .members */ }, -/* RedundantServerDataType */ +/* SimpleAttributeOperand */ { - UA_TYPENAME("RedundantServerDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {853}}, /* .typeId */ - sizeof(UA_RedundantServerDataType), /* .memSize */ - UA_TYPES_REDUNDANTSERVERDATATYPE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("SimpleAttributeOperand") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {601}}, /* .typeId */ + sizeof(UA_SimpleAttributeOperand), /* .memSize */ + UA_TYPES_SIMPLEATTRIBUTEOPERAND, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 4, /* .membersSize */ + 603, /* .binaryEncodingId */ + SimpleAttributeOperand_members /* .members */ +}, +/* RepublishRequest */ +{ + UA_TYPENAME("RepublishRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {830}}, /* .typeId */ + sizeof(UA_RepublishRequest), /* .memSize */ + UA_TYPES_REPUBLISHREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 855, /* .binaryEncodingId */ - RedundantServerDataType_members /* .members */ + 3, /* .membersSize */ + 832, /* .binaryEncodingId */ + RepublishRequest_members /* .members */ }, /* RegisterNodesResponse */ { @@ -15488,113 +16499,51 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {561}}, /* .typeId */ sizeof(UA_RegisterNodesResponse), /* .memSize */ UA_TYPES_REGISTERNODESRESPONSE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 563, /* .binaryEncodingId */ RegisterNodesResponse_members /* .members */ }, -/* CloseSessionRequest */ -{ - UA_TYPENAME("CloseSessionRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {471}}, /* .typeId */ - sizeof(UA_CloseSessionRequest), /* .memSize */ - UA_TYPES_CLOSESESSIONREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 473, /* .binaryEncodingId */ - CloseSessionRequest_members /* .members */ -}, /* ModifyMonitoredItemsResponse */ { UA_TYPENAME("ModifyMonitoredItemsResponse") /* .typeName */ {0, UA_NODEIDTYPE_NUMERIC, {764}}, /* .typeId */ sizeof(UA_ModifyMonitoredItemsResponse), /* .memSize */ UA_TYPES_MODIFYMONITOREDITEMSRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 3, /* .membersSize */ 766, /* .binaryEncodingId */ ModifyMonitoredItemsResponse_members /* .members */ }, -/* ModifySubscriptionRequest */ +/* DeleteSubscriptionsRequest */ { - UA_TYPENAME("ModifySubscriptionRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {791}}, /* .typeId */ - sizeof(UA_ModifySubscriptionRequest), /* .memSize */ - UA_TYPES_MODIFYSUBSCRIPTIONREQUEST, /* .typeIndex */ - 7, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("DeleteSubscriptionsRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {845}}, /* .typeId */ + sizeof(UA_DeleteSubscriptionsRequest), /* .memSize */ + UA_TYPES_DELETESUBSCRIPTIONSREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 793, /* .binaryEncodingId */ - ModifySubscriptionRequest_members /* .members */ + 2, /* .membersSize */ + 847, /* .binaryEncodingId */ + DeleteSubscriptionsRequest_members /* .members */ }, -/* ServerDiagnosticsSummaryDataType */ +/* RedundancySupport */ { - UA_TYPENAME("ServerDiagnosticsSummaryDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {859}}, /* .typeId */ - sizeof(UA_ServerDiagnosticsSummaryDataType), /* .memSize */ - UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE, /* .typeIndex */ - 12, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("RedundancySupport") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {851}}, /* .typeId */ + sizeof(UA_RedundancySupport), /* .memSize */ + UA_TYPES_INT32, /* .typeIndex */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ - true - && UA_BINARY_OVERLAYABLE_INTEGER - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, serverViewCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, currentSessionCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSessionCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedSessionCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedSessionCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, sessionTimeoutCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, sessionAbortCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, currentSubscriptionCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, cumulatedSubscriptionCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, publishingIntervalCount) + sizeof(UA_UInt32)) - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_ServerDiagnosticsSummaryDataType, rejectedRequestsCount) == (offsetof(UA_ServerDiagnosticsSummaryDataType, securityRejectedRequestsCount) + sizeof(UA_UInt32)), /* .overlayable */ - 861, /* .binaryEncodingId */ - ServerDiagnosticsSummaryDataType_members /* .members */ -}, -/* UserTokenPolicy */ -{ - UA_TYPENAME("UserTokenPolicy") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {304}}, /* .typeId */ - sizeof(UA_UserTokenPolicy), /* .memSize */ - UA_TYPES_USERTOKENPOLICY, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 306, /* .binaryEncodingId */ - UserTokenPolicy_members /* .members */ -}, -/* ReferenceTypeAttributes */ -{ - UA_TYPENAME("ReferenceTypeAttributes") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {367}}, /* .typeId */ - sizeof(UA_ReferenceTypeAttributes), /* .memSize */ - UA_TYPES_REFERENCETYPEATTRIBUTES, /* .typeIndex */ - 8, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 369, /* .binaryEncodingId */ - ReferenceTypeAttributes_members /* .members */ + UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ + 0, /* .binaryEncodingId */ + RedundancySupport_members /* .members */ }, /* BrowsePath */ { @@ -15602,376 +16551,103 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {543}}, /* .typeId */ sizeof(UA_BrowsePath), /* .memSize */ UA_TYPES_BROWSEPATH, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 545, /* .binaryEncodingId */ BrowsePath_members /* .members */ }, -/* SetMonitoringModeRequest */ -{ - UA_TYPENAME("SetMonitoringModeRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {767}}, /* .typeId */ - sizeof(UA_SetMonitoringModeRequest), /* .memSize */ - UA_TYPES_SETMONITORINGMODEREQUEST, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 769, /* .binaryEncodingId */ - SetMonitoringModeRequest_members /* .members */ -}, -/* UnregisterNodesResponse */ -{ - UA_TYPENAME("UnregisterNodesResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {567}}, /* .typeId */ - sizeof(UA_UnregisterNodesResponse), /* .memSize */ - UA_TYPES_UNREGISTERNODESRESPONSE, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 569, /* .binaryEncodingId */ - UnregisterNodesResponse_members /* .members */ -}, -/* WriteRequest */ -{ - UA_TYPENAME("WriteRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {671}}, /* .typeId */ - sizeof(UA_WriteRequest), /* .memSize */ - UA_TYPES_WRITEREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 673, /* .binaryEncodingId */ - WriteRequest_members /* .members */ -}, /* ObjectAttributes */ { UA_TYPENAME("ObjectAttributes") /* .typeName */ {0, UA_NODEIDTYPE_NUMERIC, {352}}, /* .typeId */ sizeof(UA_ObjectAttributes), /* .memSize */ UA_TYPES_OBJECTATTRIBUTES, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 6, /* .membersSize */ 354, /* .binaryEncodingId */ ObjectAttributes_members /* .members */ }, -/* BrowseResultMask */ -{ - UA_TYPENAME("BrowseResultMask") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {517}}, /* .typeId */ - sizeof(UA_BrowseResultMask), /* .memSize */ - UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ - true, /* .pointerFree */ - UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ - 0, /* .binaryEncodingId */ - BrowseResultMask_members /* .members */ -}, -/* BrowseDescription */ -{ - UA_TYPENAME("BrowseDescription") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {514}}, /* .typeId */ - sizeof(UA_BrowseDescription), /* .memSize */ - UA_TYPES_BROWSEDESCRIPTION, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 516, /* .binaryEncodingId */ - BrowseDescription_members /* .members */ -}, -/* SetTriggeringRequest */ -{ - UA_TYPENAME("SetTriggeringRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {773}}, /* .typeId */ - sizeof(UA_SetTriggeringRequest), /* .memSize */ - UA_TYPES_SETTRIGGERINGREQUEST, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 775, /* .binaryEncodingId */ - SetTriggeringRequest_members /* .members */ -}, -/* SessionSecurityDiagnosticsDataType */ -{ - UA_TYPENAME("SessionSecurityDiagnosticsDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {868}}, /* .typeId */ - sizeof(UA_SessionSecurityDiagnosticsDataType), /* .memSize */ - UA_TYPES_SESSIONSECURITYDIAGNOSTICSDATATYPE, /* .typeIndex */ - 9, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 870, /* .binaryEncodingId */ - SessionSecurityDiagnosticsDataType_members /* .members */ -}, -/* RepublishRequest */ -{ - UA_TYPENAME("RepublishRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {830}}, /* .typeId */ - sizeof(UA_RepublishRequest), /* .memSize */ - UA_TYPES_REPUBLISHREQUEST, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 832, /* .binaryEncodingId */ - RepublishRequest_members /* .members */ -}, -/* GetEndpointsRequest */ -{ - UA_TYPENAME("GetEndpointsRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {426}}, /* .typeId */ - sizeof(UA_GetEndpointsRequest), /* .memSize */ - UA_TYPES_GETENDPOINTSREQUEST, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 428, /* .binaryEncodingId */ - GetEndpointsRequest_members /* .members */ -}, /* PublishRequest */ { UA_TYPENAME("PublishRequest") /* .typeName */ {0, UA_NODEIDTYPE_NUMERIC, {824}}, /* .typeId */ sizeof(UA_PublishRequest), /* .memSize */ UA_TYPES_PUBLISHREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 826, /* .binaryEncodingId */ PublishRequest_members /* .members */ }, -/* DeleteSubscriptionsResponse */ -{ - UA_TYPENAME("DeleteSubscriptionsResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {848}}, /* .typeId */ - sizeof(UA_DeleteSubscriptionsResponse), /* .memSize */ - UA_TYPES_DELETESUBSCRIPTIONSRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 850, /* .binaryEncodingId */ - DeleteSubscriptionsResponse_members /* .members */ -}, -/* AddNodesResponse */ -{ - UA_TYPENAME("AddNodesResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {489}}, /* .typeId */ - sizeof(UA_AddNodesResponse), /* .memSize */ - UA_TYPES_ADDNODESRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 491, /* .binaryEncodingId */ - AddNodesResponse_members /* .members */ -}, -/* DataChangeNotification */ -{ - UA_TYPENAME("DataChangeNotification") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {809}}, /* .typeId */ - sizeof(UA_DataChangeNotification), /* .memSize */ - UA_TYPES_DATACHANGENOTIFICATION, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 811, /* .binaryEncodingId */ - DataChangeNotification_members /* .members */ -}, -/* CloseSecureChannelResponse */ -{ - UA_TYPENAME("CloseSecureChannelResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {453}}, /* .typeId */ - sizeof(UA_CloseSecureChannelResponse), /* .memSize */ - UA_TYPES_CLOSESECURECHANNELRESPONSE, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 455, /* .binaryEncodingId */ - CloseSecureChannelResponse_members /* .members */ -}, -/* ModifyMonitoredItemsRequest */ -{ - UA_TYPENAME("ModifyMonitoredItemsRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {761}}, /* .typeId */ - sizeof(UA_ModifyMonitoredItemsRequest), /* .memSize */ - UA_TYPES_MODIFYMONITOREDITEMSREQUEST, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 763, /* .binaryEncodingId */ - ModifyMonitoredItemsRequest_members /* .members */ -}, -/* SetMonitoringModeResponse */ -{ - UA_TYPENAME("SetMonitoringModeResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {770}}, /* .typeId */ - sizeof(UA_SetMonitoringModeResponse), /* .memSize */ - UA_TYPES_SETMONITORINGMODERESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 772, /* .binaryEncodingId */ - SetMonitoringModeResponse_members /* .members */ -}, /* FindServersRequest */ { UA_TYPENAME("FindServersRequest") /* .typeName */ {0, UA_NODEIDTYPE_NUMERIC, {420}}, /* .typeId */ sizeof(UA_FindServersRequest), /* .memSize */ UA_TYPES_FINDSERVERSREQUEST, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 4, /* .membersSize */ 422, /* .binaryEncodingId */ FindServersRequest_members /* .members */ }, +/* FindServersOnNetworkResponse */ +{ + UA_TYPENAME("FindServersOnNetworkResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {12191}}, /* .typeId */ + sizeof(UA_FindServersOnNetworkResponse), /* .memSize */ + UA_TYPES_FINDSERVERSONNETWORKRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 3, /* .membersSize */ + 12209, /* .binaryEncodingId */ + FindServersOnNetworkResponse_members /* .members */ +}, /* ReferenceDescription */ { UA_TYPENAME("ReferenceDescription") /* .typeName */ {0, UA_NODEIDTYPE_NUMERIC, {518}}, /* .typeId */ sizeof(UA_ReferenceDescription), /* .memSize */ UA_TYPES_REFERENCEDESCRIPTION, /* .typeIndex */ - 7, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 7, /* .membersSize */ 520, /* .binaryEncodingId */ ReferenceDescription_members /* .members */ }, -/* SetPublishingModeResponse */ -{ - UA_TYPENAME("SetPublishingModeResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {800}}, /* .typeId */ - sizeof(UA_SetPublishingModeResponse), /* .memSize */ - UA_TYPES_SETPUBLISHINGMODERESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 802, /* .binaryEncodingId */ - SetPublishingModeResponse_members /* .members */ -}, -/* ContentFilterResult */ -{ - UA_TYPENAME("ContentFilterResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {607}}, /* .typeId */ - sizeof(UA_ContentFilterResult), /* .memSize */ - UA_TYPES_CONTENTFILTERRESULT, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 609, /* .binaryEncodingId */ - ContentFilterResult_members /* .members */ -}, -/* RegisterServerResponse */ -{ - UA_TYPENAME("RegisterServerResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {438}}, /* .typeId */ - sizeof(UA_RegisterServerResponse), /* .memSize */ - UA_TYPES_REGISTERSERVERRESPONSE, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 440, /* .binaryEncodingId */ - RegisterServerResponse_members /* .members */ -}, -/* AddReferencesItem */ -{ - UA_TYPENAME("AddReferencesItem") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {379}}, /* .typeId */ - sizeof(UA_AddReferencesItem), /* .memSize */ - UA_TYPES_ADDREFERENCESITEM, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 381, /* .binaryEncodingId */ - AddReferencesItem_members /* .members */ -}, -/* QueryDataDescription */ -{ - UA_TYPENAME("QueryDataDescription") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {570}}, /* .typeId */ - sizeof(UA_QueryDataDescription), /* .memSize */ - UA_TYPES_QUERYDATADESCRIPTION, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 572, /* .binaryEncodingId */ - QueryDataDescription_members /* .members */ -}, -/* CreateSubscriptionResponse */ -{ - UA_TYPENAME("CreateSubscriptionResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {788}}, /* .typeId */ - sizeof(UA_CreateSubscriptionResponse), /* .memSize */ - UA_TYPES_CREATESUBSCRIPTIONRESPONSE, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 790, /* .binaryEncodingId */ - CreateSubscriptionResponse_members /* .members */ -}, -/* NetworkGroupDataType */ -{ - UA_TYPENAME("NetworkGroupDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {11944}}, /* .typeId */ - sizeof(UA_NetworkGroupDataType), /* .memSize */ - UA_TYPES_NETWORKGROUPDATATYPE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 11958, /* .binaryEncodingId */ - NetworkGroupDataType_members /* .members */ -}, -/* DeleteReferencesResponse */ +/* CreateSubscriptionRequest */ { - UA_TYPENAME("DeleteReferencesResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {507}}, /* .typeId */ - sizeof(UA_DeleteReferencesResponse), /* .memSize */ - UA_TYPES_DELETEREFERENCESRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("CreateSubscriptionRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {785}}, /* .typeId */ + sizeof(UA_CreateSubscriptionRequest), /* .memSize */ + UA_TYPES_CREATESUBSCRIPTIONREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 509, /* .binaryEncodingId */ - DeleteReferencesResponse_members /* .members */ + 7, /* .membersSize */ + 787, /* .binaryEncodingId */ + CreateSubscriptionRequest_members /* .members */ }, -/* CreateMonitoredItemsResponse */ +/* FindServersOnNetworkRequest */ { - UA_TYPENAME("CreateMonitoredItemsResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {752}}, /* .typeId */ - sizeof(UA_CreateMonitoredItemsResponse), /* .memSize */ - UA_TYPES_CREATEMONITOREDITEMSRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("FindServersOnNetworkRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {12190}}, /* .typeId */ + sizeof(UA_FindServersOnNetworkRequest), /* .memSize */ + UA_TYPES_FINDSERVERSONNETWORKREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 754, /* .binaryEncodingId */ - CreateMonitoredItemsResponse_members /* .members */ + 4, /* .membersSize */ + 12208, /* .binaryEncodingId */ + FindServersOnNetworkRequest_members /* .members */ }, /* CallResponse */ { @@ -15979,10 +16655,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {713}}, /* .typeId */ sizeof(UA_CallResponse), /* .memSize */ UA_TYPES_CALLRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 3, /* .membersSize */ 715, /* .binaryEncodingId */ CallResponse_members /* .members */ }, @@ -15992,90 +16668,64 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {501}}, /* .typeId */ sizeof(UA_DeleteNodesResponse), /* .memSize */ UA_TYPES_DELETENODESRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 3, /* .membersSize */ 503, /* .binaryEncodingId */ DeleteNodesResponse_members /* .members */ }, -/* RepublishResponse */ -{ - UA_TYPENAME("RepublishResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {833}}, /* .typeId */ - sizeof(UA_RepublishResponse), /* .memSize */ - UA_TYPES_REPUBLISHRESPONSE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 835, /* .binaryEncodingId */ - RepublishResponse_members /* .members */ -}, -/* MonitoredItemCreateRequest */ +/* ModifyMonitoredItemsRequest */ { - UA_TYPENAME("MonitoredItemCreateRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {743}}, /* .typeId */ - sizeof(UA_MonitoredItemCreateRequest), /* .memSize */ - UA_TYPES_MONITOREDITEMCREATEREQUEST, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ModifyMonitoredItemsRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {761}}, /* .typeId */ + sizeof(UA_ModifyMonitoredItemsRequest), /* .memSize */ + UA_TYPES_MODIFYMONITOREDITEMSREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 745, /* .binaryEncodingId */ - MonitoredItemCreateRequest_members /* .members */ + 4, /* .membersSize */ + 763, /* .binaryEncodingId */ + ModifyMonitoredItemsRequest_members /* .members */ }, -/* DeleteReferencesRequest */ +/* ServiceFault */ { - UA_TYPENAME("DeleteReferencesRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {504}}, /* .typeId */ - sizeof(UA_DeleteReferencesRequest), /* .memSize */ - UA_TYPES_DELETEREFERENCESREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ServiceFault") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {395}}, /* .typeId */ + sizeof(UA_ServiceFault), /* .memSize */ + UA_TYPES_SERVICEFAULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 506, /* .binaryEncodingId */ - DeleteReferencesRequest_members /* .members */ + 1, /* .membersSize */ + 397, /* .binaryEncodingId */ + ServiceFault_members /* .members */ }, -/* ReadResponse */ +/* PublishResponse */ { - UA_TYPENAME("ReadResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {632}}, /* .typeId */ - sizeof(UA_ReadResponse), /* .memSize */ - UA_TYPES_READRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("PublishResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {827}}, /* .typeId */ + sizeof(UA_PublishResponse), /* .memSize */ + UA_TYPES_PUBLISHRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 634, /* .binaryEncodingId */ - ReadResponse_members /* .members */ + 7, /* .membersSize */ + 829, /* .binaryEncodingId */ + PublishResponse_members /* .members */ }, -/* AddReferencesRequest */ +/* CreateMonitoredItemsRequest */ { - UA_TYPENAME("AddReferencesRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {492}}, /* .typeId */ - sizeof(UA_AddReferencesRequest), /* .memSize */ - UA_TYPES_ADDREFERENCESREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("CreateMonitoredItemsRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {749}}, /* .typeId */ + sizeof(UA_CreateMonitoredItemsRequest), /* .memSize */ + UA_TYPES_CREATEMONITOREDITEMSREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 494, /* .binaryEncodingId */ - AddReferencesRequest_members /* .members */ -}, -/* ReadRequest */ -{ - UA_TYPENAME("ReadRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {629}}, /* .typeId */ - sizeof(UA_ReadRequest), /* .memSize */ - UA_TYPES_READREQUEST, /* .typeIndex */ 4, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 631, /* .binaryEncodingId */ - ReadRequest_members /* .members */ + 751, /* .binaryEncodingId */ + CreateMonitoredItemsRequest_members /* .members */ }, /* OpenSecureChannelRequest */ { @@ -16083,212 +16733,103 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {444}}, /* .typeId */ sizeof(UA_OpenSecureChannelRequest), /* .memSize */ UA_TYPES_OPENSECURECHANNELREQUEST, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 6, /* .membersSize */ 446, /* .binaryEncodingId */ OpenSecureChannelRequest_members /* .members */ }, -/* RegisterServer2Response */ -{ - UA_TYPENAME("RegisterServer2Response") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {12194}}, /* .typeId */ - sizeof(UA_RegisterServer2Response), /* .memSize */ - UA_TYPES_REGISTERSERVER2RESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 12212, /* .binaryEncodingId */ - RegisterServer2Response_members /* .members */ -}, -/* AddNodesItem */ -{ - UA_TYPENAME("AddNodesItem") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {376}}, /* .typeId */ - sizeof(UA_AddNodesItem), /* .memSize */ - UA_TYPES_ADDNODESITEM, /* .typeIndex */ - 7, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 378, /* .binaryEncodingId */ - AddNodesItem_members /* .members */ -}, -/* NodeTypeDescription */ +/* CloseSessionRequest */ { - UA_TYPENAME("NodeTypeDescription") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {573}}, /* .typeId */ - sizeof(UA_NodeTypeDescription), /* .memSize */ - UA_TYPES_NODETYPEDESCRIPTION, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("CloseSessionRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {471}}, /* .typeId */ + sizeof(UA_CloseSessionRequest), /* .memSize */ + UA_TYPES_CLOSESESSIONREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 575, /* .binaryEncodingId */ - NodeTypeDescription_members /* .members */ + 2, /* .membersSize */ + 473, /* .binaryEncodingId */ + CloseSessionRequest_members /* .members */ }, -/* ServerStatusDataType */ +/* SetTriggeringRequest */ { - UA_TYPENAME("ServerStatusDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {862}}, /* .typeId */ - sizeof(UA_ServerStatusDataType), /* .memSize */ - UA_TYPES_SERVERSTATUSDATATYPE, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("SetTriggeringRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {773}}, /* .typeId */ + sizeof(UA_SetTriggeringRequest), /* .memSize */ + UA_TYPES_SETTRIGGERINGREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 864, /* .binaryEncodingId */ - ServerStatusDataType_members /* .members */ -}, -/* AttributeOperand */ -{ - UA_TYPENAME("AttributeOperand") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {598}}, /* .typeId */ - sizeof(UA_AttributeOperand), /* .memSize */ - UA_TYPES_ATTRIBUTEOPERAND, /* .typeIndex */ 5, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 600, /* .binaryEncodingId */ - AttributeOperand_members /* .members */ -}, -/* AddReferencesResponse */ -{ - UA_TYPENAME("AddReferencesResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {495}}, /* .typeId */ - sizeof(UA_AddReferencesResponse), /* .memSize */ - UA_TYPES_ADDREFERENCESRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 497, /* .binaryEncodingId */ - AddReferencesResponse_members /* .members */ + 775, /* .binaryEncodingId */ + SetTriggeringRequest_members /* .members */ }, -/* EventFilterResult */ +/* BrowseResult */ { - UA_TYPENAME("EventFilterResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {734}}, /* .typeId */ - sizeof(UA_EventFilterResult), /* .memSize */ - UA_TYPES_EVENTFILTERRESULT, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("BrowseResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {522}}, /* .typeId */ + sizeof(UA_BrowseResult), /* .memSize */ + UA_TYPES_BROWSERESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 736, /* .binaryEncodingId */ - EventFilterResult_members /* .members */ -}, -/* TranslateBrowsePathsToNodeIdsResponse */ -{ - UA_TYPENAME("TranslateBrowsePathsToNodeIdsResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {555}}, /* .typeId */ - sizeof(UA_TranslateBrowsePathsToNodeIdsResponse), /* .memSize */ - UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE, /* .typeIndex */ 3, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 557, /* .binaryEncodingId */ - TranslateBrowsePathsToNodeIdsResponse_members /* .members */ -}, -/* DataChangeFilter */ -{ - UA_TYPENAME("DataChangeFilter") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {722}}, /* .typeId */ - sizeof(UA_DataChangeFilter), /* .memSize */ - UA_TYPES_DATACHANGEFILTER, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ - true, /* .pointerFree */ - true - && UA_BINARY_OVERLAYABLE_INTEGER - && UA_BINARY_OVERLAYABLE_INTEGER - && offsetof(UA_DataChangeFilter, deadbandType) == (offsetof(UA_DataChangeFilter, trigger) + sizeof(UA_DataChangeTrigger)) - && UA_BINARY_OVERLAYABLE_FLOAT - && offsetof(UA_DataChangeFilter, deadbandValue) == (offsetof(UA_DataChangeFilter, deadbandType) + sizeof(UA_UInt32)), /* .overlayable */ - 724, /* .binaryEncodingId */ - DataChangeFilter_members /* .members */ + 524, /* .binaryEncodingId */ + BrowseResult_members /* .members */ }, -/* ContentFilterElement */ +/* AddReferencesRequest */ { - UA_TYPENAME("ContentFilterElement") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {583}}, /* .typeId */ - sizeof(UA_ContentFilterElement), /* .memSize */ - UA_TYPES_CONTENTFILTERELEMENT, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("AddReferencesRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {492}}, /* .typeId */ + sizeof(UA_AddReferencesRequest), /* .memSize */ + UA_TYPES_ADDREFERENCESREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 585, /* .binaryEncodingId */ - ContentFilterElement_members /* .members */ -}, -/* TranslateBrowsePathsToNodeIdsRequest */ -{ - UA_TYPENAME("TranslateBrowsePathsToNodeIdsRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {552}}, /* .typeId */ - sizeof(UA_TranslateBrowsePathsToNodeIdsRequest), /* .memSize */ - UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST, /* .typeIndex */ 2, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 554, /* .binaryEncodingId */ - TranslateBrowsePathsToNodeIdsRequest_members /* .members */ + 494, /* .binaryEncodingId */ + AddReferencesRequest_members /* .members */ }, -/* CloseSessionResponse */ +/* AddNodesItem */ { - UA_TYPENAME("CloseSessionResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {474}}, /* .typeId */ - sizeof(UA_CloseSessionResponse), /* .memSize */ - UA_TYPES_CLOSESESSIONRESPONSE, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("AddNodesItem") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {376}}, /* .typeId */ + sizeof(UA_AddNodesItem), /* .memSize */ + UA_TYPES_ADDNODESITEM, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 476, /* .binaryEncodingId */ - CloseSessionResponse_members /* .members */ -}, -/* ApplicationDescription */ -{ - UA_TYPENAME("ApplicationDescription") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {308}}, /* .typeId */ - sizeof(UA_ApplicationDescription), /* .memSize */ - UA_TYPES_APPLICATIONDESCRIPTION, /* .typeIndex */ 7, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 310, /* .binaryEncodingId */ - ApplicationDescription_members /* .members */ + 378, /* .binaryEncodingId */ + AddNodesItem_members /* .members */ }, -/* SessionDiagnosticsDataType */ +/* ServerStatusDataType */ { - UA_TYPENAME("SessionDiagnosticsDataType") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {865}}, /* .typeId */ - sizeof(UA_SessionDiagnosticsDataType), /* .memSize */ - UA_TYPES_SESSIONDIAGNOSTICSDATATYPE, /* .typeIndex */ - 43, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ServerStatusDataType") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {862}}, /* .typeId */ + sizeof(UA_ServerStatusDataType), /* .memSize */ + UA_TYPES_SERVERSTATUSDATATYPE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 867, /* .binaryEncodingId */ - SessionDiagnosticsDataType_members /* .members */ + 6, /* .membersSize */ + 864, /* .binaryEncodingId */ + ServerStatusDataType_members /* .members */ }, -/* ServiceFault */ +/* BrowseNextResponse */ { - UA_TYPENAME("ServiceFault") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {395}}, /* .typeId */ - sizeof(UA_ServiceFault), /* .memSize */ - UA_TYPES_SERVICEFAULT, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("BrowseNextResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {534}}, /* .typeId */ + sizeof(UA_BrowseNextResponse), /* .memSize */ + UA_TYPES_BROWSENEXTRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 397, /* .binaryEncodingId */ - ServiceFault_members /* .members */ + 3, /* .membersSize */ + 536, /* .binaryEncodingId */ + BrowseNextResponse_members /* .members */ }, /* RegisteredServer */ { @@ -16296,90 +16837,64 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {432}}, /* .typeId */ sizeof(UA_RegisteredServer), /* .memSize */ UA_TYPES_REGISTEREDSERVER, /* .typeIndex */ - 8, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 8, /* .membersSize */ 434, /* .binaryEncodingId */ RegisteredServer_members /* .members */ }, -/* AggregateFilter */ -{ - UA_TYPENAME("AggregateFilter") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {728}}, /* .typeId */ - sizeof(UA_AggregateFilter), /* .memSize */ - UA_TYPES_AGGREGATEFILTER, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 730, /* .binaryEncodingId */ - AggregateFilter_members /* .members */ -}, -/* RegisterServerRequest */ +/* ApplicationDescription */ { - UA_TYPENAME("RegisterServerRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {435}}, /* .typeId */ - sizeof(UA_RegisterServerRequest), /* .memSize */ - UA_TYPES_REGISTERSERVERREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ApplicationDescription") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {308}}, /* .typeId */ + sizeof(UA_ApplicationDescription), /* .memSize */ + UA_TYPES_APPLICATIONDESCRIPTION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 437, /* .binaryEncodingId */ - RegisterServerRequest_members /* .members */ + 7, /* .membersSize */ + 310, /* .binaryEncodingId */ + ApplicationDescription_members /* .members */ }, -/* EndpointDescription */ +/* ReadRequest */ { - UA_TYPENAME("EndpointDescription") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {312}}, /* .typeId */ - sizeof(UA_EndpointDescription), /* .memSize */ - UA_TYPES_ENDPOINTDESCRIPTION, /* .typeIndex */ - 8, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ReadRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {629}}, /* .typeId */ + sizeof(UA_ReadRequest), /* .memSize */ + UA_TYPES_READREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 314, /* .binaryEncodingId */ - EndpointDescription_members /* .members */ -}, -/* CreateMonitoredItemsRequest */ -{ - UA_TYPENAME("CreateMonitoredItemsRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {749}}, /* .typeId */ - sizeof(UA_CreateMonitoredItemsRequest), /* .memSize */ - UA_TYPES_CREATEMONITOREDITEMSREQUEST, /* .typeIndex */ 4, /* .membersSize */ - false, /* .builtin */ - false, /* .pointerFree */ - false, /* .overlayable */ - 751, /* .binaryEncodingId */ - CreateMonitoredItemsRequest_members /* .members */ + 631, /* .binaryEncodingId */ + ReadRequest_members /* .members */ }, -/* ContentFilter */ +/* ActivateSessionRequest */ { - UA_TYPENAME("ContentFilter") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {586}}, /* .typeId */ - sizeof(UA_ContentFilter), /* .memSize */ - UA_TYPES_CONTENTFILTER, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ActivateSessionRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {465}}, /* .typeId */ + sizeof(UA_ActivateSessionRequest), /* .memSize */ + UA_TYPES_ACTIVATESESSIONREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 588, /* .binaryEncodingId */ - ContentFilter_members /* .members */ + 6, /* .membersSize */ + 467, /* .binaryEncodingId */ + ActivateSessionRequest_members /* .members */ }, -/* QueryFirstResponse */ +/* BrowsePathResult */ { - UA_TYPENAME("QueryFirstResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {616}}, /* .typeId */ - sizeof(UA_QueryFirstResponse), /* .memSize */ - UA_TYPES_QUERYFIRSTRESPONSE, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("BrowsePathResult") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {549}}, /* .typeId */ + sizeof(UA_BrowsePathResult), /* .memSize */ + UA_TYPES_BROWSEPATHRESULT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 618, /* .binaryEncodingId */ - QueryFirstResponse_members /* .members */ + 2, /* .membersSize */ + 551, /* .binaryEncodingId */ + BrowsePathResult_members /* .members */ }, /* AddNodesRequest */ { @@ -16387,10 +16902,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {486}}, /* .typeId */ sizeof(UA_AddNodesRequest), /* .memSize */ UA_TYPES_ADDNODESREQUEST, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 488, /* .binaryEncodingId */ AddNodesRequest_members /* .members */ }, @@ -16400,25 +16915,38 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {525}}, /* .typeId */ sizeof(UA_BrowseRequest), /* .memSize */ UA_TYPES_BROWSEREQUEST, /* .typeIndex */ - 4, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 4, /* .membersSize */ 527, /* .binaryEncodingId */ BrowseRequest_members /* .members */ }, -/* BrowseResult */ +/* WriteRequest */ { - UA_TYPENAME("BrowseResult") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {522}}, /* .typeId */ - sizeof(UA_BrowseResult), /* .memSize */ - UA_TYPES_BROWSERESULT, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("WriteRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {671}}, /* .typeId */ + sizeof(UA_WriteRequest), /* .memSize */ + UA_TYPES_WRITEREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 524, /* .binaryEncodingId */ - BrowseResult_members /* .members */ + 2, /* .membersSize */ + 673, /* .binaryEncodingId */ + WriteRequest_members /* .members */ +}, +/* AddNodesResponse */ +{ + UA_TYPENAME("AddNodesResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {489}}, /* .typeId */ + sizeof(UA_AddNodesResponse), /* .memSize */ + UA_TYPES_ADDNODESRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 3, /* .membersSize */ + 491, /* .binaryEncodingId */ + AddNodesResponse_members /* .members */ }, /* RegisterServer2Request */ { @@ -16426,51 +16954,82 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {12193}}, /* .typeId */ sizeof(UA_RegisterServer2Request), /* .memSize */ UA_TYPES_REGISTERSERVER2REQUEST, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 3, /* .membersSize */ 12211, /* .binaryEncodingId */ RegisterServer2Request_members /* .members */ }, -/* CreateSessionRequest */ +/* AttributeOperand */ { - UA_TYPENAME("CreateSessionRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {459}}, /* .typeId */ - sizeof(UA_CreateSessionRequest), /* .memSize */ - UA_TYPES_CREATESESSIONREQUEST, /* .typeIndex */ - 9, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("AttributeOperand") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {598}}, /* .typeId */ + sizeof(UA_AttributeOperand), /* .memSize */ + UA_TYPES_ATTRIBUTEOPERAND, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 461, /* .binaryEncodingId */ - CreateSessionRequest_members /* .members */ + 5, /* .membersSize */ + 600, /* .binaryEncodingId */ + AttributeOperand_members /* .members */ }, -/* EventFilter */ +/* DataChangeFilter */ { - UA_TYPENAME("EventFilter") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {725}}, /* .typeId */ - sizeof(UA_EventFilter), /* .memSize */ - UA_TYPES_EVENTFILTER, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("DataChangeFilter") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {722}}, /* .typeId */ + sizeof(UA_DataChangeFilter), /* .memSize */ + UA_TYPES_DATACHANGEFILTER, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + true, /* .pointerFree */ + true + && UA_BINARY_OVERLAYABLE_INTEGER + && UA_BINARY_OVERLAYABLE_INTEGER + && offsetof(UA_DataChangeFilter, deadbandType) == (offsetof(UA_DataChangeFilter, trigger) + sizeof(UA_DataChangeTrigger)) + && UA_BINARY_OVERLAYABLE_FLOAT + && offsetof(UA_DataChangeFilter, deadbandValue) == (offsetof(UA_DataChangeFilter, deadbandType) + sizeof(UA_UInt32)), /* .overlayable */ + 3, /* .membersSize */ + 724, /* .binaryEncodingId */ + DataChangeFilter_members /* .members */ +}, +/* EndpointDescription */ +{ + UA_TYPENAME("EndpointDescription") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {312}}, /* .typeId */ + sizeof(UA_EndpointDescription), /* .memSize */ + UA_TYPES_ENDPOINTDESCRIPTION, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 727, /* .binaryEncodingId */ - EventFilter_members /* .members */ + 8, /* .membersSize */ + 314, /* .binaryEncodingId */ + EndpointDescription_members /* .members */ }, -/* GetEndpointsResponse */ +/* DeleteReferencesRequest */ { - UA_TYPENAME("GetEndpointsResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {429}}, /* .typeId */ - sizeof(UA_GetEndpointsResponse), /* .memSize */ - UA_TYPES_GETENDPOINTSRESPONSE, /* .typeIndex */ + UA_TYPENAME("DeleteReferencesRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {504}}, /* .typeId */ + sizeof(UA_DeleteReferencesRequest), /* .memSize */ + UA_TYPES_DELETEREFERENCESREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ 2, /* .membersSize */ - false, /* .builtin */ + 506, /* .binaryEncodingId */ + DeleteReferencesRequest_members /* .members */ +}, +/* TranslateBrowsePathsToNodeIdsRequest */ +{ + UA_TYPENAME("TranslateBrowsePathsToNodeIdsRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {552}}, /* .typeId */ + sizeof(UA_TranslateBrowsePathsToNodeIdsRequest), /* .memSize */ + UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 431, /* .binaryEncodingId */ - GetEndpointsResponse_members /* .members */ + 2, /* .membersSize */ + 554, /* .binaryEncodingId */ + TranslateBrowsePathsToNodeIdsRequest_members /* .members */ }, /* FindServersResponse */ { @@ -16478,25 +17037,64 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {423}}, /* .typeId */ sizeof(UA_FindServersResponse), /* .memSize */ UA_TYPES_FINDSERVERSRESPONSE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 425, /* .binaryEncodingId */ FindServersResponse_members /* .members */ }, -/* BrowseNextResponse */ +/* CreateSessionRequest */ { - UA_TYPENAME("BrowseNextResponse") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {534}}, /* .typeId */ - sizeof(UA_BrowseNextResponse), /* .memSize */ - UA_TYPES_BROWSENEXTRESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("CreateSessionRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {459}}, /* .typeId */ + sizeof(UA_CreateSessionRequest), /* .memSize */ + UA_TYPES_CREATESESSIONREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 536, /* .binaryEncodingId */ - BrowseNextResponse_members /* .members */ + 9, /* .membersSize */ + 461, /* .binaryEncodingId */ + CreateSessionRequest_members /* .members */ +}, +/* ContentFilterElement */ +{ + UA_TYPENAME("ContentFilterElement") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {583}}, /* .typeId */ + sizeof(UA_ContentFilterElement), /* .memSize */ + UA_TYPES_CONTENTFILTERELEMENT, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 2, /* .membersSize */ + 585, /* .binaryEncodingId */ + ContentFilterElement_members /* .members */ +}, +/* RegisterServerRequest */ +{ + UA_TYPENAME("RegisterServerRequest") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {435}}, /* .typeId */ + sizeof(UA_RegisterServerRequest), /* .memSize */ + UA_TYPES_REGISTERSERVERREQUEST, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 2, /* .membersSize */ + 437, /* .binaryEncodingId */ + RegisterServerRequest_members /* .members */ +}, +/* TranslateBrowsePathsToNodeIdsResponse */ +{ + UA_TYPENAME("TranslateBrowsePathsToNodeIdsResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {555}}, /* .typeId */ + sizeof(UA_TranslateBrowsePathsToNodeIdsResponse), /* .memSize */ + UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 3, /* .membersSize */ + 557, /* .binaryEncodingId */ + TranslateBrowsePathsToNodeIdsResponse_members /* .members */ }, /* BrowseResponse */ { @@ -16504,10 +17102,10 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {528}}, /* .typeId */ sizeof(UA_BrowseResponse), /* .memSize */ UA_TYPES_BROWSERESPONSE, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 3, /* .membersSize */ 530, /* .binaryEncodingId */ BrowseResponse_members /* .members */ }, @@ -16517,273 +17115,285 @@ const UA_DataType UA_TYPES[UA_TYPES_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {462}}, /* .typeId */ sizeof(UA_CreateSessionResponse), /* .memSize */ UA_TYPES_CREATESESSIONRESPONSE, /* .typeIndex */ - 10, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 10, /* .membersSize */ 464, /* .binaryEncodingId */ CreateSessionResponse_members /* .members */ }, -/* QueryFirstRequest */ +/* ContentFilter */ { - UA_TYPENAME("QueryFirstRequest") /* .typeName */ - {0, UA_NODEIDTYPE_NUMERIC, {613}}, /* .typeId */ - sizeof(UA_QueryFirstRequest), /* .memSize */ - UA_TYPES_QUERYFIRSTREQUEST, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ + UA_TYPENAME("ContentFilter") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {586}}, /* .typeId */ + sizeof(UA_ContentFilter), /* .memSize */ + UA_TYPES_CONTENTFILTER, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ - 615, /* .binaryEncodingId */ - QueryFirstRequest_members /* .members */ + 1, /* .membersSize */ + 588, /* .binaryEncodingId */ + ContentFilter_members /* .members */ +}, +/* GetEndpointsResponse */ +{ + UA_TYPENAME("GetEndpointsResponse") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {429}}, /* .typeId */ + sizeof(UA_GetEndpointsResponse), /* .memSize */ + UA_TYPES_GETENDPOINTSRESPONSE, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 2, /* .membersSize */ + 431, /* .binaryEncodingId */ + GetEndpointsResponse_members /* .members */ +}, +/* EventFilter */ +{ + UA_TYPENAME("EventFilter") /* .typeName */ + {0, UA_NODEIDTYPE_NUMERIC, {725}}, /* .typeId */ + sizeof(UA_EventFilter), /* .memSize */ + UA_TYPES_EVENTFILTER, /* .typeIndex */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ + false, /* .pointerFree */ + false, /* .overlayable */ + 2, /* .membersSize */ + 727, /* .binaryEncodingId */ + EventFilter_members /* .members */ }, }; -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_transport_generated.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/transport_generated.c" ***********************************/ /* Generated from Opc.Ua.Types.bsd, Custom.Opc.Ua.Transport.bsd with script /home/jvoe/open62541/tools/generate_datatypes.py - * on host rigel by user jvoe at 2019-01-04 01:18:40 */ + * on host rigel by user jvoe at 2019-07-30 11:30:09 */ /* SecureConversationMessageAbortBody */ static UA_DataTypeMember SecureConversationMessageAbortBody_members[2] = { { - UA_TYPENAME("error") /* .memberName */ + UA_TYPENAME("Error") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("reason") /* .memberName */ + UA_TYPENAME("Reason") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_SecureConversationMessageAbortBody, reason) - offsetof(UA_SecureConversationMessageAbortBody, error) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* SecureConversationMessageFooter */ static UA_DataTypeMember SecureConversationMessageFooter_members[2] = { { - UA_TYPENAME("padding") /* .memberName */ + UA_TYPENAME("Padding") /* .memberName */ UA_TYPES_BYTE, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ true /* .isArray */ }, { - UA_TYPENAME("signature") /* .memberName */ + UA_TYPENAME("Signature") /* .memberName */ UA_TYPES_BYTE, /* .memberTypeIndex */ offsetof(UA_SecureConversationMessageFooter, signature) - offsetof(UA_SecureConversationMessageFooter, padding) - sizeof(void*), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* TcpHelloMessage */ static UA_DataTypeMember TcpHelloMessage_members[6] = { { - UA_TYPENAME("protocolVersion") /* .memberName */ + UA_TYPENAME("ProtocolVersion") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("receiveBufferSize") /* .memberName */ + UA_TYPENAME("ReceiveBufferSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpHelloMessage, receiveBufferSize) - offsetof(UA_TcpHelloMessage, protocolVersion) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("sendBufferSize") /* .memberName */ + UA_TYPENAME("SendBufferSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpHelloMessage, sendBufferSize) - offsetof(UA_TcpHelloMessage, receiveBufferSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxMessageSize") /* .memberName */ + UA_TYPENAME("MaxMessageSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpHelloMessage, maxMessageSize) - offsetof(UA_TcpHelloMessage, sendBufferSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxChunkCount") /* .memberName */ + UA_TYPENAME("MaxChunkCount") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpHelloMessage, maxChunkCount) - offsetof(UA_TcpHelloMessage, maxMessageSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("endpointUrl") /* .memberName */ + UA_TYPENAME("EndpointUrl") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_TcpHelloMessage, endpointUrl) - offsetof(UA_TcpHelloMessage, maxChunkCount) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* TcpErrorMessage */ static UA_DataTypeMember TcpErrorMessage_members[2] = { { - UA_TYPENAME("error") /* .memberName */ + UA_TYPENAME("Error") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("reason") /* .memberName */ + UA_TYPENAME("Reason") /* .memberName */ UA_TYPES_STRING, /* .memberTypeIndex */ offsetof(UA_TcpErrorMessage, reason) - offsetof(UA_TcpErrorMessage, error) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* MessageType */ -static UA_DataTypeMember MessageType_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define MessageType_members NULL /* AsymmetricAlgorithmSecurityHeader */ static UA_DataTypeMember AsymmetricAlgorithmSecurityHeader_members[3] = { { - UA_TYPENAME("securityPolicyUri") /* .memberName */ + UA_TYPENAME("SecurityPolicyUri") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("senderCertificate") /* .memberName */ + UA_TYPENAME("SenderCertificate") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ offsetof(UA_AsymmetricAlgorithmSecurityHeader, senderCertificate) - offsetof(UA_AsymmetricAlgorithmSecurityHeader, securityPolicyUri) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("receiverCertificateThumbprint") /* .memberName */ + UA_TYPENAME("ReceiverCertificateThumbprint") /* .memberName */ UA_TYPES_BYTESTRING, /* .memberTypeIndex */ offsetof(UA_AsymmetricAlgorithmSecurityHeader, receiverCertificateThumbprint) - offsetof(UA_AsymmetricAlgorithmSecurityHeader, senderCertificate) - sizeof(UA_ByteString), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* TcpAcknowledgeMessage */ static UA_DataTypeMember TcpAcknowledgeMessage_members[5] = { { - UA_TYPENAME("protocolVersion") /* .memberName */ + UA_TYPENAME("ProtocolVersion") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("receiveBufferSize") /* .memberName */ + UA_TYPENAME("ReceiveBufferSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpAcknowledgeMessage, receiveBufferSize) - offsetof(UA_TcpAcknowledgeMessage, protocolVersion) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("sendBufferSize") /* .memberName */ + UA_TYPENAME("SendBufferSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpAcknowledgeMessage, sendBufferSize) - offsetof(UA_TcpAcknowledgeMessage, receiveBufferSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxMessageSize") /* .memberName */ + UA_TYPENAME("MaxMessageSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpAcknowledgeMessage, maxMessageSize) - offsetof(UA_TcpAcknowledgeMessage, sendBufferSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("maxChunkCount") /* .memberName */ + UA_TYPENAME("MaxChunkCount") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpAcknowledgeMessage, maxChunkCount) - offsetof(UA_TcpAcknowledgeMessage, maxMessageSize) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* SequenceHeader */ static UA_DataTypeMember SequenceHeader_members[2] = { { - UA_TYPENAME("sequenceNumber") /* .memberName */ + UA_TYPENAME("SequenceNumber") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("requestId") /* .memberName */ + UA_TYPENAME("RequestId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_SequenceHeader, requestId) - offsetof(UA_SequenceHeader, sequenceNumber) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* TcpMessageHeader */ static UA_DataTypeMember TcpMessageHeader_members[2] = { { - UA_TYPENAME("messageTypeAndChunkType") /* .memberName */ + UA_TYPENAME("MessageTypeAndChunkType") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("messageSize") /* .memberName */ + UA_TYPENAME("MessageSize") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_TcpMessageHeader, messageSize) - offsetof(UA_TcpMessageHeader, messageTypeAndChunkType) - sizeof(UA_UInt32), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* ChunkType */ -static UA_DataTypeMember ChunkType_members[1] = { -{ - UA_TYPENAME("") /* .memberName */ - UA_TYPES_INT32, /* .memberTypeIndex */ - 0, /* .padding */ - true, /* .namespaceZero */ - false /* .isArray */ -}}; +#define ChunkType_members NULL /* SymmetricAlgorithmSecurityHeader */ static UA_DataTypeMember SymmetricAlgorithmSecurityHeader_members[1] = { { - UA_TYPENAME("tokenId") /* .memberName */ + UA_TYPENAME("TokenId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ 0, /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; /* SecureConversationMessageHeader */ static UA_DataTypeMember SecureConversationMessageHeader_members[2] = { { - UA_TYPENAME("messageHeader") /* .memberName */ + UA_TYPENAME("MessageHeader") /* .memberName */ UA_TRANSPORT_TCPMESSAGEHEADER, /* .memberTypeIndex */ 0, /* .padding */ false, /* .namespaceZero */ false /* .isArray */ }, { - UA_TYPENAME("secureChannelId") /* .memberName */ + UA_TYPENAME("SecureChannelId") /* .memberName */ UA_TYPES_UINT32, /* .memberTypeIndex */ offsetof(UA_SecureConversationMessageHeader, secureChannelId) - offsetof(UA_SecureConversationMessageHeader, messageHeader) - sizeof(UA_TcpMessageHeader), /* .padding */ true, /* .namespaceZero */ false /* .isArray */ -}}; +},}; const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { /* SecureConversationMessageAbortBody */ { @@ -16791,10 +17401,10 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_SecureConversationMessageAbortBody), /* .memSize */ UA_TRANSPORT_SECURECONVERSATIONMESSAGEABORTBODY, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 0, /* .binaryEncodingId */ SecureConversationMessageAbortBody_members /* .members */ }, @@ -16804,10 +17414,10 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_SecureConversationMessageFooter), /* .memSize */ UA_TRANSPORT_SECURECONVERSATIONMESSAGEFOOTER, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 0, /* .binaryEncodingId */ SecureConversationMessageFooter_members /* .members */ }, @@ -16817,10 +17427,10 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_TcpHelloMessage), /* .memSize */ UA_TRANSPORT_TCPHELLOMESSAGE, /* .typeIndex */ - 6, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 6, /* .membersSize */ 0, /* .binaryEncodingId */ TcpHelloMessage_members /* .members */ }, @@ -16830,10 +17440,10 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_TcpErrorMessage), /* .memSize */ UA_TRANSPORT_TCPERRORMESSAGE, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 2, /* .membersSize */ 0, /* .binaryEncodingId */ TcpErrorMessage_members /* .members */ }, @@ -16843,10 +17453,10 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_MessageType), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ MessageType_members /* .members */ }, @@ -16856,10 +17466,10 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_AsymmetricAlgorithmSecurityHeader), /* .memSize */ UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER, /* .typeIndex */ - 3, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ false, /* .pointerFree */ false, /* .overlayable */ + 3, /* .membersSize */ 0, /* .binaryEncodingId */ AsymmetricAlgorithmSecurityHeader_members /* .members */ }, @@ -16869,8 +17479,7 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_TcpAcknowledgeMessage), /* .memSize */ UA_TRANSPORT_TCPACKNOWLEDGEMESSAGE, /* .typeIndex */ - 5, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true && UA_BINARY_OVERLAYABLE_INTEGER @@ -16882,6 +17491,7 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { && offsetof(UA_TcpAcknowledgeMessage, maxMessageSize) == (offsetof(UA_TcpAcknowledgeMessage, sendBufferSize) + sizeof(UA_UInt32)) && UA_BINARY_OVERLAYABLE_INTEGER && offsetof(UA_TcpAcknowledgeMessage, maxChunkCount) == (offsetof(UA_TcpAcknowledgeMessage, maxMessageSize) + sizeof(UA_UInt32)), /* .overlayable */ + 5, /* .membersSize */ 0, /* .binaryEncodingId */ TcpAcknowledgeMessage_members /* .members */ }, @@ -16891,13 +17501,13 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_SequenceHeader), /* .memSize */ UA_TRANSPORT_SEQUENCEHEADER, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true && UA_BINARY_OVERLAYABLE_INTEGER && UA_BINARY_OVERLAYABLE_INTEGER && offsetof(UA_SequenceHeader, requestId) == (offsetof(UA_SequenceHeader, sequenceNumber) + sizeof(UA_UInt32)), /* .overlayable */ + 2, /* .membersSize */ 0, /* .binaryEncodingId */ SequenceHeader_members /* .members */ }, @@ -16907,13 +17517,13 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_TcpMessageHeader), /* .memSize */ UA_TRANSPORT_TCPMESSAGEHEADER, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true && UA_BINARY_OVERLAYABLE_INTEGER && UA_BINARY_OVERLAYABLE_INTEGER && offsetof(UA_TcpMessageHeader, messageSize) == (offsetof(UA_TcpMessageHeader, messageTypeAndChunkType) + sizeof(UA_UInt32)), /* .overlayable */ + 2, /* .membersSize */ 0, /* .binaryEncodingId */ TcpMessageHeader_members /* .members */ }, @@ -16923,10 +17533,10 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_ChunkType), /* .memSize */ UA_TYPES_INT32, /* .typeIndex */ - 1, /* .membersSize */ - true, /* .builtin */ + UA_DATATYPEKIND_ENUM, /* .typeKind */ true, /* .pointerFree */ UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 0, /* .membersSize */ 0, /* .binaryEncodingId */ ChunkType_members /* .members */ }, @@ -16936,11 +17546,11 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_SymmetricAlgorithmSecurityHeader), /* .memSize */ UA_TRANSPORT_SYMMETRICALGORITHMSECURITYHEADER, /* .typeIndex */ - 1, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true && UA_BINARY_OVERLAYABLE_INTEGER, /* .overlayable */ + 1, /* .membersSize */ 0, /* .binaryEncodingId */ SymmetricAlgorithmSecurityHeader_members /* .members */ }, @@ -16950,8 +17560,7 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { {0, UA_NODEIDTYPE_NUMERIC, {0}}, /* .typeId */ sizeof(UA_SecureConversationMessageHeader), /* .memSize */ UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER, /* .typeIndex */ - 2, /* .membersSize */ - false, /* .builtin */ + UA_DATATYPEKIND_STRUCTURE, /* .typeKind */ true, /* .pointerFree */ true && true @@ -16960,24 +17569,21 @@ const UA_DataType UA_TRANSPORT[UA_TRANSPORT_COUNT] = { && offsetof(UA_TcpMessageHeader, messageSize) == (offsetof(UA_TcpMessageHeader, messageTypeAndChunkType) + sizeof(UA_UInt32)) && UA_BINARY_OVERLAYABLE_INTEGER && offsetof(UA_SecureConversationMessageHeader, secureChannelId) == (offsetof(UA_SecureConversationMessageHeader, messageHeader) + sizeof(UA_TcpMessageHeader)), /* .overlayable */ + 2, /* .membersSize */ 0, /* .binaryEncodingId */ SecureConversationMessageHeader_members /* .members */ }, }; -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_statuscode_descriptions.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/statuscodes.c" ***********************************/ /********************************************************** * Autogenerated -- do not modify - * Generated from /home/jvoe/open62541/tools/schema/Opc.Ua.StatusCodes.csv with script /home/jvoe/open62541/tools/generate_statuscode_descriptions.py + * Generated from /home/jvoe/open62541/tools/schema/StatusCode.csv with script /home/jvoe/open62541/tools/generate_statuscode_descriptions.py *********************************************************/ - -/* Definition for the deprecated StatusCode description API */ -const UA_StatusCodeDescription statusCodeExplanation_default = {0xffffffff, "", ""}; - typedef struct { UA_StatusCode code; const char *name; @@ -16989,10 +17595,9 @@ const char * UA_StatusCode_name(UA_StatusCode code) { return emptyStatusCodeName; } #else -static const size_t statusCodeDescriptionsSize = 229; -static const UA_StatusCodeName statusCodeDescriptions[229] = { +static const size_t statusCodeDescriptionsSize = 237; +static const UA_StatusCodeName statusCodeDescriptions[237] = { {UA_STATUSCODE_GOOD, "Good"}, - {UA_STATUSCODE_BADUNEXPECTEDERROR, "BadUnexpectedError"}, {UA_STATUSCODE_BADINTERNALERROR, "BadInternalError"}, {UA_STATUSCODE_BADOUTOFMEMORY, "BadOutOfMemory"}, @@ -17015,6 +17620,7 @@ static const UA_StatusCodeName statusCodeDescriptions[229] = { {UA_STATUSCODE_BADDATATYPEIDUNKNOWN, "BadDataTypeIdUnknown"}, {UA_STATUSCODE_BADCERTIFICATEINVALID, "BadCertificateInvalid"}, {UA_STATUSCODE_BADSECURITYCHECKSFAILED, "BadSecurityChecksFailed"}, + {UA_STATUSCODE_BADCERTIFICATEPOLICYCHECKFAILED, "BadCertificatePolicyCheckFailed"}, {UA_STATUSCODE_BADCERTIFICATETIMEINVALID, "BadCertificateTimeInvalid"}, {UA_STATUSCODE_BADCERTIFICATEISSUERTIMEINVALID, "BadCertificateIssuerTimeInvalid"}, {UA_STATUSCODE_BADCERTIFICATEHOSTNAMEINVALID, "BadCertificateHostNameInvalid"}, @@ -17041,6 +17647,9 @@ static const UA_StatusCodeName statusCodeDescriptions[229] = { {UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID, "BadTimestampsToReturnInvalid"}, {UA_STATUSCODE_BADREQUESTCANCELLEDBYCLIENT, "BadRequestCancelledByClient"}, {UA_STATUSCODE_BADTOOMANYARGUMENTS, "BadTooManyArguments"}, + {UA_STATUSCODE_BADLICENSEEXPIRED, "BadLicenseExpired"}, + {UA_STATUSCODE_BADLICENSELIMITSEXCEEDED, "BadLicenseLimitsExceeded"}, + {UA_STATUSCODE_BADLICENSENOTAVAILABLE, "BadLicenseNotAvailable"}, {UA_STATUSCODE_GOODSUBSCRIPTIONTRANSFERRED, "GoodSubscriptionTransferred"}, {UA_STATUSCODE_GOODCOMPLETESASYNCHRONOUSLY, "GoodCompletesAsynchronously"}, {UA_STATUSCODE_GOODOVERLOAD, "GoodOverload"}, @@ -17080,6 +17689,7 @@ static const UA_StatusCodeName statusCodeDescriptions[229] = { {UA_STATUSCODE_BADREFERENCETYPEIDINVALID, "BadReferenceTypeIdInvalid"}, {UA_STATUSCODE_BADBROWSEDIRECTIONINVALID, "BadBrowseDirectionInvalid"}, {UA_STATUSCODE_BADNODENOTINVIEW, "BadNodeNotInView"}, + {UA_STATUSCODE_BADNUMERICOVERFLOW, "BadNumericOverflow"}, {UA_STATUSCODE_BADSERVERURIINVALID, "BadServerUriInvalid"}, {UA_STATUSCODE_BADSERVERNAMEMISSING, "BadServerNameMissing"}, {UA_STATUSCODE_BADDISCOVERYURLMISSING, "BadDiscoveryUrlMissing"}, @@ -17130,6 +17740,7 @@ static const UA_StatusCodeName statusCodeDescriptions[229] = { {UA_STATUSCODE_BADTYPEMISMATCH, "BadTypeMismatch"}, {UA_STATUSCODE_BADMETHODINVALID, "BadMethodInvalid"}, {UA_STATUSCODE_BADARGUMENTSMISSING, "BadArgumentsMissing"}, + {UA_STATUSCODE_BADNOTEXECUTABLE, "BadNotExecutable"}, {UA_STATUSCODE_BADTOOMANYSUBSCRIPTIONS, "BadTooManySubscriptions"}, {UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS, "BadTooManyPublishRequests"}, {UA_STATUSCODE_BADNOSUBSCRIPTION, "BadNoSubscription"}, @@ -17137,6 +17748,7 @@ static const UA_StatusCodeName statusCodeDescriptions[229] = { {UA_STATUSCODE_BADMESSAGENOTAVAILABLE, "BadMessageNotAvailable"}, {UA_STATUSCODE_BADINSUFFICIENTCLIENTPROFILE, "BadInsufficientClientProfile"}, {UA_STATUSCODE_BADSTATENOTACTIVE, "BadStateNotActive"}, + {UA_STATUSCODE_BADALREADYEXISTS, "BadAlreadyExists"}, {UA_STATUSCODE_BADTCPSERVERTOOBUSY, "BadTcpServerTooBusy"}, {UA_STATUSCODE_BADTCPMESSAGETYPEINVALID, "BadTcpMessageTypeInvalid"}, {UA_STATUSCODE_BADTCPSECURECHANNELUNKNOWN, "BadTcpSecureChannelUnknown"}, @@ -17196,6 +17808,7 @@ static const UA_StatusCodeName statusCodeDescriptions[229] = { {UA_STATUSCODE_BADAGGREGATECONFIGURATIONREJECTED, "BadAggregateConfigurationRejected"}, {UA_STATUSCODE_GOODDATAIGNORED, "GoodDataIgnored"}, {UA_STATUSCODE_BADREQUESTNOTALLOWED, "BadRequestNotAllowed"}, + {UA_STATUSCODE_BADREQUESTNOTCOMPLETE, "BadRequestNotComplete"}, {UA_STATUSCODE_GOODEDITED, "GoodEdited"}, {UA_STATUSCODE_GOODPOSTACTIONFAILED, "GoodPostActionFailed"}, {UA_STATUSCODE_UNCERTAINDOMINANTVALUECHANGED, "UncertainDominantValueChanged"}, @@ -17239,14 +17852,16 @@ const char * UA_StatusCode_name(UA_StatusCode code) { * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014, 2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014, 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014 (c) Florian Palm * Copyright 2017 (c) Stefan Profanter, fortiss GmbH */ + + size_t -UA_readNumber(u8 *buf, size_t buflen, u32 *number) { +UA_readNumberWithBase(const UA_Byte *buf, size_t buflen, UA_UInt32 *number, UA_Byte base) { UA_assert(buf); UA_assert(number); u32 n = 0; @@ -17254,24 +17869,37 @@ UA_readNumber(u8 *buf, size_t buflen, u32 *number) { /* read numbers until the end or a non-number character appears */ while(progress < buflen) { u8 c = buf[progress]; - if(c < '0' || c > '9') - break; - n = (n*10) + (u32)(c-'0'); + if(c >= '0' && c <= '9' && c <= '0' + (base-1)) + n = (n * base) + c - '0'; + else if(base > 9 && c >= 'a' && c <= 'z' && c <= 'a' + (base-11)) + n = (n * base) + c-'a' + 10; + else if(base > 9 && c >= 'A' && c <= 'Z' && c <= 'A' + (base-11)) + n = (n * base) + c-'A' + 10; + else + break; ++progress; } *number = n; return progress; } +size_t +UA_readNumber(UA_Byte *buf, size_t buflen, UA_UInt32 *number) +{ + return UA_readNumberWithBase(buf, buflen, number, 10); +} + UA_StatusCode UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname, u16 *outPort, UA_String *outPath) { /* Url must begin with "opc.tcp://" or opc.udp:// (if pubsub enabled) */ if(endpointUrl->length < 11) { return UA_STATUSCODE_BADTCPENDPOINTURLINVALID; - } else if (strncmp((char*)endpointUrl->data, "opc.tcp://", 10) != 0) { + } + if (strncmp((char*)endpointUrl->data, "opc.tcp://", 10) != 0) { #ifdef UA_ENABLE_PUBSUB - if (strncmp((char*)endpointUrl->data, "opc.udp://", 10) != 0) { + if (strncmp((char*)endpointUrl->data, "opc.udp://", 10) != 0 && + strncmp((char*)endpointUrl->data, "opc.mqtt://", 11) != 0) { return UA_STATUSCODE_BADTCPENDPOINTURLINVALID; } #else @@ -17336,404 +17964,701 @@ UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname, return UA_STATUSCODE_GOOD; } -/*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_timer.c" ***********************************/ +UA_StatusCode +UA_parseEndpointUrlEthernet(const UA_String *endpointUrl, UA_String *target, + UA_UInt16 *vid, UA_Byte *pcp) { + /* Url must begin with "opc.eth://" */ + if(endpointUrl->length < 11) { + return UA_STATUSCODE_BADINTERNALERROR; + } + if(strncmp((char*) endpointUrl->data, "opc.eth://", 10) != 0) { + return UA_STATUSCODE_BADINTERNALERROR; + } -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB - * Copyright 2017 (c) Stefan Profanter, fortiss GmbH - */ + /* Where does the host address end? */ + size_t curr = 10; + for(; curr < endpointUrl->length; ++curr) { + if(endpointUrl->data[curr] == ':') { + break; + } + } + /* set host address */ + target->data = &endpointUrl->data[10]; + target->length = curr - 10; + if(curr == endpointUrl->length) { + return UA_STATUSCODE_GOOD; + } -/* Only one thread operates on the repeated jobs. This is usually the "main" - * thread with the event loop. All other threads introduce changes via a - * multi-producer single-consumer (MPSC) queue. The queue is based on a design - * by Dmitry Vyukov. - * http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue - * - * The RepeatedCallback structure is used both in the sorted list of callbacks - * and in the MPSC changes queue. For the changes queue, we differentiate - * between three cases encoded in the callback pointer. - * - * callback > 0x01: add the new repeated callback to the sorted list - * callback == 0x00: remove the callback with the same id - * callback == 0x01: change the interval of the existing callback */ + /* Set VLAN */ + u32 value = 0; + curr++; /* skip ':' */ + size_t progress = UA_readNumber(&endpointUrl->data[curr], + endpointUrl->length - curr, &value); + if(progress == 0 || value > 4096) { + return UA_STATUSCODE_BADINTERNALERROR; + } + curr += progress; + if(curr == endpointUrl->length || endpointUrl->data[curr] == '.') { + *vid = (UA_UInt16) value; + } + if(curr == endpointUrl->length) { + return UA_STATUSCODE_GOOD; + } -#define REMOVE_SENTINEL 0x00 -#define CHANGE_SENTINEL 0x01 + /* Set priority */ + if(endpointUrl->data[curr] != '.') { + return UA_STATUSCODE_BADINTERNALERROR; + } + curr++; /* skip '.' */ + progress = UA_readNumber(&endpointUrl->data[curr], + endpointUrl->length - curr, &value); + if(progress == 0 || value > 7) { + return UA_STATUSCODE_BADINTERNALERROR; + } + curr += progress; + if(curr != endpointUrl->length) { + return UA_STATUSCODE_BADINTERNALERROR; + } + *pcp = (UA_Byte) value; -struct UA_TimerCallbackEntry { - SLIST_ENTRY(UA_TimerCallbackEntry) next; /* Next element in the list */ - UA_DateTime nextTime; /* The next time when the callbacks - * are to be executed */ - UA_UInt64 interval; /* Interval in 100ns resolution */ - UA_UInt64 id; /* Id of the repeated callback */ + return UA_STATUSCODE_GOOD; +} - UA_TimerCallback callback; - void *data; -}; +UA_StatusCode UA_ByteString_toBase64String(const UA_ByteString *byteString, UA_String *str) { + if (str->length != 0) { + UA_free(str->data); + str->data = NULL; + str->length = 0; + } + if (byteString == NULL || byteString->data == NULL) + return UA_STATUSCODE_GOOD; + if (byteString == str) + return UA_STATUSCODE_BADINVALIDARGUMENT; -void -UA_Timer_init(UA_Timer *t) { - SLIST_INIT(&t->repeatedCallbacks); - t->changes_head = (UA_TimerCallbackEntry*)&t->changes_stub; - t->changes_tail = (UA_TimerCallbackEntry*)&t->changes_stub; - t->changes_stub = NULL; - t->idCounter = 0; + int resSize = 0; + str->data = (UA_Byte*)UA_base64(byteString->data, (int)byteString->length, &resSize); + str->length = (size_t) resSize; + if (str->data == NULL) + return UA_STATUSCODE_BADOUTOFMEMORY; + + return UA_STATUSCODE_GOOD; } -static void -enqueueChange(UA_Timer *t, UA_TimerCallbackEntry *tc) { - tc->next.sle_next = NULL; - UA_TimerCallbackEntry *prev = (UA_TimerCallbackEntry*) - UA_atomic_xchg((void * volatile *)&t->changes_head, tc); - /* Nothing can be dequeued while the producer is blocked here */ - prev->next.sle_next = tc; /* Once this change is visible in the consumer, - * the node is dequeued in the following - * iteration */ -} - -static UA_TimerCallbackEntry * -dequeueChange(UA_Timer *t) { - UA_TimerCallbackEntry *tail = t->changes_tail; - UA_TimerCallbackEntry *next = tail->next.sle_next; - if(tail == (UA_TimerCallbackEntry*)&t->changes_stub) { - if(!next) - return NULL; - t->changes_tail = next; - tail = next; - next = next->next.sle_next; +UA_StatusCode +UA_NodeId_toString(const UA_NodeId *nodeId, UA_String *nodeIdStr) { + if (nodeIdStr->length != 0) { + UA_free(nodeIdStr->data); + nodeIdStr->data = NULL; + nodeIdStr->length = 0; } - if(next) { - t->changes_tail = next; - return tail; + if (nodeId == NULL) + return UA_STATUSCODE_GOOD; + + char *nsStr = NULL; + long snprintfLen = 0; + size_t nsLen = 0; + if (nodeId->namespaceIndex != 0) { + nsStr = (char*)UA_malloc(9+1); // strlen("ns=XXXXX;") = 9 + Nullbyte + snprintfLen = UA_snprintf(nsStr, 10, "ns=%d;", nodeId->namespaceIndex); + if (snprintfLen < 0 || snprintfLen >= 10) { + UA_free(nsStr); + return UA_STATUSCODE_BADINTERNALERROR; + } + nsLen = (size_t)(snprintfLen); } - UA_TimerCallbackEntry* head = t->changes_head; - if(tail != head) - return NULL; - enqueueChange(t, (UA_TimerCallbackEntry*)&t->changes_stub); - next = tail->next.sle_next; - if(next) { - t->changes_tail = next; - return tail; + + + UA_ByteString byteStr = UA_BYTESTRING_NULL; + switch (nodeId->identifierType) { + case UA_NODEIDTYPE_NUMERIC: + /* ns (2 byte, 65535) = 5 chars, numeric (4 byte, 4294967295) = 10 chars, delim = 1 , nullbyte = 1-> 17 chars */ + nodeIdStr->length = nsLen + 2 + 10 + 1; + nodeIdStr->data = (UA_Byte*)UA_malloc(nodeIdStr->length); + if (nodeIdStr->data == NULL) { + nodeIdStr->length = 0; + UA_free(nsStr); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + snprintfLen =UA_snprintf((char*)nodeIdStr->data, nodeIdStr->length, "%si=%lu", + nsLen > 0 ? nsStr : "", + (unsigned long )nodeId->identifier.numeric); + break; + case UA_NODEIDTYPE_STRING: + /* ns (16bit) = 5 chars, strlen + nullbyte */ + nodeIdStr->length = nsLen + 2 + nodeId->identifier.string.length + 1; + nodeIdStr->data = (UA_Byte*)UA_malloc(nodeIdStr->length); + if (nodeIdStr->data == NULL) { + nodeIdStr->length = 0; + UA_free(nsStr); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + snprintfLen =UA_snprintf((char*)nodeIdStr->data, nodeIdStr->length, "%ss=%.*s", + nsLen > 0 ? nsStr : "", + (int)nodeId->identifier.string.length, nodeId->identifier.string.data); + break; + case UA_NODEIDTYPE_GUID: + /* ns (16bit) = 5 chars + strlen(A123456C-0ABC-1A2B-815F-687212AAEE1B)=36 + nullbyte */ + nodeIdStr->length = nsLen + 2 + 36 + 1; + nodeIdStr->data = (UA_Byte*)UA_malloc(nodeIdStr->length); + if (nodeIdStr->data == NULL) { + nodeIdStr->length = 0; + UA_free(nsStr); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + snprintfLen = UA_snprintf((char*)nodeIdStr->data, nodeIdStr->length, "%sg=" UA_PRINTF_GUID_FORMAT, + nsLen > 0 ? nsStr : "", + UA_PRINTF_GUID_DATA(nodeId->identifier.guid)); + break; + case UA_NODEIDTYPE_BYTESTRING: + UA_ByteString_toBase64String(&nodeId->identifier.byteString, &byteStr); + /* ns (16bit) = 5 chars + LEN + nullbyte */ + nodeIdStr->length = nsLen + 2 + byteStr.length + 1; + nodeIdStr->data = (UA_Byte*)UA_malloc(nodeIdStr->length); + if (nodeIdStr->data == NULL) { + nodeIdStr->length = 0; + UA_String_deleteMembers(&byteStr); + UA_free(nsStr); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + snprintfLen = UA_snprintf((char*)nodeIdStr->data, nodeIdStr->length, "%sb=%.*s", + nsLen > 0 ? nsStr : "", + (int)byteStr.length, byteStr.data); + UA_String_deleteMembers(&byteStr); + break; } - return NULL; -} + UA_free(nsStr); -/* Adding repeated callbacks: Add an entry with the "nextTime" timestamp in the - * future. This will be picked up in the next iteration and inserted at the - * correct place. So that the next execution takes place ät "nextTime". */ -UA_StatusCode -UA_Timer_addRepeatedCallback(UA_Timer *t, UA_TimerCallback callback, - void *data, UA_UInt32 interval, - UA_UInt64 *callbackId) { - /* A callback method needs to be present */ - if(!callback) + if (snprintfLen < 0 || snprintfLen >= (long) nodeIdStr->length) { + UA_free(nodeIdStr->data); + nodeIdStr->data = NULL; + nodeIdStr->length = 0; return UA_STATUSCODE_BADINTERNALERROR; + } + nodeIdStr->length = (size_t)snprintfLen; - /* The interval needs to be at least 5ms */ - if(interval < 5) - return UA_STATUSCODE_BADINTERNALERROR; + return UA_STATUSCODE_GOOD; +} - /* Allocate the repeated callback structure */ - UA_TimerCallbackEntry *tc = - (UA_TimerCallbackEntry*)UA_malloc(sizeof(UA_TimerCallbackEntry)); - if(!tc) - return UA_STATUSCODE_BADOUTOFMEMORY; - /* Set the repeated callback */ - tc->interval = (UA_UInt64)interval * UA_DATETIME_MSEC; - tc->id = ++t->idCounter; - tc->callback = callback; - tc->data = data; - tc->nextTime = UA_DateTime_nowMonotonic() + (UA_DateTime)tc->interval; +/*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_workqueue.c" ***********************************/ - /* Set the output identifier */ - if(callbackId) - *callbackId = tc->id; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2014-2016 (c) Sten Grüner + * Copyright 2015 (c) Chris Iatrou + * Copyright 2015 (c) Nick Goossens + * Copyright 2015 (c) Jörg Schüler-Maroldt + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2016-2017 (c) Florian Palm + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2016 (c) Lorenz Haas + * Copyright 2017 (c) Jonas Green + */ - /* Enqueue the changes in the MPSC queue */ - enqueueChange(t, tc); - return UA_STATUSCODE_GOOD; + +void UA_WorkQueue_init(UA_WorkQueue *wq) { + /* Initialized the linked list for delayed callbacks */ + SIMPLEQ_INIT(&wq->delayedCallbacks); + +#ifdef UA_ENABLE_MULTITHREADING + wq->delayedCallbacks_checkpoint = NULL; + pthread_mutex_init(&wq->delayedCallbacks_accessMutex, NULL); + + /* Initialize the dispatch queue for worker threads */ + SIMPLEQ_INIT(&wq->dispatchQueue); + pthread_mutex_init(&wq->dispatchQueue_accessMutex, NULL); + pthread_cond_init(&wq->dispatchQueue_condition, NULL); + pthread_mutex_init(&wq->dispatchQueue_conditionMutex, NULL); +#endif } -static void -addTimerCallbackEntry(UA_Timer *t, UA_TimerCallbackEntry * UA_RESTRICT tc) { - /* Find the last entry before this callback */ - UA_TimerCallbackEntry *tmpTc, *afterTc = NULL; - SLIST_FOREACH(tmpTc, &t->repeatedCallbacks, next) { - if(tmpTc->nextTime >= tc->nextTime) - break; +#ifdef UA_ENABLE_MULTITHREADING +/* Forward declaration */ +static void UA_WorkQueue_manuallyProcessDelayed(UA_WorkQueue *wq); +#endif + +void UA_WorkQueue_cleanup(UA_WorkQueue *wq) { +#ifdef UA_ENABLE_MULTITHREADING + /* Shut down workers */ + UA_WorkQueue_stop(wq); - /* The goal is to have many repeated callbacks with the same repetition - * interval in a "block" in order to reduce linear search for re-entry - * to the sorted list after processing. Allow the first execution to lie - * between "nextTime - 1s" and "nextTime" if this adjustment groups - * callbacks with the same repetition interval. - * Callbacks of a block are added in reversed order. This design allows - * the monitored items of a subscription (if created in a sequence with the - * same publish/sample interval) to be executed before the subscription - * publish the notifications */ - if(tmpTc->interval == tc->interval && - tmpTc->nextTime > (tc->nextTime - UA_DATETIME_SEC)) { - tc->nextTime = tmpTc->nextTime; + /* Execute remaining work in the dispatch queue */ + while(true) { + pthread_mutex_lock(&wq->dispatchQueue_accessMutex); + UA_DelayedCallback *dc = SIMPLEQ_FIRST(&wq->dispatchQueue); + if(!dc) { + pthread_mutex_unlock(&wq->dispatchQueue_accessMutex); break; } + SIMPLEQ_REMOVE_HEAD(&wq->dispatchQueue, next); + pthread_mutex_unlock(&wq->dispatchQueue_accessMutex); + dc->callback(dc->application, dc->data); + UA_free(dc); + } +#endif + + /* All workers are shut down. Execute remaining delayed work here. */ + UA_WorkQueue_manuallyProcessDelayed(wq); + +#ifdef UA_ENABLE_MULTITHREADING + wq->delayedCallbacks_checkpoint = NULL; + pthread_mutex_destroy(&wq->dispatchQueue_accessMutex); + pthread_cond_destroy(&wq->dispatchQueue_condition); + pthread_mutex_destroy(&wq->dispatchQueue_conditionMutex); + pthread_mutex_destroy(&wq->delayedCallbacks_accessMutex); +#endif +} - /* tc is neither in the same interval nor supposed to be executed sooner - * than tmpTc. Update afterTc to push tc further back in the timer list. */ - afterTc = tmpTc; +/***********/ +/* Workers */ +/***********/ + +#ifdef UA_ENABLE_MULTITHREADING + +static void * +workerLoop(UA_Worker *worker) { + UA_WorkQueue *wq = worker->queue; + UA_UInt32 *counter = &worker->counter; + volatile UA_Boolean *running = &worker->running; + + /* Initialize the (thread local) random seed with the ram address + * of the worker. Not for security-critical entropy! */ + UA_random_seed((uintptr_t)worker); + + while(*running) { + UA_atomic_addUInt32(counter, 1); + + /* Remove a callback from the queue */ + pthread_mutex_lock(&wq->dispatchQueue_accessMutex); + UA_DelayedCallback *dc = SIMPLEQ_FIRST(&wq->dispatchQueue); + if(dc) + SIMPLEQ_REMOVE_HEAD(&wq->dispatchQueue, next); + pthread_mutex_unlock(&wq->dispatchQueue_accessMutex); + + /* Nothing to do. Sleep until a callback is dispatched */ + if(!dc) { + pthread_mutex_lock(&wq->dispatchQueue_conditionMutex); + pthread_cond_wait(&wq->dispatchQueue_condition, + &wq->dispatchQueue_conditionMutex); + pthread_mutex_unlock(&wq->dispatchQueue_conditionMutex); + continue; + } + + /* Execute */ + if(dc->callback) + dc->callback(dc->application, dc->data); + UA_free(dc); } - /* Add the repeated callback */ - if(afterTc) - SLIST_INSERT_AFTER(afterTc, tc, next); - else - SLIST_INSERT_HEAD(&t->repeatedCallbacks, tc, next); + return NULL; } +/* Can be called repeatedly and starts additional workers */ UA_StatusCode -UA_Timer_changeRepeatedCallbackInterval(UA_Timer *t, UA_UInt64 callbackId, - UA_UInt32 interval) { - /* The interval needs to be at least 5ms */ - if(interval < 5) +UA_WorkQueue_start(UA_WorkQueue *wq, size_t workersCount) { + if(wq->workersSize > 0 || workersCount == 0) return UA_STATUSCODE_BADINTERNALERROR; - - /* Allocate the repeated callback structure */ - UA_TimerCallbackEntry *tc = - (UA_TimerCallbackEntry*)UA_malloc(sizeof(UA_TimerCallbackEntry)); - if(!tc) + + /* Create the worker array */ + wq->workers = (UA_Worker*)UA_calloc(workersCount, sizeof(UA_Worker)); + if(!wq->workers) return UA_STATUSCODE_BADOUTOFMEMORY; + wq->workersSize = workersCount; - /* Set the repeated callback */ - tc->interval = (UA_UInt64)interval * UA_DATETIME_MSEC; - tc->id = callbackId; - tc->nextTime = UA_DateTime_nowMonotonic() + (UA_DateTime)tc->interval; - tc->callback = (UA_TimerCallback)CHANGE_SENTINEL; - - /* Enqueue the changes in the MPSC queue */ - enqueueChange(t, tc); + /* Spin up the workers */ + for(size_t i = 0; i < workersCount; ++i) { + UA_Worker *w = &wq->workers[i]; + w->queue = wq; + w->counter = 0; + w->running = true; + pthread_create(&w->thread, NULL, (void* (*)(void*))workerLoop, w); + } return UA_STATUSCODE_GOOD; } -static void -changeTimerCallbackEntryInterval(UA_Timer *t, UA_UInt64 callbackId, - UA_UInt64 interval, UA_DateTime nextTime) { - /* Remove from the sorted list */ - UA_TimerCallbackEntry *tc, *prev = NULL; - SLIST_FOREACH(tc, &t->repeatedCallbacks, next) { - if(callbackId == tc->id) { - if(prev) - SLIST_REMOVE_AFTER(prev, next); - else - SLIST_REMOVE_HEAD(&t->repeatedCallbacks, next); - break; - } - prev = tc; - } - if(!tc) +void UA_WorkQueue_stop(UA_WorkQueue *wq) { + if(wq->workersSize == 0) return; - /* Adjust settings */ - tc->interval = interval; - tc->nextTime = nextTime; + /* Signal the workers to stop */ + for(size_t i = 0; i < wq->workersSize; ++i) + wq->workers[i].running = false; + + /* Wake up all workers */ + pthread_cond_broadcast(&wq->dispatchQueue_condition); + + /* Wait for the workers to finish, then clean up */ + for(size_t i = 0; i < wq->workersSize; ++i) + pthread_join(wq->workers[i].thread, NULL); - /* Reinsert at the new position */ - addTimerCallbackEntry(t, tc); + UA_free(wq->workers); + wq->workers = NULL; + wq->workersSize = 0; } -/* Removing a repeated callback: Add an entry with the "nextTime" timestamp set - * to UA_INT64_MAX. The next iteration picks this up and removes the repated - * callback from the linked list. */ -UA_StatusCode -UA_Timer_removeRepeatedCallback(UA_Timer *t, UA_UInt64 callbackId) { - /* Allocate the repeated callback structure */ - UA_TimerCallbackEntry *tc = - (UA_TimerCallbackEntry*)UA_malloc(sizeof(UA_TimerCallbackEntry)); - if(!tc) - return UA_STATUSCODE_BADOUTOFMEMORY; +void UA_WorkQueue_enqueue(UA_WorkQueue *wq, UA_ApplicationCallback cb, + void *application, void *data) { + UA_DelayedCallback *dc = (UA_DelayedCallback*)UA_malloc(sizeof(UA_DelayedCallback)); + if(!dc) { + cb(application, data); /* Execute immediately if the memory could not be allocated */ + return; + } - /* Set the repeated callback with the sentinel nextTime */ - tc->id = callbackId; - tc->callback = (UA_TimerCallback)REMOVE_SENTINEL; + dc->callback = cb; + dc->application = application; + dc->data = data; - /* Enqueue the changes in the MPSC queue */ - enqueueChange(t, tc); - return UA_STATUSCODE_GOOD; + /* Enqueue for the worker threads */ + pthread_mutex_lock(&wq->dispatchQueue_accessMutex); + SIMPLEQ_INSERT_TAIL(&wq->dispatchQueue, dc, next); + pthread_mutex_unlock(&wq->dispatchQueue_accessMutex); + + /* Wake up sleeping workers */ + pthread_cond_broadcast(&wq->dispatchQueue_condition); } +#endif + +/*********************/ +/* Delayed Callbacks */ +/*********************/ + +#ifdef UA_ENABLE_MULTITHREADING + +/* Delayed Callbacks are called only when all callbacks that were dispatched + * prior are finished. After every UA_MAX_DELAYED_SAMPLE delayed Callbacks that + * were added to the queue, we sample the counters from the workers. The + * counters are compared to the last counters that were sampled. If every worker + * has proceeded the counter, then we know that all delayed callbacks prior to + * the last sample-point are safe to execute. */ + +/* Sample the worker counter for every nth delayed callback. This is used to + * test that all workers have **finished** their current job before the delayed + * callback is processed. */ +#define UA_MAX_DELAYED_SAMPLE 100 + +/* Call only with a held mutex for the delayed callbacks */ static void -removeRepeatedCallback(UA_Timer *t, UA_UInt64 callbackId) { - UA_TimerCallbackEntry *tc, *prev = NULL; - SLIST_FOREACH(tc, &t->repeatedCallbacks, next) { - if(callbackId == tc->id) { - if(prev) - SLIST_REMOVE_AFTER(prev, next); - else - SLIST_REMOVE_HEAD(&t->repeatedCallbacks, next); - UA_free(tc); - break; - } - prev = tc; +dispatchDelayedCallbacks(UA_WorkQueue *wq, UA_DelayedCallback *cb) { + /* Are callbacks before the last checkpoint ready? */ + for(size_t i = 0; i < wq->workersSize; ++i) { + if(wq->workers[i].counter == wq->workers[i].checkpointCounter) + return; } -} -/* Process the changes that were added to the MPSC queue (by other threads) */ -static void -processChanges(UA_Timer *t) { - UA_TimerCallbackEntry *change; - while((change = dequeueChange(t))) { - switch((uintptr_t)change->callback) { - case REMOVE_SENTINEL: - removeRepeatedCallback(t, change->id); - UA_free(change); - break; - case CHANGE_SENTINEL: - changeTimerCallbackEntryInterval(t, change->id, change->interval, - change->nextTime); - UA_free(change); - break; - default: - addTimerCallbackEntry(t, change); + /* Dispatch all delayed callbacks up to the checkpoint. + * TODO: Move over the entire queue up to the checkpoint in one step. */ + if(wq->delayedCallbacks_checkpoint != NULL) { + UA_DelayedCallback *iter, *tmp_iter; + SIMPLEQ_FOREACH_SAFE(iter, &wq->delayedCallbacks, next, tmp_iter) { + pthread_mutex_lock(&wq->dispatchQueue_accessMutex); + SIMPLEQ_INSERT_TAIL(&wq->dispatchQueue, iter, next); + pthread_mutex_unlock(&wq->dispatchQueue_accessMutex); + if(iter == wq->delayedCallbacks_checkpoint) + break; } } + + /* Create the new sample point */ + for(size_t i = 0; i < wq->workersSize; ++i) + wq->workers[i].checkpointCounter = wq->workers[i].counter; + wq->delayedCallbacks_checkpoint = cb; } -UA_DateTime -UA_Timer_process(UA_Timer *t, UA_DateTime nowMonotonic, - UA_TimerDispatchCallback dispatchCallback, - void *application) { - /* Insert and remove callbacks */ - processChanges(t); - - /* Find the last callback to be executed now */ - UA_TimerCallbackEntry *firstAfter, *lastNow = NULL; - SLIST_FOREACH(firstAfter, &t->repeatedCallbacks, next) { - if(firstAfter->nextTime > nowMonotonic) - break; - lastNow = firstAfter; +#endif + +void +UA_WorkQueue_enqueueDelayed(UA_WorkQueue *wq, UA_DelayedCallback *cb) { +#ifdef UA_ENABLE_MULTITHREADING + pthread_mutex_lock(&wq->dispatchQueue_accessMutex); +#endif + + SIMPLEQ_INSERT_HEAD(&wq->delayedCallbacks, cb, next); + +#ifdef UA_ENABLE_MULTITHREADING + wq->delayedCallbacks_sinceDispatch++; + if(wq->delayedCallbacks_sinceDispatch > UA_MAX_DELAYED_SAMPLE) { + dispatchDelayedCallbacks(wq, cb); + wq->delayedCallbacks_sinceDispatch = 0; } + pthread_mutex_unlock(&wq->dispatchQueue_accessMutex); +#endif +} - /* Nothing to do */ - if(!lastNow) { - if(firstAfter) - return firstAfter->nextTime; - return UA_INT64_MAX; +/* Assumes all workers are shut down */ +void UA_WorkQueue_manuallyProcessDelayed(UA_WorkQueue *wq) { + UA_DelayedCallback *dc, *dc_tmp; + SIMPLEQ_FOREACH_SAFE(dc, &wq->delayedCallbacks, next, dc_tmp) { + SIMPLEQ_REMOVE_HEAD(&wq->delayedCallbacks, next); + if(dc->callback) + dc->callback(dc->application, dc->data); + UA_free(dc); } +#ifdef UA_ENABLE_MULTITHREADING + wq->delayedCallbacks_checkpoint = NULL; +#endif +} - /* Put the callbacks that are executed now in a separate list */ - UA_TimerCallbackList executedNowList; - executedNowList.slh_first = SLIST_FIRST(&t->repeatedCallbacks); - lastNow->next.sle_next = NULL; +/*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_timer.c" ***********************************/ - /* Fake entry to represent the first element in the newly-sorted list */ - UA_TimerCallbackEntry tmp_first; - tmp_first.nextTime = nowMonotonic - 1; /* never matches for last_dispatched */ - tmp_first.next.sle_next = firstAfter; - UA_TimerCallbackEntry *last_dispatched = &tmp_first; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2017, 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + */ - /* Iterate over the list of callbacks to process now */ - UA_TimerCallbackEntry *tc; - while((tc = SLIST_FIRST(&executedNowList))) { - /* Remove from the list */ - SLIST_REMOVE_HEAD(&executedNowList, next); - /* Dispatch/process callback */ - dispatchCallback(application, tc->callback, tc->data); +struct UA_TimerEntry { + ZIP_ENTRY(UA_TimerEntry) zipfields; + UA_DateTime nextTime; /* The next time when the callback + * is to be executed */ + UA_UInt64 interval; /* Interval in 100ns resolution */ + UA_Boolean repeated; /* Repeated callback? */ - /* Set the time for the next execution. Prevent an infinite loop by - * forcing the next processing into the next iteration. */ - tc->nextTime += (UA_Int64)tc->interval; - if(tc->nextTime < nowMonotonic) - tc->nextTime = nowMonotonic + 1; - - /* Find the new position for tc to keep the list sorted */ - UA_TimerCallbackEntry *prev_tc; - if(last_dispatched->nextTime == tc->nextTime) { - /* We try to "batch" repeatedCallbacks with the same interval. This - * saves a linear search when the last dispatched entry has the same - * nextTime timestamp as this entry. */ - UA_assert(last_dispatched != &tmp_first); - prev_tc = last_dispatched; - } else { - /* Find the position for the next execution by a linear search - * starting at last_dispatched or the first element */ - if(last_dispatched->nextTime < tc->nextTime) - prev_tc = last_dispatched; - else - prev_tc = &tmp_first; + UA_ApplicationCallback callback; + void *application; + void *data; - while(true) { - UA_TimerCallbackEntry *n = SLIST_NEXT(prev_tc, next); - if(!n || n->nextTime >= tc->nextTime) - break; - prev_tc = n; - } - } + ZIP_ENTRY(UA_TimerEntry) idZipfields; + UA_UInt64 id; /* Id of the entry */ +}; - /* Update last_dispatched to make sure batched callbacks are added in the - * same sequence as before they were executed and to save some iterations - * of the linear search for callbacks to be added further back in the list. */ - last_dispatched = tc; +/* There may be several entries with the same nextTime in the tree. We give them + * an absolute order by considering the memory address to break ties. Because of + * this, the nextTime property cannot be used to lookup specific entries. */ +static enum ZIP_CMP +cmpDateTime(const UA_DateTime *a, const UA_DateTime *b) { + if(*a < *b) + return ZIP_CMP_LESS; + if(*a > *b) + return ZIP_CMP_MORE; + if(a == b) + return ZIP_CMP_EQ; + if(a < b) + return ZIP_CMP_LESS; + return ZIP_CMP_MORE; +} + +ZIP_PROTTYPE(UA_TimerZip, UA_TimerEntry, UA_DateTime) +ZIP_IMPL(UA_TimerZip, UA_TimerEntry, zipfields, UA_DateTime, nextTime, cmpDateTime) + +/* The identifiers of entries are unique */ +static enum ZIP_CMP +cmpId(const UA_UInt64 *a, const UA_UInt64 *b) { + if(*a < *b) + return ZIP_CMP_LESS; + if(*a == *b) + return ZIP_CMP_EQ; + return ZIP_CMP_MORE; +} + +ZIP_PROTTYPE(UA_TimerIdZip, UA_TimerEntry, UA_UInt64) +ZIP_IMPL(UA_TimerIdZip, UA_TimerEntry, idZipfields, UA_UInt64, id, cmpId) - /* Add entry to the new position in the sorted list */ - SLIST_INSERT_AFTER(prev_tc, tc, next); - } +void +UA_Timer_init(UA_Timer *t) { + memset(t, 0, sizeof(UA_Timer)); +} + +static UA_StatusCode +addCallback(UA_Timer *t, UA_ApplicationCallback callback, void *application, void *data, + UA_DateTime nextTime, UA_UInt64 interval, UA_Boolean repeated, + UA_UInt64 *callbackId) { + /* A callback method needs to be present */ + if(!callback) + return UA_STATUSCODE_BADINTERNALERROR; + + /* Allocate the repeated callback structure */ + UA_TimerEntry *te = (UA_TimerEntry*)UA_malloc(sizeof(UA_TimerEntry)); + if(!te) + return UA_STATUSCODE_BADOUTOFMEMORY; + + /* Set the repeated callback */ + te->interval = (UA_UInt64)interval; + te->id = ++t->idCounter; + te->callback = callback; + te->application = application; + te->data = data; + te->repeated = repeated; + te->nextTime = nextTime; + + /* Set the output identifier */ + if(callbackId) + *callbackId = te->id; + + ZIP_INSERT(UA_TimerZip, &t->root, te, ZIP_FFS32(UA_UInt32_random())); + ZIP_INSERT(UA_TimerIdZip, &t->idRoot, te, ZIP_RANK(te, zipfields)); + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +UA_Timer_addTimedCallback(UA_Timer *t, UA_ApplicationCallback callback, + void *application, void *data, UA_DateTime date, + UA_UInt64 *callbackId) { + return addCallback(t, callback, application, data, date, 0, false, callbackId); +} - /* Set the entry-point for the newly sorted list */ - t->repeatedCallbacks.slh_first = tmp_first.next.sle_next; +/* Adding repeated callbacks: Add an entry with the "nextTime" timestamp in the + * future. This will be picked up in the next iteration and inserted at the + * correct place. So that the next execution takes place ät "nextTime". */ +UA_StatusCode +UA_Timer_addRepeatedCallback(UA_Timer *t, UA_ApplicationCallback callback, + void *application, void *data, UA_Double interval_ms, + UA_UInt64 *callbackId) { + /* The interval needs to be positive */ + if(interval_ms <= 0.0) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_UInt64 interval = (UA_UInt64)(interval_ms * UA_DATETIME_MSEC); + UA_DateTime nextTime = UA_DateTime_nowMonotonic() + (UA_DateTime)interval; + return addCallback(t, callback, application, data, nextTime, + interval, true, callbackId); +} + +UA_StatusCode +UA_Timer_changeRepeatedCallbackInterval(UA_Timer *t, UA_UInt64 callbackId, + UA_Double interval_ms) { + /* The interval needs to be positive */ + if(interval_ms <= 0.0) + return UA_STATUSCODE_BADINTERNALERROR; - /* Re-repeat processAddRemoved since one of the callbacks might have removed - * or added a callback. So we return a correct timeout. */ - processChanges(t); + /* Remove from the sorted list */ + UA_TimerEntry *te = ZIP_FIND(UA_TimerIdZip, &t->idRoot, &callbackId); + if(!te) + return UA_STATUSCODE_BADNOTFOUND; - /* Return timestamp of next repetition */ - tc = SLIST_FIRST(&t->repeatedCallbacks); - if(!tc) - return UA_INT64_MAX; /* Main-loop has a max timeout / will continue earlier */ - return tc->nextTime; + /* Set the repeated callback */ + ZIP_REMOVE(UA_TimerZip, &t->root, te); + te->interval = (UA_UInt64)(interval_ms * UA_DATETIME_MSEC); /* in 100ns resolution */ + te->nextTime = UA_DateTime_nowMonotonic() + (UA_DateTime)te->interval; + ZIP_INSERT(UA_TimerZip, &t->root, te, ZIP_RANK(te, zipfields)); + return UA_STATUSCODE_GOOD; } void -UA_Timer_deleteMembers(UA_Timer *t) { - /* Process changes to empty the MPSC queue */ - processChanges(t); +UA_Timer_removeCallback(UA_Timer *t, UA_UInt64 callbackId) { + UA_TimerEntry *te = ZIP_FIND(UA_TimerIdZip, &t->idRoot, &callbackId); + if(!te) + return; - /* Remove repeated callbacks */ - UA_TimerCallbackEntry *current; - while((current = SLIST_FIRST(&t->repeatedCallbacks))) { - SLIST_REMOVE_HEAD(&t->repeatedCallbacks, next); - UA_free(current); + ZIP_REMOVE(UA_TimerZip, &t->root, te); + ZIP_REMOVE(UA_TimerIdZip, &t->idRoot, te); + UA_free(te); +} + +UA_DateTime +UA_Timer_process(UA_Timer *t, UA_DateTime nowMonotonic, + UA_TimerExecutionCallback executionCallback, + void *executionApplication) { + UA_TimerEntry *first; + while((first = ZIP_MIN(UA_TimerZip, &t->root)) && + first->nextTime <= nowMonotonic) { + ZIP_REMOVE(UA_TimerZip, &t->root, first); + + /* Reinsert / remove to their new position first. Because the callback + * can interact with the zip tree and expects the same entries in the + * root and idRoot trees. */ + + if(!first->repeated) { + ZIP_REMOVE(UA_TimerIdZip, &t->idRoot, first); + executionCallback(executionApplication, first->callback, + first->application, first->data); + UA_free(first); + continue; + } + + /* Set the time for the next execution. Prevent an infinite loop by + * forcing the next processing into the next iteration. */ + first->nextTime += (UA_Int64)first->interval; + if(first->nextTime < nowMonotonic) + first->nextTime = nowMonotonic + 1; + ZIP_INSERT(UA_TimerZip, &t->root, first, ZIP_RANK(first, zipfields)); + executionCallback(executionApplication, first->callback, + first->application, first->data); } + + /* Return the timestamp of the earliest next callback */ + first = ZIP_MIN(UA_TimerZip, &t->root); + return (first) ? first->nextTime : UA_INT64_MAX; +} + +static void +freeEntry(UA_TimerEntry *te, void *data) { + UA_free(te); +} + +void +UA_Timer_deleteMembers(UA_Timer *t) { + /* Free all nodes and reset the root */ + ZIP_ITER(UA_TimerZip, &t->root, freeEntry, NULL); + ZIP_INIT(&t->root); } /*********************************** amalgamated original file "/home/jvoe/open62541/src/ua_connection.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014, 2016-2017 (c) Florian Palm * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015 (c) Oleksiy Vasylyev * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2019 (c) Kalycito Infotech Private Limited */ + void UA_Connection_deleteMembers(UA_Connection *connection) { - UA_ByteString_deleteMembers(&connection->incompleteMessage); + UA_ByteString_deleteMembers(&connection->incompleteChunk); +} + +UA_StatusCode +UA_Connection_processHELACK(UA_Connection *connection, + const UA_ConnectionConfig *localConfig, + const UA_ConnectionConfig *remoteConfig) { + connection->config = *remoteConfig; + + /* The lowest common version is used by both sides */ + if(connection->config.protocolVersion > localConfig->protocolVersion) + connection->config.protocolVersion = localConfig->protocolVersion; + + /* Can we receive the max send size? */ + if(connection->config.sendBufferSize > localConfig->recvBufferSize) + connection->config.sendBufferSize = localConfig->recvBufferSize; + + /* Can we send the max receive size? */ + if(connection->config.recvBufferSize > localConfig->sendBufferSize) + connection->config.recvBufferSize = localConfig->sendBufferSize; + + /* Chunks of at least 8192 bytes must be permissible. + * See Part 6, Clause 6.7.1 */ + if(connection->config.recvBufferSize < 8192 || + connection->config.sendBufferSize < 8192 || + (connection->config.maxMessageSize != 0 && + connection->config.maxMessageSize < 8192)) + return UA_STATUSCODE_BADINTERNALERROR; + + connection->state = UA_CONNECTION_ESTABLISHED; + + return UA_STATUSCODE_GOOD; } -/* Hides somme errors before sending them to a client according to the +/* Hides some errors before sending them to a client according to the * standard. */ static void hideErrors(UA_TcpErrorMessage *const error) { switch(error->error) { case UA_STATUSCODE_BADCERTIFICATEUNTRUSTED: + case UA_STATUSCODE_BADCERTIFICATEREVOKED: error->error = UA_STATUSCODE_BADSECURITYCHECKSFAILED; error->reason = UA_STRING_NULL; break; @@ -17761,37 +18686,22 @@ UA_Connection_sendError(UA_Connection *connection, UA_TcpErrorMessage *error) { /* Encode and send the response */ UA_Byte *bufPos = msg.data; const UA_Byte *bufEnd = &msg.data[msg.length]; - UA_TcpMessageHeader_encodeBinary(&header, &bufPos, &bufEnd); - UA_TcpErrorMessage_encodeBinary(error, &bufPos, &bufEnd); + UA_TcpMessageHeader_encodeBinary(&header, &bufPos, bufEnd); + UA_TcpErrorMessage_encodeBinary(error, &bufPos, bufEnd); msg.length = header.messageSize; connection->send(connection, &msg); } static UA_StatusCode -prependIncompleteChunk(UA_Connection *connection, UA_ByteString *message) { - /* Allocate the new message buffer */ - size_t length = connection->incompleteMessage.length + message->length; - UA_Byte *data = (UA_Byte*)UA_realloc(connection->incompleteMessage.data, length); - if(!data) { - UA_ByteString_deleteMembers(&connection->incompleteMessage); - return UA_STATUSCODE_BADOUTOFMEMORY; - } - - /* Copy / release the current message buffer */ - memcpy(&data[connection->incompleteMessage.length], message->data, message->length); - message->length = length; - message->data = data; - connection->incompleteMessage = UA_BYTESTRING_NULL; - return UA_STATUSCODE_GOOD; -} - -static UA_StatusCode -bufferIncompleteChunk(UA_Connection *connection, const UA_Byte *pos, const UA_Byte *end) { +bufferIncompleteChunk(UA_Connection *connection, const UA_Byte *pos, + const UA_Byte *end) { + UA_assert(connection->incompleteChunk.length == 0); + UA_assert(pos < end); size_t length = (uintptr_t)end - (uintptr_t)pos; - UA_StatusCode retval = UA_ByteString_allocBuffer(&connection->incompleteMessage, length); + UA_StatusCode retval = UA_ByteString_allocBuffer(&connection->incompleteChunk, length); if(retval != UA_STATUSCODE_GOOD) return retval; - memcpy(connection->incompleteMessage.data, pos, length); + memcpy(connection->incompleteChunk.data, pos, length); return UA_STATUSCODE_GOOD; } @@ -17800,18 +18710,17 @@ processChunk(UA_Connection *connection, void *application, UA_Connection_processChunk processCallback, const UA_Byte **posp, const UA_Byte *end, UA_Boolean *done) { const UA_Byte *pos = *posp; - size_t length = (uintptr_t)end - (uintptr_t)pos; + const size_t remaining = (uintptr_t)end - (uintptr_t)pos; /* At least 8 byte needed for the header. Wait for the next chunk. */ - if(length < 8) { - bufferIncompleteChunk(connection, pos, end); + if(remaining < 8) { *done = true; return UA_STATUSCODE_GOOD; } /* Check the message type */ - UA_MessageType msgtype = (UA_MessageType)((UA_UInt32)pos[0] + ((UA_UInt32)pos[1] << 8) + - ((UA_UInt32)pos[2] << 16)); + UA_MessageType msgtype = (UA_MessageType) + ((UA_UInt32)pos[0] + ((UA_UInt32)pos[1] << 8) + ((UA_UInt32)pos[2] << 16)); if(msgtype != UA_MESSAGETYPE_MSG && msgtype != UA_MESSAGETYPE_ERR && msgtype != UA_MESSAGETYPE_OPN && msgtype != UA_MESSAGETYPE_HEL && msgtype != UA_MESSAGETYPE_ACK && msgtype != UA_MESSAGETYPE_CLO) { @@ -17832,20 +18741,15 @@ processChunk(UA_Connection *connection, void *application, UA_UInt32_decodeBinary(&temp, &temp_offset, &chunk_length); /* The message size is not allowed */ - if(chunk_length < 16 || chunk_length > connection->localConf.recvBufferSize) + if(chunk_length < 16 || chunk_length > connection->config.recvBufferSize) return UA_STATUSCODE_BADTCPMESSAGETOOLARGE; - /* Wait for the next packet to process the complete chunk */ - if(chunk_length > length) { - bufferIncompleteChunk(connection, pos, end); + /* Have an the complete chunk */ + if(chunk_length > remaining) { *done = true; return UA_STATUSCODE_GOOD; } - /* Set pendingMessage if there is a message after this message */ - if(length > chunk_length) - connection->pendingMessage = true; - /* Process the chunk; forward the position pointer */ temp.length = chunk_length; *posp += chunk_length; @@ -17857,35 +18761,48 @@ UA_StatusCode UA_Connection_processChunks(UA_Connection *connection, void *application, UA_Connection_processChunk processCallback, const UA_ByteString *packet) { - /* If we have stored an incomplete chunk, prefix to the received message. - * After this block, connection->incompleteMessage is always empty. The - * message and the buffer is released if allocating the memory fails. */ - UA_Boolean realloced = false; - UA_ByteString message = *packet; - UA_StatusCode retval; - if(connection->incompleteMessage.length > 0) { - retval = prependIncompleteChunk(connection, &message); - if(retval != UA_STATUSCODE_GOOD) - return retval; - realloced = true; + const UA_Byte *pos = packet->data; + const UA_Byte *end = &packet->data[packet->length]; + UA_ByteString appended = connection->incompleteChunk; + + /* Prepend the incomplete last chunk. This is usually done in the + * networklayer. But we test for a buffered incomplete chunk here again to + * work around "lazy" network layers. */ + if(appended.length > 0) { + connection->incompleteChunk = UA_BYTESTRING_NULL; + UA_Byte *t = (UA_Byte*)UA_realloc(appended.data, appended.length + packet->length); + if(!t) { + UA_ByteString_deleteMembers(&appended); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + memcpy(&t[appended.length], pos, packet->length); + appended.data = t; + appended.length += packet->length; + pos = t; + end = &t[appended.length]; } + UA_assert(connection->incompleteChunk.length == 0); + /* Loop over the received chunks. pos is increased with each chunk. */ - const UA_Byte *pos = message.data; - const UA_Byte *end = &message.data[message.length]; - UA_Boolean done = true; - do { - retval = processChunk(connection, application, processCallback, - &pos, end, &done); - connection->pendingMessage = false; - } while(!done && retval == UA_STATUSCODE_GOOD); + UA_Boolean done = false; + UA_StatusCode retval = UA_STATUSCODE_GOOD; + while(!done) { + retval = processChunk(connection, application, processCallback, &pos, end, &done); + /* If an irrecoverable error happens: do not buffer incomplete chunk */ + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + } - if(realloced) - UA_ByteString_deleteMembers(&message); + if(end > pos) + retval = bufferIncompleteChunk(connection, pos, end); + + cleanup: + UA_ByteString_deleteMembers(&appended); return retval; } -/* In order to know whether a chunk was processed, we insert an indirection into +/* In order to know whether a chunk was processed, we insert an redirection into * the callback. */ struct completeChunkTrampolineData { UA_Boolean called; @@ -17944,6 +18861,28 @@ UA_Connection_receiveChunksBlocking(UA_Connection *connection, void *application return retval; } +UA_StatusCode +UA_Connection_receiveChunksNonBlocking(UA_Connection *connection, void *application, + UA_Connection_processChunk processCallback) { + struct completeChunkTrampolineData data; + data.called = false; + data.application = application; + data.processCallback = processCallback; + + /* Listen for messages to arrive */ + UA_ByteString packet = UA_BYTESTRING_NULL; + UA_StatusCode retval = connection->recv(connection, &packet, 1); + + if((retval != UA_STATUSCODE_GOOD) && (retval != UA_STATUSCODE_GOODNONCRITICALTIMEOUT)) + return retval; + + /* Try to process one complete chunk */ + retval = UA_Connection_processChunks(connection, &data, completeChunkTrampoline, &packet); + connection->releaseRecvBuffer(connection, &packet); + + return retval; +} + void UA_Connection_detachSecureChannel(UA_Connection *connection) { UA_SecureChannel *channel = connection->channel; if(channel) @@ -17965,7 +18904,7 @@ UA_Connection_attachSecureChannel(UA_Connection *connection, UA_SecureChannel *c * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014, 2016-2017 (c) Florian Palm * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015 (c) Oleksiy Vasylyev @@ -17975,8 +18914,10 @@ UA_Connection_attachSecureChannel(UA_Connection *connection, UA_SecureChannel *c */ -#define UA_BITMASK_MESSAGETYPE 0x00ffffff -#define UA_BITMASK_CHUNKTYPE 0xff000000 + + +#define UA_BITMASK_MESSAGETYPE 0x00ffffffu +#define UA_BITMASK_CHUNKTYPE 0xff000000u #define UA_ASYMMETRIC_ALG_SECURITY_HEADER_FIXED_LENGTH 12 #define UA_SYMMETRIC_ALG_SECURITY_HEADER_LENGTH 4 #define UA_SEQUENCE_HEADER_LENGTH 8 @@ -17984,8 +18925,8 @@ UA_Connection_attachSecureChannel(UA_Connection *connection, UA_SecureChannel *c (UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + \ UA_SYMMETRIC_ALG_SECURITY_HEADER_LENGTH) -const UA_ByteString - UA_SECURITY_POLICY_NONE_URI = {47, (UA_Byte *)"http://opcfoundation.org/UA/SecurityPolicy#None"}; +const UA_ByteString UA_SECURITY_POLICY_NONE_URI = + {47, (UA_Byte *)"http://opcfoundation.org/UA/SecurityPolicy#None"}; #ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS UA_StatusCode decrypt_verifySignatureFailure; @@ -17993,28 +18934,36 @@ UA_StatusCode sendAsym_sendFailure; UA_StatusCode processSym_seqNumberFailure; #endif -UA_StatusCode -UA_SecureChannel_init(UA_SecureChannel *channel, - const UA_SecurityPolicy *securityPolicy, - const UA_ByteString *remoteCertificate) { - if(channel == NULL || securityPolicy == NULL || remoteCertificate == NULL) - return UA_STATUSCODE_BADINTERNALERROR; - +void +UA_SecureChannel_init(UA_SecureChannel *channel) { /* Linked lists are also initialized by zeroing out */ memset(channel, 0, sizeof(UA_SecureChannel)); channel->state = UA_SECURECHANNELSTATE_FRESH; - channel->securityPolicy = securityPolicy; + TAILQ_INIT(&channel->messages); +} + +UA_StatusCode +UA_SecureChannel_setSecurityPolicy(UA_SecureChannel *channel, + const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *remoteCertificate) { + /* Is a policy already configured? */ + if(channel->securityPolicy) { + UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Security policy already configured"); + return UA_STATUSCODE_BADINTERNALERROR; + } UA_StatusCode retval; - if(channel->securityPolicy->certificateVerification != NULL) { - retval = channel->securityPolicy->certificateVerification-> - verifyCertificate(channel->securityPolicy->certificateVerification->context, remoteCertificate); + if(securityPolicy->certificateVerification != NULL) { + retval = securityPolicy->certificateVerification-> + verifyCertificate(securityPolicy->certificateVerification->context, + remoteCertificate); if(retval != UA_STATUSCODE_GOOD) return retval; } else { - UA_LOG_WARNING(channel->securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, "No PKI plugin set. " - "Accepting all certificates"); + UA_LOG_WARNING(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Security policy None is used to create SecureChannel. Accepting all certificates"); } retval = securityPolicy->channelModule. @@ -18031,11 +18980,47 @@ UA_SecureChannel_init(UA_SecureChannel *channel, makeCertificateThumbprint(securityPolicy, &channel->remoteCertificate, &remoteCertificateThumbprint); + if(retval == UA_STATUSCODE_GOOD) + channel->securityPolicy = securityPolicy; + return retval; } +static void +deleteMessage(UA_Message *me) { + UA_ChunkPayload *cp; + while((cp = SIMPLEQ_FIRST(&me->chunkPayloads))) { + if(cp->copied) + UA_ByteString_deleteMembers(&cp->bytes); + SIMPLEQ_REMOVE_HEAD(&me->chunkPayloads, pointers); + UA_free(cp); + } + UA_free(me); +} + +static void +deleteLatestMessage(UA_SecureChannel *channel, UA_UInt32 requestId) { + UA_Message *me = TAILQ_LAST(&channel->messages, UA_MessageQueue); + if(!me) + return; + if(me->requestId != requestId) + return; + + TAILQ_REMOVE(&channel->messages, me, pointers); + deleteMessage(me); +} + void -UA_SecureChannel_deleteMembersCleanup(UA_SecureChannel *channel) { +UA_SecureChannel_deleteMessages(UA_SecureChannel *channel) { + UA_Message *me, *me_tmp; + TAILQ_FOREACH_SAFE(me, &channel->messages, pointers, me_tmp) { + TAILQ_REMOVE(&channel->messages, me, pointers); + deleteMessage(me); + } +} + +void +UA_SecureChannel_deleteMembers(UA_SecureChannel *channel) { /* Delete members */ UA_ByteString_deleteMembers(&channel->remoteCertificate); UA_ByteString_deleteMembers(&channel->localNonce); @@ -18044,8 +19029,21 @@ UA_SecureChannel_deleteMembersCleanup(UA_SecureChannel *channel) { UA_ChannelSecurityToken_deleteMembers(&channel->nextSecurityToken); /* Delete the channel context for the security policy */ - if(channel->securityPolicy) + if(channel->securityPolicy) { channel->securityPolicy->channelModule.deleteContext(channel->channelContext); + channel->securityPolicy = NULL; + } + + /* Remove the buffered messages */ + UA_SecureChannel_deleteMessages(channel); + + UA_SecureChannel_init(channel); +} + +void +UA_SecureChannel_close(UA_SecureChannel *channel) { + /* Set the status to closed */ + channel->state = UA_SECURECHANNELSTATE_CLOSED; /* Detach from the connection and close the connection */ if(channel->connection) { @@ -18061,18 +19059,6 @@ UA_SecureChannel_deleteMembersCleanup(UA_SecureChannel *channel) { sh->channel = NULL; LIST_REMOVE(sh, pointers); } - - /* Remove the buffered chunks */ - struct MessageEntry *me, *temp_me; - LIST_FOREACH_SAFE(me, &channel->chunks, pointers, temp_me) { - struct ChunkPayload *cp, *temp_cp; - SIMPLEQ_FOREACH_SAFE(cp, &me->chunkPayload, pointers, temp_cp) { - UA_ByteString_deleteMembers(&cp->bytes); - UA_free(cp); - } - LIST_REMOVE(me, pointers); - UA_free(me); - } } UA_StatusCode @@ -18096,9 +19082,12 @@ UA_SecureChannel_generateLocalNonce(UA_SecureChannel *channel) { static UA_StatusCode UA_SecureChannel_generateLocalKeys(const UA_SecureChannel *const channel, const UA_SecurityPolicy *const securityPolicy) { + UA_LOG_TRACE_CHANNEL(securityPolicy->logger, channel, "Generating new local keys"); const UA_SecurityPolicyChannelModule *channelModule = &securityPolicy->channelModule; const UA_SecurityPolicySymmetricModule *symmetricModule = &securityPolicy->symmetricModule; - const UA_SecurityPolicyCryptoModule *const cryptoModule = &securityPolicy->symmetricModule.cryptoModule; + const UA_SecurityPolicyCryptoModule *const cryptoModule = + &securityPolicy->symmetricModule.cryptoModule; + /* Symmetric key length */ size_t encryptionKeyLength = cryptoModule->encryptionAlgorithm.getLocalKeyLength(securityPolicy, channel->channelContext); @@ -18121,18 +19110,31 @@ UA_SecureChannel_generateLocalKeys(const UA_SecureChannel *const channel, const UA_ByteString localIv = {encryptionBlockSize, buffer.data + signingKeyLength + encryptionKeyLength}; + retval = channelModule->setLocalSymSigningKey(channel->channelContext, &localSigningKey); - retval |= channelModule->setLocalSymEncryptingKey(channel->channelContext, &localEncryptingKey); - retval |= channelModule->setLocalSymIv(channel->channelContext, &localIv); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = channelModule->setLocalSymEncryptingKey(channel->channelContext, &localEncryptingKey); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = channelModule->setLocalSymIv(channel->channelContext, &localIv); + if(retval != UA_STATUSCODE_GOOD) + return retval; + return retval; } static UA_StatusCode UA_SecureChannel_generateRemoteKeys(const UA_SecureChannel *const channel, const UA_SecurityPolicy *const securityPolicy) { + UA_LOG_TRACE_CHANNEL(securityPolicy->logger, channel, "Generating new remote keys"); const UA_SecurityPolicyChannelModule *channelModule = &securityPolicy->channelModule; const UA_SecurityPolicySymmetricModule *symmetricModule = &securityPolicy->symmetricModule; - const UA_SecurityPolicyCryptoModule *const cryptoModule = &securityPolicy->symmetricModule.cryptoModule; + const UA_SecurityPolicyCryptoModule *const cryptoModule = + &securityPolicy->symmetricModule.cryptoModule; + /* Symmetric key length */ size_t encryptionKeyLength = cryptoModule->encryptionAlgorithm.getRemoteKeyLength(securityPolicy, channel->channelContext); @@ -18149,15 +19151,23 @@ UA_SecureChannel_generateRemoteKeys(const UA_SecureChannel *const channel, &channel->remoteNonce, &buffer); if(retval != UA_STATUSCODE_GOOD) return retval; + const UA_ByteString remoteSigningKey = {signingKeyLength, buffer.data}; const UA_ByteString remoteEncryptingKey = {encryptionKeyLength, buffer.data + signingKeyLength}; const UA_ByteString remoteIv = {encryptionBlockSize, buffer.data + signingKeyLength + encryptionKeyLength}; + retval = channelModule->setRemoteSymSigningKey(channel->channelContext, &remoteSigningKey); - retval |= channelModule->setRemoteSymEncryptingKey(channel->channelContext, &remoteEncryptingKey); - retval |= channelModule->setRemoteSymIv(channel->channelContext, &remoteIv); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = channelModule->setRemoteSymEncryptingKey(channel->channelContext, &remoteEncryptingKey); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = channelModule->setRemoteSymIv(channel->channelContext, &remoteIv); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -18166,13 +19176,20 @@ UA_SecureChannel_generateRemoteKeys(const UA_SecureChannel *const channel, UA_StatusCode UA_SecureChannel_generateNewKeys(UA_SecureChannel *channel) { - UA_StatusCode retval = UA_SecureChannel_generateLocalKeys(channel, channel->securityPolicy); - if(retval != UA_STATUSCODE_GOOD) + UA_StatusCode retval = + UA_SecureChannel_generateLocalKeys(channel, channel->securityPolicy); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(channel->securityPolicy->logger, UA_LOGCATEGORY_SECURECHANNEL, + "Could not generate a local key"); return retval; + } retval = UA_SecureChannel_generateRemoteKeys(channel, channel->securityPolicy); - if(retval != UA_STATUSCODE_GOOD) + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(channel->securityPolicy->logger, UA_LOGCATEGORY_SECURECHANNEL, + "Could not generate a remote key"); return retval; + } return retval; } @@ -18180,7 +19197,7 @@ UA_SecureChannel_generateNewKeys(UA_SecureChannel *channel) { UA_SessionHeader * UA_SecureChannel_getSession(UA_SecureChannel *channel, const UA_NodeId *authenticationToken) { - struct UA_SessionHeader *sh; + UA_SessionHeader *sh; LIST_FOREACH(sh, &channel->sessions, pointers) { if(UA_NodeId_equal(&sh->authenticationToken, authenticationToken)) break; @@ -18193,7 +19210,6 @@ UA_SecureChannel_revolveTokens(UA_SecureChannel *channel) { if(channel->nextSecurityToken.tokenId == 0) // no security token issued return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN; - //FIXME: not thread-safe ???? Why is this not thread safe? UA_ChannelSecurityToken_deleteMembers(&channel->previousSecurityToken); UA_ChannelSecurityToken_copy(&channel->securityToken, &channel->previousSecurityToken); @@ -18203,70 +19219,189 @@ UA_SecureChannel_revolveTokens(UA_SecureChannel *channel) { UA_ChannelSecurityToken_deleteMembers(&channel->nextSecurityToken); UA_ChannelSecurityToken_init(&channel->nextSecurityToken); - return UA_SecureChannel_generateNewKeys(channel); + + /* remote keys are generated later on */ + return UA_SecureChannel_generateLocalKeys(channel, channel->securityPolicy); } /***************************/ /* Send Asymmetric Message */ /***************************/ -static UA_UInt16 -calculatePaddingAsym(const UA_SecurityPolicy *securityPolicy, const void *channelContext, - size_t bytesToWrite, UA_Byte *paddingSize, UA_Byte *extraPaddingSize) { - size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. - getRemotePlainTextBlockSize(securityPolicy, channelContext); - size_t signatureSize = securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. - getLocalSignatureSize(securityPolicy, channelContext); - size_t paddingBytes = 1; - if(securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. - getRemoteKeyLength(securityPolicy, channelContext) > 2048) - ++paddingBytes; - size_t padding = (plainTextBlockSize - ((bytesToWrite + signatureSize + paddingBytes) % - plainTextBlockSize)); - *paddingSize = (UA_Byte)(padding & 0xff); - *extraPaddingSize = (UA_Byte)(padding >> 8); - return (UA_UInt16)padding; -} - static size_t calculateAsymAlgSecurityHeaderLength(const UA_SecureChannel *channel) { size_t asymHeaderLength = UA_ASYMMETRIC_ALG_SECURITY_HEADER_FIXED_LENGTH + channel->securityPolicy->policyUri.length; + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN && + channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return asymHeaderLength; + + /* OPN is always encrypted even if the mode is sign only */ + asymHeaderLength += 20; /* Thumbprints are always 20 byte long */ + asymHeaderLength += channel->securityPolicy->localCertificate.length; + return asymHeaderLength; +} + +static UA_StatusCode +prependHeadersAsym(UA_SecureChannel *const channel, UA_Byte *header_pos, + const UA_Byte *buf_end, size_t totalLength, + size_t securityHeaderLength, UA_UInt32 requestId, + size_t *const finalLength) { + UA_StatusCode retval; + size_t dataToEncryptLength = + totalLength - (UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + securityHeaderLength); + + UA_SecureConversationMessageHeader respHeader; + respHeader.messageHeader.messageTypeAndChunkType = UA_MESSAGETYPE_OPN + UA_CHUNKTYPE_FINAL; + respHeader.messageHeader.messageSize = (UA_UInt32) + (totalLength + + UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(channel->securityPolicy, + channel->channelContext, + dataToEncryptLength)); + respHeader.secureChannelId = channel->securityToken.channelId; + retval = UA_encodeBinary(&respHeader, + &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER], + &header_pos, &buf_end, NULL, NULL); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + UA_AsymmetricAlgorithmSecurityHeader asymHeader; + UA_AsymmetricAlgorithmSecurityHeader_init(&asymHeader); + asymHeader.securityPolicyUri = channel->securityPolicy->policyUri; if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - /* OPN is always encrypted even if mode sign only */ - asymHeaderLength += 20; /* Thumbprints are always 20 byte long */ - asymHeaderLength += channel->securityPolicy->localCertificate.length; + asymHeader.senderCertificate = channel->securityPolicy->localCertificate; + asymHeader.receiverCertificateThumbprint.length = 20; + asymHeader.receiverCertificateThumbprint.data = channel->remoteCertificateThumbprint; } - return asymHeaderLength; + retval = UA_encodeBinary(&asymHeader, + &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER], + &header_pos, &buf_end, NULL, NULL); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + UA_SequenceHeader seqHeader; + seqHeader.requestId = requestId; + seqHeader.sequenceNumber = UA_atomic_addUInt32(&channel->sendSequenceNumber, 1); + retval = UA_encodeBinary(&seqHeader, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], + &header_pos, &buf_end, NULL, NULL); + + *finalLength = respHeader.messageHeader.messageSize; + + return retval; } static void -hideBytesAsym(const UA_SecureChannel *channel, UA_Byte **buf_start, const UA_Byte **buf_end) { - const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; - *buf_start += UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + UA_SEQUENCE_HEADER_LENGTH; - - /* Add the SecurityHeaderLength */ +hideBytesAsym(const UA_SecureChannel *channel, UA_Byte **buf_start, + const UA_Byte **buf_end) { + *buf_start += UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH; *buf_start += calculateAsymAlgSecurityHeaderLength(channel); - size_t potentialEncryptionMaxSize = (size_t)(*buf_end - *buf_start) + UA_SEQUENCE_HEADER_LENGTH; + *buf_start += UA_SEQUENCE_HEADER_LENGTH; + +#ifdef UA_ENABLE_ENCRYPTION + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN && + channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return; + + const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; /* Hide bytes for signature and padding */ - if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || - channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - *buf_end -= securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. - getLocalSignatureSize(securityPolicy, channel->channelContext); - *buf_end -= 2; /* padding byte and extraPadding byte */ + size_t potentialEncryptMaxSize = (size_t)(*buf_end - *buf_start) + UA_SEQUENCE_HEADER_LENGTH; + *buf_end -= securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. + getLocalSignatureSize(securityPolicy, channel->channelContext); + *buf_end -= 2; /* padding byte and extraPadding byte */ + + /* Add some overhead length due to RSA implementations adding a signature themselves */ + *buf_end -= UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(securityPolicy, + channel->channelContext, + potentialEncryptMaxSize); +#endif +} + +#ifdef UA_ENABLE_ENCRYPTION + +static void +padChunkAsym(UA_SecureChannel *channel, const UA_ByteString *const buf, + size_t securityHeaderLength, UA_Byte **buf_pos) { + const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy; + + /* Also pad if the securityMode is SIGN_ONLY, since we are using + * asymmetric communication to exchange keys and thus need to encrypt. */ + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN && + channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return; + + const UA_Byte *buf_body_start = + &buf->data[UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + + UA_SEQUENCE_HEADER_LENGTH + securityHeaderLength]; + const size_t bytesToWrite = + (uintptr_t)*buf_pos - (uintptr_t)buf_body_start + UA_SEQUENCE_HEADER_LENGTH; + + /* Compute the padding length */ + size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. + getRemotePlainTextBlockSize(securityPolicy, channel->channelContext); + size_t signatureSize = securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. + getLocalSignatureSize(securityPolicy, channel->channelContext); + size_t paddingBytes = 1; + if(securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. + getRemoteKeyLength(securityPolicy, channel->channelContext) > 2048) + ++paddingBytes; /* extra padding */ + size_t totalPaddingSize = + (plainTextBlockSize - ((bytesToWrite + signatureSize + paddingBytes) % plainTextBlockSize)); - /* Add some overhead length due to RSA implementations adding a signature themselves */ - *buf_end -= UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(securityPolicy, - channel->channelContext, - potentialEncryptionMaxSize); + /* Write the padding. This is <= because the paddingSize byte also has to be written */ + UA_Byte paddingSize = (UA_Byte)(totalPaddingSize & 0xffu); + for(UA_UInt16 i = 0; i <= totalPaddingSize; ++i) { + **buf_pos = paddingSize; + ++*buf_pos; + } + + /* Write the extra padding byte if required */ + if(securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. + getRemoteKeyLength(securityPolicy, channel->channelContext) > 2048) { + UA_Byte extraPaddingSize = (UA_Byte)(totalPaddingSize >> 8u); + **buf_pos = extraPaddingSize; + ++*buf_pos; } } +static UA_StatusCode +signAndEncryptAsym(UA_SecureChannel *const channel, size_t preSignLength, + UA_ByteString *buf, size_t securityHeaderLength, + size_t totalLength) { + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN && + channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return UA_STATUSCODE_GOOD; + + const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy; + + /* Sign message */ + const UA_ByteString dataToSign = {preSignLength, buf->data}; + size_t sigsize = securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. + getLocalSignatureSize(securityPolicy, channel->channelContext); + UA_ByteString signature = {sigsize, buf->data + preSignLength}; + UA_StatusCode retval = securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. + sign(securityPolicy, channel->channelContext, &dataToSign, &signature); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* Specification part 6, 6.7.4: The OpenSecureChannel Messages are + * signed and encrypted if the SecurityMode is not None (even if the + * SecurityMode is SignOnly). */ + size_t unencrypted_length = + UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + securityHeaderLength; + UA_ByteString dataToEncrypt = {totalLength - unencrypted_length, + &buf->data[unencrypted_length]}; + return securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. + encrypt(securityPolicy, channel->channelContext, &dataToEncrypt); +} + +#endif /* UA_ENABLE_ENCRYPTION */ + /* Sends an OPN message using asymmetric encryption if defined */ UA_StatusCode -UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 requestId, - const void *content, const UA_DataType *contentType) { +UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, + UA_UInt32 requestId, const void *content, + const UA_DataType *contentType) { if(channel->securityMode == UA_MESSAGESECURITYMODE_INVALID) return UA_STATUSCODE_BADSECURITYMODEREJECTED; @@ -18278,7 +19413,7 @@ UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 r /* Allocate the message buffer */ UA_ByteString buf = UA_BYTESTRING_NULL; UA_StatusCode retval = - connection->getSendBuffer(connection, connection->localConf.sendBufferSize, &buf); + connection->getSendBuffer(connection, connection->config.sendBufferSize, &buf); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -18289,42 +19424,21 @@ UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 r /* Encode the message type and content */ UA_NodeId typeId = UA_NODEID_NUMERIC(0, contentType->binaryEncodingId); - retval = UA_encodeBinary(&typeId, &UA_TYPES[UA_TYPES_NODEID], &buf_pos, &buf_end, NULL, NULL); - retval |= UA_encodeBinary(content, contentType, &buf_pos, &buf_end, NULL, NULL); + retval |= UA_encodeBinary(&typeId, &UA_TYPES[UA_TYPES_NODEID], + &buf_pos, &buf_end, NULL, NULL); + retval |= UA_encodeBinary(content, contentType, + &buf_pos, &buf_end, NULL, NULL); if(retval != UA_STATUSCODE_GOOD) { connection->releaseSendBuffer(connection, &buf); return retval; } - /* Compute the length of the asym header */ const size_t securityHeaderLength = calculateAsymAlgSecurityHeaderLength(channel); - /* Pad the message. Also if securitymode is only sign, since we are using - * asymmetric communication to exchange keys and thus need to encrypt. */ - if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || - channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - const UA_Byte *buf_body_start = - &buf.data[UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + - UA_SEQUENCE_HEADER_LENGTH + securityHeaderLength]; - const size_t bytesToWrite = - (uintptr_t)buf_pos - (uintptr_t)buf_body_start + UA_SEQUENCE_HEADER_LENGTH; - UA_Byte paddingSize = 0; - UA_Byte extraPaddingSize = 0; - UA_UInt16 totalPaddingSize = - calculatePaddingAsym(securityPolicy, channel->channelContext, - bytesToWrite, &paddingSize, &extraPaddingSize); - - // This is <= because the paddingSize byte also has to be written. - for(UA_UInt16 i = 0; i <= totalPaddingSize; ++i) { - *buf_pos = paddingSize; - ++buf_pos; - } - if(securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. - getRemoteKeyLength(securityPolicy, channel->channelContext) > 2048) { - *buf_pos = extraPaddingSize; - ++buf_pos; - } - } + /* Add padding to the chunk */ +#ifdef UA_ENABLE_ENCRYPTION + padChunkAsym(channel, &buf, securityHeaderLength, &buf_pos); +#endif /* The total message length */ size_t pre_sig_length = (uintptr_t)buf_pos - (uintptr_t)buf.data; @@ -18334,115 +19448,133 @@ UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel, UA_UInt32 r total_length += securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. getLocalSignatureSize(securityPolicy, channel->channelContext); - /* Encode the headers at the beginning of the message */ - UA_Byte *header_pos = buf.data; - size_t dataToEncryptLength = - total_length - (UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + securityHeaderLength); - UA_SecureConversationMessageHeader respHeader; - respHeader.messageHeader.messageTypeAndChunkType = UA_MESSAGETYPE_OPN + UA_CHUNKTYPE_FINAL; - respHeader.messageHeader.messageSize = (UA_UInt32) - (total_length + UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(securityPolicy, - channel->channelContext, - dataToEncryptLength)); - respHeader.secureChannelId = channel->securityToken.channelId; - retval = UA_encodeBinary(&respHeader, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER], - &header_pos, &buf_end, NULL, NULL); - - UA_AsymmetricAlgorithmSecurityHeader asymHeader; - UA_AsymmetricAlgorithmSecurityHeader_init(&asymHeader); - asymHeader.securityPolicyUri = channel->securityPolicy->policyUri; - if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || - channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - asymHeader.senderCertificate = channel->securityPolicy->localCertificate; - asymHeader.receiverCertificateThumbprint.length = 20; - asymHeader.receiverCertificateThumbprint.data = channel->remoteCertificateThumbprint; - } - retval |= UA_encodeBinary(&asymHeader, &UA_TRANSPORT[UA_TRANSPORT_ASYMMETRICALGORITHMSECURITYHEADER], - &header_pos, &buf_end, NULL, NULL); - - UA_SequenceHeader seqHeader; - seqHeader.requestId = requestId; - seqHeader.sequenceNumber = UA_atomic_addUInt32(&channel->sendSequenceNumber, 1); - retval |= UA_encodeBinary(&seqHeader, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], - &header_pos, &buf_end, NULL, NULL); - - /* Did encoding the header succeed? */ - if(retval != UA_STATUSCODE_GOOD) { - connection->releaseSendBuffer(connection, &buf); - return retval; - } - - if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || - channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - /* Sign message */ - const UA_ByteString dataToSign = {pre_sig_length, buf.data}; - size_t sigsize = securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. - getLocalSignatureSize(securityPolicy, channel->channelContext); - UA_ByteString signature = {sigsize, buf.data + pre_sig_length}; - retval = securityPolicy->asymmetricModule.cryptoModule.signatureAlgorithm. - sign(securityPolicy, channel->channelContext, &dataToSign, &signature); - if(retval != UA_STATUSCODE_GOOD) { - connection->releaseSendBuffer(connection, &buf); - return retval; - } + /* The total message length is known here which is why we encode the headers + * at this step and not earlier. */ + size_t finalLength = 0; + retval = prependHeadersAsym(channel, buf.data, buf_end, total_length, + securityHeaderLength, requestId, &finalLength); + if(retval != UA_STATUSCODE_GOOD) + goto error; - /* Specification part 6, 6.7.4: The OpenSecureChannel Messages are - * signed and encrypted if the SecurityMode is not None (even if the - * SecurityMode is SignOnly). */ - size_t unencrypted_length = - UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH + securityHeaderLength; - UA_ByteString dataToEncrypt = {total_length - unencrypted_length, - &buf.data[unencrypted_length]}; - retval = securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. - encrypt(securityPolicy, channel->channelContext, &dataToEncrypt); - if(retval != UA_STATUSCODE_GOOD) { - connection->releaseSendBuffer(connection, &buf); - return retval; - } - } +#ifdef UA_ENABLE_ENCRYPTION + retval = signAndEncryptAsym(channel, pre_sig_length, &buf, securityHeaderLength, total_length); + if(retval != UA_STATUSCODE_GOOD) + goto error; +#endif /* Send the message, the buffer is freed in the network layer */ - buf.length = respHeader.messageHeader.messageSize; + buf.length = finalLength; retval = connection->send(connection, &buf); #ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS - retval |= sendAsym_sendFailure + retval |= sendAsym_sendFailure; #endif return retval; + +error: + connection->releaseSendBuffer(connection, &buf); + return retval; } /**************************/ /* Send Symmetric Message */ /**************************/ +#ifdef UA_ENABLE_ENCRYPTION + static UA_UInt16 calculatePaddingSym(const UA_SecurityPolicy *securityPolicy, const void *channelContext, size_t bytesToWrite, UA_Byte *paddingSize, UA_Byte *extraPaddingSize) { - - size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm. - getLocalBlockSize(securityPolicy, channelContext); + size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule. + encryptionAlgorithm.getLocalBlockSize(securityPolicy, channelContext); size_t signatureSize = securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm. getLocalSignatureSize(securityPolicy, channelContext); - UA_UInt16 padding = (UA_UInt16)(encryptionBlockSize - ((bytesToWrite + signatureSize + 1) % encryptionBlockSize)); + size_t padding = (encryptionBlockSize - + ((bytesToWrite + signatureSize + 1) % encryptionBlockSize)); *paddingSize = (UA_Byte)padding; - *extraPaddingSize = (UA_Byte)(padding >> 8); - return padding; + *extraPaddingSize = (UA_Byte)(padding >> 8u); + return (UA_UInt16)padding; } static void -setBufPos(UA_MessageContext *mc) { - const UA_SecureChannel *channel = mc->channel; +padChunkSym(UA_MessageContext *messageContext, size_t bodyLength) { + if(messageContext->channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return; + + /* The bytes for the padding and signature were removed from buf_end before + * encoding the payload. So we don't have to check if there is enough + * space. */ + + size_t bytesToWrite = bodyLength + UA_SEQUENCE_HEADER_LENGTH; + UA_Byte paddingSize = 0; + UA_Byte extraPaddingSize = 0; + UA_UInt16 totalPaddingSize = + calculatePaddingSym(messageContext->channel->securityPolicy, + messageContext->channel->channelContext, + bytesToWrite, &paddingSize, &extraPaddingSize); + + /* This is <= because the paddingSize byte also has to be written. */ + for(UA_UInt16 i = 0; i <= totalPaddingSize; ++i) { + *messageContext->buf_pos = paddingSize; + ++(messageContext->buf_pos); + } + if(extraPaddingSize > 0) { + *messageContext->buf_pos = extraPaddingSize; + ++(messageContext->buf_pos); + } +} + +static UA_StatusCode +signChunkSym(UA_MessageContext *const messageContext, size_t preSigLength) { + const UA_SecureChannel *channel = messageContext->channel; + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN && + channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return UA_STATUSCODE_GOOD; + const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; + UA_ByteString dataToSign = messageContext->messageBuffer; + dataToSign.length = preSigLength; + UA_ByteString signature; + signature.length = securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm. + getLocalSignatureSize(securityPolicy, channel->channelContext); + signature.data = messageContext->buf_pos; + + return securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm. + sign(securityPolicy, channel->channelContext, &dataToSign, &signature); +} +static UA_StatusCode +encryptChunkSym(UA_MessageContext *const messageContext, size_t totalLength) { + const UA_SecureChannel *channel = messageContext->channel; + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return UA_STATUSCODE_GOOD; + + UA_ByteString dataToEncrypt; + dataToEncrypt.data = messageContext->messageBuffer.data + UA_SECUREMH_AND_SYMALGH_LENGTH; + dataToEncrypt.length = totalLength - UA_SECUREMH_AND_SYMALGH_LENGTH; + + const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; + return securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm. + encrypt(securityPolicy, channel->channelContext, &dataToEncrypt); +} + +#endif /* UA_ENABLE_ENCRYPTION */ + +static void +setBufPos(UA_MessageContext *mc) { /* Forward the data pointer so that the payload is encoded after the * message header */ mc->buf_pos = &mc->messageBuffer.data[UA_SECURE_MESSAGE_HEADER_LENGTH]; mc->buf_end = &mc->messageBuffer.data[mc->messageBuffer.length]; - /* Reserve space for the message footer at the end of the chunk if the chunk - * is signed and/or encrypted. The footer includes the fields PaddingSize, - * Padding, ExtraPadding and Signature. The padding fields are only present - * if the chunk is encrypted. */ +#ifdef UA_ENABLE_ENCRYPTION + const UA_SecureChannel *channel = mc->channel; + const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; + + /* Reserve space for the message footer at the end of the chunk if the chunk + * is signed and/or encrypted. The footer includes the fields PaddingSize, + * Padding, ExtraPadding and Signature. The padding fields are only present + * if the chunk is encrypted. */ if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) mc->buf_end -= securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm. @@ -18457,132 +19589,132 @@ setBufPos(UA_MessageContext *mc) { * calculatePaddingSym(). */ if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { /* PaddingSize and ExtraPaddingSize fields */ - size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm. - getLocalBlockSize(securityPolicy, channel->channelContext ); - mc->buf_end -= 1 + ((encryptionBlockSize >> 8) ? 1 : 0); + size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule. + encryptionAlgorithm.getLocalBlockSize(securityPolicy, channel->channelContext); + mc->buf_end -= 1 + ((encryptionBlockSize >> 8u) ? 1 : 0); + /* Reduce the message body size with the remainder of the operation * maxEncryptedDataSize modulo EncryptionBlockSize to get a whole * number of blocks to encrypt later. Also reserve one byte for - * padding (1 <= paddingSize <= encryptionBlockSize). - */ - size_t maxEncryptDataSize = mc->messageBuffer.length-UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH-UA_SYMMETRIC_ALG_SECURITY_HEADER_LENGTH; + * padding (1 <= paddingSize <= encryptionBlockSize). */ + size_t maxEncryptDataSize = mc->messageBuffer.length - + UA_SECURE_CONVERSATION_MESSAGE_HEADER_LENGTH - + UA_SYMMETRIC_ALG_SECURITY_HEADER_LENGTH; mc->buf_end -= (maxEncryptDataSize % encryptionBlockSize) + 1; } +#endif } static UA_StatusCode -sendSymmetricChunk(UA_MessageContext *mc) { - UA_StatusCode res = UA_STATUSCODE_GOOD; - UA_SecureChannel *const channel = mc->channel; - const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; - UA_Connection *const connection = channel->connection; +checkLimitsSym(UA_MessageContext *const messageContext, size_t *const bodyLength) { + /* Will this chunk surpass the capacity of the SecureChannel for the message? */ + UA_Connection *const connection = messageContext->channel->connection; if(!connection) return UA_STATUSCODE_BADINTERNALERROR; - /* Will this chunk surpass the capacity of the SecureChannel for the message? */ - UA_Byte *buf_body_start = mc->messageBuffer.data + UA_SECURE_MESSAGE_HEADER_LENGTH; - const UA_Byte *buf_body_end = mc->buf_pos; - size_t bodyLength = (uintptr_t)buf_body_end - (uintptr_t)buf_body_start; - mc->messageSizeSoFar += bodyLength; - mc->chunksSoFar++; - if(mc->messageSizeSoFar > connection->remoteConf.maxMessageSize && - connection->remoteConf.maxMessageSize != 0) - res = UA_STATUSCODE_BADRESPONSETOOLARGE; - if(mc->chunksSoFar > connection->remoteConf.maxChunkCount && - connection->remoteConf.maxChunkCount != 0) - res = UA_STATUSCODE_BADRESPONSETOOLARGE; - if(res != UA_STATUSCODE_GOOD) { - connection->releaseSendBuffer(channel->connection, &mc->messageBuffer); - return res; - } - - /* Pad the message. The bytes for the padding and signature were removed - * from buf_end before encoding the payload. So we don't check here. */ - if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - size_t bytesToWrite = bodyLength + UA_SEQUENCE_HEADER_LENGTH; - UA_Byte paddingSize = 0; - UA_Byte extraPaddingSize = 0; - UA_UInt16 totalPaddingSize = - calculatePaddingSym(securityPolicy, channel->channelContext, - bytesToWrite, &paddingSize, &extraPaddingSize); + UA_Byte *buf_body_start = messageContext->messageBuffer.data + UA_SECURE_MESSAGE_HEADER_LENGTH; + const UA_Byte *buf_body_end = messageContext->buf_pos; + *bodyLength = (uintptr_t)buf_body_end - (uintptr_t)buf_body_start; + messageContext->messageSizeSoFar += *bodyLength; + messageContext->chunksSoFar++; - // This is <= because the paddingSize byte also has to be written. - for(UA_UInt16 i = 0; i <= totalPaddingSize; ++i) { - *mc->buf_pos = paddingSize; - ++(mc->buf_pos); - } - if(extraPaddingSize > 0) { - *mc->buf_pos = extraPaddingSize; - ++(mc->buf_pos); - } - } + if(messageContext->messageSizeSoFar > connection->config.maxMessageSize && + connection->config.maxMessageSize != 0) + return UA_STATUSCODE_BADRESPONSETOOLARGE; - /* The total message length */ - size_t pre_sig_length = (uintptr_t)(mc->buf_pos) - (uintptr_t)mc->messageBuffer.data; - size_t total_length = pre_sig_length; - if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || - channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) - total_length += securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm. - getLocalSignatureSize(securityPolicy, channel->channelContext); - /* Space for the padding and the signature have been reserved in setBufPos() */ - UA_assert(total_length <= connection->localConf.sendBufferSize); - mc->messageBuffer.length = total_length; /* For giving the buffer to the network layer */ + if(messageContext->chunksSoFar > connection->config.maxChunkCount && + connection->config.maxChunkCount != 0) + return UA_STATUSCODE_BADRESPONSETOOLARGE; + + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +encodeHeadersSym(UA_MessageContext *const messageContext, size_t totalLength) { + UA_SecureChannel *channel = messageContext->channel; + UA_Byte *header_pos = messageContext->messageBuffer.data; - /* Encode the chunk headers at the beginning of the buffer */ - UA_assert(res == UA_STATUSCODE_GOOD); - UA_Byte *header_pos = mc->messageBuffer.data; UA_SecureConversationMessageHeader respHeader; respHeader.secureChannelId = channel->securityToken.channelId; - respHeader.messageHeader.messageTypeAndChunkType = mc->messageType; - respHeader.messageHeader.messageSize = (UA_UInt32)total_length; - if(mc->final) + respHeader.messageHeader.messageTypeAndChunkType = messageContext->messageType; + respHeader.messageHeader.messageSize = (UA_UInt32)totalLength; + if(messageContext->final) respHeader.messageHeader.messageTypeAndChunkType += UA_CHUNKTYPE_FINAL; else respHeader.messageHeader.messageTypeAndChunkType += UA_CHUNKTYPE_INTERMEDIATE; - res = UA_encodeBinary(&respHeader, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER], - &header_pos, &mc->buf_end, NULL, NULL); + + UA_StatusCode res = + UA_encodeBinary(&respHeader, &UA_TRANSPORT[UA_TRANSPORT_SECURECONVERSATIONMESSAGEHEADER], + &header_pos, &messageContext->buf_end, NULL, NULL); UA_SymmetricAlgorithmSecurityHeader symSecHeader; symSecHeader.tokenId = channel->securityToken.tokenId; res |= UA_encodeBinary(&symSecHeader.tokenId, &UA_TRANSPORT[UA_TRANSPORT_SYMMETRICALGORITHMSECURITYHEADER], - &header_pos, &mc->buf_end, NULL, NULL); + &header_pos, &messageContext->buf_end, NULL, NULL); UA_SequenceHeader seqHeader; - seqHeader.requestId = mc->requestId; + seqHeader.requestId = messageContext->requestId; seqHeader.sequenceNumber = UA_atomic_addUInt32(&channel->sendSequenceNumber, 1); res |= UA_encodeBinary(&seqHeader, &UA_TRANSPORT[UA_TRANSPORT_SEQUENCEHEADER], - &header_pos, &mc->buf_end, NULL, NULL); + &header_pos, &messageContext->buf_end, NULL, NULL); - /* Sign message */ + return res; +} + +static UA_StatusCode +sendSymmetricChunk(UA_MessageContext *messageContext) { + UA_SecureChannel *const channel = messageContext->channel; + const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; + UA_Connection *const connection = channel->connection; + if(!connection) + return UA_STATUSCODE_BADINTERNALERROR; + + size_t bodyLength = 0; + UA_StatusCode res = checkLimitsSym(messageContext, &bodyLength); + if(res != UA_STATUSCODE_GOOD) + goto error; + + /* Add padding */ +#ifdef UA_ENABLE_ENCRYPTION + padChunkSym(messageContext, bodyLength); +#endif + + /* The total message length */ + size_t pre_sig_length = (uintptr_t)(messageContext->buf_pos) - + (uintptr_t)messageContext->messageBuffer.data; + size_t total_length = pre_sig_length; if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || - channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - UA_ByteString dataToSign = mc->messageBuffer; - dataToSign.length = pre_sig_length; - UA_ByteString signature; - signature.length = securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm. + channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + total_length += securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm. getLocalSignatureSize(securityPolicy, channel->channelContext); - signature.data = mc->buf_pos; - res |= securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm. - sign(securityPolicy, channel->channelContext, &dataToSign, &signature); - } + /* Space for the padding and the signature have been reserved in setBufPos() */ + UA_assert(total_length <= connection->config.sendBufferSize); - /* Encrypt message */ - if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - UA_ByteString dataToEncrypt; - dataToEncrypt.data = mc->messageBuffer.data + UA_SECUREMH_AND_SYMALGH_LENGTH; - dataToEncrypt.length = total_length - UA_SECUREMH_AND_SYMALGH_LENGTH; - res |= securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm. - encrypt(securityPolicy, channel->channelContext, &dataToEncrypt); - } + /* For giving the buffer to the network layer */ + messageContext->messageBuffer.length = total_length; - if(res != UA_STATUSCODE_GOOD) { - connection->releaseSendBuffer(channel->connection, &mc->messageBuffer); - return res; - } + UA_assert(res == UA_STATUSCODE_GOOD); + res = encodeHeadersSym(messageContext, total_length); + if(res != UA_STATUSCODE_GOOD) + goto error; + +#ifdef UA_ENABLE_ENCRYPTION + res = signChunkSym(messageContext, pre_sig_length); + if(res != UA_STATUSCODE_GOOD) + goto error; + + res = encryptChunkSym(messageContext, total_length); + if(res != UA_STATUSCODE_GOOD) + goto error; +#endif /* Send the chunk, the buffer is freed in the network layer */ - return connection->send(channel->connection, &mc->messageBuffer); + return connection->send(channel->connection, &messageContext->messageBuffer); + +error: + connection->releaseSendBuffer(channel->connection, &messageContext->messageBuffer); + return res; } /* Callback from the encoding layer. Send the chunk and replace the buffer. */ @@ -18600,7 +19732,10 @@ sendSymmetricEncodingCallback(void *data, UA_Byte **buf_pos, const UA_Byte **buf /* Set a new buffer for the next chunk */ UA_Connection *connection = mc->channel->connection; - retval = connection->getSendBuffer(connection, connection->localConf.sendBufferSize, + if(!connection) + return UA_STATUSCODE_BADINTERNALERROR; + + retval = connection->getSendBuffer(connection, connection->config.sendBufferSize, &mc->messageBuffer); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -18631,13 +19766,9 @@ UA_MessageContext_begin(UA_MessageContext *mc, UA_SecureChannel *channel, mc->messageBuffer = UA_BYTESTRING_NULL; mc->messageType = messageType; - /* Minimum required size */ - if(connection->localConf.sendBufferSize <= UA_SECURE_MESSAGE_HEADER_LENGTH) - return UA_STATUSCODE_BADRESPONSETOOLARGE; - /* Allocate the message buffer */ UA_StatusCode retval = - connection->getSendBuffer(connection, connection->localConf.sendBufferSize, + connection->getSendBuffer(connection, connection->config.sendBufferSize, &mc->messageBuffer); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -18652,13 +19783,8 @@ UA_MessageContext_encode(UA_MessageContext *mc, const void *content, const UA_DataType *contentType) { UA_StatusCode retval = UA_encodeBinary(content, contentType, &mc->buf_pos, &mc->buf_end, sendSymmetricEncodingCallback, mc); - if(retval != UA_STATUSCODE_GOOD) { - /* TODO: Send the abort message */ - if(mc->messageBuffer.length > 0) { - UA_Connection *connection = mc->channel->connection; - connection->releaseSendBuffer(connection, &mc->messageBuffer); - } - } + if(retval != UA_STATUSCODE_GOOD && mc->messageBuffer.length > 0) + UA_MessageContext_abort(mc); return retval; } @@ -18678,13 +19804,11 @@ UA_StatusCode UA_SecureChannel_sendSymmetricMessage(UA_SecureChannel *channel, UA_UInt32 requestId, UA_MessageType messageType, void *payload, const UA_DataType *payloadType) { - if(!channel || !payload || !payloadType) + if(!channel || !channel->connection || !payload || !payloadType) return UA_STATUSCODE_BADINTERNALERROR; - if(channel->connection) { - if(channel->connection->state == UA_CONNECTION_CLOSED) - return UA_STATUSCODE_BADCONNECTIONCLOSED; - } + if(channel->connection->state == UA_CONNECTION_CLOSED) + return UA_STATUSCODE_BADCONNECTIONCLOSED; UA_MessageContext mc; UA_StatusCode retval = UA_MessageContext_begin(&mc, channel, requestId, messageType); @@ -18711,101 +19835,130 @@ UA_SecureChannel_sendSymmetricMessage(UA_SecureChannel *channel, UA_UInt32 reque /* Assemble Complete Message */ /*****************************/ -static void -UA_SecureChannel_removeChunks(UA_SecureChannel *channel, UA_UInt32 requestId) { - struct MessageEntry *me; - LIST_FOREACH(me, &channel->chunks, pointers) { - if(me->requestId == requestId) { - struct ChunkPayload *cp, *temp_cp; - SIMPLEQ_FOREACH_SAFE(cp, &me->chunkPayload, pointers, temp_cp) { - UA_ByteString_deleteMembers(&cp->bytes); - UA_free(cp); - } - LIST_REMOVE(me, pointers); - UA_free(me); - return; - } - } -} - static UA_StatusCode -appendChunk(struct MessageEntry *messageEntry, const UA_ByteString *chunkBody) { - - struct ChunkPayload* cp = (struct ChunkPayload*)UA_malloc(sizeof(struct ChunkPayload)); - UA_StatusCode retval = UA_ByteString_copy(chunkBody, &cp->bytes); - if (retval != UA_STATUSCODE_GOOD) - return retval; - - SIMPLEQ_INSERT_TAIL(&messageEntry->chunkPayload, cp, pointers); - messageEntry->chunkPayloadSize += chunkBody->length; - return UA_STATUSCODE_GOOD; -} - -static UA_StatusCode -UA_SecureChannel_appendChunk(UA_SecureChannel *channel, UA_UInt32 requestId, - const UA_ByteString *chunkBody) { - struct MessageEntry *me; - LIST_FOREACH(me, &channel->chunks, pointers) { - if(me->requestId == requestId) - break; +addChunkPayload(UA_SecureChannel *channel, UA_UInt32 requestId, + UA_MessageType messageType, UA_ByteString *chunkPayload, + UA_Boolean final) { + UA_Message *latest = TAILQ_LAST(&channel->messages, UA_MessageQueue); + if(latest) { + if(latest->requestId != requestId) { + /* Start of a new message */ + if(!latest->final) + return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; + latest = NULL; + } else { + if(latest->messageType != messageType) /* MessageType mismatch */ + return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; + if(latest->final) /* Correct message, but already finalized */ + return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; + } } - /* No chunkentry on the channel, create one */ - if(!me) { - me = (struct MessageEntry *)UA_malloc(sizeof(struct MessageEntry)); - if(!me) + /* Create a new message entry */ + if(!latest) { + latest = (UA_Message *)UA_malloc(sizeof(UA_Message)); + if(!latest) return UA_STATUSCODE_BADOUTOFMEMORY; - memset(me, 0, sizeof(struct MessageEntry)); - me->requestId = requestId; - SIMPLEQ_INIT(&me->chunkPayload); - LIST_INSERT_HEAD(&channel->chunks, me, pointers); + memset(latest, 0, sizeof(UA_Message)); + latest->requestId = requestId; + latest->messageType = messageType; + SIMPLEQ_INIT(&latest->chunkPayloads); + TAILQ_INSERT_TAIL(&channel->messages, latest, pointers); } - return appendChunk(me, chunkBody); + /* Test against the connection settings */ + const UA_ConnectionConfig *config = &channel->connection->config; + UA_assert(config != NULL); /* clang-analyzer false positive */ + + if(config->maxChunkCount > 0 && + config->maxChunkCount <= latest->chunkPayloadsSize) + return UA_STATUSCODE_BADRESPONSETOOLARGE; + + if(config->maxMessageSize > 0 && + config->maxMessageSize < latest->messageSize + chunkPayload->length) + return UA_STATUSCODE_BADRESPONSETOOLARGE; + + /* Create a new chunk entry */ + UA_ChunkPayload *cp = (UA_ChunkPayload *)UA_malloc(sizeof(UA_ChunkPayload)); + if(!cp) + return UA_STATUSCODE_BADOUTOFMEMORY; + cp->bytes = *chunkPayload; + cp->copied = false; + + /* Add the chunk */ + SIMPLEQ_INSERT_TAIL(&latest->chunkPayloads, cp, pointers); + latest->chunkPayloadsSize += 1; + latest->messageSize += chunkPayload->length; + latest->final = final; + + return UA_STATUSCODE_GOOD; } static UA_StatusCode -UA_SecureChannel_finalizeChunk(UA_SecureChannel *channel, UA_UInt32 requestId, - const UA_ByteString *chunkBody, UA_MessageType messageType, - UA_ProcessMessageCallback callback, void *application) { - struct MessageEntry *messageEntry; - LIST_FOREACH(messageEntry, &channel->chunks, pointers) { - if(messageEntry->requestId == requestId) - break; - } - - UA_ByteString bytes; - if(!messageEntry) { - bytes = *chunkBody; +processMessage(UA_SecureChannel *channel, const UA_Message *message, + void *application, UA_ProcessMessageCallback callback) { + if(message->chunkPayloadsSize == 1) { + /* No need to combine chunks */ + UA_ChunkPayload *cp = SIMPLEQ_FIRST(&message->chunkPayloads); + callback(application, channel, message->messageType, message->requestId, &cp->bytes); } else { - UA_StatusCode retval = appendChunk(messageEntry, chunkBody); - if(retval != UA_STATUSCODE_GOOD) - return retval; - - UA_ByteString_init(&bytes); - - bytes.data = (UA_Byte*) UA_malloc(messageEntry->chunkPayloadSize); - if (!bytes.data) + /* Allocate memory */ + UA_ByteString bytes; + bytes.data = (UA_Byte *)UA_malloc(message->messageSize); + if(!bytes.data) { + UA_LOG_ERROR(channel->securityPolicy->logger, UA_LOGCATEGORY_SECURECHANNEL, + "Could not allocate the memory to assemble the message"); return UA_STATUSCODE_BADOUTOFMEMORY; + } + bytes.length = message->messageSize; - struct ChunkPayload *cp, *temp_cp; + /* Assemble the full message */ size_t curPos = 0; - SIMPLEQ_FOREACH_SAFE(cp, &messageEntry->chunkPayload, pointers, temp_cp) { + UA_ChunkPayload *cp; + SIMPLEQ_FOREACH(cp, &message->chunkPayloads, pointers) { memcpy(&bytes.data[curPos], cp->bytes.data, cp->bytes.length); curPos += cp->bytes.length; - UA_ByteString_deleteMembers(&cp->bytes); - UA_free(cp); } - bytes.length = messageEntry->chunkPayloadSize; - - LIST_REMOVE(messageEntry, pointers); - UA_free(messageEntry); + /* Process the message */ + callback(application, channel, message->messageType, message->requestId, &bytes); + UA_ByteString_deleteMembers(&bytes); } + return UA_STATUSCODE_GOOD; +} - UA_StatusCode retval = callback(application, channel, messageType, requestId, &bytes); - if(messageEntry) - UA_ByteString_deleteMembers(&bytes); +UA_StatusCode +UA_SecureChannel_processCompleteMessages(UA_SecureChannel *channel, void *application, + UA_ProcessMessageCallback callback) { + UA_Message *message, *tmp_message; + UA_StatusCode retval = UA_STATUSCODE_GOOD; + TAILQ_FOREACH_SAFE(message, &channel->messages, pointers, tmp_message) { + /* Stop at the first incomplete message */ + if(!message->final) + break; + + /* Has the channel been closed (during the last message)? */ + if(channel->state == UA_SECURECHANNELSTATE_CLOSED) + break; + + /* Remove the current message before processing */ + TAILQ_REMOVE(&channel->messages, message, pointers); + + /* Process */ + retval = processMessage(channel, message, application, callback); + if(retval != UA_STATUSCODE_GOOD) + break; + + /* Clean up the message */ + UA_ChunkPayload *payload; + while((payload = SIMPLEQ_FIRST(&message->chunkPayloads))) { + if(payload->copied) + UA_ByteString_deleteMembers(&payload->bytes); + SIMPLEQ_REMOVE_HEAD(&message->chunkPayloads, pointers); + UA_free(payload); + } + UA_free(message); + } return retval; } @@ -18814,62 +19967,118 @@ UA_SecureChannel_finalizeChunk(UA_SecureChannel *channel, UA_UInt32 requestId, /****************************/ static UA_StatusCode -decryptChunk(UA_SecureChannel *channel, const UA_SecurityPolicyCryptoModule *cryptoModule, - UA_ByteString *chunk, size_t offset, UA_UInt32 *requestId, UA_UInt32 *sequenceNumber, - UA_ByteString *payload, UA_MessageType messageType) { - UA_StatusCode retval = UA_STATUSCODE_GOOD; - const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; - size_t chunkSizeAfterDecryption = chunk->length; +decryptChunk(const UA_SecureChannel *const channel, + const UA_SecurityPolicyCryptoModule *const cryptoModule, + UA_MessageType const messageType, const UA_ByteString *const chunk, + size_t const offset, size_t *const chunkSizeAfterDecryption) { + UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel, "Decrypting chunk"); + + UA_ByteString cipherText = {chunk->length - offset, chunk->data + offset}; + size_t sizeBeforeDecryption = cipherText.length; + size_t chunkSizeBeforeDecryption = *chunkSizeAfterDecryption; - /* Decrypt the chunk. Always decrypt opn messages if mode not none */ + /* Always decrypt opn messages if mode not none */ if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT || messageType == UA_MESSAGETYPE_OPN) { - UA_ByteString cipherText = {chunk->length - offset, chunk->data + offset}; - size_t sizeBeforeDecryption = cipherText.length; - retval = cryptoModule->encryptionAlgorithm.decrypt(securityPolicy, channel->channelContext, &cipherText); - chunkSizeAfterDecryption -= (sizeBeforeDecryption - cipherText.length); - if(retval != UA_STATUSCODE_GOOD) + UA_StatusCode retval = cryptoModule->encryptionAlgorithm. + decrypt(channel->securityPolicy, channel->channelContext, &cipherText); + *chunkSizeAfterDecryption -= (sizeBeforeDecryption - cipherText.length); + if(retval != UA_STATUSCODE_GOOD) { return retval; + } } + UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel, + "Chunk size before and after decryption: %lu, %lu", + (long unsigned int)chunkSizeBeforeDecryption, + (long unsigned int)*chunkSizeAfterDecryption); + + return UA_STATUSCODE_GOOD; +} + +static UA_UInt16 +decodeChunkPaddingSize(const UA_SecureChannel *const channel, + const UA_SecurityPolicyCryptoModule *const cryptoModule, + UA_MessageType const messageType, const UA_ByteString *const chunk, + size_t const chunkSizeAfterDecryption, size_t sigsize) { + /* Is padding used? */ + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT && + !(messageType == UA_MESSAGETYPE_OPN && channel->securityMode > UA_MESSAGESECURITYMODE_NONE)) + return 0; + + size_t paddingSize = chunk->data[chunkSizeAfterDecryption - sigsize - 1]; + + /* Extra padding size */ + size_t keyLength = cryptoModule->encryptionAlgorithm. + getRemoteKeyLength(channel->securityPolicy, channel->channelContext); + if(keyLength > 2048) { + paddingSize <<= 8u; + paddingSize += 1; + paddingSize += chunk->data[chunkSizeAfterDecryption - sigsize - 2]; + } + + /* We need to add one to the padding size since the paddingSize byte itself + * need to be removed as well. */ + paddingSize += 1; + + UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel, + "Calculated padding size to be %lu", + (long unsigned int)paddingSize); + return (UA_UInt16)paddingSize; +} + +static UA_StatusCode +verifyChunk(const UA_SecureChannel *const channel, + const UA_SecurityPolicyCryptoModule *const cryptoModule, + const UA_ByteString *const chunk, + size_t const chunkSizeAfterDecryption, size_t sigsize) { + UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel, + "Verifying chunk signature"); + + /* Verify the signature */ + const UA_ByteString chunkDataToVerify = {chunkSizeAfterDecryption - sigsize, chunk->data}; + const UA_ByteString signature = {sigsize, chunk->data + chunkSizeAfterDecryption - sigsize}; + UA_StatusCode retval = cryptoModule->signatureAlgorithm. + verify(channel->securityPolicy, channel->channelContext, &chunkDataToVerify, &signature); +#ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS + retval |= decrypt_verifySignatureFailure; +#endif + + return retval; +} + +/* Sets the payload to a pointer inside the chunk buffer. Returns the requestId + * and the sequenceNumber */ +static UA_StatusCode +decryptAndVerifyChunk(const UA_SecureChannel *channel, + const UA_SecurityPolicyCryptoModule *cryptoModule, + UA_MessageType messageType, const UA_ByteString *chunk, + size_t offset, UA_UInt32 *requestId, + UA_UInt32 *sequenceNumber, UA_ByteString *payload) { + size_t chunkSizeAfterDecryption = chunk->length; + UA_StatusCode retval = decryptChunk(channel, cryptoModule, messageType, + chunk, offset, &chunkSizeAfterDecryption); + if(retval != UA_STATUSCODE_GOOD) + return retval; + /* Verify the chunk signature */ size_t sigsize = 0; size_t paddingSize = 0; + const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT || messageType == UA_MESSAGETYPE_OPN) { - /* Compute the padding size */ - sigsize = cryptoModule->signatureAlgorithm.getRemoteSignatureSize(securityPolicy, channel->channelContext); - - if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT || - (messageType == UA_MESSAGETYPE_OPN && - channel->securityMode > UA_MESSAGESECURITYMODE_NONE)) { - paddingSize = (size_t)chunk->data[chunkSizeAfterDecryption - sigsize - 1]; - - size_t keyLength = - cryptoModule->encryptionAlgorithm.getRemoteKeyLength(securityPolicy, channel->channelContext); - if(keyLength > 2048) { - paddingSize <<= 8; /* Extra padding size */ - paddingSize += chunk->data[chunkSizeAfterDecryption - sigsize - 2]; - // see comment below but for extraPaddingSize - paddingSize += 1; - } + sigsize = cryptoModule->signatureAlgorithm. + getRemoteSignatureSize(securityPolicy, channel->channelContext); + paddingSize = decodeChunkPaddingSize(channel, cryptoModule, messageType, chunk, + chunkSizeAfterDecryption, sigsize); + if(retval != UA_STATUSCODE_GOOD) + return retval; - // we need to add one to the padding size since the paddingSize byte itself need to be removed as well. - // TODO: write unit test for correct padding calculation - paddingSize += 1; - } if(offset + paddingSize + sigsize >= chunkSizeAfterDecryption) return UA_STATUSCODE_BADSECURITYCHECKSFAILED; - /* Verify the signature */ - const UA_ByteString chunkDataToVerify = {chunkSizeAfterDecryption - sigsize, chunk->data}; - const UA_ByteString signature = {sigsize, chunk->data + chunkSizeAfterDecryption - sigsize}; - retval = cryptoModule->signatureAlgorithm.verify(securityPolicy, channel->channelContext, - &chunkDataToVerify, &signature); -#ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS - retval |= decrypt_verifySignatureFailure; -#endif + retval = verifyChunk(channel, cryptoModule, chunk, chunkSizeAfterDecryption, sigsize); if(retval != UA_STATUSCODE_GOOD) return retval; } @@ -18887,27 +20096,33 @@ decryptChunk(UA_SecureChannel *channel, const UA_SecurityPolicyCryptoModule *cry *sequenceNumber = sequenceHeader.sequenceNumber; payload->data = chunk->data + offset; payload->length = chunkSizeAfterDecryption - offset - sigsize - paddingSize; + UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel, + "Decrypted and verified chunk with request id %u and " + "sequence number %u", *requestId, *sequenceNumber); return UA_STATUSCODE_GOOD; } -typedef UA_StatusCode(*UA_SequenceNumberCallback)(UA_SecureChannel *channel, - UA_UInt32 sequenceNumber); +typedef UA_StatusCode +(*UA_SequenceNumberCallback)(UA_SecureChannel *channel, UA_UInt32 sequenceNumber); static UA_StatusCode -processSequenceNumberAsym(UA_SecureChannel *const channel, UA_UInt32 sequenceNumber) { +processSequenceNumberAsym(UA_SecureChannel *channel, UA_UInt32 sequenceNumber) { + UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel, + "Sequence Number processed: %i", sequenceNumber); channel->receiveSequenceNumber = sequenceNumber; - return UA_STATUSCODE_GOOD; } static UA_StatusCode -processSequenceNumberSym(UA_SecureChannel *const channel, UA_UInt32 sequenceNumber) { +processSequenceNumberSym(UA_SecureChannel *channel, UA_UInt32 sequenceNumber) { /* Failure mode hook for unit tests */ #ifdef UA_ENABLE_UNIT_TEST_FAILURE_HOOKS if(processSym_seqNumberFailure != UA_STATUSCODE_GOOD) return processSym_seqNumberFailure; #endif + UA_LOG_TRACE_CHANNEL(channel->securityPolicy->logger, channel, + "Sequence Number processed: %i", sequenceNumber); /* Does the sequence number match? */ if(sequenceNumber != channel->receiveSequenceNumber + 1) { /* FIXME: Remove magic numbers :( */ @@ -18923,10 +20138,10 @@ processSequenceNumberSym(UA_SecureChannel *const channel, UA_UInt32 sequenceNumb static UA_StatusCode checkAsymHeader(UA_SecureChannel *const channel, UA_AsymmetricAlgorithmSecurityHeader *const asymHeader) { - UA_StatusCode retval = UA_STATUSCODE_GOOD; const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy; - if(!UA_ByteString_equal(&securityPolicy->policyUri, &asymHeader->securityPolicyUri)) { + if(!UA_ByteString_equal(&securityPolicy->policyUri, + &asymHeader->securityPolicyUri)) { return UA_STATUSCODE_BADSECURITYPOLICYREJECTED; } @@ -18936,8 +20151,9 @@ checkAsymHeader(UA_SecureChannel *const channel, if(retval != UA_STATUSCODE_GOOD) return retval; */ - retval = securityPolicy->asymmetricModule. - compareCertificateThumbprint(securityPolicy, &asymHeader->receiverCertificateThumbprint); + UA_StatusCode retval = securityPolicy->asymmetricModule. + compareCertificateThumbprint(securityPolicy, + &asymHeader->receiverCertificateThumbprint); if(retval != UA_STATUSCODE_GOOD) { return retval; } @@ -18951,13 +20167,11 @@ checkPreviousToken(UA_SecureChannel *const channel, const UA_UInt32 tokenId) { return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN; UA_DateTime timeout = channel->previousSecurityToken.createdAt + - (UA_DateTime)((UA_Double)channel->previousSecurityToken.revisedLifetime * - (UA_Double)UA_DATETIME_MSEC * - 1.25); + (UA_DateTime)((UA_Double)channel->previousSecurityToken.revisedLifetime * + (UA_Double)UA_DATETIME_MSEC * 1.25); - if(timeout < UA_DateTime_nowMonotonic()) { + if(timeout < UA_DateTime_nowMonotonic()) return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN; - } return UA_STATUSCODE_GOOD; } @@ -18966,27 +20180,48 @@ static UA_StatusCode checkSymHeader(UA_SecureChannel *const channel, const UA_UInt32 tokenId, UA_Boolean allowPreviousToken) { + /* If the message uses the currently active token, check if it is still valid */ if(tokenId == channel->securityToken.tokenId) { if(channel->state == UA_SECURECHANNELSTATE_OPEN && (channel->securityToken.createdAt + - (channel->securityToken.revisedLifetime * UA_DATETIME_MSEC)) < UA_DateTime_nowMonotonic()) { - UA_SecureChannel_deleteMembersCleanup(channel); + (channel->securityToken.revisedLifetime * UA_DATETIME_MSEC)) + < UA_DateTime_nowMonotonic()) { + UA_SecureChannel_close(channel); return UA_STATUSCODE_BADSECURECHANNELCLOSED; } } + /* If the message uses a different token, check if it is the next token. */ if(tokenId != channel->securityToken.tokenId) { + /* If it isn't the next token, we might be dealing with a message, that + * still uses the old token, so check if the old one is still valid.*/ if(tokenId != channel->nextSecurityToken.tokenId) { if(allowPreviousToken) return checkPreviousToken(channel, tokenId); - else - return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN; + + return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN; + } + /* If the token is indeed the next token, revolve the tokens */ + UA_StatusCode retval = UA_SecureChannel_revolveTokens(channel); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* If the message now uses the currently active token also generate + * new remote keys to correctly decrypt. */ + if(channel->securityToken.tokenId == tokenId) { + retval = UA_SecureChannel_generateRemoteKeys(channel, channel->securityPolicy); + UA_ChannelSecurityToken_deleteMembers(&channel->previousSecurityToken); + return retval; } - return UA_SecureChannel_revolveTokens(channel); } + /* It is possible that the sent messages already use the new token, but + * the received messages still use the old token. If we receive a message + * with the new token, we will need to generate the keys and discard the + * old token now*/ if(channel->previousSecurityToken.tokenId != 0) { - UA_StatusCode retval = UA_SecureChannel_generateRemoteKeys(channel, channel->securityPolicy); + UA_StatusCode retval = + UA_SecureChannel_generateRemoteKeys(channel, channel->securityPolicy); UA_ChannelSecurityToken_deleteMembers(&channel->previousSecurityToken); return retval; } @@ -18994,11 +20229,28 @@ checkSymHeader(UA_SecureChannel *const channel, return UA_STATUSCODE_GOOD; } -UA_StatusCode -UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, - UA_ProcessMessageCallback callback, - void *application, UA_Boolean allowPreviousToken) { - /* Decode message header */ +static UA_StatusCode +putPayload(UA_SecureChannel *const channel, UA_UInt32 const requestId, + UA_MessageType const messageType, UA_ChunkType const chunkType, + UA_ByteString *chunkPayload) { + switch(chunkType) { + case UA_CHUNKTYPE_INTERMEDIATE: + case UA_CHUNKTYPE_FINAL: + return addChunkPayload(channel, requestId, messageType, + chunkPayload, chunkType == UA_CHUNKTYPE_FINAL); + case UA_CHUNKTYPE_ABORT: + deleteLatestMessage(channel, requestId); + return UA_STATUSCODE_GOOD; + default: + return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; + } +} + +/* The chunk body begins after the SecureConversationMessageHeader */ +static UA_StatusCode +decryptAddChunk(UA_SecureChannel *channel, const UA_ByteString *chunk, + UA_Boolean allowPreviousToken) { + /* Decode the MessageHeader */ size_t offset = 0; UA_SecureConversationMessageHeader messageHeader; UA_StatusCode retval = @@ -19017,8 +20269,6 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, (messageHeader.messageHeader.messageTypeAndChunkType & UA_BITMASK_MESSAGETYPE); UA_ChunkType chunkType = (UA_ChunkType) (messageHeader.messageHeader.messageTypeAndChunkType & UA_BITMASK_CHUNKTYPE); - - /* ERR message (not encrypted) */ UA_UInt32 requestId = 0; UA_UInt32 sequenceNumber = 0; UA_ByteString chunkPayload; @@ -19026,14 +20276,15 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, UA_SequenceNumberCallback sequenceNumberCallback = NULL; switch(messageType) { - case UA_MESSAGETYPE_ERR: { + /* ERR message (not encrypted) */ + case UA_MESSAGETYPE_ERR: if(chunkType != UA_CHUNKTYPE_FINAL) return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; chunkPayload.length = chunk->length - offset; chunkPayload.data = chunk->data + offset; - return callback(application, channel, messageType, requestId, &chunkPayload); - } + return putPayload(channel, requestId, messageType, chunkType, &chunkPayload); + /* MSG and CLO: Symmetric encryption */ case UA_MESSAGETYPE_MSG: case UA_MESSAGETYPE_CLO: { /* Decode and check the symmetric security header (tokenId) */ @@ -19057,6 +20308,8 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, sequenceNumberCallback = processSequenceNumberSym; break; } + + /* OPN: Asymmetric encryption */ case UA_MESSAGETYPE_OPN: { /* Chunking not allowed for OPN */ if(chunkType != UA_CHUNKTYPE_FINAL) @@ -19080,44 +20333,71 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk, sequenceNumberCallback = processSequenceNumberAsym; break; } + + /* Invalid message type */ default:return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; } - /* Decrypt message */ UA_assert(cryptoModule != NULL); - retval = decryptChunk(channel, cryptoModule, chunk, offset, &requestId, - &sequenceNumber, &chunkPayload, messageType); + retval = decryptAndVerifyChunk(channel, cryptoModule, messageType, chunk, offset, + &requestId, &sequenceNumber, &chunkPayload); if(retval != UA_STATUSCODE_GOOD) return retval; - /* Check the sequence number */ + /* Check the sequence number. Skip sequence number checking for fuzzer to + * improve coverage */ if(sequenceNumberCallback == NULL) return UA_STATUSCODE_BADINTERNALERROR; - retval = sequenceNumberCallback(channel, sequenceNumber); - - /* Skip sequence number checking for fuzzer to improve coverage */ - if(retval != UA_STATUSCODE_GOOD) { -#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) - return retval; +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) + retval = UA_STATUSCODE_GOOD; #else - retval = UA_STATUSCODE_GOOD; + retval = sequenceNumberCallback(channel, sequenceNumber); #endif - } + if(retval != UA_STATUSCODE_GOOD) + return retval; + + return putPayload(channel, requestId, messageType, chunkType, &chunkPayload); +} + +UA_StatusCode +UA_SecureChannel_decryptAddChunk(UA_SecureChannel *channel, const UA_ByteString *chunk, + UA_Boolean allowPreviousToken) { + /* Has the SecureChannel timed out? */ + if(channel->state == UA_SECURECHANNELSTATE_CLOSED) + return UA_STATUSCODE_BADSECURECHANNELCLOSED; + + /* Is the SecureChannel configured? */ + if(!channel->connection) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_StatusCode retval = decryptAddChunk(channel, chunk, allowPreviousToken); + if(retval != UA_STATUSCODE_GOOD) + UA_SecureChannel_close(channel); - /* Process the payload */ - if(chunkType == UA_CHUNKTYPE_FINAL) { - retval = UA_SecureChannel_finalizeChunk(channel, requestId, &chunkPayload, - messageType, callback, application); - } else if(chunkType == UA_CHUNKTYPE_INTERMEDIATE) { - retval = UA_SecureChannel_appendChunk(channel, requestId, &chunkPayload); - } else if(chunkType == UA_CHUNKTYPE_ABORT) { - UA_SecureChannel_removeChunks(channel, requestId); - } else { - retval = UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; - } return retval; } +UA_StatusCode +UA_SecureChannel_persistIncompleteMessages(UA_SecureChannel *channel) { + UA_Message *me; + TAILQ_FOREACH(me, &channel->messages, pointers) { + UA_ChunkPayload *cp; + SIMPLEQ_FOREACH(cp, &me->chunkPayloads, pointers) { + if(cp->copied) + continue; + UA_ByteString copy; + UA_StatusCode retval = UA_ByteString_copy(&cp->bytes, ©); + if(retval != UA_STATUSCODE_GOOD) { + UA_SecureChannel_close(channel); + return retval; + } + cp->bytes = copy; + cp->copied = true; + } + } + return UA_STATUSCODE_GOOD; +} + /* Functionality used by both the SecureChannel and the SecurityPolicy */ size_t @@ -19127,10 +20407,10 @@ UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(const UA_SecurityP if(maxEncryptionLength == 0) return 0; - size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. - getRemotePlainTextBlockSize(securityPolicy, channelContext); - size_t encryptedBlockSize = securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. - getRemoteBlockSize(securityPolicy, channelContext); + size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule. + encryptionAlgorithm.getRemotePlainTextBlockSize(securityPolicy, channelContext); + size_t encryptedBlockSize = securityPolicy->asymmetricModule.cryptoModule. + encryptionAlgorithm.getRemoteBlockSize(securityPolicy, channelContext); if(plainTextBlockSize == 0) return 0; @@ -19144,7 +20424,7 @@ UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(const UA_SecurityP * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA */ @@ -19161,49 +20441,20 @@ void UA_Session_init(UA_Session *session) { #endif } -#ifdef UA_ENABLE_SUBSCRIPTIONS -static void -deleteSubscription(UA_Server *server, UA_Session *session, - UA_Subscription *sub) { - UA_Subscription_deleteMembers(server, sub); - - /* Add a delayed callback to remove the subscription when the currently - * scheduled jobs have completed */ - UA_StatusCode retval = UA_Server_delayedFree(server, sub); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING_SESSION(server->config.logger, session, - "Could not remove subscription with error code %s", - UA_StatusCode_name(retval)); - } - - /* Remove from the session */ - LIST_REMOVE(sub, listEntry); - UA_assert(session->numSubscriptions > 0); - session->numSubscriptions--; -} -#endif - -void UA_Session_deleteMembersCleanup(UA_Session *session, UA_Server *server) { +void UA_Session_deleteMembersCleanup(UA_Session *session, UA_Server* server) { UA_Session_detachFromSecureChannel(session); UA_ApplicationDescription_deleteMembers(&session->clientDescription); UA_NodeId_deleteMembers(&session->header.authenticationToken); UA_NodeId_deleteMembers(&session->sessionId); UA_String_deleteMembers(&session->sessionName); UA_ByteString_deleteMembers(&session->serverNonce); - struct ContinuationPointEntry *cp, *temp; - LIST_FOREACH_SAFE(cp, &session->continuationPoints, pointers, temp) { - LIST_REMOVE(cp, pointers); - UA_ByteString_deleteMembers(&cp->identifier); - UA_BrowseDescription_deleteMembers(&cp->browseDescription); + struct ContinuationPoint *cp, *next = session->continuationPoints; + while((cp = next)) { + next = ContinuationPoint_clear(cp); UA_free(cp); } - -#ifdef UA_ENABLE_SUBSCRIPTIONS - UA_Subscription *sub, *sub_tmp; - LIST_FOREACH_SAFE(sub, &session->serverSubscriptions, listEntry, sub_tmp) { - deleteSubscription(server, session, sub); - } -#endif + session->continuationPoints = NULL; + session->availableContinuationPoints = UA_MAXCONTINUATIONPOINTS; } void UA_Session_attachToSecureChannel(UA_Session *session, UA_SecureChannel *channel) { @@ -19244,11 +20495,12 @@ void UA_Session_updateLifetime(UA_Session *session) { #ifdef UA_ENABLE_SUBSCRIPTIONS -void UA_Session_addSubscription(UA_Session *session, UA_Subscription *newSubscription) { +void UA_Session_addSubscription(UA_Server *server, UA_Session *session, UA_Subscription *newSubscription) { newSubscription->subscriptionId = ++session->lastSubscriptionId; LIST_INSERT_HEAD(&session->serverSubscriptions, newSubscription, listEntry); session->numSubscriptions++; + server->numSubscriptions++; } UA_StatusCode @@ -19258,7 +20510,20 @@ UA_Session_deleteSubscription(UA_Server *server, UA_Session *session, if(!sub) return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID; - deleteSubscription(server, session, sub); + UA_Subscription_deleteMembers(server, sub); + + /* Add a delayed callback to remove the subscription when the currently + * scheduled jobs have completed. There is no actual delayed callback. Just + * free the structure. */ + sub->delayedFreePointers.callback = NULL; + UA_WorkQueue_enqueueDelayed(&server->workQueue, &sub->delayedFreePointers); + + /* Remove from the session */ + LIST_REMOVE(sub, listEntry); + UA_assert(session->numSubscriptions > 0); + UA_assert(server->numSubscriptions > 0); + session->numSubscriptions--; + server->numSubscriptions--; return UA_STATUSCODE_GOOD; } @@ -19297,9 +20562,9 @@ UA_Session_queuePublishReq(UA_Session *session, UA_PublishResponseEntry* entry, /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015 (c) Chris Iatrou * Copyright 2015, 2017 (c) Florian Palm @@ -19450,6 +20715,7 @@ UA_Node_copy(const UA_Node *src, UA_Node *dst) { retval |= UA_LocalizedText_copy(&src->description, &dst->description); dst->writeMask = src->writeMask; dst->context = src->context; + dst->constructed = src->constructed; if(retval != UA_STATUSCODE_GOOD) { UA_Node_deleteMembers(dst); return retval; @@ -19524,37 +20790,41 @@ UA_Node_copy(const UA_Node *src, UA_Node *dst) { UA_Node * UA_Node_copy_alloc(const UA_Node *src) { - // use dstPtr to trick static code analysis in accepting dirty cast - void *dstPtr; + /* use dstPtr to trick static code analysis in accepting dirty cast */ + size_t nodesize = 0; switch(src->nodeClass) { case UA_NODECLASS_OBJECT: - dstPtr = UA_malloc(sizeof(UA_ObjectNode)); + nodesize = sizeof(UA_ObjectNode); break; case UA_NODECLASS_VARIABLE: - dstPtr =UA_malloc(sizeof(UA_VariableNode)); + nodesize = sizeof(UA_VariableNode); break; case UA_NODECLASS_METHOD: - dstPtr = UA_malloc(sizeof(UA_MethodNode)); + nodesize = sizeof(UA_MethodNode); break; case UA_NODECLASS_OBJECTTYPE: - dstPtr = UA_malloc(sizeof(UA_ObjectTypeNode)); + nodesize = sizeof(UA_ObjectTypeNode); break; case UA_NODECLASS_VARIABLETYPE: - dstPtr = UA_malloc(sizeof(UA_VariableTypeNode)); + nodesize = sizeof(UA_VariableTypeNode); break; case UA_NODECLASS_REFERENCETYPE: - dstPtr = UA_malloc(sizeof(UA_ReferenceTypeNode)); + nodesize = sizeof(UA_ReferenceTypeNode); break; case UA_NODECLASS_DATATYPE: - dstPtr = UA_malloc(sizeof(UA_DataTypeNode)); + nodesize = sizeof(UA_DataTypeNode); break; case UA_NODECLASS_VIEW: - dstPtr = UA_malloc(sizeof(UA_ViewNode)); + nodesize = sizeof(UA_ViewNode); break; default: return NULL; } - UA_Node *dst = (UA_Node*)dstPtr; + + UA_Node *dst = (UA_Node*)UA_calloc(1,nodesize); + if(!dst) + return NULL; + dst->nodeClass = src->nodeClass; UA_StatusCode retval = UA_Node_copy(src, dst); @@ -19572,9 +20842,20 @@ static UA_StatusCode copyStandardAttributes(UA_Node *node, const UA_NodeAttributes *attr) { /* retval = UA_NodeId_copy(&item->requestedNewNodeId.nodeId, &node->nodeId); */ /* retval |= UA_QualifiedName_copy(&item->browseName, &node->browseName); */ - UA_StatusCode retval = UA_LocalizedText_copy(&attr->displayName, - &node->displayName); - retval |= UA_LocalizedText_copy(&attr->description, &node->description); + + UA_StatusCode retval; + /* The new nodeset format has optional display name. + * See https://github.com/open62541/open62541/issues/2627 + * If display name is NULL, then we take the name part of the browse name */ + if (attr->displayName.text.length == 0) { + retval = UA_String_copy(&node->browseName.name, + &node->displayName.text); + } else { + retval = UA_LocalizedText_copy(&attr->displayName, + &node->displayName); + retval |= UA_LocalizedText_copy(&attr->description, &node->description); + } + node->writeMask = attr->writeMask; return retval; } @@ -19591,57 +20872,15 @@ copyCommonVariableAttributes(UA_VariableNode *node, node->arrayDimensionsSize = attr->arrayDimensionsSize; /* Data type and value rank */ - retval |= UA_NodeId_copy(&attr->dataType, &node->dataType); + retval = UA_NodeId_copy(&attr->dataType, &node->dataType); + if(retval != UA_STATUSCODE_GOOD) + return retval; node->valueRank = attr->valueRank; /* Copy the value */ + retval = UA_Variant_copy(&attr->value, &node->value.data.value.value); node->valueSource = UA_VALUESOURCE_DATA; - UA_NodeId extensionObject = UA_NODEID_NUMERIC(0, UA_NS0ID_STRUCTURE); - /* if we have an extension object which is still encoded (e.g. from the nodeset compiler) - * we need to decode it and set the decoded value instead of the encoded object */ - UA_Boolean valueSet = false; - if(attr->value.type != NULL && UA_NodeId_equal(&attr->value.type->typeId, &extensionObject)) { - - if (attr->value.data == UA_EMPTY_ARRAY_SENTINEL) { - /* do nothing since we got an empty array of extension objects */ - return UA_STATUSCODE_GOOD; - } - - const UA_ExtensionObject *obj = (const UA_ExtensionObject *)attr->value.data; - if(obj && obj->encoding == UA_EXTENSIONOBJECT_ENCODED_BYTESTRING) { - - /* TODO: Once we generate type description in the nodeset compiler, - * UA_findDatatypeByBinary can be made internal to the decoding - * layer. */ - const UA_DataType *type = UA_findDataTypeByBinary(&obj->content.encoded.typeId); - - if(type) { - void *dst = UA_Array_new(attr->value.arrayLength, type); - if (!dst) { - return UA_STATUSCODE_BADOUTOFMEMORY; - } - uint8_t *tmpPos = (uint8_t *)dst; - - for(size_t i=0; i<attr->value.arrayLength; i++) { - size_t offset =0; - const UA_ExtensionObject *curr = &((const UA_ExtensionObject *)attr->value.data)[i]; - UA_StatusCode ret = UA_decodeBinary(&curr->content.encoded.body, &offset, tmpPos, type, 0, NULL); - if(ret != UA_STATUSCODE_GOOD) { - return ret; - } - tmpPos += type->memSize; - } - - UA_Variant_setArray(&node->value.data.value.value, dst, attr->value.arrayLength, type); - valueSet = true; - } - } - } - - if(!valueSet) - retval |= UA_Variant_copy(&attr->value, &node->value.data.value.value); - - node->value.data.value.hasValue = true; + node->value.data.value.hasValue = (node->value.data.value.value.type != NULL); return retval; } @@ -19714,7 +20953,6 @@ copyMethodNodeAttributes(UA_MethodNode *mnode, UA_StatusCode UA_Node_setAttributes(UA_Node *node, const void *attributes, const UA_DataType *attributeType) { - /* Copy the attributes into the node */ UA_StatusCode retval = UA_STATUSCODE_GOOD; switch(node->nodeClass) { @@ -19856,11 +21094,12 @@ UA_Node_deleteReference(UA_Node *node, const UA_DeleteReferencesItem *item) { continue; for(size_t j = refs->targetIdsSize; j > 0; --j) { - if(!UA_NodeId_equal(&item->targetNodeId.nodeId, &refs->targetIds[j-1].nodeId)) + UA_ExpandedNodeId *target = &refs->targetIds[j-1]; + if(!UA_NodeId_equal(&item->targetNodeId.nodeId, &target->nodeId)) continue; /* Ok, delete the reference */ - UA_ExpandedNodeId_deleteMembers(&refs->targetIds[j-1]); + UA_ExpandedNodeId_deleteMembers(target); refs->targetIdsSize--; /* One matching target remaining */ @@ -19868,11 +21107,11 @@ UA_Node_deleteReference(UA_Node *node, const UA_DeleteReferencesItem *item) { if(j-1 != refs->targetIdsSize) // avoid valgrind error: Source // and destination overlap in // memcpy - refs->targetIds[j-1] = refs->targetIds[refs->targetIdsSize]; + *target = refs->targetIds[refs->targetIdsSize]; return UA_STATUSCODE_GOOD; } - /* Remove refs */ + /* No target for the ReferenceType remaining. Remove entry. */ UA_free(refs->targetIds); UA_NodeId_deleteMembers(&refs->referenceTypeId); node->referencesSize--; @@ -19884,7 +21123,7 @@ UA_Node_deleteReference(UA_Node *node, const UA_DeleteReferencesItem *item) { return UA_STATUSCODE_GOOD; } - /* Remove the node references */ + /* No remaining references of any ReferenceType */ UA_free(node->references); node->references = NULL; return UA_STATUSCODE_GOOD; @@ -19893,16 +21132,53 @@ UA_Node_deleteReference(UA_Node *node, const UA_DeleteReferencesItem *item) { return UA_STATUSCODE_UNCERTAINREFERENCENOTDELETED; } -void UA_Node_deleteReferences(UA_Node *node) { - for(size_t i = 0; i < node->referencesSize; ++i) { - UA_NodeReferenceKind *refs = &node->references[i]; +void +UA_Node_deleteReferencesSubset(UA_Node *node, size_t referencesSkipSize, + UA_NodeId* referencesSkip) { + /* Nothing to do */ + if(node->referencesSize == 0 || node->references == NULL) + return; + + for(size_t i = node->referencesSize; i > 0; --i) { + UA_NodeReferenceKind *refs = &node->references[i-1]; + + /* Shall we keep the references of this type? */ + UA_Boolean skip = false; + for(size_t j = 0; j < referencesSkipSize; j++) { + if(UA_NodeId_equal(&refs->referenceTypeId, &referencesSkip[j])) { + skip = true; + break; + } + } + if(skip) + continue; + + /* Remove references */ UA_Array_delete(refs->targetIds, refs->targetIdsSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); UA_NodeId_deleteMembers(&refs->referenceTypeId); + node->referencesSize--; + + /* Move last references-kind entry to this position */ + if(i-1 == node->referencesSize) /* Don't memcpy over the same position */ + continue; + node->references[i-1] = node->references[node->referencesSize]; } - if(node->references) + + if(node->referencesSize == 0) { + /* The array is empty. Remove. */ UA_free(node->references); - node->references = NULL; - node->referencesSize = 0; + node->references = NULL; + } else { + /* Realloc to save memory */ + UA_NodeReferenceKind *refs = (UA_NodeReferenceKind*) + UA_realloc(node->references, sizeof(UA_NodeReferenceKind) * node->referencesSize); + if(refs) /* Do nothing if realloc fails */ + node->references = refs; + } +} + +void UA_Node_deleteReferences(UA_Node *node) { + UA_Node_deleteReferencesSubset(node, 0, NULL); } /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_server.c" ***********************************/ @@ -19911,7 +21187,7 @@ void UA_Node_deleteReferences(UA_Node *node) { * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2017 (c) Florian Palm * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015-2016 (c) Chris Iatrou @@ -19922,14 +21198,44 @@ void UA_Node_deleteReferences(UA_Node *node) { * Copyright 2016 (c) Lorenz Haas * Copyright 2017 (c) frax2222 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2018 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Martin Lang) + * Copyright 2019 (c) Kalycito Infotech Private Limited */ +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL +#endif + +#ifdef UA_ENABLE_SUBSCRIPTIONS +#endif + +#ifdef UA_ENABLE_VALGRIND_INTERACTIVE +#include <valgrind/memcheck.h> +#endif + /**********************/ /* Namespace Handling */ /**********************/ +/* + * The NS1 Uri can be changed by the user to some custom string. + * This method is called to initialize the NS1 Uri if it is not set before to the default Application URI. + * + * This is done as soon as the Namespace Array is read or written via node value read / write services, + * or UA_Server_addNamespace, UA_Server_getNamespaceByName or UA_Server_run_startup is called. + * + * Therefore one has to set the custom NS1 URI before one of the previously mentioned steps. + */ +void setupNs1Uri(UA_Server *server) { + if (!server->namespaces[1].data) { + UA_String_copy(&server->config.applicationDescription.applicationUri, &server->namespaces[1]); + } +} + UA_UInt16 addNamespace(UA_Server *server, const UA_String name) { + /* ensure that the uri for ns1 is set up from the app description */ + setupNs1Uri(server); + /* Check if the namespace already exists in the server's namespace array */ for(UA_UInt16 i = 0; i < server->namespacesSize; ++i) { if(UA_String_equal(&name, &server->namespaces[i])) @@ -19961,12 +21267,34 @@ UA_UInt16 UA_Server_addNamespace(UA_Server *server, const char* name) { return addNamespace(server, nameString); } +UA_ServerConfig* +UA_Server_getConfig(UA_Server *server) +{ + if(!server) + return NULL; + + return &server->config; +} + +UA_StatusCode +UA_Server_getNamespaceByName(UA_Server *server, const UA_String namespaceUri, + size_t* foundIndex) { + /* ensure that the uri for ns1 is set up from the app description */ + setupNs1Uri(server); + + for(size_t idx = 0; idx < server->namespacesSize; idx++) { + if(!UA_String_equal(&server->namespaces[idx], &namespaceUri)) + continue; + (*foundIndex) = idx; + return UA_STATUSCODE_GOOD; + } + return UA_STATUSCODE_BADNOTFOUND; +} + UA_StatusCode UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId, UA_NodeIteratorCallback callback, void *handle) { - const UA_Node *parent = - server->config.nodestore.getNode(server->config.nodestore.context, - &parentNodeId); + const UA_Node *parent = UA_Nodestore_getNode(server->nsCtx, &parentNodeId); if(!parent) return UA_STATUSCODE_BADNODEIDINVALID; @@ -19979,21 +21307,26 @@ UA_Server_forEachChildNodeCall(UA_Server *server, UA_NodeId parentNodeId, * */ UA_Node *parentCopy = UA_Node_copy_alloc(parent); if(!parentCopy) { - server->config.nodestore.releaseNode(server->config.nodestore.context, parent); + UA_Nodestore_releaseNode(server->nsCtx, parent); return UA_STATUSCODE_BADUNEXPECTEDERROR; } UA_StatusCode retval = UA_STATUSCODE_GOOD; for(size_t i = parentCopy->referencesSize; i > 0; --i) { UA_NodeReferenceKind *ref = &parentCopy->references[i - 1]; - for(size_t j = 0; j<ref->targetIdsSize; j++) - retval |= callback(ref->targetIds[j].nodeId, ref->isInverse, - ref->referenceTypeId, handle); + for(size_t j = 0; j<ref->targetIdsSize; j++) { + retval = callback(ref->targetIds[j].nodeId, ref->isInverse, + ref->referenceTypeId, handle); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + } } + +cleanup: UA_Node_deleteMembers(parentCopy); UA_free(parentCopy); - server->config.nodestore.releaseNode(server->config.nodestore.context, parent); + UA_Nodestore_releaseNode(server->nsCtx, parent); return retval; } @@ -20008,62 +21341,37 @@ void UA_Server_delete(UA_Server *server) { UA_SessionManager_deleteMembers(&server->sessionManager); UA_Array_delete(server->namespaces, server->namespacesSize, &UA_TYPES[UA_TYPES_STRING]); -#ifdef UA_ENABLE_DISCOVERY - registeredServer_list_entry *rs, *rs_tmp; - LIST_FOREACH_SAFE(rs, &server->registeredServers, pointers, rs_tmp) { - LIST_REMOVE(rs, pointers); - UA_RegisteredServer_deleteMembers(&rs->registeredServer); - UA_free(rs); - } - periodicServerRegisterCallback_entry *ps, *ps_tmp; - LIST_FOREACH_SAFE(ps, &server->periodicServerRegisterCallbacks, pointers, ps_tmp) { - LIST_REMOVE(ps, pointers); - UA_free(ps->callback); - UA_free(ps); - } - -# ifdef UA_ENABLE_DISCOVERY_MULTICAST - if(server->config.applicationDescription.applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER) - destroyMulticastDiscoveryServer(server); - - serverOnNetwork_list_entry *son, *son_tmp; - LIST_FOREACH_SAFE(son, &server->serverOnNetwork, pointers, son_tmp) { - LIST_REMOVE(son, pointers); - UA_ServerOnNetwork_deleteMembers(&son->serverOnNetwork); - if(son->pathTmp) - UA_free(son->pathTmp); - UA_free(son); +#ifdef UA_ENABLE_SUBSCRIPTIONS + UA_MonitoredItem *mon, *mon_tmp; + LIST_FOREACH_SAFE(mon, &server->localMonitoredItems, listEntry, mon_tmp) { + LIST_REMOVE(mon, listEntry); + UA_MonitoredItem_delete(server, mon); } +#endif - for(size_t i = 0; i < SERVER_ON_NETWORK_HASH_PRIME; i++) { - serverOnNetwork_hash_entry* currHash = server->serverOnNetworkHash[i]; - while(currHash) { - serverOnNetwork_hash_entry* nextHash = currHash->next; - UA_free(currHash); - currHash = nextHash; - } - } -# endif +#ifdef UA_ENABLE_PUBSUB + UA_PubSubManager_delete(server, &server->pubSubManager); +#endif +#ifdef UA_ENABLE_DISCOVERY + UA_DiscoveryManager_deleteMembers(&server->discoveryManager, server); #endif - /* Clean up the admin session */ + /* Clean up the Admin Session */ UA_Session_deleteMembersCleanup(&server->adminSession, server); -#ifdef UA_ENABLE_MULTITHREADING - /* Process new delayed callbacks from the cleanup */ - UA_Server_cleanupDispatchQueue(server); - pthread_mutex_destroy(&server->dispatchQueue_accessMutex); - pthread_cond_destroy(&server->dispatchQueue_condition); - pthread_mutex_destroy(&server->dispatchQueue_conditionMutex); -#else - /* Process new delayed callbacks from the cleanup */ - UA_Server_cleanupDelayedCallbacks(server); -#endif + /* Clean up the work queue */ + UA_WorkQueue_cleanup(&server->workQueue); /* Delete the timed work */ UA_Timer_deleteMembers(&server->timer); + /* Clean up the nodestore */ + UA_Nodestore_delete(server->nsCtx); + + /* Clean up the config */ + UA_ServerConfig_clean(&server->config); + /* Delete the server itself */ UA_free(server); } @@ -20083,36 +21391,8 @@ UA_Server_cleanup(UA_Server *server, void *_) { /* Server Lifecycle */ /********************/ -UA_Server * -UA_Server_new(const UA_ServerConfig *config) { - /* A config is required */ - if(!config) - return NULL; - - /* At least one endpoint has to be configured */ - if(config->endpointsSize == 0) { - UA_LOG_FATAL(config->logger, UA_LOGCATEGORY_SERVER, - "There has to be at least one endpoint."); - return NULL; - } - - /* Allocate the server */ - UA_Server *server = (UA_Server *)UA_calloc(1, sizeof(UA_Server)); - if(!server) - return NULL; - - /* Set the config */ - server->config = *config; - - /* Initialize the admin session */ - UA_Session_init(&server->adminSession); - server->adminSession.header.authenticationToken = UA_NODEID_NUMERIC(0, 1); - server->adminSession.sessionId.identifierType = UA_NODEIDTYPE_GUID; - server->adminSession.sessionId.identifier.guid.data1 = 1; - server->adminSession.sessionName = UA_STRING_ALLOC("Administrator Session"); - server->adminSession.validTill = UA_INT64_MAX; - server->adminSession.availableContinuationPoints = UA_MAXCONTINUATIONPOINTS; - +static UA_Server * +UA_Server_init(UA_Server *server) { /* Init start time to zero, the actual start time will be sampled in * UA_Server_run_startup() */ server->startTime = 0; @@ -20125,121 +21405,467 @@ UA_Server_new(const UA_ServerConfig *config) { /* Initialize the handling of repeated callbacks */ UA_Timer_init(&server->timer); - /* Initialized the linked list for delayed callbacks */ -#ifndef UA_ENABLE_MULTITHREADING - SLIST_INIT(&server->delayedCallbacks); -#endif + UA_WorkQueue_init(&server->workQueue); - /* Initialized the dispatch queue for worker threads */ -#ifdef UA_ENABLE_MULTITHREADING - SIMPLEQ_INIT(&server->dispatchQueue); -#endif + /* Initialize the adminSession */ + UA_Session_init(&server->adminSession); + server->adminSession.sessionId.identifierType = UA_NODEIDTYPE_GUID; + server->adminSession.sessionId.identifier.guid.data1 = 1; + server->adminSession.validTill = UA_INT64_MAX; - /* Create Namespaces 0 and 1 */ + /* Create Namespaces 0 and 1 + * Ns1 will be filled later with the uri from the app description */ server->namespaces = (UA_String *)UA_Array_new(2, &UA_TYPES[UA_TYPES_STRING]); + if(!server->namespaces) { + UA_Server_delete(server); + return NULL; + } server->namespaces[0] = UA_STRING_ALLOC("http://opcfoundation.org/UA/"); - UA_String_copy(&server->config.applicationDescription.applicationUri, &server->namespaces[1]); + server->namespaces[1] = UA_STRING_NULL; server->namespacesSize = 2; /* Initialized SecureChannel and Session managers */ UA_SecureChannelManager_init(&server->secureChannelManager, server); UA_SessionManager_init(&server->sessionManager, server); - /* Add a regular callback for cleanup and maintenance */ + /* Add a regular callback for cleanup and maintenance. With a 10s interval. */ UA_Server_addRepeatedCallback(server, (UA_ServerCallback)UA_Server_cleanup, NULL, - 10000, NULL); + 10000.0, NULL); - /* Initialized discovery database */ -#ifdef UA_ENABLE_DISCOVERY - LIST_INIT(&server->registeredServers); - server->registeredServersSize = 0; - LIST_INIT(&server->periodicServerRegisterCallbacks); - server->registerServerCallback = NULL; - server->registerServerCallbackData = NULL; -#endif + /* Initialize namespace 0*/ + UA_StatusCode retVal = UA_Nodestore_new(&server->nsCtx); + if(retVal != UA_STATUSCODE_GOOD) + goto cleanup; - /* Initialize multicast discovery */ -#if defined(UA_ENABLE_DISCOVERY) && defined(UA_ENABLE_DISCOVERY_MULTICAST) - server->mdnsDaemon = NULL; -#ifdef _WIN32 - server->mdnsSocket = INVALID_SOCKET; -#else - server->mdnsSocket = -1; + retVal = UA_Server_initNS0(server); + if(retVal != UA_STATUSCODE_GOOD) + goto cleanup; + + /* Build PubSub information model */ +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + UA_Server_initPubSubNS0(server); #endif - server->mdnsMainSrvAdded = UA_FALSE; - if(server->config.applicationDescription.applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER) - initMulticastDiscoveryServer(server); - LIST_INIT(&server->serverOnNetwork); - server->serverOnNetworkSize = 0; - server->serverOnNetworkRecordIdCounter = 0; - server->serverOnNetworkRecordIdLastReset = UA_DateTime_now(); - memset(server->serverOnNetworkHash, 0, - sizeof(struct serverOnNetwork_hash_entry*) * SERVER_ON_NETWORK_HASH_PRIME); + return server; - server->serverOnNetworkCallback = NULL; - server->serverOnNetworkCallbackData = NULL; -#endif + cleanup: + UA_Server_delete(server); + return NULL; +} - /* Initialize namespace 0*/ - UA_StatusCode retVal = UA_Server_initNS0(server); - if(retVal != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(config->logger, UA_LOGCATEGORY_SERVER, - "Initialization of Namespace 0 failed with %s. " - "See previous outputs for any error messages.", - UA_StatusCode_name(retVal)); - UA_Server_delete(server); +UA_Server * +UA_Server_new() { + /* Allocate the server */ + UA_Server *server = (UA_Server *)UA_calloc(1, sizeof(UA_Server)); + if(!server) return NULL; - } + return UA_Server_init(server); +} - return server; + +UA_Server * +UA_Server_newWithConfig(const UA_ServerConfig *config) { + UA_Server *server = (UA_Server *)UA_calloc(1, sizeof(UA_Server)); + if(!server) + return NULL; + if(config) + server->config = *config; + return UA_Server_init(server); } -/*****************/ -/* Repeated Jobs */ -/*****************/ +/* Returns if the server should be shut down immediately */ +static UA_Boolean +setServerShutdown(UA_Server *server) { + if(server->endTime != 0) + return false; + if(server->config.shutdownDelay == 0) + return true; + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Shutting down the server with a delay of %i ms", (int)server->config.shutdownDelay); + server->endTime = UA_DateTime_now() + (UA_DateTime)(server->config.shutdownDelay * UA_DATETIME_MSEC); + return false; +} + +/*******************/ +/* Timed Callbacks */ +/*******************/ + +UA_StatusCode +UA_Server_addTimedCallback(UA_Server *server, UA_ServerCallback callback, + void *data, UA_DateTime date, UA_UInt64 *callbackId) { + return UA_Timer_addTimedCallback(&server->timer, + (UA_ApplicationCallback)callback, + server, data, date, callbackId); +} UA_StatusCode UA_Server_addRepeatedCallback(UA_Server *server, UA_ServerCallback callback, - void *data, UA_UInt32 interval, + void *data, UA_Double interval_ms, UA_UInt64 *callbackId) { - return UA_Timer_addRepeatedCallback(&server->timer, (UA_TimerCallback)callback, - data, interval, callbackId); + return UA_Timer_addRepeatedCallback(&server->timer, + (UA_ApplicationCallback)callback, + server, data, interval_ms, callbackId); } UA_StatusCode UA_Server_changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId, - UA_UInt32 interval) { - return UA_Timer_changeRepeatedCallbackInterval(&server->timer, callbackId, interval); + UA_Double interval_ms) { + return UA_Timer_changeRepeatedCallbackInterval(&server->timer, callbackId, + interval_ms); +} + +void +UA_Server_removeCallback(UA_Server *server, UA_UInt64 callbackId) { + UA_Timer_removeCallback(&server->timer, callbackId); +} + +UA_StatusCode UA_EXPORT +UA_Server_updateCertificate(UA_Server *server, + const UA_ByteString *oldCertificate, + const UA_ByteString *newCertificate, + const UA_ByteString *newPrivateKey, + UA_Boolean closeSessions, + UA_Boolean closeSecureChannels) { + + if (server == NULL || oldCertificate == NULL + || newCertificate == NULL || newPrivateKey == NULL) { + return UA_STATUSCODE_BADINTERNALERROR; + } + + if (closeSessions) { + UA_SessionManager *sm = &server->sessionManager; + session_list_entry *current; + LIST_FOREACH(current, &sm->sessions, pointers) { + if (UA_ByteString_equal(oldCertificate, + ¤t->session.header.channel->securityPolicy->localCertificate)) { + UA_SessionManager_removeSession(sm, ¤t->session.header.authenticationToken); + } + } + + } + + if (closeSecureChannels) { + UA_SecureChannelManager *cm = &server->secureChannelManager; + channel_entry *entry; + TAILQ_FOREACH(entry, &cm->channels, pointers) { + if(UA_ByteString_equal(&entry->channel.securityPolicy->localCertificate, oldCertificate)){ + UA_SecureChannelManager_close(cm, entry->channel.securityToken.channelId); + } + } + } + + size_t i = 0; + while (i < server->config.endpointsSize) { + UA_EndpointDescription *ed = &server->config.endpoints[i]; + if (UA_ByteString_equal(&ed->serverCertificate, oldCertificate)) { + UA_String_deleteMembers(&ed->serverCertificate); + UA_String_copy(newCertificate, &ed->serverCertificate); + UA_SecurityPolicy *sp = UA_SecurityPolicy_getSecurityPolicyByUri(server, &server->config.endpoints[i].securityPolicyUri); + if(!sp) + return UA_STATUSCODE_BADINTERNALERROR; + sp->updateCertificateAndPrivateKey(sp, *newCertificate, *newPrivateKey); + } + i++; + } + + return UA_STATUSCODE_GOOD; +} + +/***************************/ +/* Server lookup functions */ +/***************************/ + +UA_SecurityPolicy * +UA_SecurityPolicy_getSecurityPolicyByUri(const UA_Server *server, + const UA_ByteString *securityPolicyUri) { + for(size_t i = 0; i < server->config.securityPoliciesSize; i++) { + UA_SecurityPolicy *securityPolicyCandidate = &server->config.securityPolicies[i]; + if(UA_ByteString_equal(securityPolicyUri, &securityPolicyCandidate->policyUri)) + return securityPolicyCandidate; + } + return NULL; +} + +#ifdef UA_ENABLE_ENCRYPTION +/* The local ApplicationURI has to match the certificates of the + * SecurityPolicies */ +static void +verifyServerApplicationURI(const UA_Server *server) { +#if UA_LOGLEVEL <= 400 + for(size_t i = 0; i < server->config.securityPoliciesSize; i++) { + UA_SecurityPolicy *sp = &server->config.securityPolicies[i]; + if(!sp->certificateVerification) + continue; + UA_StatusCode retval = + sp->certificateVerification-> + verifyApplicationURI(sp->certificateVerification->context, + &sp->localCertificate, + &server->config.applicationDescription.applicationUri); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "The configured ApplicationURI does not match the URI " + "specified in the certificate for the SecurityPolicy %.*s", + (int)sp->policyUri.length, sp->policyUri.data); + } + } +#endif +} +#endif + +/********************/ +/* Main Server Loop */ +/********************/ + +#define UA_MAXTIMEOUT 50 /* Max timeout in ms between main-loop iterations */ + +/* Start: Spin up the workers and the network layer and sample the server's + * start time. + * Iterate: Process repeated callbacks and events in the network layer. This + * part can be driven from an external main-loop in an event-driven + * single-threaded architecture. + * Stop: Stop workers, finish all callbacks, stop the network layer, clean up */ + +UA_StatusCode +UA_Server_run_startup(UA_Server *server) { + /* ensure that the uri for ns1 is set up from the app description */ + setupNs1Uri(server); + + /* write ServerArray with same ApplicationURI value as NamespaceArray */ + UA_StatusCode retVal = writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERARRAY, + &server->config.applicationDescription.applicationUri, + 1, &UA_TYPES[UA_TYPES_STRING]); + if(retVal != UA_STATUSCODE_GOOD) + return retVal; + + if(server->state > UA_SERVERLIFECYCLE_FRESH) + return UA_STATUSCODE_GOOD; + + /* At least one endpoint has to be configured */ + if(server->config.endpointsSize == 0) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "There has to be at least one endpoint."); + } + + /* Initialized discovery */ +#ifdef UA_ENABLE_DISCOVERY + UA_DiscoveryManager_init(&server->discoveryManager, server); +#endif + + /* Does the ApplicationURI match the local certificates? */ +#ifdef UA_ENABLE_ENCRYPTION + verifyServerApplicationURI(server); +#endif + + /* Sample the start time and set it to the Server object */ + server->startTime = UA_DateTime_now(); + UA_Variant var; + UA_Variant_init(&var); + UA_Variant_setScalar(&var, &server->startTime, &UA_TYPES[UA_TYPES_DATETIME]); + UA_Server_writeValue(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME), + var); + + /* Start the networklayers */ + UA_StatusCode result = UA_STATUSCODE_GOOD; + for(size_t i = 0; i < server->config.networkLayersSize; ++i) { + UA_ServerNetworkLayer *nl = &server->config.networkLayers[i]; + result |= nl->start(nl, &server->config.customHostname); + } + + /* Spin up the worker threads */ +#ifdef UA_ENABLE_MULTITHREADING + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Spinning up %u worker thread(s)", server->config.nThreads); + UA_WorkQueue_start(&server->workQueue, server->config.nThreads); +#endif + + /* Start the multicast discovery server */ +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + if(server->config.discovery.mdnsEnable) + startMulticastDiscoveryServer(server); +#endif + + server->state = UA_SERVERLIFECYCLE_FRESH; + + return result; +} + +static void +serverExecuteRepeatedCallback(UA_Server *server, UA_ApplicationCallback cb, + void *callbackApplication, void *data) { +#ifndef UA_ENABLE_MULTITHREADING + cb(callbackApplication, data); +#else + UA_WorkQueue_enqueue(&server->workQueue, cb, callbackApplication, data); +#endif +} + +UA_UInt16 +UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal) { + /* Process repeated work */ + UA_DateTime now = UA_DateTime_nowMonotonic(); + UA_DateTime nextRepeated = UA_Timer_process(&server->timer, now, + (UA_TimerExecutionCallback)serverExecuteRepeatedCallback, server); + UA_DateTime latest = now + (UA_MAXTIMEOUT * UA_DATETIME_MSEC); + if(nextRepeated > latest) + nextRepeated = latest; + + UA_UInt16 timeout = 0; + + /* round always to upper value to avoid timeout to be set to 0 + * if(nextRepeated - now) < (UA_DATETIME_MSEC/2) */ + if(waitInternal) + timeout = (UA_UInt16)(((nextRepeated - now) + (UA_DATETIME_MSEC - 1)) / UA_DATETIME_MSEC); + + /* Listen on the networklayer */ + for(size_t i = 0; i < server->config.networkLayersSize; ++i) { + UA_ServerNetworkLayer *nl = &server->config.networkLayers[i]; + nl->listen(nl, server, timeout); + } + +#if defined(UA_ENABLE_DISCOVERY_MULTICAST) && !defined(UA_ENABLE_MULTITHREADING) + if(server->config.discovery.mdnsEnable) { + // TODO multicastNextRepeat does not consider new input data (requests) + // on the socket. It will be handled on the next call. if needed, we + // need to use select with timeout on the multicast socket + // server->mdnsSocket (see example in mdnsd library) on higher level. + UA_DateTime multicastNextRepeat = 0; + UA_StatusCode hasNext = + iterateMulticastDiscoveryServer(server, &multicastNextRepeat, true); + if(hasNext == UA_STATUSCODE_GOOD && multicastNextRepeat < nextRepeated) + nextRepeated = multicastNextRepeat; + } +#endif + +#ifndef UA_ENABLE_MULTITHREADING + UA_WorkQueue_manuallyProcessDelayed(&server->workQueue); +#endif + + now = UA_DateTime_nowMonotonic(); + timeout = 0; + if(nextRepeated > now) + timeout = (UA_UInt16)((nextRepeated - now) / UA_DATETIME_MSEC); + return timeout; } UA_StatusCode -UA_Server_removeRepeatedCallback(UA_Server *server, UA_UInt64 callbackId) { - return UA_Timer_removeRepeatedCallback(&server->timer, callbackId); +UA_Server_run_shutdown(UA_Server *server) { + /* Stop the netowrk layer */ + for(size_t i = 0; i < server->config.networkLayersSize; ++i) { + UA_ServerNetworkLayer *nl = &server->config.networkLayers[i]; + nl->stop(nl, server); + } + +#ifdef UA_ENABLE_MULTITHREADING + /* Shut down the workers */ + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Shutting down %u worker thread(s)", + (UA_UInt32)server->workQueue.workersSize); + UA_WorkQueue_stop(&server->workQueue); +#endif + +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + /* Stop multicast discovery */ + if(server->config.discovery.mdnsEnable) + stopMulticastDiscoveryServer(server); +#endif + + /* Execute all delayed callbacks */ + UA_WorkQueue_cleanup(&server->workQueue); + + return UA_STATUSCODE_GOOD; } +static UA_Boolean +testShutdownCondition(UA_Server *server) { + if(server->endTime == 0) + return false; + return (UA_DateTime_now() > server->endTime); +} + +UA_StatusCode +UA_Server_run(UA_Server *server, const volatile UA_Boolean *running) { + UA_StatusCode retval = UA_Server_run_startup(server); + if(retval != UA_STATUSCODE_GOOD) + return retval; +#ifdef UA_ENABLE_VALGRIND_INTERACTIVE + size_t loopCount = 0; +#endif + while(!testShutdownCondition(server)) { +#ifdef UA_ENABLE_VALGRIND_INTERACTIVE + if(loopCount == 0) { + VALGRIND_DO_LEAK_CHECK; + } + ++loopCount; + loopCount %= UA_VALGRIND_INTERACTIVE_INTERVAL; +#endif + UA_Server_run_iterate(server, true); + if(!*running) { + if(setServerShutdown(server)) + break; + } + } + return UA_Server_run_shutdown(server); +} + +#ifdef UA_ENABLE_HISTORIZING +/* Allow insert of historical data */ +UA_Boolean +UA_Server_AccessControl_allowHistoryUpdateUpdateData(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, + UA_PerformUpdateType performInsertReplace, + const UA_DataValue *value) { + if(server->config.accessControl.allowHistoryUpdateUpdateData && + !server->config.accessControl.allowHistoryUpdateUpdateData(server, &server->config.accessControl, + sessionId, sessionContext, nodeId, + performInsertReplace, value)) { + return false; + } + return true; +} + +/* Allow delete of historical data */ +UA_Boolean +UA_Server_AccessControl_allowHistoryUpdateDeleteRawModified(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, + UA_DateTime startTimestamp, + UA_DateTime endTimestamp, + bool isDeleteModified) { + if(server->config.accessControl.allowHistoryUpdateDeleteRawModified && + !server->config.accessControl.allowHistoryUpdateDeleteRawModified(server, &server->config.accessControl, + sessionId, sessionContext, nodeId, + startTimestamp, endTimestamp, + isDeleteModified)) { + return false; + } + return true; + +} +#endif /* UA_ENABLE_HISTORIZING */ + /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_server_ns0.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Stefan Profanter, fortiss GmbH * Copyright 2017 (c) Thomas Bender * Copyright 2017 (c) Julian Grothoff * Copyright 2017 (c) Henrik Norrman + * Copyright 2018 (c) Fabian Arndt, Root-Core + * Copyright 2019 (c) Kalycito Infotech Private Limited */ -/*****************/ -/* Node Creation */ -/*****************/ static UA_StatusCode -addNode_begin(UA_Server *server, UA_NodeClass nodeClass, - UA_UInt32 nodeId, char *name, void *attributes, - const UA_DataType *attributesType) { +addNode_raw(UA_Server *server, UA_NodeClass nodeClass, + UA_UInt32 nodeId, char *name, void *attributes, + const UA_DataType *attributesType) { UA_AddNodesItem item; UA_AddNodesItem_init(&item); item.nodeClass = nodeClass; @@ -20248,47 +21874,19 @@ addNode_begin(UA_Server *server, UA_NodeClass nodeClass, item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE; item.nodeAttributes.content.decoded.data = attributes; item.nodeAttributes.content.decoded.type = attributesType; - UA_NodeId parentNode = UA_NODEID_NULL; - UA_NodeId referenceType = UA_NODEID_NULL; - return Operation_addNode_begin(server, &server->adminSession, NULL, &item, - &parentNode, &referenceType, NULL); + return AddNode_raw(server, &server->adminSession, NULL, &item, NULL); } static UA_StatusCode addNode_finish(UA_Server *server, UA_UInt32 nodeId, UA_UInt32 parentNodeId, UA_UInt32 referenceTypeId) { - UA_NodeId sourceId = UA_NODEID_NUMERIC(0, nodeId); - UA_NodeId refTypeId = UA_NODEID_NUMERIC(0, referenceTypeId); - UA_ExpandedNodeId targetId = UA_EXPANDEDNODEID_NUMERIC(0, parentNodeId); - UA_StatusCode retval = UA_Server_addReference(server, sourceId, refTypeId, targetId, UA_FALSE); + const UA_NodeId sourceId = UA_NODEID_NUMERIC(0, nodeId); + const UA_NodeId refTypeId = UA_NODEID_NUMERIC(0, referenceTypeId); + const UA_ExpandedNodeId targetId = UA_EXPANDEDNODEID_NUMERIC(0, parentNodeId); + UA_StatusCode retval = UA_Server_addReference(server, sourceId, refTypeId, targetId, false); if (retval != UA_STATUSCODE_GOOD) return retval; - - - UA_NodeId node = UA_NODEID_NUMERIC(0, nodeId); - return Operation_addNode_finish(server, &server->adminSession, &node); -} - -static UA_StatusCode -addDataTypeNode(UA_Server *server, char* name, UA_UInt32 datatypeid, - UA_Boolean isAbstract, UA_UInt32 parentid) { - UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; - attr.displayName = UA_LOCALIZEDTEXT("", name); - attr.isAbstract = isAbstract; - return UA_Server_addDataTypeNode(server, UA_NODEID_NUMERIC(0, datatypeid), - UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NULL, - UA_QUALIFIEDNAME(0, name), attr, NULL, NULL); -} - -static UA_StatusCode -addObjectTypeNode(UA_Server *server, char* name, UA_UInt32 objecttypeid, - UA_Boolean isAbstract, UA_UInt32 parentid) { - UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; - attr.displayName = UA_LOCALIZEDTEXT("", name); - attr.isAbstract = isAbstract; - return UA_Server_addObjectTypeNode(server, UA_NODEID_NUMERIC(0, objecttypeid), - UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NULL, - UA_QUALIFIEDNAME(0, name), attr, NULL, NULL); + return AddNode_finish(server, &server->adminSession, &sourceId); } static UA_StatusCode @@ -20297,11 +21895,11 @@ addObjectNode(UA_Server *server, char* name, UA_UInt32 objectid, UA_ObjectAttributes object_attr = UA_ObjectAttributes_default; object_attr.displayName = UA_LOCALIZEDTEXT("", name); return UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(0, objectid), - UA_NODEID_NUMERIC(0, parentid), - UA_NODEID_NUMERIC(0, referenceid), - UA_QUALIFIEDNAME(0, name), - UA_NODEID_NUMERIC(0, type_id), - object_attr, NULL, NULL); + UA_NODEID_NUMERIC(0, parentid), + UA_NODEID_NUMERIC(0, referenceid), + UA_QUALIFIEDNAME(0, name), + UA_NODEID_NUMERIC(0, type_id), + object_attr, NULL, NULL); } static UA_StatusCode @@ -20318,68 +21916,46 @@ addReferenceTypeNode(UA_Server *server, char* name, char *inverseName, UA_UInt32 UA_QUALIFIEDNAME(0, name), reference_attr, NULL, NULL); } -static UA_StatusCode -addVariableTypeNode(UA_Server *server, char* name, UA_UInt32 variabletypeid, - UA_Boolean isAbstract, UA_Int32 valueRank, UA_UInt32 dataType, - const UA_DataType *type, UA_UInt32 parentid) { - UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; - attr.displayName = UA_LOCALIZEDTEXT("", name); - attr.dataType = UA_NODEID_NUMERIC(0, dataType); - attr.isAbstract = isAbstract; - attr.valueRank = valueRank; - - if(type) { - UA_STACKARRAY(UA_Byte, tempVal, type->memSize); - UA_init(tempVal, type); - UA_Variant_setScalar(&attr.value, tempVal, type); - return UA_Server_addVariableTypeNode(server, UA_NODEID_NUMERIC(0, variabletypeid), - UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NULL, - UA_QUALIFIEDNAME(0, name), UA_NODEID_NULL, attr, NULL, NULL); - } - return UA_Server_addVariableTypeNode(server, UA_NODEID_NUMERIC(0, variabletypeid), - UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NULL, - UA_QUALIFIEDNAME(0, name), UA_NODEID_NULL, attr, NULL, NULL); -} - -/**********************/ -/* Create Namespace 0 */ -/**********************/ +/***************************/ +/* Bootstrap NS0 hierarchy */ +/***************************/ /* Creates the basic nodes which are expected by the nodeset compiler to be * already created. This is necessary to reduce the dependencies for the nodeset * compiler. */ static UA_StatusCode UA_Server_createNS0_base(UA_Server *server) { - - UA_StatusCode ret = UA_STATUSCODE_GOOD; - /*********************************/ - /* Bootstrap reference hierarchy */ - /*********************************/ - /* Bootstrap References and HasSubtype */ + UA_StatusCode ret = UA_STATUSCODE_GOOD; UA_ReferenceTypeAttributes references_attr = UA_ReferenceTypeAttributes_default; references_attr.displayName = UA_LOCALIZEDTEXT("", "References"); references_attr.isAbstract = true; references_attr.symmetric = true; references_attr.inverseName = UA_LOCALIZEDTEXT("", "References"); - ret |= addNode_begin(server, UA_NODECLASS_REFERENCETYPE, UA_NS0ID_REFERENCES, "References", - &references_attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); + ret |= addNode_raw(server, UA_NODECLASS_REFERENCETYPE, UA_NS0ID_REFERENCES, "References", + &references_attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); UA_ReferenceTypeAttributes hassubtype_attr = UA_ReferenceTypeAttributes_default; hassubtype_attr.displayName = UA_LOCALIZEDTEXT("", "HasSubtype"); hassubtype_attr.isAbstract = false; hassubtype_attr.symmetric = false; hassubtype_attr.inverseName = UA_LOCALIZEDTEXT("", "HasSupertype"); - ret |= addNode_begin(server, UA_NODECLASS_REFERENCETYPE, UA_NS0ID_HASSUBTYPE, "HasSubtype", - &hassubtype_attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); + ret |= addNode_raw(server, UA_NODECLASS_REFERENCETYPE, UA_NS0ID_HASSUBTYPE, "HasSubtype", + &hassubtype_attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); + + UA_ReferenceTypeAttributes aggregates_attr = UA_ReferenceTypeAttributes_default; + aggregates_attr.displayName = UA_LOCALIZEDTEXT("", "Aggregates"); + aggregates_attr.isAbstract = false; + aggregates_attr.symmetric = false; + aggregates_attr.inverseName = UA_LOCALIZEDTEXT("", "AggregatedBy"); + ret |= addNode_raw(server, UA_NODECLASS_REFERENCETYPE, UA_NS0ID_AGGREGATES, "Aggregates", + &aggregates_attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES]); ret |= addReferenceTypeNode(server, "HierarchicalReferences", NULL, - UA_NS0ID_HIERARCHICALREFERENCES, - true, false, UA_NS0ID_REFERENCES); + UA_NS0ID_HIERARCHICALREFERENCES, true, false, UA_NS0ID_REFERENCES); ret |= addReferenceTypeNode(server, "NonHierarchicalReferences", NULL, - UA_NS0ID_NONHIERARCHICALREFERENCES, - true, false, UA_NS0ID_REFERENCES); + UA_NS0ID_NONHIERARCHICALREFERENCES, true, false, UA_NS0ID_REFERENCES); ret |= addReferenceTypeNode(server, "HasChild", NULL, UA_NS0ID_HASCHILD, true, false, UA_NS0ID_HIERARCHICALREFERENCES); @@ -20405,8 +21981,8 @@ UA_Server_createNS0_base(UA_Server *server) { ret |= addReferenceTypeNode(server, "GeneratesEvent", "GeneratedBy", UA_NS0ID_GENERATESEVENT, false, false, UA_NS0ID_NONHIERARCHICALREFERENCES); - ret |= addReferenceTypeNode(server, "Aggregates", "AggregatedBy", UA_NS0ID_AGGREGATES, - false, false, UA_NS0ID_HASCHILD); + /* Complete bootstrap of Aggregates */ + ret |= addNode_finish(server, UA_NS0ID_AGGREGATES, UA_NS0ID_HASCHILD, UA_NS0ID_HASSUBTYPE); /* Complete bootstrap of HasSubtype */ ret |= addNode_finish(server, UA_NS0ID_HASSUBTYPE, UA_NS0ID_HASCHILD, UA_NS0ID_HASSUBTYPE); @@ -20431,68 +22007,54 @@ UA_Server_createNS0_base(UA_Server *server) { UA_DataTypeAttributes basedatatype_attr = UA_DataTypeAttributes_default; basedatatype_attr.displayName = UA_LOCALIZEDTEXT("", "BaseDataType"); basedatatype_attr.isAbstract = true; - ret |= addNode_begin(server, UA_NODECLASS_DATATYPE, UA_NS0ID_BASEDATATYPE, "BaseDataType", - &basedatatype_attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]); - - ret |= addDataTypeNode(server, "Number", UA_NS0ID_NUMBER, true, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "Integer", UA_NS0ID_INTEGER, true, UA_NS0ID_NUMBER); - ret |= addDataTypeNode(server, "UInteger", UA_NS0ID_UINTEGER, true, UA_NS0ID_NUMBER); - ret |= addDataTypeNode(server, "Boolean", UA_NS0ID_BOOLEAN, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "SByte", UA_NS0ID_SBYTE, false, UA_NS0ID_INTEGER); - ret |= addDataTypeNode(server, "Byte", UA_NS0ID_BYTE, false, UA_NS0ID_UINTEGER); - ret |= addDataTypeNode(server, "Int16", UA_NS0ID_INT16, false, UA_NS0ID_INTEGER); - ret |= addDataTypeNode(server, "UInt16", UA_NS0ID_UINT16, false, UA_NS0ID_UINTEGER); - ret |= addDataTypeNode(server, "Int32", UA_NS0ID_INT32, false, UA_NS0ID_INTEGER); - ret |= addDataTypeNode(server, "UInt32", UA_NS0ID_UINT32, false, UA_NS0ID_UINTEGER); - ret |= addDataTypeNode(server, "Int64", UA_NS0ID_INT64, false, UA_NS0ID_INTEGER); - ret |= addDataTypeNode(server, "UInt64", UA_NS0ID_UINT64, false, UA_NS0ID_UINTEGER); - ret |= addDataTypeNode(server, "Float", UA_NS0ID_FLOAT, false, UA_NS0ID_NUMBER); - ret |= addDataTypeNode(server, "Double", UA_NS0ID_DOUBLE, false, UA_NS0ID_NUMBER); - ret |= addDataTypeNode(server, "DateTime", UA_NS0ID_DATETIME, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "String", UA_NS0ID_STRING, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "ByteString", UA_NS0ID_BYTESTRING, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "Guid", UA_NS0ID_GUID, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "XmlElement", UA_NS0ID_XMLELEMENT, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "NodeId", UA_NS0ID_NODEID, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "ExpandedNodeId", UA_NS0ID_EXPANDEDNODEID, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "QualifiedName", UA_NS0ID_QUALIFIEDNAME, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "LocalizedText", UA_NS0ID_LOCALIZEDTEXT, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "StatusCode", UA_NS0ID_STATUSCODE, false, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "Structure", UA_NS0ID_STRUCTURE, true, UA_NS0ID_BASEDATATYPE); - ret |= addDataTypeNode(server, "Decimal128", UA_NS0ID_DECIMAL128, false, UA_NS0ID_NUMBER); - - ret |= addDataTypeNode(server, "Duration", UA_NS0ID_DURATION, false, UA_NS0ID_DOUBLE); - ret |= addDataTypeNode(server, "UtcTime", UA_NS0ID_UTCTIME, false, UA_NS0ID_DATETIME); - ret |= addDataTypeNode(server, "LocaleId", UA_NS0ID_LOCALEID, false, UA_NS0ID_STRING); + ret |= addNode_raw(server, UA_NODECLASS_DATATYPE, UA_NS0ID_BASEDATATYPE, "BaseDataType", + &basedatatype_attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES]); /*****************/ /* VariableTypes */ /*****************/ - /* Bootstrap BaseVariableType */ UA_VariableTypeAttributes basevar_attr = UA_VariableTypeAttributes_default; basevar_attr.displayName = UA_LOCALIZEDTEXT("", "BaseVariableType"); basevar_attr.isAbstract = true; basevar_attr.valueRank = UA_VALUERANK_ANY; basevar_attr.dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE); - ret |= addNode_begin(server, UA_NODECLASS_VARIABLETYPE, UA_NS0ID_BASEVARIABLETYPE, "BaseVariableType", - &basevar_attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]); - - ret |= addVariableTypeNode(server, "BaseDataVariableType", UA_NS0ID_BASEDATAVARIABLETYPE, - false, -2, UA_NS0ID_BASEDATATYPE, NULL, UA_NS0ID_BASEVARIABLETYPE); + ret |= addNode_raw(server, UA_NODECLASS_VARIABLETYPE, UA_NS0ID_BASEVARIABLETYPE, "BaseVariableType", + &basevar_attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES]); + + UA_VariableTypeAttributes bdv_attr = UA_VariableTypeAttributes_default; + bdv_attr.displayName = UA_LOCALIZEDTEXT("", "BaseDataVariableType"); + bdv_attr.dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE); + bdv_attr.valueRank = UA_VALUERANK_ANY; + ret |= UA_Server_addVariableTypeNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), + UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE), + UA_NODEID_NULL, UA_QUALIFIEDNAME(0, "BaseDataVariableType"), + UA_NODEID_NULL, bdv_attr, NULL, NULL); + + UA_VariableTypeAttributes prop_attr = UA_VariableTypeAttributes_default; + prop_attr.displayName = UA_LOCALIZEDTEXT("", "PropertyType"); + prop_attr.dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE); + prop_attr.valueRank = UA_VALUERANK_ANY; + ret |= UA_Server_addVariableTypeNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PROPERTYTYPE), + UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE), + UA_NODEID_NULL, UA_QUALIFIEDNAME(0, "PropertyType"), + UA_NODEID_NULL, prop_attr, NULL, NULL); /***************/ /* ObjectTypes */ /***************/ - /* Bootstrap BaseObjectType */ UA_ObjectTypeAttributes baseobj_attr = UA_ObjectTypeAttributes_default; baseobj_attr.displayName = UA_LOCALIZEDTEXT("", "BaseObjectType"); - ret |= addNode_begin(server, UA_NODECLASS_OBJECTTYPE, UA_NS0ID_BASEOBJECTTYPE, "BaseObjectType", - &baseobj_attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]); + ret |= addNode_raw(server, UA_NODECLASS_OBJECTTYPE, UA_NS0ID_BASEOBJECTTYPE, "BaseObjectType", + &baseobj_attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES]); - ret |= addObjectTypeNode(server, "FolderType", UA_NS0ID_FOLDERTYPE, - false, UA_NS0ID_BASEOBJECTTYPE); + UA_ObjectTypeAttributes folder_attr = UA_ObjectTypeAttributes_default; + folder_attr.displayName = UA_LOCALIZEDTEXT("", "FolderType"); + ret |= UA_Server_addObjectTypeNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_FOLDERTYPE), + UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE), + UA_NODEID_NULL, UA_QUALIFIEDNAME(0, "FolderType"), + folder_attr, NULL, NULL); /******************/ /* Root and below */ @@ -20513,13 +22075,11 @@ UA_Server_createNS0_base(UA_Server *server) { ret |= addObjectNode(server, "DataTypes", UA_NS0ID_DATATYPESFOLDER, UA_NS0ID_TYPESFOLDER, UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE); - ret |= addNode_finish(server, UA_NS0ID_BASEDATATYPE, UA_NS0ID_DATATYPESFOLDER, UA_NS0ID_ORGANIZES); ret |= addObjectNode(server, "VariableTypes", UA_NS0ID_VARIABLETYPESFOLDER, UA_NS0ID_TYPESFOLDER, UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE); - ret |= addNode_finish(server, UA_NS0ID_BASEVARIABLETYPE, UA_NS0ID_VARIABLETYPESFOLDER, UA_NS0ID_ORGANIZES); @@ -20535,8 +22095,9 @@ UA_Server_createNS0_base(UA_Server *server) { UA_NS0ID_ORGANIZES, UA_NS0ID_FOLDERTYPE); if(ret != UA_STATUSCODE_GOOD) - return UA_STATUSCODE_BADINTERNALERROR; - return UA_STATUSCODE_GOOD; + ret = UA_STATUSCODE_BADINTERNALERROR; + + return ret; } /****************/ @@ -20553,26 +22114,112 @@ readStatus(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, return UA_STATUSCODE_GOOD; } - UA_ServerStatusDataType *statustype = UA_ServerStatusDataType_new(); - statustype->startTime = server->startTime; - statustype->currentTime = UA_DateTime_now(); - statustype->state = UA_SERVERSTATE_RUNNING; - statustype->secondsTillShutdown = 0; - UA_BuildInfo_copy(&server->config.buildInfo, &statustype->buildInfo); - - value->value.type = &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]; - value->value.arrayLength = 0; - value->value.data = statustype; - value->value.arrayDimensionsSize = 0; - value->value.arrayDimensions = NULL; - value->hasValue = true; if(sourceTimestamp) { value->hasSourceTimestamp = true; value->sourceTimestamp = UA_DateTime_now(); } - return UA_STATUSCODE_GOOD; + + void *data = NULL; + + UA_assert(nodeId->identifierType == UA_NODEIDTYPE_NUMERIC); + + switch(nodeId->identifier.numeric) { + case UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN: { + UA_UInt32 *shutdown = UA_UInt32_new(); + if(!shutdown) + return UA_STATUSCODE_BADOUTOFMEMORY; + if(server->endTime != 0) + *shutdown = (UA_UInt32)((server->endTime - UA_DateTime_now()) / UA_DATETIME_SEC); + value->value.data = shutdown; + value->value.type = &UA_TYPES[UA_TYPES_UINT32]; + value->hasValue = true; + return UA_STATUSCODE_GOOD; + } + + case UA_NS0ID_SERVER_SERVERSTATUS_STATE: { + UA_ServerState *state = UA_ServerState_new(); + if(!state) + return UA_STATUSCODE_BADOUTOFMEMORY; + if(server->endTime != 0) + *state = UA_SERVERSTATE_SHUTDOWN; + value->value.data = state; + value->value.type = &UA_TYPES[UA_TYPES_SERVERSTATE]; + value->hasValue = true; + return UA_STATUSCODE_GOOD; + } + + case UA_NS0ID_SERVER_SERVERSTATUS: { + UA_ServerStatusDataType *statustype = UA_ServerStatusDataType_new(); + if(!statustype) + return UA_STATUSCODE_BADOUTOFMEMORY; + statustype->startTime = server->startTime; + statustype->currentTime = UA_DateTime_now(); + + statustype->state = UA_SERVERSTATE_RUNNING; + statustype->secondsTillShutdown = 0; + if(server->endTime != 0) { + statustype->state = UA_SERVERSTATE_SHUTDOWN; + statustype->secondsTillShutdown = (UA_UInt32)((server->endTime - UA_DateTime_now()) / UA_DATETIME_SEC); + } + + value->value.data = statustype; + value->value.type = &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]; + value->hasValue = true; + return UA_BuildInfo_copy(&server->config.buildInfo, &statustype->buildInfo); + } + + case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO: + value->value.type = &UA_TYPES[UA_TYPES_BUILDINFO]; + data = &server->config.buildInfo; + break; + + case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI: + value->value.type = &UA_TYPES[UA_TYPES_STRING]; + data = &server->config.buildInfo.productUri; + break; + + case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME: + value->value.type = &UA_TYPES[UA_TYPES_STRING]; + data = &server->config.buildInfo.manufacturerName; + break; + + case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME: + value->value.type = &UA_TYPES[UA_TYPES_STRING]; + data = &server->config.buildInfo.productName; + break; + + case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION: + value->value.type = &UA_TYPES[UA_TYPES_STRING]; + data = &server->config.buildInfo.softwareVersion; + break; + + case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER: + value->value.type = &UA_TYPES[UA_TYPES_STRING]; + data = &server->config.buildInfo.buildNumber; + break; + + case UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE: + value->value.type = &UA_TYPES[UA_TYPES_DATETIME]; + data = &server->config.buildInfo.buildDate; + break; + + default: + value->hasStatus = true; + value->status = UA_STATUSCODE_BADINTERNALERROR; + return UA_STATUSCODE_GOOD; + } + + value->value.data = UA_new(value->value.type); + if(!value->value.data) { + value->value.type = NULL; + return UA_STATUSCODE_BADOUTOFMEMORY; + } + + value->hasValue = true; + return UA_copy(data, value->value.data, value->value.type); } +#ifdef UA_GENERATED_NAMESPACE_ZERO static UA_StatusCode readServiceLevel(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp, @@ -20622,12 +22269,16 @@ readAuditing(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext } return UA_STATUSCODE_GOOD; } +#endif static UA_StatusCode readNamespaces(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeid, void *nodeContext, UA_Boolean includeSourceTimeStamp, const UA_NumericRange *range, UA_DataValue *value) { + /* ensure that the uri for ns1 is set up from the app description */ + setupNs1Uri(server); + if(range) { value->hasStatus = true; value->status = UA_STATUSCODE_BADINDEXRANGEINVALID; @@ -20670,6 +22321,9 @@ writeNamespaces(UA_Server *server, const UA_NodeId *sessionId, void *sessionCont if(newNamespacesSize <= server->namespacesSize) return UA_STATUSCODE_BADTYPEMISMATCH; + /* ensure that the uri for ns1 is set up from the app description */ + setupNs1Uri(server); + /* Test if the existing namespaces are unchanged */ for(size_t i = 0; i < server->namespacesSize; ++i) { if(!UA_String_equal(&server->namespaces[i], &newNamespaces[i])) @@ -20704,7 +22358,34 @@ readCurrentTime(UA_Server *server, const UA_NodeId *sessionId, void *sessionCont return UA_STATUSCODE_GOOD; } -#if defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS) +#ifdef UA_GENERATED_NAMESPACE_ZERO +static UA_StatusCode +readMinSamplingInterval(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeid, void *nodeContext, UA_Boolean includeSourceTimeStamp, + const UA_NumericRange *range, + UA_DataValue *value) { + if(range) { + value->hasStatus = true; + value->status = UA_STATUSCODE_BADINDEXRANGEINVALID; + return UA_STATUSCODE_GOOD; + } + + UA_StatusCode retval; + retval = UA_Variant_setScalarCopy(&value->value, + &server->config.samplingIntervalLimits.min, + &UA_TYPES[UA_TYPES_DURATION]); + if(retval != UA_STATUSCODE_GOOD) + return retval; + value->hasValue = true; + if(includeSourceTimeStamp) { + value->hasSourceTimestamp = true; + value->sourceTimestamp = UA_DateTime_now(); + } + return UA_STATUSCODE_GOOD; +} +#endif + +#if defined(UA_GENERATED_NAMESPACE_ZERO) && defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS) static UA_StatusCode readMonitoredItems(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *methodId, void *methodContext, const UA_NodeId *objectId, @@ -20723,14 +22404,14 @@ readMonitoredItems(UA_Server *server, const UA_NodeId *sessionId, void *sessionC if(LIST_EMPTY(&session->serverSubscriptions)) { UA_Variant_setArray(&output[0], UA_Array_new(0, &UA_TYPES[UA_TYPES_UINT32]), - 0, &UA_TYPES[UA_TYPES_UINT32]); + 0, &UA_TYPES[UA_TYPES_UINT32]); UA_Variant_setArray(&output[1], UA_Array_new(0, &UA_TYPES[UA_TYPES_UINT32]), - 0, &UA_TYPES[UA_TYPES_UINT32]); + 0, &UA_TYPES[UA_TYPES_UINT32]); return UA_STATUSCODE_BADNOMATCH; } - else - return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID; + + return UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID; } UA_UInt32 sizeOfOutput = 0; @@ -20755,23 +22436,155 @@ readMonitoredItems(UA_Server *server, const UA_NodeId *sessionId, void *sessionC } #endif /* defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS) */ -static UA_StatusCode -writeNs0Variable(UA_Server *server, UA_UInt32 id, void *v, const UA_DataType *type) { +UA_StatusCode +writeNs0VariableArray(UA_Server *server, UA_UInt32 id, void *v, + size_t length, const UA_DataType *type) { UA_Variant var; UA_Variant_init(&var); - UA_Variant_setScalar(&var, v, type); + UA_Variant_setArray(&var, v, length, type); return UA_Server_writeValue(server, UA_NODEID_NUMERIC(0, id), var); } +#ifndef UA_GENERATED_NAMESPACE_ZERO static UA_StatusCode -writeNs0VariableArray(UA_Server *server, UA_UInt32 id, void *v, - size_t length, const UA_DataType *type) { +addVariableNode(UA_Server *server, char* name, UA_UInt32 variableid, + UA_UInt32 parentid, UA_UInt32 referenceid, + UA_Int32 valueRank, UA_UInt32 dataType) { + UA_VariableAttributes attr = UA_VariableAttributes_default; + attr.displayName = UA_LOCALIZEDTEXT("", name); + attr.dataType = UA_NODEID_NUMERIC(0, dataType); + attr.valueRank = valueRank; + attr.accessLevel = UA_ACCESSLEVELMASK_READ; + return UA_Server_addVariableNode(server, UA_NODEID_NUMERIC(0, variableid), + UA_NODEID_NUMERIC(0, parentid), UA_NODEID_NUMERIC(0, referenceid), + UA_QUALIFIEDNAME(0, name), + UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), + attr, NULL, NULL); +} + +/* A minimal server object that is not complete and does not use the mandated + * references to a server type. To be used on very constrained devices. */ +static UA_StatusCode +UA_Server_minimalServerObject(UA_Server *server) { + /* Server */ + UA_StatusCode retval = addObjectNode(server, "Server", UA_NS0ID_SERVER, UA_NS0ID_OBJECTSFOLDER, + UA_NS0ID_ORGANIZES, UA_NS0ID_BASEOBJECTTYPE); + + /* Use a valuerank of -2 for now. The array is added later on and the valuerank set to 1. */ + retval |= addVariableNode(server, "ServerArray", UA_NS0ID_SERVER_SERVERARRAY, + UA_NS0ID_SERVER, UA_NS0ID_HASPROPERTY, + UA_VALUERANK_ANY, UA_NS0ID_BASEDATATYPE); + retval |= addVariableNode(server, "NamespaceArray", UA_NS0ID_SERVER_NAMESPACEARRAY, + UA_NS0ID_SERVER, UA_NS0ID_HASPROPERTY, + UA_VALUERANK_ANY, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "ServerStatus", UA_NS0ID_SERVER_SERVERSTATUS, + UA_NS0ID_SERVER, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "CurrentTime", UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME, + UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "State", UA_NS0ID_SERVER_SERVERSTATUS_STATE, + UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "BuildInfo", UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, + UA_NS0ID_SERVER_SERVERSTATUS, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "ProductUri", UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI, + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "ManufacturerName", + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME, + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "ProductName", + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME, + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "SoftwareVersion", + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION, + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "BuildNumber", + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER, + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + retval |= addVariableNode(server, "BuildDate", + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE, + UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, UA_NS0ID_HASCOMPONENT, + UA_VALUERANK_SCALAR, UA_NS0ID_BASEDATATYPE); + + return retval; +} + +#else + +static UA_StatusCode +writeNs0Variable(UA_Server *server, UA_UInt32 id, void *v, const UA_DataType *type) { UA_Variant var; UA_Variant_init(&var); - UA_Variant_setArray(&var, v, length, type); + UA_Variant_setScalar(&var, v, type); return UA_Server_writeValue(server, UA_NODEID_NUMERIC(0, id), var); } +static void +addModellingRules(UA_Server *server) { + /* Test if the ModellingRules folder was added. (Only for the full ns0.) */ + UA_NodeClass mrnc = UA_NODECLASS_UNSPECIFIED; + UA_StatusCode retval = UA_Server_readNodeClass(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES), + &mrnc); + if(retval != UA_STATUSCODE_GOOD) + return; + + /* Add ExposesItsArray */ + UA_Server_addReference(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_EXPOSESITSARRAY), + true); + + /* Add Mandatory */ + UA_Server_addReference(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORY), + true); + + + /* Add MandatoryPlaceholder */ + UA_Server_addReference(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_MANDATORYPLACEHOLDER), + true); + + /* Add Optional */ + UA_Server_addReference(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_OPTIONAL), + true); + + /* Add OptionalPlaceholder */ + UA_Server_addReference(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MODELLINGRULES), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_MODELLINGRULE_OPTIONALPLACEHOLDER), + true); +} + +#endif + /* Initialize the nodeset 0 by using the generated code of the nodeset compiler. * This also initialized the data sources for various variables, such as for * example server time. */ @@ -20786,80 +22599,34 @@ UA_Server_initNS0(UA_Server *server) { if(retVal != UA_STATUSCODE_GOOD) return retVal; +#ifdef UA_GENERATED_NAMESPACE_ZERO /* Load nodes and references generated from the XML ns0 definition */ - server->bootstrapNS0 = true; - retVal = ua_namespace0(server); - server->bootstrapNS0 = false; - if(retVal != UA_STATUSCODE_GOOD) - return retVal; + retVal = namespace0_generated(server); +#else + /* Create a minimal server object */ + retVal = UA_Server_minimalServerObject(server); +#endif + + if(retVal != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Initialization of Namespace 0 (before bootstrapping) " + "failed with %s. See previous outputs for any error messages.", + UA_StatusCode_name(retVal)); + return UA_STATUSCODE_BADINTERNALERROR; + } /* NamespaceArray */ - UA_DataSource namespaceDataSource = {readNamespaces, NULL}; + UA_DataSource namespaceDataSource = {readNamespaces, writeNamespaces}; retVal |= UA_Server_setVariableNode_dataSource(server, - UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_NAMESPACEARRAY), + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_NAMESPACEARRAY), namespaceDataSource); + retVal |= UA_Server_writeValueRank(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_NAMESPACEARRAY), 1); /* ServerArray */ retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERARRAY, &server->config.applicationDescription.applicationUri, 1, &UA_TYPES[UA_TYPES_STRING]); - - /* LocaleIdArray */ - UA_LocaleId locale_en = UA_STRING("en"); - retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_LOCALEIDARRAY, - &locale_en, 1, &UA_TYPES[UA_TYPES_LOCALEID]); - - /* MaxBrowseContinuationPoints */ - UA_UInt16 maxBrowseContinuationPoints = UA_MAXCONTINUATIONPOINTS; - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXBROWSECONTINUATIONPOINTS, - &maxBrowseContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]); - - /* ServerProfileArray */ - UA_String profileArray[4]; - UA_UInt16 profileArraySize = 0; -#define ADDPROFILEARRAY(x) profileArray[profileArraySize++] = UA_STRING_ALLOC(x) - ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/NanoEmbeddedDevice"); -#ifdef UA_ENABLE_NODEMANAGEMENT - ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/NodeManagement"); -#endif -#ifdef UA_ENABLE_METHODCALLS - ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/Methods"); -#endif -#ifdef UA_ENABLE_SUBSCRIPTIONS - ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/EmbeddedDataChangeSubscription"); -#endif - - retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_SERVERPROFILEARRAY, - profileArray, profileArraySize, &UA_TYPES[UA_TYPES_STRING]); - for(int i=0; i<profileArraySize; i++) { - UA_String_deleteMembers(&profileArray[i]); - } - - /* MaxQueryContinuationPoints */ - UA_UInt16 maxQueryContinuationPoints = 0; - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXQUERYCONTINUATIONPOINTS, - &maxQueryContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]); - - /* MaxHistoryContinuationPoints */ - UA_UInt16 maxHistoryContinuationPoints = 0; - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXHISTORYCONTINUATIONPOINTS, - &maxHistoryContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]); - - /* MinSupportedSampleRate */ - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MINSUPPORTEDSAMPLERATE, - &server->config.samplingIntervalLimits.min, &UA_TYPES[UA_TYPES_DURATION]); - - /* ServerDiagnostics - ServerDiagnosticsSummary */ - UA_ServerDiagnosticsSummaryDataType serverDiagnosticsSummary; - UA_ServerDiagnosticsSummaryDataType_init(&serverDiagnosticsSummary); - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY, - &serverDiagnosticsSummary, - &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); - - /* ServerDiagnostics - EnabledFlag */ - UA_Boolean enabledFlag = false; - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_ENABLEDFLAG, - &enabledFlag, &UA_TYPES[UA_TYPES_BOOLEAN]); + retVal |= UA_Server_writeValueRank(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERARRAY), 1); /* ServerStatus */ UA_DataSource serverStatus = {readStatus, NULL}; @@ -20871,45 +22638,53 @@ UA_Server_initNS0(UA_Server *server) { /* CurrentTime */ UA_DataSource currentTime = {readCurrentTime, NULL}; retVal |= UA_Server_setVariableNode_dataSource(server, - UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME), currentTime); + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME), currentTime); /* State */ - UA_ServerState state = UA_SERVERSTATE_RUNNING; - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_STATE, - &state, &UA_TYPES[UA_TYPES_SERVERSTATE]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE), + serverStatus); /* BuildInfo */ - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO, - &server->config.buildInfo, &UA_TYPES[UA_TYPES_BUILDINFO]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO), serverStatus); /* BuildInfo - ProductUri */ - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI, - &server->config.buildInfo.productUri, &UA_TYPES[UA_TYPES_STRING]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTURI), + serverStatus); /* BuildInfo - ManufacturerName */ - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME, - &server->config.buildInfo.manufacturerName, &UA_TYPES[UA_TYPES_STRING]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_MANUFACTURERNAME), + serverStatus); /* BuildInfo - ProductName */ - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME, - &server->config.buildInfo.productName, &UA_TYPES[UA_TYPES_STRING]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_PRODUCTNAME), + serverStatus); /* BuildInfo - SoftwareVersion */ - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION, - &server->config.buildInfo.softwareVersion, &UA_TYPES[UA_TYPES_STRING]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_SOFTWAREVERSION), + serverStatus); /* BuildInfo - BuildNumber */ - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER, - &server->config.buildInfo.buildNumber, &UA_TYPES[UA_TYPES_STRING]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDNUMBER), + serverStatus); /* BuildInfo - BuildDate */ - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE, - &server->config.buildInfo.buildDate, &UA_TYPES[UA_TYPES_DATETIME]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_BUILDINFO_BUILDDATE), + serverStatus); + +#ifdef UA_GENERATED_NAMESPACE_ZERO /* SecondsTillShutdown */ - UA_UInt32 secondsTillShutdown = 0; - retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN, - &secondsTillShutdown, &UA_TYPES[UA_TYPES_UINT32]); + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_SECONDSTILLSHUTDOWN), + serverStatus); /* ShutDownReason */ UA_LocalizedText shutdownReason; @@ -20922,21 +22697,82 @@ UA_Server_initNS0(UA_Server *server) { retVal |= UA_Server_setVariableNode_dataSource(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVICELEVEL), serviceLevel); + /* ServerDiagnostics - ServerDiagnosticsSummary */ + UA_ServerDiagnosticsSummaryDataType serverDiagnosticsSummary; + UA_ServerDiagnosticsSummaryDataType_init(&serverDiagnosticsSummary); + retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY, + &serverDiagnosticsSummary, + &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); + + /* ServerDiagnostics - EnabledFlag */ + UA_Boolean enabledFlag = false; + retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_ENABLEDFLAG, + &enabledFlag, &UA_TYPES[UA_TYPES_BOOLEAN]); + + /* According to Specification part-5 - pg.no-11(PDF pg.no-29), when the ServerDiagnostics is disabled the client + * may modify the value of enabledFlag=true in the server. By default, this node have CurrentRead/Write access. + * In CTT, Subscription_Minimum_1/002.js test will modify the above flag. This will not be a problem when build + * configuration is set at UA_NAMESPACE_ZERO="REDUCED" as NodeIds will not be present. When UA_NAMESPACE_ZERO="FULL", + * the test will fail. Hence made the NodeId as read only */ + retVal |= UA_Server_writeAccessLevel(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_ENABLEDFLAG), + UA_ACCESSLEVELMASK_READ); + /* Auditing */ UA_DataSource auditing = {readAuditing, NULL}; retVal |= UA_Server_setVariableNode_dataSource(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_AUDITING), auditing); - /* NamespaceArray */ - UA_DataSource nsarray_datasource = {readNamespaces, writeNamespaces}; - retVal |= UA_Server_setVariableNode_dataSource(server, - UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_NAMESPACEARRAY), nsarray_datasource); - /* Redundancy Support */ UA_RedundancySupport redundancySupport = UA_REDUNDANCYSUPPORT_NONE; retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERREDUNDANCY_REDUNDANCYSUPPORT, &redundancySupport, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); + /* Remove unused subtypes of ServerRedundancy */ + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERREDUNDANCY_CURRENTSERVERID), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERREDUNDANCY_REDUNDANTSERVERARRAY), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERREDUNDANCY_SERVERURIARRAY), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERREDUNDANCY_SERVERNETWORKGROUPS), true); + + /* ServerCapabilities - LocaleIdArray */ + UA_LocaleId locale_en = UA_STRING("en"); + retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_LOCALEIDARRAY, + &locale_en, 1, &UA_TYPES[UA_TYPES_LOCALEID]); + + /* ServerCapabilities - MaxBrowseContinuationPoints */ + UA_UInt16 maxBrowseContinuationPoints = UA_MAXCONTINUATIONPOINTS; + retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXBROWSECONTINUATIONPOINTS, + &maxBrowseContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]); + + /* ServerProfileArray */ + UA_String profileArray[3]; + UA_UInt16 profileArraySize = 0; +#define ADDPROFILEARRAY(x) profileArray[profileArraySize++] = UA_STRING(x) + ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/MicroEmbeddedDevice"); +#ifdef UA_ENABLE_NODEMANAGEMENT + ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/NodeManagement"); +#endif +#ifdef UA_ENABLE_METHODCALLS + ADDPROFILEARRAY("http://opcfoundation.org/UA-Profile/Server/Methods"); +#endif + retVal |= writeNs0VariableArray(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_SERVERPROFILEARRAY, + profileArray, profileArraySize, &UA_TYPES[UA_TYPES_STRING]); + + /* ServerCapabilities - MaxQueryContinuationPoints */ + UA_UInt16 maxQueryContinuationPoints = 0; + retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXQUERYCONTINUATIONPOINTS, + &maxQueryContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]); + + /* ServerCapabilities - MaxHistoryContinuationPoints */ + UA_UInt16 maxHistoryContinuationPoints = 0; + retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXHISTORYCONTINUATIONPOINTS, + &maxHistoryContinuationPoints, &UA_TYPES[UA_TYPES_UINT16]); + + /* ServerCapabilities - MinSupportedSampleRate */ + UA_DataSource samplingInterval = {readMinSamplingInterval, NULL}; + retVal |= UA_Server_setVariableNode_dataSource(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MINSUPPORTEDSAMPLERATE), + samplingInterval); + /* ServerCapabilities - OperationLimits - MaxNodesPerRead */ retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERREAD, &server->config.maxNodesPerRead, &UA_TYPES[UA_TYPES_UINT32]); @@ -20969,4909 +22805,237 @@ UA_Server_initNS0(UA_Server *server) { retVal |= writeNs0Variable(server, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXMONITOREDITEMSPERCALL, &server->config.maxMonitoredItemsPerCall, &UA_TYPES[UA_TYPES_UINT32]); -#if defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS) - retVal |= UA_Server_setMethodNode_callback(server, - UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_GETMONITOREDITEMS), readMonitoredItems); +#ifdef UA_ENABLE_MICRO_EMB_DEV_PROFILE + /* Remove unused operation limit components */ + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADDATA), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYREADEVENTS), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEDATA), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_OPERATIONLIMITS_MAXNODESPERHISTORYUPDATEEVENTS), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_ROLESET), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXSTRINGLENGTH), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXARRAYLENGTH), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERCAPABILITIES_MAXBYTESTRINGLENGTH), true); + + /* Remove not supported Server Instance */ + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_DICTIONARIES), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_ESTIMATEDRETURNTIME), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_LOCALTIME), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_NAMESPACES), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_REQUESTSERVERSTATECHANGE), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_RESENDDATA), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVERCONFIGURATION), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SETSUBSCRIPTIONDURABLE), true); + + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SAMPLINGINTERVALDIAGNOSTICSARRAY), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SESSIONSDIAGNOSTICSSUMMARY), true); + + /* Removing these NodeIds make Server Object to be non-complaint with UA 1.03 in CTT (Base Inforamtion/Base Info Core Structure/ 001.js) + * In the 1.04 specification this has been resolved by allowing to remove these static nodes as well */ + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SERVERDIAGNOSTICSSUMMARY), true); + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERDIAGNOSTICS_SUBSCRIPTIONDIAGNOSTICSARRAY), true); #endif - return retVal; -} - -/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/ua_namespace0.c" ***********************************/ - -/* WARNING: This is a generated file. - * Any manual changes will be overwritten. */ - - - -/* HasHistoricalConfiguration - ns=0;i=56 */ - -static UA_StatusCode function_ua_namespace0_0_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; -attr.inverseName = UA_LOCALIZEDTEXT("", "HistoricalConfigurationOf"); -attr.displayName = UA_LOCALIZEDTEXT("", "HasHistoricalConfiguration"); -attr.description = UA_LOCALIZEDTEXT("", "The type for a reference to the historical configuration for a data variable."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, -UA_NODEID_NUMERIC(ns[0], 56), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "HasHistoricalConfiguration"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 56), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 44), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_0_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 56) -); -} - -/* HasEffect - ns=0;i=54 */ - -static UA_StatusCode function_ua_namespace0_1_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; -attr.inverseName = UA_LOCALIZEDTEXT("", "MayBeEffectedBy"); -attr.displayName = UA_LOCALIZEDTEXT("", "HasEffect"); -attr.description = UA_LOCALIZEDTEXT("", "The type for a reference to an event that may be raised when a transition occurs."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, -UA_NODEID_NUMERIC(ns[0], 54), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "HasEffect"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 54), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 32), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_1_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 54) -); -} - -/* ToState - ns=0;i=52 */ - -static UA_StatusCode function_ua_namespace0_2_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; -attr.inverseName = UA_LOCALIZEDTEXT("", "FromTransition"); -attr.displayName = UA_LOCALIZEDTEXT("", "ToState"); -attr.description = UA_LOCALIZEDTEXT("", "The type for a reference to the state after a transition."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, -UA_NODEID_NUMERIC(ns[0], 52), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ToState"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 52), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 32), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_2_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 52) -); -} - -/* HasCause - ns=0;i=53 */ - -static UA_StatusCode function_ua_namespace0_3_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; -attr.inverseName = UA_LOCALIZEDTEXT("", "MayBeCausedBy"); -attr.displayName = UA_LOCALIZEDTEXT("", "HasCause"); -attr.description = UA_LOCALIZEDTEXT("", "The type for a reference to a method that can cause a transition to occur."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, -UA_NODEID_NUMERIC(ns[0], 53), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "HasCause"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 53), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 32), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_3_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 53) -); -} - -/* FromState - ns=0;i=51 */ - -static UA_StatusCode function_ua_namespace0_4_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; -attr.inverseName = UA_LOCALIZEDTEXT("", "ToTransition"); -attr.displayName = UA_LOCALIZEDTEXT("", "FromState"); -attr.description = UA_LOCALIZEDTEXT("", "The type for a reference to the state before a transition."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, -UA_NODEID_NUMERIC(ns[0], 51), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "FromState"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 51), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 32), false); -return retVal; -} -static UA_StatusCode function_ua_namespace0_4_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 51) -); -} - -/* EnumValueType - ns=0;i=7594 */ - -static UA_StatusCode function_ua_namespace0_5_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "EnumValueType"); -attr.description = UA_LOCALIZEDTEXT("", "A mapping between a value of an enumerated type and a name and description."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 7594), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "EnumValueType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 7594), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 22), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_5_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 7594) -); -} - -/* ServerCapabilitiesType - ns=0;i=2013 */ - -static UA_StatusCode function_ua_namespace0_6_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerCapabilitiesType"); -attr.description = UA_LOCALIZEDTEXT("", "Describes the capabilities supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 2013), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerCapabilitiesType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2013), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 58), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_6_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2013) -); -} - -/* OperationLimitsType - ns=0;i=11564 */ - -static UA_StatusCode function_ua_namespace0_7_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "OperationLimitsType"); -attr.description = UA_LOCALIZEDTEXT("", "Identifies the operation limits imposed by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 11564), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "OperationLimitsType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11564), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 61), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_7_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11564) -); -} - -/* OperationLimits - ns=0;i=11551 */ - -static UA_StatusCode function_ua_namespace0_8_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "OperationLimits"); -attr.description = UA_LOCALIZEDTEXT("", "Defines the limits supported by the server for different operations."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 11551), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "OperationLimits"), -UA_NODEID_NUMERIC(ns[0], 11564), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11551), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2013), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_8_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11551) -); -} - -/* BuildInfo - ns=0;i=338 */ - -static UA_StatusCode function_ua_namespace0_9_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "BuildInfo"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 338), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "BuildInfo"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 338), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 22), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_9_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 338) -); -} - -/* ServerType - ns=0;i=2004 */ - -static UA_StatusCode function_ua_namespace0_10_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerType"); -attr.description = UA_LOCALIZEDTEXT("", "Specifies the current status and capabilities of the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 2004), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2004), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 58), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_10_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2004) -); -} - -/* Server - ns=0;i=2253 */ - -static UA_StatusCode function_ua_namespace0_11_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.eventNotifier = true; -attr.displayName = UA_LOCALIZEDTEXT("", "Server"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 2253), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Server"), -UA_NODEID_NUMERIC(ns[0], 2004), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2253), UA_NODEID_NUMERIC(ns[0], 35), UA_EXPANDEDNODEID_NUMERIC(ns[0], 85), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_11_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2253) -); -} - -/* GetMonitoredItems - ns=0;i=11492 */ - -static UA_StatusCode function_ua_namespace0_12_begin(UA_Server *server, UA_UInt16* ns) { - -#ifdef UA_ENABLE_METHODCALLS -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_MethodAttributes attr = UA_MethodAttributes_default; -attr.executable = true; -attr.userExecutable = true; -attr.displayName = UA_LOCALIZEDTEXT("", "GetMonitoredItems"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_METHOD, -UA_NODEID_NUMERIC(ns[0], 11492), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "GetMonitoredItems"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11492), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; +#ifndef UA_ENABLE_HISTORIZING + UA_Server_deleteNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_HISTORYSERVERCAPABILITIES), true); #else -return UA_STATUSCODE_GOOD; -#endif /* UA_ENABLE_METHODCALLS */ -} - -static UA_StatusCode function_ua_namespace0_12_finish(UA_Server *server, UA_UInt16* ns) { - -#ifdef UA_ENABLE_METHODCALLS -return UA_Server_addMethodNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11492) -, NULL, 0, NULL, 0, NULL); -#else -return UA_STATUSCODE_GOOD; -#endif /* UA_ENABLE_METHODCALLS */ -} - -/* ServerCapabilities - ns=0;i=2268 */ - -static UA_StatusCode function_ua_namespace0_13_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerCapabilities"); -attr.description = UA_LOCALIZEDTEXT("", "Describes capabilities supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 2268), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerCapabilities"), -UA_NODEID_NUMERIC(ns[0], 2013), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2268), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_13_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2268) -); -} - -/* AggregateFunctions - ns=0;i=2997 */ - -static UA_StatusCode function_ua_namespace0_14_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "AggregateFunctions"); -attr.description = UA_LOCALIZEDTEXT("", "A folder for the real time aggregates supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 2997), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "AggregateFunctions"), -UA_NODEID_NUMERIC(ns[0], 61), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2997), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_14_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2997) -); -} - -/* ModellingRules - ns=0;i=2996 */ - -static UA_StatusCode function_ua_namespace0_15_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ModellingRules"); -attr.description = UA_LOCALIZEDTEXT("", "A folder for the modelling rules supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 2996), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ModellingRules"), -UA_NODEID_NUMERIC(ns[0], 61), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2996), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_15_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2996) -); -} - -/* OperationLimits - ns=0;i=11704 */ - -static UA_StatusCode function_ua_namespace0_16_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "OperationLimits"); -attr.description = UA_LOCALIZEDTEXT("", "Defines the limits supported by the server for different operations."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 11704), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "OperationLimits"), -UA_NODEID_NUMERIC(ns[0], 11564), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11704), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_16_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11704) -); -} - -/* ServerDiagnosticsSummaryType - ns=0;i=2150 */ - -static UA_StatusCode function_ua_namespace0_17_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; -attr.valueRank = (UA_Int32)-2; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 24); -attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnosticsSummaryType"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, -UA_NODEID_NUMERIC(ns[0], 2150), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerDiagnosticsSummaryType"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2150), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 63), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_17_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2150) -); -} - -/* PublishingIntervalCount - ns=0;i=2159 */ - -static UA_StatusCode function_ua_namespace0_18_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "PublishingIntervalCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2159), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "PublishingIntervalCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2159), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_18_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2159) -); -} - -/* SecurityRejectedSessionCount - ns=0;i=2154 */ - -static UA_StatusCode function_ua_namespace0_19_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SecurityRejectedSessionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2154), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SecurityRejectedSessionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2154), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_19_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2154) -); -} - -/* SecurityRejectedRequestsCount - ns=0;i=2162 */ - -static UA_StatusCode function_ua_namespace0_20_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SecurityRejectedRequestsCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2162), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SecurityRejectedRequestsCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2162), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_20_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2162) -); -} - -/* RejectedRequestsCount - ns=0;i=2163 */ - -static UA_StatusCode function_ua_namespace0_21_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "RejectedRequestsCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2163), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "RejectedRequestsCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2163), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_21_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2163) -); -} - -/* RejectedSessionCount - ns=0;i=2155 */ - -static UA_StatusCode function_ua_namespace0_22_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "RejectedSessionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2155), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "RejectedSessionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2155), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_22_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2155) -); -} - -/* CumulatedSubscriptionCount - ns=0;i=2161 */ - -static UA_StatusCode function_ua_namespace0_23_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "CumulatedSubscriptionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2161), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CumulatedSubscriptionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2161), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_23_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2161) -); -} - -/* CumulatedSessionCount - ns=0;i=2153 */ - -static UA_StatusCode function_ua_namespace0_24_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "CumulatedSessionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2153), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CumulatedSessionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2153), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_24_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2153) -); -} - -/* CurrentSessionCount - ns=0;i=2152 */ - -static UA_StatusCode function_ua_namespace0_25_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "CurrentSessionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2152), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CurrentSessionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2152), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_25_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2152) -); -} - -/* ServerViewCount - ns=0;i=2151 */ - -static UA_StatusCode function_ua_namespace0_26_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "ServerViewCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2151), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerViewCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2151), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_26_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2151) -); -} - -/* SessionAbortCount - ns=0;i=2157 */ - -static UA_StatusCode function_ua_namespace0_27_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SessionAbortCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2157), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SessionAbortCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2157), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_27_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2157) -); -} - -/* SessionTimeoutCount - ns=0;i=2156 */ - -static UA_StatusCode function_ua_namespace0_28_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SessionTimeoutCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2156), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SessionTimeoutCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2156), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_28_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2156) -); -} - -/* CurrentSubscriptionCount - ns=0;i=2160 */ - -static UA_StatusCode function_ua_namespace0_29_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "CurrentSubscriptionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2160), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CurrentSubscriptionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2160), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2150), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_29_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2160) -); -} - -/* BuildInfoType - ns=0;i=3051 */ - -static UA_StatusCode function_ua_namespace0_30_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; -attr.valueRank = (UA_Int32)-2; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 24); -attr.displayName = UA_LOCALIZEDTEXT("", "BuildInfoType"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, -UA_NODEID_NUMERIC(ns[0], 3051), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "BuildInfoType"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 3051), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 63), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_30_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 3051) -); -} - -/* Image - ns=0;i=30 */ - -static UA_StatusCode function_ua_namespace0_31_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.isAbstract = true; -attr.displayName = UA_LOCALIZEDTEXT("", "Image"); -attr.description = UA_LOCALIZEDTEXT("", "Describes a value that is an image encoded as a string of bytes."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 30), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Image"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 30), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 15), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_31_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 30) -); -} - -/* Decimal - ns=0;i=50 */ - -static UA_StatusCode function_ua_namespace0_32_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "Decimal"); -attr.description = UA_LOCALIZEDTEXT("", "Describes an arbitrary precision decimal value."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 50), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Decimal"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 50), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 26), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_32_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 50) -); -} - -/* Enumeration - ns=0;i=29 */ - -static UA_StatusCode function_ua_namespace0_33_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.isAbstract = true; -attr.displayName = UA_LOCALIZEDTEXT("", "Enumeration"); -attr.description = UA_LOCALIZEDTEXT("", "Describes a value that is an enumerated DataType."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 29), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Enumeration"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 29), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 24), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_33_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 29) -); -} - -/* NamingRuleType - ns=0;i=120 */ - -static UA_StatusCode function_ua_namespace0_34_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "NamingRuleType"); -attr.description = UA_LOCALIZEDTEXT("", "Describes a value that specifies the significance of the BrowseName for an instance declaration."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 120), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "NamingRuleType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 120), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 29), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_34_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 120) -); -} - -/* RedundancySupport - ns=0;i=851 */ - -static UA_StatusCode function_ua_namespace0_35_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "RedundancySupport"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 851), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "RedundancySupport"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 851), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 29), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_35_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 851) -); -} - -/* ServerState - ns=0;i=852 */ - -static UA_StatusCode function_ua_namespace0_36_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerState"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 852), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerState"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 852), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 29), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_36_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 852) -); -} - -/* DiagnosticInfo - ns=0;i=25 */ - -static UA_StatusCode function_ua_namespace0_37_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "DiagnosticInfo"); -attr.description = UA_LOCALIZEDTEXT("", "Describes a value that is a structure containing diagnostics associated with a StatusCode."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 25), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DiagnosticInfo"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 25), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 24), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_37_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 25) -); -} - -/* DataValue - ns=0;i=23 */ - -static UA_StatusCode function_ua_namespace0_38_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "DataValue"); -attr.description = UA_LOCALIZEDTEXT("", "Describes a value that is a structure containing a value, a status code and timestamps."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 23), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DataValue"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 23), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 24), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_38_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 23) -); -} - -/* ServerRedundancyType - ns=0;i=2034 */ - -static UA_StatusCode function_ua_namespace0_39_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerRedundancyType"); -attr.description = UA_LOCALIZEDTEXT("", "A base type for an object that describe how a server supports redundancy."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 2034), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerRedundancyType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2034), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 58), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_39_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2034) -); -} - -/* ServerRedundancy - ns=0;i=2296 */ - -static UA_StatusCode function_ua_namespace0_40_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerRedundancy"); -attr.description = UA_LOCALIZEDTEXT("", "Describes the redundancy capabilities of the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 2296), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerRedundancy"), -UA_NODEID_NUMERIC(ns[0], 2034), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2296), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_40_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2296) -); -} - -/* PropertyType - ns=0;i=68 */ - -static UA_StatusCode function_ua_namespace0_41_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; -attr.valueRank = (UA_Int32)-2; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 24); -attr.displayName = UA_LOCALIZEDTEXT("", "PropertyType"); -attr.description = UA_LOCALIZEDTEXT("", "The type for variable that represents a property of another node."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, -UA_NODEID_NUMERIC(ns[0], 68), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "PropertyType"), -UA_NODEID_NUMERIC(ns[0], 62), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 68), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 62), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_41_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 68) -); -} - -/* MaxBrowseContinuationPoints - ns=0;i=2735 */ - -static UA_StatusCode function_ua_namespace0_42_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 5); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT16]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxBrowseContinuationPoints"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of continuation points for Browse operations per session."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2735), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxBrowseContinuationPoints"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2735), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_42_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2735) -); -} - -/* MaxNodesPerBrowse - ns=0;i=11710 */ - -static UA_StatusCode function_ua_namespace0_43_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerBrowse"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single Browse request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11710), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerBrowse"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11710), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11704), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_43_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11710) -); -} - -/* MaxNodesPerWrite - ns=0;i=11707 */ - -static UA_StatusCode function_ua_namespace0_44_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerWrite"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single Write request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11707), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerWrite"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11707), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11704), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_44_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11707) -); -} - -/* Auditing - ns=0;i=2994 */ - -static UA_StatusCode function_ua_namespace0_45_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 1); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_BOOLEAN]); -attr.displayName = UA_LOCALIZEDTEXT("", "Auditing"); -attr.description = UA_LOCALIZEDTEXT("", "A flag indicating whether the server is currently generating audit events."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2994), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Auditing"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2994), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_45_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2994) -); -} - -/* MaxNodesPerRead - ns=0;i=11565 */ - -static UA_StatusCode function_ua_namespace0_46_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerRead"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single Read request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11565), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerRead"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11565), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11564), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_46_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11565) -); -} - -/* MaxNodesPerWrite - ns=0;i=11567 */ - -static UA_StatusCode function_ua_namespace0_47_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerWrite"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single Write request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11567), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerWrite"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11567), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11564), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_47_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11567) -); -} - -/* RedundancySupport - ns=0;i=2035 */ - -static UA_StatusCode function_ua_namespace0_48_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 851); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); -attr.displayName = UA_LOCALIZEDTEXT("", "RedundancySupport"); -attr.description = UA_LOCALIZEDTEXT("", "Indicates what style of redundancy is supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2035), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "RedundancySupport"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2035), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2034), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_48_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2035) -); -} - -/* MaxNodesPerMethodCall - ns=0;i=11569 */ - -static UA_StatusCode function_ua_namespace0_49_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerMethodCall"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single Call request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11569), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerMethodCall"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11569), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11564), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_49_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11569) -); -} - -/* MaxNodesPerMethodCall - ns=0;i=11709 */ - -static UA_StatusCode function_ua_namespace0_50_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerMethodCall"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single Call request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11709), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerMethodCall"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11709), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11704), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_50_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11709) -); -} - -/* NamespaceArray - ns=0;i=2255 */ - -static UA_StatusCode function_ua_namespace0_51_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setArray(&attr.value, NULL, (UA_Int32) 0, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "NamespaceArray"); -attr.description = UA_LOCALIZEDTEXT("", "The list of namespace URIs used by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2255), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "NamespaceArray"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2255), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} + /* ServerCapabilities - HistoryServerCapabilities - AccessHistoryDataCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_ACCESSHISTORYDATACAPABILITY, + &server->config.accessHistoryDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -static UA_StatusCode function_ua_namespace0_51_finish(UA_Server *server, UA_UInt16* ns) { + /* ServerCapabilities - HistoryServerCapabilities - MaxReturnDataValues */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_MAXRETURNDATAVALUES, + &server->config.maxReturnDataValues, &UA_TYPES[UA_TYPES_UINT32]); -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2255) -); -} + /* ServerCapabilities - HistoryServerCapabilities - AccessHistoryEventsCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_ACCESSHISTORYEVENTSCAPABILITY, + &server->config.accessHistoryEventsCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -/* ServerArray - ns=0;i=2254 */ - -static UA_StatusCode function_ua_namespace0_52_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setArray(&attr.value, NULL, (UA_Int32) 0, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "ServerArray"); -attr.description = UA_LOCALIZEDTEXT("", "The list of server URIs used by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2254), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerArray"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2254), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_52_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2254) -); -} - -/* MinSupportedSampleRate - ns=0;i=2272 */ - -static UA_StatusCode function_ua_namespace0_53_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 290); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_DOUBLE]); -attr.displayName = UA_LOCALIZEDTEXT("", "MinSupportedSampleRate"); -attr.description = UA_LOCALIZEDTEXT("", "The minimum sampling interval supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2272), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MinSupportedSampleRate"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2272), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} + /* ServerCapabilities - HistoryServerCapabilities - MaxReturnEventValues */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_MAXRETURNEVENTVALUES, + &server->config.maxReturnEventValues, &UA_TYPES[UA_TYPES_UINT32]); -static UA_StatusCode function_ua_namespace0_53_finish(UA_Server *server, UA_UInt16* ns) { + /* ServerCapabilities - HistoryServerCapabilities - InsertDataCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTDATACAPABILITY, + &server->config.insertDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2272) -); -} + /* ServerCapabilities - HistoryServerCapabilities - InsertEventCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTEVENTCAPABILITY, + &server->config.insertEventCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -/* LocaleIdArray - ns=0;i=2271 */ + /* ServerCapabilities - HistoryServerCapabilities - InsertAnnotationsCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_INSERTANNOTATIONCAPABILITY, + &server->config.insertAnnotationsCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -static UA_StatusCode function_ua_namespace0_54_begin(UA_Server *server, UA_UInt16* ns) { + /* ServerCapabilities - HistoryServerCapabilities - ReplaceDataCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_REPLACEDATACAPABILITY, + &server->config.replaceDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 295); -UA_Variant_setArray(&attr.value, NULL, (UA_Int32) 0, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "LocaleIdArray"); -attr.description = UA_LOCALIZEDTEXT("", "A list of locales supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2271), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "LocaleIdArray"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2271), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} + /* ServerCapabilities - HistoryServerCapabilities - ReplaceEventCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_REPLACEEVENTCAPABILITY, + &server->config.replaceEventCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -static UA_StatusCode function_ua_namespace0_54_finish(UA_Server *server, UA_UInt16* ns) { + /* ServerCapabilities - HistoryServerCapabilities - UpdateDataCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_UPDATEDATACAPABILITY, + &server->config.updateDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2271) -); -} + /* ServerCapabilities - HistoryServerCapabilities - UpdateEventCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_UPDATEEVENTCAPABILITY, + &server->config.updateEventCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -/* EnumValues - ns=0;i=12169 */ + /* ServerCapabilities - HistoryServerCapabilities - DeleteRawCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETERAWCAPABILITY, + &server->config.deleteRawCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -static UA_StatusCode function_ua_namespace0_55_begin(UA_Server *server, UA_UInt16* ns) { + /* ServerCapabilities - HistoryServerCapabilities - DeleteEventCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETEEVENTCAPABILITY, + &server->config.deleteEventCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7594); - -struct { - UA_Int64 Value; - UA_LocalizedText DisplayName; - UA_LocalizedText Description; -} variablenode_ns_0_i_12169_EnumValueType_0_0_struct; -UA_ExtensionObject *variablenode_ns_0_i_12169_EnumValueType_0_0 = UA_ExtensionObject_new(); -if (!variablenode_ns_0_i_12169_EnumValueType_0_0) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_12169_EnumValueType_0_0_struct.Value = (UA_Int64) 1; -variablenode_ns_0_i_12169_EnumValueType_0_0_struct.DisplayName = UA_LOCALIZEDTEXT("", "Mandatory"); -variablenode_ns_0_i_12169_EnumValueType_0_0_struct.Description = UA_LOCALIZEDTEXT("", "The BrowseName must appear in all instances of the type."); -variablenode_ns_0_i_12169_EnumValueType_0_0->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING; -variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.typeId = UA_NODEID_NUMERIC(0, 8251); -retVal |= UA_ByteString_allocBuffer(&variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.body, 65000); -UA_Byte *posvariablenode_ns_0_i_12169_EnumValueType_0_0 = variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.body.data; -const UA_Byte *endvariablenode_ns_0_i_12169_EnumValueType_0_0 = &variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.body.data[65000]; -{ -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_0_0_struct.Value, &UA_TYPES[UA_TYPES_INT64], &posvariablenode_ns_0_i_12169_EnumValueType_0_0, &endvariablenode_ns_0_i_12169_EnumValueType_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_0_0_struct.DisplayName, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_12169_EnumValueType_0_0, &endvariablenode_ns_0_i_12169_EnumValueType_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_0_0_struct.Description, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_12169_EnumValueType_0_0, &endvariablenode_ns_0_i_12169_EnumValueType_0_0, NULL, NULL); -} -size_t variablenode_ns_0_i_12169_EnumValueType_0_0_encOffset = (uintptr_t)(posvariablenode_ns_0_i_12169_EnumValueType_0_0-variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.body.data); -variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.body.length = variablenode_ns_0_i_12169_EnumValueType_0_0_encOffset; -UA_Byte *variablenode_ns_0_i_12169_EnumValueType_0_0_newBody = (UA_Byte *) UA_malloc(variablenode_ns_0_i_12169_EnumValueType_0_0_encOffset); -if (!variablenode_ns_0_i_12169_EnumValueType_0_0_newBody) return UA_STATUSCODE_BADOUTOFMEMORY; -memcpy(variablenode_ns_0_i_12169_EnumValueType_0_0_newBody, variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.body.data, variablenode_ns_0_i_12169_EnumValueType_0_0_encOffset); -UA_Byte *variablenode_ns_0_i_12169_EnumValueType_0_0_oldBody = variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.body.data; -variablenode_ns_0_i_12169_EnumValueType_0_0->content.encoded.body.data = variablenode_ns_0_i_12169_EnumValueType_0_0_newBody; -UA_free(variablenode_ns_0_i_12169_EnumValueType_0_0_oldBody); - - -struct { - UA_Int64 Value; - UA_LocalizedText DisplayName; - UA_LocalizedText Description; -} variablenode_ns_0_i_12169_EnumValueType_1_0_struct; -UA_ExtensionObject *variablenode_ns_0_i_12169_EnumValueType_1_0 = UA_ExtensionObject_new(); -if (!variablenode_ns_0_i_12169_EnumValueType_1_0) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_12169_EnumValueType_1_0_struct.Value = (UA_Int64) 2; -variablenode_ns_0_i_12169_EnumValueType_1_0_struct.DisplayName = UA_LOCALIZEDTEXT("", "Optional"); -variablenode_ns_0_i_12169_EnumValueType_1_0_struct.Description = UA_LOCALIZEDTEXT("", "The BrowseName may appear in an instance of the type."); -variablenode_ns_0_i_12169_EnumValueType_1_0->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING; -variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.typeId = UA_NODEID_NUMERIC(0, 8251); -retVal |= UA_ByteString_allocBuffer(&variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.body, 65000); -UA_Byte *posvariablenode_ns_0_i_12169_EnumValueType_1_0 = variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.body.data; -const UA_Byte *endvariablenode_ns_0_i_12169_EnumValueType_1_0 = &variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.body.data[65000]; -{ -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_1_0_struct.Value, &UA_TYPES[UA_TYPES_INT64], &posvariablenode_ns_0_i_12169_EnumValueType_1_0, &endvariablenode_ns_0_i_12169_EnumValueType_1_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_1_0_struct.DisplayName, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_12169_EnumValueType_1_0, &endvariablenode_ns_0_i_12169_EnumValueType_1_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_1_0_struct.Description, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_12169_EnumValueType_1_0, &endvariablenode_ns_0_i_12169_EnumValueType_1_0, NULL, NULL); -} -size_t variablenode_ns_0_i_12169_EnumValueType_1_0_encOffset = (uintptr_t)(posvariablenode_ns_0_i_12169_EnumValueType_1_0-variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.body.data); -variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.body.length = variablenode_ns_0_i_12169_EnumValueType_1_0_encOffset; -UA_Byte *variablenode_ns_0_i_12169_EnumValueType_1_0_newBody = (UA_Byte *) UA_malloc(variablenode_ns_0_i_12169_EnumValueType_1_0_encOffset); -if (!variablenode_ns_0_i_12169_EnumValueType_1_0_newBody) return UA_STATUSCODE_BADOUTOFMEMORY; -memcpy(variablenode_ns_0_i_12169_EnumValueType_1_0_newBody, variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.body.data, variablenode_ns_0_i_12169_EnumValueType_1_0_encOffset); -UA_Byte *variablenode_ns_0_i_12169_EnumValueType_1_0_oldBody = variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.body.data; -variablenode_ns_0_i_12169_EnumValueType_1_0->content.encoded.body.data = variablenode_ns_0_i_12169_EnumValueType_1_0_newBody; -UA_free(variablenode_ns_0_i_12169_EnumValueType_1_0_oldBody); - - -struct { - UA_Int64 Value; - UA_LocalizedText DisplayName; - UA_LocalizedText Description; -} variablenode_ns_0_i_12169_EnumValueType_2_0_struct; -UA_ExtensionObject *variablenode_ns_0_i_12169_EnumValueType_2_0 = UA_ExtensionObject_new(); -if (!variablenode_ns_0_i_12169_EnumValueType_2_0) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_12169_EnumValueType_2_0_struct.Value = (UA_Int64) 3; -variablenode_ns_0_i_12169_EnumValueType_2_0_struct.DisplayName = UA_LOCALIZEDTEXT("", "Constraint"); -variablenode_ns_0_i_12169_EnumValueType_2_0_struct.Description = UA_LOCALIZEDTEXT("", "The modelling rule defines a constraint and the BrowseName is not used in an instance of the type."); -variablenode_ns_0_i_12169_EnumValueType_2_0->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING; -variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.typeId = UA_NODEID_NUMERIC(0, 8251); -retVal |= UA_ByteString_allocBuffer(&variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.body, 65000); -UA_Byte *posvariablenode_ns_0_i_12169_EnumValueType_2_0 = variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.body.data; -const UA_Byte *endvariablenode_ns_0_i_12169_EnumValueType_2_0 = &variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.body.data[65000]; -{ -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_2_0_struct.Value, &UA_TYPES[UA_TYPES_INT64], &posvariablenode_ns_0_i_12169_EnumValueType_2_0, &endvariablenode_ns_0_i_12169_EnumValueType_2_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_2_0_struct.DisplayName, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_12169_EnumValueType_2_0, &endvariablenode_ns_0_i_12169_EnumValueType_2_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_12169_EnumValueType_2_0_struct.Description, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_12169_EnumValueType_2_0, &endvariablenode_ns_0_i_12169_EnumValueType_2_0, NULL, NULL); -} -size_t variablenode_ns_0_i_12169_EnumValueType_2_0_encOffset = (uintptr_t)(posvariablenode_ns_0_i_12169_EnumValueType_2_0-variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.body.data); -variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.body.length = variablenode_ns_0_i_12169_EnumValueType_2_0_encOffset; -UA_Byte *variablenode_ns_0_i_12169_EnumValueType_2_0_newBody = (UA_Byte *) UA_malloc(variablenode_ns_0_i_12169_EnumValueType_2_0_encOffset); -if (!variablenode_ns_0_i_12169_EnumValueType_2_0_newBody) return UA_STATUSCODE_BADOUTOFMEMORY; -memcpy(variablenode_ns_0_i_12169_EnumValueType_2_0_newBody, variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.body.data, variablenode_ns_0_i_12169_EnumValueType_2_0_encOffset); -UA_Byte *variablenode_ns_0_i_12169_EnumValueType_2_0_oldBody = variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.body.data; -variablenode_ns_0_i_12169_EnumValueType_2_0->content.encoded.body.data = variablenode_ns_0_i_12169_EnumValueType_2_0_newBody; -UA_free(variablenode_ns_0_i_12169_EnumValueType_2_0_oldBody); - -UA_ExtensionObject variablenode_ns_0_i_12169_variant_DataContents[3]; -variablenode_ns_0_i_12169_variant_DataContents[0] = *variablenode_ns_0_i_12169_EnumValueType_0_0; -variablenode_ns_0_i_12169_variant_DataContents[1] = *variablenode_ns_0_i_12169_EnumValueType_1_0; -variablenode_ns_0_i_12169_variant_DataContents[2] = *variablenode_ns_0_i_12169_EnumValueType_2_0; -UA_Variant_setArray(&attr.value, &variablenode_ns_0_i_12169_variant_DataContents, (UA_Int32) 3, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); -attr.displayName = UA_LOCALIZEDTEXT("", "EnumValues"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 12169), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "EnumValues"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); - -UA_ExtensionObject_delete(variablenode_ns_0_i_12169_EnumValueType_0_0); - -UA_ExtensionObject_delete(variablenode_ns_0_i_12169_EnumValueType_1_0); - -UA_ExtensionObject_delete(variablenode_ns_0_i_12169_EnumValueType_2_0); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 12169), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 120), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_55_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 12169) -); -} - -/* MaxNodesPerTranslateBrowsePathsToNodeIds - ns=0;i=11712 */ - -static UA_StatusCode function_ua_namespace0_56_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerTranslateBrowsePathsToNodeIds"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single TranslateBrowsePathsToNodeIds request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11712), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerTranslateBrowsePathsToNodeIds"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11712), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11704), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_56_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11712) -); -} - -/* MaxMonitoredItemsPerCall - ns=0;i=11574 */ - -static UA_StatusCode function_ua_namespace0_57_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxMonitoredItemsPerCall"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single MonitoredItem related request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11574), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxMonitoredItemsPerCall"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11574), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11564), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_57_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11574) -); -} - -/* MaxNodesPerNodeManagement - ns=0;i=11573 */ - -static UA_StatusCode function_ua_namespace0_58_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerNodeManagement"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single AddNodes, AddReferences, DeleteNodes or DeleteReferences request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11573), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerNodeManagement"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11573), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11564), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_58_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11573) -); -} - -/* MaxNodesPerTranslateBrowsePathsToNodeIds - ns=0;i=11572 */ - -static UA_StatusCode function_ua_namespace0_59_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerTranslateBrowsePathsToNodeIds"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single TranslateBrowsePathsToNodeIds request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11572), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerTranslateBrowsePathsToNodeIds"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11572), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11564), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_59_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11572) -); -} - -/* MaxNodesPerRegisterNodes - ns=0;i=11571 */ - -static UA_StatusCode function_ua_namespace0_60_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerRegisterNodes"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single RegisterNodes request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11571), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerRegisterNodes"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11571), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11564), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_60_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11571) -); -} - -/* MaxNodesPerBrowse - ns=0;i=11570 */ - -static UA_StatusCode function_ua_namespace0_61_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerBrowse"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single Browse request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11570), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerBrowse"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11570), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11564), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_61_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11570) -); -} - -/* MaxNodesPerRead - ns=0;i=11705 */ - -static UA_StatusCode function_ua_namespace0_62_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerRead"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single Read request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11705), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerRead"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11705), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11704), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_62_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11705) -); -} - -/* EnumStrings - ns=0;i=7611 */ - -static UA_StatusCode function_ua_namespace0_63_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 21); -UA_LocalizedText variablenode_ns_0_i_7611_variant_DataContents[6]; -variablenode_ns_0_i_7611_variant_DataContents[0] = UA_LOCALIZEDTEXT("", "None"); -variablenode_ns_0_i_7611_variant_DataContents[1] = UA_LOCALIZEDTEXT("", "Cold"); -variablenode_ns_0_i_7611_variant_DataContents[2] = UA_LOCALIZEDTEXT("", "Warm"); -variablenode_ns_0_i_7611_variant_DataContents[3] = UA_LOCALIZEDTEXT("", "Hot"); -variablenode_ns_0_i_7611_variant_DataContents[4] = UA_LOCALIZEDTEXT("", "Transparent"); -variablenode_ns_0_i_7611_variant_DataContents[5] = UA_LOCALIZEDTEXT("", "HotAndMirrored"); -UA_Variant_setArray(&attr.value, &variablenode_ns_0_i_7611_variant_DataContents, (UA_Int32) 6, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); -attr.displayName = UA_LOCALIZEDTEXT("", "EnumStrings"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 7611), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "EnumStrings"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 7611), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 851), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_63_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 7611) -); -} - -/* ServerProfileArray - ns=0;i=2269 */ - -static UA_StatusCode function_ua_namespace0_64_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setArray(&attr.value, NULL, (UA_Int32) 0, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "ServerProfileArray"); -attr.description = UA_LOCALIZEDTEXT("", "A list of profiles supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2269), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerProfileArray"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2269), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_64_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2269) -); -} - -/* MaxQueryContinuationPoints - ns=0;i=2736 */ - -static UA_StatusCode function_ua_namespace0_65_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 5); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT16]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxQueryContinuationPoints"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of continuation points for Query operations per session."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2736), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxQueryContinuationPoints"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2736), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_65_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2736) -); -} - -/* MaxHistoryContinuationPoints - ns=0;i=2737 */ - -static UA_StatusCode function_ua_namespace0_66_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 5); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT16]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxHistoryContinuationPoints"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of continuation points for ReadHistory operations per session."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2737), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxHistoryContinuationPoints"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2737), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_66_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2737) -); -} - -/* MaxNodesPerRegisterNodes - ns=0;i=11711 */ - -static UA_StatusCode function_ua_namespace0_67_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerRegisterNodes"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single RegisterNodes request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11711), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerRegisterNodes"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11711), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11704), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_67_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11711) -); -} - -/* ServiceLevel - ns=0;i=2267 */ - -static UA_StatusCode function_ua_namespace0_68_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 3); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_BYTE]); -attr.displayName = UA_LOCALIZEDTEXT("", "ServiceLevel"); -attr.description = UA_LOCALIZEDTEXT("", "A value indicating the level of service the server can provide. 255 indicates the best."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2267), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServiceLevel"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2267), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_68_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2267) -); -} - -/* RedundancySupport - ns=0;i=3709 */ - -static UA_StatusCode function_ua_namespace0_69_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 851); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_REDUNDANCYSUPPORT]); -attr.displayName = UA_LOCALIZEDTEXT("", "RedundancySupport"); -attr.description = UA_LOCALIZEDTEXT("", "Indicates what style of redundancy is supported by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 3709), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "RedundancySupport"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 3709), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2296), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_69_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 3709) -); -} - -/* MaxMonitoredItemsPerCall - ns=0;i=11714 */ - -static UA_StatusCode function_ua_namespace0_70_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxMonitoredItemsPerCall"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single MonitoredItem related request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11714), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxMonitoredItemsPerCall"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11714), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11704), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_70_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11714) -); -} - -/* MaxNodesPerNodeManagement - ns=0;i=11713 */ - -static UA_StatusCode function_ua_namespace0_71_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerNodeManagement"); -attr.description = UA_LOCALIZEDTEXT("", "The maximum number of operations in a single AddNodes, AddReferences, DeleteNodes or DeleteReferences request."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11713), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "MaxNodesPerNodeManagement"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11713), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11704), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_71_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11713) -); -} - -/* ModellingRuleType - ns=0;i=77 */ - -static UA_StatusCode function_ua_namespace0_72_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ModellingRuleType"); -attr.description = UA_LOCALIZEDTEXT("", "The type for an object that describes how an instance declaration is used when a type is instantiated."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 77), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ModellingRuleType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 77), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 58), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_72_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 77) -); -} - -/* NamingRule - ns=0;i=111 */ - -static UA_StatusCode function_ua_namespace0_73_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 120); -UA_Int32 *variablenode_ns_0_i_111_variant_DataContents = UA_Int32_new(); -if (!variablenode_ns_0_i_111_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; -*variablenode_ns_0_i_111_variant_DataContents = (UA_Int32) 1; -UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_111_variant_DataContents, &UA_TYPES[UA_TYPES_INT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "NamingRule"); -attr.description = UA_LOCALIZEDTEXT("", "Specified the significances of the BrowseName when a type is instantiated."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 111), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "NamingRule"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Int32_delete(variablenode_ns_0_i_111_variant_DataContents); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 111), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 77), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_73_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 111) -); -} - -/* Mandatory - ns=0;i=78 */ - -static UA_StatusCode function_ua_namespace0_74_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "Mandatory"); -attr.description = UA_LOCALIZEDTEXT("", "Specifies that an instance with the attributes and references of the instance declaration must appear when a type is instantiated."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 78), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Mandatory"), -UA_NODEID_NUMERIC(ns[0], 77), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2035), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2161), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2160), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7611), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 35), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2996), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2152), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2153), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 12169), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2151), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2156), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2157), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2154), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2155), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2163), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2159), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 111), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2162), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_74_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 78) -); -} - -/* NamingRule - ns=0;i=112 */ - -static UA_StatusCode function_ua_namespace0_75_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 120); -UA_Int32 *variablenode_ns_0_i_112_variant_DataContents = UA_Int32_new(); -if (!variablenode_ns_0_i_112_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; -*variablenode_ns_0_i_112_variant_DataContents = (UA_Int32) 1; -UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_112_variant_DataContents, &UA_TYPES[UA_TYPES_INT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "NamingRule"); -attr.description = UA_LOCALIZEDTEXT("", "Specified the significances of the BrowseName when a type is instantiated."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 112), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "NamingRule"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Int32_delete(variablenode_ns_0_i_112_variant_DataContents); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 112), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_75_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 112) -); -} - -/* Optional - ns=0;i=80 */ - -static UA_StatusCode function_ua_namespace0_76_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "Optional"); -attr.description = UA_LOCALIZEDTEXT("", "Specifies that an instance with the attributes and references of the instance declaration may appear when a type is instantiated."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 80), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Optional"), -UA_NODEID_NUMERIC(ns[0], 77), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 35), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2996), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11567), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11565), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11551), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11574), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11569), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11570), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11571), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11572), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11573), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_76_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 80) -); -} - -/* NamingRule - ns=0;i=113 */ - -static UA_StatusCode function_ua_namespace0_77_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 120); -UA_Int32 *variablenode_ns_0_i_113_variant_DataContents = UA_Int32_new(); -if (!variablenode_ns_0_i_113_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; -*variablenode_ns_0_i_113_variant_DataContents = (UA_Int32) 2; -UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_113_variant_DataContents, &UA_TYPES[UA_TYPES_INT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "NamingRule"); -attr.description = UA_LOCALIZEDTEXT("", "Specified the significances of the BrowseName when a type is instantiated."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 113), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "NamingRule"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Int32_delete(variablenode_ns_0_i_113_variant_DataContents); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 113), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_77_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 113) -); -} - -/* DataTypeEncodingType - ns=0;i=76 */ - -static UA_StatusCode function_ua_namespace0_78_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeEncodingType"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 76), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DataTypeEncodingType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 76), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 58), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_78_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 76) -); -} - -/* Default Binary - ns=0;i=8251 */ - -static UA_StatusCode function_ua_namespace0_79_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "Default Binary"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 8251), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Default Binary"), -UA_NODEID_NUMERIC(ns[0], 76), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 8251), UA_NODEID_NUMERIC(ns[0], 38), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7594), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_79_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 8251) -); -} - -/* DataTypeSystemType - ns=0;i=75 */ - -static UA_StatusCode function_ua_namespace0_80_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeSystemType"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 75), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DataTypeSystemType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 75), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 58), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_80_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 75) -); -} - -/* OPC Binary - ns=0;i=93 */ - -static UA_StatusCode function_ua_namespace0_81_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "OPC Binary"); -attr.description = UA_LOCALIZEDTEXT("", "A type system which uses OPC binary schema to describe the encoding of data types."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 93), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "OPC Binary"), -UA_NODEID_NUMERIC(ns[0], 75), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 93), UA_NODEID_NUMERIC(ns[0], 35), UA_EXPANDEDNODEID_NUMERIC(ns[0], 90), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_81_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 93) -); -} - -/* DataTypeDictionaryType - ns=0;i=72 */ - -static UA_StatusCode function_ua_namespace0_82_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; -attr.valueRank = (UA_Int32)-2; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 24); -attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeDictionaryType"); -attr.description = UA_LOCALIZEDTEXT("", "The type for variable that represents the collection of data type decriptions."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, -UA_NODEID_NUMERIC(ns[0], 72), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DataTypeDictionaryType"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 72), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 63), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_82_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 72) -); -} - -/* NamespaceUri - ns=0;i=107 */ - -static UA_StatusCode function_ua_namespace0_83_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "NamespaceUri"); -attr.description = UA_LOCALIZEDTEXT("", "A URI that uniquely identifies the dictionary."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 107), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "NamespaceUri"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 107), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 107), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 72), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_83_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 107) -); -} - -/* DataTypeVersion - ns=0;i=106 */ - -static UA_StatusCode function_ua_namespace0_84_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeVersion"); -attr.description = UA_LOCALIZEDTEXT("", "The version number for the data type dictionary."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 106), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DataTypeVersion"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 106), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 106), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 72), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_84_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 106) -); -} - -/* Opc.Ua - ns=0;i=7617 */ - -static UA_StatusCode function_ua_namespace0_85_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 15); -UA_ByteString *variablenode_ns_0_i_7617_variant_DataContents = UA_ByteString_new(); -if (!variablenode_ns_0_i_7617_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; -*variablenode_ns_0_i_7617_variant_DataContents = UA_BYTESTRING_NULL; -UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_7617_variant_DataContents, &UA_TYPES[UA_TYPES_BYTESTRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "Opc.Ua"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 7617), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Opc.Ua"), -UA_NODEID_NUMERIC(ns[0], 72), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_ByteString_delete(variablenode_ns_0_i_7617_variant_DataContents); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 7617), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 93), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_85_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 7617) -); -} - -/* ServerStatusDataType - ns=0;i=862 */ - -static UA_StatusCode function_ua_namespace0_86_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerStatusDataType"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 862), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerStatusDataType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 862), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 22), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_86_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 862) -); -} - -/* DataTypeDescriptionType - ns=0;i=69 */ - -static UA_StatusCode function_ua_namespace0_87_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; -attr.valueRank = (UA_Int32)-2; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 24); -attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeDescriptionType"); -attr.description = UA_LOCALIZEDTEXT("", "The type for variable that represents the description of a data type encoding."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, -UA_NODEID_NUMERIC(ns[0], 69), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DataTypeDescriptionType"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 69), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 63), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_87_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 69) -); -} - -/* DictionaryFragment - ns=0;i=105 */ - -static UA_StatusCode function_ua_namespace0_88_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 15); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_BYTESTRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "DictionaryFragment"); -attr.description = UA_LOCALIZEDTEXT("", "A fragment of a data type dictionary that defines the data type."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 105), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DictionaryFragment"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 105), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 105), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 69), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_88_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 105) -); -} - -/* DataTypeVersion - ns=0;i=104 */ - -static UA_StatusCode function_ua_namespace0_89_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeVersion"); -attr.description = UA_LOCALIZEDTEXT("", "The version number for the data type description."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 104), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "DataTypeVersion"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 104), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 104), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 69), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_89_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 104) -); -} - -/* Argument - ns=0;i=7650 */ - -static UA_StatusCode function_ua_namespace0_90_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_String *variablenode_ns_0_i_7650_variant_DataContents = UA_String_new(); -if (!variablenode_ns_0_i_7650_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; -*variablenode_ns_0_i_7650_variant_DataContents = UA_STRING_ALLOC("Argument"); -UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_7650_variant_DataContents, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "Argument"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 7650), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Argument"), -UA_NODEID_NUMERIC(ns[0], 69), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_String_delete(variablenode_ns_0_i_7650_variant_DataContents); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 7650), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7617), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_90_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 7650) -); -} - -/* EnumValueType - ns=0;i=7656 */ - -static UA_StatusCode function_ua_namespace0_91_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_String *variablenode_ns_0_i_7656_variant_DataContents = UA_String_new(); -if (!variablenode_ns_0_i_7656_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; -*variablenode_ns_0_i_7656_variant_DataContents = UA_STRING_ALLOC("EnumValueType"); -UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_7656_variant_DataContents, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "EnumValueType"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 7656), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "EnumValueType"), -UA_NODEID_NUMERIC(ns[0], 69), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_String_delete(variablenode_ns_0_i_7656_variant_DataContents); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 7656), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7617), false); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 7656), UA_NODEID_NUMERIC(ns[0], 39), UA_EXPANDEDNODEID_NUMERIC(ns[0], 8251), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_91_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 7656) -); -} - -/* ServerDiagnosticsSummaryDataType - ns=0;i=859 */ - -static UA_StatusCode function_ua_namespace0_92_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnosticsSummaryDataType"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 859), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerDiagnosticsSummaryDataType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 859), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 22), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_92_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 859) -); -} - -/* SignedSoftwareCertificate - ns=0;i=344 */ - -static UA_StatusCode function_ua_namespace0_93_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "SignedSoftwareCertificate"); -attr.description = UA_LOCALIZEDTEXT("", "A software certificate with a digital signature."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 344), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SignedSoftwareCertificate"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 344), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 22), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_93_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 344) -); -} - -/* SoftwareCertificates - ns=0;i=3704 */ - -static UA_StatusCode function_ua_namespace0_94_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 344); -UA_Variant_setArray(&attr.value, NULL, (UA_Int32) 0, &UA_TYPES[UA_TYPES_SIGNEDSOFTWARECERTIFICATE]); -attr.displayName = UA_LOCALIZEDTEXT("", "SoftwareCertificates"); -attr.description = UA_LOCALIZEDTEXT("", "The software certificates owned by the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 3704), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SoftwareCertificates"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 3704), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2268), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_94_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 3704) -); -} - -/* VendorServerInfoType - ns=0;i=2033 */ - -static UA_StatusCode function_ua_namespace0_95_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "VendorServerInfoType"); -attr.description = UA_LOCALIZEDTEXT("", "A base type for vendor specific server information."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 2033), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "VendorServerInfoType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2033), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 58), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_95_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2033) -); -} - -/* VendorServerInfo - ns=0;i=2295 */ - -static UA_StatusCode function_ua_namespace0_96_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "VendorServerInfo"); -attr.description = UA_LOCALIZEDTEXT("", "Server information provided by the vendor."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 2295), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "VendorServerInfo"), -UA_NODEID_NUMERIC(ns[0], 2033), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2295), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_96_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2295) -); -} - -/* VendorServerInfo - ns=0;i=2011 */ - -static UA_StatusCode function_ua_namespace0_97_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "VendorServerInfo"); -attr.description = UA_LOCALIZEDTEXT("", "Server information provided by the vendor."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 2011), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "VendorServerInfo"), -UA_NODEID_NUMERIC(ns[0], 2033), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2011), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2011), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2004), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_97_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2011) -); -} - -/* ServerStatusType - ns=0;i=2138 */ - -static UA_StatusCode function_ua_namespace0_98_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; -attr.valueRank = (UA_Int32)-2; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 24); -attr.displayName = UA_LOCALIZEDTEXT("", "ServerStatusType"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, -UA_NODEID_NUMERIC(ns[0], 2138), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerStatusType"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2138), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 63), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_98_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2138) -); -} - -/* ServerStatus - ns=0;i=2256 */ - -static UA_StatusCode function_ua_namespace0_99_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 862); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_SERVERSTATUSDATATYPE]); -attr.displayName = UA_LOCALIZEDTEXT("", "ServerStatus"); -attr.description = UA_LOCALIZEDTEXT("", "The current status of the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2256), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerStatus"), -UA_NODEID_NUMERIC(ns[0], 2138), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2256), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_99_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2256) -); -} - -/* State - ns=0;i=2259 */ - -static UA_StatusCode function_ua_namespace0_100_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 852); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_SERVERSTATE]); -attr.displayName = UA_LOCALIZEDTEXT("", "State"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2259), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "State"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2259), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2256), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_100_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2259) -); -} - -/* CurrentTime - ns=0;i=2258 */ - -static UA_StatusCode function_ua_namespace0_101_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 294); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_DATETIME]); -attr.displayName = UA_LOCALIZEDTEXT("", "CurrentTime"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2258), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CurrentTime"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2258), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2256), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_101_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2258) -); -} - -/* StartTime - ns=0;i=2257 */ - -static UA_StatusCode function_ua_namespace0_102_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 294); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_DATETIME]); -attr.displayName = UA_LOCALIZEDTEXT("", "StartTime"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2257), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "StartTime"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2257), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2256), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_102_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2257) -); -} - -/* BuildInfo - ns=0;i=2260 */ - -static UA_StatusCode function_ua_namespace0_103_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 338); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_BUILDINFO]); -attr.displayName = UA_LOCALIZEDTEXT("", "BuildInfo"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2260), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "BuildInfo"), -UA_NODEID_NUMERIC(ns[0], 3051), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2260), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2256), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_103_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2260) -); -} - -/* BuildDate - ns=0;i=2266 */ - -static UA_StatusCode function_ua_namespace0_104_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 294); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_DATETIME]); -attr.displayName = UA_LOCALIZEDTEXT("", "BuildDate"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2266), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "BuildDate"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2266), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2260), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_104_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2266) -); -} - -/* BuildNumber - ns=0;i=2265 */ - -static UA_StatusCode function_ua_namespace0_105_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "BuildNumber"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2265), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "BuildNumber"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2265), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2260), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_105_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2265) -); -} - -/* SoftwareVersion - ns=0;i=2264 */ - -static UA_StatusCode function_ua_namespace0_106_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "SoftwareVersion"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2264), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SoftwareVersion"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2264), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2260), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_106_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2264) -); -} - -/* ManufacturerName - ns=0;i=2263 */ - -static UA_StatusCode function_ua_namespace0_107_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "ManufacturerName"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2263), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ManufacturerName"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2263), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2260), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_107_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2263) -); -} - -/* ProductUri - ns=0;i=2262 */ - -static UA_StatusCode function_ua_namespace0_108_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "ProductUri"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2262), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ProductUri"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2262), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2260), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_108_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2262) -); -} - -/* ProductName - ns=0;i=2261 */ - -static UA_StatusCode function_ua_namespace0_109_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 1000.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_STRING]); -attr.displayName = UA_LOCALIZEDTEXT("", "ProductName"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2261), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ProductName"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2261), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2260), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_109_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2261) -); -} - -/* SecondsTillShutdown - ns=0;i=2992 */ - -static UA_StatusCode function_ua_namespace0_110_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SecondsTillShutdown"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2992), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SecondsTillShutdown"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2992), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2256), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_110_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2992) -); -} - -/* ShutdownReason - ns=0;i=2993 */ - -static UA_StatusCode function_ua_namespace0_111_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 21); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); -attr.displayName = UA_LOCALIZEDTEXT("", "ShutdownReason"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2993), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ShutdownReason"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2993), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2256), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_111_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2993) -); -} - -/* Argument - ns=0;i=296 */ - -static UA_StatusCode function_ua_namespace0_112_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "Argument"); -attr.description = UA_LOCALIZEDTEXT("", "An argument for a method."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, -UA_NODEID_NUMERIC(ns[0], 296), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Argument"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 296), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 22), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_112_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 296) -); -} - -/* Default Binary - ns=0;i=298 */ - -static UA_StatusCode function_ua_namespace0_113_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "Default Binary"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 298), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Default Binary"), -UA_NODEID_NUMERIC(ns[0], 76), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 298), UA_NODEID_NUMERIC(ns[0], 39), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7650), true); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 298), UA_NODEID_NUMERIC(ns[0], 38), UA_EXPANDEDNODEID_NUMERIC(ns[0], 296), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_113_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 298) -); -} - -/* OutputArguments - ns=0;i=11494 */ - -static UA_StatusCode function_ua_namespace0_114_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 296); - -struct { - UA_String Name; - UA_NodeId DataType; - UA_Int32 ValueRank; - UA_Int32 ArrayDimensionsSize; - UA_UInt32 *ArrayDimensions; - UA_LocalizedText Description; -} variablenode_ns_0_i_11494_Argument_0_0_struct; -UA_ExtensionObject *variablenode_ns_0_i_11494_Argument_0_0 = UA_ExtensionObject_new(); -if (!variablenode_ns_0_i_11494_Argument_0_0) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_11494_Argument_0_0_struct.Name = UA_STRING("ServerHandles"); -variablenode_ns_0_i_11494_Argument_0_0_struct.DataType = UA_NODEID_NUMERIC(ns[0], 7); -variablenode_ns_0_i_11494_Argument_0_0_struct.ValueRank = (UA_Int32) 1; -variablenode_ns_0_i_11494_Argument_0_0_struct.ArrayDimensionsSize = 1; -variablenode_ns_0_i_11494_Argument_0_0_struct.ArrayDimensions = (UA_UInt32*) UA_malloc(sizeof(UA_UInt32)); -if (!variablenode_ns_0_i_11494_Argument_0_0_struct.ArrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_11494_Argument_0_0_struct.ArrayDimensions[0] = (UA_UInt32) 0; -variablenode_ns_0_i_11494_Argument_0_0_struct.Description = UA_LOCALIZEDTEXT("", ""); -variablenode_ns_0_i_11494_Argument_0_0->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING; -variablenode_ns_0_i_11494_Argument_0_0->content.encoded.typeId = UA_NODEID_NUMERIC(0, 298); -retVal |= UA_ByteString_allocBuffer(&variablenode_ns_0_i_11494_Argument_0_0->content.encoded.body, 65000); -UA_Byte *posvariablenode_ns_0_i_11494_Argument_0_0 = variablenode_ns_0_i_11494_Argument_0_0->content.encoded.body.data; -const UA_Byte *endvariablenode_ns_0_i_11494_Argument_0_0 = &variablenode_ns_0_i_11494_Argument_0_0->content.encoded.body.data[65000]; -{ -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_0_0_struct.Name, &UA_TYPES[UA_TYPES_STRING], &posvariablenode_ns_0_i_11494_Argument_0_0, &endvariablenode_ns_0_i_11494_Argument_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_0_0_struct.DataType, &UA_TYPES[UA_TYPES_NODEID], &posvariablenode_ns_0_i_11494_Argument_0_0, &endvariablenode_ns_0_i_11494_Argument_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_0_0_struct.ValueRank, &UA_TYPES[UA_TYPES_INT32], &posvariablenode_ns_0_i_11494_Argument_0_0, &endvariablenode_ns_0_i_11494_Argument_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_0_0_struct.ArrayDimensions[0], &UA_TYPES[UA_TYPES_UINT32], &posvariablenode_ns_0_i_11494_Argument_0_0, &endvariablenode_ns_0_i_11494_Argument_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_0_0_struct.Description, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_11494_Argument_0_0, &endvariablenode_ns_0_i_11494_Argument_0_0, NULL, NULL); -} -size_t variablenode_ns_0_i_11494_Argument_0_0_encOffset = (uintptr_t)(posvariablenode_ns_0_i_11494_Argument_0_0-variablenode_ns_0_i_11494_Argument_0_0->content.encoded.body.data); -variablenode_ns_0_i_11494_Argument_0_0->content.encoded.body.length = variablenode_ns_0_i_11494_Argument_0_0_encOffset; -UA_Byte *variablenode_ns_0_i_11494_Argument_0_0_newBody = (UA_Byte *) UA_malloc(variablenode_ns_0_i_11494_Argument_0_0_encOffset); -if (!variablenode_ns_0_i_11494_Argument_0_0_newBody) return UA_STATUSCODE_BADOUTOFMEMORY; -memcpy(variablenode_ns_0_i_11494_Argument_0_0_newBody, variablenode_ns_0_i_11494_Argument_0_0->content.encoded.body.data, variablenode_ns_0_i_11494_Argument_0_0_encOffset); -UA_Byte *variablenode_ns_0_i_11494_Argument_0_0_oldBody = variablenode_ns_0_i_11494_Argument_0_0->content.encoded.body.data; -variablenode_ns_0_i_11494_Argument_0_0->content.encoded.body.data = variablenode_ns_0_i_11494_Argument_0_0_newBody; -UA_free(variablenode_ns_0_i_11494_Argument_0_0_oldBody); - - -struct { - UA_String Name; - UA_NodeId DataType; - UA_Int32 ValueRank; - UA_Int32 ArrayDimensionsSize; - UA_UInt32 *ArrayDimensions; - UA_LocalizedText Description; -} variablenode_ns_0_i_11494_Argument_1_0_struct; -UA_ExtensionObject *variablenode_ns_0_i_11494_Argument_1_0 = UA_ExtensionObject_new(); -if (!variablenode_ns_0_i_11494_Argument_1_0) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_11494_Argument_1_0_struct.Name = UA_STRING("ClientHandles"); -variablenode_ns_0_i_11494_Argument_1_0_struct.DataType = UA_NODEID_NUMERIC(ns[0], 7); -variablenode_ns_0_i_11494_Argument_1_0_struct.ValueRank = (UA_Int32) 1; -variablenode_ns_0_i_11494_Argument_1_0_struct.ArrayDimensionsSize = 1; -variablenode_ns_0_i_11494_Argument_1_0_struct.ArrayDimensions = (UA_UInt32*) UA_malloc(sizeof(UA_UInt32)); -if (!variablenode_ns_0_i_11494_Argument_1_0_struct.ArrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_11494_Argument_1_0_struct.ArrayDimensions[0] = (UA_UInt32) 0; -variablenode_ns_0_i_11494_Argument_1_0_struct.Description = UA_LOCALIZEDTEXT("", ""); -variablenode_ns_0_i_11494_Argument_1_0->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING; -variablenode_ns_0_i_11494_Argument_1_0->content.encoded.typeId = UA_NODEID_NUMERIC(0, 298); -retVal |= UA_ByteString_allocBuffer(&variablenode_ns_0_i_11494_Argument_1_0->content.encoded.body, 65000); -UA_Byte *posvariablenode_ns_0_i_11494_Argument_1_0 = variablenode_ns_0_i_11494_Argument_1_0->content.encoded.body.data; -const UA_Byte *endvariablenode_ns_0_i_11494_Argument_1_0 = &variablenode_ns_0_i_11494_Argument_1_0->content.encoded.body.data[65000]; -{ -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_1_0_struct.Name, &UA_TYPES[UA_TYPES_STRING], &posvariablenode_ns_0_i_11494_Argument_1_0, &endvariablenode_ns_0_i_11494_Argument_1_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_1_0_struct.DataType, &UA_TYPES[UA_TYPES_NODEID], &posvariablenode_ns_0_i_11494_Argument_1_0, &endvariablenode_ns_0_i_11494_Argument_1_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_1_0_struct.ValueRank, &UA_TYPES[UA_TYPES_INT32], &posvariablenode_ns_0_i_11494_Argument_1_0, &endvariablenode_ns_0_i_11494_Argument_1_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_1_0_struct.ArrayDimensions[0], &UA_TYPES[UA_TYPES_UINT32], &posvariablenode_ns_0_i_11494_Argument_1_0, &endvariablenode_ns_0_i_11494_Argument_1_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11494_Argument_1_0_struct.Description, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_11494_Argument_1_0, &endvariablenode_ns_0_i_11494_Argument_1_0, NULL, NULL); -} -size_t variablenode_ns_0_i_11494_Argument_1_0_encOffset = (uintptr_t)(posvariablenode_ns_0_i_11494_Argument_1_0-variablenode_ns_0_i_11494_Argument_1_0->content.encoded.body.data); -variablenode_ns_0_i_11494_Argument_1_0->content.encoded.body.length = variablenode_ns_0_i_11494_Argument_1_0_encOffset; -UA_Byte *variablenode_ns_0_i_11494_Argument_1_0_newBody = (UA_Byte *) UA_malloc(variablenode_ns_0_i_11494_Argument_1_0_encOffset); -if (!variablenode_ns_0_i_11494_Argument_1_0_newBody) return UA_STATUSCODE_BADOUTOFMEMORY; -memcpy(variablenode_ns_0_i_11494_Argument_1_0_newBody, variablenode_ns_0_i_11494_Argument_1_0->content.encoded.body.data, variablenode_ns_0_i_11494_Argument_1_0_encOffset); -UA_Byte *variablenode_ns_0_i_11494_Argument_1_0_oldBody = variablenode_ns_0_i_11494_Argument_1_0->content.encoded.body.data; -variablenode_ns_0_i_11494_Argument_1_0->content.encoded.body.data = variablenode_ns_0_i_11494_Argument_1_0_newBody; -UA_free(variablenode_ns_0_i_11494_Argument_1_0_oldBody); - -UA_ExtensionObject variablenode_ns_0_i_11494_variant_DataContents[2]; -variablenode_ns_0_i_11494_variant_DataContents[0] = *variablenode_ns_0_i_11494_Argument_0_0; -variablenode_ns_0_i_11494_variant_DataContents[1] = *variablenode_ns_0_i_11494_Argument_1_0; -UA_Variant_setArray(&attr.value, &variablenode_ns_0_i_11494_variant_DataContents, (UA_Int32) 2, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); -attr.displayName = UA_LOCALIZEDTEXT("", "OutputArguments"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11494), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "OutputArguments"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); - -UA_ExtensionObject_delete(variablenode_ns_0_i_11494_Argument_0_0); -UA_free(variablenode_ns_0_i_11494_Argument_0_0_struct.ArrayDimensions); - -UA_ExtensionObject_delete(variablenode_ns_0_i_11494_Argument_1_0); -UA_free(variablenode_ns_0_i_11494_Argument_1_0_struct.ArrayDimensions); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11494), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11492), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_114_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11494) -); -} - -/* InputArguments - ns=0;i=11493 */ - -static UA_StatusCode function_ua_namespace0_115_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = 1; -attr.arrayDimensionsSize = 1; -attr.arrayDimensions = (UA_UInt32 *)UA_Array_new(1, &UA_TYPES[UA_TYPES_UINT32]); -if (!attr.arrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -attr.arrayDimensions[0] = 0; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 296); - -struct { - UA_String Name; - UA_NodeId DataType; - UA_Int32 ValueRank; - UA_Int32 ArrayDimensionsSize; - UA_UInt32 *ArrayDimensions; - UA_LocalizedText Description; -} variablenode_ns_0_i_11493_Argument_0_0_struct; -UA_ExtensionObject *variablenode_ns_0_i_11493_Argument_0_0 = UA_ExtensionObject_new(); -if (!variablenode_ns_0_i_11493_Argument_0_0) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_11493_Argument_0_0_struct.Name = UA_STRING("SubscriptionId"); -variablenode_ns_0_i_11493_Argument_0_0_struct.DataType = UA_NODEID_NUMERIC(ns[0], 7); -variablenode_ns_0_i_11493_Argument_0_0_struct.ValueRank = (UA_Int32) -1; -variablenode_ns_0_i_11493_Argument_0_0_struct.ArrayDimensionsSize = 1; -variablenode_ns_0_i_11493_Argument_0_0_struct.ArrayDimensions = (UA_UInt32*) UA_malloc(sizeof(UA_UInt32)); -if (!variablenode_ns_0_i_11493_Argument_0_0_struct.ArrayDimensions) return UA_STATUSCODE_BADOUTOFMEMORY; -variablenode_ns_0_i_11493_Argument_0_0_struct.ArrayDimensions[0] = (UA_UInt32) 0; -variablenode_ns_0_i_11493_Argument_0_0_struct.Description = UA_LOCALIZEDTEXT("", ""); -variablenode_ns_0_i_11493_Argument_0_0->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING; -variablenode_ns_0_i_11493_Argument_0_0->content.encoded.typeId = UA_NODEID_NUMERIC(0, 298); -retVal |= UA_ByteString_allocBuffer(&variablenode_ns_0_i_11493_Argument_0_0->content.encoded.body, 65000); -UA_Byte *posvariablenode_ns_0_i_11493_Argument_0_0 = variablenode_ns_0_i_11493_Argument_0_0->content.encoded.body.data; -const UA_Byte *endvariablenode_ns_0_i_11493_Argument_0_0 = &variablenode_ns_0_i_11493_Argument_0_0->content.encoded.body.data[65000]; -{ -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11493_Argument_0_0_struct.Name, &UA_TYPES[UA_TYPES_STRING], &posvariablenode_ns_0_i_11493_Argument_0_0, &endvariablenode_ns_0_i_11493_Argument_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11493_Argument_0_0_struct.DataType, &UA_TYPES[UA_TYPES_NODEID], &posvariablenode_ns_0_i_11493_Argument_0_0, &endvariablenode_ns_0_i_11493_Argument_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11493_Argument_0_0_struct.ValueRank, &UA_TYPES[UA_TYPES_INT32], &posvariablenode_ns_0_i_11493_Argument_0_0, &endvariablenode_ns_0_i_11493_Argument_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11493_Argument_0_0_struct.ArrayDimensions[0], &UA_TYPES[UA_TYPES_UINT32], &posvariablenode_ns_0_i_11493_Argument_0_0, &endvariablenode_ns_0_i_11493_Argument_0_0, NULL, NULL); -retVal |= UA_encodeBinary(&variablenode_ns_0_i_11493_Argument_0_0_struct.Description, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT], &posvariablenode_ns_0_i_11493_Argument_0_0, &endvariablenode_ns_0_i_11493_Argument_0_0, NULL, NULL); -} -size_t variablenode_ns_0_i_11493_Argument_0_0_encOffset = (uintptr_t)(posvariablenode_ns_0_i_11493_Argument_0_0-variablenode_ns_0_i_11493_Argument_0_0->content.encoded.body.data); -variablenode_ns_0_i_11493_Argument_0_0->content.encoded.body.length = variablenode_ns_0_i_11493_Argument_0_0_encOffset; -UA_Byte *variablenode_ns_0_i_11493_Argument_0_0_newBody = (UA_Byte *) UA_malloc(variablenode_ns_0_i_11493_Argument_0_0_encOffset); -if (!variablenode_ns_0_i_11493_Argument_0_0_newBody) return UA_STATUSCODE_BADOUTOFMEMORY; -memcpy(variablenode_ns_0_i_11493_Argument_0_0_newBody, variablenode_ns_0_i_11493_Argument_0_0->content.encoded.body.data, variablenode_ns_0_i_11493_Argument_0_0_encOffset); -UA_Byte *variablenode_ns_0_i_11493_Argument_0_0_oldBody = variablenode_ns_0_i_11493_Argument_0_0->content.encoded.body.data; -variablenode_ns_0_i_11493_Argument_0_0->content.encoded.body.data = variablenode_ns_0_i_11493_Argument_0_0_newBody; -UA_free(variablenode_ns_0_i_11493_Argument_0_0_oldBody); - -UA_ExtensionObject variablenode_ns_0_i_11493_variant_DataContents[1]; -variablenode_ns_0_i_11493_variant_DataContents[0] = *variablenode_ns_0_i_11493_Argument_0_0; -UA_Variant_setArray(&attr.value, &variablenode_ns_0_i_11493_variant_DataContents, (UA_Int32) 1, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); -attr.displayName = UA_LOCALIZEDTEXT("", "InputArguments"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 11493), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "InputArguments"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -UA_Array_delete(attr.arrayDimensions, 1, &UA_TYPES[UA_TYPES_UINT32]); - -UA_ExtensionObject_delete(variablenode_ns_0_i_11493_Argument_0_0); -UA_free(variablenode_ns_0_i_11493_Argument_0_0_struct.ArrayDimensions); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11493), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 11492), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_115_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 11493) -); -} - -/* Default XML - ns=0;i=3063 */ - -static UA_StatusCode function_ua_namespace0_116_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "Default XML"); -attr.description = UA_LOCALIZEDTEXT("", "The default XML encoding for a data type."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 3063), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Default XML"), -UA_NODEID_NUMERIC(ns[0], 58), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_116_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 3063) -); -} - -/* Default Binary - ns=0;i=3062 */ - -static UA_StatusCode function_ua_namespace0_117_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "Default Binary"); -attr.description = UA_LOCALIZEDTEXT("", "The default binary encoding for a data type."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 3062), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "Default Binary"), -UA_NODEID_NUMERIC(ns[0], 58), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_117_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 3062) -); -} - -/* ServerDiagnosticsType - ns=0;i=2020 */ - -static UA_StatusCode function_ua_namespace0_118_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnosticsType"); -attr.description = UA_LOCALIZEDTEXT("", "The diagnostics information for a server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, -UA_NODEID_NUMERIC(ns[0], 2020), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerDiagnosticsType"), -UA_NODEID_NULL, -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2020), UA_NODEID_NUMERIC(ns[0], 45), UA_EXPANDEDNODEID_NUMERIC(ns[0], 58), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_118_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2020) -); -} - -/* ServerDiagnostics - ns=0;i=2274 */ - -static UA_StatusCode function_ua_namespace0_119_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_ObjectAttributes attr = UA_ObjectAttributes_default; -attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnostics"); -attr.description = UA_LOCALIZEDTEXT("", "Reports diagnostics about the server."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, -UA_NODEID_NUMERIC(ns[0], 2274), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerDiagnostics"), -UA_NODEID_NUMERIC(ns[0], 2020), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2274), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2253), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_119_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2274) -); -} - -/* ServerDiagnosticsSummary - ns=0;i=2275 */ - -static UA_StatusCode function_ua_namespace0_120_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 859); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_SERVERDIAGNOSTICSSUMMARYDATATYPE]); -attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnosticsSummary"); -attr.description = UA_LOCALIZEDTEXT("", "A summary of server level diagnostics."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2275), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerDiagnosticsSummary"), -UA_NODEID_NUMERIC(ns[0], 2150), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2275), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2274), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_120_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2275) -); -} - -/* SecurityRejectedRequestsCount - ns=0;i=2287 */ - -static UA_StatusCode function_ua_namespace0_121_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SecurityRejectedRequestsCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2287), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SecurityRejectedRequestsCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2287), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_121_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2287) -); -} - -/* CumulatedSubscriptionCount - ns=0;i=2286 */ - -static UA_StatusCode function_ua_namespace0_122_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "CumulatedSubscriptionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2286), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CumulatedSubscriptionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2286), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_122_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2286) -); -} - -/* CurrentSubscriptionCount - ns=0;i=2285 */ - -static UA_StatusCode function_ua_namespace0_123_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "CurrentSubscriptionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2285), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CurrentSubscriptionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2285), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_123_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2285) -); -} - -/* PublishingIntervalCount - ns=0;i=2284 */ - -static UA_StatusCode function_ua_namespace0_124_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "PublishingIntervalCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2284), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "PublishingIntervalCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2284), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_124_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2284) -); -} - -/* SessionAbortCount - ns=0;i=2282 */ - -static UA_StatusCode function_ua_namespace0_125_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SessionAbortCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2282), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SessionAbortCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2282), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_125_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2282) -); -} - -/* SessionTimeoutCount - ns=0;i=2281 */ - -static UA_StatusCode function_ua_namespace0_126_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SessionTimeoutCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2281), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SessionTimeoutCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2281), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_126_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2281) -); -} - -/* RejectedSessionCount - ns=0;i=3705 */ - -static UA_StatusCode function_ua_namespace0_127_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "RejectedSessionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 3705), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "RejectedSessionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 3705), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_127_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 3705) -); -} - -/* RejectedRequestsCount - ns=0;i=2288 */ - -static UA_StatusCode function_ua_namespace0_128_begin(UA_Server *server, UA_UInt16* ns) { - -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "RejectedRequestsCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2288), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "RejectedRequestsCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2288), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} - -static UA_StatusCode function_ua_namespace0_128_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2288) -); -} + /* ServerCapabilities - HistoryServerCapabilities - DeleteAtTimeDataCapability */ + retVal |= writeNs0Variable(server, UA_NS0ID_HISTORYSERVERCAPABILITIES_DELETEATTIMECAPABILITY, + &server->config.deleteAtTimeDataCapability, &UA_TYPES[UA_TYPES_BOOLEAN]); +#endif -/* ServerViewCount - ns=0;i=2276 */ +#if defined(UA_ENABLE_METHODCALLS) && defined(UA_ENABLE_SUBSCRIPTIONS) + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_GETMONITOREDITEMS), readMonitoredItems); +#endif -static UA_StatusCode function_ua_namespace0_129_begin(UA_Server *server, UA_UInt16* ns) { + /* The HasComponent references to the ModellingRules are not part of the + * Nodeset2.xml. So we add the references manually. */ + addModellingRules(server); + +#endif /* UA_GENERATED_NAMESPACE_ZERO */ + + /* create the OverFlowEventType + * The EventQueueOverflowEventType is defined as abstract, therefore we can not create an instance of that type + * directly, but need to create a subtype. This is already posted on the OPC Foundation bug tracker under the + * following link for clarification: https://opcfoundation-onlineapplications.org/mantis/view.php?id=4206 */ +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + UA_ObjectTypeAttributes overflowAttr = UA_ObjectTypeAttributes_default; + overflowAttr.description = UA_LOCALIZEDTEXT("en-US", "A simple event for indicating a queue overflow."); + overflowAttr.displayName = UA_LOCALIZEDTEXT("en-US", "SimpleOverflowEventType"); + retVal |= UA_Server_addObjectTypeNode(server, UA_NODEID_NUMERIC(0, UA_NS0ID_SIMPLEOVERFLOWEVENTTYPE), + UA_NODEID_NUMERIC(0, UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE), + UA_QUALIFIEDNAME(0, "SimpleOverflowEventType"), + overflowAttr, NULL, NULL); +#endif -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "ServerViewCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2276), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "ServerViewCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2276), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; + if(retVal != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Initialization of Namespace 0 (after bootstrapping) " + "failed with %s. See previous outputs for any error messages.", + UA_StatusCode_name(retVal)); + return UA_STATUSCODE_BADINTERNALERROR; + } + return UA_STATUSCODE_GOOD; } -static UA_StatusCode function_ua_namespace0_129_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2276) -); -} +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_server_config.c" ***********************************/ -/* CurrentSessionCount - ns=0;i=2277 */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + */ -static UA_StatusCode function_ua_namespace0_130_begin(UA_Server *server, UA_UInt16* ns) { -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "CurrentSessionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2277), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CurrentSessionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2277), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} +void +UA_ServerConfig_clean(UA_ServerConfig *config) { + if(!config) + return; -static UA_StatusCode function_ua_namespace0_130_finish(UA_Server *server, UA_UInt16* ns) { + /* Server Description */ + UA_BuildInfo_deleteMembers(&config->buildInfo); + UA_ApplicationDescription_deleteMembers(&config->applicationDescription); +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + UA_MdnsDiscoveryConfiguration_clear(&config->discovery.mdns); + UA_String_clear(&config->discovery.mdnsInterfaceIP); +#endif -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2277) -); -} + /* Custom DataTypes */ + /* nothing to do */ -/* CumulatedSessionCount - ns=0;i=2278 */ + /* Networking */ + for(size_t i = 0; i < config->networkLayersSize; ++i) + config->networkLayers[i].deleteMembers(&config->networkLayers[i]); + UA_free(config->networkLayers); + config->networkLayers = NULL; + config->networkLayersSize = 0; + UA_String_deleteMembers(&config->customHostname); + config->customHostname = UA_STRING_NULL; -static UA_StatusCode function_ua_namespace0_131_begin(UA_Server *server, UA_UInt16* ns) { + for(size_t i = 0; i < config->securityPoliciesSize; ++i) { + UA_SecurityPolicy *policy = &config->securityPolicies[i]; + policy->deleteMembers(policy); + } + UA_free(config->securityPolicies); + config->securityPolicies = NULL; + config->securityPoliciesSize = 0; -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "CumulatedSessionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2278), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "CumulatedSessionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2278), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; -} + for(size_t i = 0; i < config->endpointsSize; ++i) + UA_EndpointDescription_deleteMembers(&config->endpoints[i]); -static UA_StatusCode function_ua_namespace0_131_finish(UA_Server *server, UA_UInt16* ns) { + UA_free(config->endpoints); + config->endpoints = NULL; + config->endpointsSize = 0; -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2278) -); -} + /* Certificate Validation */ + if(config->certificateVerification.deleteMembers) + config->certificateVerification.deleteMembers(&config->certificateVerification); -/* SecurityRejectedSessionCount - ns=0;i=2279 */ + /* Access Control */ + if(config->accessControl.deleteMembers) + config->accessControl.deleteMembers(&config->accessControl); -static UA_StatusCode function_ua_namespace0_132_begin(UA_Server *server, UA_UInt16* ns) { + /* Historical data */ +#ifdef UA_ENABLE_HISTORIZING + if(config->historyDatabase.deleteMembers) + config->historyDatabase.deleteMembers(&config->historyDatabase); +#endif -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 1; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_UINT32]); -attr.displayName = UA_LOCALIZEDTEXT("", "SecurityRejectedSessionCount"); -attr.description = UA_LOCALIZEDTEXT("", ""); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2279), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "SecurityRejectedSessionCount"), -UA_NODEID_NUMERIC(ns[0], 63), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2279), UA_NODEID_NUMERIC(ns[0], 47), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2275), false); -return retVal; + /* Logger */ + if(config->logger.clear) + config->logger.clear(config->logger.context); } -static UA_StatusCode function_ua_namespace0_132_finish(UA_Server *server, UA_UInt16* ns) { - -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2279) -); +void +UA_ServerConfig_setCustomHostname(UA_ServerConfig *config, + const UA_String customHostname) { + if(!config) + return; + UA_String_deleteMembers(&config->customHostname); + UA_String_copy(&customHostname, &config->customHostname); } -/* EnabledFlag - ns=0;i=2294 */ - -static UA_StatusCode function_ua_namespace0_133_begin(UA_Server *server, UA_UInt16* ns) { +#ifdef UA_ENABLE_PUBSUB +/* Add a pubsubTransportLayer to the configuration. Memory is reallocated on + * demand. */ +UA_StatusCode +UA_ServerConfig_addPubSubTransportLayer(UA_ServerConfig *config, + UA_PubSubTransportLayer *pubsubTransportLayer) { -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -UA_VariableAttributes attr = UA_VariableAttributes_default; -attr.minimumSamplingInterval = 0.000000; -attr.userAccessLevel = 1; -attr.accessLevel = 3; -attr.valueRank = -1; -attr.dataType = UA_NODEID_NUMERIC(ns[0], 1); -UA_Variant_setScalar(&attr.value, NULL, &UA_TYPES[UA_TYPES_BOOLEAN]); -attr.displayName = UA_LOCALIZEDTEXT("", "EnabledFlag"); -attr.description = UA_LOCALIZEDTEXT("", "If TRUE the diagnostics collection is enabled."); -attr.writeMask = 0; -attr.userWriteMask = 0; -retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, -UA_NODEID_NUMERIC(ns[0], 2294), -UA_NODEID_NUMERIC(ns[0], 0), -UA_NODEID_NUMERIC(ns[0], 0), -UA_QUALIFIEDNAME(ns[0], "EnabledFlag"), -UA_NODEID_NUMERIC(ns[0], 68), -(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2294), UA_NODEID_NUMERIC(ns[0], 46), UA_EXPANDEDNODEID_NUMERIC(ns[0], 2274), false); -return retVal; -} + if(config->pubsubTransportLayersSize == 0) { + config->pubsubTransportLayers = (UA_PubSubTransportLayer *) + UA_malloc(sizeof(UA_PubSubTransportLayer)); + } else { + config->pubsubTransportLayers = (UA_PubSubTransportLayer*) + UA_realloc(config->pubsubTransportLayers, + sizeof(UA_PubSubTransportLayer) * (config->pubsubTransportLayersSize + 1)); + } -static UA_StatusCode function_ua_namespace0_133_finish(UA_Server *server, UA_UInt16* ns) { + if(config->pubsubTransportLayers == NULL) + return UA_STATUSCODE_BADOUTOFMEMORY; -return UA_Server_addNode_finish(server, -UA_NODEID_NUMERIC(ns[0], 2294) -); -} + memcpy(&config->pubsubTransportLayers[config->pubsubTransportLayersSize], + pubsubTransportLayer, sizeof(UA_PubSubTransportLayer)); + config->pubsubTransportLayersSize++; -UA_StatusCode ua_namespace0(UA_Server *server) { -UA_StatusCode retVal = UA_STATUSCODE_GOOD; -/* Use namespace ids generated by the server */ -UA_UInt16 ns[1]; -ns[0] = UA_Server_addNamespace(server, "http://opcfoundation.org/UA/"); -retVal |= function_ua_namespace0_0_begin(server, ns); -retVal |= function_ua_namespace0_1_begin(server, ns); -retVal |= function_ua_namespace0_2_begin(server, ns); -retVal |= function_ua_namespace0_3_begin(server, ns); -retVal |= function_ua_namespace0_4_begin(server, ns); -retVal |= function_ua_namespace0_5_begin(server, ns); -retVal |= function_ua_namespace0_6_begin(server, ns); -retVal |= function_ua_namespace0_7_begin(server, ns); -retVal |= function_ua_namespace0_8_begin(server, ns); -retVal |= function_ua_namespace0_9_begin(server, ns); -retVal |= function_ua_namespace0_10_begin(server, ns); -retVal |= function_ua_namespace0_11_begin(server, ns); -retVal |= function_ua_namespace0_12_begin(server, ns); -retVal |= function_ua_namespace0_13_begin(server, ns); -retVal |= function_ua_namespace0_14_begin(server, ns); -retVal |= function_ua_namespace0_15_begin(server, ns); -retVal |= function_ua_namespace0_16_begin(server, ns); -retVal |= function_ua_namespace0_17_begin(server, ns); -retVal |= function_ua_namespace0_18_begin(server, ns); -retVal |= function_ua_namespace0_19_begin(server, ns); -retVal |= function_ua_namespace0_20_begin(server, ns); -retVal |= function_ua_namespace0_21_begin(server, ns); -retVal |= function_ua_namespace0_22_begin(server, ns); -retVal |= function_ua_namespace0_23_begin(server, ns); -retVal |= function_ua_namespace0_24_begin(server, ns); -retVal |= function_ua_namespace0_25_begin(server, ns); -retVal |= function_ua_namespace0_26_begin(server, ns); -retVal |= function_ua_namespace0_27_begin(server, ns); -retVal |= function_ua_namespace0_28_begin(server, ns); -retVal |= function_ua_namespace0_29_begin(server, ns); -retVal |= function_ua_namespace0_30_begin(server, ns); -retVal |= function_ua_namespace0_31_begin(server, ns); -retVal |= function_ua_namespace0_32_begin(server, ns); -retVal |= function_ua_namespace0_33_begin(server, ns); -retVal |= function_ua_namespace0_34_begin(server, ns); -retVal |= function_ua_namespace0_35_begin(server, ns); -retVal |= function_ua_namespace0_36_begin(server, ns); -retVal |= function_ua_namespace0_37_begin(server, ns); -retVal |= function_ua_namespace0_38_begin(server, ns); -retVal |= function_ua_namespace0_39_begin(server, ns); -retVal |= function_ua_namespace0_40_begin(server, ns); -retVal |= function_ua_namespace0_41_begin(server, ns); -retVal |= function_ua_namespace0_42_begin(server, ns); -retVal |= function_ua_namespace0_43_begin(server, ns); -retVal |= function_ua_namespace0_44_begin(server, ns); -retVal |= function_ua_namespace0_45_begin(server, ns); -retVal |= function_ua_namespace0_46_begin(server, ns); -retVal |= function_ua_namespace0_47_begin(server, ns); -retVal |= function_ua_namespace0_48_begin(server, ns); -retVal |= function_ua_namespace0_49_begin(server, ns); -retVal |= function_ua_namespace0_50_begin(server, ns); -retVal |= function_ua_namespace0_51_begin(server, ns); -retVal |= function_ua_namespace0_52_begin(server, ns); -retVal |= function_ua_namespace0_53_begin(server, ns); -retVal |= function_ua_namespace0_54_begin(server, ns); -retVal |= function_ua_namespace0_55_begin(server, ns); -retVal |= function_ua_namespace0_56_begin(server, ns); -retVal |= function_ua_namespace0_57_begin(server, ns); -retVal |= function_ua_namespace0_58_begin(server, ns); -retVal |= function_ua_namespace0_59_begin(server, ns); -retVal |= function_ua_namespace0_60_begin(server, ns); -retVal |= function_ua_namespace0_61_begin(server, ns); -retVal |= function_ua_namespace0_62_begin(server, ns); -retVal |= function_ua_namespace0_63_begin(server, ns); -retVal |= function_ua_namespace0_64_begin(server, ns); -retVal |= function_ua_namespace0_65_begin(server, ns); -retVal |= function_ua_namespace0_66_begin(server, ns); -retVal |= function_ua_namespace0_67_begin(server, ns); -retVal |= function_ua_namespace0_68_begin(server, ns); -retVal |= function_ua_namespace0_69_begin(server, ns); -retVal |= function_ua_namespace0_70_begin(server, ns); -retVal |= function_ua_namespace0_71_begin(server, ns); -retVal |= function_ua_namespace0_72_begin(server, ns); -retVal |= function_ua_namespace0_73_begin(server, ns); -retVal |= function_ua_namespace0_74_begin(server, ns); -retVal |= function_ua_namespace0_75_begin(server, ns); -retVal |= function_ua_namespace0_76_begin(server, ns); -retVal |= function_ua_namespace0_77_begin(server, ns); -retVal |= function_ua_namespace0_78_begin(server, ns); -retVal |= function_ua_namespace0_79_begin(server, ns); -retVal |= function_ua_namespace0_80_begin(server, ns); -retVal |= function_ua_namespace0_81_begin(server, ns); -retVal |= function_ua_namespace0_82_begin(server, ns); -retVal |= function_ua_namespace0_83_begin(server, ns); -retVal |= function_ua_namespace0_84_begin(server, ns); -retVal |= function_ua_namespace0_85_begin(server, ns); -retVal |= function_ua_namespace0_86_begin(server, ns); -retVal |= function_ua_namespace0_87_begin(server, ns); -retVal |= function_ua_namespace0_88_begin(server, ns); -retVal |= function_ua_namespace0_89_begin(server, ns); -retVal |= function_ua_namespace0_90_begin(server, ns); -retVal |= function_ua_namespace0_91_begin(server, ns); -retVal |= function_ua_namespace0_92_begin(server, ns); -retVal |= function_ua_namespace0_93_begin(server, ns); -retVal |= function_ua_namespace0_94_begin(server, ns); -retVal |= function_ua_namespace0_95_begin(server, ns); -retVal |= function_ua_namespace0_96_begin(server, ns); -retVal |= function_ua_namespace0_97_begin(server, ns); -retVal |= function_ua_namespace0_98_begin(server, ns); -retVal |= function_ua_namespace0_99_begin(server, ns); -retVal |= function_ua_namespace0_100_begin(server, ns); -retVal |= function_ua_namespace0_101_begin(server, ns); -retVal |= function_ua_namespace0_102_begin(server, ns); -retVal |= function_ua_namespace0_103_begin(server, ns); -retVal |= function_ua_namespace0_104_begin(server, ns); -retVal |= function_ua_namespace0_105_begin(server, ns); -retVal |= function_ua_namespace0_106_begin(server, ns); -retVal |= function_ua_namespace0_107_begin(server, ns); -retVal |= function_ua_namespace0_108_begin(server, ns); -retVal |= function_ua_namespace0_109_begin(server, ns); -retVal |= function_ua_namespace0_110_begin(server, ns); -retVal |= function_ua_namespace0_111_begin(server, ns); -retVal |= function_ua_namespace0_112_begin(server, ns); -retVal |= function_ua_namespace0_113_begin(server, ns); -retVal |= function_ua_namespace0_114_begin(server, ns); -retVal |= function_ua_namespace0_115_begin(server, ns); -retVal |= function_ua_namespace0_116_begin(server, ns); -retVal |= function_ua_namespace0_117_begin(server, ns); -retVal |= function_ua_namespace0_118_begin(server, ns); -retVal |= function_ua_namespace0_119_begin(server, ns); -retVal |= function_ua_namespace0_120_begin(server, ns); -retVal |= function_ua_namespace0_121_begin(server, ns); -retVal |= function_ua_namespace0_122_begin(server, ns); -retVal |= function_ua_namespace0_123_begin(server, ns); -retVal |= function_ua_namespace0_124_begin(server, ns); -retVal |= function_ua_namespace0_125_begin(server, ns); -retVal |= function_ua_namespace0_126_begin(server, ns); -retVal |= function_ua_namespace0_127_begin(server, ns); -retVal |= function_ua_namespace0_128_begin(server, ns); -retVal |= function_ua_namespace0_129_begin(server, ns); -retVal |= function_ua_namespace0_130_begin(server, ns); -retVal |= function_ua_namespace0_131_begin(server, ns); -retVal |= function_ua_namespace0_132_begin(server, ns); -retVal |= function_ua_namespace0_133_begin(server, ns); -retVal |= function_ua_namespace0_133_finish(server, ns); -retVal |= function_ua_namespace0_132_finish(server, ns); -retVal |= function_ua_namespace0_131_finish(server, ns); -retVal |= function_ua_namespace0_130_finish(server, ns); -retVal |= function_ua_namespace0_129_finish(server, ns); -retVal |= function_ua_namespace0_128_finish(server, ns); -retVal |= function_ua_namespace0_127_finish(server, ns); -retVal |= function_ua_namespace0_126_finish(server, ns); -retVal |= function_ua_namespace0_125_finish(server, ns); -retVal |= function_ua_namespace0_124_finish(server, ns); -retVal |= function_ua_namespace0_123_finish(server, ns); -retVal |= function_ua_namespace0_122_finish(server, ns); -retVal |= function_ua_namespace0_121_finish(server, ns); -retVal |= function_ua_namespace0_120_finish(server, ns); -retVal |= function_ua_namespace0_119_finish(server, ns); -retVal |= function_ua_namespace0_118_finish(server, ns); -retVal |= function_ua_namespace0_117_finish(server, ns); -retVal |= function_ua_namespace0_116_finish(server, ns); -retVal |= function_ua_namespace0_115_finish(server, ns); -retVal |= function_ua_namespace0_114_finish(server, ns); -retVal |= function_ua_namespace0_113_finish(server, ns); -retVal |= function_ua_namespace0_112_finish(server, ns); -retVal |= function_ua_namespace0_111_finish(server, ns); -retVal |= function_ua_namespace0_110_finish(server, ns); -retVal |= function_ua_namespace0_109_finish(server, ns); -retVal |= function_ua_namespace0_108_finish(server, ns); -retVal |= function_ua_namespace0_107_finish(server, ns); -retVal |= function_ua_namespace0_106_finish(server, ns); -retVal |= function_ua_namespace0_105_finish(server, ns); -retVal |= function_ua_namespace0_104_finish(server, ns); -retVal |= function_ua_namespace0_103_finish(server, ns); -retVal |= function_ua_namespace0_102_finish(server, ns); -retVal |= function_ua_namespace0_101_finish(server, ns); -retVal |= function_ua_namespace0_100_finish(server, ns); -retVal |= function_ua_namespace0_99_finish(server, ns); -retVal |= function_ua_namespace0_98_finish(server, ns); -retVal |= function_ua_namespace0_97_finish(server, ns); -retVal |= function_ua_namespace0_96_finish(server, ns); -retVal |= function_ua_namespace0_95_finish(server, ns); -retVal |= function_ua_namespace0_94_finish(server, ns); -retVal |= function_ua_namespace0_93_finish(server, ns); -retVal |= function_ua_namespace0_92_finish(server, ns); -retVal |= function_ua_namespace0_91_finish(server, ns); -retVal |= function_ua_namespace0_90_finish(server, ns); -retVal |= function_ua_namespace0_89_finish(server, ns); -retVal |= function_ua_namespace0_88_finish(server, ns); -retVal |= function_ua_namespace0_87_finish(server, ns); -retVal |= function_ua_namespace0_86_finish(server, ns); -retVal |= function_ua_namespace0_85_finish(server, ns); -retVal |= function_ua_namespace0_84_finish(server, ns); -retVal |= function_ua_namespace0_83_finish(server, ns); -retVal |= function_ua_namespace0_82_finish(server, ns); -retVal |= function_ua_namespace0_81_finish(server, ns); -retVal |= function_ua_namespace0_80_finish(server, ns); -retVal |= function_ua_namespace0_79_finish(server, ns); -retVal |= function_ua_namespace0_78_finish(server, ns); -retVal |= function_ua_namespace0_77_finish(server, ns); -retVal |= function_ua_namespace0_76_finish(server, ns); -retVal |= function_ua_namespace0_75_finish(server, ns); -retVal |= function_ua_namespace0_74_finish(server, ns); -retVal |= function_ua_namespace0_73_finish(server, ns); -retVal |= function_ua_namespace0_72_finish(server, ns); -retVal |= function_ua_namespace0_71_finish(server, ns); -retVal |= function_ua_namespace0_70_finish(server, ns); -retVal |= function_ua_namespace0_69_finish(server, ns); -retVal |= function_ua_namespace0_68_finish(server, ns); -retVal |= function_ua_namespace0_67_finish(server, ns); -retVal |= function_ua_namespace0_66_finish(server, ns); -retVal |= function_ua_namespace0_65_finish(server, ns); -retVal |= function_ua_namespace0_64_finish(server, ns); -retVal |= function_ua_namespace0_63_finish(server, ns); -retVal |= function_ua_namespace0_62_finish(server, ns); -retVal |= function_ua_namespace0_61_finish(server, ns); -retVal |= function_ua_namespace0_60_finish(server, ns); -retVal |= function_ua_namespace0_59_finish(server, ns); -retVal |= function_ua_namespace0_58_finish(server, ns); -retVal |= function_ua_namespace0_57_finish(server, ns); -retVal |= function_ua_namespace0_56_finish(server, ns); -retVal |= function_ua_namespace0_55_finish(server, ns); -retVal |= function_ua_namespace0_54_finish(server, ns); -retVal |= function_ua_namespace0_53_finish(server, ns); -retVal |= function_ua_namespace0_52_finish(server, ns); -retVal |= function_ua_namespace0_51_finish(server, ns); -retVal |= function_ua_namespace0_50_finish(server, ns); -retVal |= function_ua_namespace0_49_finish(server, ns); -retVal |= function_ua_namespace0_48_finish(server, ns); -retVal |= function_ua_namespace0_47_finish(server, ns); -retVal |= function_ua_namespace0_46_finish(server, ns); -retVal |= function_ua_namespace0_45_finish(server, ns); -retVal |= function_ua_namespace0_44_finish(server, ns); -retVal |= function_ua_namespace0_43_finish(server, ns); -retVal |= function_ua_namespace0_42_finish(server, ns); -retVal |= function_ua_namespace0_41_finish(server, ns); -retVal |= function_ua_namespace0_40_finish(server, ns); -retVal |= function_ua_namespace0_39_finish(server, ns); -retVal |= function_ua_namespace0_38_finish(server, ns); -retVal |= function_ua_namespace0_37_finish(server, ns); -retVal |= function_ua_namespace0_36_finish(server, ns); -retVal |= function_ua_namespace0_35_finish(server, ns); -retVal |= function_ua_namespace0_34_finish(server, ns); -retVal |= function_ua_namespace0_33_finish(server, ns); -retVal |= function_ua_namespace0_32_finish(server, ns); -retVal |= function_ua_namespace0_31_finish(server, ns); -retVal |= function_ua_namespace0_30_finish(server, ns); -retVal |= function_ua_namespace0_29_finish(server, ns); -retVal |= function_ua_namespace0_28_finish(server, ns); -retVal |= function_ua_namespace0_27_finish(server, ns); -retVal |= function_ua_namespace0_26_finish(server, ns); -retVal |= function_ua_namespace0_25_finish(server, ns); -retVal |= function_ua_namespace0_24_finish(server, ns); -retVal |= function_ua_namespace0_23_finish(server, ns); -retVal |= function_ua_namespace0_22_finish(server, ns); -retVal |= function_ua_namespace0_21_finish(server, ns); -retVal |= function_ua_namespace0_20_finish(server, ns); -retVal |= function_ua_namespace0_19_finish(server, ns); -retVal |= function_ua_namespace0_18_finish(server, ns); -retVal |= function_ua_namespace0_17_finish(server, ns); -retVal |= function_ua_namespace0_16_finish(server, ns); -retVal |= function_ua_namespace0_15_finish(server, ns); -retVal |= function_ua_namespace0_14_finish(server, ns); -retVal |= function_ua_namespace0_13_finish(server, ns); -retVal |= function_ua_namespace0_12_finish(server, ns); -retVal |= function_ua_namespace0_11_finish(server, ns); -retVal |= function_ua_namespace0_10_finish(server, ns); -retVal |= function_ua_namespace0_9_finish(server, ns); -retVal |= function_ua_namespace0_8_finish(server, ns); -retVal |= function_ua_namespace0_7_finish(server, ns); -retVal |= function_ua_namespace0_6_finish(server, ns); -retVal |= function_ua_namespace0_5_finish(server, ns); -retVal |= function_ua_namespace0_4_finish(server, ns); -retVal |= function_ua_namespace0_3_finish(server, ns); -retVal |= function_ua_namespace0_2_finish(server, ns); -retVal |= function_ua_namespace0_1_finish(server, ns); -retVal |= function_ua_namespace0_0_finish(server, ns); -return retVal; + return UA_STATUSCODE_GOOD; } +#endif /* UA_ENABLE_PUBSUB */ /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_server_binary.c" ***********************************/ @@ -25879,7 +23043,7 @@ return retVal; * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2016 (c) Sten Grüner * Copyright 2014-2015, 2017 (c) Florian Palm * Copyright 2015-2016 (c) Chris Iatrou @@ -25889,62 +23053,68 @@ return retVal; * Copyright 2016 (c) TorbenD * Copyright 2017 (c) frax2222 * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2019 (c) Kalycito Infotech Private Limited */ + #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION // store the authentication token and session ID so we can help fuzzing by setting // these values in the next request automatically -UA_NodeId unsafe_fuzz_authenticationToken = { - 0, UA_NODEIDTYPE_NUMERIC, {0} -}; +UA_NodeId unsafe_fuzz_authenticationToken = {0, UA_NODEIDTYPE_NUMERIC, {0}}; #endif #ifdef UA_DEBUG_DUMP_PKGS_FILE -void UA_debug_dumpCompleteChunk(UA_Server *const server, UA_Connection *const connection, UA_ByteString *messageBuffer); +void UA_debug_dumpCompleteChunk(UA_Server *const server, UA_Connection *const connection, + UA_ByteString *messageBuffer); #endif /********************/ /* Helper Functions */ /********************/ - /* This is not an ERR message, the connection is not closed afterwards */ static UA_StatusCode -sendServiceFault(UA_SecureChannel *channel, const UA_ByteString *msg, - size_t offset, const UA_DataType *responseType, - UA_UInt32 requestId, UA_StatusCode error) { - UA_RequestHeader requestHeader; - UA_StatusCode retval = UA_RequestHeader_decodeBinary(msg, &offset, &requestHeader); - if(retval != UA_STATUSCODE_GOOD) - return retval; +sendServiceFaultWithRequest(UA_SecureChannel *channel, + const UA_RequestHeader *requestHeader, + const UA_DataType *responseType, + UA_UInt32 requestId, UA_StatusCode error) { UA_STACKARRAY(UA_Byte, response, responseType->memSize); UA_init(response, responseType); UA_ResponseHeader *responseHeader = (UA_ResponseHeader*)response; - responseHeader->requestHandle = requestHeader.requestHandle; + responseHeader->requestHandle = requestHeader->requestHandle; responseHeader->timestamp = UA_DateTime_now(); responseHeader->serviceResult = error; - // Send error message. Message type is MSG and not ERR, since we are on a securechannel! - retval = UA_SecureChannel_sendSymmetricMessage(channel, requestId, UA_MESSAGETYPE_MSG, - response, responseType); + /* Send error message. Message type is MSG and not ERR, since we are on a + * SecureChannel! */ + UA_StatusCode retval = + UA_SecureChannel_sendSymmetricMessage(channel, requestId, UA_MESSAGETYPE_MSG, + response, responseType); - UA_RequestHeader_deleteMembers(&requestHeader); UA_LOG_DEBUG(channel->securityPolicy->logger, UA_LOGCATEGORY_SERVER, "Sent ServiceFault with error code %s", UA_StatusCode_name(error)); return retval; } -typedef enum { - UA_SERVICETYPE_NORMAL, - UA_SERVICETYPE_INSITU, - UA_SERVICETYPE_CUSTOM -} UA_ServiceType; + /* This is not an ERR message, the connection is not closed afterwards */ +static UA_StatusCode +sendServiceFault(UA_SecureChannel *channel, const UA_ByteString *msg, + size_t offset, const UA_DataType *responseType, + UA_UInt32 requestId, UA_StatusCode error) { + UA_RequestHeader requestHeader; + UA_StatusCode retval = UA_RequestHeader_decodeBinary(msg, &offset, &requestHeader); + if(retval != UA_STATUSCODE_GOOD) + return retval; + retval = sendServiceFaultWithRequest(channel, &requestHeader, responseType, + requestId, error); + UA_RequestHeader_deleteMembers(&requestHeader); + return retval; +} static void getServicePointers(UA_UInt32 requestTypeId, const UA_DataType **requestType, const UA_DataType **responseType, UA_Service *service, - UA_InSituService *serviceInsitu, - UA_Boolean *requiresSession, UA_ServiceType *serviceType) { + UA_Boolean *requiresSession) { switch(requestTypeId) { case UA_NS0ID_GETENDPOINTSREQUEST_ENCODING_DEFAULTBINARY: *service = (UA_Service)Service_GetEndpoints; @@ -25985,13 +23155,11 @@ getServicePointers(UA_UInt32 requestTypeId, const UA_DataType **requestType, *requestType = &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]; *responseType = &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]; *requiresSession = false; - *serviceType = UA_SERVICETYPE_CUSTOM; break; case UA_NS0ID_ACTIVATESESSIONREQUEST_ENCODING_DEFAULTBINARY: *service = NULL; //(UA_Service)Service_ActivateSession; *requestType = &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]; *responseType = &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]; - *serviceType = UA_SERVICETYPE_CUSTOM; break; case UA_NS0ID_CLOSESESSIONREQUEST_ENCODING_DEFAULTBINARY: *service = (UA_Service)Service_CloseSession; @@ -26000,10 +23168,9 @@ getServicePointers(UA_UInt32 requestTypeId, const UA_DataType **requestType, break; case UA_NS0ID_READREQUEST_ENCODING_DEFAULTBINARY: *service = NULL; - *serviceInsitu = (UA_InSituService)Service_Read; + *service = (UA_Service)Service_Read; *requestType = &UA_TYPES[UA_TYPES_READREQUEST]; *responseType = &UA_TYPES[UA_TYPES_READRESPONSE]; - *serviceType = UA_SERVICETYPE_INSITU; break; case UA_NS0ID_WRITEREQUEST_ENCODING_DEFAULTBINARY: *service = (UA_Service)Service_Write; @@ -26087,6 +23254,20 @@ getServicePointers(UA_UInt32 requestTypeId, const UA_DataType **requestType, *responseType = &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]; break; #endif +#ifdef UA_ENABLE_HISTORIZING + /* For History read */ + case UA_NS0ID_HISTORYREADREQUEST_ENCODING_DEFAULTBINARY: + *service = (UA_Service)Service_HistoryRead; + *requestType = &UA_TYPES[UA_TYPES_HISTORYREADREQUEST]; + *responseType = &UA_TYPES[UA_TYPES_HISTORYREADRESPONSE]; + break; + /* For History update */ + case UA_NS0ID_HISTORYUPDATEREQUEST_ENCODING_DEFAULTBINARY: + *service = (UA_Service)Service_HistoryUpdate; + *requestType = &UA_TYPES[UA_TYPES_HISTORYUPDATEREQUEST]; + *responseType = &UA_TYPES[UA_TYPES_HISTORYUPDATERESPONSE]; + break; +#endif #ifdef UA_ENABLE_METHODCALLS case UA_NS0ID_CALLREQUEST_ENCODING_DEFAULTBINARY: @@ -26137,35 +23318,32 @@ processHEL(UA_Server *server, UA_Connection *connection, if(retval != UA_STATUSCODE_GOOD) return retval; - /* Parameterize the connection */ - connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount; /* zero -> unlimited */ - connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize; /* zero -> unlimited */ - connection->remoteConf.protocolVersion = helloMessage.protocolVersion; - connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize; - if(connection->localConf.sendBufferSize > helloMessage.receiveBufferSize) - connection->localConf.sendBufferSize = helloMessage.receiveBufferSize; - connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize; - if(connection->localConf.recvBufferSize > helloMessage.sendBufferSize) - connection->localConf.recvBufferSize = helloMessage.sendBufferSize; + /* Currently not checked */ UA_String_deleteMembers(&helloMessage.endpointUrl); - if(connection->remoteConf.recvBufferSize == 0) { - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | Remote end indicated a receive buffer size of 0. " - "Not able to send any messages.", - connection->sockfd); - return UA_STATUSCODE_BADINTERNALERROR; - } + /* TODO: Use the config of the exact NetworkLayer */ + if(server->config.networkLayersSize == 0) + return UA_STATUSCODE_BADOUTOFMEMORY; + const UA_ConnectionConfig *localConfig = &server->config.networkLayers[0].localConnectionConfig; - connection->state = UA_CONNECTION_ESTABLISHED; + /* Parameterize the connection */ + UA_ConnectionConfig remoteConfig; + remoteConfig.protocolVersion = helloMessage.protocolVersion; + remoteConfig.sendBufferSize = helloMessage.sendBufferSize; + remoteConfig.recvBufferSize = helloMessage.receiveBufferSize; + remoteConfig.maxMessageSize = helloMessage.maxMessageSize; + remoteConfig.maxChunkCount = helloMessage.maxChunkCount; + retval = UA_Connection_processHELACK(connection, localConfig, &remoteConfig); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | Error during the HEL/ACK handshake", + (int)(connection->sockfd)); + return retval; + } /* Build acknowledge response */ UA_TcpAcknowledgeMessage ackMessage; - ackMessage.protocolVersion = connection->localConf.protocolVersion; - ackMessage.receiveBufferSize = connection->localConf.recvBufferSize; - ackMessage.sendBufferSize = connection->localConf.sendBufferSize; - ackMessage.maxMessageSize = connection->localConf.maxMessageSize; - ackMessage.maxChunkCount = connection->localConf.maxChunkCount; + memcpy(&ackMessage, localConfig, sizeof(UA_TcpAcknowledgeMessage)); /* Same struct layout.. */ UA_TcpMessageHeader ackHeader; ackHeader.messageTypeAndChunkType = UA_MESSAGETYPE_ACK + UA_CHUNKTYPE_FINAL; ackHeader.messageSize = 8 + 20; /* ackHeader + ackMessage */ @@ -26173,8 +23351,7 @@ processHEL(UA_Server *server, UA_Connection *connection, /* Get the send buffer from the network layer */ UA_ByteString ack_msg; UA_ByteString_init(&ack_msg); - retval = connection->getSendBuffer(connection, connection->localConf.sendBufferSize, - &ack_msg); + retval = connection->getSendBuffer(connection, connection->config.sendBufferSize, &ack_msg); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -26182,13 +23359,13 @@ processHEL(UA_Server *server, UA_Connection *connection, UA_Byte *bufPos = ack_msg.data; const UA_Byte *bufEnd = &ack_msg.data[ack_msg.length]; - retval = UA_TcpMessageHeader_encodeBinary(&ackHeader, &bufPos, &bufEnd); + retval = UA_TcpMessageHeader_encodeBinary(&ackHeader, &bufPos, bufEnd); if(retval != UA_STATUSCODE_GOOD) { connection->releaseSendBuffer(connection, &ack_msg); return retval; } - retval = UA_TcpAcknowledgeMessage_encodeBinary(&ackMessage, &bufPos, &bufEnd); + retval = UA_TcpAcknowledgeMessage_encodeBinary(&ackMessage, &bufPos, bufEnd); if(retval != UA_STATUSCODE_GOOD) { connection->releaseSendBuffer(connection, &ack_msg); return retval; @@ -26204,17 +23381,24 @@ processOPN(UA_Server *server, UA_SecureChannel *channel, /* Decode the request */ size_t offset = 0; UA_NodeId requestType; - UA_StatusCode retval = UA_STATUSCODE_GOOD; UA_OpenSecureChannelRequest openSecureChannelRequest; - retval |= UA_NodeId_decodeBinary(msg, &offset, &requestType); - retval |= UA_OpenSecureChannelRequest_decodeBinary(msg, &offset, &openSecureChannelRequest); + UA_StatusCode retval = UA_NodeId_decodeBinary(msg, &offset, &requestType); + + if(retval != UA_STATUSCODE_GOOD) { + UA_NodeId_deleteMembers(&requestType); + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, + "Could not decode the NodeId. Closing the connection"); + UA_SecureChannelManager_close(&server->secureChannelManager, channel->securityToken.channelId); + return retval; + } + retval = UA_OpenSecureChannelRequest_decodeBinary(msg, &offset, &openSecureChannelRequest); /* Error occurred */ if(retval != UA_STATUSCODE_GOOD || requestType.identifier.numeric != UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST].binaryEncodingId) { UA_NodeId_deleteMembers(&requestType); UA_OpenSecureChannelRequest_deleteMembers(&openSecureChannelRequest); - UA_LOG_INFO_CHANNEL(server->config.logger, channel, + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, "Could not decode the OPN message. Closing the connection."); UA_SecureChannelManager_close(&server->secureChannelManager, channel->securityToken.channelId); return retval; @@ -26227,7 +23411,7 @@ processOPN(UA_Server *server, UA_SecureChannel *channel, Service_OpenSecureChannel(server, channel, &openSecureChannelRequest, &openScResponse); UA_OpenSecureChannelRequest_deleteMembers(&openSecureChannelRequest); if(openScResponse.responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_CHANNEL(server->config.logger, channel, "Could not open a SecureChannel. " + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, "Could not open a SecureChannel. " "Closing the connection."); UA_SecureChannelManager_close(&server->secureChannelManager, channel->securityToken.channelId); @@ -26239,127 +23423,106 @@ processOPN(UA_Server *server, UA_SecureChannel *channel, &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]); UA_OpenSecureChannelResponse_deleteMembers(&openScResponse); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_CHANNEL(server->config.logger, channel, + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, "Could not send the OPN answer with error code %s", UA_StatusCode_name(retval)); UA_SecureChannelManager_close(&server->secureChannelManager, channel->securityToken.channelId); + return retval; } + return retval; } static UA_StatusCode -processMSG(UA_Server *server, UA_SecureChannel *channel, - UA_UInt32 requestId, const UA_ByteString *msg) { - /* At 0, the nodeid starts... */ - size_t offset = 0; +sendResponse(UA_SecureChannel *channel, UA_UInt32 requestId, UA_UInt32 requestHandle, + UA_ResponseHeader *responseHeader, const UA_DataType *responseType) { + /* Prepare the ResponseHeader */ + responseHeader->requestHandle = requestHandle; + responseHeader->timestamp = UA_DateTime_now(); - /* Decode the nodeid */ - UA_NodeId requestTypeId; - UA_StatusCode retval = UA_NodeId_decodeBinary(msg, &offset, &requestTypeId); + /* Start the message context */ + UA_MessageContext mc; + UA_StatusCode retval = UA_MessageContext_begin(&mc, channel, requestId, UA_MESSAGETYPE_MSG); if(retval != UA_STATUSCODE_GOOD) return retval; - if(requestTypeId.namespaceIndex != 0 || - requestTypeId.identifierType != UA_NODEIDTYPE_NUMERIC) - UA_NodeId_deleteMembers(&requestTypeId); /* leads to badserviceunsupported */ - /* Store the start-position of the request */ - size_t requestPos = offset; + /* Assert's required for clang-analyzer */ + UA_assert(mc.buf_pos == &mc.messageBuffer.data[UA_SECURE_MESSAGE_HEADER_LENGTH]); + UA_assert(mc.buf_end <= &mc.messageBuffer.data[mc.messageBuffer.length]); - /* Get the service pointers */ - UA_Service service = NULL; - UA_InSituService serviceInsitu = NULL; - const UA_DataType *requestType = NULL; - const UA_DataType *responseType = NULL; - UA_Boolean sessionRequired = true; - UA_ServiceType serviceType = UA_SERVICETYPE_NORMAL; - getServicePointers(requestTypeId.identifier.numeric, &requestType, - &responseType, &service, &serviceInsitu, &sessionRequired, &serviceType); - if(!requestType) { - if(requestTypeId.identifier.numeric == 787) { - UA_LOG_INFO_CHANNEL(server->config.logger, channel, - "Client requested a subscription, " \ - "but those are not enabled in the build"); - } else { - UA_LOG_INFO_CHANNEL(server->config.logger, channel, - "Unknown request with type identifier %i", - requestTypeId.identifier.numeric); - } - return sendServiceFault(channel, msg, requestPos, &UA_TYPES[UA_TYPES_SERVICEFAULT], - requestId, UA_STATUSCODE_BADSERVICEUNSUPPORTED); - } - UA_assert(responseType); + /* Encode the response type */ + UA_NodeId typeId = UA_NODEID_NUMERIC(0, responseType->binaryEncodingId); + retval = UA_MessageContext_encode(&mc, &typeId, &UA_TYPES[UA_TYPES_NODEID]); + if(retval != UA_STATUSCODE_GOOD) + return retval; - /* Decode the request */ - UA_STACKARRAY(UA_Byte, request, requestType->memSize); - UA_RequestHeader *requestHeader = (UA_RequestHeader*)request; - retval = UA_decodeBinary(msg, &offset, request, requestType, - server->config.customDataTypesSize, - server->config.customDataTypes); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, - "Could not decode the request"); - return sendServiceFault(channel, msg, requestPos, responseType, requestId, retval); - } + /* Encode the response */ + retval = UA_MessageContext_encode(&mc, responseHeader, responseType); + if(retval != UA_STATUSCODE_GOOD) + return retval; - /* Prepare the respone */ - UA_STACKARRAY(UA_Byte, responseBuf, responseType->memSize); - void *response = (void*)(uintptr_t)&responseBuf[0]; /* Get around aliasing rules */ - UA_init(response, responseType); - UA_Session *session = NULL; /* must be initialized before goto send_response */ + /* Finish / send out */ + return UA_MessageContext_finish(&mc); +} +static UA_StatusCode +processMSGDecoded(UA_Server *server, UA_SecureChannel *channel, UA_UInt32 requestId, + UA_Service service, const UA_RequestHeader *requestHeader, + const UA_DataType *requestType, UA_ResponseHeader *responseHeader, + const UA_DataType *responseType, UA_Boolean sessionRequired) { /* CreateSession doesn't need a session */ if(requestType == &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST]) { Service_CreateSession(server, channel, - (const UA_CreateSessionRequest *)request, - (UA_CreateSessionResponse *)response); - #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - // store the authentication token and session ID so we can help fuzzing by setting - // these values in the next request automatically - UA_CreateSessionResponse *res = (UA_CreateSessionResponse *)response; + (const UA_CreateSessionRequest *)requestHeader, + (UA_CreateSessionResponse *)responseHeader); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Store the authentication token and session ID so we can help fuzzing + * by setting these values in the next request automatically */ + UA_CreateSessionResponse *res = (UA_CreateSessionResponse *)responseHeader; UA_NodeId_copy(&res->authenticationToken, &unsafe_fuzz_authenticationToken); - #endif - goto send_response; +#endif + return sendResponse(channel, requestId, requestHeader->requestHandle, + responseHeader, responseType); } - #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - // set the authenticationToken from the create session request to help fuzzing cover more lines - UA_NodeId_deleteMembers(&requestHeader->authenticationToken); - if(!UA_NodeId_isNull(&unsafe_fuzz_authenticationToken)) - UA_NodeId_copy(&unsafe_fuzz_authenticationToken, &requestHeader->authenticationToken); - #endif - /* Find the matching session */ - session = (UA_Session*)UA_SecureChannel_getSession(channel, &requestHeader->authenticationToken); + UA_Session *session = (UA_Session*) + UA_SecureChannel_getSession(channel, &requestHeader->authenticationToken); if(!session && !UA_NodeId_isNull(&requestHeader->authenticationToken)) session = UA_SessionManager_getSessionByToken(&server->sessionManager, &requestHeader->authenticationToken); if(requestType == &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST]) { if(!session) { - UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, + UA_LOG_DEBUG_CHANNEL(&server->config.logger, channel, "Trying to activate a session that is " \ "not known in the server"); - UA_deleteMembers(request, requestType); - return sendServiceFault(channel, msg, requestPos, responseType, + return sendServiceFaultWithRequest(channel, requestHeader, responseType, requestId, UA_STATUSCODE_BADSESSIONIDINVALID); } Service_ActivateSession(server, channel, session, - (const UA_ActivateSessionRequest*)request, - (UA_ActivateSessionResponse*)response); - goto send_response; + (const UA_ActivateSessionRequest*)requestHeader, + (UA_ActivateSessionResponse*)responseHeader); + return sendResponse(channel, requestId, requestHeader->requestHandle, + responseHeader, responseType); } /* Set an anonymous, inactive session for services that need no session */ UA_Session anonymousSession; if(!session) { if(sessionRequired) { - UA_LOG_WARNING_CHANNEL(server->config.logger, channel, - "Service request %i without a valid session", +#ifdef UA_ENABLE_TYPENAMES + UA_LOG_WARNING_CHANNEL(&server->config.logger, channel, + "%s refused without a valid session", + requestType->typeName); +#else + UA_LOG_WARNING_CHANNEL(&server->config.logger, channel, + "Service %i refused without a valid session", requestType->binaryEncodingId); - UA_deleteMembers(request, requestType); - return sendServiceFault(channel, msg, requestPos, responseType, - requestId, UA_STATUSCODE_BADSESSIONIDINVALID); +#endif + return sendServiceFaultWithRequest(channel, requestHeader, responseType, + requestId, UA_STATUSCODE_BADSESSIONIDINVALID); } UA_Session_init(&anonymousSession); @@ -26368,26 +23531,32 @@ processMSG(UA_Server *server, UA_SecureChannel *channel, session = &anonymousSession; } - /* Trying to use a non-activated session? */ - if(sessionRequired && !session->activated) { - UA_LOG_WARNING_SESSION(server->config.logger, session, - "Calling service %i on a non-activated session", + /* Trying to use a non-activated session? Do not allow if request is of type + * CloseSessionRequest */ + if(sessionRequired && !session->activated && + requestType != &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST]) { +#ifdef UA_ENABLE_TYPENAMES + UA_LOG_WARNING_SESSION(&server->config.logger, session, + "%s refused on a non-activated session", + requestType->typeName); +#else + UA_LOG_WARNING_SESSION(&server->config.logger, session, + "Service %i refused on a non-activated session", requestType->binaryEncodingId); +#endif UA_SessionManager_removeSession(&server->sessionManager, &session->header.authenticationToken); - UA_deleteMembers(request, requestType); - return sendServiceFault(channel, msg, requestPos, responseType, - requestId, UA_STATUSCODE_BADSESSIONNOTACTIVATED); + return sendServiceFaultWithRequest(channel, requestHeader, responseType, + requestId, UA_STATUSCODE_BADSESSIONNOTACTIVATED); } /* The session is bound to another channel */ if(session != &anonymousSession && session->header.channel != channel) { - UA_LOG_WARNING_CHANNEL(server->config.logger, channel, + UA_LOG_WARNING_CHANNEL(&server->config.logger, channel, "Client tries to use a Session that is not " "bound to this SecureChannel"); - UA_deleteMembers(request, requestType); - return sendServiceFault(channel, msg, requestPos, responseType, - requestId, UA_STATUSCODE_BADSECURECHANNELIDINVALID); + return sendServiceFaultWithRequest(channel, requestHeader, responseType, + requestId, UA_STATUSCODE_BADSECURECHANNELIDINVALID); } /* Update the session lifetime */ @@ -26396,77 +23565,104 @@ processMSG(UA_Server *server, UA_SecureChannel *channel, #ifdef UA_ENABLE_SUBSCRIPTIONS /* The publish request is not answered immediately */ if(requestType == &UA_TYPES[UA_TYPES_PUBLISHREQUEST]) { - Service_Publish(server, session, - (const UA_PublishRequest*)request, requestId); - UA_deleteMembers(request, requestType); + Service_Publish(server, session, (const UA_PublishRequest*)requestHeader, requestId); return UA_STATUSCODE_GOOD; } #endif - send_response: - - /* Prepare the ResponseHeader */ - ((UA_ResponseHeader*)response)->requestHandle = requestHeader->requestHandle; - ((UA_ResponseHeader*)response)->timestamp = UA_DateTime_now(); - - /* Process normal services before initializing the message context. - * Some services may initialize new message contexts and to support network - * layers only providing one send buffer, only one message context can be - * initialized concurrently. */ - if(serviceType == UA_SERVICETYPE_NORMAL) - service(server, session, request, response); + /* Dispatch the synchronous service call and send the response */ + service(server, session, requestHeader, responseHeader); + return sendResponse(channel, requestId, requestHeader->requestHandle, + responseHeader, responseType); +} - /* Start the message */ - UA_NodeId typeId = UA_NODEID_NUMERIC(0, responseType->binaryEncodingId); - UA_MessageContext mc; - retval = UA_MessageContext_begin(&mc, channel, requestId, UA_MESSAGETYPE_MSG); +static UA_StatusCode +processMSG(UA_Server *server, UA_SecureChannel *channel, + UA_UInt32 requestId, const UA_ByteString *msg) { + /* Decode the nodeid */ + size_t offset = 0; + UA_NodeId requestTypeId; + UA_StatusCode retval = UA_NodeId_decodeBinary(msg, &offset, &requestTypeId); if(retval != UA_STATUSCODE_GOOD) - goto cleanup; + return retval; + if(requestTypeId.namespaceIndex != 0 || + requestTypeId.identifierType != UA_NODEIDTYPE_NUMERIC) + UA_NodeId_deleteMembers(&requestTypeId); /* leads to badserviceunsupported */ - /* Assert's required for clang-analyzer */ - UA_assert(mc.buf_pos == &mc.messageBuffer.data[UA_SECURE_MESSAGE_HEADER_LENGTH]); - UA_assert(mc.buf_end <= &mc.messageBuffer.data[mc.messageBuffer.length]); + size_t requestPos = offset; /* Store the offset (for sendServiceFault) */ - retval = UA_MessageContext_encode(&mc, &typeId, &UA_TYPES[UA_TYPES_NODEID]); - if(retval != UA_STATUSCODE_GOOD) - goto cleanup; - - switch(serviceType) { - case UA_SERVICETYPE_CUSTOM: - /* Was processed before...*/ - retval = UA_MessageContext_encode(&mc, response, responseType); - break; - case UA_SERVICETYPE_INSITU: - retval = serviceInsitu - (server, session, &mc, request, (UA_ResponseHeader*)response); - break; - case UA_SERVICETYPE_NORMAL: - default: - retval = UA_MessageContext_encode(&mc, response, responseType); - break; + /* Get the service pointers */ + UA_Service service = NULL; + UA_Boolean sessionRequired = true; + const UA_DataType *requestType = NULL; + const UA_DataType *responseType = NULL; + getServicePointers(requestTypeId.identifier.numeric, &requestType, + &responseType, &service, &sessionRequired); + if(!requestType) { + if(requestTypeId.identifier.numeric == 787) { + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, + "Client requested a subscription, " \ + "but those are not enabled in the build"); + } else { + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, + "Unknown request with type identifier %i", + requestTypeId.identifier.numeric); + } + return sendServiceFault(channel, msg, requestPos, &UA_TYPES[UA_TYPES_SERVICEFAULT], + requestId, UA_STATUSCODE_BADSERVICEUNSUPPORTED); } + UA_assert(responseType); - /* Finish sending the message */ + /* Decode the request */ + UA_STACKARRAY(UA_Byte, request, requestType->memSize); + retval = UA_decodeBinary(msg, &offset, request, requestType, server->config.customDataTypes); if(retval != UA_STATUSCODE_GOOD) { - UA_MessageContext_abort(&mc); - goto cleanup; + UA_LOG_DEBUG_CHANNEL(&server->config.logger, channel, + "Could not decode the request"); + return sendServiceFault(channel, msg, requestPos, responseType, requestId, retval); } - retval = UA_MessageContext_finish(&mc); + /* Check timestamp in the request header */ + UA_RequestHeader *requestHeader = (UA_RequestHeader*)request; + if(requestHeader->timestamp == 0) { + if(server->config.verifyRequestTimestamp <= UA_RULEHANDLING_WARN) { + UA_LOG_WARNING_CHANNEL(&server->config.logger, channel, + "The server sends no timestamp in the request header. " + "See the 'verifyRequestTimestamp' setting."); + if(server->config.verifyRequestTimestamp <= UA_RULEHANDLING_ABORT) { + retval = sendServiceFaultWithRequest(channel, requestHeader, responseType, + requestId, UA_STATUSCODE_BADINVALIDTIMESTAMP); + UA_deleteMembers(request, requestType); + return retval; + } + } + } + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Set the authenticationToken from the create session request to help + * fuzzing cover more lines */ + UA_NodeId_deleteMembers(&requestHeader->authenticationToken); + if(!UA_NodeId_isNull(&unsafe_fuzz_authenticationToken)) + UA_NodeId_copy(&unsafe_fuzz_authenticationToken, &requestHeader->authenticationToken); +#endif + + /* Prepare the respone */ + UA_STACKARRAY(UA_Byte, response, responseType->memSize); + UA_ResponseHeader *responseHeader = (UA_ResponseHeader*)response; + UA_init(response, responseType); + + /* Continue with the decoded Request */ + retval = processMSGDecoded(server, channel, requestId, service, requestHeader, requestType, + responseHeader, responseType, sessionRequired); - cleanup: - if(retval != UA_STATUSCODE_GOOD) - UA_LOG_INFO_CHANNEL(server->config.logger, channel, - "Could not send the message over the SecureChannel " - "with StatusCode %s", UA_StatusCode_name(retval)); /* Clean up */ UA_deleteMembers(request, requestType); - UA_deleteMembers(response, responseType); + UA_deleteMembers(responseHeader, responseType); return retval; } /* Takes decoded messages starting at the nodeid of the content type. */ -static UA_StatusCode +static void processSecureChannelMessage(void *application, UA_SecureChannel *channel, UA_MessageType messagetype, UA_UInt32 requestId, const UA_ByteString *message) { @@ -26474,24 +23670,29 @@ processSecureChannelMessage(void *application, UA_SecureChannel *channel, UA_StatusCode retval = UA_STATUSCODE_GOOD; switch(messagetype) { case UA_MESSAGETYPE_OPN: - UA_LOG_TRACE_CHANNEL(server->config.logger, channel, + UA_LOG_TRACE_CHANNEL(&server->config.logger, channel, "Process an OPN on an open channel"); retval = processOPN(server, channel, requestId, message); break; case UA_MESSAGETYPE_MSG: - UA_LOG_TRACE_CHANNEL(server->config.logger, channel, "Process a MSG"); + UA_LOG_TRACE_CHANNEL(&server->config.logger, channel, "Process a MSG"); retval = processMSG(server, channel, requestId, message); break; case UA_MESSAGETYPE_CLO: - UA_LOG_TRACE_CHANNEL(server->config.logger, channel, "Process a CLO"); + UA_LOG_TRACE_CHANNEL(&server->config.logger, channel, "Process a CLO"); Service_CloseSecureChannel(server, channel); break; default: - UA_LOG_TRACE_CHANNEL(server->config.logger, channel, "Invalid message type"); + UA_LOG_TRACE_CHANNEL(&server->config.logger, channel, "Invalid message type"); retval = UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; break; } - return retval; + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, + "Processing the message failed with StatusCode %s. " + "Closing the channel.", UA_StatusCode_name(retval)); + Service_CloseSecureChannel(server, channel); + } } static UA_StatusCode @@ -26500,41 +23701,39 @@ createSecureChannel(void *application, UA_Connection *connection, UA_Server *server = (UA_Server*)application; /* Iterate over available endpoints and choose the correct one */ - UA_Endpoint *endpoint = NULL; - UA_StatusCode retval = UA_STATUSCODE_GOOD; - for(size_t i = 0; i < server->config.endpointsSize; ++i) { - UA_Endpoint *endpointCandidate = &server->config.endpoints[i]; - if(!UA_ByteString_equal(&asymHeader->securityPolicyUri, - &endpointCandidate->securityPolicy.policyUri)) + UA_SecurityPolicy *securityPolicy = NULL; + for(size_t i = 0; i < server->config.securityPoliciesSize; ++i) { + UA_SecurityPolicy *policy = &server->config.securityPolicies[i]; + if(!UA_ByteString_equal(&asymHeader->securityPolicyUri, &policy->policyUri)) continue; - retval = endpointCandidate->securityPolicy.asymmetricModule. - compareCertificateThumbprint(&endpointCandidate->securityPolicy, - &asymHeader->receiverCertificateThumbprint); + + UA_StatusCode retval = policy->asymmetricModule. + compareCertificateThumbprint(policy, &asymHeader->receiverCertificateThumbprint); if(retval != UA_STATUSCODE_GOOD) continue; - /* We found the correct endpoint (except for security mode) The endpoint - * needs to be changed by the client / server to match the security - * mode. The server does this in the securechannel manager */ - endpoint = endpointCandidate; + /* We found the correct policy (except for security mode). The endpoint + * needs to be selected by the client / server to match the security + * mode in the endpoint for the session. */ + securityPolicy = policy; break; } - if(!endpoint) + if(!securityPolicy) return UA_STATUSCODE_BADSECURITYPOLICYREJECTED; /* Create a new channel */ return UA_SecureChannelManager_create(&server->secureChannelManager, connection, - &endpoint->securityPolicy, asymHeader); + securityPolicy, asymHeader); } static UA_StatusCode processCompleteChunkWithoutChannel(UA_Server *server, UA_Connection *connection, UA_ByteString *message) { /* Process chunk without a channel; must be OPN */ - UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, + UA_LOG_TRACE(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Connection %i | No channel attached to the connection. " - "Process the chunk directly", connection->sockfd); + "Process the chunk directly", (int)(connection->sockfd)); size_t offset = 0; UA_TcpMessageHeader tcpMessageHeader; UA_StatusCode retval = @@ -26543,14 +23742,14 @@ processCompleteChunkWithoutChannel(UA_Server *server, UA_Connection *connection, return retval; // Only HEL and OPN messages possible without a channel (on the server side) - switch(tcpMessageHeader.messageTypeAndChunkType & 0x00ffffff) { + switch(tcpMessageHeader.messageTypeAndChunkType & 0x00ffffffu) { case UA_MESSAGETYPE_HEL: retval = processHEL(server, connection, message, &offset); break; case UA_MESSAGETYPE_OPN: { - UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | Process OPN message", connection->sockfd); + UA_LOG_TRACE(&server->config.logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | Process OPN message", (int)(connection->sockfd)); /* Called before HEL */ if(connection->state != UA_CONNECTION_ESTABLISHED) { @@ -26574,17 +23773,18 @@ processCompleteChunkWithoutChannel(UA_Server *server, UA_Connection *connection, if(retval != UA_STATUSCODE_GOOD) break; - retval = UA_SecureChannel_processChunk(connection->channel, message, - processSecureChannelMessage, - server, UA_FALSE); + retval = UA_SecureChannel_decryptAddChunk(connection->channel, message, false); if(retval != UA_STATUSCODE_GOOD) break; + + UA_SecureChannel_processCompleteMessages(connection->channel, server, + processSecureChannelMessage); break; } default: - UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, + UA_LOG_TRACE(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Connection %i | Expected OPN or HEL message on a connection " - "without a SecureChannel", connection->sockfd); + "without a SecureChannel", (int)(connection->sockfd)); retval = UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; break; } @@ -26592,25 +23792,22 @@ processCompleteChunkWithoutChannel(UA_Server *server, UA_Connection *connection, } static UA_StatusCode -processCompleteChunk(void *const application, - UA_Connection *const connection, - UA_ByteString *const chunk) { - UA_Server *const server = (UA_Server*)application; +processCompleteChunk(void *const application, UA_Connection *connection, + UA_ByteString *chunk) { + UA_Server *server = (UA_Server*)application; #ifdef UA_DEBUG_DUMP_PKGS_FILE UA_debug_dumpCompleteChunk(server, connection, chunk); #endif if(!connection->channel) return processCompleteChunkWithoutChannel(server, connection, chunk); - return UA_SecureChannel_processChunk(connection->channel, chunk, - processSecureChannelMessage, - server, UA_FALSE); + return UA_SecureChannel_decryptAddChunk(connection->channel, chunk, false); } -static void -processBinaryMessage(UA_Server *server, UA_Connection *connection, - UA_ByteString *message) { - UA_LOG_TRACE(server->config.logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | Received a packet.", connection->sockfd); +void +UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, + UA_ByteString *message) { + UA_LOG_TRACE(&server->config.logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | Received a packet.", (int)(connection->sockfd)); #ifdef UA_DEBUG_DUMP_PKGS UA_dump_hex_pkg(message->data, message->length); #endif @@ -26618,60 +23815,36 @@ processBinaryMessage(UA_Server *server, UA_Connection *connection, UA_StatusCode retval = UA_Connection_processChunks(connection, server, processCompleteChunk, message); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_NETWORK, + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Connection %i | Processing the message failed with " - "error %s", connection->sockfd, UA_StatusCode_name(retval)); + "error %s", (int)(connection->sockfd), UA_StatusCode_name(retval)); /* Send an ERR message and close the connection */ UA_TcpErrorMessage error; error.error = retval; error.reason = UA_STRING_NULL; UA_Connection_sendError(connection, &error); connection->close(connection); + return; } -} - -#ifndef UA_ENABLE_MULTITHREADING -void -UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, - UA_ByteString *message) { - processBinaryMessage(server, connection, message); -} - -#else - -typedef struct { - UA_Connection *connection; - UA_ByteString message; -} ConnectionMessage; - -static void -workerProcessBinaryMessage(UA_Server *server, ConnectionMessage *cm) { - processBinaryMessage(server, cm->connection, &cm->message); - UA_free(cm); -} + UA_SecureChannel *channel = connection->channel; + if(!channel) + return; -void -UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, - UA_ByteString *message) { - /* Allocate the memory for the callback data */ - ConnectionMessage *cm = (ConnectionMessage*)UA_malloc(sizeof(ConnectionMessage)); + /* Process complete messages */ + UA_SecureChannel_processCompleteMessages(channel, server, processSecureChannelMessage); - /* If malloc failed, execute immediately */ - if(!cm) { - processBinaryMessage(server, connection, message); + /* Is the channel still open? */ + if(channel->state == UA_SECURECHANNELSTATE_CLOSED) return; - } - /* Dispatch to the workers */ - cm->connection = connection; - cm->message = *message; - UA_Server_workerCallback(server, (UA_ServerCallback)workerProcessBinaryMessage, cm); + /* Store unused decoded chunks internally in the SecureChannel */ + UA_SecureChannel_persistIncompleteMessages(connection->channel); } +#ifdef UA_ENABLE_MULTITHREADING static void -deleteConnectionTrampoline(UA_Server *server, void *data) { - UA_Connection *connection = (UA_Connection*)data; +deleteConnection(UA_Server *server, UA_Connection *connection) { connection->free(connection); } #endif @@ -26682,7 +23855,14 @@ UA_Server_removeConnection(UA_Server *server, UA_Connection *connection) { #ifndef UA_ENABLE_MULTITHREADING connection->free(connection); #else - UA_Server_delayedCallback(server, deleteConnectionTrampoline, connection); + UA_DelayedCallback *dc = (UA_DelayedCallback*)UA_malloc(sizeof(UA_DelayedCallback)); + if(!dc) + return; /* Malloc cannot fail on OS's that support multithreading. They + * rather kill the process. */ + dc->callback = (UA_ApplicationCallback)deleteConnection; + dc->application = server; + dc->data = connection; + UA_WorkQueue_enqueueDelayed(&server->workQueue, dc); #endif } @@ -26692,7 +23872,7 @@ UA_Server_removeConnection(UA_Server *server, UA_Connection *connection) { * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2016 (c) Lorenz Haas * Copyright 2017 (c) frax2222 * Copyright 2017 (c) Florian Palm @@ -26703,83 +23883,6 @@ UA_Server_removeConnection(UA_Server *server, UA_Connection *connection) { #define UA_MAX_TREE_RECURSE 50 /* How deep up/down the tree do we recurse at most? */ -/**********************/ -/* Parse NumericRange */ -/**********************/ - -static size_t -readDimension(UA_Byte *buf, size_t buflen, UA_NumericRangeDimension *dim) { - size_t progress = UA_readNumber(buf, buflen, &dim->min); - if(progress == 0) - return 0; - if(buflen <= progress + 1 || buf[progress] != ':') { - dim->max = dim->min; - return progress; - } - - ++progress; - size_t progress2 = UA_readNumber(&buf[progress], buflen - progress, &dim->max); - if(progress2 == 0) - return 0; - - /* invalid range */ - if(dim->min >= dim->max) - return 0; - - return progress + progress2; -} - -UA_StatusCode -UA_NumericRange_parseFromString(UA_NumericRange *range, const UA_String *str) { - size_t idx = 0; - size_t dimensionsMax = 0; - UA_NumericRangeDimension *dimensions = NULL; - UA_StatusCode retval = UA_STATUSCODE_GOOD; - size_t offset = 0; - while(true) { - /* alloc dimensions */ - if(idx >= dimensionsMax) { - UA_NumericRangeDimension *newds; - size_t newdssize = sizeof(UA_NumericRangeDimension) * (dimensionsMax + 2); - newds = (UA_NumericRangeDimension*)UA_realloc(dimensions, newdssize); - if(!newds) { - retval = UA_STATUSCODE_BADOUTOFMEMORY; - break; - } - dimensions = newds; - dimensionsMax = dimensionsMax + 2; - } - - /* read the dimension */ - size_t progress = readDimension(&str->data[offset], str->length - offset, - &dimensions[idx]); - if(progress == 0) { - retval = UA_STATUSCODE_BADINDEXRANGEINVALID; - break; - } - offset += progress; - ++idx; - - /* loop into the next dimension */ - if(offset >= str->length) - break; - - if(str->data[offset] != ',') { - retval = UA_STATUSCODE_BADINDEXRANGEINVALID; - break; - } - ++offset; - } - - if(retval == UA_STATUSCODE_GOOD && idx > 0) { - range->dimensions = dimensions; - range->dimensionsSize = idx; - } else - UA_free(dimensions); - - return retval; -} - /********************************/ /* Information Model Operations */ /********************************/ @@ -26792,7 +23895,7 @@ struct ref_history { }; static UA_Boolean -isNodeInTreeNoCircular(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind, +isNodeInTreeNoCircular(void *nsCtx, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind, struct ref_history *visitedRefs, const UA_NodeId *referenceTypeIds, size_t referenceTypeIdsSize) { if(UA_NodeId_equal(nodeToFind, leafNode)) @@ -26801,7 +23904,7 @@ isNodeInTreeNoCircular(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_Nod if(visitedRefs->depth >= UA_MAX_TREE_RECURSE) return false; - const UA_Node *node = ns->getNode(ns->context, leafNode); + const UA_Node *node = UA_Nodestore_getNode(nsCtx, leafNode); if(!node) return false; @@ -26830,10 +23933,10 @@ isNodeInTreeNoCircular(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_Nod * reference types. */ if(visitedRefs->depth % 5 == 4) { struct ref_history *last = visitedRefs; - UA_Boolean skip = UA_FALSE; + UA_Boolean skip = false; while(!skip && last) { if(UA_NodeId_equal(last->id, &refs->targetIds[j].nodeId)) - skip = UA_TRUE; + skip = true; last = last->parent; } if(skip) @@ -26846,24 +23949,25 @@ isNodeInTreeNoCircular(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_Nod /* Recurse */ UA_Boolean foundRecursive = - isNodeInTreeNoCircular(ns, &refs->targetIds[j].nodeId, nodeToFind, &nextVisitedRefs, + isNodeInTreeNoCircular(nsCtx, &refs->targetIds[j].nodeId, nodeToFind, &nextVisitedRefs, referenceTypeIds, referenceTypeIdsSize); if(foundRecursive) { - ns->releaseNode(ns->context, node); + UA_Nodestore_releaseNode(nsCtx, node); return true; } } } - ns->releaseNode(ns->context, node); + UA_Nodestore_releaseNode(nsCtx, node); return false; } UA_Boolean -isNodeInTree(UA_Nodestore *ns, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind, +isNodeInTree(void *nsCtx, const UA_NodeId *leafNode, const UA_NodeId *nodeToFind, const UA_NodeId *referenceTypeIds, size_t referenceTypeIdsSize) { struct ref_history visitedRefs = {NULL, leafNode, 0}; - return isNodeInTreeNoCircular(ns, leafNode, nodeToFind, &visitedRefs, referenceTypeIds, referenceTypeIdsSize); + return isNodeInTreeNoCircular(nsCtx, leafNode, nodeToFind, &visitedRefs, + referenceTypeIds, referenceTypeIdsSize); } const UA_Node * @@ -26903,12 +24007,12 @@ getNodeType(UA_Server *server, const UA_Node *node) { continue; UA_assert(node->references[i].targetIdsSize > 0); const UA_NodeId *targetId = &node->references[i].targetIds[0].nodeId; - const UA_Node *type = UA_Nodestore_get(server, targetId); + const UA_Node *type = UA_Nodestore_getNode(server->nsCtx, targetId); if(!type) continue; if(type->nodeClass == typeNodeClass) return type; - UA_Nodestore_release(server, type); + UA_Nodestore_releaseNode(server->nsCtx, type); } return NULL; @@ -26929,111 +24033,66 @@ UA_Node_hasSubTypeOrInstances(const UA_Node *node) { return false; } -static const UA_NodeId hasSubtypeNodeId = - {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}}; - -static UA_StatusCode -getTypeHierarchyFromNode(UA_NodeId **results_ptr, size_t *results_count, - size_t *results_size, const UA_Node *node) { - UA_NodeId *results = *results_ptr; - for(size_t i = 0; i < node->referencesSize; ++i) { - /* Is the reference kind relevant? */ - UA_NodeReferenceKind *refs = &node->references[i]; - if(!refs->isInverse) - continue; - if(!UA_NodeId_equal(&hasSubtypeNodeId, &refs->referenceTypeId)) - continue; - - /* Append all targets of the reference kind .. if not a duplicate */ - for(size_t j = 0; j < refs->targetIdsSize; ++j) { - /* Is the target a duplicate? (multi-inheritance) */ - UA_NodeId *targetId = &refs->targetIds[j].nodeId; - UA_Boolean duplicate = false; - for(size_t k = 0; k < *results_count; ++k) { - if(UA_NodeId_equal(targetId, &results[k])) { - duplicate = true; - break; - } - } - if(duplicate) - continue; - - /* Increase array length if necessary */ - if(*results_count >= *results_size) { - size_t new_size = sizeof(UA_NodeId) * (*results_size) * 2; - UA_NodeId *new_results = (UA_NodeId*)UA_realloc(results, new_size); - if(!new_results) { - UA_Array_delete(results, *results_count, &UA_TYPES[UA_TYPES_NODEID]); - return UA_STATUSCODE_BADOUTOFMEMORY; - } - results = new_results; - *results_ptr = results; - *results_size *= 2; - } - - /* Copy new nodeid to the end of the list */ - UA_StatusCode retval = UA_NodeId_copy(targetId, &results[*results_count]); - if(retval != UA_STATUSCODE_GOOD) { - UA_Array_delete(results, *results_count, &UA_TYPES[UA_TYPES_NODEID]); - return retval; - } - *results_count += 1; - } - } - return UA_STATUSCODE_GOOD; -} +static const UA_NodeId hasInterfaceNodeId = + {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASINTERFACE}}; UA_StatusCode -getTypeHierarchy(UA_Nodestore *ns, const UA_NodeId *leafType, - UA_NodeId **typeHierarchy, size_t *typeHierarchySize) { - /* Allocate the results array. Probably too big, but saves mallocs. */ - size_t results_size = 20; - UA_NodeId *results = (UA_NodeId*)UA_malloc(sizeof(UA_NodeId) * results_size); - if(!results) - return UA_STATUSCODE_BADOUTOFMEMORY; +getParentTypeAndInterfaceHierarchy(UA_Server *server, const UA_NodeId *typeNode, + UA_NodeId **typeHierarchy, size_t *typeHierarchySize) { + UA_ExpandedNodeId *subTypes = NULL; + size_t subTypesSize = 0; + UA_StatusCode retval = browseRecursive(server, 1, typeNode, 1, &subtypeId, + UA_BROWSEDIRECTION_INVERSE, false, + &subTypesSize, &subTypes); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + UA_assert(subTypesSize < 1000); - /* The leaf is the first element */ - size_t results_count = 1; - UA_StatusCode retval = UA_NodeId_copy(leafType, &results[0]); + UA_ExpandedNodeId *interfaces = NULL; + size_t interfacesSize = 0; + retval = browseRecursive(server, 1, typeNode, 1, &hasInterfaceNodeId, + UA_BROWSEDIRECTION_FORWARD, false, + &interfacesSize, &interfaces); if(retval != UA_STATUSCODE_GOOD) { - UA_free(results); + UA_Array_delete(subTypes, subTypesSize, &UA_TYPES[UA_TYPES_NODEID]); return retval; } - /* Loop over the array members .. and add new elements to the end */ - for(size_t idx = 0; idx < results_count; ++idx) { - /* Get the node */ - const UA_Node *node = ns->getNode(ns->context, &results[idx]); + UA_assert(interfacesSize < 1000); - /* Invalid node, remove from the array */ - if(!node) { - for(size_t i = idx; i < results_count-1; ++i) - results[i] = results[i+1]; - results_count--; - continue; - } - - /* Add references from the current node to the end of the array */ - retval = getTypeHierarchyFromNode(&results, &results_count, - &results_size, node); - - /* Release the node */ - ns->releaseNode(ns->context, node); + UA_NodeId *hierarchy = (UA_NodeId*) + UA_malloc(sizeof(UA_NodeId) * (1 + subTypesSize + interfacesSize)); + if(!hierarchy) { + UA_Array_delete(subTypes, subTypesSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); + UA_Array_delete(interfaces, interfacesSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); + return UA_STATUSCODE_BADOUTOFMEMORY; + } - if(retval != UA_STATUSCODE_GOOD) { - UA_Array_delete(results, results_count, &UA_TYPES[UA_TYPES_NODEID]); - return retval; - } + retval = UA_NodeId_copy(typeNode, hierarchy); + if(retval != UA_STATUSCODE_GOOD) { + UA_free(hierarchy); + UA_Array_delete(subTypes, subTypesSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); + UA_Array_delete(interfaces, interfacesSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); + return UA_STATUSCODE_BADOUTOFMEMORY; } - /* Zero results. The leaf node was not found */ - if(results_count == 0) { - UA_free(results); - results = NULL; + for(size_t i = 0; i < subTypesSize; i++) { + hierarchy[i+1] = subTypes[i].nodeId; + UA_NodeId_init(&subTypes[i].nodeId); } + for(size_t i = 0; i < interfacesSize; i++) { + hierarchy[i+1+subTypesSize] = interfaces[i].nodeId; + UA_NodeId_init(&interfaces[i].nodeId); + } + + *typeHierarchy = hierarchy; + *typeHierarchySize = subTypesSize + interfacesSize + 1; + + UA_assert(*typeHierarchySize < 1000); - *typeHierarchy = results; - *typeHierarchySize = results_count; + UA_Array_delete(subTypes, subTypesSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); + UA_Array_delete(interfaces, interfacesSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); return UA_STATUSCODE_GOOD; } @@ -27043,28 +24102,32 @@ UA_StatusCode UA_Server_editNode(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId, UA_EditNodeCallback callback, void *data) { -#ifndef UA_ENABLE_MULTITHREADING - const UA_Node *node = UA_Nodestore_get(server, nodeId); +#ifndef UA_ENABLE_IMMUTABLE_NODES + /* Get the node and process it in-situ */ + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId); if(!node) return UA_STATUSCODE_BADNODEIDUNKNOWN; - UA_StatusCode retval = callback(server, session, - (UA_Node*)(uintptr_t)node, data); - UA_Nodestore_release(server, node); + UA_StatusCode retval = callback(server, session, (UA_Node*)(uintptr_t)node, data); + UA_Nodestore_releaseNode(server->nsCtx, node); return retval; #else UA_StatusCode retval; do { + /* Get an editable copy of the node */ UA_Node *node; - retval = server->config.nodestore.getNodeCopy(server->config.nodestore.context, - nodeId, &node); + retval = UA_Nodestore_getNodeCopy(server->nsCtx, nodeId, &node); if(retval != UA_STATUSCODE_GOOD) return retval; + + /* Run the operation on the copy */ retval = callback(server, session, node, data); if(retval != UA_STATUSCODE_GOOD) { - server->config.nodestore.deleteNode(server->config.nodestore.context, node); + UA_Nodestore_deleteNode(server->nsCtx, node); return retval; } - retval = server->config.nodestore.replaceNode(server->config.nodestore.context, node); + + /* Replace the node */ + retval = UA_Nodestore_replaceNode(server->nsCtx, node); } while(retval != UA_STATUSCODE_GOOD); return retval; #endif @@ -27073,7 +24136,7 @@ UA_Server_editNode(UA_Server *server, UA_Session *session, UA_StatusCode UA_Server_processServiceOperations(UA_Server *server, UA_Session *session, UA_ServiceOperation operationCallback, - void *context, const size_t *requestOperations, + const void *context, const size_t *requestOperations, const UA_DataType *requestOperationsType, size_t *responseOperations, const UA_DataType *responseOperationsType) { @@ -27099,6 +24162,10 @@ UA_Server_processServiceOperations(UA_Server *server, UA_Session *session, return UA_STATUSCODE_GOOD; } +/* A few global NodeId definitions */ +const UA_NodeId subtypeId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}}; +const UA_NodeId hierarchicalReferences = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HIERARCHICALREFERENCES}}; + /*********************************/ /* Default attribute definitions */ /*********************************/ @@ -27185,513 +24252,25 @@ const UA_ViewAttributes UA_ViewAttributes_default = { }; -/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_server_worker.c" ***********************************/ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB - * Copyright 2014-2016 (c) Sten Grüner - * Copyright 2015 (c) Chris Iatrou - * Copyright 2015 (c) Nick Goossens - * Copyright 2015 (c) Jörg Schüler-Maroldt - * Copyright 2015-2016 (c) Oleksiy Vasylyev - * Copyright 2016-2017 (c) Florian Palm - * Copyright 2017 (c) Stefan Profanter, fortiss GmbH - * Copyright 2016 (c) Lorenz Haas - * Copyright 2017 (c) Jonas Green - */ - -#ifdef UA_ENABLE_VALGRIND_INTERACTIVE -#include <valgrind/memcheck.h> -#endif - -#define UA_MAXTIMEOUT 50 /* Max timeout in ms between main-loop iterations */ - -/** - * Worker Threads and Dispatch Queue - * --------------------------------- - * The worker threads dequeue callbacks from a central Multi-Producer - * Multi-Consumer Queue (MPMC). When there are no callbacks, workers go idle. - * The condition to wake them up is triggered whenever a callback is - * dispatched. - * - * Future Plans: Use work-stealing to load-balance between cores. - * Le, Nhat Minh, et al. "Correct and efficient work-stealing for weak memory - * models." ACM SIGPLAN Notices. Vol. 48. No. 8. ACM, 2013. */ - -#ifdef UA_ENABLE_MULTITHREADING - -struct UA_Worker { - UA_Server *server; - pthread_t thr; - UA_UInt32 counter; - volatile UA_Boolean running; - - /* separate cache lines */ - char padding[64 - sizeof(void*) - sizeof(pthread_t) - - sizeof(UA_UInt32) - sizeof(UA_Boolean)]; -}; - -struct UA_WorkerCallback { - SIMPLEQ_ENTRY(UA_WorkerCallback) next; - UA_ServerCallback callback; - void *data; - - UA_Boolean delayed; /* Is it a delayed callback? */ - UA_Boolean countersSampled; /* Have the worker counters been sampled? */ - UA_UInt32 workerCounters[]; /* Counter value for each worker */ -}; -typedef struct UA_WorkerCallback WorkerCallback; - -/* Forward Declaration */ -static void -processDelayedCallback(UA_Server *server, WorkerCallback *dc); - -static void * -workerLoop(UA_Worker *worker) { - UA_Server *server = worker->server; - UA_UInt32 *counter = &worker->counter; - volatile UA_Boolean *running = &worker->running; - - /* Initialize the (thread local) random seed with the ram address - * of the worker. Not for security-critical entropy! */ - UA_random_seed((uintptr_t)worker); - - while(*running) { - UA_atomic_addUInt32(counter, 1); - pthread_mutex_lock(&server->dispatchQueue_accessMutex); - WorkerCallback *dc = SIMPLEQ_FIRST(&server->dispatchQueue); - if(dc) { - SIMPLEQ_REMOVE_HEAD(&server->dispatchQueue, next); - } - pthread_mutex_unlock(&server->dispatchQueue_accessMutex); - if(!dc) { - /* Nothing to do. Sleep until a callback is dispatched */ - pthread_mutex_lock(&server->dispatchQueue_conditionMutex); - pthread_cond_wait(&server->dispatchQueue_condition, - &server->dispatchQueue_conditionMutex); - pthread_mutex_unlock(&server->dispatchQueue_conditionMutex); - continue; - } - - if(dc->delayed) { - processDelayedCallback(server, dc); - continue; - } - - dc->callback(server, dc->data); - UA_free(dc); - } - - UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER, - "Worker shut down"); - return NULL; -} - -void UA_Server_cleanupDispatchQueue(UA_Server *server) { - while(true) { - pthread_mutex_lock(&server->dispatchQueue_accessMutex); - WorkerCallback *dc = SIMPLEQ_FIRST(&server->dispatchQueue); - if(!dc) { - pthread_mutex_unlock(&server->dispatchQueue_accessMutex); - break; - } - SIMPLEQ_REMOVE_HEAD(&server->dispatchQueue, next); - pthread_mutex_unlock(&server->dispatchQueue_accessMutex); - dc->callback(server, dc->data); - UA_free(dc); - } -} - -#endif - -/** - * Repeated Callbacks - * ------------------ - * Repeated Callbacks are handled by UA_Timer (used in both client and server). - * In the multi-threaded case, callbacks are dispatched to workers. Otherwise, - * they are executed immediately. */ - -void -UA_Server_workerCallback(UA_Server *server, UA_ServerCallback callback, - void *data) { -#ifndef UA_ENABLE_MULTITHREADING - /* Execute immediately */ - callback(server, data); -#else - /* Execute immediately if memory could not be allocated */ - WorkerCallback *dc = (WorkerCallback*)UA_malloc(sizeof(WorkerCallback)); - if(!dc) { - callback(server, data); - return; - } - - /* Enqueue for the worker threads */ - dc->callback = callback; - dc->data = data; - dc->delayed = false; - pthread_mutex_lock(&server->dispatchQueue_accessMutex); - SIMPLEQ_INSERT_TAIL(&server->dispatchQueue, dc, next); - pthread_mutex_unlock(&server->dispatchQueue_accessMutex); - - /* Wake up sleeping workers */ - pthread_cond_broadcast(&server->dispatchQueue_condition); -#endif -} - -/** - * Delayed Callbacks - * ----------------- - * - * Delayed Callbacks are called only when all callbacks that were dispatched - * prior are finished. In the single-threaded case, the callback is added to a - * singly-linked list that is processed at the end of the server's main-loop. In - * the multi-threaded case, the delay is ensure by a three-step procedure: - * - * 1. The delayed callback is dispatched to the worker queue. So it is only - * dequeued when all prior callbacks have been dequeued. - * - * 2. When the callback is first dequeued by a worker, sample the counter of all - * workers. Once all counters have advanced, the callback is ready. - * - * 3. Check regularly if the callback is ready by adding it back to the dispatch - * queue. */ - -/* Delayed callback to free the subscription memory */ -static void -freeCallback(UA_Server *server, void *data) { - UA_free(data); -} - -/* TODO: Delayed free should never fail. This can be achieved by adding a prefix - * with the list pointers */ -UA_StatusCode -UA_Server_delayedFree(UA_Server *server, void *data) { - return UA_Server_delayedCallback(server, freeCallback, data); -} - -#ifndef UA_ENABLE_MULTITHREADING - -typedef struct UA_DelayedCallback { - SLIST_ENTRY(UA_DelayedCallback) next; - UA_ServerCallback callback; - void *data; -} UA_DelayedCallback; - -UA_StatusCode -UA_Server_delayedCallback(UA_Server *server, UA_ServerCallback callback, - void *data) { - UA_DelayedCallback *dc = - (UA_DelayedCallback*)UA_malloc(sizeof(UA_DelayedCallback)); - if(!dc) - return UA_STATUSCODE_BADOUTOFMEMORY; - - dc->callback = callback; - dc->data = data; - SLIST_INSERT_HEAD(&server->delayedCallbacks, dc, next); - return UA_STATUSCODE_GOOD; -} - -void UA_Server_cleanupDelayedCallbacks(UA_Server *server) { - UA_DelayedCallback *dc, *dc_tmp; - SLIST_FOREACH_SAFE(dc, &server->delayedCallbacks, next, dc_tmp) { - SLIST_REMOVE(&server->delayedCallbacks, dc, UA_DelayedCallback, next); - dc->callback(server, dc->data); - UA_free(dc); - } -} - -#else /* UA_ENABLE_MULTITHREADING */ - -UA_StatusCode -UA_Server_delayedCallback(UA_Server *server, UA_ServerCallback callback, - void *data) { - size_t dcsize = sizeof(WorkerCallback) + - (sizeof(UA_UInt32) * server->config.nThreads); - WorkerCallback *dc = (WorkerCallback*)UA_malloc(dcsize); - if(!dc) - return UA_STATUSCODE_BADOUTOFMEMORY; - - /* Enqueue for the worker threads */ - dc->callback = callback; - dc->data = data; - dc->delayed = true; - dc->countersSampled = false; - pthread_mutex_lock(&server->dispatchQueue_accessMutex); - SIMPLEQ_INSERT_TAIL(&server->dispatchQueue, dc, next); - pthread_mutex_unlock(&server->dispatchQueue_accessMutex); - - /* Wake up sleeping workers */ - pthread_cond_broadcast(&server->dispatchQueue_condition); - return UA_STATUSCODE_GOOD; -} - -/* Called from the worker loop */ -static void -processDelayedCallback(UA_Server *server, WorkerCallback *dc) { - /* Set the worker counters */ - if(!dc->countersSampled) { - for(size_t i = 0; i < server->config.nThreads; ++i) - dc->workerCounters[i] = server->workers[i].counter; - dc->countersSampled = true; - - /* Re-add to the dispatch queue */ - pthread_mutex_lock(&server->dispatchQueue_accessMutex); - SIMPLEQ_INSERT_TAIL(&server->dispatchQueue, dc, next); - pthread_mutex_unlock(&server->dispatchQueue_accessMutex); - - /* Wake up sleeping workers */ - pthread_cond_broadcast(&server->dispatchQueue_condition); - return; - } - - /* Have all other jobs finished? */ - UA_Boolean ready = true; - for(size_t i = 0; i < server->config.nThreads; ++i) { - if(dc->workerCounters[i] == server->workers[i].counter) { - ready = false; - break; - } - } - - /* Re-add to the dispatch queue. - * TODO: What is the impact of this loop? - * Can we add a small delay here? */ - if(!ready) { - pthread_mutex_lock(&server->dispatchQueue_accessMutex); - SIMPLEQ_INSERT_TAIL(&server->dispatchQueue, dc, next); - pthread_mutex_unlock(&server->dispatchQueue_accessMutex); - - /* Wake up sleeping workers */ - pthread_cond_broadcast(&server->dispatchQueue_condition); - return; - } - - /* Execute the callback */ - dc->callback(server, dc->data); - UA_free(dc); -} - -#endif - -/** - * Main Server Loop - * ---------------- - * Start: Spin up the workers and the network layer and sample the server's - * start time. - * Iterate: Process repeated callbacks and events in the network layer. - * This part can be driven from an external main-loop in an - * event-driven single-threaded architecture. - * Stop: Stop workers, finish all callbacks, stop the network layer, - * clean up */ - -UA_StatusCode -UA_Server_run_startup(UA_Server *server) { - UA_Variant var; - UA_StatusCode result = UA_STATUSCODE_GOOD; - - /* Sample the start time and set it to the Server object */ - server->startTime = UA_DateTime_now(); - UA_Variant_init(&var); - UA_Variant_setScalar(&var, &server->startTime, &UA_TYPES[UA_TYPES_DATETIME]); - UA_Server_writeValue(server, - UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STARTTIME), - var); - - /* Start the networklayers */ - for(size_t i = 0; i < server->config.networkLayersSize; ++i) { - UA_ServerNetworkLayer *nl = &server->config.networkLayers[i]; - result |= nl->start(nl, &server->config.customHostname); - } - - /* Spin up the worker threads */ -#ifdef UA_ENABLE_MULTITHREADING - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, - "Spinning up %u worker thread(s)", server->config.nThreads); - pthread_mutex_init(&server->dispatchQueue_accessMutex, NULL); - pthread_cond_init(&server->dispatchQueue_condition, NULL); - pthread_mutex_init(&server->dispatchQueue_conditionMutex, NULL); - server->workers = (UA_Worker*)UA_malloc(server->config.nThreads * sizeof(UA_Worker)); - if(!server->workers) - return UA_STATUSCODE_BADOUTOFMEMORY; - for(size_t i = 0; i < server->config.nThreads; ++i) { - UA_Worker *worker = &server->workers[i]; - worker->server = server; - worker->counter = 0; - worker->running = true; - pthread_create(&worker->thr, NULL, (void* (*)(void*))workerLoop, worker); - } -#endif - - /* Start the multicast discovery server */ -#ifdef UA_ENABLE_DISCOVERY_MULTICAST - if(server->config.applicationDescription.applicationType == - UA_APPLICATIONTYPE_DISCOVERYSERVER) - startMulticastDiscoveryServer(server); -#endif - - return result; -} - -UA_UInt16 -UA_Server_run_iterate(UA_Server *server, UA_Boolean waitInternal) { - /* Process repeated work */ - UA_DateTime now = UA_DateTime_nowMonotonic(); - UA_DateTime nextRepeated = - UA_Timer_process(&server->timer, now, - (UA_TimerDispatchCallback)UA_Server_workerCallback, - server); - UA_DateTime latest = now + (UA_MAXTIMEOUT * UA_DATETIME_MSEC); - if(nextRepeated > latest) - nextRepeated = latest; - - UA_UInt16 timeout = 0; - - /* round always to upper value to avoid timeout to be set to 0 - * if(nextRepeated - now) < (UA_DATETIME_MSEC/2) */ - if(waitInternal) - timeout = (UA_UInt16)(((nextRepeated - now) + (UA_DATETIME_MSEC - 1)) / UA_DATETIME_MSEC); - - /* Listen on the networklayer */ - for(size_t i = 0; i < server->config.networkLayersSize; ++i) { - UA_ServerNetworkLayer *nl = &server->config.networkLayers[i]; - nl->listen(nl, server, timeout); - } - -#ifndef UA_ENABLE_MULTITHREADING - /* Process delayed callbacks when all callbacks and network events are done. - * If multithreading is enabled, the cleanup of delayed values is attempted - * by a callback in the job queue. */ - UA_Server_cleanupDelayedCallbacks(server); -#endif - -#if defined(UA_ENABLE_DISCOVERY_MULTICAST) && !defined(UA_ENABLE_MULTITHREADING) - if(server->config.applicationDescription.applicationType == - UA_APPLICATIONTYPE_DISCOVERYSERVER) { - // TODO multicastNextRepeat does not consider new input data (requests) - // on the socket. It will be handled on the next call. if needed, we - // need to use select with timeout on the multicast socket - // server->mdnsSocket (see example in mdnsd library) on higher level. - UA_DateTime multicastNextRepeat = 0; - UA_StatusCode hasNext = - iterateMulticastDiscoveryServer(server, &multicastNextRepeat, UA_TRUE); - if(hasNext == UA_STATUSCODE_GOOD && multicastNextRepeat < nextRepeated) - nextRepeated = multicastNextRepeat; - } -#endif - - now = UA_DateTime_nowMonotonic(); - timeout = 0; - if(nextRepeated > now) - timeout = (UA_UInt16)((nextRepeated - now) / UA_DATETIME_MSEC); - return timeout; -} - -UA_StatusCode -UA_Server_run_shutdown(UA_Server *server) { - /* Stop the netowrk layer */ - for(size_t i = 0; i < server->config.networkLayersSize; ++i) { - UA_ServerNetworkLayer *nl = &server->config.networkLayers[i]; - nl->stop(nl, server); - } - -#ifdef UA_ENABLE_MULTITHREADING - /* Shut down the workers */ - if(server->workers) { - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, - "Shutting down %u worker thread(s)", - server->config.nThreads); - for(size_t i = 0; i < server->config.nThreads; ++i) - server->workers[i].running = false; - pthread_cond_broadcast(&server->dispatchQueue_condition); - for(size_t i = 0; i < server->config.nThreads; ++i) - pthread_join(server->workers[i].thr, NULL); - UA_free(server->workers); - server->workers = NULL; - } - - /* Execute the remaining callbacks in the dispatch queue. Also executes - * delayed callbacks. */ - UA_Server_cleanupDispatchQueue(server); -#else - /* Process remaining delayed callbacks */ - UA_Server_cleanupDelayedCallbacks(server); -#endif - -#ifdef UA_ENABLE_DISCOVERY_MULTICAST - /* Stop multicast discovery */ - if(server->config.applicationDescription.applicationType == - UA_APPLICATIONTYPE_DISCOVERYSERVER) - stopMulticastDiscoveryServer(server); -#endif - - return UA_STATUSCODE_GOOD; -} - -UA_StatusCode -UA_Server_run(UA_Server *server, volatile UA_Boolean *running) { - UA_StatusCode retval = UA_Server_run_startup(server); - if(retval != UA_STATUSCODE_GOOD) - return retval; -#ifdef UA_ENABLE_VALGRIND_INTERACTIVE - size_t loopCount = 0; -#endif - while(*running) { -#ifdef UA_ENABLE_VALGRIND_INTERACTIVE - if(loopCount == 0) { - VALGRIND_DO_LEAK_CHECK; - } - ++loopCount; - loopCount %= UA_VALGRIND_INTERACTIVE_INTERVAL; -#endif - UA_Server_run_iterate(server, true); - } - return UA_Server_run_shutdown(server); -} - /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_server_discovery.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Stefan Profanter, fortiss GmbH */ + #ifdef UA_ENABLE_DISCOVERY static UA_StatusCode register_server_with_discovery_server(UA_Server *server, - const char* discoveryServerUrl, + UA_Client *client, const UA_Boolean isUnregister, const char* semaphoreFilePath) { - if(!discoveryServerUrl) { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, - "No discovery server url provided"); - return UA_STATUSCODE_BADINTERNALERROR; - } - - /* Create the client */ - UA_ClientConfig clientConfig = UA_Server_getClientConfig(); - UA_Client *client = UA_Client_new(clientConfig); - if(!client) - return UA_STATUSCODE_BADOUTOFMEMORY; - - /* Connect the client */ - UA_StatusCode retval = UA_Client_connect(client, discoveryServerUrl); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_CLIENT, - "Connecting to the discovery server failed with statuscode %s", - UA_StatusCode_name(retval)); - UA_Client_disconnect(client); - UA_Client_delete(client); - return retval; - } - /* Prepare the request. Do not cleanup the request after the service call, * as the members are stack-allocated or point into the server config. */ UA_RegisterServer2Request request; @@ -27710,7 +24289,7 @@ register_server_with_discovery_server(UA_Server *server, request.server.semaphoreFilePath = UA_STRING((char*)(uintptr_t)semaphoreFilePath); /* dirty cast */ #else - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_CLIENT, "Ignoring semaphore file path. open62541 not compiled " "with UA_ENABLE_DISCOVERY_SEMAPHORE=ON"); #endif @@ -27736,19 +24315,15 @@ register_server_with_discovery_server(UA_Server *server, request.server.discoveryUrls[config_discurls + i] = nl->discoveryUrl; } - UA_MdnsDiscoveryConfiguration mdnsConfig; - UA_MdnsDiscoveryConfiguration_init(&mdnsConfig); - +#ifdef UA_ENABLE_DISCOVERY_MULTICAST request.discoveryConfigurationSize = 1; request.discoveryConfiguration = UA_ExtensionObject_new(); UA_ExtensionObject_init(&request.discoveryConfiguration[0]); + // Set to NODELETE so that we can just use a pointer to the mdns config request.discoveryConfiguration[0].encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE; request.discoveryConfiguration[0].content.decoded.type = &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION]; - request.discoveryConfiguration[0].content.decoded.data = &mdnsConfig; - - mdnsConfig.mdnsServerName = server->config.mdnsServerName; - mdnsConfig.serverCapabilities = server->config.serverCapabilities; - mdnsConfig.serverCapabilitiesSize = server->config.serverCapabilitiesSize; + request.discoveryConfiguration[0].content.decoded.data = &server->config.discovery.mdns; +#endif // First try with RegisterServer2, if that isn't implemented, use RegisterServer UA_RegisterServer2Response response; @@ -27757,7 +24332,11 @@ register_server_with_discovery_server(UA_Server *server, UA_StatusCode serviceResult = response.responseHeader.serviceResult; UA_RegisterServer2Response_deleteMembers(&response); - UA_ExtensionObject_delete(request.discoveryConfiguration); + UA_Array_delete(request.discoveryConfiguration, + request.discoveryConfigurationSize, + &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); + request.discoveryConfiguration = NULL; + request.discoveryConfigurationSize = 0; if(serviceResult == UA_STATUSCODE_BADNOTIMPLEMENTED || serviceResult == UA_STATUSCODE_BADSERVICEUNSUPPORTED) { @@ -27780,27 +24359,25 @@ register_server_with_discovery_server(UA_Server *server, } if(serviceResult != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_CLIENT, "RegisterServer/RegisterServer2 failed with statuscode %s", UA_StatusCode_name(serviceResult)); } - UA_Client_disconnect(client); - UA_Client_delete(client); return serviceResult; } UA_StatusCode -UA_Server_register_discovery(UA_Server *server, const char* discoveryServerUrl, +UA_Server_register_discovery(UA_Server *server, UA_Client *client, const char* semaphoreFilePath) { - return register_server_with_discovery_server(server, discoveryServerUrl, - UA_FALSE, semaphoreFilePath); + return register_server_with_discovery_server(server, client, + false, semaphoreFilePath); } UA_StatusCode -UA_Server_unregister_discovery(UA_Server *server, const char* discoveryServerUrl) { - return register_server_with_discovery_server(server, discoveryServerUrl, - UA_TRUE, NULL); +UA_Server_unregister_discovery(UA_Server *server, UA_Client *client) { + return register_server_with_discovery_server(server, client, + true, NULL); } #endif /* UA_ENABLE_DISCOVERY */ @@ -27811,7 +24388,7 @@ UA_Server_unregister_discovery(UA_Server *server, const char* discoveryServerUrl * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2017 (c) Florian Palm * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015 (c) Oleksiy Vasylyev @@ -27820,6 +24397,8 @@ UA_Server_unregister_discovery(UA_Server *server, const char* discoveryServerUrl */ + + #define STARTCHANNELID 1 #define STARTTOKENID 1 @@ -27839,48 +24418,60 @@ UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm) { channel_entry *entry, *temp; TAILQ_FOREACH_SAFE(entry, &cm->channels, pointers, temp) { TAILQ_REMOVE(&cm->channels, entry, pointers); - UA_SecureChannel_deleteMembersCleanup(&entry->channel); + UA_SecureChannel_close(&entry->channel); + UA_SecureChannel_deleteMembers(&entry->channel); UA_free(entry); } } static void -removeSecureChannelCallback(UA_Server *server, void *entry) { - channel_entry *centry = (channel_entry *)entry; - UA_SecureChannel_deleteMembersCleanup(¢ry->channel); - UA_free(entry); +removeSecureChannelCallback(void *_, channel_entry *entry) { + UA_SecureChannel_deleteMembers(&entry->channel); } -static UA_StatusCode +static void removeSecureChannel(UA_SecureChannelManager *cm, channel_entry *entry) { - /* Add a delayed callback to remove the channel when the currently - * scheduled jobs have completed */ - UA_StatusCode retval = UA_Server_delayedCallback(cm->server, removeSecureChannelCallback, entry); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING(cm->server->config.logger, UA_LOGCATEGORY_SESSION, - "Could not remove the secure channel with error code %s", - UA_StatusCode_name(retval)); - return retval; /* Try again next time */ - } + /* Close the SecureChannel */ + UA_SecureChannel_close(&entry->channel); /* Detach the channel and make the capacity available */ TAILQ_REMOVE(&cm->channels, entry, pointers); UA_atomic_subUInt32(&cm->currentChannelCount, 1); - return UA_STATUSCODE_GOOD; + + /* Add a delayed callback to remove the channel when the currently + * scheduled jobs have completed */ + entry->cleanupCallback.callback = (UA_ApplicationCallback)removeSecureChannelCallback; + entry->cleanupCallback.application = NULL; + entry->cleanupCallback.data = entry; + UA_WorkQueue_enqueueDelayed(&cm->server->workQueue, &entry->cleanupCallback); } /* remove channels that were not renewed or who have no connection attached */ void -UA_SecureChannelManager_cleanupTimedOut(UA_SecureChannelManager *cm, UA_DateTime nowMonotonic) { +UA_SecureChannelManager_cleanupTimedOut(UA_SecureChannelManager *cm, + UA_DateTime nowMonotonic) { channel_entry *entry, *temp; TAILQ_FOREACH_SAFE(entry, &cm->channels, pointers, temp) { - UA_DateTime timeout = entry->channel.securityToken.createdAt + - (UA_DateTime)(entry->channel.securityToken.revisedLifetime * UA_DATETIME_MSEC); - if(timeout < nowMonotonic || !entry->channel.connection) { - UA_LOG_INFO_CHANNEL(cm->server->config.logger, &entry->channel, + /* The channel was closed internally */ + if(entry->channel.state == UA_SECURECHANNELSTATE_CLOSED || + !entry->channel.connection) { + removeSecureChannel(cm, entry); + continue; + } + + /* The channel has timed out */ + UA_DateTime timeout = + entry->channel.securityToken.createdAt + + (UA_DateTime)(entry->channel.securityToken.revisedLifetime * UA_DATETIME_MSEC); + if(timeout < nowMonotonic) { + UA_LOG_INFO_CHANNEL(&cm->server->config.logger, &entry->channel, "SecureChannel has timed out"); removeSecureChannel(cm, entry); - } else if(entry->channel.nextSecurityToken.tokenId > 0) { + continue; + } + + /* Revolve the channel tokens */ + if(entry->channel.nextSecurityToken.tokenId > 0) { UA_SecureChannel_revolveTokens(&entry->channel); } } @@ -27892,7 +24483,7 @@ purgeFirstChannelWithoutSession(UA_SecureChannelManager *cm) { channel_entry *entry; TAILQ_FOREACH(entry, &cm->channels, pointers) { if(LIST_EMPTY(&entry->channel.sessions)) { - UA_LOG_INFO_CHANNEL(cm->server->config.logger, &entry->channel, + UA_LOG_INFO_CHANNEL(&cm->server->config.logger, &entry->channel, "Channel was purged since maxSecureChannels was " "reached and channel had no session attached"); removeSecureChannel(cm, entry); @@ -27917,7 +24508,7 @@ UA_SecureChannelManager_create(UA_SecureChannelManager *const cm, UA_Connection !purgeFirstChannelWithoutSession(cm)) return UA_STATUSCODE_BADOUTOFMEMORY; - UA_LOG_INFO(cm->server->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + UA_LOG_INFO(&cm->server->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "Creating a new SecureChannel"); channel_entry *entry = (channel_entry *)UA_malloc(sizeof(channel_entry)); @@ -27926,8 +24517,10 @@ UA_SecureChannelManager_create(UA_SecureChannelManager *const cm, UA_Connection /* Create the channel context and parse the sender (remote) certificate used for the * secureChannel. */ - UA_StatusCode retval = UA_SecureChannel_init(&entry->channel, securityPolicy, - &asymHeader->senderCertificate); + UA_SecureChannel_init(&entry->channel); + UA_StatusCode retval = + UA_SecureChannel_setSecurityPolicy(&entry->channel, securityPolicy, + &asymHeader->senderCertificate); if(retval != UA_STATUSCODE_GOOD) { UA_free(entry); return retval; @@ -27950,7 +24543,7 @@ UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_SecureChannel *chan const UA_OpenSecureChannelRequest *request, UA_OpenSecureChannelResponse *response) { if(channel->state != UA_SECURECHANNELSTATE_FRESH) { - UA_LOG_ERROR_CHANNEL(cm->server->config.logger, channel, + UA_LOG_ERROR_CHANNEL(&cm->server->config.logger, channel, "Called open on already open or closed channel"); return UA_STATUSCODE_BADINTERNALERROR; } @@ -27974,19 +24567,29 @@ UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_SecureChannel *chan /* Set the nonces and generate the keys */ UA_StatusCode retval = UA_ByteString_copy(&request->clientNonce, &channel->remoteNonce); - retval |= UA_SecureChannel_generateLocalNonce(channel); - retval |= UA_SecureChannel_generateNewKeys(channel); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = UA_SecureChannel_generateLocalNonce(channel); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = UA_SecureChannel_generateNewKeys(channel); if(retval != UA_STATUSCODE_GOOD) return retval; /* Set the response */ retval = UA_ByteString_copy(&channel->localNonce, &response->serverNonce); - retval |= UA_ChannelSecurityToken_copy(&channel->securityToken, &response->securityToken); - response->responseHeader.timestamp = UA_DateTime_now(); - response->responseHeader.requestHandle = request->requestHeader.requestHandle; if(retval != UA_STATUSCODE_GOOD) return retval; + retval = UA_ChannelSecurityToken_copy(&channel->securityToken, &response->securityToken); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + response->responseHeader.timestamp = UA_DateTime_now(); + response->responseHeader.requestHandle = request->requestHeader.requestHandle; + /* The channel is open */ channel->state = UA_SECURECHANNELSTATE_OPEN; @@ -27998,7 +24601,7 @@ UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_SecureChannel *cha const UA_OpenSecureChannelRequest *request, UA_OpenSecureChannelResponse *response) { if(channel->state != UA_SECURECHANNELSTATE_OPEN) { - UA_LOG_ERROR_CHANNEL(cm->server->config.logger, channel, + UA_LOG_ERROR_CHANNEL(&cm->server->config.logger, channel, "Called renew on channel which is not open"); return UA_STATUSCODE_BADINTERNALERROR; } @@ -28018,14 +24621,20 @@ UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_SecureChannel *cha /* Replace the nonces */ UA_ByteString_deleteMembers(&channel->remoteNonce); UA_StatusCode retval = UA_ByteString_copy(&request->clientNonce, &channel->remoteNonce); - retval |= UA_SecureChannel_generateLocalNonce(channel); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = UA_SecureChannel_generateLocalNonce(channel); if(retval != UA_STATUSCODE_GOOD) return retval; /* Set the response */ response->responseHeader.requestHandle = request->requestHeader.requestHandle; retval = UA_ByteString_copy(&channel->localNonce, &response->serverNonce); - retval |= UA_ChannelSecurityToken_copy(&channel->nextSecurityToken, &response->securityToken); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = UA_ChannelSecurityToken_copy(&channel->nextSecurityToken, &response->securityToken); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -28053,7 +24662,9 @@ UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId) } if(!entry) return UA_STATUSCODE_BADINTERNALERROR; - return removeSecureChannel(cm, entry); + + removeSecureChannel(cm, entry); + return UA_STATUSCODE_GOOD; } /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_session_manager.c" ***********************************/ @@ -28062,7 +24673,7 @@ UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId) * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014, 2017 (c) Florian Palm * Copyright 2015 (c) Sten Grüner * Copyright 2015 (c) Oleksiy Vasylyev @@ -28080,13 +24691,11 @@ UA_SessionManager_init(UA_SessionManager *sm, UA_Server *server) { /* Delayed callback to free the session memory */ static void -removeSessionCallback(UA_Server *server, void *entry) { - session_list_entry *sentry = (session_list_entry*)entry; - UA_Session_deleteMembersCleanup(&sentry->session, server); - UA_free(sentry); +removeSessionCallback(UA_Server *server, session_list_entry *entry) { + UA_Session_deleteMembersCleanup(&entry->session, server); } -static UA_StatusCode +static void removeSession(UA_SessionManager *sm, session_list_entry *sentry) { /* Remove the Subscriptions */ #ifdef UA_ENABLE_SUBSCRIPTIONS @@ -28108,21 +24717,17 @@ removeSession(UA_SessionManager *sm, session_list_entry *sentry) { /* Deactivate the session */ sentry->session.activated = false; - /* Add a delayed callback to remove the session when the currently - * scheduled jobs have completed */ - UA_StatusCode retval = UA_Server_delayedCallback(sm->server, removeSessionCallback, sentry); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING_SESSION(sm->server->config.logger, &sentry->session, - "Could not remove session with error code %s", - UA_StatusCode_name(retval)); - return retval; /* Try again next time */ - } - /* Detach the session from the session manager and make the capacity * available */ LIST_REMOVE(sentry, pointers); UA_atomic_subUInt32(&sm->currentSessionCount, 1); - return UA_STATUSCODE_GOOD; + + /* Add a delayed callback to remove the session when the currently + * scheduled jobs have completed */ + sentry->cleanupCallback.callback = (UA_ApplicationCallback)removeSessionCallback; + sentry->cleanupCallback.application = sm->server; + sentry->cleanupCallback.data = sentry; + UA_WorkQueue_enqueueDelayed(&sm->server->workQueue, &sentry->cleanupCallback); } void UA_SessionManager_deleteMembers(UA_SessionManager *sm) { @@ -28140,7 +24745,7 @@ UA_SessionManager_cleanupTimedOut(UA_SessionManager *sm, /* Session has timed out? */ if(sentry->session.validTill >= nowMonotonic) continue; - UA_LOG_INFO_SESSION(sm->server->config.logger, &sentry->session, + UA_LOG_INFO_SESSION(&sm->server->config.logger, &sentry->session, "Session has timed out"); sm->server->config.accessControl.closeSession(sm->server, &sm->server->config.accessControl, @@ -28160,7 +24765,7 @@ UA_SessionManager_getSessionByToken(UA_SessionManager *sm, const UA_NodeId *toke /* Session has timed out */ if(UA_DateTime_nowMonotonic() > current->session.validTill) { - UA_LOG_INFO_SESSION(sm->server->config.logger, ¤t->session, + UA_LOG_INFO_SESSION(&sm->server->config.logger, ¤t->session, "Client tries to use a session that has timed out"); return NULL; } @@ -28170,9 +24775,12 @@ UA_SessionManager_getSessionByToken(UA_SessionManager *sm, const UA_NodeId *toke } /* Session not found */ - UA_LOG_INFO(sm->server->config.logger, UA_LOGCATEGORY_SESSION, - "Try to use Session with token " UA_PRINTF_GUID_FORMAT " but is not found", - UA_PRINTF_GUID_DATA(token->identifier.guid)); + UA_String nodeIdStr = UA_STRING_NULL; + UA_NodeId_toString(token, &nodeIdStr); + UA_LOG_INFO(&sm->server->config.logger, UA_LOGCATEGORY_SESSION, + "Try to use Session with token %.*s but is not found", + (int)nodeIdStr.length, nodeIdStr.data); + UA_String_deleteMembers(&nodeIdStr); return NULL; } @@ -28186,7 +24794,7 @@ UA_SessionManager_getSessionById(UA_SessionManager *sm, const UA_NodeId *session /* Session has timed out */ if(UA_DateTime_nowMonotonic() > current->session.validTill) { - UA_LOG_INFO_SESSION(sm->server->config.logger, ¤t->session, + UA_LOG_INFO_SESSION(&sm->server->config.logger, ¤t->session, "Client tries to use a session that has timed out"); return NULL; } @@ -28196,9 +24804,12 @@ UA_SessionManager_getSessionById(UA_SessionManager *sm, const UA_NodeId *session } /* Session not found */ - UA_LOG_INFO(sm->server->config.logger, UA_LOGCATEGORY_SESSION, - "Try to use Session with identifier " UA_PRINTF_GUID_FORMAT " but is not found", - UA_PRINTF_GUID_DATA(sessionId->identifier.guid)); + UA_String sessionIdStr = UA_STRING_NULL; + UA_NodeId_toString(sessionId, &sessionIdStr); + UA_LOG_INFO(&sm->server->config.logger, UA_LOGCATEGORY_SESSION, + "Try to use Session with identifier %.*s but is not found", + (int)sessionIdStr.length, sessionIdStr.data); + UA_String_deleteMembers(&sessionIdStr); return NULL; } @@ -28239,959 +24850,4937 @@ UA_SessionManager_removeSession(UA_SessionManager *sm, const UA_NodeId *token) { } if(!current) return UA_STATUSCODE_BADSESSIONIDINVALID; - return removeSession(sm, current); + + removeSession(sm, current); + return UA_STATUSCODE_GOOD; } -/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_subscription.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/src/pubsub/ua_pubsub_networkmessage.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015-2017 (c) Julius Pfrommer, Fraunhofer IOSB - * Copyright 2015 (c) Chris Iatrou - * Copyright 2015-2016 (c) Sten Grüner - * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA - * Copyright 2015 (c) Joakim L. Gilje - * Copyright 2016-2017 (c) Florian Palm - * Copyright 2015-2016 (c) Oleksiy Vasylyev - * Copyright 2017 (c) frax2222 - * Copyright 2017 (c) Stefan Profanter, fortiss GmbH - * Copyright 2017 (c) Mattias Bornhager - * Copyright 2018 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Martin Lang) + * Copyright (c) 2017 - 2018 Fraunhofer IOSB (Author: Tino Bischoff) */ -#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ +#ifdef UA_ENABLE_PUBSUB /* conditional compilation */ + + +const UA_Byte NM_VERSION_MASK = 15; +const UA_Byte NM_PUBLISHER_ID_ENABLED_MASK = 16; +const UA_Byte NM_GROUP_HEADER_ENABLED_MASK = 32; +const UA_Byte NM_PAYLOAD_HEADER_ENABLED_MASK = 64; +const UA_Byte NM_EXTENDEDFLAGS1_ENABLED_MASK = 128; +const UA_Byte NM_PUBLISHER_ID_MASK = 7; +const UA_Byte NM_DATASET_CLASSID_ENABLED_MASK = 8; +const UA_Byte NM_SECURITY_ENABLED_MASK = 16; +const UA_Byte NM_TIMESTAMP_ENABLED_MASK = 32; +const UA_Byte NM_PICOSECONDS_ENABLED_MASK = 64; +const UA_Byte NM_EXTENDEDFLAGS2_ENABLED_MASK = 128; +const UA_Byte NM_NETWORK_MSG_TYPE_MASK = 28; +const UA_Byte NM_CHUNK_MESSAGE_MASK = 1; +const UA_Byte NM_PROMOTEDFIELDS_ENABLED_MASK = 2; +const UA_Byte GROUP_HEADER_WRITER_GROUPID_ENABLED = 1; +const UA_Byte GROUP_HEADER_GROUP_VERSION_ENABLED = 2; +const UA_Byte GROUP_HEADER_NM_NUMBER_ENABLED = 4; +const UA_Byte GROUP_HEADER_SEQUENCE_NUMBER_ENABLED = 8; +const UA_Byte SECURITY_HEADER_NM_SIGNED = 1; +const UA_Byte SECURITY_HEADER_NM_ENCRYPTED = 2; +const UA_Byte SECURITY_HEADER_SEC_FOOTER_ENABLED = 4; +const UA_Byte SECURITY_HEADER_FORCE_KEY_RESET = 8; +const UA_Byte DS_MESSAGEHEADER_DS_MSG_VALID = 1; +const UA_Byte DS_MESSAGEHEADER_FIELD_ENCODING_MASK = 6; +const UA_Byte DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK = 8; +const UA_Byte DS_MESSAGEHEADER_STATUS_ENABLED_MASK = 16; +const UA_Byte DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK = 32; +const UA_Byte DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK = 64; +const UA_Byte DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK = 128; +const UA_Byte DS_MESSAGEHEADER_DS_MESSAGE_TYPE_MASK = 15; +const UA_Byte DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK = 16; +const UA_Byte DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK = 32; +const UA_Byte NM_SHIFT_LEN = 2; +const UA_Byte DS_MH_SHIFT_LEN = 1; + +static UA_Boolean UA_NetworkMessage_ExtendedFlags1Enabled(const UA_NetworkMessage* src); +static UA_Boolean UA_NetworkMessage_ExtendedFlags2Enabled(const UA_NetworkMessage* src); +static UA_Boolean UA_DataSetMessageHeader_DataSetFlags2Enabled(const UA_DataSetMessageHeader* src); -UA_Subscription * -UA_Subscription_new(UA_Session *session, UA_UInt32 subscriptionId) { - /* Allocate the memory */ - UA_Subscription *newSub = - (UA_Subscription*)UA_calloc(1, sizeof(UA_Subscription)); - if(!newSub) - return NULL; +UA_StatusCode +UA_NetworkMessage_encodeBinary(const UA_NetworkMessage* src, UA_Byte **bufPos, + const UA_Byte *bufEnd) { + /* UADPVersion + UADP Flags */ + UA_Byte v = src->version; + if(src->publisherIdEnabled) + v |= NM_PUBLISHER_ID_ENABLED_MASK; - /* Remaining members are covered by calloc zeroing out the memory */ - newSub->session = session; - newSub->subscriptionId = subscriptionId; - newSub->state = UA_SUBSCRIPTIONSTATE_NORMAL; /* The first publish response is sent immediately */ - /* Even if the first publish response is a keepalive the sequence number is 1. - * This can happen by a subscription without a monitored item (see CTT test scripts). */ - newSub->nextSequenceNumber = 1; - TAILQ_INIT(&newSub->retransmissionQueue); - TAILQ_INIT(&newSub->notificationQueue); - return newSub; -} + if(src->groupHeaderEnabled) + v |= NM_GROUP_HEADER_ENABLED_MASK; -void -UA_Subscription_deleteMembers(UA_Server *server, UA_Subscription *sub) { - Subscription_unregisterPublishCallback(server, sub); + if(src->payloadHeaderEnabled) + v |= NM_PAYLOAD_HEADER_ENABLED_MASK; - /* Delete monitored Items */ - UA_MonitoredItem *mon, *tmp_mon; - LIST_FOREACH_SAFE(mon, &sub->monitoredItems, listEntry, tmp_mon) { - UA_LOG_INFO_SESSION(server->config.logger, sub->session, - "Subscription %u | MonitoredItem %i | " - "Deleted the MonitoredItem", sub->subscriptionId, - mon->monitoredItemId); - MonitoredItem_delete(server, mon); + if(UA_NetworkMessage_ExtendedFlags1Enabled(src)) + v |= NM_EXTENDEDFLAGS1_ENABLED_MASK; + + UA_StatusCode rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // ExtendedFlags1 + if(UA_NetworkMessage_ExtendedFlags1Enabled(src)) { + v = (UA_Byte)src->publisherIdType; + + if(src->dataSetClassIdEnabled) + v |= NM_DATASET_CLASSID_ENABLED_MASK; + + if(src->securityEnabled) + v |= NM_SECURITY_ENABLED_MASK; + + if(src->timestampEnabled) + v |= NM_TIMESTAMP_ENABLED_MASK; + + if(src->picosecondsEnabled) + v |= NM_PICOSECONDS_ENABLED_MASK; + + if(UA_NetworkMessage_ExtendedFlags2Enabled(src)) + v |= NM_EXTENDEDFLAGS2_ENABLED_MASK; + + rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // ExtendedFlags2 + if(UA_NetworkMessage_ExtendedFlags2Enabled(src)) { + v = (UA_Byte)src->networkMessageType; + // shift left 2 bit + v = (UA_Byte) (v << NM_SHIFT_LEN); + + if(src->chunkMessage) + v |= NM_CHUNK_MESSAGE_MASK; + + if(src->promotedFieldsEnabled) + v |= NM_PROMOTEDFIELDS_ENABLED_MASK; + + rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } } - sub->monitoredItemsSize = 0; - /* Delete Retransmission Queue */ - UA_NotificationMessageEntry *nme, *nme_tmp; - TAILQ_FOREACH_SAFE(nme, &sub->retransmissionQueue, listEntry, nme_tmp) { - TAILQ_REMOVE(&sub->retransmissionQueue, nme, listEntry); - UA_NotificationMessage_deleteMembers(&nme->message); - UA_free(nme); - --sub->session->totalRetransmissionQueueSize; - --sub->retransmissionQueueSize; + // PublisherId + if(src->publisherIdEnabled) { + switch (src->publisherIdType) { + case UA_PUBLISHERDATATYPE_BYTE: + rv = UA_Byte_encodeBinary(&(src->publisherId.publisherIdByte), bufPos, bufEnd); + break; + + case UA_PUBLISHERDATATYPE_UINT16: + rv = UA_UInt16_encodeBinary(&(src->publisherId.publisherIdUInt16), bufPos, bufEnd); + break; + + case UA_PUBLISHERDATATYPE_UINT32: + rv = UA_UInt32_encodeBinary(&(src->publisherId.publisherIdUInt32), bufPos, bufEnd); + break; + + case UA_PUBLISHERDATATYPE_UINT64: + rv = UA_UInt64_encodeBinary(&(src->publisherId.publisherIdUInt64), bufPos, bufEnd); + break; + + case UA_PUBLISHERDATATYPE_STRING: + rv = UA_String_encodeBinary(&(src->publisherId.publisherIdString), bufPos, bufEnd); + break; + + default: + rv = UA_STATUSCODE_BADINTERNALERROR; + break; + } + + if(rv != UA_STATUSCODE_GOOD) + return rv; } - UA_assert(sub->retransmissionQueueSize == 0); - UA_LOG_INFO_SESSION(server->config.logger, sub->session, - "Subscription %u | Deleted the Subscription", - sub->subscriptionId); + // DataSetClassId + if(src->dataSetClassIdEnabled) { + rv = UA_Guid_encodeBinary(&(src->dataSetClassId), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // Group Header + if(src->groupHeaderEnabled) { + v = 0; + + if(src->groupHeader.writerGroupIdEnabled) + v |= GROUP_HEADER_WRITER_GROUPID_ENABLED; + + if(src->groupHeader.groupVersionEnabled) + v |= GROUP_HEADER_GROUP_VERSION_ENABLED; + + if(src->groupHeader.networkMessageNumberEnabled) + v |= GROUP_HEADER_NM_NUMBER_ENABLED; + + if(src->groupHeader.sequenceNumberEnabled) + v |= GROUP_HEADER_SEQUENCE_NUMBER_ENABLED; + + rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if(src->groupHeader.writerGroupIdEnabled) { + rv = UA_UInt16_encodeBinary(&(src->groupHeader.writerGroupId), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(src->groupHeader.groupVersionEnabled) { + rv = UA_UInt32_encodeBinary(&(src->groupHeader.groupVersion), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(src->groupHeader.networkMessageNumberEnabled) { + rv = UA_UInt16_encodeBinary(&(src->groupHeader.networkMessageNumber), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(src->groupHeader.sequenceNumberEnabled) { + rv = UA_UInt16_encodeBinary(&(src->groupHeader.sequenceNumber), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // Payload-Header + if(src->payloadHeaderEnabled) { + if(src->networkMessageType != UA_NETWORKMESSAGE_DATASET) + return UA_STATUSCODE_BADNOTIMPLEMENTED; + + rv = UA_Byte_encodeBinary(&(src->payloadHeader.dataSetPayloadHeader.count), bufPos, bufEnd); + + if(src->payloadHeader.dataSetPayloadHeader.dataSetWriterIds == NULL) + return UA_STATUSCODE_BADENCODINGERROR; + + for(UA_Byte i = 0; i < src->payloadHeader.dataSetPayloadHeader.count; i++) { + rv = UA_UInt16_encodeBinary(&(src->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[i]), + bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // Timestamp + if(src->timestampEnabled) + rv = UA_DateTime_encodeBinary(&(src->timestamp), bufPos, bufEnd); + + // Picoseconds + if(src->picosecondsEnabled) + rv = UA_UInt16_encodeBinary(&(src->picoseconds), bufPos, bufEnd); + + // PromotedFields + if(src->promotedFieldsEnabled) { + /* Size (calculate & encode) */ + UA_UInt16 pfSize = 0; + for(UA_UInt16 i = 0; i < src->promotedFieldsSize; i++) + pfSize = (UA_UInt16) (pfSize + UA_Variant_calcSizeBinary(&src->promotedFields[i])); + rv |= UA_UInt16_encodeBinary(&pfSize, bufPos, bufEnd); + + for (UA_UInt16 i = 0; i < src->promotedFieldsSize; i++) + rv |= UA_Variant_encodeBinary(&(src->promotedFields[i]), bufPos, bufEnd); + } + + // SecurityHeader + if(src->securityEnabled) { + // SecurityFlags + v = 0; + if(src->securityHeader.networkMessageSigned) + v |= SECURITY_HEADER_NM_SIGNED; + + if(src->securityHeader.networkMessageEncrypted) + v |= SECURITY_HEADER_NM_ENCRYPTED; + + if(src->securityHeader.securityFooterEnabled) + v |= SECURITY_HEADER_SEC_FOOTER_ENABLED; + + if(src->securityHeader.forceKeyReset) + v |= SECURITY_HEADER_FORCE_KEY_RESET; + + rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // SecurityTokenId + rv = UA_UInt32_encodeBinary(&src->securityHeader.securityTokenId, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // NonceLength + rv = UA_Byte_encodeBinary(&src->securityHeader.nonceLength, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // MessageNonce + for (UA_Byte i = 0; i < src->securityHeader.nonceLength; i++) { + rv = UA_Byte_encodeBinary(&(src->securityHeader.messageNonce.data[i]), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // SecurityFooterSize + if(src->securityHeader.securityFooterEnabled) { + rv = UA_UInt16_encodeBinary(&src->securityHeader.securityFooterSize, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // Payload + if(src->networkMessageType != UA_NETWORKMESSAGE_DATASET) + return UA_STATUSCODE_BADNOTIMPLEMENTED; + + UA_Byte count = 1; + + if(src->payloadHeaderEnabled) { + count = src->payloadHeader.dataSetPayloadHeader.count; + if(count > 1) { + for (UA_Byte i = 0; i < count; i++) { + // initially calculate the size, if not specified + UA_UInt16 sz = 0; + if((src->payload.dataSetPayload.sizes != NULL) && + (src->payload.dataSetPayload.sizes[i] != 0)) { + sz = src->payload.dataSetPayload.sizes[i]; + } else { + sz = (UA_UInt16)UA_DataSetMessage_calcSizeBinary(&src->payload.dataSetPayload.dataSetMessages[i]); + } + + rv = UA_UInt16_encodeBinary(&sz, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + } + + for(UA_Byte i = 0; i < count; i++) { + rv = UA_DataSetMessage_encodeBinary(&(src->payload.dataSetPayload.dataSetMessages[i]), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(src->securityEnabled) { + // SecurityFooter + if(src->securityHeader.securityFooterEnabled) { + for(UA_Byte i = 0; i < src->securityHeader.securityFooterSize; i++) { + rv = UA_Byte_encodeBinary(&(src->securityFooter.data[i]), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // Signature + if(src->securityHeader.networkMessageSigned) { + rv = UA_ByteString_encodeBinary(&(src->signature), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + return UA_STATUSCODE_GOOD; } -UA_MonitoredItem * -UA_Subscription_getMonitoredItem(UA_Subscription *sub, UA_UInt32 monitoredItemId) { - UA_MonitoredItem *mon; - LIST_FOREACH(mon, &sub->monitoredItems, listEntry) { - if(mon->monitoredItemId == monitoredItemId) +static UA_StatusCode +UA_NetworkMessage_decodeBinaryInternal(const UA_ByteString *src, size_t *offset, + UA_NetworkMessage* dst) { + memset(dst, 0, sizeof(UA_NetworkMessage)); + UA_Byte v = 0; + UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, &v); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + dst->version = v & NM_VERSION_MASK; + + if((v & NM_PUBLISHER_ID_ENABLED_MASK) != 0) + dst->publisherIdEnabled = true; + + if((v & NM_GROUP_HEADER_ENABLED_MASK) != 0) + dst->groupHeaderEnabled = true; + + if((v & NM_PAYLOAD_HEADER_ENABLED_MASK) != 0) + dst->payloadHeaderEnabled = true; + + if((v & NM_EXTENDEDFLAGS1_ENABLED_MASK) != 0) { + v = 0; + rv = UA_Byte_decodeBinary(src, offset, &v); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + dst->publisherIdType = (UA_PublisherIdDatatype)(v & NM_PUBLISHER_ID_MASK); + if((v & NM_DATASET_CLASSID_ENABLED_MASK) != 0) + dst->dataSetClassIdEnabled = true; + + if((v & NM_SECURITY_ENABLED_MASK) != 0) + dst->securityEnabled = true; + + if((v & NM_TIMESTAMP_ENABLED_MASK) != 0) + dst->timestampEnabled = true; + + if((v & NM_PICOSECONDS_ENABLED_MASK) != 0) + dst->picosecondsEnabled = true; + + if((v & NM_EXTENDEDFLAGS2_ENABLED_MASK) != 0) { + v = 0; + rv = UA_Byte_decodeBinary(src, offset, &v); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if((v & NM_CHUNK_MESSAGE_MASK) != 0) + dst->chunkMessage = true; + + if((v & NM_PROMOTEDFIELDS_ENABLED_MASK) != 0) + dst->promotedFieldsEnabled = true; + + v = v & NM_NETWORK_MSG_TYPE_MASK; + v = (UA_Byte) (v >> NM_SHIFT_LEN); + dst->networkMessageType = (UA_NetworkMessageType)v; + } + } + + if(dst->publisherIdEnabled) { + switch (dst->publisherIdType) { + case UA_PUBLISHERDATATYPE_BYTE: + rv = UA_Byte_decodeBinary(src, offset, &(dst->publisherId.publisherIdByte)); + break; + + case UA_PUBLISHERDATATYPE_UINT16: + rv = UA_UInt16_decodeBinary(src, offset, &(dst->publisherId.publisherIdUInt16)); + break; + + case UA_PUBLISHERDATATYPE_UINT32: + rv = UA_UInt32_decodeBinary(src, offset, &(dst->publisherId.publisherIdUInt32)); + break; + + case UA_PUBLISHERDATATYPE_UINT64: + rv = UA_UInt64_decodeBinary(src, offset, &(dst->publisherId.publisherIdUInt64)); break; + + case UA_PUBLISHERDATATYPE_STRING: + rv = UA_String_decodeBinary(src, offset, &(dst->publisherId.publisherIdString)); + break; + + default: + rv = UA_STATUSCODE_BADINTERNALERROR; + break; + } + + if(rv != UA_STATUSCODE_GOOD) + return rv; } - return mon; + + if(dst->dataSetClassIdEnabled) { + rv = UA_Guid_decodeBinary(src, offset, &(dst->dataSetClassId)); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // GroupHeader + if(dst->groupHeaderEnabled) { + v = 0; + rv = UA_Byte_decodeBinary(src, offset, &v); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if((v & GROUP_HEADER_WRITER_GROUPID_ENABLED) != 0) + dst->groupHeader.writerGroupIdEnabled = true; + + if((v & GROUP_HEADER_GROUP_VERSION_ENABLED) != 0) + dst->groupHeader.groupVersionEnabled = true; + + if((v & GROUP_HEADER_NM_NUMBER_ENABLED) != 0) + dst->groupHeader.networkMessageNumberEnabled = true; + + if((v & GROUP_HEADER_SEQUENCE_NUMBER_ENABLED) != 0) + dst->groupHeader.sequenceNumberEnabled = true; + + if(dst->groupHeader.writerGroupIdEnabled) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->groupHeader.writerGroupId); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(dst->groupHeader.groupVersionEnabled) { + rv = UA_UInt32_decodeBinary(src, offset, &dst->groupHeader.groupVersion); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(dst->groupHeader.networkMessageNumberEnabled) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->groupHeader.networkMessageNumber); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(dst->groupHeader.sequenceNumberEnabled) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->groupHeader.sequenceNumber); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // Payload-Header + if(dst->payloadHeaderEnabled) { + if(dst->networkMessageType != UA_NETWORKMESSAGE_DATASET) + return UA_STATUSCODE_BADNOTIMPLEMENTED; + + rv = UA_Byte_decodeBinary(src, offset, &dst->payloadHeader.dataSetPayloadHeader.count); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + dst->payloadHeader.dataSetPayloadHeader.dataSetWriterIds = + (UA_UInt16 *)UA_Array_new(dst->payloadHeader.dataSetPayloadHeader.count, + &UA_TYPES[UA_TYPES_UINT16]); + for (UA_Byte i = 0; i < dst->payloadHeader.dataSetPayloadHeader.count; i++) { + rv = UA_UInt16_decodeBinary(src, offset, + &dst->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[i]); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // Timestamp + if(dst->timestampEnabled) { + rv = UA_DateTime_decodeBinary(src, offset, &(dst->timestamp)); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // Picoseconds + if(dst->picosecondsEnabled) { + rv = UA_UInt16_decodeBinary(src, offset, &(dst->picoseconds)); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // PromotedFields + if(dst->promotedFieldsEnabled) { + // Size + UA_UInt16 promotedFieldsSize = 0; + rv = UA_UInt16_decodeBinary(src, offset, &promotedFieldsSize); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // promotedFieldsSize: here size in Byte, not the number of objects! + if(promotedFieldsSize > 0) { + // store offset, later compared with promotedFieldsSize + size_t offsetEnd = (*offset) + promotedFieldsSize; + + unsigned int counter = 0; + do { + if(counter == 0) { + dst->promotedFields = (UA_Variant*)UA_malloc(UA_TYPES[UA_TYPES_VARIANT].memSize); + // set promotedFieldsSize to the number of objects + dst->promotedFieldsSize = (UA_UInt16) (counter + 1); + } else { + dst->promotedFields = (UA_Variant*) + UA_realloc(dst->promotedFields, + UA_TYPES[UA_TYPES_VARIANT].memSize * (counter + 1)); + // set promotedFieldsSize to the number of objects + dst->promotedFieldsSize = (UA_UInt16) (counter + 1); + } + + UA_Variant_init(&dst->promotedFields[counter]); + rv = UA_Variant_decodeBinary(src, offset, &dst->promotedFields[counter]); + if(rv != UA_STATUSCODE_GOOD) + return rv; + counter++; + } while ((*offset) < offsetEnd); + } + } + + // SecurityHeader + if(dst->securityEnabled) { + // SecurityFlags + v = 0; + rv = UA_Byte_decodeBinary(src, offset, &v); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if((v & SECURITY_HEADER_NM_SIGNED) != 0) + dst->securityHeader.networkMessageSigned = true; + + if((v & SECURITY_HEADER_NM_ENCRYPTED) != 0) + dst->securityHeader.networkMessageEncrypted = true; + + if((v & SECURITY_HEADER_SEC_FOOTER_ENABLED) != 0) + dst->securityHeader.securityFooterEnabled = true; + + if((v & SECURITY_HEADER_FORCE_KEY_RESET) != 0) + dst->securityHeader.forceKeyReset = true; + + // SecurityTokenId + rv = UA_UInt32_decodeBinary(src, offset, &dst->securityHeader.securityTokenId); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // NonceLength + rv = UA_Byte_decodeBinary(src, offset, &dst->securityHeader.nonceLength); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // MessageNonce + if(dst->securityHeader.nonceLength > 0) { + rv = UA_ByteString_allocBuffer(&dst->securityHeader.messageNonce, + dst->securityHeader.nonceLength); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + for (UA_Byte i = 0; i < dst->securityHeader.nonceLength; i++) { + rv = UA_Byte_decodeBinary(src, offset, &(dst->securityHeader.messageNonce.data[i])); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // SecurityFooterSize + if(dst->securityHeader.securityFooterEnabled) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->securityHeader.securityFooterSize); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // Payload + if(dst->networkMessageType != UA_NETWORKMESSAGE_DATASET) + return UA_STATUSCODE_BADNOTIMPLEMENTED; + + UA_Byte count = 1; + if(dst->payloadHeaderEnabled) { + count = dst->payloadHeader.dataSetPayloadHeader.count; + if(count > 1) { + dst->payload.dataSetPayload.sizes = (UA_UInt16 *)UA_Array_new(count, &UA_TYPES[UA_TYPES_UINT16]); + for (UA_Byte i = 0; i < count; i++) { + rv = UA_UInt16_decodeBinary(src, offset, &(dst->payload.dataSetPayload.sizes[i])); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + } + + dst->payload.dataSetPayload.dataSetMessages = (UA_DataSetMessage*) + UA_calloc(count, sizeof(UA_DataSetMessage)); + for(UA_Byte i = 0; i < count; i++) { + rv = UA_DataSetMessage_decodeBinary(src, offset, &(dst->payload.dataSetPayload.dataSetMessages[i])); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if(dst->securityEnabled) { + // SecurityFooter + if(dst->securityHeader.securityFooterEnabled && (dst->securityHeader.securityFooterSize > 0)) { + rv = UA_ByteString_allocBuffer(&dst->securityFooter, dst->securityHeader.securityFooterSize); + if (rv != UA_STATUSCODE_GOOD) + return rv; + + for (UA_Byte i = 0; i < dst->securityHeader.securityFooterSize; i++) { + rv = UA_Byte_decodeBinary(src, offset, &(dst->securityFooter.data[i])); + if (rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + // Signature + if(dst->securityHeader.networkMessageSigned) { + rv = UA_ByteString_decodeBinary(src, offset, &(dst->signature)); + if (rv != UA_STATUSCODE_GOOD) + return rv; + } + } + + return UA_STATUSCODE_GOOD; } UA_StatusCode -UA_Subscription_deleteMonitoredItem(UA_Server *server, UA_Subscription *sub, - UA_UInt32 monitoredItemId) { - /* Find the MonitoredItem */ - UA_MonitoredItem *mon; - LIST_FOREACH(mon, &sub->monitoredItems, listEntry) { - if(mon->monitoredItemId == monitoredItemId) +UA_NetworkMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_NetworkMessage* dst) { + UA_StatusCode retval = UA_NetworkMessage_decodeBinaryInternal(src, offset, dst); + + if(retval != UA_STATUSCODE_GOOD) + UA_NetworkMessage_deleteMembers(dst); + + return retval; +} + +size_t UA_NetworkMessage_calcSizeBinary(const UA_NetworkMessage* p) { + size_t retval = 0; + UA_Byte byte; + size_t size = UA_Byte_calcSizeBinary(&byte); // UADPVersion + UADPFlags + if(UA_NetworkMessage_ExtendedFlags1Enabled(p)) { + size += UA_Byte_calcSizeBinary(&byte); + if(UA_NetworkMessage_ExtendedFlags2Enabled(p)) + size += UA_Byte_calcSizeBinary(&byte); + } + + if(p->publisherIdEnabled) { + switch (p->publisherIdType) { + case UA_PUBLISHERDATATYPE_BYTE: + size += UA_Byte_calcSizeBinary(&p->publisherId.publisherIdByte); break; + + case UA_PUBLISHERDATATYPE_UINT16: + size += UA_UInt16_calcSizeBinary(&p->publisherId.publisherIdUInt16); + break; + + case UA_PUBLISHERDATATYPE_UINT32: + size += UA_UInt32_calcSizeBinary(&p->publisherId.publisherIdUInt32); + break; + + case UA_PUBLISHERDATATYPE_UINT64: + size += UA_UInt64_calcSizeBinary(&p->publisherId.publisherIdUInt64); + break; + + case UA_PUBLISHERDATATYPE_STRING: + size += UA_String_calcSizeBinary(&p->publisherId.publisherIdString); + break; + } } - if(!mon) - return UA_STATUSCODE_BADMONITOREDITEMIDINVALID; - UA_LOG_INFO_SESSION(server->config.logger, sub->session, - "Subscription %u | MonitoredItem %i | " - "Delete the MonitoredItem", sub->subscriptionId, - mon->monitoredItemId); + if(p->dataSetClassIdEnabled) + size += UA_Guid_calcSizeBinary(&p->dataSetClassId); - /* Remove the MonitoredItem */ - MonitoredItem_delete(server, mon); - sub->monitoredItemsSize--; - return UA_STATUSCODE_GOOD; + // Group Header + if(p->groupHeaderEnabled) { + size += UA_Byte_calcSizeBinary(&byte); + + if(p->groupHeader.writerGroupIdEnabled) + size += UA_UInt16_calcSizeBinary(&p->groupHeader.writerGroupId); + + if(p->groupHeader.groupVersionEnabled) + size += UA_UInt32_calcSizeBinary(&p->groupHeader.groupVersion); + + if(p->groupHeader.networkMessageNumberEnabled) + size += UA_UInt16_calcSizeBinary(&p->groupHeader.networkMessageNumber); + + if(p->groupHeader.sequenceNumberEnabled) + size += UA_UInt16_calcSizeBinary(&p->groupHeader.sequenceNumber); + } + + // Payload Header + if(p->payloadHeaderEnabled) { + if(p->networkMessageType == UA_NETWORKMESSAGE_DATASET) { + size += UA_Byte_calcSizeBinary(&p->payloadHeader.dataSetPayloadHeader.count); + if(p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds != NULL) { + size += UA_UInt16_calcSizeBinary(&p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds[0]) * + p->payloadHeader.dataSetPayloadHeader.count; + } else { + return 0; /* no dataSetWriterIds given! */ + } + } else { + // not implemented + } + } + + if(p->timestampEnabled) + size += UA_DateTime_calcSizeBinary(&p->timestamp); + + if(p->picosecondsEnabled) + size += UA_UInt16_calcSizeBinary(&p->picoseconds); + + if(p->promotedFieldsEnabled) { + size += UA_UInt16_calcSizeBinary(&p->promotedFieldsSize); + for (UA_UInt16 i = 0; i < p->promotedFieldsSize; i++) + size += UA_Variant_calcSizeBinary(&p->promotedFields[i]); + } + + if(p->securityEnabled) { + size += UA_Byte_calcSizeBinary(&byte); + size += UA_UInt32_calcSizeBinary(&p->securityHeader.securityTokenId); + size += UA_Byte_calcSizeBinary(&p->securityHeader.nonceLength); + if(p->securityHeader.nonceLength > 0) + size += (UA_Byte_calcSizeBinary(&p->securityHeader.messageNonce.data[0]) * p->securityHeader.nonceLength); + if(p->securityHeader.securityFooterEnabled) + size += UA_UInt16_calcSizeBinary(&p->securityHeader.securityFooterSize); + } + + if(p->networkMessageType == UA_NETWORKMESSAGE_DATASET) { + UA_Byte count = 1; + if(p->payloadHeaderEnabled) { + count = p->payloadHeader.dataSetPayloadHeader.count; + if(count > 1) + size += UA_UInt16_calcSizeBinary(&(p->payload.dataSetPayload.sizes[0])) * count; + } + + for (size_t i = 0; i < count; i++) + size += UA_DataSetMessage_calcSizeBinary(&(p->payload.dataSetPayload.dataSetMessages[i])); + } + + if (p->securityEnabled) { + if (p->securityHeader.securityFooterEnabled) + size += p->securityHeader.securityFooterSize; + + if (p->securityHeader.networkMessageSigned) + size += UA_ByteString_calcSizeBinary(&p->signature); + } + + retval = size; + return retval; } void -UA_Subscription_addMonitoredItem(UA_Subscription *sub, UA_MonitoredItem *newMon) { - sub->monitoredItemsSize++; - LIST_INSERT_HEAD(&sub->monitoredItems, newMon, listEntry); -} +UA_NetworkMessage_deleteMembers(UA_NetworkMessage* p) { + if(p->promotedFieldsEnabled) + UA_Array_delete(p->promotedFields, p->promotedFieldsSize, &UA_TYPES[UA_TYPES_VARIANT]); + + if(p->securityEnabled && (p->securityHeader.nonceLength > 0)) + UA_ByteString_deleteMembers(&p->securityHeader.messageNonce); + + if(p->networkMessageType == UA_NETWORKMESSAGE_DATASET) { + if(p->payloadHeaderEnabled) { + if(p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds != NULL) { + UA_Array_delete(p->payloadHeader.dataSetPayloadHeader.dataSetWriterIds, + p->payloadHeader.dataSetPayloadHeader.count, &UA_TYPES[UA_TYPES_UINT16]); + } -static void -removeOldestRetransmissionMessage(UA_Session *session) { - UA_NotificationMessageEntry *oldestEntry = NULL; - UA_Subscription *oldestSub = NULL; + if(p->payload.dataSetPayload.sizes != NULL) { + UA_Array_delete(p->payload.dataSetPayload.sizes, + p->payloadHeader.dataSetPayloadHeader.count, &UA_TYPES[UA_TYPES_UINT16]); + } + } - UA_Subscription *sub; - LIST_FOREACH(sub, &session->serverSubscriptions, listEntry) { - UA_NotificationMessageEntry *first = - TAILQ_LAST(&sub->retransmissionQueue, ListOfNotificationMessages); - if(!first) - continue; - if(!oldestEntry || oldestEntry->message.publishTime > first->message.publishTime) { - oldestEntry = first; - oldestSub = sub; + if(p->payload.dataSetPayload.dataSetMessages != NULL) { + UA_Byte count = 1; + if(p->payloadHeaderEnabled) + count = p->payloadHeader.dataSetPayloadHeader.count; + + for (size_t i = 0; i < count; i++) + UA_DataSetMessage_free(&(p->payload.dataSetPayload.dataSetMessages[i])); + + UA_free(p->payload.dataSetPayload.dataSetMessages); } } - UA_assert(oldestEntry); - UA_assert(oldestSub); - TAILQ_REMOVE(&oldestSub->retransmissionQueue, oldestEntry, listEntry); - UA_NotificationMessage_deleteMembers(&oldestEntry->message); - UA_free(oldestEntry); - --session->totalRetransmissionQueueSize; - --oldestSub->retransmissionQueueSize; + if(p->securityHeader.securityFooterEnabled && (p->securityHeader.securityFooterSize > 0)) + UA_ByteString_deleteMembers(&p->securityFooter); + + if(p->messageIdEnabled){ + UA_String_deleteMembers(&p->messageId); + } + + if(p->publisherIdEnabled && p->publisherIdType == UA_PUBLISHERDATATYPE_STRING){ + UA_String_deleteMembers(&p->publisherId.publisherIdString); + } + + memset(p, 0, sizeof(UA_NetworkMessage)); } -static void -UA_Subscription_addRetransmissionMessage(UA_Server *server, UA_Subscription *sub, - UA_NotificationMessageEntry *entry) { - /* Release the oldest entry if there is not enough space */ - if(server->config.maxRetransmissionQueueSize > 0 && - sub->session->totalRetransmissionQueueSize >= server->config.maxRetransmissionQueueSize) { - UA_LOG_WARNING_SESSION(server->config.logger, sub->session, "Subscription %u | " - "Retransmission queue overflow", sub->subscriptionId); - removeOldestRetransmissionMessage(sub->session); +void UA_NetworkMessage_delete(UA_NetworkMessage* p) { + UA_NetworkMessage_deleteMembers(p); +} + +UA_Boolean +UA_NetworkMessage_ExtendedFlags1Enabled(const UA_NetworkMessage* src) { + UA_Boolean retval = false; + + if((src->publisherIdType != UA_PUBLISHERDATATYPE_BYTE) + || src->dataSetClassIdEnabled + || src->securityEnabled + || src->timestampEnabled + || src->picosecondsEnabled + || UA_NetworkMessage_ExtendedFlags2Enabled(src)) + { + retval = true; } - /* Add entry */ - TAILQ_INSERT_TAIL(&sub->retransmissionQueue, entry, listEntry); - ++sub->session->totalRetransmissionQueueSize; - ++sub->retransmissionQueueSize; + return retval; +} + +UA_Boolean +UA_NetworkMessage_ExtendedFlags2Enabled(const UA_NetworkMessage* src) { + if(src->chunkMessage || src->promotedFieldsEnabled || + src->networkMessageType != UA_NETWORKMESSAGE_DATASET) + return true; + return false; +} + +UA_Boolean +UA_DataSetMessageHeader_DataSetFlags2Enabled(const UA_DataSetMessageHeader* src) { + if(src->dataSetMessageType != UA_DATASETMESSAGE_DATAKEYFRAME || + src->timestampEnabled || src->picoSecondsIncluded) + return true; + return false; } UA_StatusCode -UA_Subscription_removeRetransmissionMessage(UA_Subscription *sub, UA_UInt32 sequenceNumber) { - /* Find the retransmission message */ - UA_NotificationMessageEntry *entry; - TAILQ_FOREACH(entry, &sub->retransmissionQueue, listEntry) { - if(entry->message.sequenceNumber == sequenceNumber) - break; +UA_DataSetMessageHeader_encodeBinary(const UA_DataSetMessageHeader* src, UA_Byte **bufPos, + const UA_Byte *bufEnd) { + UA_Byte v; + // DataSetFlags1 + v = (UA_Byte)src->fieldEncoding; + // shift left 1 bit + v = (UA_Byte)(v << DS_MH_SHIFT_LEN); + + if(src->dataSetMessageValid) + v |= DS_MESSAGEHEADER_DS_MSG_VALID; + + if(src->dataSetMessageSequenceNrEnabled) + v |= DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK; + + if(src->statusEnabled) + v |= DS_MESSAGEHEADER_STATUS_ENABLED_MASK; + + if(src->configVersionMajorVersionEnabled) + v |= DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK; + + if(src->configVersionMinorVersionEnabled) + v |= DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK; + + if(UA_DataSetMessageHeader_DataSetFlags2Enabled(src)) + v |= DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK; + + UA_StatusCode rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + // DataSetFlags2 + if(UA_DataSetMessageHeader_DataSetFlags2Enabled(src)) { + v = (UA_Byte)src->dataSetMessageType; + + if(src->timestampEnabled) + v |= DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK; + + if(src->picoSecondsIncluded) + v |= DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK; + + rv = UA_Byte_encodeBinary(&v, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // DataSetMessageSequenceNr + if(src->dataSetMessageSequenceNrEnabled) { + rv = UA_UInt16_encodeBinary(&src->dataSetMessageSequenceNr, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // Timestamp + if(src->timestampEnabled) { + rv = UA_DateTime_encodeBinary(&(src->timestamp), bufPos, bufEnd); /* UtcTime */ + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // PicoSeconds + if(src->picoSecondsIncluded) { + rv = UA_UInt16_encodeBinary(&(src->picoSeconds), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // Status + if(src->statusEnabled) { + rv = UA_UInt16_encodeBinary(&(src->status), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // ConfigVersionMajorVersion + if(src->configVersionMajorVersionEnabled) { + rv = UA_UInt32_encodeBinary(&(src->configVersionMajorVersion), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + // ConfigVersionMinorVersion + if(src->configVersionMinorVersionEnabled) { + rv = UA_UInt32_encodeBinary(&(src->configVersionMinorVersion), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +UA_DataSetMessageHeader_decodeBinary(const UA_ByteString *src, size_t *offset, + UA_DataSetMessageHeader* dst) { + memset(dst, 0, sizeof(UA_DataSetMessageHeader)); + UA_Byte v = 0; + UA_StatusCode rv = UA_Byte_decodeBinary(src, offset, &v); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + UA_Byte v2 = v & DS_MESSAGEHEADER_FIELD_ENCODING_MASK; + v2 = (UA_Byte)(v2 >> DS_MH_SHIFT_LEN); + dst->fieldEncoding = (UA_FieldEncoding)v2; + + if((v & DS_MESSAGEHEADER_DS_MSG_VALID) != 0) + dst->dataSetMessageValid = true; + + if((v & DS_MESSAGEHEADER_SEQ_NR_ENABLED_MASK) != 0) + dst->dataSetMessageSequenceNrEnabled = true; + + if((v & DS_MESSAGEHEADER_STATUS_ENABLED_MASK) != 0) + dst->statusEnabled = true; + + if((v & DS_MESSAGEHEADER_CONFIGMAJORVERSION_ENABLED_MASK) != 0) + dst->configVersionMajorVersionEnabled = true; + + if((v & DS_MESSAGEHEADER_CONFIGMINORVERSION_ENABLED_MASK) != 0) + dst->configVersionMinorVersionEnabled = true; + + if((v & DS_MESSAGEHEADER_FLAGS2_ENABLED_MASK) != 0) { + v = 0; + rv = UA_Byte_decodeBinary(src, offset, &v); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + dst->dataSetMessageType = (UA_DataSetMessageType)(v & DS_MESSAGEHEADER_DS_MESSAGE_TYPE_MASK); + + if((v & DS_MESSAGEHEADER_TIMESTAMP_ENABLED_MASK) != 0) + dst->timestampEnabled = true; + + if((v & DS_MESSAGEHEADER_PICOSECONDS_INCLUDED_MASK) != 0) + dst->picoSecondsIncluded = true; + } else { + dst->dataSetMessageType = UA_DATASETMESSAGE_DATAKEYFRAME; + dst->picoSecondsIncluded = false; + } + + if(dst->dataSetMessageSequenceNrEnabled) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->dataSetMessageSequenceNr); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } else { + dst->dataSetMessageSequenceNr = 0; + } + + if(dst->timestampEnabled) { + rv = UA_DateTime_decodeBinary(src, offset, &dst->timestamp); /* UtcTime */ + if(rv != UA_STATUSCODE_GOOD) + return rv; + } else { + dst->timestamp = 0; + } + + if(dst->picoSecondsIncluded) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->picoSeconds); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } else { + dst->picoSeconds = 0; + } + + if(dst->statusEnabled) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->status); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } else { + dst->status = 0; + } + + if(dst->configVersionMajorVersionEnabled) { + rv = UA_UInt32_decodeBinary(src, offset, &dst->configVersionMajorVersion); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } else { + dst->configVersionMajorVersion = 0; + } + + if(dst->configVersionMinorVersionEnabled) { + rv = UA_UInt32_decodeBinary(src, offset, &dst->configVersionMinorVersion); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } else { + dst->configVersionMinorVersion = 0; } - if(!entry) - return UA_STATUSCODE_BADSEQUENCENUMBERUNKNOWN; - /* Remove the retransmission message */ - TAILQ_REMOVE(&sub->retransmissionQueue, entry, listEntry); - --sub->session->totalRetransmissionQueueSize; - --sub->retransmissionQueueSize; - UA_NotificationMessage_deleteMembers(&entry->message); - UA_free(entry); return UA_STATUSCODE_GOOD; } -/* Iterate over the monitoreditems of the subscription, starting at mon, and - * move notifications into the response. */ +size_t +UA_DataSetMessageHeader_calcSizeBinary(const UA_DataSetMessageHeader* p) { + UA_Byte byte; + size_t size = UA_Byte_calcSizeBinary(&byte); // DataSetMessage Type + Flags + if(UA_DataSetMessageHeader_DataSetFlags2Enabled(p)) + size += UA_Byte_calcSizeBinary(&byte); + + if(p->dataSetMessageSequenceNrEnabled) + size += UA_UInt16_calcSizeBinary(&p->dataSetMessageSequenceNr); + + if(p->timestampEnabled) + size += UA_DateTime_calcSizeBinary(&p->timestamp); /* UtcTime */ + + if(p->picoSecondsIncluded) + size += UA_UInt16_calcSizeBinary(&p->picoSeconds); + + if(p->statusEnabled) + size += UA_UInt16_calcSizeBinary(&p->status); + + if(p->configVersionMajorVersionEnabled) + size += UA_UInt32_calcSizeBinary(&p->configVersionMajorVersion); + + if(p->configVersionMinorVersionEnabled) + size += UA_UInt32_calcSizeBinary(&p->configVersionMinorVersion); + + return size; +} + +UA_StatusCode +UA_DataSetMessage_encodeBinary(const UA_DataSetMessage* src, UA_Byte **bufPos, + const UA_Byte *bufEnd) { + UA_StatusCode rv = UA_DataSetMessageHeader_encodeBinary(&src->header, bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if(src->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) { + if(src->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) { + rv = UA_UInt16_encodeBinary(&(src->data.keyFrameData.fieldCount), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + + if(src->header.fieldEncoding == UA_FIELDENCODING_VARIANT) { + for (UA_UInt16 i = 0; i < src->data.keyFrameData.fieldCount; i++) { + rv = UA_Variant_encodeBinary(&(src->data.keyFrameData.dataSetFields[i].value), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } else if(src->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) { + return UA_STATUSCODE_BADNOTIMPLEMENTED; + } else if(src->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) { + for (UA_UInt16 i = 0; i < src->data.keyFrameData.fieldCount; i++) { + rv = UA_DataValue_encodeBinary(&(src->data.keyFrameData.dataSetFields[i]), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + } else if(src->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) { + // Encode Delta Frame + // Here the FieldCount is always present + rv = UA_UInt16_encodeBinary(&(src->data.keyFrameData.fieldCount), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if(src->header.fieldEncoding == UA_FIELDENCODING_VARIANT) { + for (UA_UInt16 i = 0; i < src->data.deltaFrameData.fieldCount; i++) { + rv = UA_UInt16_encodeBinary(&(src->data.deltaFrameData.deltaFrameFields[i].fieldIndex), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + rv = UA_Variant_encodeBinary(&(src->data.deltaFrameData.deltaFrameFields[i].fieldValue.value), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } else if(src->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) { + return UA_STATUSCODE_BADNOTIMPLEMENTED; + } else if(src->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) { + for (UA_UInt16 i = 0; i < src->data.deltaFrameData.fieldCount; i++) { + rv = UA_UInt16_encodeBinary(&(src->data.deltaFrameData.deltaFrameFields[i].fieldIndex), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + rv = UA_DataValue_encodeBinary(&(src->data.deltaFrameData.deltaFrameFields[i].fieldValue), bufPos, bufEnd); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + } else if(src->header.dataSetMessageType != UA_DATASETMESSAGE_KEEPALIVE) { + return UA_STATUSCODE_BADNOTIMPLEMENTED; + } + + /* Keep-Alive Message contains no Payload Data */ + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +UA_DataSetMessage_decodeBinary(const UA_ByteString *src, size_t *offset, UA_DataSetMessage* dst) { + memset(dst, 0, sizeof(UA_DataSetMessage)); + UA_StatusCode rv = UA_DataSetMessageHeader_decodeBinary(src, offset, &dst->header); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if(dst->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) { + if(dst->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->data.keyFrameData.fieldCount); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if(dst->header.fieldEncoding == UA_FIELDENCODING_VARIANT) { + dst->data.keyFrameData.dataSetFields = + (UA_DataValue *)UA_Array_new(dst->data.keyFrameData.fieldCount, &UA_TYPES[UA_TYPES_DATAVALUE]); + for (UA_UInt16 i = 0; i < dst->data.keyFrameData.fieldCount; i++) { + UA_DataValue_init(&dst->data.keyFrameData.dataSetFields[i]); + rv = UA_Variant_decodeBinary(src, offset, &dst->data.keyFrameData.dataSetFields[i].value); + if(rv != UA_STATUSCODE_GOOD) + return rv; + dst->data.keyFrameData.dataSetFields[i].hasValue = true; + } + } else if(dst->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) { + return UA_STATUSCODE_BADNOTIMPLEMENTED; + } else if(dst->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) { + dst->data.keyFrameData.dataSetFields = + (UA_DataValue *)UA_Array_new(dst->data.keyFrameData.fieldCount, &UA_TYPES[UA_TYPES_DATAVALUE]); + for (UA_UInt16 i = 0; i < dst->data.keyFrameData.fieldCount; i++) { + rv = UA_DataValue_decodeBinary(src, offset, &(dst->data.keyFrameData.dataSetFields[i])); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + } + } else if(dst->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) { + if(dst->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->data.deltaFrameData.fieldCount); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + if(dst->header.fieldEncoding == UA_FIELDENCODING_VARIANT) { + size_t memsize = sizeof(UA_DataSetMessage_DeltaFrameField) * dst->data.deltaFrameData.fieldCount; + dst->data.deltaFrameData.deltaFrameFields = (UA_DataSetMessage_DeltaFrameField*)UA_malloc(memsize); + for (UA_UInt16 i = 0; i < dst->data.deltaFrameData.fieldCount; i++) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->data.deltaFrameData.deltaFrameFields[i].fieldIndex); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + UA_DataValue_init(&dst->data.deltaFrameData.deltaFrameFields[i].fieldValue); + rv = UA_Variant_decodeBinary(src, offset, &dst->data.deltaFrameData.deltaFrameFields[i].fieldValue.value); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + dst->data.deltaFrameData.deltaFrameFields[i].fieldValue.hasValue = true; + } + } else if(dst->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) { + return UA_STATUSCODE_BADNOTIMPLEMENTED; + } else if(dst->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) { + size_t memsize = sizeof(UA_DataSetMessage_DeltaFrameField) * dst->data.deltaFrameData.fieldCount; + dst->data.deltaFrameData.deltaFrameFields = (UA_DataSetMessage_DeltaFrameField*)UA_malloc(memsize); + for (UA_UInt16 i = 0; i < dst->data.deltaFrameData.fieldCount; i++) { + rv = UA_UInt16_decodeBinary(src, offset, &dst->data.deltaFrameData.deltaFrameFields[i].fieldIndex); + if(rv != UA_STATUSCODE_GOOD) + return rv; + + rv = UA_DataValue_decodeBinary(src, offset, &(dst->data.deltaFrameData.deltaFrameFields[i].fieldValue)); + if(rv != UA_STATUSCODE_GOOD) + return rv; + } + } + } + } else if(dst->header.dataSetMessageType != UA_DATASETMESSAGE_KEEPALIVE) { + return UA_STATUSCODE_BADNOTIMPLEMENTED; + } + + /* Keep-Alive Message contains no Payload Data */ + return UA_STATUSCODE_GOOD; +} + +size_t +UA_DataSetMessage_calcSizeBinary(const UA_DataSetMessage* p) { + size_t size = UA_DataSetMessageHeader_calcSizeBinary(&p->header); + + if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) { + if(p->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) + size += UA_calcSizeBinary(&p->data.keyFrameData.fieldCount, &UA_TYPES[UA_TYPES_UINT16]); + + if(p->header.fieldEncoding == UA_FIELDENCODING_VARIANT) { + for (UA_UInt16 i = 0; i < p->data.keyFrameData.fieldCount; i++) + size += UA_calcSizeBinary(&p->data.keyFrameData.dataSetFields[i].value, &UA_TYPES[UA_TYPES_VARIANT]); + } else if(p->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) { + // not implemented + } else if(p->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) { + for (UA_UInt16 i = 0; i < p->data.keyFrameData.fieldCount; i++) + size += UA_calcSizeBinary(&p->data.keyFrameData.dataSetFields[i], &UA_TYPES[UA_TYPES_DATAVALUE]); + } + } else if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) { + if(p->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) + size += UA_calcSizeBinary(&p->data.deltaFrameData.fieldCount, &UA_TYPES[UA_TYPES_UINT16]); + + if(p->header.fieldEncoding == UA_FIELDENCODING_VARIANT) { + for (UA_UInt16 i = 0; i < p->data.deltaFrameData.fieldCount; i++) { + size += UA_calcSizeBinary(&p->data.deltaFrameData.deltaFrameFields[i].fieldIndex, &UA_TYPES[UA_TYPES_UINT16]); + size += UA_calcSizeBinary(&p->data.deltaFrameData.deltaFrameFields[i].fieldValue.value, &UA_TYPES[UA_TYPES_VARIANT]); + } + } else if(p->header.fieldEncoding == UA_FIELDENCODING_RAWDATA) { + // not implemented + } else if(p->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) { + for (UA_UInt16 i = 0; i < p->data.deltaFrameData.fieldCount; i++) { + size += UA_calcSizeBinary(&p->data.deltaFrameData.deltaFrameFields[i].fieldIndex, &UA_TYPES[UA_TYPES_UINT16]); + size += UA_calcSizeBinary(&p->data.deltaFrameData.deltaFrameFields[i].fieldValue, &UA_TYPES[UA_TYPES_DATAVALUE]); + } + } + } + + /* KeepAlive-Message contains no Payload Data */ + return size; +} + +void UA_DataSetMessage_free(const UA_DataSetMessage* p) { + if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) { + if(p->data.keyFrameData.dataSetFields != NULL) + UA_Array_delete(p->data.keyFrameData.dataSetFields, p->data.keyFrameData.fieldCount, + &UA_TYPES[UA_TYPES_DATAVALUE]); + /* Json keys */ + if(p->data.keyFrameData.fieldNames != NULL){ + UA_Array_delete(p->data.keyFrameData.fieldNames, p->data.keyFrameData.fieldCount, + &UA_TYPES[UA_TYPES_STRING]); + } + } else if(p->header.dataSetMessageType == UA_DATASETMESSAGE_DATADELTAFRAME) { + if(p->data.deltaFrameData.deltaFrameFields != NULL) { + for(UA_UInt16 i = 0; i < p->data.deltaFrameData.fieldCount; i++) { + if(p->header.fieldEncoding == UA_FIELDENCODING_DATAVALUE) { + UA_DataValue_deleteMembers(&p->data.deltaFrameData.deltaFrameFields[i].fieldValue); + } else if(p->header.fieldEncoding == UA_FIELDENCODING_VARIANT) { + UA_Variant_deleteMembers(&p->data.deltaFrameData.deltaFrameFields[i].fieldValue.value); + } + } + UA_free(p->data.deltaFrameData.deltaFrameFields); + } + } +} +#endif /* UA_ENABLE_PUBSUB */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/pubsub/ua_pubsub.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner) + * Copyright (c) 2019 Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright (c) 2019 Kalycito Infotech Private Limited + */ + + +#ifdef UA_ENABLE_PUBSUB /* conditional compilation */ + + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL +#endif + +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES +#endif + +#define UA_MAX_STACKBUF 512 /* Max size of network messages on the stack */ +#define UA_MAX_SIZENAME 64 /* Max size of Qualified Name of Subscribed Variable */ + +/* Forward declaration */ static void -moveNotificationsFromMonitoredItems(UA_Subscription *sub, UA_MonitoredItemNotification *mins, - size_t minsSize) { - size_t pos = 0; - UA_Notification *notification, *notification_tmp; - TAILQ_FOREACH_SAFE(notification, &sub->notificationQueue, globalEntry, notification_tmp) { - if(pos >= minsSize) - return; +UA_WriterGroup_deleteMembers(UA_Server *server, UA_WriterGroup *writerGroup); +static void +UA_DataSetField_deleteMembers(UA_DataSetField *field); - UA_MonitoredItem *mon = notification->mon; +/**********************************************/ +/* Connection */ +/**********************************************/ - /* Remove the notification from the queues */ - TAILQ_REMOVE(&sub->notificationQueue, notification, globalEntry); - TAILQ_REMOVE(&mon->queue, notification, listEntry); - --mon->queueSize; - --sub->notificationQueueSize; +UA_StatusCode +UA_PubSubConnectionConfig_copy(const UA_PubSubConnectionConfig *src, + UA_PubSubConnectionConfig *dst) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + memcpy(dst, src, sizeof(UA_PubSubConnectionConfig)); + retVal |= UA_String_copy(&src->name, &dst->name); + retVal |= UA_Variant_copy(&src->address, &dst->address); + retVal |= UA_String_copy(&src->transportProfileUri, &dst->transportProfileUri); + retVal |= UA_Variant_copy(&src->connectionTransportSettings, &dst->connectionTransportSettings); + if(src->connectionPropertiesSize > 0){ + dst->connectionProperties = (UA_KeyValuePair *) + UA_calloc(src->connectionPropertiesSize, sizeof(UA_KeyValuePair)); + if(!dst->connectionProperties){ + return UA_STATUSCODE_BADOUTOFMEMORY; + } + for(size_t i = 0; i < src->connectionPropertiesSize; i++){ + retVal |= UA_QualifiedName_copy(&src->connectionProperties[i].key, + &dst->connectionProperties[i].key); + retVal |= UA_Variant_copy(&src->connectionProperties[i].value, + &dst->connectionProperties[i].value); + } + } + return retVal; +} - /* Move the content to the response */ - UA_MonitoredItemNotification *min = &mins[pos]; - min->clientHandle = mon->clientHandle; - if(mon->monitoredItemType == UA_MONITOREDITEMTYPE_CHANGENOTIFY) { - min->value = notification->data.value; - } else { - /* TODO implementation for events */ +UA_StatusCode +UA_Server_getPubSubConnectionConfig(UA_Server *server, const UA_NodeId connection, + UA_PubSubConnectionConfig *config) { + if(!config) + return UA_STATUSCODE_BADINVALIDARGUMENT; + + UA_PubSubConnection *currentPubSubConnection = + UA_PubSubConnection_findConnectionbyId(server, connection); + if(!currentPubSubConnection) + return UA_STATUSCODE_BADNOTFOUND; + + UA_PubSubConnectionConfig tmpPubSubConnectionConfig; + //deep copy of the actual config + UA_PubSubConnectionConfig_copy(currentPubSubConnection->config, &tmpPubSubConnectionConfig); + *config = tmpPubSubConnectionConfig; + return UA_STATUSCODE_GOOD; +} + +UA_PubSubConnection * +UA_PubSubConnection_findConnectionbyId(UA_Server *server, UA_NodeId connectionIdentifier) { + for(size_t i = 0; i < server->pubSubManager.connectionsSize; i++){ + if(UA_NodeId_equal(&connectionIdentifier, &server->pubSubManager.connections[i].identifier)){ + return &server->pubSubManager.connections[i]; } - UA_free(notification); - ++pos; } + return NULL; } -static UA_StatusCode -prepareNotificationMessage(UA_Subscription *sub, UA_NotificationMessage *message, - size_t notifications) { - /* Array of ExtensionObject to hold different kinds of notifications - * (currently only DataChangeNotifications) */ - message->notificationData = UA_ExtensionObject_new(); - if(!message->notificationData) - return UA_STATUSCODE_BADOUTOFMEMORY; - message->notificationDataSize = 1; +void +UA_PubSubConnectionConfig_deleteMembers(UA_PubSubConnectionConfig *connectionConfig) { + UA_String_deleteMembers(&connectionConfig->name); + UA_String_deleteMembers(&connectionConfig->transportProfileUri); + UA_Variant_deleteMembers(&connectionConfig->connectionTransportSettings); + UA_Variant_deleteMembers(&connectionConfig->address); + for(size_t i = 0; i < connectionConfig->connectionPropertiesSize; i++){ + UA_QualifiedName_deleteMembers(&connectionConfig->connectionProperties[i].key); + UA_Variant_deleteMembers(&connectionConfig->connectionProperties[i].value); + } + UA_free(connectionConfig->connectionProperties); +} + +void +UA_PubSubConnection_deleteMembers(UA_Server *server, UA_PubSubConnection *connection) { + //delete connection config + UA_PubSubConnectionConfig_deleteMembers(connection->config); + //remove contained WriterGroups + UA_WriterGroup *writerGroup, *tmpWriterGroup; + LIST_FOREACH_SAFE(writerGroup, &connection->writerGroups, listEntry, tmpWriterGroup){ + UA_Server_removeWriterGroup(server, writerGroup->identifier); + } + /* remove contained ReaderGroups */ + UA_ReaderGroup *readerGroups, *tmpReaderGroup; + LIST_FOREACH_SAFE(readerGroups, &connection->readerGroups, listEntry, tmpReaderGroup){ + UA_Server_removeReaderGroup(server, readerGroups->identifier); + } - /* Allocate Notification */ - UA_DataChangeNotification *dcn = UA_DataChangeNotification_new(); - if(!dcn) { - UA_NotificationMessage_deleteMembers(message); + UA_NodeId_deleteMembers(&connection->identifier); + if(connection->channel){ + connection->channel->close(connection->channel); + } + UA_free(connection->config); +} + +UA_StatusCode +UA_Server_addWriterGroup(UA_Server *server, const UA_NodeId connection, + const UA_WriterGroupConfig *writerGroupConfig, + UA_NodeId *writerGroupIdentifier) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(!writerGroupConfig) + return UA_STATUSCODE_BADINVALIDARGUMENT; + //search the connection by the given connectionIdentifier + UA_PubSubConnection *currentConnectionContext = + UA_PubSubConnection_findConnectionbyId(server, connection); + if(!currentConnectionContext) + return UA_STATUSCODE_BADNOTFOUND; + + //allocate memory for new WriterGroup + UA_WriterGroup *newWriterGroup = (UA_WriterGroup *) UA_calloc(1, sizeof(UA_WriterGroup)); + if(!newWriterGroup) return UA_STATUSCODE_BADOUTOFMEMORY; + + newWriterGroup->linkedConnection = currentConnectionContext->identifier; + UA_PubSubManager_generateUniqueNodeId(server, &newWriterGroup->identifier); + if(writerGroupIdentifier){ + UA_NodeId_copy(&newWriterGroup->identifier, writerGroupIdentifier); + } + + //deep copy of the config + UA_WriterGroupConfig tmpWriterGroupConfig; + retVal |= UA_WriterGroupConfig_copy(writerGroupConfig, &tmpWriterGroupConfig); + + if(!tmpWriterGroupConfig.messageSettings.content.decoded.type) { + UA_UadpWriterGroupMessageDataType *wgm = UA_UadpWriterGroupMessageDataType_new(); + tmpWriterGroupConfig.messageSettings.content.decoded.data = wgm; + tmpWriterGroupConfig.messageSettings.content.decoded.type = + &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]; + tmpWriterGroupConfig.messageSettings.encoding = UA_EXTENSIONOBJECT_DECODED; + } + + newWriterGroup->config = tmpWriterGroupConfig; + retVal |= UA_WriterGroup_addPublishCallback(server, newWriterGroup); + LIST_INSERT_HEAD(¤tConnectionContext->writerGroups, newWriterGroup, listEntry); +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + addWriterGroupRepresentation(server, newWriterGroup); +#endif + return retVal; +} + +UA_StatusCode +UA_Server_removeWriterGroup(UA_Server *server, const UA_NodeId writerGroup){ + UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, writerGroup); + if(!wg) + return UA_STATUSCODE_BADNOTFOUND; + + UA_PubSubConnection *connection = + UA_PubSubConnection_findConnectionbyId(server, wg->linkedConnection); + if(!connection) + return UA_STATUSCODE_BADNOTFOUND; + + //unregister the publish callback + UA_PubSubManager_removeRepeatedPubSubCallback(server, wg->publishCallbackId); +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + removeGroupRepresentation(server, wg); +#endif + + UA_WriterGroup_deleteMembers(server, wg); + LIST_REMOVE(wg, listEntry); + UA_free(wg); + return UA_STATUSCODE_GOOD; +} + +/**********************************************/ +/* ReaderGroup */ +/**********************************************/ + +/** + * Add ReaderGroup to connection. + * + * @param server + * @param connectionIdentifier + * @param readerGroupConfiguration + * @param readerGroupIdentifier + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_addReaderGroup(UA_Server *server, UA_NodeId connectionIdentifier, + const UA_ReaderGroupConfig *readerGroupConfig, + UA_NodeId *readerGroupIdentifier) { + UA_StatusCode retval = UA_STATUSCODE_GOOD; + UA_ReaderGroupConfig tmpReaderGroupConfig; + + /* Search the connection by the given connectionIdentifier */ + if(!readerGroupConfig) { + return UA_STATUSCODE_BADINVALIDARGUMENT; } - UA_ExtensionObject *data = message->notificationData; - data->encoding = UA_EXTENSIONOBJECT_DECODED; - data->content.decoded.data = dcn; - data->content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]; - - /* Allocate array of notifications */ - dcn->monitoredItems = (UA_MonitoredItemNotification *) - UA_Array_new(notifications, - &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]); - if(!dcn->monitoredItems) { - UA_NotificationMessage_deleteMembers(message); + + /* Search the connection by the given connectionIdentifier */ + UA_PubSubConnection *currentConnectionContext = UA_PubSubConnection_findConnectionbyId(server, connectionIdentifier); + if(!currentConnectionContext) { + return UA_STATUSCODE_BADNOTFOUND; + } + + /* Allocate memory for new reader group */ + UA_ReaderGroup *newGroup = (UA_ReaderGroup *)UA_calloc(1, sizeof(UA_ReaderGroup)); + if(!newGroup) { return UA_STATUSCODE_BADOUTOFMEMORY; } - dcn->monitoredItemsSize = notifications; - /* Move notifications into the response .. the point of no return */ + /* Generate nodeid for the readergroup identifier */ + newGroup->linkedConnection = currentConnectionContext->identifier; + UA_PubSubManager_generateUniqueNodeId(server, &newGroup->identifier); + if(readerGroupIdentifier) { + UA_NodeId_copy(&newGroup->identifier, readerGroupIdentifier); + } + + /* Deep copy of the config */ + retval |= UA_ReaderGroupConfig_copy(readerGroupConfig, &tmpReaderGroupConfig); + newGroup->config = tmpReaderGroupConfig; + retval |= UA_ReaderGroup_addSubscribeCallback(server, newGroup); + LIST_INSERT_HEAD(¤tConnectionContext->readerGroups, newGroup, listEntry); + currentConnectionContext->readerGroupsSize++; + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + addReaderGroupRepresentation(server, newGroup); +#endif + + return retval; +} + +/** + * Remove ReaderGroup from connection and delete contained readers. + * + * @param server + * @param groupIdentifier + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_removeReaderGroup(UA_Server *server, UA_NodeId groupIdentifier) { + UA_ReaderGroup* readerGroup = UA_ReaderGroup_findRGbyId(server, groupIdentifier); + if(readerGroup == NULL) { + return UA_STATUSCODE_BADNOTFOUND; + } + + /* Search the connection to which the given readergroup is connected to */ + UA_PubSubConnection *connection = UA_PubSubConnection_findConnectionbyId(server, readerGroup->linkedConnection); + if(connection == NULL) { + return UA_STATUSCODE_BADNOTFOUND; + } - moveNotificationsFromMonitoredItems(sub, dcn->monitoredItems, notifications); + /* Unregister subscribe callback */ + UA_PubSubManager_removeRepeatedPubSubCallback(server, readerGroup->subscribeCallbackId); +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + /* To Do:RemoveGroupRepresentation(server, &readerGroup->identifier) */ +#endif + /* UA_Server_ReaderGroup_delete also removes itself from the list */ + UA_Server_ReaderGroup_delete(server, readerGroup); + /* Remove readerGroup from Connection */ + LIST_REMOVE(readerGroup, listEntry); + UA_free(readerGroup); return UA_STATUSCODE_GOOD; } -/* According to OPC Unified Architecture, Part 4 5.13.1.1 i) The value 0 is - * never used for the sequence number */ -static UA_UInt32 -UA_Subscription_nextSequenceNumber(UA_UInt32 sequenceNumber) { - UA_UInt32 nextSequenceNumber = sequenceNumber + 1; - if(nextSequenceNumber == 0) - nextSequenceNumber = 1; - return nextSequenceNumber; +/** + * To Do: + * Update ReaderGroup configuration. + * + * @param server + * @param readerGroupIdentifier + * @param readerGroupConfiguration + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_ReaderGroup_updateConfig(UA_Server *server, UA_NodeId readerGroupIdentifier, + const UA_ReaderGroupConfig *config) { + return UA_STATUSCODE_BADNOTIMPLEMENTED; } -static void -publishCallback(UA_Server *server, UA_Subscription *sub) { - sub->readyNotifications = sub->notificationQueueSize; - UA_Subscription_publish(server, sub); +/** + * Get ReaderGroup configuration. + * + * @param server + * @param groupIdentifier + * @param readerGroupConfiguration + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_ReaderGroup_getConfig(UA_Server *server, UA_NodeId readerGroupIdentifier, + UA_ReaderGroupConfig *config) { + if(!config) { + return UA_STATUSCODE_BADINVALIDARGUMENT; + } + + /* Identify the readergroup through the readerGroupIdentifier */ + UA_ReaderGroup *currentReaderGroup = UA_ReaderGroup_findRGbyId(server, readerGroupIdentifier); + if(!currentReaderGroup) { + return UA_STATUSCODE_BADNOTFOUND; + } + + UA_ReaderGroupConfig tmpReaderGroupConfig; + /* deep copy of the actual config */ + UA_ReaderGroupConfig_copy(¤tReaderGroup->config, &tmpReaderGroupConfig); + *config = tmpReaderGroupConfig; + return UA_STATUSCODE_GOOD; } -void -UA_Subscription_publish(UA_Server *server, UA_Subscription *sub) { - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, "Subscription %u | " - "Publish Callback", sub->subscriptionId); - /* Dequeue a response */ - UA_PublishResponseEntry *pre = UA_Session_dequeuePublishReq(sub->session); - if(pre) { - sub->currentLifetimeCount = 0; /* Reset the LifetimeCounter */ - } else { - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, - "Subscription %u | The publish queue is empty", - sub->subscriptionId); - ++sub->currentLifetimeCount; +/* To Do UA_ReaderGroupConfig delete */ - if(sub->currentLifetimeCount > sub->lifeTimeCount) { - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, - "Subscription %u | End of lifetime " - "for subscription", sub->subscriptionId); - UA_Session_deleteSubscription(server, sub->session, sub->subscriptionId); - /* TODO: send a StatusChangeNotification with Bad_Timeout */ - return; +/** + * Delete ReaderGroup. + * + * @param server + * @param groupIdentifier + */ +void UA_Server_ReaderGroup_delete(UA_Server* server, UA_ReaderGroup *readerGroup) { + /* To Do Call UA_ReaderGroupConfig_delete */ + UA_DataSetReader *dataSetReader, *tmpDataSetReader; + LIST_FOREACH_SAFE(dataSetReader, &readerGroup->readers, listEntry, tmpDataSetReader) { + UA_DataSetReader_delete(server, dataSetReader); + } + UA_PubSubConnection* pConn = UA_PubSubConnection_findConnectionbyId(server, readerGroup->linkedConnection); + if(pConn != NULL) { + pConn->readerGroupsSize--; + } + + /* Delete ReaderGroup and its members */ + UA_String_deleteMembers(&readerGroup->config.name); + UA_NodeId_deleteMembers(&readerGroup->linkedConnection); + UA_NodeId_deleteMembers(&readerGroup->identifier); +} + +/** + * Copy ReaderGroup configuration. + * + * @param source + * @param destination + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_ReaderGroupConfig_copy(const UA_ReaderGroupConfig *src, + UA_ReaderGroupConfig *dst) { + UA_String_copy(&src->name, &dst->name); + /* Currently simple memcpy only */ + memcpy(&dst->securityParameters, &src->securityParameters, sizeof(UA_PubSubSecurityParameters)); + return UA_STATUSCODE_GOOD; +} + + +static UA_DataSetReader * +getReaderFromIdentifier(UA_Server *server, UA_NetworkMessage *pMsg, UA_PubSubConnection *pConnection) { + if(pConnection->readerGroupsSize == 1) { + if(LIST_FIRST(&pConnection->readerGroups)->readersCount == 1) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "only 1 DataSetReader available. This one will be used."); + return LIST_FIRST(&LIST_FIRST(&pConnection->readerGroups)->readers); } } - if (sub->readyNotifications > sub->notificationQueueSize) - sub->readyNotifications = sub->notificationQueueSize; + if(!pMsg->publisherIdEnabled) + return NULL; - /* Count the available notifications */ - UA_UInt32 notifications = sub->readyNotifications; - if(!sub->publishingEnabled) - notifications = 0; + UA_ReaderGroup* readerGroup; + LIST_FOREACH(readerGroup, &pConnection->readerGroups, listEntry) { + UA_DataSetReader *tmpReader; + LIST_FOREACH(tmpReader, &readerGroup->readers, listEntry) { + switch (pMsg->publisherIdType) { + case UA_PUBLISHERDATATYPE_BYTE: + if(tmpReader->config.publisherId.type == &UA_TYPES[UA_TYPES_BYTE] && + pMsg->publisherIdType == UA_PUBLISHERDATATYPE_BYTE && + pMsg->publisherId.publisherIdByte == *(UA_Byte*)tmpReader->config.publisherId.data) { + return tmpReader; + } + break; + case UA_PUBLISHERDATATYPE_UINT16: + if(tmpReader->config.publisherId.type == &UA_TYPES[UA_TYPES_UINT16] && + pMsg->publisherIdType == UA_PUBLISHERDATATYPE_UINT16 && + pMsg->publisherId.publisherIdUInt16 == *(UA_UInt16*)tmpReader->config.publisherId.data) { + return tmpReader; + } + break; + case UA_PUBLISHERDATATYPE_UINT32: + if(tmpReader->config.publisherId.type == &UA_TYPES[UA_TYPES_UINT32] && + pMsg->publisherIdType == UA_PUBLISHERDATATYPE_UINT32 && + pMsg->publisherId.publisherIdUInt32 == *(UA_UInt32*)tmpReader->config.publisherId.data) { + return tmpReader; + } + break; + case UA_PUBLISHERDATATYPE_UINT64: + if(tmpReader->config.publisherId.type == &UA_TYPES[UA_TYPES_UINT64] && + pMsg->publisherIdType == UA_PUBLISHERDATATYPE_UINT64 && + pMsg->publisherId.publisherIdUInt64 == *(UA_UInt64*)tmpReader->config.publisherId.data) { + return tmpReader; + } + break; + case UA_PUBLISHERDATATYPE_STRING: + if(tmpReader->config.publisherId.type == &UA_TYPES[UA_TYPES_STRING] && + pMsg->publisherIdType == UA_PUBLISHERDATATYPE_STRING && + UA_String_equal(&pMsg->publisherId.publisherIdString, (UA_String*)tmpReader->config.publisherId.data)) { + return tmpReader; + } + break; + default: + return NULL; + } + } + } - UA_Boolean moreNotifications = false; - if(notifications > sub->notificationsPerPublish) { - notifications = sub->notificationsPerPublish; - moreNotifications = true; + return NULL; +} + +/** + * Process NetworkMessage. + * + * @param server + * @param networkmessage + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_processNetworkMessage(UA_Server *server, UA_NetworkMessage *pMsg, + UA_PubSubConnection *pConnection) { + if(!pMsg || !pConnection) + return UA_STATUSCODE_BADINVALIDARGUMENT; + + /* To Do The condition with dataSetWriterIdAvailable and WriterGroupIdAvailable to be handled + * when pMsg->groupHeaderEnabled, pMsg->dataSetClassIdEnabled, pMsg->payloadHeaderEnabled + * Here some filtering is possible */ + + UA_DataSetReader* dataSetReaderErg = getReaderFromIdentifier(server, pMsg, pConnection); + + /* No Reader with the specified id found */ + if(!dataSetReaderErg) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "No DataSetReader found with PublisherId"); + return UA_STATUSCODE_BADNOTFOUND; /* TODO: Check the return code */ } - /* Return if no notifications and no keepalive */ - if(notifications == 0) { - ++sub->currentKeepAliveCount; - if(sub->currentKeepAliveCount < sub->maxKeepAliveCount) { - if(pre) - UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */ - return; + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "DataSetReader found with PublisherId"); + + UA_Byte anzDataSets = 1; + if(pMsg->payloadHeaderEnabled) + anzDataSets = pMsg->payloadHeader.dataSetPayloadHeader.count; + for(UA_Byte iterator = 0; iterator < anzDataSets; iterator++) { + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Process Msg with DataSetReader!"); + UA_Server_DataSetReader_process(server, dataSetReaderErg, &pMsg->payload.dataSetPayload.dataSetMessages[iterator]); + } + + /* To Do the condition with dataSetWriterId and WriterGroupId + * else condition for dataSetWriterIdAvailable and writerGroupIdAvailable) */ + + return UA_STATUSCODE_GOOD; +} + +/** + * Find ReaderGroup with its identifier. + * + * @param server + * @param groupIdentifier + * @return the ReaderGroup or NULL if not found + */ +UA_ReaderGroup * UA_ReaderGroup_findRGbyId(UA_Server *server, UA_NodeId identifier) { + for (size_t iteratorConn = 0; iteratorConn < server->pubSubManager.connectionsSize; iteratorConn++) { + UA_ReaderGroup* readerGroup = NULL; + LIST_FOREACH(readerGroup, &server->pubSubManager.connections[iteratorConn].readerGroups, listEntry) { + if(UA_NodeId_equal(&identifier, &readerGroup->identifier)) { + return readerGroup; + } + } - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, - "Subscription %u | Sending a KeepAlive", - sub->subscriptionId); } + return NULL; +} - /* We want to send a response. Is it possible? */ - UA_SecureChannel *channel = sub->session->header.channel; - if(!channel || !pre) { - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, - "Subscription %u | Want to send a publish response but can't. " - "The subscription is late.", sub->subscriptionId); - sub->state = UA_SUBSCRIPTIONSTATE_LATE; - if(pre) - UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */ - return; +/** + * Find a DataSetReader with its identifier + * + * @param server + * @param identifier + * @return the DataSetReader or NULL if not found + */ +UA_DataSetReader *UA_ReaderGroup_findDSRbyId(UA_Server *server, UA_NodeId identifier) { + for (size_t iteratorConn = 0; iteratorConn < server->pubSubManager.connectionsSize; iteratorConn++) { + UA_ReaderGroup* readerGroup = NULL; + LIST_FOREACH(readerGroup, &server->pubSubManager.connections[iteratorConn].readerGroups, listEntry) { + UA_DataSetReader *tmpReader; + LIST_FOREACH(tmpReader, &readerGroup->readers, listEntry) { + if(UA_NodeId_equal(&tmpReader->identifier, &identifier)) { + return tmpReader; + } + + } + } } + return NULL; +} + +/**********************************************/ +/* DataSetReader */ +/**********************************************/ + +/** + * Add a DataSetReader to ReaderGroup + * + * @param server + * @param readerGroupIdentifier + * @param dataSetReaderConfig + * @param readerIdentifier + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_addDataSetReader(UA_Server *server, UA_NodeId readerGroupIdentifier, + const UA_DataSetReaderConfig *dataSetReaderConfig, + UA_NodeId *readerIdentifier) { + /* Search the reader group by the given readerGroupIdentifier */ + UA_ReaderGroup *readerGroup = UA_ReaderGroup_findRGbyId(server, readerGroupIdentifier); + + if(!dataSetReaderConfig) { + return UA_STATUSCODE_BADNOTFOUND; + } + + if(readerGroup == NULL) { + return UA_STATUSCODE_BADNOTFOUND; + } + + /* Allocate memory for new DataSetReader */ + UA_DataSetReader *newDataSetReader = (UA_DataSetReader *)UA_calloc(1, sizeof(UA_DataSetReader)); + /* Copy the config into the new dataSetReader */ + UA_DataSetReaderConfig_copy(dataSetReaderConfig, &newDataSetReader->config); + newDataSetReader->linkedReaderGroup = readerGroup->identifier; + UA_PubSubManager_generateUniqueNodeId(server, &newDataSetReader->identifier); + if(readerIdentifier != NULL) { + UA_NodeId_copy(&newDataSetReader->identifier, readerIdentifier); + } + + /* Add the new reader to the group */ + LIST_INSERT_HEAD(&readerGroup->readers, newDataSetReader, listEntry); + readerGroup->readersCount++; + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + addDataSetReaderRepresentation(server, newDataSetReader); +#endif + + return UA_STATUSCODE_GOOD; +} + +/** + * Remove a DataSetReader from ReaderGroup + * + * @param server + * @param readerGroupIdentifier + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_removeDataSetReader(UA_Server *server, UA_NodeId readerIdentifier) { + /* Remove datasetreader given by the identifier */ + UA_DataSetReader *dataSetReader = UA_ReaderGroup_findDSRbyId(server, readerIdentifier); + if(!dataSetReader) { + return UA_STATUSCODE_BADNOTFOUND; + } + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + removeDataSetReaderRepresentation(server, dataSetReader); +#endif + + UA_DataSetReader_delete(server, dataSetReader); + return UA_STATUSCODE_GOOD; +} + +/** + * Update the config of the DataSetReader. + * + * @param server + * @param dataSetReaderIdentifier + * @param readerGroupIdentifier + * @param config + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_DataSetReader_updateConfig(UA_Server *server, UA_NodeId dataSetReaderIdentifier, UA_NodeId readerGroupIdentifier, + const UA_DataSetReaderConfig *config) { + if(config == NULL) { + return UA_STATUSCODE_BADINVALIDARGUMENT; + } + + UA_DataSetReader *currentDataSetReader = UA_ReaderGroup_findDSRbyId(server, dataSetReaderIdentifier); + UA_ReaderGroup *currentReaderGroup = UA_ReaderGroup_findRGbyId(server, readerGroupIdentifier); + if(!currentDataSetReader) { + return UA_STATUSCODE_BADNOTFOUND; + } + + /* The update functionality will be extended during the next PubSub batches. + * Currently is only a change of the publishing interval possible. */ + if(currentDataSetReader->config.writerGroupId != config->writerGroupId) { + UA_PubSubManager_removeRepeatedPubSubCallback(server, currentReaderGroup->subscribeCallbackId); + currentDataSetReader->config.writerGroupId = config->writerGroupId; + UA_ReaderGroup_subscribeCallback(server, currentReaderGroup); + } + else { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "No or unsupported ReaderGroup update."); + } + + return UA_STATUSCODE_GOOD; +} + +/** + * Get the current config of the UA_DataSetReader. + * + * @param server + * @param dataSetReaderIdentifier + * @param config + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_DataSetReader_getConfig(UA_Server *server, UA_NodeId dataSetReaderIdentifier, + UA_DataSetReaderConfig *config) { + if(!config) { + return UA_STATUSCODE_BADINVALIDARGUMENT; + } + + UA_DataSetReader *currentDataSetReader = UA_ReaderGroup_findDSRbyId(server, dataSetReaderIdentifier); + if(!currentDataSetReader) { + return UA_STATUSCODE_BADNOTFOUND; + } + + UA_DataSetReaderConfig tmpReaderConfig; + /* Deep copy of the actual config */ + UA_DataSetReaderConfig_copy(¤tDataSetReader->config, &tmpReaderConfig); + *config = tmpReaderConfig; + return UA_STATUSCODE_GOOD; +} + +/** + * This Method is used to initially set the SubscribedDataSet to TargetVariablesType and to create the list of target Variables of a SubscribedDataSetType. + * + * @param server + * @param dataSetReaderIdentifier + * @param targetVariables + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_Server_DataSetReader_createTargetVariables(UA_Server *server, UA_NodeId dataSetReaderIdentifier, UA_TargetVariablesDataType *targetVariables) { + UA_StatusCode retval = UA_STATUSCODE_BADUNEXPECTEDERROR; + UA_DataSetReader* pDS = UA_ReaderGroup_findDSRbyId(server, dataSetReaderIdentifier); + if(pDS == NULL) { + return UA_STATUSCODE_BADINVALIDARGUMENT; + } + + if(pDS->subscribedDataSetTarget.targetVariablesSize > 0) { + UA_TargetVariablesDataType_deleteMembers(&pDS->subscribedDataSetTarget); + pDS->subscribedDataSetTarget.targetVariablesSize = 0; + pDS->subscribedDataSetTarget.targetVariables = NULL; + } + + /* Set subscribed dataset to TargetVariableType */ + pDS->subscribedDataSetType = UA_PUBSUB_SDS_TARGET; + retval = UA_TargetVariablesDataType_copy(targetVariables, &pDS->subscribedDataSetTarget); + return retval; +} + +/** + * Adds Subscribed Variables from the DataSetMetaData for the given DataSet into the given parent node + * and creates the corresponding data in the targetVariables of the DataSetReader + * + * @param server + * @param parentNode + * @param dataSetReaderIdentifier + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode UA_Server_DataSetReader_addTargetVariables(UA_Server *server, UA_NodeId *parentNode, UA_NodeId dataSetReaderIdentifier, UA_SubscribedDataSetEnumType sdsType) { + if((server == NULL) || (parentNode == NULL)) { + return UA_STATUSCODE_BADINVALIDARGUMENT; + } + + UA_StatusCode retval = UA_STATUSCODE_GOOD; + UA_DataSetReader* pDataSetReader = UA_ReaderGroup_findDSRbyId(server, dataSetReaderIdentifier); + if(pDataSetReader == NULL) { + return UA_STATUSCODE_BADINVALIDARGUMENT; + } + + UA_TargetVariablesDataType targetVars; + targetVars.targetVariablesSize = pDataSetReader->config.dataSetMetaData.fieldsSize; + targetVars.targetVariables = (UA_FieldTargetDataType *)UA_calloc(targetVars.targetVariablesSize, sizeof(UA_FieldTargetDataType)); + for (size_t iteratorField = 0; iteratorField < pDataSetReader->config.dataSetMetaData.fieldsSize; iteratorField++) { + UA_VariableAttributes vAttr = UA_VariableAttributes_default; + vAttr.valueRank = pDataSetReader->config.dataSetMetaData.fields[iteratorField].valueRank; + if(pDataSetReader->config.dataSetMetaData.fields[iteratorField].arrayDimensionsSize > 0) { + retval = UA_Array_copy(pDataSetReader->config.dataSetMetaData.fields[iteratorField].arrayDimensions, pDataSetReader->config.dataSetMetaData.fields[iteratorField].arrayDimensionsSize, (void**)&vAttr.arrayDimensions, &UA_TYPES[UA_TYPES_UINT32]); + if(retval == UA_STATUSCODE_GOOD) { + vAttr.arrayDimensionsSize = pDataSetReader->config.dataSetMetaData.fields[iteratorField].arrayDimensionsSize; + } - /* Prepare the response */ - UA_PublishResponse *response = &pre->response; - UA_NotificationMessage *message = &response->notificationMessage; - UA_NotificationMessageEntry *retransmission = NULL; - if(notifications > 0) { - /* Allocate the retransmission entry */ - retransmission = (UA_NotificationMessageEntry*)UA_malloc(sizeof(UA_NotificationMessageEntry)); - if(!retransmission) { - UA_LOG_WARNING_SESSION(server->config.logger, sub->session, - "Subscription %u | Could not allocate memory for retransmission. " - "The subscription is late.", sub->subscriptionId); - sub->state = UA_SUBSCRIPTIONSTATE_LATE; - UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */ - return; } - /* Prepare the response */ - UA_StatusCode retval = prepareNotificationMessage(sub, message, notifications); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING_SESSION(server->config.logger, sub->session, - "Subscription %u | Could not prepare the notification message. " - "The subscription is late.", sub->subscriptionId); - UA_free(retransmission); - sub->state = UA_SUBSCRIPTIONSTATE_LATE; - UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */ - return; + vAttr.dataType = pDataSetReader->config.dataSetMetaData.fields[iteratorField].dataType; + + vAttr.accessLevel = UA_ACCESSLEVELMASK_READ; + UA_LocalizedText_copy(&pDataSetReader->config.dataSetMetaData.fields[iteratorField].description, &vAttr.description); + UA_QualifiedName qn; + UA_QualifiedName_init(&qn); + char szTmpName[UA_MAX_SIZENAME]; + if(pDataSetReader->config.dataSetMetaData.fields[iteratorField].name.length > 0) { + UA_UInt16 slen = UA_MAX_SIZENAME -1; + vAttr.displayName.locale = UA_STRING("en-US"); + vAttr.displayName.text = pDataSetReader->config.dataSetMetaData.fields[iteratorField].name; + if(pDataSetReader->config.dataSetMetaData.fields[iteratorField].name.length < slen) { + slen = (UA_UInt16)pDataSetReader->config.dataSetMetaData.fields[iteratorField].name.length; + UA_snprintf(szTmpName, sizeof(szTmpName), "%s", (const char*)pDataSetReader->config.dataSetMetaData.fields[iteratorField].name.data); + } + + szTmpName[slen] = '\0'; + qn = UA_QUALIFIEDNAME(1, szTmpName); + } + else { + strcpy(szTmpName, "SubscribedVariable"); + vAttr.displayName = UA_LOCALIZEDTEXT("en-US", szTmpName); + qn = UA_QUALIFIEDNAME(1, "SubscribedVariable"); + } + + /* Add variable to the given parent node */ + UA_NodeId newNode; + retval = UA_Server_addVariableNode(server, UA_NODEID_NULL, *parentNode, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), qn, + UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), vAttr, NULL, &newNode); + if(retval == UA_STATUSCODE_GOOD) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_USERLAND, "addVariableNode %s succeeded", szTmpName); + } + else { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_USERLAND, "addVariableNode: error 0x%x", retval); + } + + UA_FieldTargetDataType_init(&targetVars.targetVariables[iteratorField]); + targetVars.targetVariables[iteratorField].attributeId = UA_ATTRIBUTEID_VALUE; + UA_NodeId_copy(&newNode, &targetVars.targetVariables[iteratorField].targetNodeId); + UA_NodeId_deleteMembers(&newNode); + if(vAttr.arrayDimensionsSize > 0) { + UA_Array_delete(vAttr.arrayDimensions, vAttr.arrayDimensionsSize, &UA_TYPES[UA_TYPES_UINT32]); } } - /* <-- The point of no return --> */ + if(sdsType == UA_PUBSUB_SDS_TARGET) { + retval = UA_Server_DataSetReader_createTargetVariables(server, pDataSetReader->identifier, &targetVars); + } - /* Adjust the number of ready notifications */ - UA_assert(sub->readyNotifications >= notifications); - sub->readyNotifications -= notifications; + UA_TargetVariablesDataType_deleteMembers(&targetVars); + return retval; +} - /* Set up the response */ - response->responseHeader.timestamp = UA_DateTime_now(); - response->subscriptionId = sub->subscriptionId; - response->moreNotifications = moreNotifications; - message->publishTime = response->responseHeader.timestamp; +/** + * Process a NetworkMessage with a DataSetReader. + * + * @param server + * @param dataSetReader + * @param dataSetMsg + */ +void UA_Server_DataSetReader_process(UA_Server *server, UA_DataSetReader *dataSetReader, UA_DataSetMessage* dataSetMsg) { + if((dataSetReader == NULL) || (dataSetMsg == NULL) || (server == NULL)) { + return; + } - /* Set sequence number to message. Started at 1 which is given - * during creating a new subscription. The 1 is required for - * initial publish response with or without an monitored item. */ - message->sequenceNumber = sub->nextSequenceNumber; + if(!dataSetMsg->header.dataSetMessageValid) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "DataSetMessage is discarded: message is not valid"); + /* To Do check ConfigurationVersion*/ + /*if(dataSetMsg->header.configVersionMajorVersionEnabled) + * { + * if(dataSetMsg->header.configVersionMajorVersion != dataSetReader->config.dataSetMetaData.configurationVersion.majorVersion) + * { + * UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, "DataSetMessage is discarded: ConfigurationVersion MajorVersion does not match"); + * return; + * } + } */ + } + else { + if(dataSetMsg->header.dataSetMessageType == UA_DATASETMESSAGE_DATAKEYFRAME) { + if(dataSetMsg->header.fieldEncoding != UA_FIELDENCODING_RAWDATA) { + size_t anzFields = dataSetMsg->data.keyFrameData.fieldCount; + if(dataSetReader->config.dataSetMetaData.fieldsSize < anzFields) { + anzFields = dataSetReader->config.dataSetMetaData.fieldsSize; + } + + if(dataSetReader->subscribedDataSetTarget.targetVariablesSize < anzFields) { + anzFields = dataSetReader->subscribedDataSetTarget.targetVariablesSize; + } + + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + for (UA_UInt16 iteratorField = 0; iteratorField < anzFields; iteratorField++) { + if(dataSetMsg->data.keyFrameData.dataSetFields[iteratorField].hasValue) { + if(dataSetReader->subscribedDataSetTarget.targetVariables[iteratorField].attributeId == UA_ATTRIBUTEID_VALUE) { + retVal = UA_Server_writeValue(server, dataSetReader->subscribedDataSetTarget.targetVariables[iteratorField].targetNodeId, dataSetMsg->data.keyFrameData.dataSetFields[iteratorField].value); + if(retVal != UA_STATUSCODE_GOOD) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "Error Write Value KF %u: 0x%x", iteratorField, retVal); + } + + } + else { + UA_WriteValue writeVal; + UA_WriteValue_init(&writeVal); + writeVal.attributeId = dataSetReader->subscribedDataSetTarget.targetVariables[iteratorField].attributeId; + writeVal.indexRange = dataSetReader->subscribedDataSetTarget.targetVariables[iteratorField].receiverIndexRange; + writeVal.nodeId = dataSetReader->subscribedDataSetTarget.targetVariables[iteratorField].targetNodeId; + UA_DataValue_copy(&dataSetMsg->data.keyFrameData.dataSetFields[iteratorField], &writeVal.value); + retVal = UA_Server_write(server, &writeVal); + if(retVal != UA_STATUSCODE_GOOD) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "Error Write KF %u: 0x%x", iteratorField, retVal); + } + + } + + } + + } + + } + + } - if(notifications > 0) { - /* Put the notification message into the retransmission queue. This - * needs to be done here, so that the message itself is included in the - * available sequence numbers for acknowledgement. */ - retransmission->message = response->notificationMessage; - UA_Subscription_addRetransmissionMessage(server, sub, retransmission); - /* Only if a notification was created, the sequence number must be increased. - * For a keepalive the sequence number can be reused. */ - sub->nextSequenceNumber = UA_Subscription_nextSequenceNumber(sub->nextSequenceNumber); } +} - /* Get the available sequence numbers from the retransmission queue */ - size_t available = sub->retransmissionQueueSize; - UA_STACKARRAY(UA_UInt32, seqNumbers, available); - if(available > 0) { - response->availableSequenceNumbers = seqNumbers; - response->availableSequenceNumbersSize = available; - size_t i = 0; - UA_NotificationMessageEntry *nme; - TAILQ_FOREACH(nme, &sub->retransmissionQueue, listEntry) { - response->availableSequenceNumbers[i] = nme->message.sequenceNumber; - ++i; +/** + * Copy the config of the DataSetReader. + * + * @param src + * @param dst + * @return UA_STATUSCODE_GOOD on success + */ +UA_StatusCode +UA_DataSetReaderConfig_copy(const UA_DataSetReaderConfig *src, + UA_DataSetReaderConfig *dst) { + memset(dst, 0, sizeof(UA_DataSetReaderConfig)); + UA_StatusCode retVal = UA_String_copy(&src->name, &dst->name); + if(retVal != UA_STATUSCODE_GOOD) { + return retVal; + } + + retVal = UA_Variant_copy(&src->publisherId, &dst->publisherId); + if(retVal != UA_STATUSCODE_GOOD) { + return retVal; + } + + dst->writerGroupId = src->writerGroupId; + dst->dataSetWriterId = src->dataSetWriterId; + retVal = UA_DataSetMetaDataType_copy(&src->dataSetMetaData, &dst->dataSetMetaData); + if(retVal != UA_STATUSCODE_GOOD) { + return retVal; + } + + dst->dataSetFieldContentMask = src->dataSetFieldContentMask; + dst->messageReceiveTimeout = src->messageReceiveTimeout; + + /* Currently memcpy is used to copy the securityParameters */ + memcpy(&dst->securityParameters, &src->securityParameters, sizeof(UA_PubSubSecurityParameters)); + retVal = UA_UadpDataSetReaderMessageDataType_copy(&src->messageSettings, &dst->messageSettings); + if(retVal != UA_STATUSCODE_GOOD) { + return retVal; + } + + return UA_STATUSCODE_GOOD; +} + +/** + * Delete the DataSetReader. + * + * @param server + * @param dataSetReader + */ +void UA_DataSetReader_delete(UA_Server *server, UA_DataSetReader *dataSetReader) { + /* Delete DataSetReader config */ + UA_String_deleteMembers(&dataSetReader->config.name); + UA_Variant_deleteMembers(&dataSetReader->config.publisherId); + UA_DataSetMetaDataType_deleteMembers(&dataSetReader->config.dataSetMetaData); + UA_UadpDataSetReaderMessageDataType_deleteMembers(&dataSetReader->config.messageSettings); + UA_TargetVariablesDataType_deleteMembers(&dataSetReader->subscribedDataSetTarget); + + /* Delete DataSetReader */ + UA_ReaderGroup* pGroup = UA_ReaderGroup_findRGbyId(server, dataSetReader->linkedReaderGroup); + if(pGroup != NULL) { + pGroup->readersCount--; + } + + UA_NodeId_deleteMembers(&dataSetReader->identifier); + UA_NodeId_deleteMembers(&dataSetReader->linkedReaderGroup); + /* Remove DataSetReader from group */ + LIST_REMOVE(dataSetReader, listEntry); + /* Free memory allocated for DataSetReader */ + UA_free(dataSetReader); +} + +/**********************************************/ +/* PublishedDataSet */ +/**********************************************/ +UA_StatusCode +UA_PublishedDataSetConfig_copy(const UA_PublishedDataSetConfig *src, + UA_PublishedDataSetConfig *dst) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + memcpy(dst, src, sizeof(UA_PublishedDataSetConfig)); + retVal |= UA_String_copy(&src->name, &dst->name); + switch(src->publishedDataSetType){ + case UA_PUBSUB_DATASET_PUBLISHEDITEMS: + //no additional items + break; + case UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE: + if(src->config.itemsTemplate.variablesToAddSize > 0){ + dst->config.itemsTemplate.variablesToAdd = (UA_PublishedVariableDataType *) UA_calloc( + src->config.itemsTemplate.variablesToAddSize, sizeof(UA_PublishedVariableDataType)); + } + + for(size_t i = 0; i < src->config.itemsTemplate.variablesToAddSize; i++){ + retVal |= UA_PublishedVariableDataType_copy(&src->config.itemsTemplate.variablesToAdd[i], + &dst->config.itemsTemplate.variablesToAdd[i]); + } + retVal |= UA_DataSetMetaDataType_copy(&src->config.itemsTemplate.metaData, + &dst->config.itemsTemplate.metaData); + break; + + default: + return UA_STATUSCODE_BADINVALIDARGUMENT; + } + return retVal; +} + +UA_StatusCode +UA_Server_getPublishedDataSetConfig(UA_Server *server, const UA_NodeId pds, + UA_PublishedDataSetConfig *config){ + if(!config) + return UA_STATUSCODE_BADINVALIDARGUMENT; + + UA_PublishedDataSet *currentPublishedDataSet = UA_PublishedDataSet_findPDSbyId(server, pds); + if(!currentPublishedDataSet) + return UA_STATUSCODE_BADNOTFOUND; + + UA_PublishedDataSetConfig tmpPublishedDataSetConfig; + //deep copy of the actual config + UA_PublishedDataSetConfig_copy(¤tPublishedDataSet->config, &tmpPublishedDataSetConfig); + *config = tmpPublishedDataSetConfig; + return UA_STATUSCODE_GOOD; +} + +UA_PublishedDataSet * +UA_PublishedDataSet_findPDSbyId(UA_Server *server, UA_NodeId identifier){ + for(size_t i = 0; i < server->pubSubManager.publishedDataSetsSize; i++){ + if(UA_NodeId_equal(&server->pubSubManager.publishedDataSets[i].identifier, &identifier)){ + return &server->pubSubManager.publishedDataSets[i]; } } + return NULL; +} - /* Send the response */ - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, - "Subscription %u | Sending out a publish response " - "with %u notifications", sub->subscriptionId, - (UA_UInt32)notifications); - UA_SecureChannel_sendSymmetricMessage(sub->session->header.channel, pre->requestId, - UA_MESSAGETYPE_MSG, response, - &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +void +UA_PublishedDataSetConfig_deleteMembers(UA_PublishedDataSetConfig *pdsConfig){ + //delete pds config + UA_String_deleteMembers(&pdsConfig->name); + switch (pdsConfig->publishedDataSetType){ + case UA_PUBSUB_DATASET_PUBLISHEDITEMS: + //no additional items + break; + case UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE: + if(pdsConfig->config.itemsTemplate.variablesToAddSize > 0){ + for(size_t i = 0; i < pdsConfig->config.itemsTemplate.variablesToAddSize; i++){ + UA_PublishedVariableDataType_deleteMembers(&pdsConfig->config.itemsTemplate.variablesToAdd[i]); + } + UA_free(pdsConfig->config.itemsTemplate.variablesToAdd); + } + UA_DataSetMetaDataType_deleteMembers(&pdsConfig->config.itemsTemplate.metaData); + break; + default: + break; + } +} - /* Reset subscription state to normal */ - sub->state = UA_SUBSCRIPTIONSTATE_NORMAL; - sub->currentKeepAliveCount = 0; +void +UA_PublishedDataSet_deleteMembers(UA_Server *server, UA_PublishedDataSet *publishedDataSet){ + UA_PublishedDataSetConfig_deleteMembers(&publishedDataSet->config); + //delete PDS + UA_DataSetMetaDataType_deleteMembers(&publishedDataSet->dataSetMetaData); + UA_DataSetField *field, *tmpField; + LIST_FOREACH_SAFE(field, &publishedDataSet->fields, listEntry, tmpField) { + UA_Server_removeDataSetField(server, field->identifier); + } + UA_NodeId_deleteMembers(&publishedDataSet->identifier); +} + +UA_DataSetFieldResult +UA_Server_addDataSetField(UA_Server *server, const UA_NodeId publishedDataSet, + const UA_DataSetFieldConfig *fieldConfig, + UA_NodeId *fieldIdentifier) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_DataSetFieldResult result = {UA_STATUSCODE_BADINVALIDARGUMENT, {0, 0}}; + if(!fieldConfig) + return result; - /* Free the response */ - UA_Array_delete(response->results, response->resultsSize, &UA_TYPES[UA_TYPES_UINT32]); - UA_free(pre); /* No need for UA_PublishResponse_deleteMembers */ + UA_PublishedDataSet *currentDataSet = UA_PublishedDataSet_findPDSbyId(server, publishedDataSet); + if(currentDataSet == NULL){ + result.result = UA_STATUSCODE_BADNOTFOUND; + return result; + } - /* Repeat sending responses if there are more notifications to send */ - if(moreNotifications) - UA_Subscription_publish(server, sub); + if(currentDataSet->config.publishedDataSetType != UA_PUBSUB_DATASET_PUBLISHEDITEMS){ + result.result = UA_STATUSCODE_BADNOTIMPLEMENTED; + return result; + } + + UA_DataSetField *newField = (UA_DataSetField *) UA_calloc(1, sizeof(UA_DataSetField)); + if(!newField){ + result.result = UA_STATUSCODE_BADINTERNALERROR; + return result; + } + + UA_DataSetFieldConfig tmpFieldConfig; + retVal |= UA_DataSetFieldConfig_copy(fieldConfig, &tmpFieldConfig); + newField->config = tmpFieldConfig; + UA_PubSubManager_generateUniqueNodeId(server, &newField->identifier); + if(fieldIdentifier != NULL){ + UA_NodeId_copy(&newField->identifier, fieldIdentifier); + } + newField->publishedDataSet = currentDataSet->identifier; + //update major version of parent published data set + currentDataSet->dataSetMetaData.configurationVersion.majorVersion = UA_PubSubConfigurationVersionTimeDifference(); + LIST_INSERT_HEAD(¤tDataSet->fields, newField, listEntry); + if(newField->config.field.variable.promotedField) + currentDataSet->promotedFieldsCount++; + currentDataSet->fieldSize++; + result.result = retVal; + result.configurationVersion.majorVersion = currentDataSet->dataSetMetaData.configurationVersion.majorVersion; + result.configurationVersion.minorVersion = currentDataSet->dataSetMetaData.configurationVersion.minorVersion; + return result; } -UA_Boolean -UA_Subscription_reachedPublishReqLimit(UA_Server *server, UA_Session *session) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Reached number of publish request limit"); +UA_DataSetFieldResult +UA_Server_removeDataSetField(UA_Server *server, const UA_NodeId dsf) { + UA_DataSetField *currentField = UA_DataSetField_findDSFbyId(server, dsf); + UA_DataSetFieldResult result = {UA_STATUSCODE_BADNOTFOUND, {0, 0}}; + if(!currentField) + return result; - /* Dequeue a response */ - UA_PublishResponseEntry *pre = UA_Session_dequeuePublishReq(session); + UA_PublishedDataSet *parentPublishedDataSet = + UA_PublishedDataSet_findPDSbyId(server, currentField->publishedDataSet); + if(!parentPublishedDataSet) + return result; - /* Cannot publish without a response */ - if(!pre) { - UA_LOG_FATAL_SESSION(server->config.logger, session, "No publish requests available"); - return false; + parentPublishedDataSet->fieldSize--; + if(currentField->config.field.variable.promotedField) + parentPublishedDataSet->promotedFieldsCount--; + /* update major version of PublishedDataSet */ + parentPublishedDataSet->dataSetMetaData.configurationVersion.majorVersion = + UA_PubSubConfigurationVersionTimeDifference(); + + UA_DataSetField_deleteMembers(currentField); + LIST_REMOVE(currentField, listEntry); + UA_free(currentField); + + result.result = UA_STATUSCODE_GOOD; + result.configurationVersion.majorVersion = parentPublishedDataSet->dataSetMetaData.configurationVersion.majorVersion; + result.configurationVersion.minorVersion = parentPublishedDataSet->dataSetMetaData.configurationVersion.minorVersion; + return result; +} + +/**********************************************/ +/* DataSetWriter */ +/**********************************************/ + +UA_StatusCode +UA_DataSetWriterConfig_copy(const UA_DataSetWriterConfig *src, + UA_DataSetWriterConfig *dst){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + memcpy(dst, src, sizeof(UA_DataSetWriterConfig)); + retVal |= UA_String_copy(&src->name, &dst->name); + retVal |= UA_String_copy(&src->dataSetName, &dst->dataSetName); + retVal |= UA_ExtensionObject_copy(&src->messageSettings, &dst->messageSettings); + dst->dataSetWriterProperties = (UA_KeyValuePair *) + UA_calloc(src->dataSetWriterPropertiesSize, sizeof(UA_KeyValuePair)); + if(!dst->dataSetWriterProperties) + return UA_STATUSCODE_BADOUTOFMEMORY; + for(size_t i = 0; i < src->dataSetWriterPropertiesSize; i++){ + retVal |= UA_KeyValuePair_copy(&src->dataSetWriterProperties[i], &dst->dataSetWriterProperties[i]); } + return retVal; +} - /* <-- The point of no return --> */ +UA_StatusCode +UA_Server_getDataSetWriterConfig(UA_Server *server, const UA_NodeId dsw, + UA_DataSetWriterConfig *config){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(!config) + return UA_STATUSCODE_BADINVALIDARGUMENT; - UA_PublishResponse *response = &pre->response; - UA_NotificationMessage *message = &response->notificationMessage; + UA_DataSetWriter *currentDataSetWriter = UA_DataSetWriter_findDSWbyId(server, dsw); + if(!currentDataSetWriter) + return UA_STATUSCODE_BADNOTFOUND; - /* Set up the response. Note that this response has no related subscription id */ - response->responseHeader.timestamp = UA_DateTime_now(); - response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS; - response->subscriptionId = 0; - response->moreNotifications = false; - message->publishTime = response->responseHeader.timestamp; - message->sequenceNumber = 0; - response->availableSequenceNumbersSize = 0; + UA_DataSetWriterConfig tmpWriterConfig; + //deep copy of the actual config + retVal |= UA_DataSetWriterConfig_copy(¤tDataSetWriter->config, &tmpWriterConfig); + *config = tmpWriterConfig; + return retVal; +} - /* Send the response */ - UA_LOG_DEBUG_SESSION(server->config.logger, session, - "Sending out a publish response triggered by too many publish requests"); - UA_SecureChannel_sendSymmetricMessage(session->header.channel, pre->requestId, - UA_MESSAGETYPE_MSG, response, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +UA_DataSetWriter * +UA_DataSetWriter_findDSWbyId(UA_Server *server, UA_NodeId identifier) { + for(size_t i = 0; i < server->pubSubManager.connectionsSize; i++){ + UA_WriterGroup *tmpWriterGroup; + LIST_FOREACH(tmpWriterGroup, &server->pubSubManager.connections[i].writerGroups, listEntry){ + UA_DataSetWriter *tmpWriter; + LIST_FOREACH(tmpWriter, &tmpWriterGroup->writers, listEntry){ + if(UA_NodeId_equal(&tmpWriter->identifier, &identifier)){ + return tmpWriter; + } + } + } + } + return NULL; +} - /* Free the response */ - UA_Array_delete(response->results, response->resultsSize, &UA_TYPES[UA_TYPES_UINT32]); - UA_free(pre); /* no need for UA_PublishResponse_deleteMembers */ +void +UA_DataSetWriterConfig_deleteMembers(UA_DataSetWriterConfig *pdsConfig) { + UA_String_deleteMembers(&pdsConfig->name); + UA_String_deleteMembers(&pdsConfig->dataSetName); + for(size_t i = 0; i < pdsConfig->dataSetWriterPropertiesSize; i++){ + UA_KeyValuePair_deleteMembers(&pdsConfig->dataSetWriterProperties[i]); + } + UA_free(pdsConfig->dataSetWriterProperties); + UA_ExtensionObject_deleteMembers(&pdsConfig->messageSettings); +} - return true; +static void +UA_DataSetWriter_deleteMembers(UA_Server *server, UA_DataSetWriter *dataSetWriter) { + UA_DataSetWriterConfig_deleteMembers(&dataSetWriter->config); + //delete DataSetWriter + UA_NodeId_deleteMembers(&dataSetWriter->identifier); + UA_NodeId_deleteMembers(&dataSetWriter->linkedWriterGroup); + UA_NodeId_deleteMembers(&dataSetWriter->connectedDataSet); +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES + //delete lastSamples store + for(size_t i = 0; i < dataSetWriter->lastSamplesCount; i++) { + UA_DataValue_deleteMembers(&dataSetWriter->lastSamples[i].value); + } + UA_free(dataSetWriter->lastSamples); + dataSetWriter->lastSamples = NULL; + dataSetWriter->lastSamplesCount = 0; +#endif } +/**********************************************/ +/* WriterGroup */ +/**********************************************/ + UA_StatusCode -Subscription_registerPublishCallback(UA_Server *server, UA_Subscription *sub) { - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, - "Subscription %u | Register subscription " - "publishing callback", sub->subscriptionId); +UA_WriterGroupConfig_copy(const UA_WriterGroupConfig *src, + UA_WriterGroupConfig *dst){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + memcpy(dst, src, sizeof(UA_WriterGroupConfig)); + retVal |= UA_String_copy(&src->name, &dst->name); + retVal |= UA_ExtensionObject_copy(&src->transportSettings, &dst->transportSettings); + retVal |= UA_ExtensionObject_copy(&src->messageSettings, &dst->messageSettings); + dst->groupProperties = (UA_KeyValuePair *) UA_calloc(src->groupPropertiesSize, sizeof(UA_KeyValuePair)); + if(!dst->groupProperties) + return UA_STATUSCODE_BADOUTOFMEMORY; + for(size_t i = 0; i < src->groupPropertiesSize; i++){ + retVal |= UA_KeyValuePair_copy(&src->groupProperties[i], &dst->groupProperties[i]); + } + return retVal; +} - if(sub->publishCallbackIsRegistered) - return UA_STATUSCODE_GOOD; +UA_StatusCode +UA_Server_getWriterGroupConfig(UA_Server *server, const UA_NodeId writerGroup, + UA_WriterGroupConfig *config){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(!config) + return UA_STATUSCODE_BADINVALIDARGUMENT; - UA_StatusCode retval = - UA_Server_addRepeatedCallback(server, (UA_ServerCallback)publishCallback, - sub, (UA_UInt32)sub->publishingInterval, &sub->publishCallbackId); - if(retval != UA_STATUSCODE_GOOD) - return retval; + UA_WriterGroup *currentWriterGroup = UA_WriterGroup_findWGbyId(server, writerGroup); + if(!currentWriterGroup){ + return UA_STATUSCODE_BADNOTFOUND; + } + UA_WriterGroupConfig tmpWriterGroupConfig; + //deep copy of the actual config + retVal |= UA_WriterGroupConfig_copy(¤tWriterGroup->config, &tmpWriterGroupConfig); + *config = tmpWriterGroupConfig; + return retVal; +} - sub->publishCallbackIsRegistered = true; +UA_StatusCode +UA_Server_updateWriterGroupConfig(UA_Server *server, UA_NodeId writerGroupIdentifier, + const UA_WriterGroupConfig *config){ + if(!config) + return UA_STATUSCODE_BADINVALIDARGUMENT; + + UA_WriterGroup *currentWriterGroup = UA_WriterGroup_findWGbyId(server, writerGroupIdentifier); + if(!currentWriterGroup) + return UA_STATUSCODE_BADNOTFOUND; + //The update functionality will be extended during the next PubSub batches. + //Currently is only a change of the publishing interval possible. + if(currentWriterGroup->config.maxEncapsulatedDataSetMessageCount != config->maxEncapsulatedDataSetMessageCount){ + currentWriterGroup->config.maxEncapsulatedDataSetMessageCount = config->maxEncapsulatedDataSetMessageCount; + if(currentWriterGroup->config.messageSettings.encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "MaxEncapsulatedDataSetMessag need enabled 'PayloadHeader' within the message settings."); + } + } + if(currentWriterGroup->config.publishingInterval != config->publishingInterval) { + UA_PubSubManager_removeRepeatedPubSubCallback(server, currentWriterGroup->publishCallbackId); + currentWriterGroup->config.publishingInterval = config->publishingInterval; + UA_WriterGroup_addPublishCallback(server, currentWriterGroup); + } + if(currentWriterGroup->config.priority != config->priority) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "No or unsupported WriterGroup update."); + } return UA_STATUSCODE_GOOD; } +UA_WriterGroup * +UA_WriterGroup_findWGbyId(UA_Server *server, UA_NodeId identifier){ + for(size_t i = 0; i < server->pubSubManager.connectionsSize; i++){ + UA_WriterGroup *tmpWriterGroup; + LIST_FOREACH(tmpWriterGroup, &server->pubSubManager.connections[i].writerGroups, listEntry) { + if(UA_NodeId_equal(&identifier, &tmpWriterGroup->identifier)){ + return tmpWriterGroup; + } + } + } + return NULL; +} + +void +UA_WriterGroupConfig_deleteMembers(UA_WriterGroupConfig *writerGroupConfig){ + //delete writerGroup config + UA_String_deleteMembers(&writerGroupConfig->name); + UA_ExtensionObject_deleteMembers(&writerGroupConfig->transportSettings); + UA_ExtensionObject_deleteMembers(&writerGroupConfig->messageSettings); + for(size_t i = 0; i < writerGroupConfig->groupPropertiesSize; i++){ + UA_KeyValuePair_deleteMembers(&writerGroupConfig->groupProperties[i]); + } + UA_free(writerGroupConfig->groupProperties); +} + +static void +UA_WriterGroup_deleteMembers(UA_Server *server, UA_WriterGroup *writerGroup) { + UA_WriterGroupConfig_deleteMembers(&writerGroup->config); + //delete WriterGroup + //delete all writers. Therefore removeDataSetWriter is called from PublishedDataSet + UA_DataSetWriter *dataSetWriter, *tmpDataSetWriter; + LIST_FOREACH_SAFE(dataSetWriter, &writerGroup->writers, listEntry, tmpDataSetWriter){ + UA_Server_removeDataSetWriter(server, dataSetWriter->identifier); + } + UA_NodeId_deleteMembers(&writerGroup->linkedConnection); + UA_NodeId_deleteMembers(&writerGroup->identifier); +} + UA_StatusCode -Subscription_unregisterPublishCallback(UA_Server *server, UA_Subscription *sub) { - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, "Subscription %u | " - "Unregister subscription publishing callback", sub->subscriptionId); +UA_Server_addDataSetWriter(UA_Server *server, + const UA_NodeId writerGroup, const UA_NodeId dataSet, + const UA_DataSetWriterConfig *dataSetWriterConfig, + UA_NodeId *writerIdentifier) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(!dataSetWriterConfig) + return UA_STATUSCODE_BADINVALIDARGUMENT; - if(!sub->publishCallbackIsRegistered) - return UA_STATUSCODE_GOOD; + UA_PublishedDataSet *currentDataSetContext = UA_PublishedDataSet_findPDSbyId(server, dataSet); + if(!currentDataSetContext) + return UA_STATUSCODE_BADNOTFOUND; - UA_StatusCode retval = UA_Server_removeRepeatedCallback(server, sub->publishCallbackId); - if(retval != UA_STATUSCODE_GOOD) - return retval; + UA_WriterGroup *wg = UA_WriterGroup_findWGbyId(server, writerGroup); + if(!wg) + return UA_STATUSCODE_BADNOTFOUND; - sub->publishCallbackIsRegistered = false; + UA_DataSetWriter *newDataSetWriter = (UA_DataSetWriter *) UA_calloc(1, sizeof(UA_DataSetWriter)); + if(!newDataSetWriter) + return UA_STATUSCODE_BADOUTOFMEMORY; + + //copy the config into the new dataSetWriter + UA_DataSetWriterConfig tmpDataSetWriterConfig; + retVal |= UA_DataSetWriterConfig_copy(dataSetWriterConfig, &tmpDataSetWriterConfig); + newDataSetWriter->config = tmpDataSetWriterConfig; + //save the current version of the connected PublishedDataSet + newDataSetWriter->connectedDataSetVersion = currentDataSetContext->dataSetMetaData.configurationVersion; + +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES + //initialize the queue for the last values + newDataSetWriter->lastSamples = (UA_DataSetWriterSample * ) + UA_calloc(currentDataSetContext->fieldSize, sizeof(UA_DataSetWriterSample)); + if(!newDataSetWriter->lastSamples) { + UA_DataSetWriterConfig_deleteMembers(&newDataSetWriter->config); + UA_free(newDataSetWriter); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + newDataSetWriter->lastSamplesCount = currentDataSetContext->fieldSize; +#endif + + //connect PublishedDataSet with DataSetWriter + newDataSetWriter->connectedDataSet = currentDataSetContext->identifier; + newDataSetWriter->linkedWriterGroup = wg->identifier; + UA_PubSubManager_generateUniqueNodeId(server, &newDataSetWriter->identifier); + if(writerIdentifier != NULL) + UA_NodeId_copy(&newDataSetWriter->identifier, writerIdentifier); + //add the new writer to the group + LIST_INSERT_HEAD(&wg->writers, newDataSetWriter, listEntry); + wg->writersCount++; +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + addDataSetWriterRepresentation(server, newDataSetWriter); +#endif + return retVal; +} + +UA_StatusCode +UA_Server_removeDataSetWriter(UA_Server *server, const UA_NodeId dsw){ + UA_DataSetWriter *dataSetWriter = UA_DataSetWriter_findDSWbyId(server, dsw); + if(!dataSetWriter) + return UA_STATUSCODE_BADNOTFOUND; + + UA_WriterGroup *linkedWriterGroup = UA_WriterGroup_findWGbyId(server, dataSetWriter->linkedWriterGroup); + if(!linkedWriterGroup) + return UA_STATUSCODE_BADNOTFOUND; + + linkedWriterGroup->writersCount--; +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + removeDataSetWriterRepresentation(server, dataSetWriter); +#endif + + //remove DataSetWriter from group + UA_DataSetWriter_deleteMembers(server, dataSetWriter); + LIST_REMOVE(dataSetWriter, listEntry); + UA_free(dataSetWriter); return UA_STATUSCODE_GOOD; } -/* When the session has publish requests stored but the last subscription is - * deleted... Send out empty responses */ +/**********************************************/ +/* DataSetField */ +/**********************************************/ + +UA_StatusCode +UA_DataSetFieldConfig_copy(const UA_DataSetFieldConfig *src, UA_DataSetFieldConfig *dst){ + memcpy(dst, src, sizeof(UA_DataSetFieldConfig)); + if(src->dataSetFieldType == UA_PUBSUB_DATASETFIELD_VARIABLE) { + UA_String_copy(&src->field.variable.fieldNameAlias, &dst->field.variable.fieldNameAlias); + UA_PublishedVariableDataType_copy(&src->field.variable.publishParameters, + &dst->field.variable.publishParameters); + } else { + return UA_STATUSCODE_BADNOTSUPPORTED; + } + + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +UA_Server_getDataSetFieldConfig(UA_Server *server, const UA_NodeId dsf, + UA_DataSetFieldConfig *config) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(!config) + return UA_STATUSCODE_BADINVALIDARGUMENT; + UA_DataSetField *currentDataSetField = UA_DataSetField_findDSFbyId(server, dsf); + if(!currentDataSetField) + return UA_STATUSCODE_BADNOTFOUND; + UA_DataSetFieldConfig tmpFieldConfig; + //deep copy of the actual config + retVal |= UA_DataSetFieldConfig_copy(¤tDataSetField->config, &tmpFieldConfig); + *config = tmpFieldConfig; + return retVal; +} + +UA_DataSetField * +UA_DataSetField_findDSFbyId(UA_Server *server, UA_NodeId identifier) { + for(size_t i = 0; i < server->pubSubManager.publishedDataSetsSize; i++){ + UA_DataSetField *tmpField; + LIST_FOREACH(tmpField, &server->pubSubManager.publishedDataSets[i].fields, listEntry){ + if(UA_NodeId_equal(&tmpField->identifier, &identifier)){ + return tmpField; + } + } + } + return NULL; +} + void -UA_Subscription_answerPublishRequestsNoSubscription(UA_Server *server, UA_Session *session) { - /* No session or there are remaining subscriptions */ - if(!session || LIST_FIRST(&session->serverSubscriptions)) - return; +UA_DataSetFieldConfig_deleteMembers(UA_DataSetFieldConfig *dataSetFieldConfig){ + if(dataSetFieldConfig->dataSetFieldType == UA_PUBSUB_DATASETFIELD_VARIABLE){ + UA_String_deleteMembers(&dataSetFieldConfig->field.variable.fieldNameAlias); + UA_PublishedVariableDataType_deleteMembers(&dataSetFieldConfig->field.variable.publishParameters); + } +} - /* Send a response for every queued request */ - UA_PublishResponseEntry *pre; - while((pre = UA_Session_dequeuePublishReq(session))) { - UA_PublishResponse *response = &pre->response; - response->responseHeader.serviceResult = UA_STATUSCODE_BADNOSUBSCRIPTION; - response->responseHeader.timestamp = UA_DateTime_now(); - UA_SecureChannel_sendSymmetricMessage(session->header.channel, pre->requestId, UA_MESSAGETYPE_MSG, - response, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); - UA_PublishResponse_deleteMembers(response); - UA_free(pre); +static void +UA_DataSetField_deleteMembers(UA_DataSetField *field) { + UA_DataSetFieldConfig_deleteMembers(&field->config); + //delete DataSetField + UA_NodeId_deleteMembers(&field->identifier); + UA_NodeId_deleteMembers(&field->publishedDataSet); + UA_FieldMetaData_deleteMembers(&field->fieldMetaData); +} + +/*********************************************************/ +/* PublishValues handling */ +/*********************************************************/ + +/** + * Compare two variants. Internally used for value change detection. + * + * @return true if the value has changed + */ +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES +static UA_Boolean +valueChangedVariant(UA_Variant *oldValue, UA_Variant *newValue){ + if(! (oldValue && newValue)) + return false; + + UA_ByteString *oldValueEncoding = UA_ByteString_new(), *newValueEncoding = UA_ByteString_new(); + size_t oldValueEncodingSize, newValueEncodingSize; + oldValueEncodingSize = UA_calcSizeBinary(oldValue, &UA_TYPES[UA_TYPES_VARIANT]); + newValueEncodingSize = UA_calcSizeBinary(newValue, &UA_TYPES[UA_TYPES_VARIANT]); + if((oldValueEncodingSize == 0) || (newValueEncodingSize == 0)) + return false; + + if(oldValueEncodingSize != newValueEncodingSize) + return true; + + if(UA_ByteString_allocBuffer(oldValueEncoding, oldValueEncodingSize) != UA_STATUSCODE_GOOD) + return false; + + if(UA_ByteString_allocBuffer(newValueEncoding, newValueEncodingSize) != UA_STATUSCODE_GOOD) + return false; + + UA_Byte *bufPosOldValue = oldValueEncoding->data; + const UA_Byte *bufEndOldValue = &oldValueEncoding->data[oldValueEncoding->length]; + UA_Byte *bufPosNewValue = newValueEncoding->data; + const UA_Byte *bufEndNewValue = &newValueEncoding->data[newValueEncoding->length]; + if(UA_encodeBinary(oldValue, &UA_TYPES[UA_TYPES_VARIANT], + &bufPosOldValue, &bufEndOldValue, NULL, NULL) != UA_STATUSCODE_GOOD){ + return false; + } + if(UA_encodeBinary(newValue, &UA_TYPES[UA_TYPES_VARIANT], + &bufPosNewValue, &bufEndNewValue, NULL, NULL) != UA_STATUSCODE_GOOD){ + return false; } + oldValueEncoding->length = (uintptr_t)bufPosOldValue - (uintptr_t)oldValueEncoding->data; + newValueEncoding->length = (uintptr_t)bufPosNewValue - (uintptr_t)newValueEncoding->data; + UA_Boolean compareResult = !UA_ByteString_equal(oldValueEncoding, newValueEncoding); + UA_ByteString_delete(oldValueEncoding); + UA_ByteString_delete(newValueEncoding); + return compareResult; } +#endif -#endif /* UA_ENABLE_SUBSCRIPTIONS */ +/** + * Obtain the latest value for a specific DataSetField. This method is currently + * called inside the DataSetMessage generation process. + */ +static void +UA_PubSubDataSetField_sampleValue(UA_Server *server, UA_DataSetField *field, + UA_DataValue *value) { + /* Read the value */ + UA_ReadValueId rvid; + UA_ReadValueId_init(&rvid); + rvid.nodeId = field->config.field.variable.publishParameters.publishedVariable; + rvid.attributeId = field->config.field.variable.publishParameters.attributeId; + rvid.indexRange = field->config.field.variable.publishParameters.indexRange; + *value = UA_Server_read(server, &rvid, UA_TIMESTAMPSTORETURN_BOTH); +} -/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_subscription_datachange.c" ***********************************/ +static UA_StatusCode +UA_PubSubDataSetWriter_generateKeyFrameMessage(UA_Server *server, UA_DataSetMessage *dataSetMessage, + UA_DataSetWriter *dataSetWriter) { + UA_PublishedDataSet *currentDataSet = + UA_PublishedDataSet_findPDSbyId(server, dataSetWriter->connectedDataSet); + if(!currentDataSet) + return UA_STATUSCODE_BADNOTFOUND; + + /* Prepare DataSetMessageContent */ + dataSetMessage->header.dataSetMessageValid = true; + dataSetMessage->header.dataSetMessageType = UA_DATASETMESSAGE_DATAKEYFRAME; + dataSetMessage->data.keyFrameData.fieldCount = currentDataSet->fieldSize; + dataSetMessage->data.keyFrameData.dataSetFields = (UA_DataValue *) + UA_Array_new(currentDataSet->fieldSize, &UA_TYPES[UA_TYPES_DATAVALUE]); + if(!dataSetMessage->data.keyFrameData.dataSetFields) + return UA_STATUSCODE_BADOUTOFMEMORY; -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. +#ifdef UA_ENABLE_JSON_ENCODING + /* json: insert fieldnames used as json keys */ + dataSetMessage->data.keyFrameData.fieldNames = + (UA_String *)UA_Array_new(currentDataSet->fieldSize, &UA_TYPES[UA_TYPES_STRING]); + if(!dataSetMessage->data.keyFrameData.fieldNames) + return UA_STATUSCODE_BADOUTOFMEMORY; +#endif + + /* Loop over the fields */ + size_t counter = 0; + UA_DataSetField *dsf; + LIST_FOREACH(dsf, ¤tDataSet->fields, listEntry) { + +#ifdef UA_ENABLE_JSON_ENCODING + /* json: store the fieldNameAlias*/ + UA_String_copy(&dsf->config.field.variable.fieldNameAlias, + &dataSetMessage->data.keyFrameData.fieldNames[counter]); +#endif + + /* Sample the value */ + UA_DataValue *dfv = &dataSetMessage->data.keyFrameData.dataSetFields[counter]; + UA_PubSubDataSetField_sampleValue(server, dsf, dfv); + + /* Deactivate statuscode? */ + if(((u64)dataSetWriter->config.dataSetFieldContentMask & (u64)UA_DATASETFIELDCONTENTMASK_STATUSCODE) == 0) + dfv->hasStatus = false; + + /* Deactivate timestamps */ + if(((u64)dataSetWriter->config.dataSetFieldContentMask & + (u64)UA_DATASETFIELDCONTENTMASK_SOURCETIMESTAMP) == 0) + dfv->hasSourceTimestamp = false; + if(((u64)dataSetWriter->config.dataSetFieldContentMask & + (u64)UA_DATASETFIELDCONTENTMASK_SOURCEPICOSECONDS) == 0) + dfv->hasSourcePicoseconds = false; + if(((u64)dataSetWriter->config.dataSetFieldContentMask & + (u64)UA_DATASETFIELDCONTENTMASK_SERVERTIMESTAMP) == 0) + dfv->hasServerTimestamp = false; + if(((u64)dataSetWriter->config.dataSetFieldContentMask & + (u64)UA_DATASETFIELDCONTENTMASK_SERVERPICOSECONDS) == 0) + dfv->hasServerPicoseconds = false; + +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES + /* Update lastValue store */ + UA_DataValue_deleteMembers(&dataSetWriter->lastSamples[counter].value); + UA_DataValue_copy(dfv, &dataSetWriter->lastSamples[counter].value); +#endif + + counter++; + } + return UA_STATUSCODE_GOOD; +} + +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES +static UA_StatusCode +UA_PubSubDataSetWriter_generateDeltaFrameMessage(UA_Server *server, + UA_DataSetMessage *dataSetMessage, + UA_DataSetWriter *dataSetWriter) { + UA_PublishedDataSet *currentDataSet = + UA_PublishedDataSet_findPDSbyId(server, dataSetWriter->connectedDataSet); + if(!currentDataSet) + return UA_STATUSCODE_BADNOTFOUND; + + /* Prepare DataSetMessageContent */ + memset(dataSetMessage, 0, sizeof(UA_DataSetMessage)); + dataSetMessage->header.dataSetMessageValid = true; + dataSetMessage->header.dataSetMessageType = UA_DATASETMESSAGE_DATADELTAFRAME; + + UA_DataSetField *dsf; + size_t counter = 0; + LIST_FOREACH(dsf, ¤tDataSet->fields, listEntry) { + /* Sample the value */ + UA_DataValue value; + UA_DataValue_init(&value); + UA_PubSubDataSetField_sampleValue(server, dsf, &value); + + /* Check if the value has changed */ + if(valueChangedVariant(&dataSetWriter->lastSamples[counter].value.value, &value.value)) { + /* increase fieldCount for current delta message */ + dataSetMessage->data.deltaFrameData.fieldCount++; + dataSetWriter->lastSamples[counter].valueChanged = true; + + /* Update last stored sample */ + UA_DataValue_deleteMembers(&dataSetWriter->lastSamples[counter].value); + dataSetWriter->lastSamples[counter].value = value; + } else { + UA_DataValue_deleteMembers(&value); + dataSetWriter->lastSamples[counter].valueChanged = false; + } + + counter++; + } + + /* Allocate DeltaFrameFields */ + UA_DataSetMessage_DeltaFrameField *deltaFields = (UA_DataSetMessage_DeltaFrameField *) + UA_calloc(dataSetMessage->data.deltaFrameData.fieldCount, sizeof(UA_DataSetMessage_DeltaFrameField)); + if(!deltaFields) + return UA_STATUSCODE_BADOUTOFMEMORY; + + dataSetMessage->data.deltaFrameData.deltaFrameFields = deltaFields; + size_t currentDeltaField = 0; + for(size_t i = 0; i < currentDataSet->fieldSize; i++) { + if(!dataSetWriter->lastSamples[i].valueChanged) + continue; + + UA_DataSetMessage_DeltaFrameField *dff = &deltaFields[currentDeltaField]; + + dff->fieldIndex = (UA_UInt16) i; + UA_DataValue_copy(&dataSetWriter->lastSamples[i].value, &dff->fieldValue); + dataSetWriter->lastSamples[i].valueChanged = false; + + /* Deactivate statuscode? */ + if(((u64)dataSetWriter->config.dataSetFieldContentMask & (u64)UA_DATASETFIELDCONTENTMASK_STATUSCODE) == 0) + dff->fieldValue.hasStatus = false; + + /* Deactivate timestamps? */ + if(((u64)dataSetWriter->config.dataSetFieldContentMask & (u64)UA_DATASETFIELDCONTENTMASK_SOURCETIMESTAMP) == 0) + dff->fieldValue.hasSourceTimestamp = false; + if(((u64)dataSetWriter->config.dataSetFieldContentMask & (u64)UA_DATASETFIELDCONTENTMASK_SOURCEPICOSECONDS) == 0) + dff->fieldValue.hasServerPicoseconds = false; + if(((u64)dataSetWriter->config.dataSetFieldContentMask & (u64)UA_DATASETFIELDCONTENTMASK_SERVERTIMESTAMP) == 0) + dff->fieldValue.hasServerTimestamp = false; + if(((u64)dataSetWriter->config.dataSetFieldContentMask & (u64)UA_DATASETFIELDCONTENTMASK_SERVERPICOSECONDS) == 0) + dff->fieldValue.hasServerPicoseconds = false; + + currentDeltaField++; + } + return UA_STATUSCODE_GOOD; +} +#endif + +/** + * Generate a DataSetMessage for the given writer. * - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB - * Copyright 2017 (c) Stefan Profanter, fortiss GmbH - * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA + * @param dataSetWriter ptr to corresponding writer + * @return ptr to generated DataSetMessage */ +static UA_StatusCode +UA_DataSetWriter_generateDataSetMessage(UA_Server *server, UA_DataSetMessage *dataSetMessage, + UA_DataSetWriter *dataSetWriter) { + UA_PublishedDataSet *currentDataSet = + UA_PublishedDataSet_findPDSbyId(server, dataSetWriter->connectedDataSet); + if(!currentDataSet) + return UA_STATUSCODE_BADNOTFOUND; + + /* Reset the message */ + memset(dataSetMessage, 0, sizeof(UA_DataSetMessage)); + + /* store messageType to switch between json or uadp (default) */ + UA_UInt16 messageType = UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE; + UA_JsonDataSetWriterMessageDataType *jsonDataSetWriterMessageDataType = NULL; + + /* The configuration Flags are included + * inside the std. defined UA_UadpDataSetWriterMessageDataType */ + UA_UadpDataSetWriterMessageDataType defaultUadpConfiguration; + UA_UadpDataSetWriterMessageDataType *dataSetWriterMessageDataType = NULL; + if((dataSetWriter->config.messageSettings.encoding == UA_EXTENSIONOBJECT_DECODED || + dataSetWriter->config.messageSettings.encoding == UA_EXTENSIONOBJECT_DECODED_NODELETE) && + (dataSetWriter->config.messageSettings.content.decoded.type == + &UA_TYPES[UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE])) { + dataSetWriterMessageDataType = (UA_UadpDataSetWriterMessageDataType *) + dataSetWriter->config.messageSettings.content.decoded.data; + + /* type is UADP */ + messageType = UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE; + } else if((dataSetWriter->config.messageSettings.encoding == UA_EXTENSIONOBJECT_DECODED || + dataSetWriter->config.messageSettings.encoding == UA_EXTENSIONOBJECT_DECODED_NODELETE) && + (dataSetWriter->config.messageSettings.content.decoded.type == + &UA_TYPES[UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE])) { + jsonDataSetWriterMessageDataType = (UA_JsonDataSetWriterMessageDataType *) + dataSetWriter->config.messageSettings.content.decoded.data; + + /* type is JSON */ + messageType = UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE; + } else { + /* create default flag configuration if no + * UadpDataSetWriterMessageDataType was passed in */ + memset(&defaultUadpConfiguration, 0, sizeof(UA_UadpDataSetWriterMessageDataType)); + defaultUadpConfiguration.dataSetMessageContentMask = (UA_UadpDataSetMessageContentMask) + ((u64)UA_UADPDATASETMESSAGECONTENTMASK_TIMESTAMP | (u64)UA_UADPDATASETMESSAGECONTENTMASK_MAJORVERSION | + (u64)UA_UADPDATASETMESSAGECONTENTMASK_MINORVERSION); + dataSetWriterMessageDataType = &defaultUadpConfiguration; + } + + /* Sanity-test the configuration */ + if(dataSetWriterMessageDataType && + (dataSetWriterMessageDataType->networkMessageNumber != 0 || + dataSetWriterMessageDataType->dataSetOffset != 0 || + dataSetWriterMessageDataType->configuredSize != 0)) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Static DSM configuration not supported. Using defaults"); + dataSetWriterMessageDataType->networkMessageNumber = 0; + dataSetWriterMessageDataType->dataSetOffset = 0; + dataSetWriterMessageDataType->configuredSize = 0; + } + + /* The field encoding depends on the flags inside the writer config. + * TODO: This can be moved to the encoding layer. */ + if(dataSetWriter->config.dataSetFieldContentMask & (u64)UA_DATASETFIELDCONTENTMASK_RAWDATA +) { + dataSetMessage->header.fieldEncoding = UA_FIELDENCODING_RAWDATA; + } else if((u64)dataSetWriter->config.dataSetFieldContentMask & + ((u64)UA_DATASETFIELDCONTENTMASK_SOURCETIMESTAMP | (u64)UA_DATASETFIELDCONTENTMASK_SERVERPICOSECONDS | + (u64)UA_DATASETFIELDCONTENTMASK_SOURCEPICOSECONDS | (u64)UA_DATASETFIELDCONTENTMASK_STATUSCODE)) { + dataSetMessage->header.fieldEncoding = UA_FIELDENCODING_DATAVALUE; + } else { + dataSetMessage->header.fieldEncoding = UA_FIELDENCODING_VARIANT; + } + if(messageType == UA_TYPES_UADPDATASETWRITERMESSAGEDATATYPE) { + /* Std: 'The DataSetMessageContentMask defines the flags for the content of the DataSetMessage header.' */ + if((u64)dataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_UADPDATASETMESSAGECONTENTMASK_MAJORVERSION) { + dataSetMessage->header.configVersionMajorVersionEnabled = true; + dataSetMessage->header.configVersionMajorVersion = + currentDataSet->dataSetMetaData.configurationVersion.majorVersion; + } + if((u64)dataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_UADPDATASETMESSAGECONTENTMASK_MINORVERSION) { + dataSetMessage->header.configVersionMinorVersionEnabled = true; + dataSetMessage->header.configVersionMinorVersion = + currentDataSet->dataSetMetaData.configurationVersion.minorVersion; + } -#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ + if((u64)dataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_UADPDATASETMESSAGECONTENTMASK_SEQUENCENUMBER) { + dataSetMessage->header.dataSetMessageSequenceNrEnabled = true; + dataSetMessage->header.dataSetMessageSequenceNr = + dataSetWriter->actualDataSetMessageSequenceCount; + } -#define UA_VALUENCODING_MAXSTACK 512 + if((u64)dataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_UADPDATASETMESSAGECONTENTMASK_TIMESTAMP) { + dataSetMessage->header.timestampEnabled = true; + dataSetMessage->header.timestamp = UA_DateTime_now(); + } + /* TODO: Picoseconds resolution not supported atm */ + if((u64)dataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_UADPDATASETMESSAGECONTENTMASK_PICOSECONDS) { + dataSetMessage->header.picoSecondsIncluded = false; + } -UA_MonitoredItem * -UA_MonitoredItem_new(UA_MonitoredItemType monType) { - /* Allocate the memory */ - UA_MonitoredItem *newItem = - (UA_MonitoredItem *) UA_calloc(1, sizeof(UA_MonitoredItem)); - if(!newItem) - return NULL; + /* TODO: Statuscode not supported yet */ + if((u64)dataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_UADPDATASETMESSAGECONTENTMASK_STATUS) { + dataSetMessage->header.statusEnabled = false; + } + } else if(messageType == UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE) { + if((u64)jsonDataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_JSONDATASETMESSAGECONTENTMASK_METADATAVERSION) { + dataSetMessage->header.configVersionMajorVersionEnabled = true; + dataSetMessage->header.configVersionMajorVersion = + currentDataSet->dataSetMetaData.configurationVersion.majorVersion; + } + if((u64)jsonDataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_JSONDATASETMESSAGECONTENTMASK_METADATAVERSION) { + dataSetMessage->header.configVersionMinorVersionEnabled = true; + dataSetMessage->header.configVersionMinorVersion = + currentDataSet->dataSetMetaData.configurationVersion.minorVersion; + } - /* Remaining members are covered by calloc zeroing out the memory */ - newItem->monitoredItemType = monType; /* currently hardcoded */ - newItem->timestampsToReturn = UA_TIMESTAMPSTORETURN_SOURCE; - TAILQ_INIT(&newItem->queue); - return newItem; + if((u64)jsonDataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_JSONDATASETMESSAGECONTENTMASK_SEQUENCENUMBER) { + dataSetMessage->header.dataSetMessageSequenceNrEnabled = true; + dataSetMessage->header.dataSetMessageSequenceNr = + dataSetWriter->actualDataSetMessageSequenceCount; + } + + if((u64)jsonDataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_JSONDATASETMESSAGECONTENTMASK_TIMESTAMP) { + dataSetMessage->header.timestampEnabled = true; + dataSetMessage->header.timestamp = UA_DateTime_now(); + } + + /* TODO: Statuscode not supported yet */ + if((u64)jsonDataSetWriterMessageDataType->dataSetMessageContentMask & + (u64)UA_JSONDATASETMESSAGECONTENTMASK_STATUS) { + dataSetMessage->header.statusEnabled = false; + } + } + + /* Set the sequence count. Automatically rolls over to zero */ + dataSetWriter->actualDataSetMessageSequenceCount++; + + /* JSON does not differ between deltaframes and keyframes, only keyframes are currently used. */ + if(messageType != UA_TYPES_JSONDATASETWRITERMESSAGEDATATYPE){ +#ifdef UA_ENABLE_PUBSUB_DELTAFRAMES + /* Check if the PublishedDataSet version has changed -> if yes flush the lastValue store and send a KeyFrame */ + if(dataSetWriter->connectedDataSetVersion.majorVersion != currentDataSet->dataSetMetaData.configurationVersion.majorVersion || + dataSetWriter->connectedDataSetVersion.minorVersion != currentDataSet->dataSetMetaData.configurationVersion.minorVersion) { + /* Remove old samples */ + for(size_t i = 0; i < dataSetWriter->lastSamplesCount; i++) + UA_DataValue_deleteMembers(&dataSetWriter->lastSamples[i].value); + + /* Realloc pds dependent memory */ + dataSetWriter->lastSamplesCount = currentDataSet->fieldSize; + UA_DataSetWriterSample *newSamplesArray = (UA_DataSetWriterSample * ) + UA_realloc(dataSetWriter->lastSamples, sizeof(UA_DataSetWriterSample) * dataSetWriter->lastSamplesCount); + if(!newSamplesArray) + return UA_STATUSCODE_BADOUTOFMEMORY; + dataSetWriter->lastSamples = newSamplesArray; + memset(dataSetWriter->lastSamples, 0, sizeof(UA_DataSetWriterSample) * dataSetWriter->lastSamplesCount); + + dataSetWriter->connectedDataSetVersion = currentDataSet->dataSetMetaData.configurationVersion; + UA_PubSubDataSetWriter_generateKeyFrameMessage(server, dataSetMessage, dataSetWriter); + dataSetWriter->deltaFrameCounter = 0; + return UA_STATUSCODE_GOOD; + } + + /* The standard defines: if a PDS contains only one fields no delta messages + * should be generated because they need more memory than a keyframe with 1 + * field. */ + if(currentDataSet->fieldSize > 1 && dataSetWriter->deltaFrameCounter > 0 && + dataSetWriter->deltaFrameCounter <= dataSetWriter->config.keyFrameCount) { + UA_PubSubDataSetWriter_generateDeltaFrameMessage(server, dataSetMessage, dataSetWriter); + dataSetWriter->deltaFrameCounter++; + return UA_STATUSCODE_GOOD; + } + + dataSetWriter->deltaFrameCounter = 1; +#endif + } + + UA_PubSubDataSetWriter_generateKeyFrameMessage(server, dataSetMessage, dataSetWriter); + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +sendNetworkMessageJson(UA_PubSubConnection *connection, UA_DataSetMessage *dsm, + UA_UInt16 *writerIds, UA_Byte dsmCount, UA_ExtensionObject *transportSettings) { + UA_StatusCode retval = UA_STATUSCODE_BADNOTSUPPORTED; +#ifdef UA_ENABLE_JSON_ENCODING + UA_NetworkMessage nm; + memset(&nm, 0, sizeof(UA_NetworkMessage)); + nm.version = 1; + nm.networkMessageType = UA_NETWORKMESSAGE_DATASET; + nm.payloadHeaderEnabled = true; + + nm.payloadHeader.dataSetPayloadHeader.count = dsmCount; + nm.payloadHeader.dataSetPayloadHeader.dataSetWriterIds = writerIds; + nm.payload.dataSetPayload.dataSetMessages = dsm; + + /* Allocate the buffer. Allocate on the stack if the buffer is small. */ + UA_ByteString buf; + size_t msgSize = UA_NetworkMessage_calcSizeJson(&nm, NULL, 0, NULL, 0, true); + size_t stackSize = 1; + if(msgSize <= UA_MAX_STACKBUF) + stackSize = msgSize; + UA_STACKARRAY(UA_Byte, stackBuf, stackSize); + buf.data = stackBuf; + buf.length = msgSize; + if(msgSize > UA_MAX_STACKBUF) { + retval = UA_ByteString_allocBuffer(&buf, msgSize); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } + + /* Encode the message */ + UA_Byte *bufPos = buf.data; + memset(bufPos, 0, msgSize); + const UA_Byte *bufEnd = &buf.data[buf.length]; + retval = UA_NetworkMessage_encodeJson(&nm, &bufPos, &bufEnd, NULL, 0, NULL, 0, true); + if(retval != UA_STATUSCODE_GOOD) { + if(msgSize > UA_MAX_STACKBUF) + UA_ByteString_deleteMembers(&buf); + return retval; + } + + /* Send the prepared messages */ + retval = connection->channel->send(connection->channel, transportSettings, &buf); + if(msgSize > UA_MAX_STACKBUF) + UA_ByteString_deleteMembers(&buf); +#endif + return retval; } +static UA_StatusCode +sendNetworkMessage(UA_PubSubConnection *connection, UA_WriterGroup *wg, + UA_DataSetMessage *dsm, UA_UInt16 *writerIds, UA_Byte dsmCount, + UA_ExtensionObject *messageSettings, + UA_ExtensionObject *transportSettings) { + + if(messageSettings->content.decoded.type != + &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]) + return UA_STATUSCODE_BADINTERNALERROR; + UA_UadpWriterGroupMessageDataType *wgm = (UA_UadpWriterGroupMessageDataType*) + messageSettings->content.decoded.data; + + UA_NetworkMessage nm; + memset(&nm, 0, sizeof(UA_NetworkMessage)); + + nm.publisherIdEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_PUBLISHERID) != 0; + nm.groupHeaderEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_GROUPHEADER) != 0; + nm.groupHeader.writerGroupIdEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_WRITERGROUPID) != 0; + nm.groupHeader.groupVersionEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_GROUPVERSION) != 0; + nm.groupHeader.networkMessageNumberEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_NETWORKMESSAGENUMBER) != 0; + nm.groupHeader.sequenceNumberEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_SEQUENCENUMBER) != 0; + nm.payloadHeaderEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_PAYLOADHEADER) != 0; + nm.timestampEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_TIMESTAMP) != 0; + nm.picosecondsEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_PICOSECONDS) != 0; + nm.dataSetClassIdEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_DATASETCLASSID) != 0; + nm.promotedFieldsEnabled = + ((u64)wgm->networkMessageContentMask & (u64)UA_UADPNETWORKMESSAGECONTENTMASK_PROMOTEDFIELDS) != 0; + + nm.version = 1; + nm.networkMessageType = UA_NETWORKMESSAGE_DATASET; + if(connection->config->publisherIdType == UA_PUBSUB_PUBLISHERID_NUMERIC) { + nm.publisherIdType = UA_PUBLISHERDATATYPE_UINT16; + nm.publisherId.publisherIdUInt32 = connection->config->publisherId.numeric; + } else if(connection->config->publisherIdType == UA_PUBSUB_PUBLISHERID_STRING){ + nm.publisherIdType = UA_PUBLISHERDATATYPE_STRING; + nm.publisherId.publisherIdString = connection->config->publisherId.string; + } + + /* Compute the length of the dsm separately for the header */ + UA_STACKARRAY(UA_UInt16, dsmLengths, dsmCount); + for(UA_Byte i = 0; i < dsmCount; i++) + dsmLengths[i] = (UA_UInt16)UA_DataSetMessage_calcSizeBinary(&dsm[i]); + + nm.payloadHeader.dataSetPayloadHeader.count = dsmCount; + nm.payloadHeader.dataSetPayloadHeader.dataSetWriterIds = writerIds; + nm.groupHeader.writerGroupId = wg->config.writerGroupId; + nm.groupHeader.networkMessageNumber = 1; + nm.payload.dataSetPayload.sizes = dsmLengths; + nm.payload.dataSetPayload.dataSetMessages = dsm; + + /* Allocate the buffer. Allocate on the stack if the buffer is small. */ + UA_ByteString buf; + size_t msgSize = UA_NetworkMessage_calcSizeBinary(&nm); + size_t stackSize = 1; + if(msgSize <= UA_MAX_STACKBUF) + stackSize = msgSize; + UA_STACKARRAY(UA_Byte, stackBuf, stackSize); + buf.data = stackBuf; + buf.length = msgSize; + UA_StatusCode retval; + if(msgSize > UA_MAX_STACKBUF) { + retval = UA_ByteString_allocBuffer(&buf, msgSize); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } + + /* Encode the message */ + UA_Byte *bufPos = buf.data; + memset(bufPos, 0, msgSize); + const UA_Byte *bufEnd = &buf.data[buf.length]; + retval = UA_NetworkMessage_encodeBinary(&nm, &bufPos, bufEnd); + if(retval != UA_STATUSCODE_GOOD) { + if(msgSize > UA_MAX_STACKBUF) + UA_ByteString_deleteMembers(&buf); + return retval; + } + + /* Send the prepared messages */ + retval = connection->channel->send(connection->channel, transportSettings, &buf); + if(msgSize > UA_MAX_STACKBUF) + UA_ByteString_deleteMembers(&buf); + return retval; +} + +/* This callback triggers the collection and publish of NetworkMessages and the + * contained DataSetMessages. */ void -MonitoredItem_delete(UA_Server *server, UA_MonitoredItem *monitoredItem) { - UA_Subscription *sub = monitoredItem->subscription; +UA_WriterGroup_publishCallback(UA_Server *server, UA_WriterGroup *writerGroup) { + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Publish Callback"); - if(monitoredItem->monitoredItemType == UA_MONITOREDITEMTYPE_CHANGENOTIFY) { - /* Remove the sampling callback */ - MonitoredItem_unregisterSampleCallback(server, monitoredItem); + if(!writerGroup) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Publish failed. WriterGroup not found"); + return; + } - /* Clear the queued notifications */ - UA_Notification *notification, *notification_tmp; - TAILQ_FOREACH_SAFE(notification, &monitoredItem->queue, listEntry, notification_tmp) { - /* Remove the item from the queues */ - TAILQ_REMOVE(&monitoredItem->queue, notification, listEntry); - TAILQ_REMOVE(&sub->notificationQueue, notification, globalEntry); - --sub->notificationQueueSize; + /* Nothing to do? */ + if(writerGroup->writersCount <= 0) + return; + + /* Binary or Json encoding? */ + if(writerGroup->config.encodingMimeType != UA_PUBSUB_ENCODING_UADP && + writerGroup->config.encodingMimeType != UA_PUBSUB_ENCODING_JSON) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Publish failed: Unknown encoding type."); + return; + } - UA_DataValue_deleteMembers(¬ification->data.value); - UA_free(notification); + /* Find the connection associated with the writer */ + UA_PubSubConnection *connection = + UA_PubSubConnection_findConnectionbyId(server, writerGroup->linkedConnection); + if(!connection) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Publish failed. PubSubConnection invalid."); + return; + } + + /* How many DSM can be sent in one NM? */ + UA_Byte maxDSM = (UA_Byte)writerGroup->config.maxEncapsulatedDataSetMessageCount; + if(writerGroup->config.maxEncapsulatedDataSetMessageCount > UA_BYTE_MAX) + maxDSM = UA_BYTE_MAX; + /* If the maxEncapsulatedDataSetMessageCount is set to 0->1 */ + if(maxDSM == 0) + maxDSM = 1; + + /* It is possible to put several DataSetMessages into one NetworkMessage. + * But only if they do not contain promoted fields. NM with only DSM are + * sent out right away. The others are kept in a buffer for "batching". */ + size_t dsmCount = 0; + UA_DataSetWriter *dsw; + UA_STACKARRAY(UA_UInt16, dsWriterIds, writerGroup->writersCount); + UA_STACKARRAY(UA_DataSetMessage, dsmStore, writerGroup->writersCount); + LIST_FOREACH(dsw, &writerGroup->writers, listEntry) { + /* Find the dataset */ + UA_PublishedDataSet *pds = + UA_PublishedDataSet_findPDSbyId(server, dsw->connectedDataSet); + if(!pds) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Publish: PublishedDataSet not found"); + continue; } - monitoredItem->queueSize = 0; - } else { - /* TODO: Access val data.event */ - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, - "MonitoredItemTypes other than ChangeNotify are not supported yet"); + + /* Generate the DSM */ + UA_StatusCode res = + UA_DataSetWriter_generateDataSetMessage(server, &dsmStore[dsmCount], dsw); + if(res != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Publish: DataSetMessage creation failed"); + continue; + } + + /* Send right away if there is only this DSM in a NM. If promoted fields + * are contained in the PublishedDataSet, then this DSM must go into a + * dedicated NM as well. */ + if(pds->promotedFieldsCount > 0 || maxDSM == 1) { + if(writerGroup->config.encodingMimeType == UA_PUBSUB_ENCODING_UADP){ + res = sendNetworkMessage(connection, writerGroup, &dsmStore[dsmCount], + &dsw->config.dataSetWriterId, 1, + &writerGroup->config.messageSettings, + &writerGroup->config.transportSettings); + }else if(writerGroup->config.encodingMimeType == UA_PUBSUB_ENCODING_JSON){ + res = sendNetworkMessageJson(connection, &dsmStore[dsmCount], + &dsw->config.dataSetWriterId, 1, &writerGroup->config.transportSettings); + } + if(res != UA_STATUSCODE_GOOD) + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Publish: Could not send a NetworkMessage"); + UA_DataSetMessage_free(&dsmStore[dsmCount]); + continue; + } + + dsWriterIds[dsmCount] = dsw->config.dataSetWriterId; + dsmCount++; + } + + /* Send the NetworkMessages with batched DataSetMessages */ + size_t nmCount = (dsmCount / maxDSM) + ((dsmCount % maxDSM) == 0 ? 0 : 1); + for(UA_UInt32 i = 0; i < nmCount; i++) { + UA_Byte nmDsmCount = maxDSM; + if(i == nmCount - 1 && (dsmCount % maxDSM)) + nmDsmCount = (UA_Byte)dsmCount % maxDSM; + + UA_StatusCode res3 = UA_STATUSCODE_GOOD; + if(writerGroup->config.encodingMimeType == UA_PUBSUB_ENCODING_UADP){ + res3 = sendNetworkMessage(connection, writerGroup, &dsmStore[i * maxDSM], + &dsWriterIds[i * maxDSM], nmDsmCount, + &writerGroup->config.messageSettings, + &writerGroup->config.transportSettings); + }else if(writerGroup->config.encodingMimeType == UA_PUBSUB_ENCODING_JSON){ + res3 = sendNetworkMessageJson(connection, &dsmStore[i * maxDSM], + &dsWriterIds[i * maxDSM], nmDsmCount, &writerGroup->config.transportSettings); + } + if(res3 != UA_STATUSCODE_GOOD) + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Publish: Sending a NetworkMessage failed"); } - /* Remove the monitored item */ - if(monitoredItem->listEntry.le_prev != NULL) - LIST_REMOVE(monitoredItem, listEntry); - UA_String_deleteMembers(&monitoredItem->indexRange); - UA_ByteString_deleteMembers(&monitoredItem->lastSampledValue); - UA_Variant_deleteMembers(&monitoredItem->lastValue); - UA_NodeId_deleteMembers(&monitoredItem->monitoredNodeId); - UA_Server_delayedFree(server, monitoredItem); + /* Clean up DSM */ + for(size_t i = 0; i < dsmCount; i++) + UA_DataSetMessage_free(&dsmStore[i]); } -void MonitoredItem_ensureQueueSpace(UA_MonitoredItem *mon) { - if(mon->queueSize <= mon->maxQueueSize) +/* Add new publishCallback. The first execution is triggered directly after + * creation. */ +UA_StatusCode +UA_WriterGroup_addPublishCallback(UA_Server *server, UA_WriterGroup *writerGroup) { + UA_StatusCode retval = + UA_PubSubManager_addRepeatedCallback(server, + (UA_ServerCallback) UA_WriterGroup_publishCallback, + writerGroup, writerGroup->config.publishingInterval, + &writerGroup->publishCallbackId); + if(retval == UA_STATUSCODE_GOOD) + writerGroup->publishCallbackIsRegistered = true; + + /* Run once after creation */ + UA_WriterGroup_publishCallback(server, writerGroup); + return retval; +} + +/* This callback triggers the collection and reception of NetworkMessages and the + * contained DataSetMessages. */ +void UA_ReaderGroup_subscribeCallback(UA_Server *server, UA_ReaderGroup *readerGroup) { + UA_PubSubConnection *connection = UA_PubSubConnection_findConnectionbyId(server, readerGroup->linkedConnection); + UA_ByteString buffer; + if(UA_ByteString_allocBuffer(&buffer, 512) != UA_STATUSCODE_GOOD) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "Message buffer alloc failed!"); return; + } - /* Remove notifications until the queue size is reached */ - UA_Subscription *sub = mon->subscription; - while(mon->queueSize > mon->maxQueueSize) { - UA_assert(mon->queueSize >= 2); /* At least two Notifications in the queue */ - - /* Make sure that the MonitoredItem does not lose its place in the - * global queue when notifications are removed. Otherwise the - * MonitoredItem can "starve" itself by putting new notifications always - * at the end of the global queue and removing the old ones. - * - * - If the oldest notification is removed, put the second oldest - * notification right behind it. - * - If the newest notification is removed, put the new notification - * right behind it. */ - - UA_Notification *del; /* The notification that will be deleted */ - UA_Notification *after_del; /* The notification to keep and move after del */ - if(mon->discardOldest) { - /* Remove the oldest */ - del = TAILQ_FIRST(&mon->queue); - after_del = TAILQ_NEXT(del, listEntry); - } else { - /* Remove the second newest (to keep the up-to-date notification) */ - after_del = TAILQ_LAST(&mon->queue, NotificationQueue); - del = TAILQ_PREV(after_del, NotificationQueue, listEntry); + connection->channel->receive(connection->channel, &buffer, NULL, 300000); + if(buffer.length > 0) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_USERLAND, "Message received:"); + UA_NetworkMessage currentNetworkMessage; + memset(¤tNetworkMessage, 0, sizeof(UA_NetworkMessage)); + size_t currentPosition = 0; + UA_NetworkMessage_decodeBinary(&buffer, ¤tPosition, ¤tNetworkMessage); + UA_Server_processNetworkMessage(server, ¤tNetworkMessage, connection); + UA_NetworkMessage_deleteMembers(¤tNetworkMessage); + } + + UA_ByteString_deleteMembers(&buffer); +} + +/* Add new subscribeCallback. The first execution is triggered directly after + * creation. */ +UA_StatusCode +UA_ReaderGroup_addSubscribeCallback(UA_Server *server, UA_ReaderGroup *readerGroup) { + UA_StatusCode retval = UA_STATUSCODE_GOOD; + UA_PubSubConnection *connection = UA_PubSubConnection_findConnectionbyId(server, readerGroup->linkedConnection); + if(connection != NULL) { + retval = connection->channel->regist(connection->channel, NULL, NULL); + if(retval == UA_STATUSCODE_GOOD) { + retval = UA_PubSubManager_addRepeatedCallback(server, + (UA_ServerCallback) UA_ReaderGroup_subscribeCallback, + readerGroup, 5, + &readerGroup->subscribeCallbackId); + } + else { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "register channel failed: 0x%x!", retval); } - /* Move after_del right after del in the global queue */ - TAILQ_REMOVE(&sub->notificationQueue, after_del, globalEntry); - TAILQ_INSERT_AFTER(&sub->notificationQueue, del, after_del, globalEntry); + } - /* Remove the notification from the queues */ - TAILQ_REMOVE(&mon->queue, del, listEntry); - TAILQ_REMOVE(&sub->notificationQueue, del, globalEntry); - --mon->queueSize; - --sub->notificationQueueSize; + if(retval == UA_STATUSCODE_GOOD) { + readerGroup->subscribeCallbackIsRegistered = true; + } - /* Free the notification */ - if(mon->monitoredItemType == UA_MONITOREDITEMTYPE_CHANGENOTIFY) { - UA_DataValue_deleteMembers(&del->data.value); - } else { - /* TODO: event implemantation */ + /* Run once after creation */ + UA_ReaderGroup_subscribeCallback(server, readerGroup); + return retval; +} + +#endif /* UA_ENABLE_PUBSUB */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/pubsub/ua_pubsub_manager.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner) + * Copyright (c) 2018 Fraunhofer IOSB (Author: Julius Pfrommer) + */ + + +#ifdef UA_ENABLE_PUBSUB /* conditional compilation */ + +#define UA_DATETIMESTAMP_2000 125911584000000000 + +UA_StatusCode +UA_Server_addPubSubConnection(UA_Server *server, + const UA_PubSubConnectionConfig *connectionConfig, + UA_NodeId *connectionIdentifier) { + /* Find the matching UA_PubSubTransportLayers */ + UA_PubSubTransportLayer *tl = NULL; + for(size_t i = 0; i < server->config.pubsubTransportLayersSize; i++) { + if(connectionConfig && + UA_String_equal(&server->config.pubsubTransportLayers[i].transportProfileUri, + &connectionConfig->transportProfileUri)) { + tl = &server->config.pubsubTransportLayers[i]; } + } + if(!tl) { + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Connection creation failed. Requested transport layer not found."); + return UA_STATUSCODE_BADNOTFOUND; + } - /* Work around a false positive in clang analyzer */ -#ifndef __clang_analyzer__ - UA_free(del); -#endif + /* Create a copy of the connection config */ + UA_PubSubConnectionConfig *tmpConnectionConfig = (UA_PubSubConnectionConfig *) + UA_calloc(1, sizeof(UA_PubSubConnectionConfig)); + if(!tmpConnectionConfig){ + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Connection creation failed. Out of Memory."); + return UA_STATUSCODE_BADOUTOFMEMORY; } - if(mon->monitoredItemType == UA_MONITOREDITEMTYPE_CHANGENOTIFY) { - /* Get the element that carries the infobits */ - UA_Notification *notification = NULL; - if(mon->discardOldest) - notification = TAILQ_FIRST(&mon->queue); - else - notification = TAILQ_LAST(&mon->queue, NotificationQueue); - UA_assert(notification); + UA_StatusCode retval = UA_PubSubConnectionConfig_copy(connectionConfig, tmpConnectionConfig); + if(retval != UA_STATUSCODE_GOOD){ + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Connection creation failed. Could not copy the config."); + return retval; + } - if(mon->maxQueueSize > 1) { - /* Add the infobits either to the newest or the new last entry */ - notification->data.value.hasStatus = true; - notification->data.value.status |= (UA_STATUSCODE_INFOTYPE_DATAVALUE | - UA_STATUSCODE_INFOBITS_OVERFLOW); - } else { - /* If the queue size is reduced to one, remove the infobits */ - notification->data.value.status &= ~(UA_StatusCode)(UA_STATUSCODE_INFOTYPE_DATAVALUE | - UA_STATUSCODE_INFOBITS_OVERFLOW); + /* Create new connection and add to UA_PubSubManager */ + UA_PubSubConnection *newConnectionsField = (UA_PubSubConnection *) + UA_realloc(server->pubSubManager.connections, + sizeof(UA_PubSubConnection) * (server->pubSubManager.connectionsSize + 1)); + if(!newConnectionsField) { + UA_PubSubConnectionConfig_deleteMembers(tmpConnectionConfig); + UA_free(tmpConnectionConfig); + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Connection creation failed. Out of Memory."); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + server->pubSubManager.connections = newConnectionsField; + server->pubSubManager.connectionsSize++; + + UA_PubSubConnection *newConnection = + &server->pubSubManager.connections[server->pubSubManager.connectionsSize-1]; + + /* Initialize the new connection */ + memset(newConnection, 0, sizeof(UA_PubSubConnection)); + LIST_INIT(&newConnection->writerGroups); + //workaround - fixing issue with queue.h and realloc. + for(size_t n = 0; n < server->pubSubManager.connectionsSize; n++){ + if(server->pubSubManager.connections[n].writerGroups.lh_first){ + server->pubSubManager.connections[n].writerGroups.lh_first->listEntry.le_prev = &server->pubSubManager.connections[n].writerGroups.lh_first; + } + } + newConnection->config = tmpConnectionConfig; + + /* Open the channel */ + newConnection->channel = tl->createPubSubChannel(newConnection->config); + if(!newConnection->channel) { + UA_PubSubConnection_deleteMembers(server, newConnection); + server->pubSubManager.connectionsSize--; + /* Keep the realloced (longer) array if entries remain */ + if(server->pubSubManager.connectionsSize == 0) { + UA_free(server->pubSubManager.connections); + server->pubSubManager.connections = NULL; } + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PubSub Connection creation failed. Transport layer creation problem."); + return UA_STATUSCODE_BADINTERNALERROR; } - /* TODO: Infobits for Events? */ + UA_PubSubManager_generateUniqueNodeId(server, &newConnection->identifier); + + if(connectionIdentifier) + UA_NodeId_copy(&newConnection->identifier, connectionIdentifier); + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + addPubSubConnectionRepresentation(server, newConnection); +#endif + return UA_STATUSCODE_GOOD; } -#define ABS_SUBTRACT_TYPE_INDEPENDENT(a,b) ((a)>(b)?(a)-(b):(b)-(a)) +UA_StatusCode +UA_Server_removePubSubConnection(UA_Server *server, const UA_NodeId connection) { + //search the identified Connection and store the Connection index + size_t connectionIndex; + UA_PubSubConnection *currentConnection = NULL; + for(connectionIndex = 0; connectionIndex < server->pubSubManager.connectionsSize; connectionIndex++){ + if(UA_NodeId_equal(&connection, &server->pubSubManager.connections[connectionIndex].identifier)){ + currentConnection = &server->pubSubManager.connections[connectionIndex]; + break; + } + } + if(!currentConnection) + return UA_STATUSCODE_BADNOTFOUND; -static UA_INLINE UA_Boolean -outOfDeadBand(const void *data1, const void *data2, const size_t index, const UA_DataType *type, const UA_Double deadbandValue) { - if(type == &UA_TYPES[UA_TYPES_BOOLEAN]) { - if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Boolean*)data1)[index], ((const UA_Boolean*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_SBYTE]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_SByte*)data1)[index], ((const UA_SByte*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_BYTE]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Byte*)data1)[index], ((const UA_Byte*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_INT16]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int16*)data1)[index], ((const UA_Int16*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_UINT16]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt16*)data1)[index], ((const UA_UInt16*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_INT32]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int32*)data1)[index], ((const UA_Int32*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_UINT32]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt32*)data1)[index], ((const UA_UInt32*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_INT64]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int64*)data1)[index], ((const UA_Int64*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_UINT64]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt64*)data1)[index], ((const UA_UInt64*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_FLOAT]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Float*)data1)[index], ((const UA_Float*)data2)[index]) <= deadbandValue) - return false; - } else - if (type == &UA_TYPES[UA_TYPES_DOUBLE]) { - if (ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Double*)data1)[index], ((const UA_Double*)data2)[index]) <= deadbandValue) - return false; +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + removePubSubConnectionRepresentation(server, currentConnection); +#endif + UA_PubSubConnection_deleteMembers(server, currentConnection); + server->pubSubManager.connectionsSize--; + //remove the connection from the pubSubManager, move the last connection + //into the allocated memory of the deleted connection + if(server->pubSubManager.connectionsSize != connectionIndex){ + memcpy(&server->pubSubManager.connections[connectionIndex], + &server->pubSubManager.connections[server->pubSubManager.connectionsSize], + sizeof(UA_PubSubConnection)); + } + + if(server->pubSubManager.connectionsSize <= 0){ + UA_free(server->pubSubManager.connections); + server->pubSubManager.connections = NULL; + } else { + server->pubSubManager.connections = (UA_PubSubConnection *) + UA_realloc(server->pubSubManager.connections, sizeof(UA_PubSubConnection) * server->pubSubManager.connectionsSize); + if(!server->pubSubManager.connections){ + return UA_STATUSCODE_BADINTERNALERROR; + } + //workaround - fixing issue with queue.h and realloc. + for(size_t n = 0; n < server->pubSubManager.connectionsSize; n++){ + if(server->pubSubManager.connections[n].writerGroups.lh_first){ + server->pubSubManager.connections[n].writerGroups.lh_first->listEntry.le_prev = &server->pubSubManager.connections[n].writerGroups.lh_first; + } + } } - return true; + return UA_STATUSCODE_GOOD; } -static UA_INLINE UA_Boolean -updateNeededForFilteredValue(const UA_Variant *value, const UA_Variant *oldValue, const UA_Double deadbandValue) { - if (value->arrayLength != oldValue->arrayLength) { - return true; +UA_AddPublishedDataSetResult +UA_Server_addPublishedDataSet(UA_Server *server, const UA_PublishedDataSetConfig *publishedDataSetConfig, + UA_NodeId *pdsIdentifier) { + UA_AddPublishedDataSetResult result = {UA_STATUSCODE_BADINVALIDARGUMENT, 0, NULL, {0, 0}}; + if(!publishedDataSetConfig){ + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PublishedDataSet creation failed. No config passed in."); + return result; } - if (value->type != oldValue->type) { - return true; + if(publishedDataSetConfig->publishedDataSetType != UA_PUBSUB_DATASET_PUBLISHEDITEMS){ + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PublishedDataSet creation failed. Unsupported PublishedDataSet type."); + return result; } - if (UA_Variant_isScalar(value)) { - return outOfDeadBand(value->data, oldValue->data, 0, value->type, deadbandValue); + //deep copy the given connection config + UA_PublishedDataSetConfig tmpPublishedDataSetConfig; + memset(&tmpPublishedDataSetConfig, 0, sizeof(UA_PublishedDataSetConfig)); + if(UA_PublishedDataSetConfig_copy(publishedDataSetConfig, &tmpPublishedDataSetConfig) != UA_STATUSCODE_GOOD){ + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PublishedDataSet creation failed. Configuration copy failed."); + result.addResult = UA_STATUSCODE_BADINTERNALERROR; + return result; + } + //create new PDS and add to UA_PubSubManager + UA_PublishedDataSet *newPubSubDataSetField = (UA_PublishedDataSet *) + UA_realloc(server->pubSubManager.publishedDataSets, + sizeof(UA_PublishedDataSet) * (server->pubSubManager.publishedDataSetsSize + 1)); + if(!newPubSubDataSetField) { + UA_PublishedDataSetConfig_deleteMembers(&tmpPublishedDataSetConfig); + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "PublishedDataSet creation failed. Out of Memory."); + result.addResult = UA_STATUSCODE_BADOUTOFMEMORY; + return result; + } + server->pubSubManager.publishedDataSets = newPubSubDataSetField; + UA_PublishedDataSet *newPubSubDataSet = &server->pubSubManager.publishedDataSets[(server->pubSubManager.publishedDataSetsSize)]; + memset(newPubSubDataSet, 0, sizeof(UA_PublishedDataSet)); + LIST_INIT(&newPubSubDataSet->fields); + //workaround - fixing issue with queue.h and realloc. + for(size_t n = 0; n < server->pubSubManager.publishedDataSetsSize; n++){ + if(server->pubSubManager.publishedDataSets[n].fields.lh_first){ + server->pubSubManager.publishedDataSets[n].fields.lh_first->listEntry.le_prev = &server->pubSubManager.publishedDataSets[n].fields.lh_first; + } + } + newPubSubDataSet->config = tmpPublishedDataSetConfig; + if(tmpPublishedDataSetConfig.publishedDataSetType == UA_PUBSUB_DATASET_PUBLISHEDITEMS_TEMPLATE){ + //parse template config and add fields (later PubSub batch) + } + //generate unique nodeId + UA_PubSubManager_generateUniqueNodeId(server, &newPubSubDataSet->identifier); + if(pdsIdentifier != NULL){ + UA_NodeId_copy(&newPubSubDataSet->identifier, pdsIdentifier); + } + server->pubSubManager.publishedDataSetsSize++; + result.addResult = UA_STATUSCODE_GOOD; + result.fieldAddResults = NULL; + result.fieldAddResultsSize = 0; + result.configurationVersion.majorVersion = UA_PubSubConfigurationVersionTimeDifference(); + result.configurationVersion.minorVersion = UA_PubSubConfigurationVersionTimeDifference(); +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + addPublishedDataItemsRepresentation(server, newPubSubDataSet); +#endif + return result; +} + +UA_StatusCode +UA_Server_removePublishedDataSet(UA_Server *server, const UA_NodeId pds) { + //search the identified PublishedDataSet and store the PDS index + UA_PublishedDataSet *publishedDataSet = NULL; + size_t publishedDataSetIndex; + for(publishedDataSetIndex = 0; publishedDataSetIndex < server->pubSubManager.publishedDataSetsSize; publishedDataSetIndex++){ + if(UA_NodeId_equal(&server->pubSubManager.publishedDataSets[publishedDataSetIndex].identifier, &pds)){ + publishedDataSet = &server->pubSubManager.publishedDataSets[publishedDataSetIndex]; + break; + } + } + if(!publishedDataSet){ + return UA_STATUSCODE_BADNOTFOUND; + } + //search for referenced writers -> delete this writers. (Standard: writer must be connected with PDS) + for(size_t i = 0; i < server->pubSubManager.connectionsSize; i++){ + UA_WriterGroup *writerGroup; + LIST_FOREACH(writerGroup, &server->pubSubManager.connections[i].writerGroups, listEntry){ + UA_DataSetWriter *currentWriter, *tmpWriterGroup; + LIST_FOREACH_SAFE(currentWriter, &writerGroup->writers, listEntry, tmpWriterGroup){ + if(UA_NodeId_equal(¤tWriter->connectedDataSet, &publishedDataSet->identifier)){ + UA_Server_removeDataSetWriter(server, currentWriter->identifier); + } + } + } + } +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL + removePublishedDataSetRepresentation(server, publishedDataSet); +#endif + UA_PublishedDataSet_deleteMembers(server, publishedDataSet); + server->pubSubManager.publishedDataSetsSize--; + //copy the last PDS to the removed PDS inside the allocated memory block + if(server->pubSubManager.publishedDataSetsSize != publishedDataSetIndex){ + memcpy(&server->pubSubManager.publishedDataSets[publishedDataSetIndex], + &server->pubSubManager.publishedDataSets[server->pubSubManager.publishedDataSetsSize], + sizeof(UA_PublishedDataSet)); + } + if(server->pubSubManager.publishedDataSetsSize <= 0){ + UA_free(server->pubSubManager.publishedDataSets); + server->pubSubManager.publishedDataSets = NULL; } else { - for (size_t i = 0; i < value->arrayLength; ++i) { - if (outOfDeadBand(value->data, oldValue->data, i, value->type, deadbandValue)) - return true; + server->pubSubManager.publishedDataSets = (UA_PublishedDataSet *) + UA_realloc(server->pubSubManager.publishedDataSets, sizeof(UA_PublishedDataSet) * server->pubSubManager.publishedDataSetsSize); + if(!server->pubSubManager.publishedDataSets){ + return UA_STATUSCODE_BADINTERNALERROR; + } + //workaround - fixing issue with queue.h and realloc. + for(size_t n = 0; n < server->pubSubManager.publishedDataSetsSize; n++){ + if(server->pubSubManager.publishedDataSets[n].fields.lh_first){ + server->pubSubManager.publishedDataSets[n].fields.lh_first->listEntry.le_prev = &server->pubSubManager.publishedDataSets[n].fields.lh_first; + } } } - return false; + return UA_STATUSCODE_GOOD; } -/* Errors are returned as no change detected */ -static UA_Boolean -detectValueChangeWithFilter(UA_MonitoredItem *mon, UA_DataValue *value, - UA_ByteString *encoding) { - if (isDataTypeNumeric(value->value.type) - && (mon->filter.trigger == UA_DATACHANGETRIGGER_STATUSVALUE - || mon->filter.trigger == UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP)) { - if (mon->filter.deadbandType == UA_DEADBANDTYPE_ABSOLUTE) { - if (!updateNeededForFilteredValue(&value->value, &mon->lastValue, mon->filter.deadbandValue)) - return false; - } /*else if (mon->filter.deadbandType == UA_DEADBANDTYPE_PERCENT) { - // TODO where do this EURange come from ? - UA_Double deadbandValue = fabs(mon->filter.deadbandValue * (EURange.high-EURange.low)); - if (!updateNeededForFilteredValue(value->value, mon->lastValue, deadbandValue)) - return false; - }*/ +/* Calculate the time difference between current time and UTC (00:00) on January + * 1, 2000. */ +UA_UInt32 +UA_PubSubConfigurationVersionTimeDifference() { + UA_UInt32 timeDiffSince2000 = (UA_UInt32) (UA_DateTime_now() - UA_DATETIMESTAMP_2000); + return timeDiffSince2000; +} + +/* Generate a new unique NodeId. This NodeId will be used for the information + * model representation of PubSub entities. */ +void +UA_PubSubManager_generateUniqueNodeId(UA_Server *server, UA_NodeId *nodeId) { + UA_NodeId newNodeId = UA_NODEID_NUMERIC(0, 0); + UA_Node *newNode = UA_Nodestore_newNode(server->nsCtx, UA_NODECLASS_OBJECT); + UA_Nodestore_insertNode(server->nsCtx, newNode, &newNodeId); + UA_NodeId_copy(&newNodeId, nodeId); +} + +/* Delete the current PubSub configuration including all nested members. This + * action also delete the configured PubSub transport Layers. */ +void +UA_PubSubManager_delete(UA_Server *server, UA_PubSubManager *pubSubManager) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "PubSub cleanup was called."); + //free the currently configured transport layers + UA_free(server->config.pubsubTransportLayers); + server->config.pubsubTransportLayersSize = 0; + + //remove Connections and WriterGroups + while(pubSubManager->connectionsSize > 0){ + UA_Server_removePubSubConnection(server, pubSubManager->connections[pubSubManager->connectionsSize-1].identifier); + } + while(pubSubManager->publishedDataSetsSize > 0){ + UA_Server_removePublishedDataSet(server, pubSubManager->publishedDataSets[pubSubManager->publishedDataSetsSize-1].identifier); } +} - /* Encode the data for comparison */ - size_t binsize = UA_calcSizeBinary(value, &UA_TYPES[UA_TYPES_DATAVALUE]); - if(binsize == 0) - return false; +/***********************************/ +/* PubSub Jobs abstraction */ +/***********************************/ - /* Allocate buffer on the heap if necessary */ - if(binsize > UA_VALUENCODING_MAXSTACK && - UA_ByteString_allocBuffer(encoding, binsize) != UA_STATUSCODE_GOOD) - return false; +#ifndef UA_ENABLE_PUBSUB_CUSTOM_PUBLISH_HANDLING - /* Encode the value */ - UA_Byte *bufPos = encoding->data; - const UA_Byte *bufEnd = &encoding->data[encoding->length]; - UA_StatusCode retval = UA_encodeBinary(value, &UA_TYPES[UA_TYPES_DATAVALUE], - &bufPos, &bufEnd, NULL, NULL); - if(retval != UA_STATUSCODE_GOOD) - return false; +/* If UA_ENABLE_PUBSUB_CUSTOM_PUBLISH_INTERRUPT is enabled, a custom callback + * management must be linked to the application */ - /* The value has changed */ - encoding->length = (uintptr_t)bufPos - (uintptr_t)encoding->data; - return !mon->lastSampledValue.data || !UA_String_equal(encoding, &mon->lastSampledValue); +UA_StatusCode +UA_PubSubManager_addRepeatedCallback(UA_Server *server, UA_ServerCallback callback, + void *data, UA_Double interval_ms, UA_UInt64 *callbackId) { + return UA_Timer_addRepeatedCallback(&server->timer, (UA_ApplicationCallback)callback, + server, data, interval_ms, callbackId); } -/* Has this sample changed from the last one? The method may allocate additional - * space for the encoding buffer. Detect the change in encoding->data. */ -static UA_Boolean -detectValueChange(UA_MonitoredItem *mon, UA_DataValue *value, UA_ByteString *encoding) { - /* Apply Filter */ - UA_Boolean hasValue = value->hasValue; - if(mon->filter.trigger == UA_DATACHANGETRIGGER_STATUS) - value->hasValue = false; - - UA_Boolean hasServerTimestamp = value->hasServerTimestamp; - UA_Boolean hasServerPicoseconds = value->hasServerPicoseconds; - value->hasServerTimestamp = false; - value->hasServerPicoseconds = false; - - UA_Boolean hasSourceTimestamp = value->hasSourceTimestamp; - UA_Boolean hasSourcePicoseconds = value->hasSourcePicoseconds; - if(mon->filter.trigger < UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP) { - value->hasSourceTimestamp = false; - value->hasSourcePicoseconds = false; - } - - /* Detect the Value Change */ - UA_Boolean res = detectValueChangeWithFilter(mon, value, encoding); - - /* Reset the filter */ - value->hasValue = hasValue; - value->hasServerTimestamp = hasServerTimestamp; - value->hasServerPicoseconds = hasServerPicoseconds; - value->hasSourceTimestamp = hasSourceTimestamp; - value->hasSourcePicoseconds = hasSourcePicoseconds; - return res; +UA_StatusCode +UA_PubSubManager_changeRepeatedCallbackInterval(UA_Server *server, UA_UInt64 callbackId, + UA_Double interval_ms) { + return UA_Timer_changeRepeatedCallbackInterval(&server->timer, callbackId, interval_ms); } -/* Returns whether a new sample was created */ -static UA_Boolean -sampleCallbackWithValue(UA_Server *server, UA_Subscription *sub, - UA_MonitoredItem *monitoredItem, - UA_DataValue *value, - UA_ByteString *valueEncoding) { - UA_assert(monitoredItem->monitoredItemType == UA_MONITOREDITEMTYPE_CHANGENOTIFY); - /* Store the pointer to the stack-allocated bytestring to see if a heap-allocation - * was necessary */ - UA_Byte *stackValueEncoding = valueEncoding->data; +void +UA_PubSubManager_removeRepeatedPubSubCallback(UA_Server *server, UA_UInt64 callbackId) { + UA_Timer_removeCallback(&server->timer, callbackId); +} - /* Has the value changed? */ - UA_Boolean changed = detectValueChange(monitoredItem, value, valueEncoding); - if(!changed) - return false; +#endif /* UA_ENABLE_PUBSUB_CUSTOM_PUBLISH_HANDLING */ - /* Allocate the entry for the publish queue */ - UA_Notification *newNotification = - (UA_Notification *)UA_malloc(sizeof(UA_Notification)); - if(!newNotification) { - UA_LOG_WARNING_SESSION(server->config.logger, sub->session, - "Subscription %u | MonitoredItem %i | " - "Item for the publishing queue could not be allocated", - sub->subscriptionId, monitoredItem->monitoredItemId); - return false; - } +#endif /* UA_ENABLE_PUBSUB */ - /* Copy valueEncoding on the heap for the next comparison (if not already done) */ - if(valueEncoding->data == stackValueEncoding) { - UA_ByteString cbs; - if(UA_ByteString_copy(valueEncoding, &cbs) != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING_SESSION(server->config.logger, sub->session, - "Subscription %u | MonitoredItem %i | " - "ByteString to compare values could not be created", - sub->subscriptionId, monitoredItem->monitoredItemId); - UA_free(newNotification); - return false; +/*********************************** amalgamated original file "/home/jvoe/open62541/src/pubsub/ua_pubsub_ns0.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2017-2018 Fraunhofer IOSB (Author: Andreas Ebner) + * Copyright (c) 2019 Kalycito Infotech Private Limited + */ + + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL /* conditional compilation */ + +typedef struct{ + UA_NodeId parentNodeId; + UA_UInt32 parentClassifier; + UA_UInt32 elementClassiefier; +} UA_NodePropertyContext; + +//Prototypes +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode addWriterGroupAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output); +static UA_StatusCode removeGroupAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output); +static UA_StatusCode addDataSetWriterAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output); + +#endif + +static UA_StatusCode +addPubSubObjectNode(UA_Server *server, char* name, UA_UInt32 objectid, + UA_UInt32 parentid, UA_UInt32 referenceid, UA_UInt32 type_id) { + UA_ObjectAttributes object_attr = UA_ObjectAttributes_default; + object_attr.displayName = UA_LOCALIZEDTEXT("", name); + return UA_Server_addObjectNode(server, UA_NODEID_NUMERIC(0, objectid), + UA_NODEID_NUMERIC(0, parentid), + UA_NODEID_NUMERIC(0, referenceid), + UA_QUALIFIEDNAME(0, name), + UA_NODEID_NUMERIC(0, type_id), + object_attr, NULL, NULL); +} + +static UA_StatusCode +writePubSubNs0VariableArray(UA_Server *server, UA_UInt32 id, void *v, + size_t length, const UA_DataType *type) { + UA_Variant var; + UA_Variant_init(&var); + UA_Variant_setArray(&var, v, length, type); + return UA_Server_writeValue(server, UA_NODEID_NUMERIC(0, id), var); +} + +static UA_NodeId +findSingleChildNode(UA_Server *server, UA_QualifiedName targetName, + UA_NodeId referenceTypeId, UA_NodeId startingNode){ + UA_NodeId resultNodeId; + UA_RelativePathElement rpe; + UA_RelativePathElement_init(&rpe); + rpe.referenceTypeId = referenceTypeId; + rpe.isInverse = false; + rpe.includeSubtypes = false; + rpe.targetName = targetName; + UA_BrowsePath bp; + UA_BrowsePath_init(&bp); + bp.startingNode = startingNode; + bp.relativePath.elementsSize = 1; + bp.relativePath.elements = &rpe; + UA_BrowsePathResult bpr = + UA_Server_translateBrowsePathToNodeIds(server, &bp); + if(bpr.statusCode != UA_STATUSCODE_GOOD || + bpr.targetsSize < 1) + return UA_NODEID_NULL; + if(UA_NodeId_copy(&bpr.targets[0].targetId.nodeId, &resultNodeId) != UA_STATUSCODE_GOOD){ + UA_BrowsePathResult_deleteMembers(&bpr); + return UA_NODEID_NULL; + } + UA_BrowsePathResult_deleteMembers(&bpr); + return resultNodeId; +} + +static void +onRead(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeid, void *context, + const UA_NumericRange *range, const UA_DataValue *data) { + UA_Variant value; + UA_Variant_init(&value); + const UA_NodePropertyContext *nodeContext = (const UA_NodePropertyContext*)context; + const UA_NodeId *myNodeId = &nodeContext->parentNodeId; + + switch(nodeContext->parentClassifier){ + case UA_NS0ID_PUBSUBCONNECTIONTYPE: { + UA_PubSubConnection *pubSubConnection = + UA_PubSubConnection_findConnectionbyId(server, *myNodeId); + switch(nodeContext->elementClassiefier) { + case UA_NS0ID_PUBSUBCONNECTIONTYPE_PUBLISHERID: + if(pubSubConnection->config->publisherIdType == UA_PUBSUB_PUBLISHERID_STRING) { + UA_Variant_setScalar(&value, &pubSubConnection->config->publisherId.numeric, + &UA_TYPES[UA_TYPES_STRING]); + } else { + UA_Variant_setScalar(&value, &pubSubConnection->config->publisherId.numeric, + &UA_TYPES[UA_TYPES_UINT32]); + } + break; + default: + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Read error! Unknown property."); + } + break; + } + case UA_NS0ID_WRITERGROUPTYPE: { + UA_WriterGroup *writerGroup = UA_WriterGroup_findWGbyId(server, *myNodeId); + if(!writerGroup) + return; + switch(nodeContext->elementClassiefier){ + case UA_NS0ID_WRITERGROUPTYPE_PUBLISHINGINTERVAL: + UA_Variant_setScalar(&value, &writerGroup->config.publishingInterval, + &UA_TYPES[UA_TYPES_DURATION]); + break; + default: + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Read error! Unknown property."); } - *valueEncoding = cbs; + break; } + case UA_NS0ID_PUBLISHEDDATAITEMSTYPE: { + UA_PublishedDataSet *publishedDataSet = UA_PublishedDataSet_findPDSbyId(server, *myNodeId); + if(!publishedDataSet) + return; + switch(nodeContext->elementClassiefier) { + case UA_NS0ID_PUBLISHEDDATAITEMSTYPE_PUBLISHEDDATA: { + UA_PublishedVariableDataType *pvd = (UA_PublishedVariableDataType *) + UA_calloc(publishedDataSet->fieldSize, sizeof(UA_PublishedVariableDataType)); + size_t counter = 0; + UA_DataSetField *field; + LIST_FOREACH(field, &publishedDataSet->fields, listEntry) { + pvd[counter].attributeId = UA_ATTRIBUTEID_VALUE; + pvd[counter].publishedVariable = field->config.field.variable.publishParameters.publishedVariable; + //UA_NodeId_copy(&field->config.field.variable.publishParameters.publishedVariable, &pvd[counter].publishedVariable); + counter++; + } + UA_Variant_setArray(&value, pvd, publishedDataSet->fieldSize, + &UA_TYPES[UA_TYPES_PUBLISHEDVARIABLEDATATYPE]); + break; + } + case UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETMETADATA: { + UA_Variant_setScalarCopy(&value, &publishedDataSet->dataSetMetaData, &UA_TYPES[UA_TYPES_DATASETMETADATATYPE]); + break; + } + case UA_NS0ID_PUBLISHEDDATAITEMSTYPE_CONFIGURATIONVERSION: { + UA_Variant_setScalarCopy(&value, &publishedDataSet->dataSetMetaData.configurationVersion, + &UA_TYPES[UA_TYPES_CONFIGURATIONVERSIONDATATYPE]); + break; + } + default: + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Read error! Unknown property."); + } + break; + } + default: + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Read error! Unknown parent element."); + } + UA_Server_writeValue(server, *nodeid, value); +} - /* Prepare the newQueueItem */ - if(value->hasValue && value->value.storageType == UA_VARIANT_DATA_NODELETE) { - /* Make a deep copy of the value */ - UA_StatusCode retval = UA_DataValue_copy(value, &newNotification->data.value); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING_SESSION(server->config.logger, sub->session, - "Subscription %u | MonitoredItem %i | " - "Item for the publishing queue could not be prepared", - sub->subscriptionId, monitoredItem->monitoredItemId); - UA_free(newNotification); - return false; +static void +onWrite(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, void *nodeContext, + const UA_NumericRange *range, const UA_DataValue *data){ + UA_Variant value; + UA_NodeId myNodeId; + UA_WriterGroup *writerGroup = NULL; + switch(((UA_NodePropertyContext *) nodeContext)->parentClassifier){ + case UA_NS0ID_PUBSUBCONNECTIONTYPE: + //no runtime writable attributes + break; + case UA_NS0ID_WRITERGROUPTYPE: + myNodeId = ((UA_NodePropertyContext *) nodeContext)->parentNodeId; + writerGroup = UA_WriterGroup_findWGbyId(server, myNodeId); + UA_WriterGroupConfig writerGroupConfig; + memset(&writerGroupConfig, 0, sizeof(writerGroupConfig)); + if(!writerGroup) + return; + switch(((UA_NodePropertyContext *) nodeContext)->elementClassiefier){ + case UA_NS0ID_WRITERGROUPTYPE_PUBLISHINGINTERVAL: + UA_Server_getWriterGroupConfig(server, writerGroup->identifier, &writerGroupConfig); + writerGroupConfig.publishingInterval = *((UA_Duration *) data->value.data); + UA_Server_updateWriterGroupConfig(server, writerGroup->identifier, &writerGroupConfig); + UA_Variant_setScalar(&value, data->value.data, &UA_TYPES[UA_TYPES_DURATION]); + UA_WriterGroupConfig_deleteMembers(&writerGroupConfig); + break; + default: + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Write error! Unknown property element."); + } + break; + default: + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Read error! Unknown parent element."); + } +} + +static UA_StatusCode +addVariableValueSource(UA_Server *server, UA_ValueCallback valueCallback, + UA_NodeId node, UA_NodePropertyContext *context){ + UA_Server_setNodeContext(server, node, context); + return UA_Server_setVariableNode_valueCallback(server, node, valueCallback); +} + +/*************************************************/ +/* PubSubConnection */ +/*************************************************/ +UA_StatusCode +addPubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connection){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(connection->config->name.length > 512) + return UA_STATUSCODE_BADOUTOFMEMORY; + UA_STACKARRAY(char, connectionName, sizeof(char) * connection->config->name.length +1); + memcpy(connectionName, connection->config->name.data, connection->config->name.length); + connectionName[connection->config->name.length] = '\0'; + //This code block must use a lock + UA_Nodestore_removeNode(server->nsCtx, &connection->identifier); + UA_NodeId pubSubConnectionNodeId; + UA_ObjectAttributes attr = UA_ObjectAttributes_default; + attr.displayName = UA_LOCALIZEDTEXT("de-DE", connectionName); + retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, + UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric), + UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPUBSUBCONNECTION), + UA_QUALIFIEDNAME(0, connectionName), + UA_NODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE), + (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], + NULL, &pubSubConnectionNodeId); + addPubSubObjectNode(server, "Address", connection->identifier.identifier.numeric+1, + pubSubConnectionNodeId.identifier.numeric, UA_NS0ID_HASCOMPONENT, + UA_NS0ID_NETWORKADDRESSURLTYPE); + UA_Server_addNode_finish(server, pubSubConnectionNodeId); + //End lock zone + + UA_NodeId addressNode, urlNode, interfaceNode, publisherIdNode, connectionPropertieNode, transportProfileUri; + addressNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "Address"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric)); + urlNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "Url"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), addressNode); + interfaceNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "NetworkInterface"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), addressNode); + publisherIdNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "PublisherId"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric)); + connectionPropertieNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "ConnectionProperties"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric)); + transportProfileUri = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "TransportProfileUri"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_NODEID_NUMERIC(0, connection->identifier.identifier.numeric)); + + if(UA_NodeId_equal(&addressNode, &UA_NODEID_NULL) || + UA_NodeId_equal(&urlNode, &UA_NODEID_NULL) || + UA_NodeId_equal(&interfaceNode, &UA_NODEID_NULL) || + UA_NodeId_equal(&publisherIdNode, &UA_NODEID_NULL) || + UA_NodeId_equal(&connectionPropertieNode, &UA_NODEID_NULL) || + UA_NodeId_equal(&transportProfileUri, &UA_NODEID_NULL)) { + return UA_STATUSCODE_BADNOTFOUND; + } + + retVal |= writePubSubNs0VariableArray(server, connectionPropertieNode.identifier.numeric, + connection->config->connectionProperties, + connection->config->connectionPropertiesSize, + &UA_TYPES[UA_TYPES_KEYVALUEPAIR]); + + UA_NetworkAddressUrlDataType *networkAddressUrlDataType = ((UA_NetworkAddressUrlDataType *) connection->config->address.data); + UA_Variant value; + UA_Variant_init(&value); + UA_Variant_setScalar(&value, &networkAddressUrlDataType->url, &UA_TYPES[UA_TYPES_STRING]); + UA_Server_writeValue(server, urlNode, value); + UA_Variant_setScalar(&value, &networkAddressUrlDataType->networkInterface, &UA_TYPES[UA_TYPES_STRING]); + UA_Server_writeValue(server, interfaceNode, value); + UA_Variant_setScalar(&value, &connection->config->transportProfileUri, &UA_TYPES[UA_TYPES_STRING]); + UA_Server_writeValue(server, transportProfileUri, value); + + UA_NodePropertyContext *connectionPublisherIdContext = (UA_NodePropertyContext *) UA_malloc(sizeof(UA_NodePropertyContext)); + connectionPublisherIdContext->parentNodeId = connection->identifier; + connectionPublisherIdContext->parentClassifier = UA_NS0ID_PUBSUBCONNECTIONTYPE; + connectionPublisherIdContext->elementClassiefier = UA_NS0ID_PUBSUBCONNECTIONTYPE_PUBLISHERID; + UA_ValueCallback valueCallback; + valueCallback.onRead = onRead; + valueCallback.onWrite = NULL; + retVal |= addVariableValueSource(server, valueCallback, publisherIdNode, connectionPublisherIdContext); + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS + retVal |= UA_Server_addReference(server, connection->identifier, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP), true); + retVal |= UA_Server_addReference(server, connection->identifier, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP), true); + retVal |= UA_Server_addReference(server, connection->identifier, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP), true); +#endif + return retVal; +} + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +addPubSubConnectionAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_PubSubConnectionDataType pubSubConnectionDataType = *((UA_PubSubConnectionDataType *) input[0].data); + UA_NetworkAddressUrlDataType networkAddressUrlDataType; + memset(&networkAddressUrlDataType, 0, sizeof(networkAddressUrlDataType)); + UA_ExtensionObject eo = pubSubConnectionDataType.address; + if(eo.encoding == UA_EXTENSIONOBJECT_DECODED){ + if(eo.content.decoded.type == &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]){ + if(UA_NetworkAddressUrlDataType_copy((UA_NetworkAddressUrlDataType *) eo.content.decoded.data, + &networkAddressUrlDataType) != UA_STATUSCODE_GOOD){ + return UA_STATUSCODE_BADOUTOFMEMORY; + } } + } + UA_PubSubConnectionConfig connectionConfig; + memset(&connectionConfig, 0, sizeof(UA_PubSubConnectionConfig)); + connectionConfig.transportProfileUri = pubSubConnectionDataType.transportProfileUri; + connectionConfig.name = pubSubConnectionDataType.name; + //TODO set real connection state + connectionConfig.enabled = pubSubConnectionDataType.enabled; + //connectionConfig.enabled = pubSubConnectionDataType.enabled; + UA_Variant_setScalar(&connectionConfig.address, &networkAddressUrlDataType, + &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]); + if(pubSubConnectionDataType.publisherId.type == &UA_TYPES[UA_TYPES_UINT32]){ + connectionConfig.publisherId.numeric = * ((UA_UInt32 *) pubSubConnectionDataType.publisherId.data); + } else if(pubSubConnectionDataType.publisherId.type == &UA_TYPES[UA_TYPES_STRING]){ + connectionConfig.publisherIdType = UA_PUBSUB_PUBLISHERID_STRING; + UA_String_copy((UA_String *) pubSubConnectionDataType.publisherId.data, &connectionConfig.publisherId.string); } else { - newNotification->data.value = *value; /* Just copy the value and do not release it */ + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "Unsupported PublisherId Type used."); + //TODO what's the best default behaviour here? + connectionConfig.publisherId.numeric = 0; } + //call API function and create the connection + UA_NodeId connectionId; - /* <-- Point of no return --> */ + retVal |= UA_Server_addPubSubConnection(server, &connectionConfig, &connectionId); - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, - "Subscription %u | MonitoredItem %u | Sampled a new value", - sub->subscriptionId, monitoredItem->monitoredItemId); + if(retVal != UA_STATUSCODE_GOOD){ + return retVal; + } + for(size_t i = 0; i < pubSubConnectionDataType.writerGroupsSize; i++){ + //UA_PubSubConnection_addWriterGroup(server, UA_NODEID_NULL, NULL, NULL); + } + for(size_t i = 0; i < pubSubConnectionDataType.readerGroupsSize; i++){ + //UA_Server_addReaderGroup(server, NULL, NULL, NULL); + } + UA_NetworkAddressUrlDataType_deleteMembers(&networkAddressUrlDataType); + //set ouput value + UA_Variant_setScalarCopy(output, &connectionId, &UA_TYPES[UA_TYPES_NODEID]); + return UA_STATUSCODE_GOOD; +} +#endif - newNotification->mon = monitoredItem; +UA_StatusCode +removePubSubConnectionRepresentation(UA_Server *server, UA_PubSubConnection *connection){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS + retVal |= UA_Server_deleteReference(server, connection->identifier, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP), + false); + retVal |= UA_Server_deleteReference(server, connection->identifier, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP), + false); + retVal |= UA_Server_deleteReference(server, connection->identifier, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP), + false); +#endif + retVal |= UA_Server_deleteNode(server, connection->identifier, true); + return retVal; +} - /* Replace the encoding for comparison */ - UA_Variant_deleteMembers(&monitoredItem->lastValue); - UA_Variant_copy(&value->value, &monitoredItem->lastValue); - UA_ByteString_deleteMembers(&monitoredItem->lastSampledValue); - monitoredItem->lastSampledValue = *valueEncoding; +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +removeConnectionAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data); + retVal |= UA_Server_removePubSubConnection(server, nodeToRemove); + if(retVal == UA_STATUSCODE_BADNOTFOUND) + retVal = UA_STATUSCODE_BADNODEIDUNKNOWN; + return retVal; +} +#endif - /* Add the notification to the end of local and global queue */ - TAILQ_INSERT_TAIL(&monitoredItem->queue, newNotification, listEntry); - TAILQ_INSERT_TAIL(&sub->notificationQueue, newNotification, globalEntry); - ++monitoredItem->queueSize; - ++sub->notificationQueueSize; +/**********************************************/ +/* DataSetReader */ +/**********************************************/ +UA_StatusCode +addDataSetReaderRepresentation(UA_Server *server, UA_DataSetReader *dataSetReader){ + //TODO implement reader part + return UA_STATUSCODE_BADNOTIMPLEMENTED; +} - /* Remove some notifications if the queue is beyond maximum capacity */ - MonitoredItem_ensureQueueSpace(monitoredItem); +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +addDataSetReaderAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_BADNOTIMPLEMENTED; + //TODO implement reader part + return retVal; +} +#endif - return true; +UA_StatusCode +removeDataSetReaderRepresentation(UA_Server *server, UA_DataSetReader* dataSetReader){ + //TODO implement reader part + return UA_STATUSCODE_BADNOTIMPLEMENTED; } -void -UA_MonitoredItem_SampleCallback(UA_Server *server, - UA_MonitoredItem *monitoredItem) { - UA_Subscription *sub = monitoredItem->subscription; - if(monitoredItem->monitoredItemType != UA_MONITOREDITEMTYPE_CHANGENOTIFY) { - UA_LOG_DEBUG_SESSION(server->config.logger, sub->session, - "Subscription %u | MonitoredItem %i | " - "Not a data change notification", - sub->subscriptionId, monitoredItem->monitoredItemId); - return; +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +removeDataSetReaderAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_BADNOTIMPLEMENTED; + //TODO implement reader part + return retVal; +} +#endif + +/*************************************************/ +/* PublishedDataSet */ +/*************************************************/ +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +addDataSetFolderAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + /* defined in R 1.04 9.1.4.5.7 */ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_String newFolderName = *((UA_String *) input[0].data); + UA_NodeId generatedId; + UA_ObjectAttributes objectAttributes = UA_ObjectAttributes_default; + UA_LocalizedText name = {UA_STRING("en-US"), newFolderName}; + objectAttributes.displayName = name; + retVal |= UA_Server_addObjectNode(server, UA_NODEID_NULL, *objectId, UA_NODEID_NUMERIC(0,UA_NS0ID_ORGANIZES), + UA_QUALIFIEDNAME(0, "DataSetFolder"), UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE), + objectAttributes, NULL, &generatedId); + UA_Variant_setScalarCopy(output, &generatedId, &UA_TYPES[UA_TYPES_NODEID]); +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS + retVal |= UA_Server_addReference(server, generatedId, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS), true); + retVal |= UA_Server_addReference(server, generatedId, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET), true); + retVal |= UA_Server_addReference(server, generatedId, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER), true); + retVal |= UA_Server_addReference(server, generatedId, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER), true); +#endif + return retVal; +} +#endif + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +removeDataSetFolderAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data); +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS + retVal |= UA_Server_deleteReference(server, nodeToRemove, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS), + false); + retVal |= UA_Server_deleteReference(server, nodeToRemove, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET), + false); + retVal |= UA_Server_deleteReference(server, nodeToRemove, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER), + false); + retVal |= UA_Server_deleteReference(server, nodeToRemove, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER), + false); +#endif + retVal |= UA_Server_deleteNode(server, nodeToRemove, false); + return retVal; +} +#endif + +UA_StatusCode +addPublishedDataItemsRepresentation(UA_Server *server, UA_PublishedDataSet *publishedDataSet) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(publishedDataSet->config.name.length > 512) + return UA_STATUSCODE_BADOUTOFMEMORY; + UA_STACKARRAY(char, pdsName, sizeof(char) * publishedDataSet->config.name.length +1); + memcpy(pdsName, publishedDataSet->config.name.data, publishedDataSet->config.name.length); + pdsName[publishedDataSet->config.name.length] = '\0'; + //This code block must use a lock + UA_Nodestore_removeNode(server->nsCtx, &publishedDataSet->identifier); + retVal |= addPubSubObjectNode(server, pdsName, publishedDataSet->identifier.identifier.numeric, + UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS, + UA_NS0ID_HASPROPERTY, UA_NS0ID_PUBLISHEDDATAITEMSTYPE); + //End lock zone + + UA_ValueCallback valueCallback; + valueCallback.onRead = onRead; + valueCallback.onWrite = NULL; + + UA_NodeId configurationVersionNode = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "ConfigurationVersion"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, publishedDataSet->identifier.identifier.numeric)); + if(UA_NodeId_equal(&configurationVersionNode, &UA_NODEID_NULL)) + return UA_STATUSCODE_BADNOTFOUND; + + UA_NodePropertyContext * configurationVersionContext = (UA_NodePropertyContext *) + UA_malloc(sizeof(UA_NodePropertyContext)); + configurationVersionContext->parentNodeId = publishedDataSet->identifier; + configurationVersionContext->parentClassifier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE; + configurationVersionContext->elementClassiefier = + UA_NS0ID_PUBLISHEDDATAITEMSTYPE_CONFIGURATIONVERSION; + retVal |= addVariableValueSource(server, valueCallback, configurationVersionNode, + configurationVersionContext); + + UA_NodeId publishedDataNode = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "PublishedData"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, publishedDataSet->identifier.identifier.numeric)); + if(UA_NodeId_equal(&publishedDataNode, &UA_NODEID_NULL)) + return UA_STATUSCODE_BADNOTFOUND; + + UA_NodePropertyContext * publishingIntervalContext = (UA_NodePropertyContext *) + UA_malloc(sizeof(UA_NodePropertyContext)); + publishingIntervalContext->parentNodeId = publishedDataSet->identifier; + publishingIntervalContext->parentClassifier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE; + publishingIntervalContext->elementClassiefier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE_PUBLISHEDDATA; + retVal |= addVariableValueSource(server, valueCallback, publishedDataNode, + publishingIntervalContext); + + UA_NodeId dataSetMetaDataNode = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "DataSetMetaData"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, publishedDataSet->identifier.identifier.numeric)); + if(UA_NodeId_equal(&dataSetMetaDataNode, &UA_NODEID_NULL)) + return UA_STATUSCODE_BADNOTFOUND; + + UA_NodePropertyContext *metaDataContext = (UA_NodePropertyContext *) + UA_malloc(sizeof(UA_NodePropertyContext)); + metaDataContext->parentNodeId = publishedDataSet->identifier; + metaDataContext->parentClassifier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE; + metaDataContext->elementClassiefier = UA_NS0ID_PUBLISHEDDATAITEMSTYPE_DATASETMETADATA; + retVal |= addVariableValueSource(server, valueCallback, dataSetMetaDataNode, metaDataContext); + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS + retVal |= UA_Server_addReference(server, publishedDataSet->identifier, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE_ADDVARIABLES), true); + retVal |= UA_Server_addReference(server, publishedDataSet->identifier, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE_REMOVEVARIABLES), true); +#endif + return retVal; +} + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +addPublishedDataItemsAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + size_t fieldNameAliasesSize = input[1].arrayLength; + UA_String * fieldNameAliases = (UA_String *) input[1].data; + size_t fieldFlagsSize = input[2].arrayLength; + UA_DataSetFieldFlags * fieldFlags = (UA_DataSetFieldFlags *) input[2].data; + size_t variablesToAddSize = input[3].arrayLength; + UA_PublishedVariableDataType *variablesToAddField = (UA_PublishedVariableDataType *) input[3].data; + + if(!(fieldNameAliasesSize == fieldFlagsSize || fieldFlagsSize == variablesToAddSize)) + return UA_STATUSCODE_BADINVALIDARGUMENT; + + UA_PublishedDataSetConfig publishedDataSetConfig; + memset(&publishedDataSetConfig, 0, sizeof(publishedDataSetConfig)); + publishedDataSetConfig.name = *((UA_String *) input[0].data); + publishedDataSetConfig.publishedDataSetType = UA_PUBSUB_DATASET_PUBLISHEDITEMS; + + UA_NodeId dataSetItemsNodeId; + retVal |= UA_Server_addPublishedDataSet(server, &publishedDataSetConfig, &dataSetItemsNodeId).addResult; + + UA_DataSetFieldConfig dataSetFieldConfig; + for(size_t j = 0; j < variablesToAddSize; ++j) { + memset(&dataSetFieldConfig, 0, sizeof(dataSetFieldConfig)); + dataSetFieldConfig.dataSetFieldType = UA_PUBSUB_DATASETFIELD_VARIABLE; + dataSetFieldConfig.field.variable.fieldNameAlias = fieldNameAliases[j]; + if(fieldFlags[j] == UA_DATASETFIELDFLAGS_PROMOTEDFIELD){ + dataSetFieldConfig.field.variable.promotedField = UA_TRUE; + } + dataSetFieldConfig.field.variable.publishParameters = variablesToAddField[j]; + UA_Server_addDataSetField(server, dataSetItemsNodeId, &dataSetFieldConfig, NULL); } + UA_PublishedVariableDataType_clear(variablesToAddField); + return retVal; +} +#endif - /* Read the value */ - UA_ReadValueId rvid; - UA_ReadValueId_init(&rvid); - rvid.nodeId = monitoredItem->monitoredNodeId; - rvid.attributeId = monitoredItem->attributeId; - rvid.indexRange = monitoredItem->indexRange; - UA_DataValue value = - UA_Server_readWithSession(server, sub->session, - &rvid, monitoredItem->timestampsToReturn); +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +addVariablesAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; - /* Stack-allocate some memory for the value encoding. We might heap-allocate - * more memory if needed. This is just enough for scalars and small - * structures. */ - UA_STACKARRAY(UA_Byte, stackValueEncoding, UA_VALUENCODING_MAXSTACK); - UA_ByteString valueEncoding; - valueEncoding.data = stackValueEncoding; - valueEncoding.length = UA_VALUENCODING_MAXSTACK; + return retVal; +} - /* Create a sample and compare with the last value */ - UA_Boolean newNotification = sampleCallbackWithValue(server, sub, monitoredItem, - &value, &valueEncoding); +static UA_StatusCode +removeVariablesAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; - /* Clean up */ - if(!newNotification) { - if(valueEncoding.data != stackValueEncoding) - UA_ByteString_deleteMembers(&valueEncoding); - UA_DataValue_deleteMembers(&value); + return retVal; +} +#endif + + +UA_StatusCode +removePublishedDataSetRepresentation(UA_Server *server, UA_PublishedDataSet *publishedDataSet){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + retVal |= UA_Server_deleteNode(server, publishedDataSet->identifier, false); + + return retVal; +} + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +removePublishedDataSetAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data); + retVal |= UA_Server_removePublishedDataSet(server, nodeToRemove); + return retVal; +} +#endif + +/**********************************************/ +/* WriterGroup */ +/**********************************************/ + +static UA_StatusCode +readContentMask(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *nodeId, + void *nodeContext, UA_Boolean includeSourceTimeStamp, + const UA_NumericRange *range, UA_DataValue *value) { + UA_WriterGroup *writerGroup = (UA_WriterGroup*)nodeContext; + if((writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED && + writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) || + writerGroup->config.messageSettings.content.decoded.type != + &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]) + return UA_STATUSCODE_BADINTERNALERROR; + UA_UadpWriterGroupMessageDataType *wgm = (UA_UadpWriterGroupMessageDataType*) + writerGroup->config.messageSettings.content.decoded.data; + + UA_Variant_setScalarCopy(&value->value, &wgm->networkMessageContentMask, + &UA_TYPES[UA_TYPES_UADPNETWORKMESSAGECONTENTMASK]); + value->hasValue = true; + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +writeContentMask(UA_Server *server, const UA_NodeId *sessionId, + void *sessionContext, const UA_NodeId *nodeId, + void *nodeContext, const UA_NumericRange *range, + const UA_DataValue *value) { + UA_WriterGroup *writerGroup = (UA_WriterGroup*)nodeContext; + if((writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED && + writerGroup->config.messageSettings.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) || + writerGroup->config.messageSettings.content.decoded.type != + &UA_TYPES[UA_TYPES_UADPWRITERGROUPMESSAGEDATATYPE]) + return UA_STATUSCODE_BADINTERNALERROR; + UA_UadpWriterGroupMessageDataType *wgm = (UA_UadpWriterGroupMessageDataType*) + writerGroup->config.messageSettings.content.decoded.data; + + if(!value->value.type) + return UA_STATUSCODE_BADTYPEMISMATCH; + if(value->value.type->typeKind != UA_DATATYPEKIND_ENUM && + value->value.type->typeKind != UA_DATATYPEKIND_INT32) + return UA_STATUSCODE_BADTYPEMISMATCH; + + wgm->networkMessageContentMask = *(UA_UadpNetworkMessageContentMask*)value->value.data; + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +addWriterGroupRepresentation(UA_Server *server, UA_WriterGroup *writerGroup){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(writerGroup->config.name.length > 512) + return UA_STATUSCODE_BADOUTOFMEMORY; + UA_STACKARRAY(char, wgName, sizeof(char) * writerGroup->config.name.length + 1); + memcpy(wgName, writerGroup->config.name.data, writerGroup->config.name.length); + wgName[writerGroup->config.name.length] = '\0'; + //This code block must use a lock + UA_Nodestore_removeNode(server->nsCtx, &writerGroup->identifier); + retVal |= addPubSubObjectNode(server, wgName, writerGroup->identifier.identifier.numeric, + writerGroup->linkedConnection.identifier.numeric, + UA_NS0ID_HASCOMPONENT, UA_NS0ID_WRITERGROUPTYPE); + //End lock zone + UA_NodeId keepAliveNode = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "KeepAliveTime"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, writerGroup->identifier.identifier.numeric)); + UA_NodeId publishingIntervalNode = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "PublishingInterval"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, writerGroup->identifier.identifier.numeric)); + if(UA_NodeId_equal(&keepAliveNode, &UA_NODEID_NULL) || + UA_NodeId_equal(&publishingIntervalNode, &UA_NODEID_NULL)) + return UA_STATUSCODE_BADNOTFOUND; + + UA_NodePropertyContext * publishingIntervalContext = (UA_NodePropertyContext *) + UA_malloc(sizeof(UA_NodePropertyContext)); + publishingIntervalContext->parentNodeId = writerGroup->identifier; + publishingIntervalContext->parentClassifier = UA_NS0ID_WRITERGROUPTYPE; + publishingIntervalContext->elementClassiefier = UA_NS0ID_WRITERGROUPTYPE_PUBLISHINGINTERVAL; + UA_ValueCallback valueCallback; + valueCallback.onRead = onRead; + valueCallback.onWrite = onWrite; + retVal |= addVariableValueSource(server, valueCallback, + publishingIntervalNode, publishingIntervalContext); + UA_Server_writeAccessLevel(server, publishingIntervalNode, + UA_ACCESSLEVELMASK_READ ^ UA_ACCESSLEVELMASK_WRITE); + + UA_NodeId priorityNode = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "Priority"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, writerGroup->identifier.identifier.numeric)); + UA_NodeId writerGroupIdNode = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "WriterGroupId"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + UA_NODEID_NUMERIC(0, writerGroup->identifier.identifier.numeric)); + UA_Variant value; + UA_Variant_init(&value); + UA_Variant_setScalar(&value, &writerGroup->config.publishingInterval, &UA_TYPES[UA_TYPES_DURATION]); + UA_Server_writeValue(server, publishingIntervalNode, value); + UA_Variant_setScalar(&value, &writerGroup->config.keepAliveTime, &UA_TYPES[UA_TYPES_DURATION]); + UA_Server_writeValue(server, keepAliveNode, value); + UA_Variant_setScalar(&value, &writerGroup->config.priority, &UA_TYPES[UA_TYPES_BYTE]); + UA_Server_writeValue(server, priorityNode, value); + UA_Variant_setScalar(&value, &writerGroup->config.writerGroupId, &UA_TYPES[UA_TYPES_UINT16]); + UA_Server_writeValue(server, writerGroupIdNode, value); + + retVal |= addPubSubObjectNode(server, "MessageSettings", 0, + writerGroup->identifier.identifier.numeric, + UA_NS0ID_HASCOMPONENT, UA_NS0ID_UADPWRITERGROUPMESSAGETYPE); + + /* Find the variable with the content mask */ + + UA_NodeId messageSettingsId = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "MessageSettings"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_NODEID_NUMERIC(0, writerGroup->identifier.identifier.numeric)); + UA_NodeId contentMaskId = + findSingleChildNode(server, UA_QUALIFIEDNAME(0, "NetworkMessageContentMask"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), messageSettingsId); + if(UA_NodeId_equal(&messageSettingsId, &UA_NODEID_NULL) || + UA_NodeId_equal(&contentMaskId, &UA_NODEID_NULL)) { + return UA_STATUSCODE_BADNOTFOUND; + } + + /* Set the callback */ + UA_DataSource ds; + ds.read = readContentMask; + ds.write = writeContentMask; + UA_Server_setVariableNode_dataSource(server, contentMaskId, ds); + UA_Server_setNodeContext(server, contentMaskId, writerGroup); + + /* Make writable */ + UA_Server_writeAccessLevel(server, contentMaskId, + UA_ACCESSLEVELMASK_WRITE | UA_ACCESSLEVELMASK_READ); + + return retVal; +} + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +addWriterGroupAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_WriterGroupDataType *writerGroupDataType = ((UA_WriterGroupDataType *) input[0].data); + UA_NodeId generatedId; + UA_WriterGroupConfig writerGroupConfig; + memset(&writerGroupConfig, 0, sizeof(UA_WriterGroupConfig)); + writerGroupConfig.name = writerGroupDataType->name; + writerGroupConfig.publishingInterval = writerGroupDataType->publishingInterval; + writerGroupConfig.writerGroupId = writerGroupDataType->writerGroupId; + writerGroupConfig.enabled = writerGroupDataType->enabled; + writerGroupConfig.priority = writerGroupDataType->priority; + //TODO remove hard coded UADP + writerGroupConfig.encodingMimeType = UA_PUBSUB_ENCODING_UADP; + //ToDo transfer all arguments to internal WGConfiguration + retVal |= UA_Server_addWriterGroup(server, *objectId, &writerGroupConfig, &generatedId); + UA_Variant_setScalarCopy(output, &generatedId, &UA_TYPES[UA_TYPES_NODEID]); + return retVal; +} +#endif + +UA_StatusCode +removeGroupRepresentation(UA_Server *server, UA_WriterGroup *writerGroup) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + retVal |= UA_Server_deleteNode(server, writerGroup->identifier, false); + return retVal; +} + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +removeGroupAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data); + if(UA_WriterGroup_findWGbyId(server, nodeToRemove) != NULL) + retVal |= UA_Server_removeWriterGroup(server, nodeToRemove); + //else + //retVal |= UA_Server_removeReaderGroup(server, nodeToRemve); + return retVal; +} +#endif + +/**********************************************/ +/* ReaderGroup */ +/**********************************************/ +UA_StatusCode +addReaderGroupRepresentation(UA_Server *server, UA_ReaderGroup *readerGroup){ + //TODO implement reader part + return UA_STATUSCODE_BADNOTIMPLEMENTED; +} + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +addReaderGroupAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + //TODO implement reader part + return retVal; +} +#endif + +/**********************************************/ +/* DataSetWriter */ +/**********************************************/ +UA_StatusCode +addDataSetWriterRepresentation(UA_Server *server, UA_DataSetWriter *dataSetWriter){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + if(dataSetWriter->config.name.length > 512) + return UA_STATUSCODE_BADOUTOFMEMORY; + UA_STACKARRAY(char, dswName, sizeof(char) * dataSetWriter->config.name.length + 1); + memcpy(dswName, dataSetWriter->config.name.data, dataSetWriter->config.name.length); + dswName[dataSetWriter->config.name.length] = '\0'; + //This code block must use a lock + UA_Nodestore_removeNode(server->nsCtx, &dataSetWriter->identifier); + retVal |= addPubSubObjectNode(server, dswName, dataSetWriter->identifier.identifier.numeric, + dataSetWriter->linkedWriterGroup.identifier.numeric, + UA_NS0ID_HASDATASETWRITER, UA_NS0ID_DATASETWRITERTYPE); + //End lock zone + retVal |= UA_Server_addReference(server, dataSetWriter->connectedDataSet, + UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETTOWRITER), + UA_EXPANDEDNODEID_NUMERIC(0, dataSetWriter->identifier.identifier.numeric), true); + + + retVal |= addPubSubObjectNode(server, "MessageSettings", 0, + dataSetWriter->identifier.identifier.numeric, + UA_NS0ID_HASCOMPONENT, UA_NS0ID_UADPDATASETWRITERMESSAGETYPE); + return retVal; +} + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +addDataSetWriterAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_DataSetWriterDataType *dataSetWriterDataType = (UA_DataSetWriterDataType *) input[0].data; + + UA_NodeId targetPDS = UA_NODEID_NULL; + for(size_t i = 0; i < server->pubSubManager.publishedDataSetsSize; ++i) { + if(UA_String_equal(&dataSetWriterDataType->dataSetName, + &server->pubSubManager.publishedDataSets[i].config.name)){ + targetPDS = server->pubSubManager.publishedDataSets[i].identifier; + } } + if(UA_NodeId_isNull(&targetPDS)) + return UA_STATUSCODE_BADPARENTNODEIDINVALID; + + UA_NodeId generatedId; + UA_DataSetWriterConfig dataSetWriterConfig; + memset(&dataSetWriterConfig, 0, sizeof(UA_DataSetWriterConfig)); + dataSetWriterConfig.name = dataSetWriterDataType->name; + dataSetWriterConfig.dataSetName = dataSetWriterDataType->dataSetName; + dataSetWriterConfig.keyFrameCount = dataSetWriterDataType->keyFrameCount; + dataSetWriterConfig.dataSetWriterId = dataSetWriterDataType->dataSetWriterId; + + UA_Server_addDataSetWriter(server, *objectId, targetPDS, &dataSetWriterConfig, &generatedId); + UA_Variant_setScalarCopy(output, &generatedId, &UA_TYPES[UA_TYPES_NODEID]); + return UA_STATUSCODE_GOOD; } +#endif + UA_StatusCode -MonitoredItem_registerSampleCallback(UA_Server *server, UA_MonitoredItem *mon) { - if(mon->sampleCallbackIsRegistered) - return UA_STATUSCODE_GOOD; - UA_StatusCode retval = - UA_Server_addRepeatedCallback(server, (UA_ServerCallback)UA_MonitoredItem_SampleCallback, - mon, (UA_UInt32)mon->samplingInterval, &mon->sampleCallbackId); - if(retval == UA_STATUSCODE_GOOD) - mon->sampleCallbackIsRegistered = true; - return retval; +removeDataSetWriterRepresentation(UA_Server *server, UA_DataSetWriter *dataSetWriter) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + retVal |= UA_Server_deleteNode(server, dataSetWriter->identifier, false); + return retVal; +} + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS +static UA_StatusCode +removeDataSetWriterAction(UA_Server *server, + const UA_NodeId *sessionId, void *sessionHandle, + const UA_NodeId *methodId, void *methodContext, + const UA_NodeId *objectId, void *objectContext, + size_t inputSize, const UA_Variant *input, + size_t outputSize, UA_Variant *output){ + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_NodeId nodeToRemove = *((UA_NodeId *) input[0].data); + retVal |= UA_Server_removeDataSetWriter(server, nodeToRemove); + return retVal; +} +#endif + +/**********************************************/ +/* Destructors */ +/**********************************************/ + +static void +connectionTypeDestructor(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *typeId, void *typeContext, + const UA_NodeId *nodeId, void **nodeContext) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_USERLAND, "Connection destructor called!"); + UA_NodeId publisherIdNode; + publisherIdNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "PublisherId"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), *nodeId); + UA_NodePropertyContext *internalConnectionContext; + UA_Server_getNodeContext(server, publisherIdNode, (void **) &internalConnectionContext); + if(!UA_NodeId_equal(&UA_NODEID_NULL , &publisherIdNode)){ + UA_free(internalConnectionContext); + } + +} + +static void +writerGroupTypeDestructor(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *typeId, void *typeContext, + const UA_NodeId *nodeId, void **nodeContext) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_USERLAND, "WriterGroup destructor called!"); + UA_NodeId intervalNode; + intervalNode = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "PublishingInterval"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), *nodeId); + UA_NodePropertyContext *internalConnectionContext; + UA_Server_getNodeContext(server, intervalNode, (void **) &internalConnectionContext); + if(!UA_NodeId_equal(&UA_NODEID_NULL , &intervalNode)){ + UA_free(internalConnectionContext); + } +} + +static void +readerGroupTypeDestructor(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *typeId, void *typeContext, + const UA_NodeId *nodeId, void **nodeContext) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_USERLAND, "ReaderGroup destructor called!"); +} + +static void +dataSetWriterTypeDestructor(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *typeId, void *typeContext, + const UA_NodeId *nodeId, void **nodeContext) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_USERLAND, "DataSetWriter destructor called!"); +} + +static void +dataSetReaderTypeDestructor(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *typeId, void *typeContext, + const UA_NodeId *nodeId, void **nodeContext) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_USERLAND, "DataSetReader destructor called!"); +} + +static void +publishedDataItemsTypeDestructor(UA_Server *server, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *typeId, void *typeContext, + const UA_NodeId *nodeId, void **nodeContext) { + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_USERLAND, + "PublishedDataItems destructor called!"); + void *childContext; + UA_NodeId node = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "PublishedData"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), *nodeId); + UA_Server_getNodeContext(server, node, (void**)&childContext); + if(!UA_NodeId_equal(&UA_NODEID_NULL , &node)) + UA_free(childContext); + + node = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "ConfigurationVersion"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), + *nodeId); + UA_Server_getNodeContext(server, node, (void**)&childContext); + if(!UA_NodeId_equal(&UA_NODEID_NULL , &node)) + UA_free(childContext); + + node = findSingleChildNode(server, UA_QUALIFIEDNAME(0, "DataSetMetaData"), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY), *nodeId); + UA_Server_getNodeContext(server, node, (void**)&childContext); + if(!UA_NodeId_equal(&node, &UA_NODEID_NULL)) + UA_free(childContext); } UA_StatusCode -MonitoredItem_unregisterSampleCallback(UA_Server *server, UA_MonitoredItem *mon) { - if(!mon->sampleCallbackIsRegistered) - return UA_STATUSCODE_GOOD; - mon->sampleCallbackIsRegistered = false; - return UA_Server_removeRepeatedCallback(server, mon->sampleCallbackId); +UA_Server_initPubSubNS0(UA_Server *server) { + UA_StatusCode retVal = UA_STATUSCODE_GOOD; + UA_String profileArray[1]; + profileArray[0] = UA_STRING("http://opcfoundation.org/UA-Profile/Transport/pubsub-udp-uadp"); + + retVal |= writePubSubNs0VariableArray(server, UA_NS0ID_PUBLISHSUBSCRIBE_SUPPORTEDTRANSPORTPROFILES, + profileArray, + 1, &UA_TYPES[UA_TYPES_STRING]); + +#ifdef UA_ENABLE_PUBSUB_INFORMATIONMODEL_METHODS + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION), addPubSubConnectionAction); + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_REMOVECONNECTION), removeConnectionAction); + retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER), true); + retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS), true); + retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET), true); + retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_PUBLISHEDDATASETS), + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER), true); + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDDATASETFOLDER), addDataSetFolderAction); + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEDATASETFOLDER), removeDataSetFolderAction); + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_ADDPUBLISHEDDATAITEMS), addPublishedDataItemsAction); + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETFOLDERTYPE_REMOVEPUBLISHEDDATASET), removePublishedDataSetAction); + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE_ADDVARIABLES), addVariablesAction); + retVal |= UA_Server_setMethodNode_callback(server, + UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE_REMOVEVARIABLES), removeVariablesAction); + retVal |= UA_Server_setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDWRITERGROUP), addWriterGroupAction); + retVal |= UA_Server_setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_ADDREADERGROUP), addReaderGroupAction); + retVal |= UA_Server_setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE_REMOVEGROUP), removeGroupAction); + retVal |= UA_Server_setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_WRITERGROUPTYPE_ADDDATASETWRITER), addDataSetWriterAction); + retVal |= UA_Server_setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_WRITERGROUPTYPE_REMOVEDATASETWRITER), removeDataSetWriterAction); + retVal |= UA_Server_setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_READERGROUPTYPE_ADDDATASETREADER), addDataSetReaderAction); + retVal |= UA_Server_setMethodNode_callback(server, UA_NODEID_NUMERIC(0, UA_NS0ID_READERGROUPTYPE_REMOVEDATASETREADER), removeDataSetReaderAction); + +#else + retVal |= UA_Server_deleteReference(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_ADDCONNECTION), + false); + retVal |= UA_Server_deleteReference(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE), UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), true, + UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PUBLISHSUBSCRIBE_REMOVECONNECTION), + false); +#endif + UA_NodeTypeLifecycle liveCycle; + liveCycle.constructor = NULL; + liveCycle.destructor = connectionTypeDestructor; + UA_Server_setNodeTypeLifecycle(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBSUBCONNECTIONTYPE), liveCycle); + liveCycle.destructor = writerGroupTypeDestructor; + UA_Server_setNodeTypeLifecycle(server, UA_NODEID_NUMERIC(0, UA_NS0ID_WRITERGROUPTYPE), liveCycle); + liveCycle.destructor = readerGroupTypeDestructor; + UA_Server_setNodeTypeLifecycle(server, UA_NODEID_NUMERIC(0, UA_NS0ID_READERGROUPTYPE), liveCycle); + liveCycle.destructor = dataSetWriterTypeDestructor; + UA_Server_setNodeTypeLifecycle(server, UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETWRITERDATATYPE), liveCycle); + liveCycle.destructor = publishedDataItemsTypeDestructor; + UA_Server_setNodeTypeLifecycle(server, UA_NODEID_NUMERIC(0, UA_NS0ID_PUBLISHEDDATAITEMSTYPE), liveCycle); + liveCycle.destructor = dataSetReaderTypeDestructor; + UA_Server_setNodeTypeLifecycle(server, UA_NODEID_NUMERIC(0, UA_NS0ID_DATASETREADERDATATYPE), liveCycle); + + return retVal; } -#endif /* UA_ENABLE_SUBSCRIPTIONS */ +#endif /* UA_ENABLE_PUBSUB_INFORMATIONMODEL */ /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_services_view.c" ***********************************/ @@ -29199,7 +29788,7 @@ MonitoredItem_unregisterSampleCallback(UA_Server *server, UA_MonitoredItem *mon) * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2017 (c) Florian Palm * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015 (c) LEvertz @@ -29214,17 +29803,394 @@ MonitoredItem_unregisterSampleCallback(UA_Server *server, UA_MonitoredItem *mon) */ -/* Target node on top of the stack */ +/********************/ +/* Browse Recursive */ +/********************/ + +/* A RefTree holds a single array for both the NodeIds encountered during + * recursive browsing and the entries for a tree-structure to check for + * duplicates. Once the (recursive) browse has finished, the tree-structure part + * can be simply cut away. A single realloc operation (with some pointer + * repairing) can be used to increase the capacity of the RefTree. + * + * If an ExpandedNodeId is encountered, it has to be processed right away. + * Remote ExpandedNodeId are not put into the tree, since it is not possible to + * recurse into them anyway. + * + * The layout of the results array is as follows: + * + * | Targets [ExpandedNodeId] | Tree [RefEntry] | */ + +#define UA_BROWSE_INITIAL_SIZE 16 + +typedef struct RefEntry { + ZIP_ENTRY(RefEntry) zipfields; + const UA_ExpandedNodeId *target; + UA_UInt32 targetHash; /* Hash of the target nodeid */ +} RefEntry; + +static enum ZIP_CMP +cmpTarget(const void *a, const void *b) { + const RefEntry *aa = (const RefEntry*)a; + const RefEntry *bb = (const RefEntry*)b; + if(aa->targetHash < bb->targetHash) + return ZIP_CMP_LESS; + if(aa->targetHash > bb->targetHash) + return ZIP_CMP_MORE; + return (enum ZIP_CMP)UA_ExpandedNodeId_order(aa->target, bb->target); +} + +ZIP_HEAD(RefHead, RefEntry); +typedef struct RefHead RefHead; +ZIP_PROTTYPE(RefHead, RefEntry, RefEntry) +ZIP_IMPL(RefHead, RefEntry, zipfields, RefEntry, zipfields, cmpTarget) + +typedef struct { + UA_ExpandedNodeId *targets; + RefHead head; + size_t capacity; /* available space */ + size_t size; /* used space */ +} RefTree; + +static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT +RefTree_init(RefTree *rt) { + size_t space = (sizeof(UA_ExpandedNodeId) + sizeof(RefEntry)) * UA_BROWSE_INITIAL_SIZE; + rt->targets = (UA_ExpandedNodeId*)UA_malloc(space); + if(!rt->targets) + return UA_STATUSCODE_BADOUTOFMEMORY; + rt->capacity = UA_BROWSE_INITIAL_SIZE; + rt->size = 0; + ZIP_INIT(&rt->head); + return UA_STATUSCODE_GOOD; +} + +static void +RefTree_clear(RefTree *rt) { + for(size_t i = 0; i < rt->size; i++) + UA_ExpandedNodeId_deleteMembers(&rt->targets[i]); + UA_free(rt->targets); +} + +/* Double the capacity of the reftree */ +static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT +RefTree_double(RefTree *rt) { + size_t capacity = rt->capacity * 2; + UA_assert(capacity > 0); + size_t space = (sizeof(UA_ExpandedNodeId) + sizeof(RefEntry)) * capacity; + UA_ExpandedNodeId *newTargets = (UA_ExpandedNodeId*)UA_realloc(rt->targets, space); + if(!newTargets) + return UA_STATUSCODE_BADOUTOFMEMORY; + + /* Repair the pointers for the realloced array+tree */ + uintptr_t arraydiff = (uintptr_t)newTargets - (uintptr_t)rt->targets; + RefEntry *reArray = (RefEntry*) + ((uintptr_t)newTargets + (capacity * sizeof(UA_ExpandedNodeId))); + uintptr_t entrydiff = (uintptr_t)reArray - + ((uintptr_t)rt->targets + (rt->capacity * sizeof(UA_ExpandedNodeId))); + RefEntry *oldReArray = (RefEntry*) + ((uintptr_t)newTargets + (rt->capacity * sizeof(UA_ExpandedNodeId))); + memmove(reArray, oldReArray, rt->size * sizeof(RefEntry)); + for(size_t i = 0; i < rt->size; i++) { + if(reArray[i].zipfields.zip_left) + *(uintptr_t*)&reArray[i].zipfields.zip_left += entrydiff; + if(reArray[i].zipfields.zip_right) + *(uintptr_t*)&reArray[i].zipfields.zip_right += entrydiff; + *(uintptr_t*)&reArray[i].target += arraydiff; + } + + rt->head.zip_root = (RefEntry*)((uintptr_t)rt->head.zip_root + entrydiff); + rt->capacity = capacity; + rt->targets = newTargets; + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT +RefTree_add(RefTree *rt, const UA_ExpandedNodeId *target) { + UA_StatusCode s = UA_STATUSCODE_GOOD; + if(rt->capacity <= rt->size) { + s = RefTree_double(rt); + if(s != UA_STATUSCODE_GOOD) + return s; + } + s = UA_ExpandedNodeId_copy(target, &rt->targets[rt->size]); + if(s != UA_STATUSCODE_GOOD) + return s; + RefEntry *re = (RefEntry*)((uintptr_t)rt->targets + + (sizeof(UA_ExpandedNodeId) * rt->capacity) + + (sizeof(RefEntry) * rt->size)); + re->target = &rt->targets[rt->size]; + re->targetHash = UA_ExpandedNodeId_hash(target); + ZIP_INSERT(RefHead, &rt->head, re, ZIP_FFS32(UA_UInt32_random())); + rt->size++; + return UA_STATUSCODE_GOOD; +} + +static UA_Boolean +relevantReference(const UA_NodeId *refType, size_t relevantRefsSize, + const UA_NodeId *relevantRefs) { + if(!relevantRefs) + return true; + for(size_t i = 0; i < relevantRefsSize; i++) { + if(UA_NodeId_equal(refType, &relevantRefs[i])) + return true; + } + return false; +} + static UA_StatusCode -fillReferenceDescription(UA_Server *server, const UA_Node *curr, - const UA_NodeReferenceKind *ref, - UA_UInt32 mask, UA_ReferenceDescription *descr) { - UA_ReferenceDescription_init(descr); - UA_StatusCode retval = UA_NodeId_copy(&curr->nodeId, &descr->nodeId.nodeId); +addRelevantReferences(UA_Server *server, RefTree *rt, const UA_NodeId *nodeId, + size_t refTypesSize, const UA_NodeId *refTypes, + UA_BrowseDirection browseDirection) { + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId); + if(!node) + return UA_STATUSCODE_BADNODEIDUNKNOWN; + + UA_StatusCode retval = UA_STATUSCODE_GOOD; + for(size_t i = 0; i < node->referencesSize; i++) { + UA_NodeReferenceKind *rk = &node->references[i]; + + /* Reference in the right direction? */ + if(rk->isInverse && browseDirection == UA_BROWSEDIRECTION_FORWARD) + continue; + if(!rk->isInverse && browseDirection == UA_BROWSEDIRECTION_INVERSE) + continue; + + /* Is the reference part of the hierarchy of references we look for? */ + if(!relevantReference(&rk->referenceTypeId, refTypesSize, refTypes)) + continue; + + for(size_t k = 0; k < rk->targetIdsSize; k++) { + retval = RefTree_add(rt ,&rk->targetIds[k]); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + } + } + + cleanup: + UA_Nodestore_releaseNode(server->nsCtx, node); + return retval; +} + +UA_StatusCode +browseRecursive(UA_Server *server, + size_t startNodesSize, const UA_NodeId *startNodes, + size_t refTypesSize, const UA_NodeId *refTypes, + UA_BrowseDirection browseDirection, UA_Boolean includeStartNodes, + size_t *resultsSize, UA_ExpandedNodeId **results) { + RefTree rt; + UA_StatusCode retval = RefTree_init(&rt); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* Add the start nodes? */ + UA_ExpandedNodeId en = UA_EXPANDEDNODEID_NULL; + for(size_t i = 0; i < startNodesSize && retval == UA_STATUSCODE_GOOD; i++) { + if(includeStartNodes) { + en.nodeId = startNodes[i]; + retval = RefTree_add(&rt, &en); + } else { + retval = addRelevantReferences(server, &rt, &startNodes[i], + refTypesSize, refTypes, browseDirection); + } + } + if(retval != UA_STATUSCODE_GOOD) { + RefTree_clear(&rt); + return retval; + } + + /* Loop over the targets we have so far. This recurses, as new targets are + * added to rt. */ + for(size_t i = 0; i < rt.size; i++) { + /* Dont recurse into remote nodes */ + if(rt.targets[i].serverIndex > 0) + continue; + if(rt.targets[i].namespaceUri.data != NULL) + continue; + + retval = addRelevantReferences(server, &rt, &rt.targets[i].nodeId, + refTypesSize, refTypes, browseDirection); + if(retval != UA_STATUSCODE_GOOD) { + RefTree_clear(&rt); + return retval; + } + } + + if(rt.size > 0) { + *results = rt.targets; + *resultsSize = rt.size; + } else { + RefTree_clear(&rt); + } + + return UA_STATUSCODE_GOOD; +} + +/* Only if IncludeSubtypes is selected */ +UA_StatusCode +referenceSubtypes(UA_Server *server, const UA_NodeId *refType, + size_t *refTypesSize, UA_NodeId **refTypes) { + /* Leave refTypes == NULL */ + if(UA_NodeId_isNull(refType)) + return UA_STATUSCODE_GOOD; + + /* Browse recursive for the hierarchy of sub-references */ + UA_ExpandedNodeId *rt = NULL; + size_t rtSize = 0; + UA_NodeId hasSubtype = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE); + UA_StatusCode retval = browseRecursive(server, 1, refType, 1, &hasSubtype, + UA_BROWSEDIRECTION_FORWARD, true, &rtSize, &rt); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + UA_assert(rtSize > 0); + + /* Allocate space (realloc if non-NULL) */ + UA_NodeId *newRt = NULL; + if(!*refTypes) { + newRt = (UA_NodeId*)UA_malloc(rtSize * UA_TYPES[UA_TYPES_NODEID].memSize); + } else { + newRt = (UA_NodeId*)UA_realloc(*refTypes, (*refTypesSize + rtSize) * + UA_TYPES[UA_TYPES_NODEID].memSize); + } + if(!newRt) { + UA_Array_delete(rt, rtSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + *refTypes = newRt; + + /* Move NodeIds */ + for(size_t i = 0; i < rtSize; i++) { + (*refTypes)[*refTypesSize + i] = rt[i].nodeId; + UA_NodeId_init(&rt[i].nodeId); + } + *refTypesSize += rtSize; + UA_Array_delete(rt, rtSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +UA_Server_browseRecursive(UA_Server *server, const UA_BrowseDescription *bd, + size_t *resultsSize, UA_ExpandedNodeId **results) { + /* Set the list of relevant reference types */ + UA_NodeId *refTypes = NULL; + size_t refTypesSize = 0; + UA_StatusCode retval = UA_STATUSCODE_GOOD; + if(!UA_NodeId_isNull(&bd->referenceTypeId)) { + if(!bd->includeSubtypes) { + refTypes = (UA_NodeId*)(uintptr_t)&bd->referenceTypeId; + refTypesSize = 1; + } else { + retval = referenceSubtypes(server, &bd->referenceTypeId, + &refTypesSize, &refTypes); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } + } + + /* Browse */ + retval = browseRecursive(server, 1, &bd->nodeId, refTypesSize, refTypes, + bd->browseDirection, false, resultsSize, results); + + /* Clean up */ + if(refTypes && bd->includeSubtypes) + UA_Array_delete(refTypes, refTypesSize, &UA_TYPES[UA_TYPES_NODEID]); + return retval; +} + +/**********/ +/* Browse */ +/**********/ + +typedef struct { + size_t size; + size_t capacity; + UA_ReferenceDescription *descr; +} RefResult; + +static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT +RefResult_init(RefResult *rr) { + memset(rr, 0, sizeof(RefResult)); + rr->descr = (UA_ReferenceDescription*) + UA_Array_new(UA_BROWSE_INITIAL_SIZE, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); + if(!rr->descr) + return UA_STATUSCODE_BADOUTOFMEMORY; + rr->capacity = UA_BROWSE_INITIAL_SIZE; + rr->size = 0; + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT +RefResult_double(RefResult *rr) { + size_t newSize = rr->capacity * 2; + UA_ReferenceDescription *rd = (UA_ReferenceDescription*) + UA_realloc(rr->descr, newSize * sizeof(UA_ReferenceDescription)); + if(!rd) + return UA_STATUSCODE_BADOUTOFMEMORY; + memset(&rd[rr->size], 0, sizeof(UA_ReferenceDescription) * (newSize - rr->size)); + rr->descr = rd; + rr->capacity = newSize; + return UA_STATUSCODE_GOOD; +} + +static void +RefResult_clear(RefResult *rr) { + UA_assert(rr->descr != NULL); + for(size_t i = 0; i < rr->size; i++) + UA_ReferenceDescription_clear(&rr->descr[i]); + UA_free(rr->descr); +} + +struct ContinuationPoint { + ContinuationPoint *next; + UA_ByteString identifier; + UA_BrowseDescription browseDescription; + UA_UInt32 maxReferences; + + size_t relevantReferencesSize; + UA_NodeId *relevantReferences; + + /* The last point in the node references? */ + size_t referenceKindIndex; + size_t targetIndex; +}; + +ContinuationPoint * +ContinuationPoint_clear(ContinuationPoint *cp) { + UA_ByteString_deleteMembers(&cp->identifier); + UA_BrowseDescription_deleteMembers(&cp->browseDescription); + UA_Array_delete(cp->relevantReferences, cp->relevantReferencesSize, + &UA_TYPES[UA_TYPES_NODEID]); + return cp->next; +} + +/* Target node on top of the stack */ +static UA_StatusCode UA_FUNC_ATTR_WARN_UNUSED_RESULT +addReferenceDescription(UA_Server *server, RefResult *rr, const UA_NodeReferenceKind *ref, + UA_UInt32 mask, const UA_ExpandedNodeId *nodeId, const UA_Node *curr) { + /* Ensure capacity is left */ + UA_StatusCode retval = UA_STATUSCODE_GOOD; + if(rr->size >= rr->capacity) { + retval = RefResult_double(rr); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } + + UA_ReferenceDescription *descr = &rr->descr[rr->size]; + + /* Fields without access to the actual node */ + retval = UA_ExpandedNodeId_copy(nodeId, &descr->nodeId); if(mask & UA_BROWSERESULTMASK_REFERENCETYPEID) retval |= UA_NodeId_copy(&ref->referenceTypeId, &descr->referenceTypeId); if(mask & UA_BROWSERESULTMASK_ISFORWARD) descr->isForward = !ref->isInverse; + + /* Remote references (ExpandedNodeId) are not further looked up here */ + if(!curr) { + UA_ReferenceDescription_deleteMembers(descr); + return retval; + } + + /* Fields that require the actual node */ if(mask & UA_BROWSERESULTMASK_NODECLASS) retval |= UA_NodeClass_copy(&curr->nodeClass, &descr->nodeClass); if(mask & UA_BROWSERESULTMASK_BROWSENAME) @@ -29237,161 +30203,93 @@ fillReferenceDescription(UA_Server *server, const UA_Node *curr, const UA_Node *type = getNodeType(server, curr); if(type) { retval |= UA_NodeId_copy(&type->nodeId, &descr->typeDefinition.nodeId); - UA_Nodestore_release(server, type); + UA_Nodestore_releaseNode(server->nsCtx, type); } } } - return retval; -} -static void -removeCp(ContinuationPointEntry *cp, UA_Session* session) { - LIST_REMOVE(cp, pointers); - UA_ByteString_deleteMembers(&cp->identifier); - UA_BrowseDescription_deleteMembers(&cp->browseDescription); - UA_free(cp); - ++session->availableContinuationPoints; + if(retval == UA_STATUSCODE_GOOD) + rr->size++; /* Increase the counter */ + else + UA_ReferenceDescription_deleteMembers(descr); + return retval; } static UA_Boolean -relevantReference(UA_Server *server, UA_Boolean includeSubtypes, - const UA_NodeId *rootRef, const UA_NodeId *testRef) { - if(!includeSubtypes) - return UA_NodeId_equal(rootRef, testRef); - - const UA_NodeId hasSubType = UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE); - return isNodeInTree(&server->config.nodestore, testRef, rootRef, &hasSubType, 1); +matchClassMask(const UA_Node *node, UA_UInt32 nodeClassMask) { + if(nodeClassMask != UA_NODECLASS_UNSPECIFIED && + (node->nodeClass & nodeClassMask) == 0) + return false; + return true; } /* Returns whether the node / continuationpoint is done */ -static UA_Boolean +static UA_StatusCode browseReferences(UA_Server *server, const UA_Node *node, - ContinuationPointEntry *cp, UA_BrowseResult *result) { + ContinuationPoint *cp, RefResult *rr, UA_Boolean *done) { UA_assert(cp != NULL); - const UA_BrowseDescription *descr = &cp->browseDescription; - - /* If the node has no references, just return */ - if(node->referencesSize == 0) { - result->referencesSize = 0; - return true; - } - - /* Follow all references? */ - UA_Boolean browseAll = UA_NodeId_isNull(&descr->referenceTypeId); - - /* How many references can we return at most? */ - size_t maxrefs = cp->maxReferences; - if(maxrefs == 0) { - if(server->config.maxReferencesPerNode != 0) { - maxrefs = server->config.maxReferencesPerNode; - } else { - maxrefs = UA_INT32_MAX; - } - } else { - if(server->config.maxReferencesPerNode != 0 && maxrefs > server->config.maxReferencesPerNode) { - maxrefs = server->config.maxReferencesPerNode; - } - } - - /* Allocate the results array */ - size_t refs_size = 2; /* True size of the array */ - result->references = (UA_ReferenceDescription*) - UA_Array_new(refs_size, &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); - if(!result->references) { - result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY; - return false; - } + const UA_BrowseDescription *bd= &cp->browseDescription; size_t referenceKindIndex = cp->referenceKindIndex; size_t targetIndex = cp->targetIndex; /* Loop over the node's references */ + const UA_Node *target = NULL; + UA_StatusCode retval = UA_STATUSCODE_GOOD; for(; referenceKindIndex < node->referencesSize; ++referenceKindIndex) { UA_NodeReferenceKind *rk = &node->references[referenceKindIndex]; /* Reference in the right direction? */ - if(rk->isInverse && descr->browseDirection == UA_BROWSEDIRECTION_FORWARD) + if(rk->isInverse && bd->browseDirection == UA_BROWSEDIRECTION_FORWARD) continue; - if(!rk->isInverse && descr->browseDirection == UA_BROWSEDIRECTION_INVERSE) + if(!rk->isInverse && bd->browseDirection == UA_BROWSEDIRECTION_INVERSE) continue; /* Is the reference part of the hierarchy of references we look for? */ - if(!browseAll && !relevantReference(server, descr->includeSubtypes, - &descr->referenceTypeId, &rk->referenceTypeId)) + if(!relevantReference(&rk->referenceTypeId, cp->relevantReferencesSize, + cp->relevantReferences)) continue; /* Loop over the targets */ for(; targetIndex < rk->targetIdsSize; ++targetIndex) { - /* Get the node */ - const UA_Node *target = UA_Nodestore_get(server, &rk->targetIds[targetIndex].nodeId); - if(!target) - continue; + target = NULL; - /* Test if the node class matches */ - if(descr->nodeClassMask != 0 && (target->nodeClass & descr->nodeClassMask) == 0) { - UA_Nodestore_release(server, target); - continue; + /* Get the node if it is not a remote reference */ + if(rk->targetIds[targetIndex].serverIndex == 0 && + rk->targetIds[targetIndex].namespaceUri.data == NULL) { + target = UA_Nodestore_getNode(server->nsCtx, &rk->targetIds[targetIndex].nodeId); + + /* Test if the node class matches */ + if(target && !matchClassMask(target, bd->nodeClassMask)) { + if(target) + UA_Nodestore_releaseNode(server->nsCtx, target); + continue; + } } - /* A match! Can we return it? */ - if(result->referencesSize >= maxrefs) { - /* There are references we could not return */ + /* A match! Did we reach maxrefs? */ + if(rr->size >= cp->maxReferences) { cp->referenceKindIndex = referenceKindIndex; cp->targetIndex = targetIndex; - UA_Nodestore_release(server, target); - return false; - } - - /* Make enough space in the array */ - if(result->referencesSize >= refs_size) { - refs_size *= 2; - if(refs_size > maxrefs) - refs_size = maxrefs; - UA_ReferenceDescription *rd = (UA_ReferenceDescription*) - UA_realloc(result->references, sizeof(UA_ReferenceDescription) * refs_size); - if(!rd) { - result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY; - UA_Nodestore_release(server, target); - goto error_recovery; - } - result->references = rd; + if(target) + UA_Nodestore_releaseNode(server->nsCtx, target); + return UA_STATUSCODE_GOOD; } /* Copy the node description. Target is on top of the stack */ - result->statusCode = - fillReferenceDescription(server, target, rk, descr->resultMask, - &result->references[result->referencesSize]); - - UA_Nodestore_release(server, target); - - if(result->statusCode != UA_STATUSCODE_GOOD) - goto error_recovery; - - /* Increase the counter */ - result->referencesSize++; + retval = addReferenceDescription(server, rr, rk, bd->resultMask, + &rk->targetIds[targetIndex], target); + UA_Nodestore_releaseNode(server->nsCtx, target); + if(retval != UA_STATUSCODE_GOOD) + return retval; } targetIndex = 0; /* Start at index 0 for the next reference kind */ } - /* No relevant references, return array of length zero */ - if(result->referencesSize == 0) { - UA_free(result->references); - result->references = (UA_ReferenceDescription*)UA_EMPTY_ARRAY_SENTINEL; - } - /* The node is done */ - return true; - - error_recovery: - if(result->referencesSize == 0) - UA_free(result->references); - else - UA_Array_delete(result->references, result->referencesSize, - &UA_TYPES[UA_TYPES_REFERENCEDESCRIPTION]); - result->references = NULL; - result->referencesSize = 0; - return false; + *done = true; + return UA_STATUSCODE_GOOD; } /* Results for a single browsedescription. This is the inner loop for both @@ -29400,7 +30298,7 @@ browseReferences(UA_Server *server, const UA_Node *node, * references. */ static UA_Boolean browseWithContinuation(UA_Server *server, UA_Session *session, - ContinuationPointEntry *cp, UA_BrowseResult *result) { + ContinuationPoint *cp, UA_BrowseResult *result) { const UA_BrowseDescription *descr = &cp->browseDescription; /* Is the browsedirection valid? */ @@ -29413,14 +30311,14 @@ browseWithContinuation(UA_Server *server, UA_Session *session, /* Is the reference type valid? */ if(!UA_NodeId_isNull(&descr->referenceTypeId)) { - const UA_Node *reftype = UA_Nodestore_get(server, &descr->referenceTypeId); + const UA_Node *reftype = UA_Nodestore_getNode(server->nsCtx, &descr->referenceTypeId); if(!reftype) { result->statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID; return true; } UA_Boolean isRef = (reftype->nodeClass == UA_NODECLASS_REFERENCETYPE); - UA_Nodestore_release(server, reftype); + UA_Nodestore_releaseNode(server->nsCtx, reftype); if(!isRef) { result->statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID; @@ -29428,52 +30326,130 @@ browseWithContinuation(UA_Server *server, UA_Session *session, } } - const UA_Node *node = UA_Nodestore_get(server, &descr->nodeId); + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &descr->nodeId); if(!node) { result->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN; return true; } + RefResult rr; + result->statusCode = RefResult_init(&rr); + if(result->statusCode != UA_STATUSCODE_GOOD) { + UA_Nodestore_releaseNode(server->nsCtx, node); + return true; + } + /* Browse the references */ - UA_Boolean done = browseReferences(server, node, cp, result); - UA_Nodestore_release(server, node); + UA_Boolean done = false; + result->statusCode = browseReferences(server, node, cp, &rr, &done); + UA_Nodestore_releaseNode(server->nsCtx, node); + if(result->statusCode != UA_STATUSCODE_GOOD) { + RefResult_clear(&rr); + return true; + } + + /* Move results */ + if(rr.size > 0) { + result->references = rr.descr; + result->referencesSize = rr.size; + } else { + /* No relevant references, return array of length zero */ + RefResult_clear(&rr); + result->references = (UA_ReferenceDescription*)UA_EMPTY_ARRAY_SENTINEL; + } + return done; } /* Start to browse with no previous cp */ void -Operation_Browse(UA_Server *server, UA_Session *session, UA_UInt32 *maxrefs, +Operation_Browse(UA_Server *server, UA_Session *session, const UA_UInt32 *maxrefs, const UA_BrowseDescription *descr, UA_BrowseResult *result) { /* Stack-allocate a temporary cp */ - UA_STACKARRAY(ContinuationPointEntry, cp, 1); - memset(cp, 0, sizeof(ContinuationPointEntry)); + UA_STACKARRAY(ContinuationPoint, cp, 1); + memset(cp, 0, sizeof(ContinuationPoint)); cp->maxReferences = *maxrefs; cp->browseDescription = *descr; /* Shallow copy. Deep-copy later if we persist the cp. */ + /* How many references can we return at most? */ + if(cp->maxReferences == 0) { + if(server->config.maxReferencesPerNode != 0) { + cp->maxReferences = server->config.maxReferencesPerNode; + } else { + cp->maxReferences = UA_INT32_MAX; + } + } else { + if(server->config.maxReferencesPerNode != 0 && + cp->maxReferences > server->config.maxReferencesPerNode) { + cp->maxReferences= server->config.maxReferencesPerNode; + } + } + + /* Get the list of relevant reference types */ + if(!UA_NodeId_isNull(&descr->referenceTypeId)) { + if(!descr->includeSubtypes) { + cp->relevantReferences = (UA_NodeId*)(uintptr_t)&descr->referenceTypeId; + cp->relevantReferencesSize = 1; + } else { + result->statusCode = + referenceSubtypes(server, &descr->referenceTypeId, + &cp->relevantReferencesSize, &cp->relevantReferences); + if(result->statusCode != UA_STATUSCODE_GOOD) + return; + } + } + UA_Boolean done = browseWithContinuation(server, session, cp, result); /* Exit early if done or an error occurred */ - if(done || result->statusCode != UA_STATUSCODE_GOOD) + if(done || result->statusCode != UA_STATUSCODE_GOOD) { + if(descr->includeSubtypes) + UA_Array_delete(cp->relevantReferences, cp->relevantReferencesSize, + &UA_TYPES[UA_TYPES_NODEID]); return; + } /* Persist the new continuation point */ - ContinuationPointEntry *cp2 = NULL; + + ContinuationPoint *cp2 = NULL; + UA_Guid *ident = NULL; UA_StatusCode retval = UA_STATUSCODE_GOOD; - if(session->availableContinuationPoints <= 0 || - !(cp2 = (ContinuationPointEntry *)UA_malloc(sizeof(ContinuationPointEntry)))) { + + /* Enough space for the continuation point? */ + if(session->availableContinuationPoints <= 0) { retval = UA_STATUSCODE_BADNOCONTINUATIONPOINTS; goto cleanup; } - memset(cp2, 0, sizeof(ContinuationPointEntry)); + + /* Allocate and fill the data structure */ + cp2 = (ContinuationPoint*)UA_malloc(sizeof(ContinuationPoint)); + if(!cp2) { + retval = UA_STATUSCODE_BADOUTOFMEMORY; + goto cleanup; + } + memset(cp2, 0, sizeof(ContinuationPoint)); cp2->referenceKindIndex = cp->referenceKindIndex; cp2->targetIndex = cp->targetIndex; cp2->maxReferences = cp->maxReferences; + + if(descr->includeSubtypes) { + cp2->relevantReferences = cp->relevantReferences; + cp2->relevantReferencesSize = cp->relevantReferencesSize; + } else { + retval = UA_Array_copy(cp->relevantReferences, cp->relevantReferencesSize, + (void**)&cp2->relevantReferences, &UA_TYPES[UA_TYPES_NODEID]); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + cp2->relevantReferencesSize = cp->relevantReferencesSize; + } + + /* Copy the description */ retval = UA_BrowseDescription_copy(descr, &cp2->browseDescription); if(retval != UA_STATUSCODE_GOOD) goto cleanup; /* Create a random bytestring via a Guid */ - UA_Guid *ident = UA_Guid_new(); + ident = UA_Guid_new(); if(!ident) { retval = UA_STATUSCODE_BADOUTOFMEMORY; goto cleanup; @@ -29488,14 +30464,14 @@ Operation_Browse(UA_Server *server, UA_Session *session, UA_UInt32 *maxrefs, goto cleanup; /* Attach the cp to the session */ - LIST_INSERT_HEAD(&session->continuationPoints, cp2, pointers); + cp2->next = session->continuationPoints; + session->continuationPoints = cp2; --session->availableContinuationPoints; return; cleanup: if(cp2) { - UA_ByteString_deleteMembers(&cp2->identifier); - UA_BrowseDescription_deleteMembers(&cp2->browseDescription); + ContinuationPoint_clear(cp2); UA_free(cp2); } UA_BrowseResult_deleteMembers(result); @@ -29504,44 +30480,47 @@ Operation_Browse(UA_Server *server, UA_Session *session, UA_UInt32 *maxrefs, void Service_Browse(UA_Server *server, UA_Session *session, const UA_BrowseRequest *request, UA_BrowseResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing BrowseRequest"); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing BrowseRequest"); + /* Test the number of operations in the request */ if(server->config.maxNodesPerBrowse != 0 && request->nodesToBrowseSize > server->config.maxNodesPerBrowse) { response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS; return; } - + /* No views supported at the moment */ if(!UA_NodeId_isNull(&request->view.viewId)) { response->responseHeader.serviceResult = UA_STATUSCODE_BADVIEWIDUNKNOWN; return; } - UA_UInt32 requestedMaxReferencesPerNode = request->requestedMaxReferencesPerNode; response->responseHeader.serviceResult = UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)Operation_Browse, - &requestedMaxReferencesPerNode, + &request->requestedMaxReferencesPerNode, &request->nodesToBrowseSize, &UA_TYPES[UA_TYPES_BROWSEDESCRIPTION], &response->resultsSize, &UA_TYPES[UA_TYPES_BROWSERESULT]); } UA_BrowseResult -UA_Server_browse(UA_Server *server, UA_UInt32 maxrefs, const UA_BrowseDescription *descr) { +UA_Server_browse(UA_Server *server, UA_UInt32 maxReferences, + const UA_BrowseDescription *bd) { UA_BrowseResult result; UA_BrowseResult_init(&result); - Operation_Browse(server, &server->adminSession, &maxrefs, descr, &result); + Operation_Browse(server, &server->adminSession, &maxReferences, bd, &result); return result; } static void -Operation_BrowseNext(UA_Server *server, UA_Session *session, UA_Boolean *releaseContinuationPoints, +Operation_BrowseNext(UA_Server *server, UA_Session *session, + const UA_Boolean *releaseContinuationPoints, const UA_ByteString *continuationPoint, UA_BrowseResult *result) { /* Find the continuation point */ - ContinuationPointEntry *cp; - LIST_FOREACH(cp, &session->continuationPoints, pointers) { + ContinuationPoint **prev = &session->continuationPoints, *cp; + while((cp = *prev)) { if(UA_ByteString_equal(&cp->identifier, continuationPoint)) break; + prev = &cp->next; } if(!cp) { result->statusCode = UA_STATUSCODE_BADCONTINUATIONPOINTINVALID; @@ -29550,7 +30529,9 @@ Operation_BrowseNext(UA_Server *server, UA_Session *session, UA_Boolean *release /* Remove the cp */ if(*releaseContinuationPoints) { - removeCp(cp, session); + *prev = ContinuationPoint_clear(cp); + UA_free(cp); + ++session->availableContinuationPoints; return; } @@ -29559,7 +30540,9 @@ Operation_BrowseNext(UA_Server *server, UA_Session *session, UA_Boolean *release if(done) { /* Remove the cp if there are no references left */ - removeCp(cp, session); + *prev = ContinuationPoint_clear(cp); + UA_free(cp); + ++session->availableContinuationPoints; } else { /* Return the cp identifier */ UA_StatusCode retval = UA_ByteString_copy(&cp->identifier, &result->continuationPoint); @@ -29574,7 +30557,7 @@ void Service_BrowseNext(UA_Server *server, UA_Session *session, const UA_BrowseNextRequest *request, UA_BrowseNextResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing BrowseNextRequest"); UA_Boolean releaseContinuationPoints = request->releaseContinuationPoints; /* request is const */ response->responseHeader.serviceResult = @@ -29646,7 +30629,7 @@ walkBrowsePathElementReferenceTargets(UA_BrowsePathResult *result, size_t *targe } static void -walkBrowsePathElement(UA_Server *server, UA_Session *session, +walkBrowsePathElement(UA_Server *server, UA_Session *session, UA_UInt32 nodeClassMask, UA_BrowsePathResult *result, size_t *targetsSize, const UA_RelativePathElement *elem, UA_UInt32 elemDepth, const UA_QualifiedName *targetName, @@ -29655,11 +30638,11 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, /* Return all references? */ UA_Boolean all_refs = UA_NodeId_isNull(&elem->referenceTypeId); if(!all_refs) { - const UA_Node *rootRef = UA_Nodestore_get(server, &elem->referenceTypeId); + const UA_Node *rootRef = UA_Nodestore_getNode(server->nsCtx, &elem->referenceTypeId); if(!rootRef) return; UA_Boolean match = (rootRef->nodeClass == UA_NODECLASS_REFERENCETYPE); - UA_Nodestore_release(server, rootRef); + UA_Nodestore_releaseNode(server->nsCtx, rootRef); if(!match) return; } @@ -29667,7 +30650,7 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, /* Iterate over all nodes at the current depth-level */ for(size_t i = 0; i < currentCount; ++i) { /* Get the node */ - const UA_Node *node = UA_Nodestore_get(server, ¤t[i]); + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, ¤t[i]); if(!node) { /* If we cannot find the node at depth 0, the starting node does not exist */ if(elemDepth == 0) @@ -29675,11 +30658,17 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, continue; } - /* Test whether the current node has the target name required in the - * previous path element */ + /* Test whether the node fits the class mask */ + if(!matchClassMask(node, nodeClassMask)) { + UA_Nodestore_releaseNode(server->nsCtx, node); + continue; + } + + /* Test whether the node has the target name required in the previous + * path element */ if(targetName && (targetName->namespaceIndex != node->browseName.namespaceIndex || !UA_String_equal(&targetName->name, &node->browseName.name))) { - UA_Nodestore_release(server, node); + UA_Nodestore_releaseNode(server->nsCtx, node); continue; } @@ -29693,39 +30682,46 @@ walkBrowsePathElement(UA_Server *server, UA_Session *session, continue; /* Is the node relevant? */ - if(!all_refs && !relevantReference(server, elem->includeSubtypes, - &elem->referenceTypeId, &rk->referenceTypeId)) - continue; + if(!all_refs) { + if(!elem->includeSubtypes && !UA_NodeId_equal(&rk->referenceTypeId, &elem->referenceTypeId)) + continue; + if(!isNodeInTree(server->nsCtx, &rk->referenceTypeId, &elem->referenceTypeId, &subtypeId, 1)) + continue; + } /* Walk over the reference targets */ walkBrowsePathElementReferenceTargets(result, targetsSize, next, nextSize, nextCount, elemDepth, rk); } - UA_Nodestore_release(server, node); + UA_Nodestore_releaseNode(server->nsCtx, node); } } /* This assumes that result->targets has enough room for all currentCount elements */ static void -addBrowsePathTargets(UA_Server *server, UA_Session *session, +addBrowsePathTargets(UA_Server *server, UA_Session *session, UA_UInt32 nodeClassMask, UA_BrowsePathResult *result, const UA_QualifiedName *targetName, UA_NodeId *current, size_t currentCount) { for(size_t i = 0; i < currentCount; i++) { - const UA_Node *node = UA_Nodestore_get(server, ¤t[i]); + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, ¤t[i]); if(!node) { UA_NodeId_deleteMembers(¤t[i]); continue; } - /* Test whether the current node has the target name required in the + /* Test whether the node fits the class mask */ + UA_Boolean skip = !matchClassMask(node, nodeClassMask); + + /* Test whether the node has the target name required in the * previous path element */ - UA_Boolean valid = targetName->namespaceIndex == node->browseName.namespaceIndex && - UA_String_equal(&targetName->name, &node->browseName.name); + if(targetName->namespaceIndex != node->browseName.namespaceIndex || + !UA_String_equal(&targetName->name, &node->browseName.name)) + skip = true; - UA_Nodestore_release(server, node); + UA_Nodestore_releaseNode(server->nsCtx, node); - if(!valid) { + if(skip) { UA_NodeId_deleteMembers(¤t[i]); continue; } @@ -29740,7 +30736,7 @@ addBrowsePathTargets(UA_Server *server, UA_Session *session, static void walkBrowsePath(UA_Server *server, UA_Session *session, const UA_BrowsePath *path, - UA_BrowsePathResult *result, size_t targetsSize, + UA_UInt32 nodeClassMask, UA_BrowsePathResult *result, size_t targetsSize, UA_NodeId **current, size_t *currentSize, size_t *currentCount, UA_NodeId **next, size_t *nextSize, size_t *nextCount) { UA_assert(*currentCount == 1); @@ -29752,7 +30748,7 @@ walkBrowsePath(UA_Server *server, UA_Session *session, const UA_BrowsePath *path /* Iterate over path elements */ UA_assert(path->relativePath.elementsSize > 0); for(UA_UInt32 i = 0; i < path->relativePath.elementsSize; ++i) { - walkBrowsePathElement(server, session, result, &targetsSize, + walkBrowsePathElement(server, session, nodeClassMask, result, &targetsSize, &path->relativePath.elements[i], i, targetName, *current, *currentCount, next, nextSize, nextCount); @@ -29800,13 +30796,13 @@ walkBrowsePath(UA_Server *server, UA_Session *session, const UA_BrowsePath *path } /* Move the elements of current to the targets */ - addBrowsePathTargets(server, session, result, targetName, *current, *currentCount); + addBrowsePathTargets(server, session, nodeClassMask, result, targetName, *current, *currentCount); *currentCount = 0; } static void Operation_TranslateBrowsePathToNodeIds(UA_Server *server, UA_Session *session, - void *context, const UA_BrowsePath *path, + const UA_UInt32 *nodeClassMask, const UA_BrowsePath *path, UA_BrowsePathResult *result) { if(path->relativePath.elementsSize <= 0) { result->statusCode = UA_STATUSCODE_BADNOTHINGTODO; @@ -29863,7 +30859,7 @@ Operation_TranslateBrowsePathToNodeIds(UA_Server *server, UA_Session *session, currentCount = 1; /* Walk the path elements */ - walkBrowsePath(server, session, path, result, targetsSize, + walkBrowsePath(server, session, path, *nodeClassMask, result, targetsSize, ¤t, ¤tSize, ¤tCount, &next, &nextSize, &nextCount); @@ -29891,7 +30887,9 @@ UA_Server_translateBrowsePathToNodeIds(UA_Server *server, const UA_BrowsePath *browsePath) { UA_BrowsePathResult result; UA_BrowsePathResult_init(&result); - Operation_TranslateBrowsePathToNodeIds(server, &server->adminSession, NULL, browsePath, &result); + UA_UInt32 nodeClassMask = 0; /* All node classes */ + Operation_TranslateBrowsePathToNodeIds(server, &server->adminSession, &nodeClassMask, + browsePath, &result); return result; } @@ -29899,26 +30897,58 @@ void Service_TranslateBrowsePathsToNodeIds(UA_Server *server, UA_Session *session, const UA_TranslateBrowsePathsToNodeIdsRequest *request, UA_TranslateBrowsePathsToNodeIdsResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing TranslateBrowsePathsToNodeIdsRequest"); + /* Test the number of operations in the request */ if(server->config.maxNodesPerTranslateBrowsePathsToNodeIds != 0 && request->browsePathsSize > server->config.maxNodesPerTranslateBrowsePathsToNodeIds) { response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS; return; } + UA_UInt32 nodeClassMask = 0; /* All node classes */ response->responseHeader.serviceResult = UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)Operation_TranslateBrowsePathToNodeIds, - NULL, &request->browsePathsSize, &UA_TYPES[UA_TYPES_BROWSEPATH], + &nodeClassMask, + &request->browsePathsSize, &UA_TYPES[UA_TYPES_BROWSEPATH], &response->resultsSize, &UA_TYPES[UA_TYPES_BROWSEPATHRESULT]); } +UA_BrowsePathResult +UA_Server_browseSimplifiedBrowsePath(UA_Server *server, const UA_NodeId origin, + size_t browsePathSize, const UA_QualifiedName *browsePath) { + /* Construct the BrowsePath */ + UA_BrowsePath bp; + UA_BrowsePath_init(&bp); + bp.startingNode = origin; + UA_STACKARRAY(UA_RelativePathElement, rpe, browsePathSize); + memset(rpe, 0, sizeof(UA_RelativePathElement) * browsePathSize); + for(size_t j = 0; j < browsePathSize; j++) { + rpe[j].referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HIERARCHICALREFERENCES); + rpe[j].includeSubtypes = true; + rpe[j].targetName = browsePath[j]; + } + bp.relativePath.elements = rpe; + bp.relativePath.elementsSize = browsePathSize; + + /* Browse */ + UA_BrowsePathResult bpr; + UA_BrowsePathResult_init(&bpr); + UA_UInt32 nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE; + Operation_TranslateBrowsePathToNodeIds(server, &server->adminSession, &nodeClassMask, &bp, &bpr); + return bpr; +} + +/************/ +/* Register */ +/************/ + void Service_RegisterNodes(UA_Server *server, UA_Session *session, const UA_RegisterNodesRequest *request, UA_RegisterNodesResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing RegisterNodesRequest"); //TODO: hang the nodeids to the session if really needed @@ -29927,6 +30957,7 @@ void Service_RegisterNodes(UA_Server *server, UA_Session *session, return; } + /* Test the number of operations in the request */ if(server->config.maxNodesPerRegisterNodes != 0 && request->nodesToRegisterSize > server->config.maxNodesPerRegisterNodes) { response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS; @@ -29943,13 +30974,14 @@ void Service_RegisterNodes(UA_Server *server, UA_Session *session, void Service_UnregisterNodes(UA_Server *server, UA_Session *session, const UA_UnregisterNodesRequest *request, UA_UnregisterNodesResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing UnRegisterNodesRequest"); //TODO: remove the nodeids from the session if really needed if(request->nodesToUnregisterSize == 0) response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO; + /* Test the number of operations in the request */ if(server->config.maxNodesPerRegisterNodes != 0 && request->nodesToUnregisterSize > server->config.maxNodesPerRegisterNodes) { response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS; @@ -29957,7 +30989,7 @@ void Service_UnregisterNodes(UA_Server *server, UA_Session *session, } } -/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_services_call.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_services_method.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -29965,7 +30997,7 @@ void Service_UnregisterNodes(UA_Server *server, UA_Session *session, * * Copyright 2015 (c) Chris Iatrou * Copyright 2015-2017 (c) Florian Palm - * Copyright 2015-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015 (c) Oleksiy Vasylyev * Copyright 2016 (c) LEvertz @@ -29991,8 +31023,7 @@ getArgumentsVariableNode(UA_Server *server, const UA_MethodNode *ofMethod, for(size_t j = 0; j < rk->targetIdsSize; ++j) { const UA_Node *refTarget = - server->config.nodestore.getNode(server->config.nodestore.context, - &rk->targetIds[j].nodeId); + UA_Nodestore_getNode(server->nsCtx, &rk->targetIds[j].nodeId); if(!refTarget) continue; if(refTarget->nodeClass == UA_NODECLASS_VARIABLE && @@ -30000,13 +31031,13 @@ getArgumentsVariableNode(UA_Server *server, const UA_MethodNode *ofMethod, UA_String_equal(&withBrowseName, &refTarget->browseName.name)) { return (const UA_VariableNode*)refTarget; } - server->config.nodestore.releaseNode(server->config.nodestore.context, - refTarget); + UA_Nodestore_releaseNode(server->nsCtx, refTarget); } } return NULL; } +/* inputArgumentResults has the length request->inputArgumentsSize */ static UA_StatusCode typeCheckArguments(UA_Server *server, UA_Session *session, const UA_VariableNode *argRequirements, size_t argsSize, @@ -30031,16 +31062,20 @@ typeCheckArguments(UA_Server *server, UA_Session *session, return UA_STATUSCODE_BADTOOMANYARGUMENTS; /* Type-check every argument against the definition */ + UA_StatusCode retval = UA_STATUSCODE_GOOD; UA_Argument *argReqs = (UA_Argument*)argRequirements->value.data.value.value.data; for(size_t i = 0; i < argReqsSize; ++i) { if(!compatibleValue(server, session, &argReqs[i].dataType, argReqs[i].valueRank, argReqs[i].arrayDimensionsSize, argReqs[i].arrayDimensions, - &args[i], NULL)) - return UA_STATUSCODE_BADTYPEMISMATCH; + &args[i], NULL)) { + inputArgumentResults[i] = UA_STATUSCODE_BADTYPEMISMATCH; + retval = UA_STATUSCODE_BADINVALIDARGUMENT; + } } - return UA_STATUSCODE_GOOD; + return retval; } +/* inputArgumentResults has the length request->inputArgumentsSize */ static UA_StatusCode validMethodArguments(UA_Server *server, UA_Session *session, const UA_MethodNode *method, const UA_CallMethodRequest *request, @@ -30048,22 +31083,20 @@ validMethodArguments(UA_Server *server, UA_Session *session, const UA_MethodNode /* Get the input arguments node */ const UA_VariableNode *inputArguments = getArgumentsVariableNode(server, method, UA_STRING("InputArguments")); - UA_StatusCode retval = UA_STATUSCODE_GOOD; if(!inputArguments) { if(request->inputArgumentsSize > 0) - retval = UA_STATUSCODE_BADINVALIDARGUMENT; - return retval; + return UA_STATUSCODE_BADTOOMANYARGUMENTS; + return UA_STATUSCODE_GOOD; } /* Verify the request */ - retval = typeCheckArguments(server, session, inputArguments, + UA_StatusCode retval = typeCheckArguments(server, session, inputArguments, request->inputArgumentsSize, request->inputArguments, inputArgumentResults); /* Release the input arguments node */ - server->config.nodestore.releaseNode(server->config.nodestore.context, - (const UA_Node*)inputArguments); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)inputArguments); return retval; } @@ -30102,7 +31135,7 @@ callWithMethodAndObject(UA_Server *server, UA_Session *session, UA_NodeReferenceKind *rk = &object->references[i]; if(rk->isInverse) continue; - if(!isNodeInTree(&server->config.nodestore, &rk->referenceTypeId, + if(!isNodeInTree(server->nsCtx, &rk->referenceTypeId, &hasComponentNodeId, &hasSubTypeNodeId, 1)) continue; for(size_t j = 0; j < rk->targetIdsSize; ++j) { @@ -30126,10 +31159,19 @@ callWithMethodAndObject(UA_Server *server, UA_Session *session, session->sessionHandle, &request->methodId, method->context, &request->objectId, object->context); if(!executable) { - result->statusCode = UA_STATUSCODE_BADNOTWRITABLE; // There is no NOTEXECUTABLE? + result->statusCode = UA_STATUSCODE_BADNOTEXECUTABLE; return; } + /* Allocate the inputArgumentResults array */ + result->inputArgumentResults = (UA_StatusCode*) + UA_Array_new(request->inputArgumentsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); + if(!result->inputArgumentResults) { + result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY; + return; + } + result->inputArgumentResultsSize = request->inputArgumentsSize; + /* Verify Input Arguments */ result->statusCode = validMethodArguments(server, session, method, request, result->inputArgumentResults); @@ -30150,22 +31192,19 @@ callWithMethodAndObject(UA_Server *server, UA_Session *session, getArgumentsVariableNode(server, method, UA_STRING("OutputArguments")); /* Allocate the output arguments array */ - if(outputArguments) { - if(outputArguments->value.data.value.value.arrayLength > 0) { - result->outputArguments = (UA_Variant*) - UA_Array_new(outputArguments->value.data.value.value.arrayLength, - &UA_TYPES[UA_TYPES_VARIANT]); - if(!result->outputArguments) { - result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY; - return; - } - result->outputArgumentsSize = outputArguments->value.data.value.value.arrayLength; - } - - /* Release the output arguments node */ - server->config.nodestore.releaseNode(server->config.nodestore.context, - (const UA_Node*)outputArguments); + size_t outputArgsSize = 0; + if(outputArguments) + outputArgsSize = outputArguments->value.data.value.value.arrayLength; + result->outputArguments = (UA_Variant*) + UA_Array_new(outputArgsSize, &UA_TYPES[UA_TYPES_VARIANT]); + if(!result->outputArguments) { + result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY; + return; } + result->outputArgumentsSize = outputArgsSize; + + /* Release the output arguments node */ + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)outputArguments); /* Call the method */ result->statusCode = method->method(server, &session->sessionId, session->sessionHandle, @@ -30181,21 +31220,18 @@ Operation_CallMethod(UA_Server *server, UA_Session *session, void *context, const UA_CallMethodRequest *request, UA_CallMethodResult *result) { /* Get the method node */ const UA_MethodNode *method = (const UA_MethodNode*) - server->config.nodestore.getNode(server->config.nodestore.context, - &request->methodId); + UA_Nodestore_getNode(server->nsCtx, &request->methodId); if(!method) { - result->statusCode = UA_STATUSCODE_BADMETHODINVALID; + result->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN; return; } /* Get the object node */ const UA_ObjectNode *object = (const UA_ObjectNode*) - server->config.nodestore.getNode(server->config.nodestore.context, - &request->objectId); + UA_Nodestore_getNode(server->nsCtx, &request->objectId); if(!object) { - result->statusCode = UA_STATUSCODE_BADNODEIDINVALID; - server->config.nodestore.releaseNode(server->config.nodestore.context, - (const UA_Node*)method); + result->statusCode = UA_STATUSCODE_BADNODEIDUNKNOWN; + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)method); return; } @@ -30203,16 +31239,14 @@ Operation_CallMethod(UA_Server *server, UA_Session *session, void *context, callWithMethodAndObject(server, session, request, result, method, object); /* Release the method and object node */ - server->config.nodestore.releaseNode(server->config.nodestore.context, - (const UA_Node*)method); - server->config.nodestore.releaseNode(server->config.nodestore.context, - (const UA_Node*)object); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)method); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)object); } void Service_Call(UA_Server *server, UA_Session *session, const UA_CallRequest *request, UA_CallResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing CallRequest"); if(server->config.maxNodesPerMethodCall != 0 && @@ -30241,15 +31275,16 @@ UA_Server_call(UA_Server *server, const UA_CallMethodRequest *request) { /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2017 (c) Florian Palm * Copyright 2014-2016 (c) Sten Grüner * Copyright 2015 (c) Chris Iatrou * Copyright 2015 (c) Oleksiy Vasylyev * Copyright 2017 (c) Stefan Profanter, fortiss GmbH * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2019 (c) Kalycito Infotech Private Limited */ @@ -30306,19 +31341,22 @@ Service_CreateSession(UA_Server *server, UA_SecureChannel *channel, return; } - UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, "Trying to create session"); + UA_LOG_DEBUG_CHANNEL(&server->config.logger, channel, "Trying to create session"); if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { /* Compare the clientCertificate with the remoteCertificate of the channel. * Both the clientCertificate of this request and the remoteCertificate * of the channel may contain a partial or a complete certificate chain. - * The compareCertificate function of the channelModule will compare the + * The compareCertificate function of the channelModule will compare the * first certificate of each chain. The end certificate shall be located * first in the chain according to the OPC UA specification Part 6 (1.04), * chapter 6.2.3.*/ - if(channel->securityPolicy->channelModule.compareCertificate(channel->channelContext, - &request->clientCertificate) != UA_STATUSCODE_GOOD) { + UA_StatusCode retval = channel->securityPolicy->channelModule. + compareCertificate(channel->channelContext, &request->clientCertificate); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING_CHANNEL(&server->config.logger, channel, + "The client certificate did not validate"); response->responseHeader.serviceResult = UA_STATUSCODE_BADCERTIFICATEINVALID; return; } @@ -30342,16 +31380,19 @@ Service_CreateSession(UA_Server *server, UA_SecureChannel *channel, response->responseHeader.serviceResult = cv->verifyApplicationURI(cv->context, &request->clientCertificate, &request->clientDescription.applicationUri); - if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) + if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING_CHANNEL(&server->config.logger, channel, + "The client's ApplicationURI did not match the certificate"); return; + } } UA_Session *newSession = NULL; response->responseHeader.serviceResult = UA_SessionManager_createSession(&server->sessionManager, channel, request, &newSession); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, - "Processing CreateSessionRequest failed"); + UA_LOG_WARNING_CHANNEL(&server->config.logger, channel, + "Processing CreateSessionRequest failed"); return; } @@ -30372,7 +31413,7 @@ Service_CreateSession(UA_Server *server, UA_SecureChannel *channel, /* Copy the server's endpointdescriptions into the response */ for(size_t i = 0; i < server->config.endpointsSize; ++i) response->responseHeader.serviceResult |= - UA_EndpointDescription_copy(&server->config.endpoints[i].endpointDescription, + UA_EndpointDescription_copy(&server->config.endpoints[i], &response->serverEndpoints[i]); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { UA_SessionManager_removeSession(&server->sessionManager, @@ -30394,7 +31435,7 @@ Service_CreateSession(UA_Server *server, UA_SecureChannel *channel, /* Fill the session information */ newSession->maxResponseMessageSize = request->maxResponseMessageSize; newSession->maxRequestMessageSize = - channel->connection->localConf.maxMessageSize; + channel->connection->config.maxMessageSize; response->responseHeader.serviceResult |= UA_ApplicationDescription_copy(&request->clientDescription, &newSession->clientDescription); @@ -30438,9 +31479,9 @@ Service_CreateSession(UA_Server *server, UA_SecureChannel *channel, return; } - UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, - "Session " UA_PRINTF_GUID_FORMAT " created", - UA_PRINTF_GUID_DATA(newSession->sessionId.identifier.guid)); + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, + "Session " UA_PRINTF_GUID_FORMAT " created", + UA_PRINTF_GUID_DATA(newSession->sessionId.identifier.guid)); } static UA_StatusCode @@ -30450,6 +31491,11 @@ checkSignature(const UA_Server *server, const UA_SecureChannel *channel, channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) return UA_STATUSCODE_GOOD; + /* Check for zero signature length in client signature */ + if(request->clientSignature.signature.length == 0) { + return UA_STATUSCODE_BADAPPLICATIONSIGNATUREINVALID; + } + if(!channel->securityPolicy) return UA_STATUSCODE_BADINTERNALERROR; const UA_SecurityPolicy *securityPolicy = channel->securityPolicy; @@ -30472,6 +31518,64 @@ checkSignature(const UA_Server *server, const UA_SecureChannel *channel, return retval; } +#ifdef UA_ENABLE_ENCRYPTION +static UA_StatusCode +decryptPassword(UA_SecurityPolicy *securityPolicy, void *tempChannelContext, + const UA_ByteString *serverNonce, UA_UserNameIdentityToken *userToken) { + UA_SecurityPolicyEncryptionAlgorithm *asymEnc = + &securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm; + if(!UA_String_equal(&userToken->encryptionAlgorithm, &asymEnc->uri)) + return UA_STATUSCODE_BADIDENTITYTOKENINVALID; + + UA_UInt32 tokenSecretLength; + UA_ByteString decryptedTokenSecret, tokenServerNonce; + if(UA_ByteString_copy(&userToken->password, &decryptedTokenSecret) != UA_STATUSCODE_GOOD) + return UA_STATUSCODE_BADIDENTITYTOKENINVALID; + + UA_StatusCode retval = UA_STATUSCODE_BADIDENTITYTOKENINVALID; + if(asymEnc->decrypt(securityPolicy, tempChannelContext, + &decryptedTokenSecret) != UA_STATUSCODE_GOOD) + goto cleanup; + + memcpy(&tokenSecretLength, decryptedTokenSecret.data, sizeof(UA_UInt32)); + + /* The decrypted data must be large enough to include the Encrypted Token + * Secret Format and the length field must indicate enough data to include + * the server nonce. */ + if(decryptedTokenSecret.length < sizeof(UA_UInt32) + serverNonce->length || + decryptedTokenSecret.length < sizeof(UA_UInt32) + tokenSecretLength || + tokenSecretLength < serverNonce->length) + goto cleanup; + + /* If the Encrypted Token Secret contains padding, the padding must be + * zeroes according to the 1.04.1 specification errata, chapter 3. */ + for(size_t i = sizeof(UA_UInt32) + tokenSecretLength; i < decryptedTokenSecret.length; i++) { + if(decryptedTokenSecret.data[i] != 0) + goto cleanup; + } + + /* The server nonce must match according to the 1.04.1 specification errata, + * chapter 3. */ + tokenServerNonce.length = serverNonce->length; + tokenServerNonce.data = &decryptedTokenSecret.data[sizeof(UA_UInt32) + tokenSecretLength - serverNonce->length]; + if(!UA_ByteString_equal(serverNonce, &tokenServerNonce)) + goto cleanup; + + /* The password was decrypted successfully. Replace usertoken with the + * decrypted password. The encryptionAlgorithm and policyId fields are left + * in the UserToken as an indication for the AccessControl plugin that + * evaluates the decrypted content. */ + memcpy(userToken->password.data, &decryptedTokenSecret.data[sizeof(UA_UInt32)], + tokenSecretLength - serverNonce->length); + userToken->password.length = tokenSecretLength - serverNonce->length; + retval = UA_STATUSCODE_GOOD; + + cleanup: + UA_ByteString_deleteMembers(&decryptedTokenSecret); + return retval; +} +#endif + /* TODO: Check all of the following: * * Part 4, §5.6.3: When the ActivateSession Service is called for the first time @@ -30489,10 +31593,10 @@ void Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel, UA_Session *session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Execute ActivateSession"); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Execute ActivateSession"); if(session->validTill < UA_DateTime_nowMonotonic()) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "ActivateSession: SecureChannel %i wants " "to activate, but the session has timed out", channel->securityToken.channelId); @@ -30505,25 +31609,160 @@ Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel, * to the client */ response->responseHeader.serviceResult = checkSignature(server, channel, session, request); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "Signature check failed with status code %s", UA_StatusCode_name(response->responseHeader.serviceResult)); return; } + /* Find the matching endpoint */ + const UA_EndpointDescription *ed = NULL; + for(size_t i = 0; ed == NULL && i < server->config.endpointsSize; ++i) { + const UA_EndpointDescription *e = &server->config.endpoints[i]; + + /* Match the Security Mode */ + if(e->securityMode != channel->securityMode) + continue; + + /* Match the SecurityPolicy */ + if(!UA_String_equal(&e->securityPolicyUri, &channel->securityPolicy->policyUri)) + continue; + + /* Match the UserTokenType */ + for(size_t j = 0; j < e->userIdentityTokensSize; j++) { + const UA_UserTokenPolicy *u = &e->userIdentityTokens[j]; + if(u->tokenType == UA_USERTOKENTYPE_ANONYMOUS) { + /* Part 4, Section 5.6.3.2, Table 17: A NULL or empty + * UserIdentityToken should be treated as Anonymous */ + if(request->userIdentityToken.content.decoded.type != &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN] && + request->userIdentityToken.encoding != UA_EXTENSIONOBJECT_ENCODED_NOBODY) + continue; + } else if(u->tokenType == UA_USERTOKENTYPE_USERNAME) { + if(request->userIdentityToken.content.decoded.type != &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) + continue; + } else if(u->tokenType == UA_USERTOKENTYPE_CERTIFICATE) { + if(request->userIdentityToken.content.decoded.type != &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]) + continue; + } else if(u->tokenType == UA_USERTOKENTYPE_ISSUEDTOKEN) { + if(request->userIdentityToken.content.decoded.type != &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]) + continue; + } else { + response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID; + return; + } + + /* Match found */ + ed = e; + break; + } + + } + + /* No matching endpoint found */ + if(!ed) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID; + return; + } + +#ifdef UA_ENABLE_ENCRYPTION + /* If it is a UserNameIdentityToken, decrypt the password if encrypted */ + if((request->userIdentityToken.encoding == UA_EXTENSIONOBJECT_DECODED) && + (request->userIdentityToken.content.decoded.type == &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN])) { + UA_UserNameIdentityToken *userToken = (UA_UserNameIdentityToken *) + request->userIdentityToken.content.decoded.data; + + /* Find the UserTokenPolicy */ + UA_Byte tokenIndex = 0; + for(; tokenIndex < ed->userIdentityTokensSize; tokenIndex++) { + if(ed->userIdentityTokens[tokenIndex].tokenType != UA_USERTOKENTYPE_USERNAME) + continue; + if(UA_String_equal(&userToken->policyId, &ed->userIdentityTokens[tokenIndex].policyId)) + break; + } + if(tokenIndex == ed->userIdentityTokensSize) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID; + return; + } + + /* Get the SecurityPolicy. If the userTokenPolicy doesn't specify a + * security policy the security policy of the secure channel is used. */ + UA_SecurityPolicy* securityPolicy; + if(ed->userIdentityTokens[tokenIndex].securityPolicyUri.data == NULL) + securityPolicy = UA_SecurityPolicy_getSecurityPolicyByUri(server, &ed->securityPolicyUri); + else + securityPolicy = UA_SecurityPolicy_getSecurityPolicyByUri(server, &ed->userIdentityTokens[tokenIndex].securityPolicyUri); + if(!securityPolicy) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR; + return; + } + + /* Encrypted password? */ + if(!UA_String_equal(&securityPolicy->policyUri, &UA_SECURITY_POLICY_NONE_URI)) { + /* Test if the encryption algorithm is correctly specified */ + if(!UA_String_equal(&userToken->encryptionAlgorithm, + &securityPolicy->asymmetricModule.cryptoModule. + encryptionAlgorithm.uri)) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID; + return; + } + + /* Create a temporary channel context if a different SecurityPolicy is + * used for the password from the SecureChannel */ + void *tempChannelContext = channel->channelContext; + if(securityPolicy != channel->securityPolicy) { + /* TODO: This is a hack. We use our own certificate to create a + * channel context. Because the client does not provide one in a + * #None SecureChannel. We should not need a ChannelContext at all + * for asymmetric decryption where the remote certificate is not + * used. */ + response->responseHeader.serviceResult = + securityPolicy->channelModule.newContext(securityPolicy, + &securityPolicy->localCertificate, + &tempChannelContext); + if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING_SESSION(&server->config.logger, session, "ActivateSession: " + "Failed to create a context for the SecurityPolicy %.*s", + (int)securityPolicy->policyUri.length, + securityPolicy->policyUri.data); + return; + } + } + + /* Decrypt */ + response->responseHeader.serviceResult = + decryptPassword(securityPolicy, tempChannelContext, &session->serverNonce, userToken); + + /* Remove the temporary channel context */ + if(securityPolicy != channel->securityPolicy) + securityPolicy->channelModule.deleteContext(tempChannelContext); + } + + if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { + UA_LOG_INFO_SESSION(&server->config.logger, session, "ActivateSession: " + "Failed to decrypt the password with the status code %s", + UA_StatusCode_name(response->responseHeader.serviceResult)); + } + + } +#endif + /* Callback into userland access control */ response->responseHeader.serviceResult = server->config.accessControl.activateSession(server, &server->config.accessControl, - &session->sessionId, &request->userIdentityToken, + ed, &channel->remoteCertificate, + &session->sessionId, + &request->userIdentityToken, &session->sessionHandle); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "ActivateSession: Could not generate a server nonce"); + UA_LOG_INFO_SESSION(&server->config.logger, session, + "ActivateSession: The AccessControl plugin " + "denied the access with the status code %s", + UA_StatusCode_name(response->responseHeader.serviceResult)); return; } if(session->header.channel && session->header.channel != channel) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "ActivateSession: Detach from old channel"); /* Detach the old SecureChannel and attach the new */ UA_Session_detachFromSecureChannel(session); @@ -30541,12 +31780,12 @@ Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel, if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { UA_Session_detachFromSecureChannel(session); session->activated = false; - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "ActivateSession: Could not generate a server nonce"); return; } - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "ActivateSession: Session activated"); } @@ -30554,7 +31793,7 @@ void Service_CloseSession(UA_Server *server, UA_Session *session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response) { - UA_LOG_INFO_SESSION(server->config.logger, session, "CloseSession"); + UA_LOG_INFO_SESSION(&server->config.logger, session, "CloseSession"); /* Callback into userland access control */ server->config.accessControl.closeSession(server, &server->config.accessControl, @@ -30570,7 +31809,7 @@ Service_CloseSession(UA_Server *server, UA_Session *session, * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015-2016 (c) Sten Grüner * Copyright 2014-2017 (c) Florian Palm * Copyright 2015 (c) Christian Fimmers @@ -30587,6 +31826,9 @@ Service_CloseSession(UA_Server *server, UA_Session *session, */ +#ifdef UA_ENABLE_HISTORIZING +#endif + /******************/ /* Access Control */ /******************/ @@ -30637,21 +31879,6 @@ getUserExecutable(UA_Server *server, const UA_Session *session, /****************/ static UA_StatusCode -readArrayDimensionsAttribute(const UA_VariableNode *vn, UA_DataValue *v) { - UA_Variant_setArray(&v->value, vn->arrayDimensions, - vn->arrayDimensionsSize, &UA_TYPES[UA_TYPES_UINT32]); - v->value.storageType = UA_VARIANT_DATA_NODELETE; - return UA_STATUSCODE_GOOD; -} - -static void -setScalarNoDelete(UA_Variant *v, const void * UA_RESTRICT p, - const UA_DataType *type) { - UA_Variant_setScalar(v, (void*)(uintptr_t)p, type); - v->storageType = UA_VARIANT_DATA_NODELETE; -} - -static UA_StatusCode readIsAbstractAttribute(const UA_Node *node, UA_Variant *v) { const UA_Boolean *isAbstract; switch(node->nodeClass) { @@ -30671,29 +31898,32 @@ readIsAbstractAttribute(const UA_Node *node, UA_Variant *v) { return UA_STATUSCODE_BADATTRIBUTEIDINVALID; } - setScalarNoDelete(v, isAbstract, &UA_TYPES[UA_TYPES_BOOLEAN]); - v->storageType = UA_VARIANT_DATA_NODELETE; - return UA_STATUSCODE_GOOD; + return UA_Variant_setScalarCopy(v, isAbstract, &UA_TYPES[UA_TYPES_BOOLEAN]); } static UA_StatusCode readValueAttributeFromNode(UA_Server *server, UA_Session *session, const UA_VariableNode *vn, UA_DataValue *v, UA_NumericRange *rangeptr) { + /* Update the value by the user callback */ if(vn->value.data.callback.onRead) { vn->value.data.callback.onRead(server, &session->sessionId, session->sessionHandle, &vn->nodeId, vn->context, rangeptr, &vn->value.data.value); - const UA_Node *old = (const UA_Node *)vn; - /* Reopen the node to see the changes from onRead */ - vn = (const UA_VariableNode*)UA_Nodestore_get(server, &vn->nodeId); - UA_Nodestore_release(server, old); + vn = (const UA_VariableNode*)UA_Nodestore_getNode(server->nsCtx, &vn->nodeId); + if(!vn) + return UA_STATUSCODE_BADNODEIDUNKNOWN; } + + /* Set the result */ if(rangeptr) return UA_Variant_copyRange(&vn->value.data.value.value, &v->value, *rangeptr); - *v = vn->value.data.value; - v->value.storageType = UA_VARIANT_DATA_NODELETE; - return UA_STATUSCODE_GOOD; + UA_StatusCode retval = UA_DataValue_copy(&vn->value.data.value, v); + + /* Clean up */ + if(vn->value.data.callback.onRead) + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node *)vn); + return retval; } static UA_StatusCode @@ -30705,8 +31935,18 @@ readValueAttributeFromDataSource(UA_Server *server, UA_Session *session, return UA_STATUSCODE_BADINTERNALERROR; UA_Boolean sourceTimeStamp = (timestamps == UA_TIMESTAMPSTORETURN_SOURCE || timestamps == UA_TIMESTAMPSTORETURN_BOTH); - return vn->value.dataSource.read(server, &session->sessionId, session->sessionHandle, - &vn->nodeId, vn->context, sourceTimeStamp, rangeptr, v); + UA_DataValue v2; + UA_DataValue_init(&v2); + UA_StatusCode retval = vn->value.dataSource. + read(server, &session->sessionId, session->sessionHandle, + &vn->nodeId, vn->context, sourceTimeStamp, rangeptr, &v2); + if(v2.hasValue && v2.value.storageType == UA_VARIANT_DATA_NODELETE) { + retval = UA_DataValue_copy(&v2, v); + UA_DataValue_deleteMembers(&v2); + } else { + *v = v2; + } + return retval; } static UA_StatusCode @@ -30755,11 +31995,11 @@ static const UA_String jsonEncoding = {sizeof("Default JSON")-1, (UA_Byte*)"Defa /* Returns a datavalue that may point into the node via the * UA_VARIANT_DATA_NODELETE tag. Don't access the returned DataValue once the * node has been released! */ -static void -Read(const UA_Node *node, UA_Server *server, UA_Session *session, - UA_TimestampsToReturn timestampsToReturn, - const UA_ReadValueId *id, UA_DataValue *v) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, +void +ReadWithNode(const UA_Node *node, UA_Server *server, UA_Session *session, + UA_TimestampsToReturn timestampsToReturn, + const UA_ReadValueId *id, UA_DataValue *v) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Read the attribute %i", id->attributeId); /* Only Binary Encoding is supported */ @@ -30785,22 +32025,22 @@ Read(const UA_Node *node, UA_Server *server, UA_Session *session, UA_StatusCode retval = UA_STATUSCODE_GOOD; switch(id->attributeId) { case UA_ATTRIBUTEID_NODEID: - setScalarNoDelete(&v->value, &node->nodeId, &UA_TYPES[UA_TYPES_NODEID]); + retval = UA_Variant_setScalarCopy(&v->value, &node->nodeId, &UA_TYPES[UA_TYPES_NODEID]); break; case UA_ATTRIBUTEID_NODECLASS: - setScalarNoDelete(&v->value, &node->nodeClass, &UA_TYPES[UA_TYPES_NODECLASS]); + retval = UA_Variant_setScalarCopy(&v->value, &node->nodeClass, &UA_TYPES[UA_TYPES_NODECLASS]); break; case UA_ATTRIBUTEID_BROWSENAME: - setScalarNoDelete(&v->value, &node->browseName, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); + retval = UA_Variant_setScalarCopy(&v->value, &node->browseName, &UA_TYPES[UA_TYPES_QUALIFIEDNAME]); break; case UA_ATTRIBUTEID_DISPLAYNAME: - setScalarNoDelete(&v->value, &node->displayName, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); + retval = UA_Variant_setScalarCopy(&v->value, &node->displayName, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); break; case UA_ATTRIBUTEID_DESCRIPTION: - setScalarNoDelete(&v->value, &node->description, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); + retval = UA_Variant_setScalarCopy(&v->value, &node->description, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); break; case UA_ATTRIBUTEID_WRITEMASK: - setScalarNoDelete(&v->value, &node->writeMask, &UA_TYPES[UA_TYPES_UINT32]); + retval = UA_Variant_setScalarCopy(&v->value, &node->writeMask, &UA_TYPES[UA_TYPES_UINT32]); break; case UA_ATTRIBUTEID_USERWRITEMASK: { UA_UInt32 userWriteMask = getUserWriteMask(server, session, node); @@ -30811,23 +32051,29 @@ Read(const UA_Node *node, UA_Server *server, UA_Session *session, break; case UA_ATTRIBUTEID_SYMMETRIC: CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE); - setScalarNoDelete(&v->value, &((const UA_ReferenceTypeNode*)node)->symmetric, + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_ReferenceTypeNode*)node)->symmetric, &UA_TYPES[UA_TYPES_BOOLEAN]); break; case UA_ATTRIBUTEID_INVERSENAME: CHECK_NODECLASS(UA_NODECLASS_REFERENCETYPE); - setScalarNoDelete(&v->value, &((const UA_ReferenceTypeNode*)node)->inverseName, + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_ReferenceTypeNode*)node)->inverseName, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); break; case UA_ATTRIBUTEID_CONTAINSNOLOOPS: CHECK_NODECLASS(UA_NODECLASS_VIEW); - setScalarNoDelete(&v->value, &((const UA_ViewNode*)node)->containsNoLoops, + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_ViewNode*)node)->containsNoLoops, &UA_TYPES[UA_TYPES_BOOLEAN]); break; case UA_ATTRIBUTEID_EVENTNOTIFIER: CHECK_NODECLASS(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT); - setScalarNoDelete(&v->value, &((const UA_ViewNode*)node)->eventNotifier, - &UA_TYPES[UA_TYPES_BYTE]); + if(node->nodeClass == UA_NODECLASS_VIEW) { + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_ViewNode*)node)->eventNotifier, + &UA_TYPES[UA_TYPES_BYTE]); + } + else{ + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_ObjectNode*)node)->eventNotifier, + &UA_TYPES[UA_TYPES_BYTE]); + } break; case UA_ATTRIBUTEID_VALUE: { CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE); @@ -30853,48 +32099,48 @@ Read(const UA_Node *node, UA_Server *server, UA_Session *session, } case UA_ATTRIBUTEID_DATATYPE: CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE); - setScalarNoDelete(&v->value, &((const UA_VariableTypeNode*)node)->dataType, - &UA_TYPES[UA_TYPES_NODEID]); + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_VariableTypeNode*)node)->dataType, + &UA_TYPES[UA_TYPES_NODEID]); break; case UA_ATTRIBUTEID_VALUERANK: CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE); - setScalarNoDelete(&v->value, &((const UA_VariableTypeNode*)node)->valueRank, - &UA_TYPES[UA_TYPES_INT32]); + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_VariableTypeNode*)node)->valueRank, + &UA_TYPES[UA_TYPES_INT32]); break; case UA_ATTRIBUTEID_ARRAYDIMENSIONS: CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE); - retval = readArrayDimensionsAttribute((const UA_VariableNode*)node, v); + retval = UA_Variant_setArrayCopy(&v->value, ((const UA_VariableTypeNode*)node)->arrayDimensions, + ((const UA_VariableTypeNode*)node)->arrayDimensionsSize, + &UA_TYPES[UA_TYPES_UINT32]); break; case UA_ATTRIBUTEID_ACCESSLEVEL: CHECK_NODECLASS(UA_NODECLASS_VARIABLE); - setScalarNoDelete(&v->value, &((const UA_VariableNode*)node)->accessLevel, - &UA_TYPES[UA_TYPES_BYTE]); + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_VariableNode*)node)->accessLevel, + &UA_TYPES[UA_TYPES_BYTE]); break; case UA_ATTRIBUTEID_USERACCESSLEVEL: { CHECK_NODECLASS(UA_NODECLASS_VARIABLE); - UA_Byte userAccessLevel = getUserAccessLevel(server, session, - (const UA_VariableNode*)node); + UA_Byte userAccessLevel = getUserAccessLevel(server, session, (const UA_VariableNode*)node); retval = UA_Variant_setScalarCopy(&v->value, &userAccessLevel, &UA_TYPES[UA_TYPES_BYTE]); break; } case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL: CHECK_NODECLASS(UA_NODECLASS_VARIABLE); - setScalarNoDelete(&v->value, &((const UA_VariableNode*)node)->minimumSamplingInterval, + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_VariableNode*)node)->minimumSamplingInterval, &UA_TYPES[UA_TYPES_DOUBLE]); break; case UA_ATTRIBUTEID_HISTORIZING: CHECK_NODECLASS(UA_NODECLASS_VARIABLE); - setScalarNoDelete(&v->value, &((const UA_VariableNode*)node)->historizing, + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_VariableNode*)node)->historizing, &UA_TYPES[UA_TYPES_BOOLEAN]); break; case UA_ATTRIBUTEID_EXECUTABLE: CHECK_NODECLASS(UA_NODECLASS_METHOD); - setScalarNoDelete(&v->value, &((const UA_MethodNode*)node)->executable, + retval = UA_Variant_setScalarCopy(&v->value, &((const UA_MethodNode*)node)->executable, &UA_TYPES[UA_TYPES_BOOLEAN]); break; case UA_ATTRIBUTEID_USEREXECUTABLE: { CHECK_NODECLASS(UA_NODECLASS_METHOD); - UA_Boolean userExecutable = getUserExecutable(server, session, - (const UA_MethodNode*)node); + UA_Boolean userExecutable = getUserExecutable(server, session, (const UA_MethodNode*)node); retval = UA_Variant_setScalarCopy(&v->value, &userExecutable, &UA_TYPES[UA_TYPES_BOOLEAN]); break; } default: @@ -30917,6 +32163,9 @@ Read(const UA_Node *node, UA_Server *server, UA_Session *session, v->serverTimestamp = UA_DateTime_now(); v->hasServerTimestamp = true; } + } else { + /* In case the ServerTimestamp has been set manually */ + v->hasServerTimestamp = false; } /* Handle source time stamp */ @@ -30932,79 +32181,52 @@ Read(const UA_Node *node, UA_Server *server, UA_Session *session, } } -static UA_StatusCode -Operation_Read(UA_Server *server, UA_Session *session, UA_MessageContext *mc, - UA_TimestampsToReturn timestampsToReturn, const UA_ReadValueId *id) { - UA_DataValue dv; - UA_DataValue_init(&dv); - +static void +Operation_Read(UA_Server *server, UA_Session *session, UA_ReadRequest *request, + UA_ReadValueId *rvi, UA_DataValue *result) { /* Get the node */ - const UA_Node *node = UA_Nodestore_get(server, &id->nodeId); + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &rvi->nodeId); /* Perform the read operation */ if(node) { - Read(node, server, session, timestampsToReturn, id, &dv); + ReadWithNode(node, server, session, request->timestampsToReturn, rvi, result); + UA_Nodestore_releaseNode(server->nsCtx, node); } else { - dv.hasStatus = true; - dv.status = UA_STATUSCODE_BADNODEIDUNKNOWN; + result->hasStatus = true; + result->status = UA_STATUSCODE_BADNODEIDUNKNOWN; } - - /* Encode (and send) the results */ - UA_StatusCode retval = UA_MessageContext_encode(mc, &dv, &UA_TYPES[UA_TYPES_DATAVALUE]); - - /* Free copied data and release the node */ - UA_Variant_deleteMembers(&dv.value); - UA_Nodestore_release(server, node); - return retval; } -UA_StatusCode Service_Read(UA_Server *server, UA_Session *session, UA_MessageContext *mc, - const UA_ReadRequest *request, UA_ResponseHeader *responseHeader) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, - "Processing ReadRequest"); +void +Service_Read(UA_Server *server, UA_Session *session, + const UA_ReadRequest *request, UA_ReadResponse *response) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing ReadRequest"); /* Check if the timestampstoreturn is valid */ - if(request->timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) - responseHeader->serviceResult = UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID; - - if(request->nodesToReadSize == 0) - responseHeader->serviceResult = UA_STATUSCODE_BADNOTHINGTODO; + if(request->timestampsToReturn < 0 || + request->timestampsToReturn > UA_TIMESTAMPSTORETURN_NEITHER) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADTIMESTAMPSTORETURNINVALID; + return; + } /* Check if maxAge is valid */ - if(request->maxAge < 0) - responseHeader->serviceResult = UA_STATUSCODE_BADMAXAGEINVALID; + if(request->maxAge < 0) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADMAXAGEINVALID; + return; + } /* Check if there are too many operations */ if(server->config.maxNodesPerRead != 0 && - request->nodesToReadSize > server->config.maxNodesPerRead) - responseHeader->serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS; - - /* Encode the response header */ - UA_StatusCode retval = - UA_MessageContext_encode(mc, responseHeader, &UA_TYPES[UA_TYPES_RESPONSEHEADER]); - if(retval != UA_STATUSCODE_GOOD) - return retval; - - /* Process nothing if we return an error code for the entire service */ - UA_Int32 arraySize = (UA_Int32)request->nodesToReadSize; - if(responseHeader->serviceResult != UA_STATUSCODE_GOOD) - arraySize = 0; - - /* Process all ReadValueIds */ - retval = UA_MessageContext_encode(mc, &arraySize, &UA_TYPES[UA_TYPES_INT32]); - if(retval != UA_STATUSCODE_GOOD) - return retval; - - for(UA_Int32 i = 0; i < arraySize; i++) { - retval = Operation_Read(server, session, mc, request->timestampsToReturn, - &request->nodesToRead[i]); - if(retval != UA_STATUSCODE_GOOD) - return retval; + request->nodesToReadSize > server->config.maxNodesPerRead) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS; + return; } - /* Don't return any DiagnosticInfo */ - arraySize = -1; - return UA_MessageContext_encode(mc, &arraySize, &UA_TYPES[UA_TYPES_INT32]); + response->responseHeader.serviceResult = + UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)Operation_Read, + request, + &request->nodesToReadSize, &UA_TYPES[UA_TYPES_READVALUEID], + &response->resultsSize, &UA_TYPES[UA_TYPES_DATAVALUE]); } UA_DataValue @@ -31015,7 +32237,7 @@ UA_Server_readWithSession(UA_Server *server, UA_Session *session, UA_DataValue_init(&dv); /* Get the node */ - const UA_Node *node = UA_Nodestore_get(server, &item->nodeId); + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &item->nodeId); if(!node) { dv.hasStatus = true; dv.status = UA_STATUSCODE_BADNODEIDUNKNOWN; @@ -31023,23 +32245,10 @@ UA_Server_readWithSession(UA_Server *server, UA_Session *session, } /* Perform the read operation */ - Read(node, server, session, timestampsToReturn, item, &dv); - - /* Do we have to copy the result before releasing the node? */ - if(dv.hasValue && dv.value.storageType == UA_VARIANT_DATA_NODELETE) { - UA_DataValue dv2; - UA_StatusCode retval = UA_DataValue_copy(&dv, &dv2); - if(retval == UA_STATUSCODE_GOOD) { - dv = dv2; - } else { - UA_DataValue_init(&dv); - dv.hasStatus = true; - dv.status = retval; - } - } + ReadWithNode(node, server, session, timestampsToReturn, item, &dv); /* Release the node and return */ - UA_Nodestore_release(server, node); + UA_Nodestore_releaseNode(server->nsCtx, node); return dv; } @@ -31085,28 +32294,49 @@ __UA_Server_read(UA_Server *server, const UA_NodeId *nodeId, return retval; } +UA_StatusCode +UA_Server_readObjectProperty(UA_Server *server, const UA_NodeId objectId, + const UA_QualifiedName propertyName, + UA_Variant *value) { + UA_RelativePathElement rpe; + UA_RelativePathElement_init(&rpe); + rpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY); + rpe.isInverse = false; + rpe.includeSubtypes = false; + rpe.targetName = propertyName; + + UA_BrowsePath bp; + UA_BrowsePath_init(&bp); + bp.startingNode = objectId; + bp.relativePath.elementsSize = 1; + bp.relativePath.elements = &rpe; + + UA_StatusCode retval; + UA_BrowsePathResult bpr = UA_Server_translateBrowsePathToNodeIds(server, &bp); + if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) { + retval = bpr.statusCode; + UA_BrowsePathResult_deleteMembers(&bpr); + return retval; + } + + retval = UA_Server_readValue(server, bpr.targets[0].targetId.nodeId, value); + + UA_BrowsePathResult_deleteMembers(&bpr); + return retval; +} + /*****************/ /* Type Checking */ /*****************/ -enum type_equivalence { - TYPE_EQUIVALENCE_NONE, - TYPE_EQUIVALENCE_ENUM, - TYPE_EQUIVALENCE_OPAQUE -}; - -static enum type_equivalence +static UA_DataTypeKind typeEquivalence(const UA_DataType *t) { - if(t->membersSize != 1 || !t->members[0].namespaceZero) - return TYPE_EQUIVALENCE_NONE; - if(t->members[0].memberTypeIndex == UA_TYPES_INT32) - return TYPE_EQUIVALENCE_ENUM; - if(t->members[0].memberTypeIndex == UA_TYPES_BYTE && t->members[0].isArray) - return TYPE_EQUIVALENCE_OPAQUE; - return TYPE_EQUIVALENCE_NONE; + UA_DataTypeKind k = (UA_DataTypeKind)t->typeKind; + if(k == UA_DATATYPEKIND_ENUM) + return UA_DATATYPEKIND_INT32; + return k; } -const UA_NodeId subtypeId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}}; static const UA_NodeId enumNodeId = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_ENUMERATION}}; UA_Boolean @@ -31129,12 +32359,12 @@ compatibleDataType(UA_Server *server, const UA_NodeId *dataType, return true; /* Is the value-type a subtype of the required type? */ - if(isNodeInTree(&server->config.nodestore, dataType, constraintDataType, &subtypeId, 1)) + if(isNodeInTree(server->nsCtx, dataType, constraintDataType, &subtypeId, 1)) return true; /* Enum allows Int32 (only) */ if(UA_NodeId_equal(dataType, &UA_TYPES[UA_TYPES_INT32].typeId) && - isNodeInTree(&server->config.nodestore, constraintDataType, &enumNodeId, &subtypeId, 1)) + isNodeInTree(server->nsCtx, constraintDataType, &enumNodeId, &subtypeId, 1)) return true; /* More checks for the data type of real values (variants) */ @@ -31146,7 +32376,7 @@ compatibleDataType(UA_Server *server, const UA_NodeId *dataType, if(dataType->namespaceIndex == 0 && dataType->identifierType == UA_NODEIDTYPE_NUMERIC && dataType->identifier.numeric <= 25 && - isNodeInTree(&server->config.nodestore, constraintDataType, + isNodeInTree(server->nsCtx, constraintDataType, dataType, &subtypeId, 1)) return true; } @@ -31164,7 +32394,8 @@ compatibleValueRankArrayDimensions(UA_Server *server, UA_Session *session, UA_Int32 valueRank, size_t arrayDimensionsSize) { /* ValueRank invalid */ if(valueRank < UA_VALUERANK_SCALAR_OR_ONE_DIMENSION) { - UA_LOG_INFO_SESSION(server->config.logger, session, "The ValueRank is invalid (< -3)"); + UA_LOG_INFO_SESSION(&server->config.logger, session, + "The ValueRank is invalid (< -3)"); return false; } @@ -31174,7 +32405,7 @@ compatibleValueRankArrayDimensions(UA_Server *server, UA_Session *session, /* case 0, UA_VALUERANK_ONE_OR_MORE_DIMENSIONS: the value is an array with one or more dimensions */ if(valueRank <= UA_VALUERANK_ONE_OR_MORE_DIMENSIONS) { if(arrayDimensionsSize > 0) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "No ArrayDimensions can be defined for a ValueRank <= 0"); return false; } @@ -31183,7 +32414,7 @@ compatibleValueRankArrayDimensions(UA_Server *server, UA_Session *session, /* case >= 1, UA_VALUERANK_ONE_DIMENSION: the value is an array with the specified number of dimensions */ if(arrayDimensionsSize != (size_t)valueRank) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "The number of ArrayDimensions is not equal to the (positive) ValueRank"); return false; } @@ -31230,7 +32461,7 @@ compatibleValueRankValue(UA_Int32 valueRank, const UA_Variant *value) { return true; size_t arrayDims = value->arrayDimensionsSize; - if(!arrayDims && !UA_Variant_isScalar(value)) + if(arrayDims == 0 && !UA_Variant_isScalar(value)) arrayDims = 1; /* array but no arraydimensions -> implicit array dimension 1 */ /* We cannot simply use compatibleValueRankArrayDimensions since we can have @@ -31265,9 +32496,10 @@ compatibleArrayDimensions(size_t constraintArrayDimensionsSize, if(testArrayDimensionsSize != constraintArrayDimensionsSize) return false; - /* Dimension lengths must match; zero in the constraint is a wildcard */ + /* Dimension lengths must not be larger than the constraint. Zero in the + * constraint indicates a wildcard. */ for(size_t i = 0; i < constraintArrayDimensionsSize; ++i) { - if(constraintArrayDimensions[i] != testArrayDimensions[i] && + if(constraintArrayDimensions[i] < testArrayDimensions[i] && constraintArrayDimensions[i] != 0) return false; } @@ -31280,11 +32512,12 @@ compatibleValueArrayDimensions(const UA_Variant *value, size_t targetArrayDimens size_t valueArrayDimensionsSize = value->arrayDimensionsSize; UA_UInt32 *valueArrayDimensions = value->arrayDimensions; UA_UInt32 tempArrayDimensions; - if(valueArrayDimensions == 0 && !UA_Variant_isScalar(value)) { + if(!valueArrayDimensions && !UA_Variant_isScalar(value)) { valueArrayDimensionsSize = 1; tempArrayDimensions = (UA_UInt32)value->arrayLength; valueArrayDimensions = &tempArrayDimensions; } + UA_assert(valueArrayDimensionsSize == 0 || valueArrayDimensions != NULL); return compatibleArrayDimensions(targetArrayDimensionsSize, targetArrayDimensions, valueArrayDimensionsSize, valueArrayDimensions); } @@ -31301,18 +32534,18 @@ compatibleValue(UA_Server *server, UA_Session *session, const UA_NodeId *targetD UA_NodeId_equal(targetDataTypeId, &UA_NODEID_NULL)) return true; - /* Workaround: Allow empty value if the target data type is abstract */ - const UA_Node *datatype = UA_Nodestore_get(server, targetDataTypeId); - if(datatype && datatype->nodeClass == UA_NODECLASS_DATATYPE) { - UA_Boolean isAbstract = ((const UA_DataTypeNode*)datatype)->isAbstract; - UA_Nodestore_release(server, datatype); - if(isAbstract) - return true; + /* Allow empty node values since existing information models may have + * variables with no value, e.g. OldValues - ns=0;i=3024. See also + * #1889, https://github.com/open62541/open62541/pull/1889#issuecomment-403506538 */ + if(server->config.relaxEmptyValueConstraint) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Only Variables with data type BaseDataType can contain an " + "empty value. Allow via explicit constraint relaxation."); + return true; } - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, - "Only Variables with data type BaseDataType may contain " - "a null (empty) value"); + UA_LOG_INFO_SESSION(&server->config.logger, session, + "Only Variables with data type BaseDataType can contain an empty value"); return false; } @@ -31358,9 +32591,9 @@ adjustValue(UA_Server *server, UA_Variant *value, /* An enum was sent as an int32, or an opaque type as a bytestring. This * is detected with the typeIndex indicating the "true" datatype. */ - enum type_equivalence te1 = typeEquivalence(targetDataType); - enum type_equivalence te2 = typeEquivalence(value->type); - if(te1 != TYPE_EQUIVALENCE_NONE && te1 == te2) { + UA_DataTypeKind te1 = typeEquivalence(targetDataType); + UA_DataTypeKind te2 = typeEquivalence(value->type); + if(te1 == te2 && te1 <= UA_DATATYPEKIND_ENUM) { value->type = targetDataType; return; } @@ -31379,14 +32612,14 @@ writeArrayDimensionsAttribute(UA_Server *server, UA_Session *session, * when we do the change */ if(node->nodeClass == UA_NODECLASS_VARIABLETYPE && UA_Node_hasSubTypeOrInstances((UA_Node*)node)) { - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "Cannot change a variable type with existing instances"); return UA_STATUSCODE_BADINTERNALERROR; } /* Check that the array dimensions match with the valuerank */ if(!compatibleValueRankArrayDimensions(server, session, node->valueRank, arrayDimensionsSize)) { - UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Cannot write the ArrayDimensions. The ValueRank does not match."); return UA_STATUSCODE_BADTYPEMISMATCH; } @@ -31396,7 +32629,7 @@ writeArrayDimensionsAttribute(UA_Server *server, UA_Session *session, if(type->arrayDimensions && !compatibleArrayDimensions(type->arrayDimensionsSize, type->arrayDimensions, arrayDimensionsSize, arrayDimensions)) { - UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Array dimensions in the variable type do not match"); return UA_STATUSCODE_BADTYPEMISMATCH; } @@ -31412,7 +32645,7 @@ writeArrayDimensionsAttribute(UA_Server *server, UA_Session *session, retval = UA_STATUSCODE_BADTYPEMISMATCH; UA_DataValue_deleteMembers(&value); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Array dimensions in the current value do not match"); return retval; } @@ -31509,7 +32742,7 @@ writeDataTypeAttribute(UA_Server *server, UA_Session *session, retval = UA_STATUSCODE_BADTYPEMISMATCH; UA_DataValue_deleteMembers(&value); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "The current value does not match the new data type"); return retval; } @@ -31606,21 +32839,15 @@ writeValueAttribute(UA_Server *server, UA_Session *session, * uses extension objects to write variable values. If value is an * extension object we check if the current node value is also an * extension object. */ - UA_Boolean compatible; + const UA_NodeId nodeDataType = UA_NODEID_NUMERIC(0, UA_NS0ID_STRUCTURE); + const UA_NodeId *nodeDataTypePtr = &node->dataType; if(value->value.type->typeId.identifierType == UA_NODEIDTYPE_NUMERIC && - value->value.type->typeId.identifier.numeric == UA_NS0ID_STRUCTURE) { - const UA_NodeId nodeDataType = UA_NODEID_NUMERIC(0, UA_NS0ID_STRUCTURE); - compatible = compatibleValue(server, session, &nodeDataType, node->valueRank, - node->arrayDimensionsSize, node->arrayDimensions, - &adjustedValue.value, rangeptr); - } else { - compatible = compatibleValue(server, session, &node->dataType, node->valueRank, - node->arrayDimensionsSize, node->arrayDimensions, - &adjustedValue.value, rangeptr); - } - + value->value.type->typeId.identifier.numeric == UA_NS0ID_STRUCTURE) + nodeDataTypePtr = &nodeDataType; - if(!compatible) { + if(!compatibleValue(server, session, nodeDataTypePtr, node->valueRank, + node->arrayDimensionsSize, node->arrayDimensions, + &adjustedValue.value, rangeptr)) { if(rangeptr) UA_free(range.dimensions); return UA_STATUSCODE_BADTYPEMISMATCH; @@ -31646,6 +32873,15 @@ writeValueAttribute(UA_Server *server, UA_Session *session, else retval = writeValueAttributeWithRange(node, &adjustedValue, rangeptr); +#ifdef UA_ENABLE_HISTORIZING + /* node is a UA_VariableNode*, but it may also point to a UA_VariableTypeNode */ + /* UA_VariableTypeNode doesn't have the historizing attribute */ + if(retval == UA_STATUSCODE_GOOD && node->nodeClass == UA_NODECLASS_VARIABLE && + server->config.historyDatabase.setValue) + server->config.historyDatabase.setValue(server, server->config.historyDatabase.context, + &session->sessionId, session->sessionHandle, + &node->nodeId, node->historizing, &adjustedValue); +#endif /* Callback after writing */ if(retval == UA_STATUSCODE_GOOD && node->value.data.callback.onWrite) node->value.data.callback.onWrite(server, &session->sessionId, @@ -31800,7 +33036,11 @@ copyAttributeIntoNode(UA_Server *server, UA_Session *session, CHECK_NODECLASS_WRITE(UA_NODECLASS_VIEW | UA_NODECLASS_OBJECT); CHECK_USERWRITEMASK(UA_WRITEMASK_EVENTNOTIFIER); CHECK_DATATYPE_SCALAR(BYTE); - ((UA_ViewNode*)node)->eventNotifier = *(const UA_Byte*)value; + if(node->nodeClass == UA_NODECLASS_VIEW) { + ((UA_ViewNode*)node)->eventNotifier = *(const UA_Byte*)value; + } else { + ((UA_ObjectNode*)node)->eventNotifier = *(const UA_Byte*)value; + } break; case UA_ATTRIBUTEID_VALUE: CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE); @@ -31831,7 +33071,7 @@ copyAttributeIntoNode(UA_Server *server, UA_Session *session, GET_NODETYPE retval = writeDataTypeAttribute(server, session, (UA_VariableNode*)node, type, (const UA_NodeId*)value); - UA_Nodestore_release(server, (const UA_Node*)type); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)type); break; case UA_ATTRIBUTEID_VALUERANK: CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE); @@ -31840,7 +33080,7 @@ copyAttributeIntoNode(UA_Server *server, UA_Session *session, GET_NODETYPE retval = writeValueRankAttribute(server, session, (UA_VariableNode*)node, type, *(const UA_Int32*)value); - UA_Nodestore_release(server, (const UA_Node*)type); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)type); break; case UA_ATTRIBUTEID_ARRAYDIMENSIONS: CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE); @@ -31850,7 +33090,7 @@ copyAttributeIntoNode(UA_Server *server, UA_Session *session, retval = writeArrayDimensionsAttribute(server, session, (UA_VariableNode*)node, type, wvalue->value.value.arrayLength, (UA_UInt32 *)wvalue->value.value.data); - UA_Nodestore_release(server, (const UA_Node*)type); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)type); break; case UA_ATTRIBUTEID_ACCESSLEVEL: CHECK_NODECLASS_WRITE(UA_NODECLASS_VARIABLE); @@ -31881,7 +33121,7 @@ copyAttributeIntoNode(UA_Server *server, UA_Session *session, break; } if(retval != UA_STATUSCODE_GOOD) - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "WriteRequest returned status code %s", UA_StatusCode_name(retval)); return retval; @@ -31898,7 +33138,7 @@ void Service_Write(UA_Server *server, UA_Session *session, const UA_WriteRequest *request, UA_WriteResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing WriteRequest"); if(server->config.maxNodesPerWrite != 0 && @@ -31914,13 +33154,20 @@ Service_Write(UA_Server *server, UA_Session *session, } UA_StatusCode +UA_Server_writeWithSession(UA_Server *server, UA_Session *session, + const UA_WriteValue *value) { + return UA_Server_editNode(server, session, &value->nodeId, + (UA_EditNodeCallback)copyAttributeIntoNode, + /* casting away const qualifier because callback uses const anyway */ + (UA_WriteValue *)(uintptr_t)value); +} + +UA_StatusCode UA_Server_write(UA_Server *server, const UA_WriteValue *value) { - UA_StatusCode retval = - UA_Server_editNode(server, &server->adminSession, &value->nodeId, - (UA_EditNodeCallback)copyAttributeIntoNode, - /* casting away const qualifier because callback uses const anyway */ - (UA_WriteValue *)(uintptr_t)value); - return retval; + return UA_Server_editNode(server, &server->adminSession, &value->nodeId, + (UA_EditNodeCallback)copyAttributeIntoNode, + /* casting away const qualifier because callback uses const anyway */ + (UA_WriteValue *)(uintptr_t)value); } /* Convenience function to be wrapped into inline functions */ @@ -31944,13 +33191,188 @@ __UA_Server_write(UA_Server *server, const UA_NodeId *nodeId, return UA_Server_write(server, &wvalue); } +#ifdef UA_ENABLE_HISTORIZING +void +Service_HistoryRead(UA_Server *server, UA_Session *session, + const UA_HistoryReadRequest *request, + UA_HistoryReadResponse *response) { + if(request->historyReadDetails.encoding != UA_EXTENSIONOBJECT_DECODED) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTSUPPORTED; + return; + } + + if(request->historyReadDetails.content.decoded.type != &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]) { + /* TODO handle more request->historyReadDetails.content.decoded.type types */ + response->responseHeader.serviceResult = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED; + return; + } + + /* History read with ReadRawModifiedDetails */ + UA_ReadRawModifiedDetails * details = (UA_ReadRawModifiedDetails*) + request->historyReadDetails.content.decoded.data; + if(details->isReadModified) { + // TODO add server->config.historyReadService.read_modified + response->responseHeader.serviceResult = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED; + return; + } + + /* Something to do? */ + if(request->nodesToReadSize == 0) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO; + return; + } + + /* Check if there are too many operations */ + if(server->config.maxNodesPerRead != 0 && + request->nodesToReadSize > server->config.maxNodesPerRead) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYOPERATIONS; + return; + } + + /* The history database is not configured */ + if(!server->config.historyDatabase.readRaw) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED; + return; + } + + /* Allocate a temporary array to forward the result pointers to the + * backend */ + UA_HistoryData ** historyData = (UA_HistoryData **) + UA_calloc(request->nodesToReadSize, sizeof(UA_HistoryData*)); + if(!historyData) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; + return; + } + + /* Allocate the results array */ + response->results = (UA_HistoryReadResult*)UA_Array_new(request->nodesToReadSize, + &UA_TYPES[UA_TYPES_HISTORYREADRESULT]); + if(!response->results) { + UA_free(historyData); + response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; + return; + } + response->resultsSize = request->nodesToReadSize; + + for(size_t i = 0; i < response->resultsSize; ++i) { + UA_HistoryData * data = UA_HistoryData_new(); + response->results[i].historyData.encoding = UA_EXTENSIONOBJECT_DECODED; + response->results[i].historyData.content.decoded.type = &UA_TYPES[UA_TYPES_HISTORYDATA]; + response->results[i].historyData.content.decoded.data = data; + historyData[i] = data; + } + server->config.historyDatabase.readRaw(server, server->config.historyDatabase.context, + &session->sessionId, session->sessionHandle, + &request->requestHeader, details, + request->timestampsToReturn, + request->releaseContinuationPoints, + request->nodesToReadSize, request->nodesToRead, + response, historyData); + UA_free(historyData); +} + +void +Service_HistoryUpdate(UA_Server *server, UA_Session *session, + const UA_HistoryUpdateRequest *request, + UA_HistoryUpdateResponse *response) { + response->resultsSize = request->historyUpdateDetailsSize; + response->results = (UA_HistoryUpdateResult*)UA_Array_new(response->resultsSize, &UA_TYPES[UA_TYPES_HISTORYUPDATERESULT]); + if (!response->results) { + response->resultsSize = 0; + response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; + return; + } + for (size_t i = 0; i < request->historyUpdateDetailsSize; ++i) { + UA_HistoryUpdateResult_init(&response->results[i]); + if(request->historyUpdateDetails[i].encoding != UA_EXTENSIONOBJECT_DECODED) { + response->results[i].statusCode = UA_STATUSCODE_BADNOTSUPPORTED; + continue; + } + if (request->historyUpdateDetails[i].content.decoded.type + == &UA_TYPES[UA_TYPES_UPDATEDATADETAILS]) { + if (server->config.historyDatabase.updateData) { + server->config.historyDatabase.updateData(server, + server->config.historyDatabase.context, + &session->sessionId, session->sessionHandle, + &request->requestHeader, + (UA_UpdateDataDetails*)request->historyUpdateDetails[i].content.decoded.data, + &response->results[i]); + } else { + response->results[i].statusCode = UA_STATUSCODE_BADNOTSUPPORTED; + } + continue; + } else + if (request->historyUpdateDetails[i].content.decoded.type + == &UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS]) { + if (server->config.historyDatabase.deleteRawModified) { + server->config.historyDatabase.deleteRawModified(server, + server->config.historyDatabase.context, + &session->sessionId, session->sessionHandle, + &request->requestHeader, + (UA_DeleteRawModifiedDetails*)request->historyUpdateDetails[i].content.decoded.data, + &response->results[i]); + } else { + response->results[i].statusCode = UA_STATUSCODE_BADNOTSUPPORTED; + } + continue; + } else { + response->results[i].statusCode = UA_STATUSCODE_BADNOTSUPPORTED; + continue; + } + } + response->responseHeader.serviceResult = UA_STATUSCODE_GOOD; +} + +#endif + +UA_StatusCode UA_EXPORT +UA_Server_writeObjectProperty(UA_Server *server, const UA_NodeId objectId, + const UA_QualifiedName propertyName, + const UA_Variant value) { + UA_RelativePathElement rpe; + UA_RelativePathElement_init(&rpe); + rpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY); + rpe.isInverse = false; + rpe.includeSubtypes = false; + rpe.targetName = propertyName; + + UA_BrowsePath bp; + UA_BrowsePath_init(&bp); + bp.startingNode = objectId; + bp.relativePath.elementsSize = 1; + bp.relativePath.elements = &rpe; + + UA_StatusCode retval; + UA_BrowsePathResult bpr = UA_Server_translateBrowsePathToNodeIds(server, &bp); + if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) { + retval = bpr.statusCode; + UA_BrowsePathResult_deleteMembers(&bpr); + return retval; + } + + retval = UA_Server_writeValue(server, bpr.targets[0].targetId.nodeId, value); + + UA_BrowsePathResult_deleteMembers(&bpr); + return retval; +} + +UA_StatusCode UA_EXPORT +UA_Server_writeObjectProperty_scalar(UA_Server *server, const UA_NodeId objectId, + const UA_QualifiedName propertyName, + const void *value, const UA_DataType *type) { + UA_Variant var; + UA_Variant_init(&var); + UA_Variant_setScalar(&var, (void*)(uintptr_t)value, type); + return UA_Server_writeObjectProperty(server, objectId, propertyName, var); +} + /*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_services_discovery.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2016 (c) Sten Grüner * Copyright 2014, 2017 (c) Florian Palm * Copyright 2016 (c) Oleksiy Vasylyev @@ -31960,36 +33382,33 @@ __UA_Server_write(UA_Server *server, const UA_NodeId *nodeId, */ -#ifdef _WIN32 -# ifndef UNDER_CE -# include <io.h> //access -# define access _access -# endif -#else -# include <unistd.h> //access -#endif - #ifdef UA_ENABLE_DISCOVERY + static UA_StatusCode setApplicationDescriptionFromRegisteredServer(const UA_FindServersRequest *request, UA_ApplicationDescription *target, const UA_RegisteredServer *registeredServer) { - UA_StatusCode retval = UA_STATUSCODE_GOOD; - UA_ApplicationDescription_init(target); - retval |= UA_String_copy(®isteredServer->serverUri, &target->applicationUri); - retval |= UA_String_copy(®isteredServer->productUri, &target->productUri); + UA_StatusCode retval = UA_String_copy(®isteredServer->serverUri, &target->applicationUri); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = UA_String_copy(®isteredServer->productUri, &target->productUri); + if(retval != UA_STATUSCODE_GOOD) + return retval; // if the client requests a specific locale, select the corresponding server name if(request->localeIdsSize) { - UA_Boolean appNameFound = UA_FALSE; + UA_Boolean appNameFound = false; for(size_t i =0; i<request->localeIdsSize && !appNameFound; i++) { for(size_t j =0; j<registeredServer->serverNamesSize; j++) { if(UA_String_equal(&request->localeIds[i], ®isteredServer->serverNames[j].locale)) { - retval |= UA_LocalizedText_copy(®isteredServer->serverNames[j], - &target->applicationName); - appNameFound = UA_TRUE; + retval = UA_LocalizedText_copy(®isteredServer->serverNames[j], + &target->applicationName); + if(retval != UA_STATUSCODE_GOOD) + return retval; + appNameFound = true; break; } } @@ -31997,16 +33416,23 @@ setApplicationDescriptionFromRegisteredServer(const UA_FindServersRequest *reque // server does not have the requested local, therefore we can select the // most suitable one - if(!appNameFound && registeredServer->serverNamesSize) - retval |= UA_LocalizedText_copy(®isteredServer->serverNames[0], - &target->applicationName); + if(!appNameFound && registeredServer->serverNamesSize) { + retval = UA_LocalizedText_copy(®isteredServer->serverNames[0], + &target->applicationName); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } } else if(registeredServer->serverNamesSize) { // just take the first name - retval |= UA_LocalizedText_copy(®isteredServer->serverNames[0], &target->applicationName); + retval = UA_LocalizedText_copy(®isteredServer->serverNames[0], &target->applicationName); + if(retval != UA_STATUSCODE_GOOD) + return retval; } target->applicationType = registeredServer->serverType; - retval |= UA_String_copy(®isteredServer->gatewayServerUri, &target->gatewayServerUri); + retval = UA_String_copy(®isteredServer->gatewayServerUri, &target->gatewayServerUri); + if(retval != UA_STATUSCODE_GOOD) + return retval; // TODO where do we get the discoveryProfileUri for application data? target->discoveryUrlsSize = registeredServer->discoveryUrlsSize; @@ -32015,8 +33441,11 @@ setApplicationDescriptionFromRegisteredServer(const UA_FindServersRequest *reque target->discoveryUrls = (UA_String *)UA_malloc(duSize); if(!target->discoveryUrls) return UA_STATUSCODE_BADOUTOFMEMORY; - for(size_t i = 0; i<registeredServer->discoveryUrlsSize; i++) - retval |= UA_String_copy(®isteredServer->discoveryUrls[i], &target->discoveryUrls[i]); + for(size_t i = 0; i < registeredServer->discoveryUrlsSize; i++) { + retval = UA_String_copy(®isteredServer->discoveryUrls[i], &target->discoveryUrls[i]); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } } return retval; @@ -32026,23 +33455,15 @@ setApplicationDescriptionFromRegisteredServer(const UA_FindServersRequest *reque static UA_StatusCode setApplicationDescriptionFromServer(UA_ApplicationDescription *target, const UA_Server *server) { /* Copy ApplicationDescription from the config */ - - UA_StatusCode result = UA_ApplicationDescription_copy(&server->config.applicationDescription, - target); - if(result != UA_STATUSCODE_GOOD) { + UA_StatusCode result = UA_ApplicationDescription_copy(&server->config.applicationDescription, target); + if(result != UA_STATUSCODE_GOOD) return result; - } - // UaExpert does not list DiscoveryServer, thus set it to Server - // See http://forum.unified-automation.com/topic1987.html - if(target->applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER) - target->applicationType = UA_APPLICATIONTYPE_SERVER; /* add the discoveryUrls from the networklayers */ size_t discSize = sizeof(UA_String) * (target->discoveryUrlsSize + server->config.networkLayersSize); UA_String* disc = (UA_String *)UA_realloc(target->discoveryUrls, discSize); - if(!disc) { + if(!disc) return UA_STATUSCODE_BADOUTOFMEMORY; - } size_t existing = target->discoveryUrlsSize; target->discoveryUrls = disc; target->discoveryUrlsSize += server->config.networkLayersSize; @@ -32058,153 +33479,109 @@ setApplicationDescriptionFromServer(UA_ApplicationDescription *target, const UA_ void Service_FindServers(UA_Server *server, UA_Session *session, const UA_FindServersRequest *request, UA_FindServersResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, - "Processing FindServersRequest"); - - size_t foundServersSize = 0; - UA_ApplicationDescription *foundServers = NULL; - - UA_Boolean addSelf = UA_FALSE; - // temporarily store all the pointers which we found to avoid reiterating - // through the list - UA_RegisteredServer **foundServerFilteredPointer = NULL; + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing FindServersRequest"); -#ifdef UA_ENABLE_DISCOVERY - // check if client only requested a specific set of servers - if(request->serverUrisSize) { - size_t fsfpSize = sizeof(UA_RegisteredServer*) * server->registeredServersSize; - foundServerFilteredPointer = (UA_RegisteredServer **)UA_malloc(fsfpSize); - if(!foundServerFilteredPointer) { - response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; - return; - } - - for(size_t i = 0; i < request->serverUrisSize; i++) { - if(!addSelf && UA_String_equal(&request->serverUris[i], - &server->config.applicationDescription.applicationUri)) { - addSelf = UA_TRUE; - } else { - registeredServer_list_entry* current; - LIST_FOREACH(current, &server->registeredServers, pointers) { - if(UA_String_equal(¤t->registeredServer.serverUri, &request->serverUris[i])) { - // check if entry already in list: - UA_Boolean existing = false; - for(size_t j=0; j<foundServersSize; j++) { - if(UA_String_equal(&foundServerFilteredPointer[j]->serverUri, &request->serverUris[i])) { - existing = true; - break; - } - } - if(!existing) - foundServerFilteredPointer[foundServersSize++] = ¤t->registeredServer; - break; - } - } - } - } - - if(addSelf) - foundServersSize++; - - } else { - addSelf = true; - // self + registered servers - foundServersSize = 1 + server->registeredServersSize; - } -#else + /* Return the server itself? */ + UA_Boolean foundSelf = false; if(request->serverUrisSize) { for(size_t i = 0; i < request->serverUrisSize; i++) { if(UA_String_equal(&request->serverUris[i], &server->config.applicationDescription.applicationUri)) { - addSelf = UA_TRUE; - foundServersSize = 1; + foundSelf = true; break; } } } else { - addSelf = UA_TRUE; - foundServersSize = 1; + foundSelf = true; } -#endif - if(foundServersSize) { - size_t fsSize = sizeof(UA_ApplicationDescription) * foundServersSize; - foundServers = (UA_ApplicationDescription *)UA_malloc(fsSize); - if(!foundServers) { - if(foundServerFilteredPointer) - UA_free(foundServerFilteredPointer); - response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; - return; - } +#ifndef UA_ENABLE_DISCOVERY + if(!foundSelf) + return; - if(addSelf) { - response->responseHeader.serviceResult = - setApplicationDescriptionFromServer(&foundServers[0], server); - if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_free(foundServers); - if(foundServerFilteredPointer) - UA_free(foundServerFilteredPointer); - return; - } - } + UA_ApplicationDescription *ad = UA_ApplicationDescription_new(); + if(!ad) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; + return; + } -#ifdef UA_ENABLE_DISCOVERY - size_t currentIndex = 0; - if(addSelf) - currentIndex++; - - // add all the registered servers to the list - - if(foundServerFilteredPointer) { - // use filtered list because client only requested specific uris - // -1 because foundServersSize also includes this self server - size_t iterCount = addSelf ? foundServersSize - 1 : foundServersSize; - for(size_t i = 0; i < iterCount; i++) { - response->responseHeader.serviceResult = - setApplicationDescriptionFromRegisteredServer(request, &foundServers[currentIndex++], - foundServerFilteredPointer[i]); - if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_free(foundServers); - UA_free(foundServerFilteredPointer); - return; + UA_StatusCode retval = setApplicationDescriptionFromServer(ad, server); + if(retval != UA_STATUSCODE_GOOD) { + UA_ApplicationDescription_delete(ad); + response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; + return; + } + + response->servers = ad; + response->serversSize = 1; + return; + +#else + + /* Temporarily store all the pointers which we found to avoid reiterating + * through the list */ + size_t foundServersSize = 0; + UA_STACKARRAY(UA_RegisteredServer*, foundServers, server->discoveryManager.registeredServersSize+1); + + registeredServer_list_entry* current; + LIST_FOREACH(current, &server->discoveryManager.registeredServers, pointers) { + if(request->serverUrisSize) { + /* If client only requested a specific set of servers */ + for(size_t i = 0; i < request->serverUrisSize; i++) { + if(UA_String_equal(¤t->registeredServer.serverUri, &request->serverUris[i])) { + foundServers[foundServersSize] = ¤t->registeredServer; + foundServersSize++; + break; } } - UA_free(foundServerFilteredPointer); - foundServerFilteredPointer = NULL; } else { - registeredServer_list_entry* current; - LIST_FOREACH(current, &server->registeredServers, pointers) { - response->responseHeader.serviceResult = - setApplicationDescriptionFromRegisteredServer(request, &foundServers[currentIndex++], - ¤t->registeredServer); - if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_free(foundServers); - return; - } - } + /* Return all registered servers */ + foundServers[foundServersSize] = ¤t->registeredServer; + foundServersSize++; } -#endif } - if(foundServerFilteredPointer) - UA_free(foundServerFilteredPointer); + size_t allocSize = foundServersSize; + if(foundSelf) + allocSize++; + + /* Nothing to do? */ + if(allocSize == 0) + return; + + /* Allocate memory */ + response->servers = (UA_ApplicationDescription*)UA_Array_new(allocSize, &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]); + if(!response->servers) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; + return; + } + response->serversSize = allocSize; + + /* Copy into the response. TODO: Evaluate return codes */ + size_t pos = 0; + if(foundSelf) { + setApplicationDescriptionFromServer(&response->servers[pos++], server); + } + for(size_t i = 0; i < foundServersSize; i++) { + setApplicationDescriptionFromRegisteredServer(request, &response->servers[pos++], foundServers[i]); + } - response->servers = foundServers; - response->serversSize = foundServersSize; +#endif } -void Service_GetEndpoints(UA_Server *server, UA_Session *session, - const UA_GetEndpointsRequest *request, - UA_GetEndpointsResponse *response) { +void +Service_GetEndpoints(UA_Server *server, UA_Session *session, + const UA_GetEndpointsRequest *request, + UA_GetEndpointsResponse *response) { /* If the client expects to see a specific endpointurl, mirror it back. If not, clone the endpoints with the discovery url of all networklayers. */ const UA_String *endpointUrl = &request->endpointUrl; if(endpointUrl->length > 0) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing GetEndpointsRequest with endpointUrl " UA_PRINTF_STRING_FORMAT, UA_PRINTF_STRING_DATA(*endpointUrl)); } else { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing GetEndpointsRequest with an empty endpointUrl"); } @@ -32221,7 +33598,7 @@ void Service_GetEndpoints(UA_Server *server, UA_Session *session, for(size_t j = 0; j < server->config.endpointsSize; ++j) { for(size_t i = 0; i < request->profileUrisSize; ++i) { if(!UA_String_equal(&request->profileUris[i], - &server->config.endpoints[j].endpointDescription.transportProfileUri)) + &server->config.endpoints[j].transportProfileUri)) continue; relevant_endpoints[j] = true; ++relevant_count; @@ -32253,39 +33630,35 @@ void Service_GetEndpoints(UA_Server *server, UA_Session *session, response->endpointsSize = relevant_count * clone_times; size_t k = 0; - UA_StatusCode retval = UA_STATUSCODE_GOOD; + UA_StatusCode retval; for(size_t i = 0; i < clone_times; ++i) { if(nl_endpointurl) endpointUrl = &server->config.networkLayers[i].discoveryUrl; for(size_t j = 0; j < server->config.endpointsSize; ++j) { if(!relevant_endpoints[j]) continue; - retval |= UA_EndpointDescription_copy(&server->config.endpoints[j].endpointDescription, - &response->endpoints[k]); - retval |= UA_String_copy(endpointUrl, &response->endpoints[k].endpointUrl); + retval = UA_EndpointDescription_copy(&server->config.endpoints[j], + &response->endpoints[k]); + if(retval != UA_STATUSCODE_GOOD) + goto error; + retval = UA_String_copy(endpointUrl, &response->endpoints[k].endpointUrl); + if(retval != UA_STATUSCODE_GOOD) + goto error; ++k; } } - if(retval != UA_STATUSCODE_GOOD) { - response->responseHeader.serviceResult = retval; - UA_Array_delete(response->endpoints, response->endpointsSize, - &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); - response->endpoints = NULL; - response->endpointsSize = 0; - return; - } + return; +error: + response->responseHeader.serviceResult = retval; + UA_Array_delete(response->endpoints, response->endpointsSize, + &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); + response->endpoints = NULL; + response->endpointsSize = 0; } #ifdef UA_ENABLE_DISCOVERY -#ifdef UA_ENABLE_MULTITHREADING -static void -freeEntry(UA_Server *server, void *entry) { - UA_free(entry); -} -#endif - static void process_RegisterServer(UA_Server *server, UA_Session *session, const UA_RequestHeader* requestHeader, @@ -32300,7 +33673,7 @@ process_RegisterServer(UA_Server *server, UA_Session *session, /* Find the server from the request in the registered list */ registeredServer_list_entry* current; registeredServer_list_entry *registeredServer_entry = NULL; - LIST_FOREACH(current, &server->registeredServers, pointers) { + LIST_FOREACH(current, &server->discoveryManager.registeredServers, pointers) { if(UA_String_equal(¤t->registeredServer.serverUri, &requestServer->serverUri)) { registeredServer_entry = current; break; @@ -32352,35 +33725,35 @@ process_RegisterServer(UA_Server *server, UA_Session *session, char* filePath = (char*) UA_malloc(sizeof(char)*requestServer->semaphoreFilePath.length+1); if(!filePath) { - UA_LOG_ERROR_SESSION(server->config.logger, session, - "Cannot allocate memory for semaphore path. Out of memory."); + UA_LOG_ERROR_SESSION(&server->config.logger, session, + "Cannot allocate memory for semaphore path. Out of memory."); responseHeader->serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; return; } memcpy(filePath, requestServer->semaphoreFilePath.data, requestServer->semaphoreFilePath.length ); filePath[requestServer->semaphoreFilePath.length] = '\0'; - if(access( filePath, 0 ) == -1) { + if(!UA_fileExists( filePath )) { responseHeader->serviceResult = UA_STATUSCODE_BADSEMPAHOREFILEMISSING; UA_free(filePath); return; } UA_free(filePath); #else - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_CLIENT, "Ignoring semaphore file path. open62541 not compiled " "with UA_ENABLE_DISCOVERY_SEMAPHORE=ON"); #endif } #ifdef UA_ENABLE_DISCOVERY_MULTICAST - if(server->config.applicationDescription.applicationType == UA_APPLICATIONTYPE_DISCOVERYSERVER) { + if(server->config.discovery.mdnsEnable) { for(size_t i = 0; i < requestServer->discoveryUrlsSize; i++) { /* create TXT if is online and first index, delete TXT if is offline and last index */ UA_Boolean updateTxt = (requestServer->isOnline && i==0) || (!requestServer->isOnline && i==requestServer->discoveryUrlsSize); - UA_Discovery_update_MdnsForDiscoveryUrl(server, mdnsServerName, mdnsConfig, - &requestServer->discoveryUrls[i], - requestServer->isOnline, updateTxt); + UA_Server_updateMdnsForDiscoveryUrl(server, mdnsServerName, mdnsConfig, + &requestServer->discoveryUrls[i], + requestServer->isOnline, updateTxt); } } #endif @@ -32389,25 +33762,28 @@ process_RegisterServer(UA_Server *server, UA_Session *session, // server is shutting down. Remove it from the registered servers list if(!registeredServer_entry) { // server not found, show warning - UA_LOG_WARNING_SESSION(server->config.logger, session, + UA_LOG_WARNING_SESSION(&server->config.logger, session, "Could not unregister server %.*s. Not registered.", (int)requestServer->serverUri.length, requestServer->serverUri.data); responseHeader->serviceResult = UA_STATUSCODE_BADNOTHINGTODO; return; } - if(server->registerServerCallback) - server->registerServerCallback(requestServer, server->registerServerCallbackData); + if(server->discoveryManager.registerServerCallback) + server->discoveryManager. + registerServerCallback(requestServer, + server->discoveryManager.registerServerCallbackData); // server found, remove from list LIST_REMOVE(registeredServer_entry, pointers); UA_RegisteredServer_deleteMembers(®isteredServer_entry->registeredServer); #ifndef UA_ENABLE_MULTITHREADING UA_free(registeredServer_entry); - server->registeredServersSize--; + server->discoveryManager.registeredServersSize--; #else - UA_atomic_subSize(&server->registeredServersSize, 1); - UA_Server_delayedCallback(server, freeEntry, registeredServer_entry); + UA_atomic_subSize(&server->discoveryManager.registeredServersSize, 1); + registeredServer_entry->delayedCleanup.callback = NULL; /* only free the structure */ + UA_WorkQueue_enqueueDelayed(&server->workQueue, ®isteredServer_entry->delayedCleanup); #endif responseHeader->serviceResult = UA_STATUSCODE_GOOD; return; @@ -32416,7 +33792,7 @@ process_RegisterServer(UA_Server *server, UA_Session *session, UA_StatusCode retval = UA_STATUSCODE_GOOD; if(!registeredServer_entry) { // server not yet registered, register it by adding it to the list - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Registering new server: %.*s", + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Registering new server: %.*s", (int)requestServer->serverUri.length, requestServer->serverUri.data); registeredServer_entry = @@ -32426,15 +33802,17 @@ process_RegisterServer(UA_Server *server, UA_Session *session, return; } - LIST_INSERT_HEAD(&server->registeredServers, registeredServer_entry, pointers); + LIST_INSERT_HEAD(&server->discoveryManager.registeredServers, registeredServer_entry, pointers); #ifndef UA_ENABLE_MULTITHREADING - server->registeredServersSize++; + server->discoveryManager.registeredServersSize++; #else - UA_atomic_addSize(&server->registeredServersSize, 1); + UA_atomic_addSize(&server->discoveryManager.registeredServersSize, 1); #endif - if(server->registerServerCallback) - server->registerServerCallback(requestServer, server->registerServerCallbackData); + if(server->discoveryManager.registerServerCallback) + server->discoveryManager. + registerServerCallback(requestServer, + server->discoveryManager.registerServerCallbackData); } else { UA_RegisteredServer_deleteMembers(®isteredServer_entry->registeredServer); } @@ -32448,7 +33826,7 @@ process_RegisterServer(UA_Server *server, UA_Session *session, void Service_RegisterServer(UA_Server *server, UA_Session *session, const UA_RegisterServerRequest *request, UA_RegisterServerResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing RegisterServerRequest"); process_RegisterServer(server, session, &request->requestHeader, &request->server, 0, NULL, &response->responseHeader, 0, NULL, 0, NULL); @@ -32457,7 +33835,7 @@ void Service_RegisterServer(UA_Server *server, UA_Session *session, void Service_RegisterServer2(UA_Server *server, UA_Session *session, const UA_RegisterServer2Request *request, UA_RegisterServer2Response *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing RegisterServer2Request"); process_RegisterServer(server, session, &request->requestHeader, &request->server, request->discoveryConfigurationSize, request->discoveryConfiguration, @@ -32474,12 +33852,12 @@ void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic) { UA_DateTime timedOut = nowMonotonic; // registration is timed out if lastSeen is older than 60 minutes (default // value, can be modified by user). - if(server->config.discoveryCleanupTimeout) - timedOut -= server->config.discoveryCleanupTimeout*UA_DATETIME_SEC; + if(server->config.discovery.cleanupTimeout) + timedOut -= server->config.discovery.cleanupTimeout*UA_DATETIME_SEC; registeredServer_list_entry* current, *temp; - LIST_FOREACH_SAFE(current, &server->registeredServers, pointers, temp) { - UA_Boolean semaphoreDeleted = UA_FALSE; + LIST_FOREACH_SAFE(current, &server->discoveryManager.registeredServers, pointers, temp) { + UA_Boolean semaphoreDeleted = false; #ifdef UA_ENABLE_DISCOVERY_SEMAPHORE if(current->registeredServer.semaphoreFilePath.length) { @@ -32490,25 +33868,19 @@ void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic) { memcpy(filePath, current->registeredServer.semaphoreFilePath.data, current->registeredServer.semaphoreFilePath.length ); filePath[current->registeredServer.semaphoreFilePath.length] = '\0'; -#ifdef UNDER_CE - FILE *fp = fopen(filePath,"rb"); - semaphoreDeleted = (fp==NULL); - if(fp) - fclose(fp); -#else - semaphoreDeleted = access( filePath, 0 ) == -1; -#endif + semaphoreDeleted = UA_fileExists(filePath) == false; UA_free(filePath); } else { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, "Cannot check registration semaphore. Out of memory"); + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Cannot check registration semaphore. Out of memory"); } } #endif - if(semaphoreDeleted || (server->config.discoveryCleanupTimeout && + if(semaphoreDeleted || (server->config.discovery.cleanupTimeout && current->lastSeen < timedOut)) { if(semaphoreDeleted) { - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "Registration of server with URI %.*s is removed because " "the semaphore file '%.*s' was deleted.", (int)current->registeredServer.serverUri.length, @@ -32517,7 +33889,7 @@ void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic) { current->registeredServer.semaphoreFilePath.data); } else { // cppcheck-suppress unreadVariable - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "Registration of server with URI %.*s has timed out and is removed.", (int)current->registeredServer.serverUri.length, current->registeredServer.serverUri.data); @@ -32526,10 +33898,11 @@ void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic) { UA_RegisteredServer_deleteMembers(¤t->registeredServer); #ifndef UA_ENABLE_MULTITHREADING UA_free(current); - server->registeredServersSize--; + server->discoveryManager.registeredServersSize--; #else - UA_atomic_subSize(&server->registeredServersSize, 1); - UA_Server_delayedCallback(server, freeEntry, current); + UA_atomic_subSize(&server->discoveryManager.registeredServersSize, 1); + current->delayedCleanup.callback = NULL; /* Only free the structure */ + UA_WorkQueue_enqueueDelayed(&server->workQueue, ¤t->delayedCleanup); #endif } } @@ -32537,9 +33910,10 @@ void UA_Discovery_cleanupTimedOut(UA_Server *server, UA_DateTime nowMonotonic) { struct PeriodicServerRegisterCallback { UA_UInt64 id; - UA_UInt32 this_interval; - UA_UInt32 default_interval; + UA_Double this_interval; + UA_Double default_interval; UA_Boolean registered; + UA_Client* client; const char* discovery_server_url; }; @@ -32551,7 +33925,7 @@ struct PeriodicServerRegisterCallback { * > errors occurred. The recommended approach would double the period each attempt until reaching the maximum. * * We will do so by using the additional data parameter which holds information - * if the next interval is default or if it is a repeaded call. */ + * if the next interval is default or if it is a repeated call. */ static void periodicServerRegister(UA_Server *server, void *data) { UA_assert(data != NULL); @@ -32565,27 +33939,36 @@ periodicServerRegister(UA_Server *server, void *data) { server_url = cb->discovery_server_url; else server_url = "opc.tcp://localhost:4840"; - - /* Register - You can also use a semaphore file. That file must exist. When the file is - deleted, the server is automatically unregistered. The semaphore file has - to be accessible by the discovery server - - UA_StatusCode retval = UA_Server_register_discovery(server, - "opc.tcp://localhost:4840", "/path/to/some/file"); - */ - UA_StatusCode retval = UA_Server_register_discovery(server, server_url, NULL); - + UA_StatusCode retval = UA_Client_connect_noSession(cb->client, server_url); + if (retval == UA_STATUSCODE_GOOD) { + /* Register + You can also use a semaphore file. That file must exist. When the file is + deleted, the server is automatically unregistered. The semaphore file has + to be accessible by the discovery server + + UA_StatusCode retval = UA_Server_register_discovery(server, + "opc.tcp://localhost:4840", "/path/to/some/file"); + */ + retval = UA_Server_register_discovery(server, cb->client, NULL); + } + if (cb->client->state == UA_CLIENTSTATE_CONNECTED) { + UA_StatusCode retval1 = UA_Client_disconnect(cb->client); + if(retval1 != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Could not disconnect client from register server. StatusCode %s", + UA_StatusCode_name(retval)); + } + } /* Registering failed */ if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Could not register server with discovery server. " "Is the discovery server started? StatusCode %s", UA_StatusCode_name(retval)); /* If the server was previously registered, retry in one second, * else, double the previous interval */ - UA_UInt32 nextInterval = 1000; + UA_Double nextInterval = 1000.0; if(!cb->registered) nextInterval = cb->this_interval * 2; @@ -32599,7 +33982,7 @@ periodicServerRegister(UA_Server *server, void *data) { } /* Registering succeeded */ - UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Server successfully registered. Next periodical register will be in %d seconds", (int)(cb->default_interval/1000)); @@ -32613,25 +33996,30 @@ periodicServerRegister(UA_Server *server, void *data) { UA_StatusCode UA_Server_addPeriodicServerRegisterCallback(UA_Server *server, + struct UA_Client *client, const char* discoveryServerUrl, - UA_UInt32 intervalMs, - UA_UInt32 delayFirstRegisterMs, + UA_Double intervalMs, + UA_Double delayFirstRegisterMs, UA_UInt64 *periodicCallbackId) { /* No valid server URL */ if(!discoveryServerUrl) { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "No discovery server URL provided"); return UA_STATUSCODE_BADINTERNALERROR; } + if (client->connection.state != UA_CONNECTION_CLOSED) + return UA_STATUSCODE_BADINVALIDSTATE; + /* check if we are already registering with the given discovery url and remove the old periodic call */ { periodicServerRegisterCallback_entry *rs, *rs_tmp; - LIST_FOREACH_SAFE(rs, &server->periodicServerRegisterCallbacks, pointers, rs_tmp) { + LIST_FOREACH_SAFE(rs, &server->discoveryManager. + periodicServerRegisterCallbacks, pointers, rs_tmp) { if(strcmp(rs->callback->discovery_server_url, discoveryServerUrl) == 0) { - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "There is already a register callback for '%s' in place. Removing the older one.", discoveryServerUrl); UA_Server_removeRepeatedCallback(server, rs->callback->id); LIST_REMOVE(rs, pointers); @@ -32652,9 +34040,10 @@ UA_Server_addPeriodicServerRegisterCallback(UA_Server *server, /* Start repeating a failed register after 1s, then increase the delay. Set * to 500ms, as the delay is doubled before changing the callback * interval.*/ - cb->this_interval = 500; + cb->this_interval = 500.0; cb->default_interval = intervalMs; cb->registered = false; + cb->client = client; cb->discovery_server_url = discoveryServerUrl; @@ -32664,7 +34053,7 @@ UA_Server_addPeriodicServerRegisterCallback(UA_Server *server, UA_Server_addRepeatedCallback(server, periodicServerRegister, cb, delayFirstRegisterMs, &cb->id); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Could not create periodic job for server register. " "StatusCode %s", UA_StatusCode_name(retval)); UA_free(cb); @@ -32681,7 +34070,7 @@ UA_Server_addPeriodicServerRegisterCallback(UA_Server *server, return UA_STATUSCODE_BADOUTOFMEMORY; } newEntry->callback = cb; - LIST_INSERT_HEAD(&server->periodicServerRegisterCallbacks, newEntry, pointers); + LIST_INSERT_HEAD(&server->discoveryManager.periodicServerRegisterCallbacks, newEntry, pointers); #endif if(periodicCallbackId) @@ -32693,8 +34082,8 @@ void UA_Server_setRegisterServerCallback(UA_Server *server, UA_Server_registerServerCallback cb, void* data) { - server->registerServerCallback = cb; - server->registerServerCallbackData = data; + server->discoveryManager.registerServerCallback = cb; + server->discoveryManager.registerServerCallbackData = data; } #endif /* UA_ENABLE_DISCOVERY */ @@ -32705,26 +34094,22 @@ UA_Server_setRegisterServerCallback(UA_Server *server, * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2016-2017 (c) Florian Palm * Copyright 2015 (c) Chris Iatrou * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015-2016 (c) Oleksiy Vasylyev * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH * Copyright 2017 (c) Mattias Bornhager * Copyright 2017 (c) Henrik Norrman * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2018 (c) Fabian Arndt, Root-Core */ #ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ -#define UA_BOUNDEDVALUE_SETWBOUNDS(BOUNDS, SRC, DST) { \ - if(SRC > BOUNDS.max) DST = BOUNDS.max; \ - else if(SRC < BOUNDS.min) DST = BOUNDS.min; \ - else DST = SRC; \ - } - static UA_StatusCode setSubscriptionSettings(UA_Server *server, UA_Subscription *subscription, UA_Double requestedPublishingInterval, @@ -32732,16 +34117,9 @@ setSubscriptionSettings(UA_Server *server, UA_Subscription *subscription, UA_UInt32 requestedMaxKeepAliveCount, UA_UInt32 maxNotificationsPerPublish, UA_Byte priority) { /* deregister the callback if required */ - UA_StatusCode retval = Subscription_unregisterPublishCallback(server, subscription); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_DEBUG_SESSION(server->config.logger, subscription->session, - "Subscription %u | Could not unregister publish callback with error code %s", - subscription->subscriptionId, UA_StatusCode_name(retval)); - return retval; - } + Subscription_unregisterPublishCallback(server, subscription); /* re-parameterize the subscription */ - subscription->publishingInterval = requestedPublishingInterval; UA_BOUNDEDVALUE_SETWBOUNDS(server->config.publishingIntervalLimits, requestedPublishingInterval, subscription->publishingInterval); /* check for nan*/ @@ -32759,14 +34137,13 @@ setSubscriptionSettings(UA_Server *server, UA_Subscription *subscription, subscription->notificationsPerPublish = server->config.maxNotificationsPerPublish; subscription->priority = priority; - retval = Subscription_registerPublishCallback(server, subscription); + UA_StatusCode retval = Subscription_registerPublishCallback(server, subscription); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_DEBUG_SESSION(server->config.logger, subscription->session, + UA_LOG_DEBUG_SESSION(&server->config.logger, subscription->session, "Subscription %u | Could not register publish callback with error code %s", subscription->subscriptionId, UA_StatusCode_name(retval)); - return retval; } - return UA_STATUSCODE_GOOD; + return retval; } void @@ -32774,8 +34151,10 @@ Service_CreateSubscription(UA_Server *server, UA_Session *session, const UA_CreateSubscriptionRequest *request, UA_CreateSubscriptionResponse *response) { /* Check limits for the number of subscriptions */ - if((server->config.maxSubscriptionsPerSession != 0) && - (session->numSubscriptions >= server->config.maxSubscriptionsPerSession)) { + if(((server->config.maxSubscriptions != 0) && + (server->numSubscriptions >= server->config.maxSubscriptions)) || + ((server->config.maxSubscriptionsPerSession != 0) && + (session->numSubscriptions >= server->config.maxSubscriptionsPerSession))) { response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYSUBSCRIPTIONS; return; } @@ -32783,13 +34162,13 @@ Service_CreateSubscription(UA_Server *server, UA_Session *session, /* Create the subscription */ UA_Subscription *newSubscription = UA_Subscription_new(session, response->subscriptionId); if(!newSubscription) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing CreateSubscriptionRequest failed"); response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; return; } - UA_Session_addSubscription(session, newSubscription); /* Also assigns the subscription id */ + UA_Session_addSubscription(server, session, newSubscription); /* Also assigns the subscription id */ /* Set the subscription parameters */ newSubscription->publishingEnabled = request->publishingEnabled; @@ -32810,8 +34189,8 @@ Service_CreateSubscription(UA_Server *server, UA_Session *session, response->revisedLifetimeCount = newSubscription->lifeTimeCount; response->revisedMaxKeepAliveCount = newSubscription->maxKeepAliveCount; - UA_LOG_INFO_SESSION(server->config.logger, session, "Subscription %u | " - "Created the Subscription with a publishing interval of %f ms", + UA_LOG_INFO_SESSION(&server->config.logger, session, "Subscription %u | " + "Created the Subscription with a publishing interval of %.2f ms", response->subscriptionId, newSubscription->publishingInterval); } @@ -32819,7 +34198,7 @@ void Service_ModifySubscription(UA_Server *server, UA_Session *session, const UA_ModifySubscriptionRequest *request, UA_ModifySubscriptionResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing ModifySubscriptionRequest"); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing ModifySubscriptionRequest"); UA_Subscription *sub = UA_Session_getSubscriptionById(session, request->subscriptionId); if(!sub) { @@ -32844,7 +34223,7 @@ Service_ModifySubscription(UA_Server *server, UA_Session *session, static void Operation_SetPublishingMode(UA_Server *Server, UA_Session *session, - UA_Boolean *publishingEnabled, UA_UInt32 *subscriptionId, + const UA_Boolean *publishingEnabled, const UA_UInt32 *subscriptionId, UA_StatusCode *result) { UA_Subscription *sub = UA_Session_getSubscriptionById(session, *subscriptionId); if(!sub) { @@ -32860,7 +34239,7 @@ void Service_SetPublishingMode(UA_Server *server, UA_Session *session, const UA_SetPublishingModeRequest *request, UA_SetPublishingModeResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing SetPublishingModeRequest"); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing SetPublishingModeRequest"); UA_Boolean publishingEnabled = request->publishingEnabled; /* request is const */ response->responseHeader.serviceResult = UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)Operation_SetPublishingMode, @@ -32869,64 +34248,318 @@ Service_SetPublishingMode(UA_Server *server, UA_Session *session, &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); } +/* TODO: Unify with senderror in ua_server_binary.c */ +static void +subscriptionSendError(UA_SecureChannel *channel, UA_UInt32 requestHandle, + UA_UInt32 requestId, UA_StatusCode error) { + UA_PublishResponse err_response; + UA_PublishResponse_init(&err_response); + err_response.responseHeader.requestHandle = requestHandle; + err_response.responseHeader.timestamp = UA_DateTime_now(); + err_response.responseHeader.serviceResult = error; + UA_SecureChannel_sendSymmetricMessage(channel, requestId, UA_MESSAGETYPE_MSG, + &err_response, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); +} + +void +Service_Publish(UA_Server *server, UA_Session *session, + const UA_PublishRequest *request, UA_UInt32 requestId) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing PublishRequest"); + + /* Return an error if the session has no subscription */ + if(LIST_EMPTY(&session->serverSubscriptions)) { + subscriptionSendError(session->header.channel, request->requestHeader.requestHandle, + requestId, UA_STATUSCODE_BADNOSUBSCRIPTION); + return; + } + + /* Handle too many subscriptions to free resources before trying to allocate + * resources for the new publish request. If the limit has been reached the + * oldest publish request shall be responded */ + if((server->config.maxPublishReqPerSession != 0) && + (session->numPublishReq >= server->config.maxPublishReqPerSession)) { + if(!UA_Subscription_reachedPublishReqLimit(server, session)) { + subscriptionSendError(session->header.channel, requestId, + request->requestHeader.requestHandle, + UA_STATUSCODE_BADINTERNALERROR); + return; + } + } + + /* Allocate the response to store it in the retransmission queue */ + UA_PublishResponseEntry *entry = (UA_PublishResponseEntry *) + UA_malloc(sizeof(UA_PublishResponseEntry)); + if(!entry) { + subscriptionSendError(session->header.channel, requestId, + request->requestHeader.requestHandle, + UA_STATUSCODE_BADOUTOFMEMORY); + return; + } + + /* Prepare the response */ + entry->requestId = requestId; + UA_PublishResponse *response = &entry->response; + UA_PublishResponse_init(response); + response->responseHeader.requestHandle = request->requestHeader.requestHandle; + + /* Allocate the results array to acknowledge the acknowledge */ + if(request->subscriptionAcknowledgementsSize > 0) { + response->results = (UA_StatusCode *) + UA_Array_new(request->subscriptionAcknowledgementsSize, + &UA_TYPES[UA_TYPES_STATUSCODE]); + if(!response->results) { + UA_free(entry); + subscriptionSendError(session->header.channel, requestId, + request->requestHeader.requestHandle, + UA_STATUSCODE_BADOUTOFMEMORY); + return; + } + response->resultsSize = request->subscriptionAcknowledgementsSize; + } + + /* Delete Acknowledged Subscription Messages */ + for(size_t i = 0; i < request->subscriptionAcknowledgementsSize; ++i) { + UA_SubscriptionAcknowledgement *ack = &request->subscriptionAcknowledgements[i]; + UA_Subscription *sub = UA_Session_getSubscriptionById(session, ack->subscriptionId); + if(!sub) { + response->results[i] = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID; + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Cannot process acknowledgements subscription %u", + ack->subscriptionId); + continue; + } + /* Remove the acked transmission from the retransmission queue */ + response->results[i] = UA_Subscription_removeRetransmissionMessage(sub, ack->sequenceNumber); + } + + /* Queue the publish response. It will be dequeued in a repeated publish + * callback. This can also be triggered right now for a late + * subscription. */ + UA_Session_queuePublishReq(session, entry, false); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Queued a publication message"); + + /* If there are late subscriptions, the new publish request is used to + * answer them immediately. However, a single subscription that generates + * many notifications must not "starve" other late subscriptions. Therefore + * we keep track of the last subscription that got preferential treatment. + * We start searching for late subscriptions **after** the last one. */ + + UA_Subscription *immediate = NULL; + if(session->lastSeenSubscriptionId > 0) { + LIST_FOREACH(immediate, &session->serverSubscriptions, listEntry) { + if(immediate->subscriptionId == session->lastSeenSubscriptionId) { + immediate = LIST_NEXT(immediate, listEntry); + break; + } + } + } + + /* If no entry was found, start at the beginning and don't restart */ + UA_Boolean found = false; + if(!immediate) + immediate = LIST_FIRST(&session->serverSubscriptions); + else + found = true; + + repeat: + while(immediate) { + if(immediate->state == UA_SUBSCRIPTIONSTATE_LATE) { + session->lastSeenSubscriptionId = immediate->subscriptionId; + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Subscription %u | Response on a late subscription", + immediate->subscriptionId); + UA_Subscription_publish(server, immediate); + return; + } + immediate = LIST_NEXT(immediate, listEntry); + } + + /* Restart at the beginning of the list */ + if(found) { + immediate = LIST_FIRST(&session->serverSubscriptions); + found = false; + goto repeat; + } + + /* No late subscription this time */ + session->lastSeenSubscriptionId = 0; +} + +static void +Operation_DeleteSubscription(UA_Server *server, UA_Session *session, void *_, + const UA_UInt32 *subscriptionId, UA_StatusCode *result) { + *result = UA_Session_deleteSubscription(server, session, *subscriptionId); + if(*result == UA_STATUSCODE_GOOD) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Subscription %u | Subscription deleted", + *subscriptionId); + } else { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Deleting Subscription with Id %u failed with error code %s", + *subscriptionId, UA_StatusCode_name(*result)); + } +} + +void +Service_DeleteSubscriptions(UA_Server *server, UA_Session *session, + const UA_DeleteSubscriptionsRequest *request, + UA_DeleteSubscriptionsResponse *response) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Processing DeleteSubscriptionsRequest"); + + response->responseHeader.serviceResult = + UA_Server_processServiceOperations(server, session, + (UA_ServiceOperation)Operation_DeleteSubscription, NULL, + &request->subscriptionIdsSize, &UA_TYPES[UA_TYPES_UINT32], + &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); + + /* The session has at least one subscription */ + if(LIST_FIRST(&session->serverSubscriptions)) + return; + + /* Send remaining publish responses if the last subscription was removed */ + UA_Subscription_answerPublishRequestsNoSubscription(server, session); +} + +void +Service_Republish(UA_Server *server, UA_Session *session, + const UA_RepublishRequest *request, + UA_RepublishResponse *response) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Processing RepublishRequest"); + + /* Get the subscription */ + UA_Subscription *sub = UA_Session_getSubscriptionById(session, request->subscriptionId); + if(!sub) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID; + return; + } + + /* Reset the subscription lifetime */ + sub->currentLifetimeCount = 0; + + /* Find the notification in the retransmission queue */ + UA_NotificationMessageEntry *entry; + TAILQ_FOREACH(entry, &sub->retransmissionQueue, listEntry) { + if(entry->message.sequenceNumber == request->retransmitSequenceNumber) + break; + } + if(!entry) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADMESSAGENOTAVAILABLE; + return; + } + + response->responseHeader.serviceResult = + UA_NotificationMessage_copy(&entry->message, &response->notificationMessage); +} + +#endif /* UA_ENABLE_SUBSCRIPTIONS */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_services_monitoreditem.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2016-2017 (c) Florian Palm + * Copyright 2015 (c) Chris Iatrou + * Copyright 2015-2016 (c) Sten Grüner + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH + * Copyright 2017 (c) Mattias Bornhager + * Copyright 2017 (c) Henrik Norrman + * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2018 (c) Fabian Arndt, Root-Core + */ + + +#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ + static UA_StatusCode setMonitoredItemSettings(UA_Server *server, UA_MonitoredItem *mon, UA_MonitoringMode monitoringMode, const UA_MonitoringParameters *params, - // This parameter is optional and used only if mon->lastValue is not set yet. - // Then numeric type will be detected from this value. Set null as defaut. const UA_DataType* dataType) { + UA_StatusCode retval = UA_STATUSCODE_GOOD; - /* Filter */ - if(params->filter.encoding != UA_EXTENSIONOBJECT_DECODED) { - UA_DataChangeFilter_init(&(mon->filter)); - mon->filter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE; - } else if(params->filter.content.decoded.type != &UA_TYPES[UA_TYPES_DATACHANGEFILTER]) { - return UA_STATUSCODE_BADMONITOREDITEMFILTERINVALID; + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + /* Event MonitoredItem */ +#ifndef UA_ENABLE_SUBSCRIPTIONS_EVENTS + return UA_STATUSCODE_BADNOTSUPPORTED; +#else + if(params->filter.encoding != UA_EXTENSIONOBJECT_DECODED && + params->filter.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) + return UA_STATUSCODE_BADEVENTFILTERINVALID; + if(params->filter.content.decoded.type != &UA_TYPES[UA_TYPES_EVENTFILTER]) + return UA_STATUSCODE_BADEVENTFILTERINVALID; + UA_EventFilter_clear(&mon->filter.eventFilter); + retval = UA_EventFilter_copy((UA_EventFilter *)params->filter.content.decoded.data, + &mon->filter.eventFilter); +#endif } else { - UA_DataChangeFilter *filter = (UA_DataChangeFilter *)params->filter.content.decoded.data; - // TODO implement EURange to support UA_DEADBANDTYPE_PERCENT - if (filter->deadbandType == UA_DEADBANDTYPE_PERCENT) { + /* DataChange MonitoredItem */ + if(params->filter.encoding != UA_EXTENSIONOBJECT_DECODED && + params->filter.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) { + /* Default: Look for status and value */ + UA_DataChangeFilter_clear(&mon->filter.dataChangeFilter); + mon->filter.dataChangeFilter.trigger = UA_DATACHANGETRIGGER_STATUSVALUE; + } else if(params->filter.content.decoded.type == &UA_TYPES[UA_TYPES_DATACHANGEFILTER]) { + UA_DataChangeFilter *filter = (UA_DataChangeFilter *)params->filter.content.decoded.data; + // TODO implement EURange to support UA_DEADBANDTYPE_PERCENT + switch(filter->deadbandType) { + case UA_DEADBANDTYPE_NONE: + break; + case UA_DEADBANDTYPE_ABSOLUTE: + if(!dataType || !UA_DataType_isNumeric(dataType)) + return UA_STATUSCODE_BADFILTERNOTALLOWED; + break; + case UA_DEADBANDTYPE_PERCENT: + return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED; + default: + return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED; + } + retval = UA_DataChangeFilter_copy(filter, &mon->filter.dataChangeFilter); + } else { return UA_STATUSCODE_BADMONITOREDITEMFILTERUNSUPPORTED; } - if (UA_Variant_isEmpty(&mon->lastValue)) { - if (!dataType || !isDataTypeNumeric(dataType)) - return UA_STATUSCODE_BADFILTERNOTALLOWED; - } else - if (!isDataTypeNumeric(mon->lastValue.type)) { - return UA_STATUSCODE_BADFILTERNOTALLOWED; - } - UA_DataChangeFilter_copy(filter, &(mon->filter)); } - MonitoredItem_unregisterSampleCallback(server, mon); - mon->monitoringMode = monitoringMode; + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* <-- The point of no return --> */ + + /* Unregister the callback */ + UA_MonitoredItem_unregisterSampleCallback(server, mon); + + /* Remove the old samples */ + UA_ByteString_deleteMembers(&mon->lastSampledValue); + UA_Variant_deleteMembers(&mon->lastValue); /* ClientHandle */ mon->clientHandle = params->clientHandle; /* SamplingInterval */ UA_Double samplingInterval = params->samplingInterval; + if(mon->attributeId == UA_ATTRIBUTEID_VALUE) { const UA_VariableNode *vn = (const UA_VariableNode *) - UA_Nodestore_get(server, &mon->monitoredNodeId); + UA_Nodestore_getNode(server->nsCtx, &mon->monitoredNodeId); if(vn) { if(vn->nodeClass == UA_NODECLASS_VARIABLE && samplingInterval < vn->minimumSamplingInterval) samplingInterval = vn->minimumSamplingInterval; - UA_Nodestore_release(server, (const UA_Node *)vn); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node *)vn); } - } else if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { - /* TODO: events should not need a samplinginterval */ - samplingInterval = 10000.0f; // 10 seconds to reduce the load } - mon->samplingInterval = samplingInterval; + UA_BOUNDEDVALUE_SETWBOUNDS(server->config.samplingIntervalLimits, samplingInterval, mon->samplingInterval); if(samplingInterval != samplingInterval) /* Check for nan */ mon->samplingInterval = server->config.samplingIntervalLimits.min; - /* QueueSize */ UA_BOUNDEDVALUE_SETWBOUNDS(server->config.queueSizeLimits, params->queueSize, mon->maxQueueSize); @@ -32935,18 +34568,36 @@ setMonitoredItemSettings(UA_Server *server, UA_MonitoredItem *mon, mon->discardOldest = params->discardOldest; /* Register sample callback if reporting is enabled */ - if(monitoringMode == UA_MONITORINGMODE_REPORTING) - return MonitoredItem_registerSampleCallback(server, mon); + mon->monitoringMode = monitoringMode; + if(monitoringMode == UA_MONITORINGMODE_SAMPLING || + monitoringMode == UA_MONITORINGMODE_REPORTING) + return UA_MonitoredItem_registerSampleCallback(server, mon); return UA_STATUSCODE_GOOD; } static const UA_String binaryEncoding = {sizeof("Default Binary") - 1, (UA_Byte *)"Default Binary"}; +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS +static UA_StatusCode +UA_Server_addMonitoredItemToNodeEditNodeCallback(UA_Server *server, UA_Session *session, + UA_Node *node, void *data) { + /* data is the MonitoredItem */ + /* SLIST_INSERT_HEAD */ + ((UA_MonitoredItem *)data)->next = ((UA_ObjectNode *)node)->monitoredItemQueue; + ((UA_ObjectNode *)node)->monitoredItemQueue = (UA_MonitoredItem *)data; + return UA_STATUSCODE_GOOD; +} +#endif + /* Thread-local variables to pass additional arguments into the operation */ struct createMonContext { UA_Subscription *sub; UA_TimestampsToReturn timestampsToReturn; + + /* If sub is NULL, use local callbacks */ + UA_Server_DataChangeNotificationCallback dataChangeCallback; + void *context; }; static void @@ -32954,8 +34605,11 @@ Operation_CreateMonitoredItem(UA_Server *server, UA_Session *session, struct cre const UA_MonitoredItemCreateRequest *request, UA_MonitoredItemCreateResult *result) { /* Check available capacity */ - if(server->config.maxMonitoredItemsPerSubscription != 0 && - cmc->sub->monitoredItemsSize >= server->config.maxMonitoredItemsPerSubscription) { + if(cmc->sub && + (((server->config.maxMonitoredItems != 0) && + (server->numMonitoredItems >= server->config.maxMonitoredItems)) || + ((server->config.maxMonitoredItemsPerSubscription != 0) && + (cmc->sub->monitoredItemsSize >= server->config.maxMonitoredItemsPerSubscription)))) { result->statusCode = UA_STATUSCODE_BADTOOMANYMONITOREDITEMS; return; } @@ -32994,49 +34648,78 @@ Operation_CreateMonitoredItem(UA_Server *server, UA_Session *session, struct cre return; } - /* Create the monitoreditem */ - UA_MonitoredItem *newMon = UA_MonitoredItem_new(UA_MONITOREDITEMTYPE_CHANGENOTIFY); + /* Allocate the MonitoredItem */ + size_t nmsize = sizeof(UA_MonitoredItem); + if(!cmc->sub) + nmsize = sizeof(UA_LocalMonitoredItem); + UA_MonitoredItem *newMon = (UA_MonitoredItem*)UA_malloc(nmsize); if(!newMon) { result->statusCode = UA_STATUSCODE_BADOUTOFMEMORY; UA_DataValue_deleteMembers(&v); return; } - UA_StatusCode retval = UA_NodeId_copy(&request->itemToMonitor.nodeId, - &newMon->monitoredNodeId); - if(retval != UA_STATUSCODE_GOOD) { - result->statusCode = retval; - MonitoredItem_delete(server, newMon); - UA_DataValue_deleteMembers(&v); - return; - } - newMon->subscription = cmc->sub; + + /* Initialize the MonitoredItem */ + UA_MonitoredItem_init(newMon, cmc->sub); newMon->attributeId = request->itemToMonitor.attributeId; - UA_String_copy(&request->itemToMonitor.indexRange, &newMon->indexRange); - newMon->monitoredItemId = ++cmc->sub->lastMonitoredItemId; newMon->timestampsToReturn = cmc->timestampsToReturn; - retval = setMonitoredItemSettings(server, newMon, request->monitoringMode, - &request->requestedParameters, v.value.type); + UA_StatusCode retval = UA_STATUSCODE_GOOD; + retval |= UA_NodeId_copy(&request->itemToMonitor.nodeId, &newMon->monitoredNodeId); + retval |= UA_String_copy(&request->itemToMonitor.indexRange, &newMon->indexRange); + retval |= setMonitoredItemSettings(server, newMon, request->monitoringMode, + &request->requestedParameters, v.value.type); UA_DataValue_deleteMembers(&v); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, cmc->sub->session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "Subscription %u | Could not create a MonitoredItem " - "with StatusCode %s", cmc->sub->subscriptionId, + "with StatusCode %s", cmc->sub ? cmc->sub->subscriptionId : 0, UA_StatusCode_name(retval)); result->statusCode = retval; - MonitoredItem_delete(server, newMon); - --cmc->sub->lastMonitoredItemId; + UA_MonitoredItem_delete(server, newMon); return; } - UA_Subscription_addMonitoredItem(cmc->sub, newMon); - UA_LOG_INFO_SESSION(server->config.logger, cmc->sub->session, + /* Add to the subscriptions or the local MonitoredItems */ + if(cmc->sub) { + newMon->monitoredItemId = ++cmc->sub->lastMonitoredItemId; + UA_Subscription_addMonitoredItem(server, cmc->sub, newMon); +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(newMon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + /* Insert the monitored item into the node's queue */ + UA_Server_editNode(server, NULL, &newMon->monitoredNodeId, + UA_Server_addMonitoredItemToNodeEditNodeCallback, newMon); + } +#endif + } else { + //TODO support events for local monitored items + UA_LocalMonitoredItem *localMon = (UA_LocalMonitoredItem*)newMon; + localMon->context = cmc->context; + localMon->callback.dataChangeCallback = cmc->dataChangeCallback; + newMon->monitoredItemId = ++server->lastLocalMonitoredItemId; + LIST_INSERT_HEAD(&server->localMonitoredItems, newMon, listEntry); + } + + /* Register MonitoredItem in userland */ + if(server->config.monitoredItemRegisterCallback) { + void *targetContext = NULL; + UA_Server_getNodeContext(server, request->itemToMonitor.nodeId, &targetContext); + server->config.monitoredItemRegisterCallback(server, &session->sessionId, + session->sessionHandle, + &request->itemToMonitor.nodeId, + targetContext, newMon->attributeId, false); + newMon->registered = true; + } + + UA_LOG_INFO_SESSION(&server->config.logger, session, "Subscription %u | MonitoredItem %i | " - "Created the MonitoredItem", cmc->sub->subscriptionId, + "Created the MonitoredItem", + cmc->sub ? cmc->sub->subscriptionId : 0, newMon->monitoredItemId); /* Create the first sample */ - if(request->monitoringMode == UA_MONITORINGMODE_REPORTING) - UA_MonitoredItem_SampleCallback(server, newMon); + if(request->monitoringMode == UA_MONITORINGMODE_REPORTING && + newMon->attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER) + UA_MonitoredItem_sampleCallback(server, newMon); /* Prepare the response */ result->revisedSamplingInterval = newMon->samplingInterval; @@ -33048,7 +34731,7 @@ void Service_CreateMonitoredItems(UA_Server *server, UA_Session *session, const UA_CreateMonitoredItemsRequest *request, UA_CreateMonitoredItemsResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing CreateMonitoredItemsRequest"); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing CreateMonitoredItemsRequest"); if(server->config.maxMonitoredItemsPerCall != 0 && request->itemsToCreateSize > server->config.maxMonitoredItemsPerCall) { @@ -33080,6 +34763,24 @@ Service_CreateMonitoredItems(UA_Server *server, UA_Session *session, &response->resultsSize, &UA_TYPES[UA_TYPES_MONITOREDITEMCREATERESULT]); } +UA_MonitoredItemCreateResult +UA_Server_createDataChangeMonitoredItem(UA_Server *server, + UA_TimestampsToReturn timestampsToReturn, + const UA_MonitoredItemCreateRequest item, + void *monitoredItemContext, + UA_Server_DataChangeNotificationCallback callback) { + struct createMonContext cmc; + cmc.sub = NULL; + cmc.context = monitoredItemContext; + cmc.dataChangeCallback = callback; + cmc.timestampsToReturn = timestampsToReturn; + + UA_MonitoredItemCreateResult result; + UA_MonitoredItemCreateResult_init(&result); + Operation_CreateMonitoredItem(server, &server->adminSession, &cmc, &item, &result); + return result; +} + static void Operation_ModifyMonitoredItem(UA_Server *server, UA_Session *session, UA_Subscription *sub, const UA_MonitoredItemModifyRequest *request, @@ -33090,8 +34791,19 @@ Operation_ModifyMonitoredItem(UA_Server *server, UA_Session *session, UA_Subscri result->statusCode = UA_STATUSCODE_BADMONITOREDITEMIDINVALID; return; } - UA_StatusCode retval; - retval = setMonitoredItemSettings(server, mon, mon->monitoringMode, &request->requestedParameters, NULL); + + /* Read the current value to test if filters are possible. + * Can return an empty value (v.value.type == NULL). */ + UA_ReadValueId rvid; + UA_ReadValueId_init(&rvid); + rvid.nodeId = mon->monitoredNodeId; + rvid.attributeId = mon->attributeId; + rvid.indexRange = mon->indexRange; + UA_DataValue v = UA_Server_readWithSession(server, session, &rvid, mon->timestampsToReturn); + UA_StatusCode retval = setMonitoredItemSettings(server, mon, mon->monitoringMode, + &request->requestedParameters, + v.value.type); + UA_DataValue_deleteMembers(&v); if(retval != UA_STATUSCODE_GOOD) { result->statusCode = retval; return; @@ -33101,14 +34813,14 @@ Operation_ModifyMonitoredItem(UA_Server *server, UA_Session *session, UA_Subscri result->revisedQueueSize = mon->maxQueueSize; /* Remove some notifications if the queue is now too small */ - MonitoredItem_ensureQueueSpace(mon); + UA_MonitoredItem_ensureQueueSpace(server, mon); } void Service_ModifyMonitoredItems(UA_Server *server, UA_Session *session, const UA_ModifyMonitoredItemsRequest *request, UA_ModifyMonitoredItemsResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing ModifyMonitoredItemsRequest"); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing ModifyMonitoredItemsRequest"); if(server->config.maxMonitoredItemsPerCall != 0 && request->itemsToModifySize > server->config.maxMonitoredItemsPerCall) { @@ -33146,17 +34858,13 @@ struct setMonitoringContext { static void Operation_SetMonitoringMode(UA_Server *server, UA_Session *session, struct setMonitoringContext *smc, - UA_UInt32 *monitoredItemId, UA_StatusCode *result) { + const UA_UInt32 *monitoredItemId, UA_StatusCode *result) { UA_MonitoredItem *mon = UA_Subscription_getMonitoredItem(smc->sub, *monitoredItemId); if(!mon) { *result = UA_STATUSCODE_BADMONITOREDITEMIDINVALID; return; } - - if(mon->monitoredItemType != UA_MONITOREDITEMTYPE_CHANGENOTIFY) { - *result = UA_STATUSCODE_BADNOTIMPLEMENTED; - return; - } + UA_Subscription *sub = mon->subscription; /* Check if the MonitoringMode is valid or not */ if(smc->monitoringMode > UA_MONITORINGMODE_REPORTING) { @@ -33164,27 +34872,59 @@ Operation_SetMonitoringMode(UA_Server *server, UA_Session *session, return; } + /* Nothing has changed */ if(mon->monitoringMode == smc->monitoringMode) return; mon->monitoringMode = smc->monitoringMode; + + /* When reporting is enabled, put all notifications that were already + * sampled into the global queue of the subscription. When sampling is + * enabled, remove all notifications from the global queue. !!! This needs + * to be the same operation as in UA_Notification_enqueue !!! */ if(mon->monitoringMode == UA_MONITORINGMODE_REPORTING) { - *result = MonitoredItem_registerSampleCallback(server, mon); + UA_Notification *notification; + TAILQ_FOREACH(notification, &mon->queue, listEntry) { + TAILQ_INSERT_TAIL(&sub->notificationQueue, notification, globalEntry); + ++sub->notificationQueueSize; +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + ++sub->eventNotifications; + } else +#endif + { + ++sub->dataChangeNotifications; + } + } + /* Register the sampling callback with an interval */ + *result = UA_MonitoredItem_registerSampleCallback(server, mon); + } else if(mon->monitoringMode == UA_MONITORINGMODE_SAMPLING) { + UA_Notification *notification; + TAILQ_FOREACH(notification, &mon->queue, listEntry) { + TAILQ_REMOVE(&sub->notificationQueue, notification, globalEntry); + TAILQ_NEXT(notification, globalEntry) = UA_SUBSCRIPTION_QUEUE_SENTINEL; + --sub->notificationQueueSize; +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + --sub->eventNotifications; + } else +#endif + { + --sub->dataChangeNotifications; + } + } + /* Register the sampling callback with an interval */ + *result = UA_MonitoredItem_registerSampleCallback(server, mon); } else { - MonitoredItem_unregisterSampleCallback(server, mon); + /* UA_MONITORINGMODE_DISABLED */ + UA_MonitoredItem_unregisterSampleCallback(server, mon); - // TODO correctly implement SAMPLING - /* Setting the mode to DISABLED or SAMPLING causes all queued Notifications to be deleted */ + /* Setting the mode to DISABLED or SAMPLING causes all queued Notifications to be deleted */ UA_Notification *notification, *notification_tmp; TAILQ_FOREACH_SAFE(notification, &mon->queue, listEntry, notification_tmp) { - TAILQ_REMOVE(&mon->queue, notification, listEntry); - TAILQ_REMOVE(&smc->sub->notificationQueue, notification, globalEntry); - --smc->sub->notificationQueueSize; - - UA_DataValue_deleteMembers(¬ification->data.value); - UA_free(notification); + UA_Notification_dequeue(server, notification); + UA_Notification_delete(notification); } - mon->queueSize = 0; /* Initialize lastSampledValue */ UA_ByteString_deleteMembers(&mon->lastSampledValue); @@ -33196,7 +34936,7 @@ void Service_SetMonitoringMode(UA_Server *server, UA_Session *session, const UA_SetMonitoringModeRequest *request, UA_SetMonitoringModeResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing SetMonitoringMode"); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing SetMonitoringMode"); if(server->config.maxMonitoredItemsPerCall != 0 && request->monitoredItemIdsSize > server->config.maxMonitoredItemsPerCall) { @@ -33222,181 +34962,9 @@ Service_SetMonitoringMode(UA_Server *server, UA_Session *session, &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); } -/* TODO: Unify with senderror in ua_server_binary.c */ -static void -subscriptionSendError(UA_SecureChannel *channel, UA_UInt32 requestHandle, - UA_UInt32 requestId, UA_StatusCode error) { - UA_PublishResponse err_response; - UA_PublishResponse_init(&err_response); - err_response.responseHeader.requestHandle = requestHandle; - err_response.responseHeader.timestamp = UA_DateTime_now(); - err_response.responseHeader.serviceResult = error; - UA_SecureChannel_sendSymmetricMessage(channel, requestId, UA_MESSAGETYPE_MSG, - &err_response, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); -} - -void -Service_Publish(UA_Server *server, UA_Session *session, - const UA_PublishRequest *request, UA_UInt32 requestId) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing PublishRequest"); - - /* Return an error if the session has no subscription */ - if(LIST_EMPTY(&session->serverSubscriptions)) { - subscriptionSendError(session->header.channel, request->requestHeader.requestHandle, - requestId, UA_STATUSCODE_BADNOSUBSCRIPTION); - return; - } - - /* Handle too many subscriptions to free resources before trying to allocate - * resources for the new publish request. If the limit has been reached the - * oldest publish request shall be responded */ - if((server->config.maxPublishReqPerSession != 0) && - (session->numPublishReq >= server->config.maxPublishReqPerSession)) { - if(!UA_Subscription_reachedPublishReqLimit(server, session)) { - subscriptionSendError(session->header.channel, requestId, - request->requestHeader.requestHandle, - UA_STATUSCODE_BADINTERNALERROR); - return; - } - } - - /* Allocate the response to store it in the retransmission queue */ - UA_PublishResponseEntry *entry = (UA_PublishResponseEntry *) - UA_malloc(sizeof(UA_PublishResponseEntry)); - if(!entry) { - subscriptionSendError(session->header.channel, requestId, - request->requestHeader.requestHandle, - UA_STATUSCODE_BADOUTOFMEMORY); - return; - } - - /* Prepare the response */ - entry->requestId = requestId; - UA_PublishResponse *response = &entry->response; - UA_PublishResponse_init(response); - response->responseHeader.requestHandle = request->requestHeader.requestHandle; - - /* Allocate the results array to acknowledge the acknowledge */ - if(request->subscriptionAcknowledgementsSize > 0) { - response->results = (UA_StatusCode *) - UA_Array_new(request->subscriptionAcknowledgementsSize, - &UA_TYPES[UA_TYPES_STATUSCODE]); - if(!response->results) { - UA_free(entry); - subscriptionSendError(session->header.channel, requestId, - request->requestHeader.requestHandle, - UA_STATUSCODE_BADOUTOFMEMORY); - return; - } - response->resultsSize = request->subscriptionAcknowledgementsSize; - } - - /* Delete Acknowledged Subscription Messages */ - for(size_t i = 0; i < request->subscriptionAcknowledgementsSize; ++i) { - UA_SubscriptionAcknowledgement *ack = &request->subscriptionAcknowledgements[i]; - UA_Subscription *sub = UA_Session_getSubscriptionById(session, ack->subscriptionId); - if(!sub) { - response->results[i] = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID; - UA_LOG_DEBUG_SESSION(server->config.logger, session, - "Cannot process acknowledgements subscription %u", - ack->subscriptionId); - continue; - } - /* Remove the acked transmission from the retransmission queue */ - response->results[i] = UA_Subscription_removeRetransmissionMessage(sub, ack->sequenceNumber); - } - - /* Queue the publish response. It will be dequeued in a repeated publish - * callback. This can also be triggered right now for a late - * subscription. */ - UA_Session_queuePublishReq(session, entry, false); - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Queued a publication message"); - - /* If there are late subscriptions, the new publish request is used to - * answer them immediately. However, a single subscription that generates - * many notifications must not "starve" other late subscriptions. Therefore - * we keep track of the last subscription that got preferential treatment. - * We start searching for late subscriptions **after** the last one. */ - - UA_Subscription *immediate = NULL; - if(session->lastSeenSubscriptionId > 0) { - LIST_FOREACH(immediate, &session->serverSubscriptions, listEntry) { - if(immediate->subscriptionId == session->lastSeenSubscriptionId) { - immediate = LIST_NEXT(immediate, listEntry); - break; - } - } - } - - /* If no entry was found, start at the beginning and don't restart */ - UA_Boolean found = false; - if(!immediate) - immediate = LIST_FIRST(&session->serverSubscriptions); - else - found = true; - - repeat: - while(immediate) { - if(immediate->state == UA_SUBSCRIPTIONSTATE_LATE) { - session->lastSeenSubscriptionId = immediate->subscriptionId; - UA_LOG_DEBUG_SESSION(server->config.logger, session, - "Subscription %u | Response on a late subscription", - immediate->subscriptionId); - UA_Subscription_publish(server, immediate); - return; - } - immediate = LIST_NEXT(immediate, listEntry); - } - - /* Restart at the beginning of the list */ - if(found) { - immediate = LIST_FIRST(&session->serverSubscriptions); - found = false; - goto repeat; - } - - /* No late subscription this time */ - session->lastSeenSubscriptionId = 0; -} - -static void -Operation_DeleteSubscription(UA_Server *server, UA_Session *session, void *_, - UA_UInt32 *subscriptionId, UA_StatusCode *result) { - *result = UA_Session_deleteSubscription(server, session, *subscriptionId); - if(*result == UA_STATUSCODE_GOOD) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, - "Subscription %u | Subscription deleted", - *subscriptionId); - } else { - UA_LOG_DEBUG_SESSION(server->config.logger, session, - "Deleting Subscription with Id %u failed with error code %s", - *subscriptionId, UA_StatusCode_name(*result)); - } -} - -void -Service_DeleteSubscriptions(UA_Server *server, UA_Session *session, - const UA_DeleteSubscriptionsRequest *request, - UA_DeleteSubscriptionsResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing DeleteSubscriptionsRequest"); - - response->responseHeader.serviceResult = - UA_Server_processServiceOperations(server, session, - (UA_ServiceOperation)Operation_DeleteSubscription, NULL, - &request->subscriptionIdsSize, &UA_TYPES[UA_TYPES_UINT32], - &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); - - /* The session has at least one subscription */ - if(LIST_FIRST(&session->serverSubscriptions)) - return; - - /* Send remaining publish responses if the last subscription was removed */ - UA_Subscription_answerPublishRequestsNoSubscription(server, session); -} - static void Operation_DeleteMonitoredItem(UA_Server *server, UA_Session *session, UA_Subscription *sub, - UA_UInt32 *monitoredItemId, UA_StatusCode *result) { + const UA_UInt32 *monitoredItemId, UA_StatusCode *result) { *result = UA_Subscription_deleteMonitoredItem(server, sub, *monitoredItemId); } @@ -33404,7 +34972,8 @@ void Service_DeleteMonitoredItems(UA_Server *server, UA_Session *session, const UA_DeleteMonitoredItemsRequest *request, UA_DeleteMonitoredItemsResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing DeleteMonitoredItemsRequest"); + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Processing DeleteMonitoredItemsRequest"); if(server->config.maxMonitoredItemsPerCall != 0 && request->monitoredItemIdsSize > server->config.maxMonitoredItemsPerCall) { @@ -33429,34 +34998,17 @@ Service_DeleteMonitoredItems(UA_Server *server, UA_Session *session, &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); } -void -Service_Republish(UA_Server *server, UA_Session *session, const UA_RepublishRequest *request, - UA_RepublishResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing RepublishRequest"); - - /* Get the subscription */ - UA_Subscription *sub = UA_Session_getSubscriptionById(session, request->subscriptionId); - if(!sub) { - response->responseHeader.serviceResult = UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID; - return; - } - - /* Reset the subscription lifetime */ - sub->currentLifetimeCount = 0; - - /* Find the notification in the retransmission queue */ - UA_NotificationMessageEntry *entry; - TAILQ_FOREACH(entry, &sub->retransmissionQueue, listEntry) { - if(entry->message.sequenceNumber == request->retransmitSequenceNumber) - break; - } - if(!entry) { - response->responseHeader.serviceResult = UA_STATUSCODE_BADMESSAGENOTAVAILABLE; - return; +UA_StatusCode +UA_Server_deleteMonitoredItem(UA_Server *server, UA_UInt32 monitoredItemId) { + UA_MonitoredItem *mon; + LIST_FOREACH(mon, &server->localMonitoredItems, listEntry) { + if(mon->monitoredItemId != monitoredItemId) + continue; + LIST_REMOVE(mon, listEntry); + UA_MonitoredItem_delete(server, mon); + return UA_STATUSCODE_GOOD; } - - response->responseHeader.serviceResult = - UA_NotificationMessage_copy(&entry->message, &response->notificationMessage); + return UA_STATUSCODE_BADMONITOREDITEMIDINVALID; } #endif /* UA_ENABLE_SUBSCRIPTIONS */ @@ -33467,7 +35019,7 @@ Service_Republish(UA_Server *server, UA_Session *session, const UA_RepublishRequ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014, 2017 (c) Florian Palm * Copyright 2015 (c) Oleksiy Vasylyev * Copyright 2017 (c) Stefan Profanter, fortiss GmbH @@ -33487,10 +35039,10 @@ Service_OpenSecureChannel(UA_Server *server, UA_SecureChannel *channel, /* Logging */ if(response->responseHeader.serviceResult == UA_STATUSCODE_GOOD) { - UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, + UA_LOG_DEBUG_CHANNEL(&server->config.logger, channel, "SecureChannel renewed"); } else { - UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, + UA_LOG_DEBUG_CHANNEL(&server->config.logger, channel, "Renewing SecureChannel failed"); } return; @@ -33509,10 +35061,10 @@ Service_OpenSecureChannel(UA_Server *server, UA_SecureChannel *channel, /* Logging */ if(response->responseHeader.serviceResult == UA_STATUSCODE_GOOD) { - UA_LOG_INFO_CHANNEL(server->config.logger, channel, + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, "Opened SecureChannel"); } else { - UA_LOG_INFO_CHANNEL(server->config.logger, channel, + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, "Opening a SecureChannel failed"); } } @@ -33520,7 +35072,7 @@ Service_OpenSecureChannel(UA_Server *server, UA_SecureChannel *channel, /* The server does not send a CloseSecureChannel response */ void Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel) { - UA_LOG_INFO_CHANNEL(server->config.logger, channel, "CloseSecureChannel"); + UA_LOG_INFO_CHANNEL(&server->config.logger, channel, "CloseSecureChannel"); UA_SecureChannelManager_close(&server->secureChannelManager, channel->securityToken.channelId); } @@ -33529,9 +35081,9 @@ Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel) { /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2014-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2014-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2014-2017 (c) Florian Palm * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015-2016 (c) Chris Iatrou @@ -33546,6 +35098,13 @@ Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel) { */ +#define UA_LOG_NODEID_WRAP(NODEID, LOG) { \ + UA_String nodeIdStr = UA_STRING_NULL; \ + UA_NodeId_toString(NODEID, &nodeIdStr); \ + LOG; \ + UA_String_deleteMembers(&nodeIdStr); \ +} + /*********************/ /* Edit Node Context */ /*********************/ @@ -33553,12 +35112,26 @@ Service_CloseSecureChannel(UA_Server *server, UA_SecureChannel *channel) { UA_StatusCode UA_Server_getNodeContext(UA_Server *server, UA_NodeId nodeId, void **nodeContext) { - const UA_Node *node = UA_Nodestore_get(server, &nodeId); + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &nodeId); if(!node) return UA_STATUSCODE_BADNODEIDUNKNOWN; - *nodeContext = node->context; - UA_Nodestore_release(server, node); + UA_Nodestore_releaseNode(server->nsCtx, node); + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +setDeconstructedNode(UA_Server *server, UA_Session *session, + UA_Node *node, void *context) { + node->constructed = false; + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +setConstructedNodeContext(UA_Server *server, UA_Session *session, + UA_Node *node, void *context) { + node->context = context; + node->constructed = true; return UA_STATUSCODE_GOOD; } @@ -33572,29 +35145,21 @@ editNodeContext(UA_Server *server, UA_Session* session, UA_StatusCode UA_Server_setNodeContext(UA_Server *server, UA_NodeId nodeId, void *nodeContext) { - UA_StatusCode retval = - UA_Server_editNode(server, &server->adminSession, &nodeId, - (UA_EditNodeCallback)editNodeContext, nodeContext); - return retval; + return UA_Server_editNode(server, &server->adminSession, &nodeId, + (UA_EditNodeCallback)editNodeContext, nodeContext); } /**********************/ /* Consistency Checks */ /**********************/ - #define UA_PARENT_REFERENCES_COUNT 2 const UA_NodeId parentReferences[UA_PARENT_REFERENCES_COUNT] = { - { - 0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE} - }, - { - 0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASCOMPONENT} - } + {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}}, + {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASCOMPONENT}} }; - /* Check if the requested parent node exists, has the right node class and is * referenced with an allowed (hierarchical) reference type. For "type" nodes, * only hasSubType references are allowed. */ @@ -33602,48 +35167,49 @@ static UA_StatusCode checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeClass, const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId) { /* Objects do not need a parent (e.g. mandatory/optional modellingrules) */ - if(nodeClass == UA_NODECLASS_OBJECT && UA_NodeId_isNull(parentNodeId) && - UA_NodeId_isNull(referenceTypeId)) - return UA_STATUSCODE_GOOD; - - /* Omit checks during bootstrap */ - if(server->bootstrapNS0) + /* Also, there are some variables which do not have parents, e.g. EnumStrings, EnumValues */ + if((nodeClass == UA_NODECLASS_OBJECT || nodeClass == UA_NODECLASS_VARIABLE) && + UA_NodeId_isNull(parentNodeId) && UA_NodeId_isNull(referenceTypeId)) return UA_STATUSCODE_GOOD; /* See if the parent exists */ - const UA_Node *parent = UA_Nodestore_get(server, parentNodeId); + const UA_Node *parent = UA_Nodestore_getNode(server->nsCtx, parentNodeId); if(!parent) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Parent node not found"); + UA_LOG_NODEID_WRAP(parentNodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Parent node %.*s not found", + (int)nodeIdStr.length, nodeIdStr.data)); return UA_STATUSCODE_BADPARENTNODEIDINVALID; } UA_NodeClass parentNodeClass = parent->nodeClass; - UA_Nodestore_release(server, parent); + UA_Nodestore_releaseNode(server->nsCtx, parent); /* Check the referencetype exists */ const UA_ReferenceTypeNode *referenceType = (const UA_ReferenceTypeNode*) - UA_Nodestore_get(server, referenceTypeId); + UA_Nodestore_getNode(server->nsCtx, referenceTypeId); if(!referenceType) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Reference type to the parent not found"); + UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Reference type %.*s to the parent not found", + (int)nodeIdStr.length, nodeIdStr.data)); return UA_STATUSCODE_BADREFERENCETYPEIDINVALID; } /* Check if the referencetype is a reference type node */ if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Reference type to the parent invalid"); - UA_Nodestore_release(server, (const UA_Node*)referenceType); + UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Reference type %.*s to the parent is not a ReferenceTypeNode", + (int)nodeIdStr.length, nodeIdStr.data)); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)referenceType); return UA_STATUSCODE_BADREFERENCETYPEIDINVALID; } UA_Boolean referenceTypeIsAbstract = referenceType->isAbstract; - UA_Nodestore_release(server, (const UA_Node*)referenceType); + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)referenceType); /* Check that the reference type is not abstract */ if(referenceTypeIsAbstract == true) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Abstract reference type to the parent not allowed"); + UA_LOG_NODEID_WRAP(referenceTypeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Abstract reference type %.*s to the parent not allowed", + (int)nodeIdStr.length, nodeIdStr.data)); return UA_STATUSCODE_BADREFERENCENOTALLOWED; } @@ -33654,28 +35220,26 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl nodeClass == UA_NODECLASS_REFERENCETYPE) { /* type needs hassubtype reference to the supertype */ if(!UA_NodeId_equal(referenceTypeId, &subtypeId)) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: New type node need to have a " - "HasSubType reference"); + UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Type nodes need to have a HasSubType " + "reference to the parent"); return UA_STATUSCODE_BADREFERENCENOTALLOWED; } /* supertype needs to be of the same node type */ if(parentNodeClass != nodeClass) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: New type node needs to be of the same " - "node type as the parent"); + UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Type nodes needs to be of the same node " + "type as their parent"); return UA_STATUSCODE_BADPARENTNODEIDINVALID; } return UA_STATUSCODE_GOOD; } /* Test if the referencetype is hierarchical */ - const UA_NodeId hierarchicalReference = - UA_NODEID_NUMERIC(0, UA_NS0ID_HIERARCHICALREFERENCES); - if(!isNodeInTree(&server->config.nodestore, referenceTypeId, - &hierarchicalReference, &subtypeId, 1)) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Reference type is not hierarchical"); + if(!isNodeInTree(server->nsCtx, referenceTypeId, + &hierarchicalReferences, &subtypeId, 1)) { + UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Reference type to the parent is not hierarchical"); return UA_STATUSCODE_BADREFERENCETYPEIDINVALID; } @@ -33685,8 +35249,7 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl static UA_StatusCode typeCheckVariableNode(UA_Server *server, UA_Session *session, const UA_VariableNode *node, - const UA_VariableTypeNode *vt, - const UA_NodeId *parentNodeId) { + const UA_VariableTypeNode *vt) { /* The value might come from a datasource, so we perform a * regular read. */ UA_DataValue value; @@ -33695,32 +35258,51 @@ typeCheckVariableNode(UA_Server *server, UA_Session *session, if(retval != UA_STATUSCODE_GOOD) return retval; + UA_NodeId baseDataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE); + /* Check the datatype against the vt */ - if(!compatibleDataType(server, &node->dataType, &vt->dataType, false)) + /* If the node does not have any value and the dataType is BaseDataType, + * then it's also fine. This is the default for empty nodes. */ + if(!compatibleDataType(server, &node->dataType, &vt->dataType, false) && + (value.hasValue || !UA_NodeId_equal(&node->dataType, &baseDataType))) { + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: The value of %.*s is incompatible with " + "the datatype of the VariableType", + (int)nodeIdStr.length, nodeIdStr.data)); + UA_DataValue_deleteMembers(&value); return UA_STATUSCODE_BADTYPEMISMATCH; + } /* Check valueRank against array dimensions */ - if(!compatibleValueRankArrayDimensions(server, session, node->valueRank, node->arrayDimensionsSize)) + if(!compatibleValueRankArrayDimensions(server, session, node->valueRank, + node->arrayDimensionsSize)) { + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: The value rank of %.*s is incomatible " + "with its array dimensions", (int)nodeIdStr.length, nodeIdStr.data)); + UA_DataValue_deleteMembers(&value); return UA_STATUSCODE_BADTYPEMISMATCH; + } - /* If variable node is created below BaseObjectType and has its default valueRank of -2, - * skip the test */ - const UA_NodeId objectTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE); - - // TODO handle subtypes of parent reference types - if(node->valueRank != vt->valueRank && - node->valueRank != UA_VariableAttributes_default.valueRank && - !isNodeInTree(&server->config.nodestore, parentNodeId, &objectTypes, - parentReferences, UA_PARENT_REFERENCES_COUNT)) { - /* Check valueRank against the vt */ - if(!compatibleValueRanks(node->valueRank, vt->valueRank)) - return UA_STATUSCODE_BADTYPEMISMATCH; + /* Check valueRank against the vt */ + if(!compatibleValueRanks(node->valueRank, vt->valueRank)) { + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: The value rank of %.*s is incomatible " + "with the value rank of the VariableType", + (int)nodeIdStr.length, nodeIdStr.data)); + UA_DataValue_deleteMembers(&value); + return UA_STATUSCODE_BADTYPEMISMATCH; } /* Check array dimensions against the vt */ if(!compatibleArrayDimensions(vt->arrayDimensionsSize, vt->arrayDimensions, - node->arrayDimensionsSize, node->arrayDimensions)) + node->arrayDimensionsSize, node->arrayDimensions)) { + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: The array dimensions of %.*s are " + "incomatible with the array dimensions of the VariableType", + (int)nodeIdStr.length, nodeIdStr.data)); + UA_DataValue_deleteMembers(&value); return UA_STATUSCODE_BADTYPEMISMATCH; + } /* Typecheck the value */ if(value.hasValue && value.value.data) { @@ -33731,7 +35313,13 @@ typeCheckVariableNode(UA_Server *server, UA_Session *session, &value.value, NULL)) retval = UA_Server_writeValue(server, node->nodeId, value.value); UA_DataValue_deleteMembers(&value); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: The value of of %.*s is incomatible with the " + "variable definition", (int)nodeIdStr.length, nodeIdStr.data)); + } } + return retval; } @@ -33743,63 +35331,94 @@ static const UA_NodeId baseDataVariableType = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_BASEDATAVARIABLETYPE}}; static const UA_NodeId baseObjectType = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_BASEOBJECTTYPE}}; +static const UA_NodeId hasTypeDefinition = + {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASTYPEDEFINITION}}; -/* Use attributes from the variable type wherever required */ +/* Use attributes from the variable type wherever required. Reload the node if + * changes were made. */ static UA_StatusCode useVariableTypeAttributes(UA_Server *server, UA_Session *session, - UA_VariableNode *node, const UA_AddNodesItem *item) { - const UA_VariableAttributes *attributes = (const UA_VariableAttributes*) - item->nodeAttributes.content.decoded.data; - - /* Select the type definition */ - const UA_NodeId *typeDefinition; - if(node->nodeClass == UA_NODECLASS_VARIABLE) - typeDefinition = &item->typeDefinition.nodeId; - else /* UA_NODECLASS_VARIABLETYPE */ - typeDefinition = &item->parentNodeId.nodeId; - - /* Replace an empty typeDefinition with the most permissive default */ - if(UA_NodeId_isNull(typeDefinition)) - typeDefinition = &baseDataVariableType; - - const UA_VariableTypeNode *vt = (const UA_VariableTypeNode*) - UA_Nodestore_get(server, typeDefinition); - if(!vt || vt->nodeClass != UA_NODECLASS_VARIABLETYPE) { - UA_Nodestore_release(server, (const UA_Node*)vt); - return UA_STATUSCODE_BADTYPEMISMATCH; - } + const UA_VariableNode **node_ptr, + const UA_VariableTypeNode *vt) { + const UA_VariableNode *node = *node_ptr; + UA_Boolean modified = false; /* If no value is set, see if the vt provides one and copy it. This needs to * be done before copying the datatype from the vt, as setting the datatype * triggers a typecheck. */ - UA_StatusCode retval = UA_STATUSCODE_GOOD; - if(!attributes->value.type) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, - "AddNodes: No value given; Copy the value" + UA_DataValue orig; + UA_DataValue_init(&orig); + UA_StatusCode retval = readValueAttribute(server, session, node, &orig); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + if(orig.value.type) { + /* A value is present */ + UA_DataValue_deleteMembers(&orig); + } else { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "AddNodes: No value given; Copy the value " "from the TypeDefinition"); - UA_DataValue vt_value; - UA_DataValue_init(&vt_value); - retval = readValueAttribute(server, session, - (const UA_VariableNode*)vt, &vt_value); - if(retval == UA_STATUSCODE_GOOD && vt_value.hasValue) { - retval = UA_Variant_copy(&vt_value.value, &node->value.data.value.value); - node->value.data.value.hasValue = true; + UA_WriteValue v; + UA_WriteValue_init(&v); + retval = readValueAttribute(server, session, (const UA_VariableNode*)vt, &v.value); + if(retval == UA_STATUSCODE_GOOD && v.value.hasValue) { + v.nodeId = node->nodeId; + v.attributeId = UA_ATTRIBUTEID_VALUE; + retval = UA_Server_writeWithSession(server, session, &v); + modified = true; } - UA_DataValue_deleteMembers(&vt_value); + UA_DataValue_deleteMembers(&v.value); + if(retval != UA_STATUSCODE_GOOD) + return retval; } /* If no datatype is given, use the datatype of the vt */ - if(retval == UA_STATUSCODE_GOOD && UA_NodeId_isNull(&node->dataType)) { - UA_LOG_INFO_SESSION(server->config.logger, session, "AddNodes: " + if(UA_NodeId_isNull(&node->dataType)) { + UA_LOG_INFO_SESSION(&server->config.logger, session, "AddNodes: " "No datatype given; Copy the datatype attribute " "from the TypeDefinition"); - retval = UA_NodeId_copy(&vt->dataType, &node->dataType); + UA_WriteValue v; + UA_WriteValue_init(&v); + v.nodeId = node->nodeId; + v.attributeId = UA_ATTRIBUTEID_DATATYPE; + v.value.hasValue = true; + UA_Variant_setScalar(&v.value.value, (void*)(uintptr_t)&vt->dataType, + &UA_TYPES[UA_TYPES_NODEID]); + retval = UA_Server_writeWithSession(server, session, &v); + modified = true; + if(retval != UA_STATUSCODE_GOOD) + return retval; } - /* TODO: If the vt has arraydimensions but this variable does not, copy */ + /* Use the ArrayDimensions of the vt */ + if(node->arrayDimensionsSize == 0 && vt->arrayDimensionsSize > 0) { + UA_WriteValue v; + UA_WriteValue_init(&v); + v.nodeId = node->nodeId; + v.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS; + v.value.hasValue = true; + UA_Variant_setArray(&v.value.value, vt->arrayDimensions, + vt->arrayDimensionsSize, &UA_TYPES[UA_TYPES_UINT32]); + retval = UA_Server_writeWithSession(server, session, &v); + modified = true; + if(retval != UA_STATUSCODE_GOOD) + return retval; + } - UA_Nodestore_release(server, (const UA_Node*)vt); - return retval; + /* If the node was modified, update the pointer to the new version */ + if(modified) { + const UA_VariableNode *updated = (const UA_VariableNode*) + UA_Nodestore_getNode(server->nsCtx, &node->nodeId); + + if(!updated) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_Nodestore_releaseNode(server->nsCtx, (const UA_Node*)node); + *node_ptr = updated; + } + + return UA_STATUSCODE_GOOD; } /* Search for an instance of "browseName" in node searchInstance. Used during @@ -33817,7 +35436,7 @@ findChildByBrowsename(UA_Server *server, UA_Session *session, bd.includeSubtypes = true; bd.browseDirection = UA_BROWSEDIRECTION_FORWARD; bd.nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE | UA_NODECLASS_METHOD; - bd.resultMask = UA_BROWSERESULTMASK_NODECLASS | UA_BROWSERESULTMASK_BROWSENAME; + bd.resultMask = UA_BROWSERESULTMASK_BROWSENAME; UA_BrowseResult br; UA_BrowseResult_init(&br); @@ -33849,7 +35468,7 @@ static UA_Boolean isMandatoryChild(UA_Server *server, UA_Session *session, const UA_NodeId *childNodeId) { /* Get the child */ - const UA_Node *child = UA_Nodestore_get(server, childNodeId); + const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, childNodeId); if(!child) return false; @@ -33862,116 +35481,43 @@ isMandatoryChild(UA_Server *server, UA_Session *session, continue; for(size_t j = 0; j < refs->targetIdsSize; ++j) { if(UA_NodeId_equal(&mandatoryId, &refs->targetIds[j].nodeId)) { - UA_Nodestore_release(server, child); + UA_Nodestore_releaseNode(server->nsCtx, child); return true; } } } - UA_Nodestore_release(server, child); + UA_Nodestore_releaseNode(server->nsCtx, child); return false; } static UA_StatusCode -copyChildNodes(UA_Server *server, UA_Session *session, - const UA_NodeId *sourceNodeId, - const UA_NodeId *destinationNodeId); +copyAllChildren(UA_Server *server, UA_Session *session, + const UA_NodeId *source, const UA_NodeId *destination); + +static UA_StatusCode +recursiveTypeCheckAddChildren(UA_Server *server, UA_Session *session, + const UA_Node **node, const UA_Node *type); static void Operation_addReference(UA_Server *server, UA_Session *session, void *context, const UA_AddReferencesItem *item, UA_StatusCode *retval); - -/* - * This method only deletes references from the node which are not matching any type in the given array. - * Could be used to e.g. delete all the references, except 'HASMODELINGRULE' - */ -static void deleteReferencesSubset(UA_Node *node, size_t referencesSkipSize, UA_NodeId* referencesSkip) { - if(referencesSkipSize == 0) { - UA_Node_deleteReferences(node); - return; - } - - /* Let's count if there are references left. If not just delete all the references. - * It's faster */ - size_t newSize = 0; - for(size_t i = 0; i < node->referencesSize; ++i) { - for(size_t j = 0; j < referencesSkipSize; j++) { - if(UA_NodeId_equal(&node->references[i].referenceTypeId, &referencesSkip[j])) { - newSize++; - } - } - } - if(newSize == 0) { - UA_Node_deleteReferences(node); - return; - } - - /* Now copy the remaining references to a new array */ - UA_NodeReferenceKind *newReferences = (UA_NodeReferenceKind *)UA_malloc(sizeof(UA_NodeReferenceKind) * (newSize)); - size_t curr = 0; - UA_StatusCode retval = UA_STATUSCODE_GOOD; - for(size_t i = 0; i < node->referencesSize && retval == UA_STATUSCODE_GOOD; ++i) { - for(size_t j = 0; j < referencesSkipSize; j++) { - if(!UA_NodeId_equal(&node->references[i].referenceTypeId, &referencesSkip[j])) - continue; - - // copy the reference - UA_NodeReferenceKind *srefs = &node->references[i]; - UA_NodeReferenceKind *drefs = &newReferences[curr++]; - drefs->isInverse = srefs->isInverse; - retval = UA_NodeId_copy(&srefs->referenceTypeId, &drefs->referenceTypeId); - if(retval != UA_STATUSCODE_GOOD) - break; - retval = UA_Array_copy(srefs->targetIds, srefs->targetIdsSize, - (void**)&drefs->targetIds, - &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); - if(retval != UA_STATUSCODE_GOOD) - break; - drefs->targetIdsSize = srefs->targetIdsSize; - break; - } - if(retval != UA_STATUSCODE_GOOD) { - for(size_t k=0; k<i; k++) { - UA_NodeReferenceKind *refs = &newReferences[i]; - for(size_t j = 0; j < refs->targetIdsSize; ++j) - UA_ExpandedNodeId_deleteMembers(&refs->targetIds[j]); - UA_Array_delete(refs->targetIds, refs->targetIdsSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); - UA_NodeId_deleteMembers(&refs->referenceTypeId); - } - } - } - - UA_Node_deleteReferences(node); - if(retval == UA_STATUSCODE_GOOD) { - node->references = newReferences; - node->referencesSize = newSize; - } else { - UA_free(newReferences); - } -} - static UA_StatusCode -AddNode_typeCheckAddRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId, - const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId, - const UA_NodeId *typeDefinitionId); - -static UA_StatusCode -copyChildNode(UA_Server *server, UA_Session *session, - const UA_NodeId *destinationNodeId, - const UA_ReferenceDescription *rd) { +copyChild(UA_Server *server, UA_Session *session, const UA_NodeId *destinationNodeId, + const UA_ReferenceDescription *rd) { + /* Is there an existing child with the browsename? */ UA_NodeId existingChild = UA_NODEID_NULL; - UA_StatusCode retval = - findChildByBrowsename(server, session, destinationNodeId, - &rd->browseName, &existingChild); + UA_StatusCode retval = findChildByBrowsename(server, session, destinationNodeId, + &rd->browseName, &existingChild); if(retval != UA_STATUSCODE_GOOD) return retval; - /* Have a child with that browseName. Try to deep-copy missing members. */ + /* Have a child with that browseName. Deep-copy missing members. */ if(!UA_NodeId_isNull(&existingChild)) { if(rd->nodeClass == UA_NODECLASS_VARIABLE || rd->nodeClass == UA_NODECLASS_OBJECT) - retval = copyChildNodes(server, session, &rd->nodeId.nodeId, &existingChild); + retval = copyAllChildren(server, session, &rd->nodeId.nodeId, &existingChild); UA_NodeId_deleteMembers(&existingChild); return retval; } @@ -33980,9 +35526,8 @@ copyChildNode(UA_Server *server, UA_Session *session, if(!isMandatoryChild(server, session, &rd->nodeId.nodeId)) return UA_STATUSCODE_GOOD; - /* No existing child with that browsename. Create it. */ + /* Child is a method -> create a reference */ if(rd->nodeClass == UA_NODECLASS_METHOD) { - /* Add a reference to the method in the objecttype */ UA_AddReferencesItem newItem; UA_AddReferencesItem_init(&newItem); newItem.sourceNodeId = *destinationNodeId; @@ -33994,23 +35539,18 @@ copyChildNode(UA_Server *server, UA_Session *session, return retval; } - /* Node exists and is a variable or object. Instantiate missing mandatory - * children */ + /* Child is a variable or object */ if(rd->nodeClass == UA_NODECLASS_VARIABLE || rd->nodeClass == UA_NODECLASS_OBJECT) { - /* Get the node */ + /* Make a copy of the node */ UA_Node *node; - retval = UA_Nodestore_getCopy(server, &rd->nodeId.nodeId, &node); + retval = UA_Nodestore_getNodeCopy(server->nsCtx, &rd->nodeId.nodeId, &node); if(retval != UA_STATUSCODE_GOOD) return retval; - /* Get the type */ - const UA_Node *type = getNodeType(server, node); - const UA_NodeId *typeId; - if(type) - typeId = &type->nodeId; - else - typeId = &UA_NODEID_NULL; + /* Remove the context of the copied node */ + node->context = NULL; + node->constructed = false; /* Reset the NodeId (random numeric id will be assigned in the nodestore) */ UA_NodeId_deleteMembers(&node->nodeId); @@ -34022,55 +35562,45 @@ copyChildNode(UA_Server *server, UA_Session *session, * manually added by the user during addnode_begin and addnode_finish. */ /* For now we keep all the modelling rule references and delete all others */ UA_NodeId modellingRuleReferenceId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASMODELLINGRULE); - deleteReferencesSubset(node, 1, &modellingRuleReferenceId); + UA_Node_deleteReferencesSubset(node, 1, &modellingRuleReferenceId); /* Add the node to the nodestore */ UA_NodeId newNodeId; - retval = UA_Nodestore_insert(server, node, &newNodeId); - if(retval != UA_STATUSCODE_GOOD) { - UA_Nodestore_release(server, type); + retval = UA_Nodestore_insertNode(server->nsCtx, node, &newNodeId); + if(retval != UA_STATUSCODE_GOOD) return retval; - } - - /* Add all the children of this child to the new child node to make sure we take - * the values from the nearest inherited object first. - * The call to addNode_finish will then only add the children from the type and - * thus skip the direct children of rd->nodeId.nodeId */ - copyChildNodes(server, session, &rd->nodeId.nodeId, &newNodeId); - /* Add the parent reference */ - retval = AddNode_typeCheckAddRefs(server, session, &newNodeId, destinationNodeId, - &rd->referenceTypeId, typeId); + /* Add the node references */ + retval = AddNode_addRefs(server, session, &newNodeId, destinationNodeId, + &rd->referenceTypeId, &rd->typeDefinition.nodeId); if(retval != UA_STATUSCODE_GOOD) { - UA_Nodestore_delete(server, node); - UA_Nodestore_release(server, type); + UA_Nodestore_removeNode(server->nsCtx, &newNodeId); return retval; } - /* Call addnode_finish, this recursively adds additional members, the type - * definition and so on of the base type of this child, if they are not yet - * in the destination */ - retval |= Operation_addNode_finish(server, session, &newNodeId); - UA_NodeId_deleteMembers(&newNodeId); - UA_Nodestore_release(server, type); + /* For the new child, recursively copy the members of the original. No + * typechecking is performed here. Assuming that the original is + * consistent. */ + retval = copyAllChildren(server, session, &rd->nodeId.nodeId, &newNodeId); } + return retval; } /* Copy any children of Node sourceNodeId to another node destinationNodeId. */ static UA_StatusCode -copyChildNodes(UA_Server *server, UA_Session *session, - const UA_NodeId *sourceNodeId, const UA_NodeId *destinationNodeId) { +copyAllChildren(UA_Server *server, UA_Session *session, + const UA_NodeId *source, const UA_NodeId *destination) { /* Browse to get all children of the source */ UA_BrowseDescription bd; UA_BrowseDescription_init(&bd); - bd.nodeId = *sourceNodeId; + bd.nodeId = *source; bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES); bd.includeSubtypes = true; bd.browseDirection = UA_BROWSEDIRECTION_FORWARD; bd.nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE | UA_NODECLASS_METHOD; bd.resultMask = UA_BROWSERESULTMASK_REFERENCETYPEID | UA_BROWSERESULTMASK_NODECLASS | - UA_BROWSERESULTMASK_BROWSENAME; + UA_BROWSERESULTMASK_BROWSENAME | UA_BROWSERESULTMASK_TYPEDEFINITION; UA_BrowseResult br; UA_BrowseResult_init(&br); @@ -34082,7 +35612,9 @@ copyChildNodes(UA_Server *server, UA_Session *session, UA_StatusCode retval = UA_STATUSCODE_GOOD; for(size_t i = 0; i < br.referencesSize; ++i) { UA_ReferenceDescription *rd = &br.references[i]; - retval |= copyChildNode(server, session, destinationNodeId, rd); + retval = copyChild(server, session, destination, rd); + if(retval != UA_STATUSCODE_GOOD) + return retval; } UA_BrowseResult_deleteMembers(&br); @@ -34090,106 +35622,40 @@ copyChildNodes(UA_Server *server, UA_Session *session, } static UA_StatusCode -addChildren(UA_Server *server, UA_Session *session, - const UA_Node *node, const UA_Node *type) { +addTypeChildren(UA_Server *server, UA_Session *session, + const UA_Node *node, const UA_Node *type) { /* Get the hierarchy of the type and all its supertypes */ UA_NodeId *hierarchy = NULL; size_t hierarchySize = 0; - UA_StatusCode retval = getTypeHierarchy(&server->config.nodestore, &type->nodeId, - &hierarchy, &hierarchySize); + UA_StatusCode retval = getParentTypeAndInterfaceHierarchy(server, &type->nodeId, + &hierarchy, &hierarchySize); if(retval != UA_STATUSCODE_GOOD) return retval; + UA_assert(hierarchySize < 1000); /* Copy members of the type and supertypes (and instantiate them) */ - for(size_t i = 0; i < hierarchySize; ++i) - retval |= copyChildNodes(server, session, &hierarchy[i], &node->nodeId); - UA_Array_delete(hierarchy, hierarchySize, &UA_TYPES[UA_TYPES_NODEID]); - return retval; -} - -/* Calls the global destructor internally of the global constructor succeeds and - * the type-level constructor fails. */ -static UA_StatusCode callConstructors(UA_Server *server, UA_Session *session, - const UA_Node *node, const UA_Node *type) { - /* Get the node type constructor */ - const UA_NodeTypeLifecycle *lifecycle = NULL; - if(node->nodeClass == UA_NODECLASS_OBJECT) { - const UA_ObjectTypeNode *ot = (const UA_ObjectTypeNode*)type; - lifecycle = &ot->lifecycle; - } else if(node->nodeClass == UA_NODECLASS_VARIABLE) { - const UA_VariableTypeNode *vt = (const UA_VariableTypeNode*)type; - lifecycle = &vt->lifecycle; + for(size_t i = 0; i < hierarchySize; ++i) { + retval = copyAllChildren(server, session, &hierarchy[i], &node->nodeId); + if(retval != UA_STATUSCODE_GOOD) + break; } - /* Call the global constructor */ - void *context = node->context; - UA_StatusCode retval = UA_STATUSCODE_GOOD; - if(server->config.nodeLifecycle.constructor) - retval = server->config.nodeLifecycle.constructor(server, &session->sessionId, - session->sessionHandle, - &node->nodeId, &context); - - /* Call the type constructor */ - if(retval == UA_STATUSCODE_GOOD && lifecycle && lifecycle->constructor) - retval = lifecycle->constructor(server, &session->sessionId, - session->sessionHandle, &type->nodeId, - type->context, &node->nodeId, &context); - - /* Set the context *and* mark the node as constructed */ - if(retval == UA_STATUSCODE_GOOD) - retval = UA_Server_editNode(server, &server->adminSession, &node->nodeId, - (UA_EditNodeCallback)editNodeContext, - context); - - /* Fail. Call the global destructor. */ - if(retval != UA_STATUSCODE_GOOD && server->config.nodeLifecycle.destructor) - server->config.nodeLifecycle.destructor(server, &session->sessionId, - session->sessionHandle, - &node->nodeId, context); - - return retval; -} - -static UA_StatusCode -addTypeDefRef(UA_Server *server, UA_Session *session, - const UA_Node *node, const UA_Node *type) { - UA_StatusCode retval = UA_STATUSCODE_GOOD; - UA_AddReferencesItem addref; - UA_AddReferencesItem_init(&addref); - addref.sourceNodeId = node->nodeId; - addref.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION); - addref.isForward = true; - addref.targetNodeId.nodeId = type->nodeId; - Operation_addReference(server, session, NULL, &addref, &retval); + UA_Array_delete(hierarchy, hierarchySize, &UA_TYPES[UA_TYPES_NODEID]); return retval; } static UA_StatusCode -getTypeDef(UA_Server *server, const UA_Node *node, UA_NodeId **typeDefinitionId) { - UA_NodeId hasTypeDef = UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION); - for (size_t i=0; i< node->referencesSize; i++) { - if (node->references[i].isInverse == UA_FALSE && UA_NodeId_equal(&node->references[i].referenceTypeId, &hasTypeDef) && - node->references[i].targetIdsSize > 0) { - *typeDefinitionId = &node->references[i].targetIds[0].nodeId; - return UA_STATUSCODE_GOOD; - } - } - - return UA_STATUSCODE_BADNOTFOUND; -} - -static UA_StatusCode -addParentRef(UA_Server *server, UA_Session *session, - const UA_NodeId *nodeId, - const UA_NodeId *referenceTypeId, - const UA_NodeId *parentNodeId) { - UA_StatusCode retval = UA_STATUSCODE_GOOD; +addRef(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId, + const UA_NodeId *referenceTypeId, const UA_NodeId *parentNodeId, + UA_Boolean forward) { UA_AddReferencesItem ref_item; UA_AddReferencesItem_init(&ref_item); ref_item.sourceNodeId = *nodeId; ref_item.referenceTypeId = *referenceTypeId; - ref_item.isForward = false; + ref_item.isForward = forward; ref_item.targetNodeId.nodeId = *parentNodeId; + + UA_StatusCode retval = UA_STATUSCODE_GOOD; Operation_addReference(server, session, NULL, &ref_item, &retval); return retval; } @@ -34198,24 +35664,18 @@ addParentRef(UA_Server *server, UA_Session *session, /* Add Node */ /************/ -static void -removeDeconstructedNode(UA_Server *server, UA_Session *session, - const UA_Node *node, UA_Boolean removeTargetRefs); - static const UA_NodeId hasSubtype = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASSUBTYPE}}; -static UA_StatusCode -AddNode_typeCheckAddRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId, - const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId, - const UA_NodeId *typeDefinitionId) { +UA_StatusCode +AddNode_addRefs(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId, + const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId, + const UA_NodeId *typeDefinitionId) { /* Get the node */ - const UA_Node *node = UA_Nodestore_get(server, nodeId); + const UA_Node *type = NULL; + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId); if(!node) return UA_STATUSCODE_BADNODEIDUNKNOWN; - UA_StatusCode retval = UA_STATUSCODE_GOOD; - const UA_Node *type = NULL; - /* Use the typeDefinition as parent for type-nodes */ if(node->nodeClass == UA_NODECLASS_VARIABLETYPE || node->nodeClass == UA_NODECLASS_OBJECTTYPE || @@ -34223,23 +35683,23 @@ AddNode_typeCheckAddRefs(UA_Server *server, UA_Session *session, const UA_NodeId node->nodeClass == UA_NODECLASS_DATATYPE) { if(UA_NodeId_equal(referenceTypeId, &UA_NODEID_NULL)) referenceTypeId = &hasSubtype; - const UA_Node *parentNode = UA_Nodestore_get(server, parentNodeId); + const UA_Node *parentNode = UA_Nodestore_getNode(server->nsCtx, parentNodeId); if(parentNode) { if(parentNode->nodeClass == node->nodeClass) typeDefinitionId = parentNodeId; - UA_Nodestore_release(server, parentNode); + UA_Nodestore_releaseNode(server->nsCtx, parentNode); } } - if(server->bootstrapNS0) - goto get_type; - /* Check parent reference. Objects may have no parent. */ - retval = checkParentReference(server, session, node->nodeClass, - parentNodeId, referenceTypeId); + UA_StatusCode retval = checkParentReference(server, session, node->nodeClass, + parentNodeId, referenceTypeId); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: The parent reference is invalid"); + UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: The parent reference for %.*s is invalid " + "with status code %s", + (int)nodeIdStr.length, nodeIdStr.data, + UA_StatusCode_name(retval))); goto cleanup; } @@ -34247,29 +35707,30 @@ AddNode_typeCheckAddRefs(UA_Server *server, UA_Session *session, const UA_NodeId if((node->nodeClass == UA_NODECLASS_VARIABLE || node->nodeClass == UA_NODECLASS_OBJECT) && UA_NodeId_isNull(typeDefinitionId)) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: No TypeDefinition; Use the default " - "TypeDefinition for the Variable/Object"); + UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: No TypeDefinition for %.*s; Use the default " + "TypeDefinition for the Variable/Object", + (int)nodeIdStr.length, nodeIdStr.data)); if(node->nodeClass == UA_NODECLASS_VARIABLE) typeDefinitionId = &baseDataVariableType; else typeDefinitionId = &baseObjectType; } - get_type: /* Get the node type. There must be a typedefinition for variables, objects * and type-nodes. See the above checks. */ if(!UA_NodeId_isNull(typeDefinitionId)) { /* Get the type node */ - type = UA_Nodestore_get(server, typeDefinitionId); + type = UA_Nodestore_getNode(server->nsCtx, typeDefinitionId); if(!type) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Node type not found in nodestore"); + UA_LOG_NODEID_WRAP(typeDefinitionId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Node type %.*s not found", + (int)nodeIdStr.length, nodeIdStr.data)); retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID; goto cleanup; } - UA_Boolean typeOk = UA_FALSE; + UA_Boolean typeOk = false; switch(node->nodeClass) { case UA_NODECLASS_DATATYPE: typeOk = type->nodeClass == UA_NODECLASS_DATATYPE; @@ -34296,83 +35757,109 @@ AddNode_typeCheckAddRefs(UA_Server *server, UA_Session *session, const UA_NodeId typeOk = type->nodeClass == UA_NODECLASS_VIEW; break; default: - typeOk = UA_FALSE; + typeOk = false; } if(!typeOk) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Type does not match node class"); + UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Type for %.*s does not match node class", + (int)nodeIdStr.length, nodeIdStr.data)); retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID; goto cleanup; } /* See if the type has the correct node class. For type-nodes, we know * that type has the same nodeClass from checkParentReference. */ - if(!server->bootstrapNS0 && node->nodeClass == UA_NODECLASS_VARIABLE) { + if(node->nodeClass == UA_NODECLASS_VARIABLE) { if(((const UA_VariableTypeNode*)type)->isAbstract) { - /* Abstract variable is allowed if parent is a children of a base data variable */ + /* Get subtypes of the parent reference types */ + UA_NodeId *parentTypeHierarchy = NULL; + size_t parentTypeHierarchySize = 0; + retval |= referenceSubtypes(server, &parentReferences[0], + &parentTypeHierarchySize, &parentTypeHierarchy); + retval |= referenceSubtypes(server, &parentReferences[1], + &parentTypeHierarchySize, &parentTypeHierarchy); + if(retval != UA_STATUSCODE_GOOD) { + UA_Array_delete(parentTypeHierarchy, parentTypeHierarchySize, + &UA_TYPES[UA_TYPES_NODEID]); + goto cleanup; + } + + /* Abstract variable is allowed if parent is a children of a + * base data variable. An abstract variable may be part of an + * object type which again is below BaseObjectType */ const UA_NodeId variableTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE); - /* A variable may be of an object type which again is below BaseObjectType */ const UA_NodeId objectTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE); - // TODO handle subtypes of parent reference types - if(!isNodeInTree(&server->config.nodestore, parentNodeId, &variableTypes, - parentReferences, UA_PARENT_REFERENCES_COUNT) && - !isNodeInTree(&server->config.nodestore, parentNodeId, &objectTypes, - parentReferences, UA_PARENT_REFERENCES_COUNT)) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Type of variable node must " - "be VariableType and not cannot be abstract"); + if(!isNodeInTree(server->nsCtx, parentNodeId, &variableTypes, + parentTypeHierarchy, parentTypeHierarchySize) && + !isNodeInTree(server->nsCtx, parentNodeId, &objectTypes, + parentTypeHierarchy, parentTypeHierarchySize)) { + UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Type of variable node %.*s must " + "be VariableType and not cannot be abstract", + (int)nodeIdStr.length, nodeIdStr.data)); retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID; - goto cleanup; } + UA_Array_delete(parentTypeHierarchy, parentTypeHierarchySize, + &UA_TYPES[UA_TYPES_NODEID]); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; } } - if(!server->bootstrapNS0 && node->nodeClass == UA_NODECLASS_OBJECT) { + if(node->nodeClass == UA_NODECLASS_OBJECT) { if(((const UA_ObjectTypeNode*)type)->isAbstract) { + /* Get subtypes of the parent reference types */ + UA_NodeId *parentTypeHierarchy = NULL; + size_t parentTypeHierarchySize = 0; + retval |= referenceSubtypes(server, &parentReferences[0], + &parentTypeHierarchySize, &parentTypeHierarchy); + retval |= referenceSubtypes(server, &parentReferences[1], + &parentTypeHierarchySize, &parentTypeHierarchy); + if(retval != UA_STATUSCODE_GOOD) { + UA_Array_delete(parentTypeHierarchy, parentTypeHierarchySize, + &UA_TYPES[UA_TYPES_NODEID]); + goto cleanup; + } + /* Object node created of an abstract ObjectType. Only allowed - * if within BaseObjectType folder */ + * if within BaseObjectType folder or if it's an event (subType of BaseEventType) */ const UA_NodeId objectTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE); - // TODO handle subtypes of parent reference types - if(!isNodeInTree(&server->config.nodestore, parentNodeId, &objectTypes, - parentReferences, UA_PARENT_REFERENCES_COUNT)) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Type of object node must " - "be ObjectType and not be abstract"); + UA_Boolean isInBaseObjectType = isNodeInTree(server->nsCtx, parentNodeId, &objectTypes, + parentTypeHierarchy, parentTypeHierarchySize); + + const UA_NodeId eventTypes = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEEVENTTYPE); + UA_Boolean isInBaseEventType = isNodeInTree(server->nsCtx, &type->nodeId, &eventTypes, &hasSubtype, 1); + + if(!isInBaseObjectType && !(isInBaseEventType && UA_NodeId_isNull(parentNodeId))) { + UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Type of object node %.*s must " + "be ObjectType and not be abstract", + (int)nodeIdStr.length, nodeIdStr.data)); retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID; - goto cleanup; } + UA_Array_delete(parentTypeHierarchy, parentTypeHierarchySize, + &UA_TYPES[UA_TYPES_NODEID]); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; } } } - /* Check if all attributes hold the constraints of the type now. The initial - * attributes must type-check. The constructor might change the attributes - * again. Then, the changes are type-checked by the normal write service. */ - if(type && (node->nodeClass == UA_NODECLASS_VARIABLE || - node->nodeClass == UA_NODECLASS_VARIABLETYPE)) { - retval = typeCheckVariableNode(server, session, (const UA_VariableNode*)node, - (const UA_VariableTypeNode*)type, parentNodeId); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Type-checking the variable node " - "failed with error code %s", UA_StatusCode_name(retval)); - goto cleanup; - } - } - /* Add reference to the parent */ if(!UA_NodeId_isNull(parentNodeId)) { if(UA_NodeId_isNull(referenceTypeId)) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Reference to parent cannot be null"); + UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Reference to parent of %.*s cannot be null", + (int)nodeIdStr.length, nodeIdStr.data)); retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID; goto cleanup; } - retval = addParentRef(server, session, &node->nodeId, referenceTypeId, parentNodeId); + retval = addRef(server, session, &node->nodeId, referenceTypeId, parentNodeId, false); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Adding reference to parent failed"); + UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Adding reference to parent of %.*s failed", + (int)nodeIdStr.length, nodeIdStr.data)); goto cleanup; } } @@ -34381,30 +35868,28 @@ AddNode_typeCheckAddRefs(UA_Server *server, UA_Session *session, const UA_NodeId if(node->nodeClass == UA_NODECLASS_VARIABLE || node->nodeClass == UA_NODECLASS_OBJECT) { UA_assert(type != NULL); /* see above */ - retval = addTypeDefRef(server, session, node, type); - if(retval != UA_STATUSCODE_GOOD) - UA_LOG_INFO_SESSION(server->config.logger, session, + retval = addRef(server, session, &node->nodeId, &hasTypeDefinition, &type->nodeId, true); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_NODEID_WRAP(nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, "AddNodes: Adding a reference to the type " - "definition failed with error code %s", - UA_StatusCode_name(retval)); + "definition of %.*s failed with error code %s", + (int)nodeIdStr.length, nodeIdStr.data, + UA_StatusCode_name(retval))); + } } cleanup: - UA_Nodestore_release(server, node); + UA_Nodestore_releaseNode(server->nsCtx, node); if(type) - UA_Nodestore_release(server, type); - if(retval != UA_STATUSCODE_GOOD) - UA_Server_deleteNode(server, *nodeId, UA_TRUE); + UA_Nodestore_releaseNode(server->nsCtx, type); return retval; } /* Create the node and add it to the nodestore. But don't typecheck and add * references so far */ -static UA_StatusCode +UA_StatusCode AddNode_raw(UA_Server *server, UA_Session *session, void *nodeContext, const UA_AddNodesItem *item, UA_NodeId *outNewNodeId) { - UA_assert(outNewNodeId); - /* Do not check access for server */ if(session != &server->adminSession && server->config.accessControl.allowAddNode && !server->config.accessControl.allowAddNode(server, &server->config.accessControl, @@ -34414,22 +35899,22 @@ AddNode_raw(UA_Server *server, UA_Session *session, void *nodeContext, /* Check the namespaceindex */ if(item->requestedNewNodeId.nodeId.namespaceIndex >= server->namespacesSize) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "AddNodes: Namespace invalid"); return UA_STATUSCODE_BADNODEIDINVALID; } if(item->nodeAttributes.encoding != UA_EXTENSIONOBJECT_DECODED && item->nodeAttributes.encoding != UA_EXTENSIONOBJECT_DECODED_NODELETE) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "AddNodes: Node attributes invalid"); return UA_STATUSCODE_BADINTERNALERROR; } /* Create a node */ - UA_Node *node = UA_Nodestore_new(server, item->nodeClass); + UA_Node *node = UA_Nodestore_newNode(server->nsCtx, item->nodeClass); if(!node) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "AddNodes: Node could not create a node " "in the nodestore"); return UA_STATUSCODE_BADOUTOFMEMORY; @@ -34437,48 +35922,38 @@ AddNode_raw(UA_Server *server, UA_Session *session, void *nodeContext, /* Fill the node attributes */ node->context = nodeContext; - UA_StatusCode retval = UA_STATUSCODE_GOOD; - retval |= UA_NodeId_copy(&item->requestedNewNodeId.nodeId, &node->nodeId); - retval |= UA_QualifiedName_copy(&item->browseName, &node->browseName); - retval |= UA_Node_setAttributes(node, item->nodeAttributes.content.decoded.data, - item->nodeAttributes.content.decoded.type); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Node could not create a node " - "with error code %s", UA_StatusCode_name(retval)); - UA_Nodestore_delete(server, node); - return retval; - } + UA_StatusCode retval = UA_NodeId_copy(&item->requestedNewNodeId.nodeId, &node->nodeId); + if(retval != UA_STATUSCODE_GOOD) + goto create_error; - /* Use attributes from the typedefinition */ - if(!server->bootstrapNS0 && - (node->nodeClass == UA_NODECLASS_VARIABLE || - node->nodeClass == UA_NODECLASS_VARIABLETYPE)) { - /* Use attributes from the type. The value and value constraints are the - * same for the variable and variabletype attribute structs. */ - retval = useVariableTypeAttributes(server, session, - (UA_VariableNode*)node, item); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Using attributes from the variable type " - "failed with error code %s", UA_StatusCode_name(retval)); - UA_Nodestore_delete(server, node); - return retval; - } - } + retval = UA_QualifiedName_copy(&item->browseName, &node->browseName); + if(retval != UA_STATUSCODE_GOOD) + goto create_error; + + retval = UA_Node_setAttributes(node, item->nodeAttributes.content.decoded.data, + item->nodeAttributes.content.decoded.type); + if(retval != UA_STATUSCODE_GOOD) + goto create_error; /* Add the node to the nodestore */ - retval = UA_Nodestore_insert(server, node, outNewNodeId); + retval = UA_Nodestore_insertNode(server->nsCtx, node, outNewNodeId); if(retval != UA_STATUSCODE_GOOD) - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "AddNodes: Node could not add the new node " "to the nodestore with error code %s", UA_StatusCode_name(retval)); return retval; + +create_error: + UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Node could not create a node " + "with error code %s", UA_StatusCode_name(retval)); + UA_Nodestore_deleteNode(server->nsCtx, node); + return retval; } /* Prepare the node, then add it to the nodestore */ -UA_StatusCode +static UA_StatusCode Operation_addNode_begin(UA_Server *server, UA_Session *session, void *nodeContext, const UA_AddNodesItem *item, const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId, UA_NodeId *outNewNodeId) { @@ -34495,20 +35970,274 @@ Operation_addNode_begin(UA_Server *server, UA_Session *session, void *nodeContex return retval; /* Typecheck and add references to parent and type definition */ - retval = AddNode_typeCheckAddRefs(server, session, outNewNodeId, parentNodeId, - referenceTypeId, &item->typeDefinition.nodeId); + retval = AddNode_addRefs(server, session, outNewNodeId, parentNodeId, + referenceTypeId, &item->typeDefinition.nodeId); + if(retval != UA_STATUSCODE_GOOD) + UA_Server_deleteNode(server, *outNewNodeId, true); + if(outNewNodeId == &newId) UA_NodeId_deleteMembers(&newId); return retval; } +static UA_StatusCode +recursiveTypeCheckAddChildren(UA_Server *server, UA_Session *session, + const UA_Node **nodeptr, const UA_Node *type) { + UA_assert(type != NULL); + UA_StatusCode retval = UA_STATUSCODE_GOOD; + const UA_Node *node = *nodeptr; + + /* Use attributes from the type. The value and value constraints are the + * same for the variable and variabletype attribute structs. */ + if(node->nodeClass == UA_NODECLASS_VARIABLE || + node->nodeClass == UA_NODECLASS_VARIABLETYPE) { + retval = useVariableTypeAttributes(server, session, (const UA_VariableNode**)nodeptr, + (const UA_VariableTypeNode*)type); + node = *nodeptr; /* If the node was replaced */ + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Using attributes for %.*s from the variable type " + "failed with error code %s", (int)nodeIdStr.length, + nodeIdStr.data, UA_StatusCode_name(retval))); + return retval; + } + + /* Check NodeClass for 'hasSubtype'. UA_NODECLASS_VARIABLE not allowed to have subtype */ + if((node->nodeClass == UA_NODECLASS_VARIABLE) && (UA_NodeId_equal( + &node->references->referenceTypeId, &hasSubtype))) { + UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: VariableType not allowed to have HasSubType"); + return UA_STATUSCODE_BADREFERENCENOTALLOWED; + } + + /* Check if all attributes hold the constraints of the type now. The initial + * attributes must type-check. The constructor might change the attributes + * again. Then, the changes are type-checked by the normal write service. */ + retval = typeCheckVariableNode(server, session, (const UA_VariableNode*)node, + (const UA_VariableTypeNode*)type); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Type-checking the variable node %.*s " + "failed with error code %s", (int)nodeIdStr.length, + nodeIdStr.data, UA_StatusCode_name(retval))); + return retval; + } + } + + /* Add (mandatory) child nodes from the type definition */ + if(node->nodeClass == UA_NODECLASS_VARIABLE || + node->nodeClass == UA_NODECLASS_OBJECT) { + retval = addTypeChildren(server, session, node, type); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Adding child nodes of %.*s failed with error code %s", + (int)nodeIdStr.length, nodeIdStr.data, UA_StatusCode_name(retval))); + } + } + + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +findDefaultInstanceBrowseNameNode(UA_Server *server, + UA_NodeId startingNode, UA_NodeId *foundId){ + + UA_NodeId_init(foundId); + UA_RelativePathElement rpe; + UA_RelativePathElement_init(&rpe); + rpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY); + rpe.isInverse = false; + rpe.includeSubtypes = false; + rpe.targetName = UA_QUALIFIEDNAME(0, "DefaultInstanceBrowseName"); + UA_BrowsePath bp; + UA_BrowsePath_init(&bp); + bp.startingNode = startingNode; + bp.relativePath.elementsSize = 1; + bp.relativePath.elements = &rpe; + UA_BrowsePathResult bpr = + UA_Server_translateBrowsePathToNodeIds(server, &bp); + UA_StatusCode retval = bpr.statusCode; + if (retval == UA_STATUSCODE_GOOD && + bpr.targetsSize > 0) { + retval = UA_NodeId_copy(&bpr.targets[0].targetId.nodeId, foundId); + } + UA_BrowsePathResult_deleteMembers(&bpr); + return retval; +} + +/* Check if we got a valid browse name for the new node. + * For object nodes the BrowseName may only be null if the parent type has a + * 'DefaultInstanceBrowseName' property. + * */ +static UA_StatusCode +checkValidBrowseName(UA_Server *server, UA_Session *session, + const UA_Node *node, const UA_Node *type) { + + UA_assert(type != NULL); + UA_StatusCode retval = UA_STATUSCODE_GOOD; + + if(node->nodeClass != UA_NODECLASS_OBJECT) { + /* nodes other than Objects must have a browseName */ + if (UA_QualifiedName_isNull(&node->browseName)) + return UA_STATUSCODE_BADBROWSENAMEINVALID; + return UA_STATUSCODE_GOOD; + } + + /* If the object node already has a browse name we are done here. */ + if(!UA_QualifiedName_isNull(&node->browseName)) + return UA_STATUSCODE_GOOD; + + /* at this point we have an object with an empty browse name. + * Check the type node if it has a DefaultInstanceBrowseName property + */ + + UA_NodeId defaultBrowseNameNode; + retval = findDefaultInstanceBrowseNameNode(server, type->nodeId, &defaultBrowseNameNode); + if (retval != UA_STATUSCODE_GOOD) { + if (retval == UA_STATUSCODE_BADNOMATCH) + /* the DefaultBrowseName property is not found, return the corresponding status code */ + return UA_STATUSCODE_BADBROWSENAMEINVALID; + return retval; + } + + UA_Variant defaultBrowseName; + retval = UA_Server_readValue(server, defaultBrowseNameNode, &defaultBrowseName); + if (retval != UA_STATUSCODE_GOOD) + return retval; + + UA_QualifiedName *defaultValue = (UA_QualifiedName *) defaultBrowseName.data; + retval = UA_Server_writeBrowseName(server, node->nodeId, *defaultValue); + UA_Variant_clear(&defaultBrowseName); + + return retval; +} + +/* Construct children first */ +static UA_StatusCode +recursiveCallConstructors(UA_Server *server, UA_Session *session, + const UA_Node *node, const UA_Node *type) { + if(node->constructed) + return UA_STATUSCODE_GOOD; + + /* Construct the children */ + UA_BrowseDescription bd; + UA_BrowseDescription_init(&bd); + bd.nodeId = node->nodeId; + bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES); + bd.includeSubtypes = true; + bd.browseDirection = UA_BROWSEDIRECTION_FORWARD; + + UA_BrowseResult br; + UA_BrowseResult_init(&br); + UA_UInt32 maxrefs = 0; + Operation_Browse(server, session, &maxrefs, &bd, &br); + if(br.statusCode != UA_STATUSCODE_GOOD) + return br.statusCode; + + /* Call the constructor for every unconstructed node */ + UA_StatusCode retval = UA_STATUSCODE_GOOD; + for(size_t i = 0; i < br.referencesSize; ++i) { + UA_ReferenceDescription *rd = &br.references[i]; + const UA_Node *target = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId); + if(!target) + continue; + if(target->constructed) { + UA_Nodestore_releaseNode(server->nsCtx, target); + continue; + } + + const UA_Node *targetType = NULL; + if(node->nodeClass == UA_NODECLASS_VARIABLE || + node->nodeClass == UA_NODECLASS_OBJECT) { + targetType = getNodeType(server, target); + if(!targetType) { + UA_Nodestore_releaseNode(server->nsCtx, target); + retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID; + break; + } + } + retval = recursiveCallConstructors(server, session, target, targetType); + UA_Nodestore_releaseNode(server->nsCtx, target); + if(targetType) + UA_Nodestore_releaseNode(server->nsCtx, targetType); + if(retval != UA_STATUSCODE_GOOD) + break; + } + + UA_BrowseResult_deleteMembers(&br); + + /* If a child could not be constructed or the node is already constructed */ + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* Get the node type constructor */ + const UA_NodeTypeLifecycle *lifecycle = NULL; + if(type && node->nodeClass == UA_NODECLASS_OBJECT) { + const UA_ObjectTypeNode *ot = (const UA_ObjectTypeNode*)type; + lifecycle = &ot->lifecycle; + } else if(type && node->nodeClass == UA_NODECLASS_VARIABLE) { + const UA_VariableTypeNode *vt = (const UA_VariableTypeNode*)type; + lifecycle = &vt->lifecycle; + } + + /* Call the global constructor */ + void *context = node->context; + if(server->config.nodeLifecycle.constructor) + retval = server->config.nodeLifecycle.constructor(server, &session->sessionId, + session->sessionHandle, + &node->nodeId, &context); + + /* Call the type constructor */ + if(retval == UA_STATUSCODE_GOOD && lifecycle && lifecycle->constructor) + retval = lifecycle->constructor(server, &session->sessionId, + session->sessionHandle, &type->nodeId, + type->context, &node->nodeId, &context); + if(retval != UA_STATUSCODE_GOOD) + goto fail1; + + /* Set the context *and* mark the node as constructed */ + if(retval == UA_STATUSCODE_GOOD) + retval = UA_Server_editNode(server, &server->adminSession, &node->nodeId, + (UA_EditNodeCallback)setConstructedNodeContext, + context); + + /* All good, return */ + if(retval == UA_STATUSCODE_GOOD) + return retval; + + /* Fail. Call the destructors. */ + if(lifecycle && lifecycle->destructor) + lifecycle->destructor(server, &session->sessionId, + session->sessionHandle, &type->nodeId, + type->context, &node->nodeId, &context); + + fail1: + if(server->config.nodeLifecycle.destructor) + server->config.nodeLifecycle.destructor(server, &session->sessionId, + session->sessionHandle, + &node->nodeId, context); + return retval; +} + +static void +recursiveDeconstructNode(UA_Server *server, UA_Session *session, + size_t hierarchicalReferencesSize, + UA_ExpandedNodeId *hierarchicalReferences, + const UA_Node *node); + +static void +recursiveDeleteNode(UA_Server *server, UA_Session *session, + size_t hierarchicalReferencesSize, + UA_ExpandedNodeId *hierarchicalReferences, + const UA_Node *node, UA_Boolean removeTargetRefs); + /* Children, references, type-checking, constructors. */ UA_StatusCode -Operation_addNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId) { +AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *nodeId) { UA_StatusCode retval = UA_STATUSCODE_GOOD; /* Get the node */ - const UA_Node *node = UA_Nodestore_get(server, nodeId); + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, nodeId); if(!node) return UA_STATUSCODE_BADNODEIDUNKNOWN; @@ -34516,51 +36245,47 @@ Operation_addNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId /* Instantiate variables and objects */ if(node->nodeClass == UA_NODECLASS_VARIABLE || + node->nodeClass == UA_NODECLASS_VARIABLETYPE || node->nodeClass == UA_NODECLASS_OBJECT) { - UA_NodeId *typeDefId; - retval = getTypeDef(server, node, &typeDefId); - if (retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Can not get type definition of node since it " - "has no 'hasTypeDef' reference"); - goto cleanup; - } - /* Get the type node */ - type = UA_Nodestore_get(server, typeDefId); + type = getNodeType(server, node); if(!type) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Node type not found in nodestore"); + if(server->bootstrapNS0) + goto constructor; + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Node type for %.*s not found", + (int)nodeIdStr.length, nodeIdStr.data)); retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID; goto cleanup; } - /* Add (mandatory) child nodes from the type definition */ - if(!server->bootstrapNS0) { - retval = addChildren(server, session, node, type); - if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Adding child nodes failed with error code %s", - UA_StatusCode_name(retval)); - goto cleanup; - } - } + retval = checkValidBrowseName(server, session, node, type); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + + retval = recursiveTypeCheckAddChildren(server, session, &node, type); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; } /* Call the constructor(s) */ - retval = callConstructors(server, session, node, type); + constructor: + retval = recursiveCallConstructors(server, session, node, type); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO_SESSION(server->config.logger, session, - "AddNodes: Calling the node constructor(s) failed " - "with status code %s", UA_StatusCode_name(retval)); + UA_LOG_NODEID_WRAP(&node->nodeId, UA_LOG_INFO_SESSION(&server->config.logger, session, + "AddNodes: Calling the node constructor(s) of %.*s failed " + "with status code %s", (int)nodeIdStr.length, + nodeIdStr.data, UA_StatusCode_name(retval))); } cleanup: if(type) - UA_Nodestore_release(server, type); - if(retval != UA_STATUSCODE_GOOD) - removeDeconstructedNode(server, session, node, true); - UA_Nodestore_release(server, node); + UA_Nodestore_releaseNode(server->nsCtx, type); + if(retval != UA_STATUSCODE_GOOD) { + recursiveDeconstructNode(server, session, 0, NULL, node); + recursiveDeleteNode(server, session, 0, NULL, node, true); + } + UA_Nodestore_releaseNode(server->nsCtx, node); return retval; } @@ -34574,8 +36299,7 @@ Operation_addNode(UA_Server *server, UA_Session *session, void *nodeContext, return; /* AddNodes_finish */ - result->statusCode = - Operation_addNode_finish(server, session, &result->addedNodeId); + result->statusCode = AddNode_finish(server, session, &result->addedNodeId); /* If finishing failed, the node was deleted */ if(result->statusCode != UA_STATUSCODE_GOOD) @@ -34584,9 +36308,9 @@ Operation_addNode(UA_Server *server, UA_Session *session, void *nodeContext, void Service_AddNodes(UA_Server *server, UA_Session *session, - const UA_AddNodesRequest *request, - UA_AddNodesResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing AddNodesRequest"); + const UA_AddNodesRequest *request, + UA_AddNodesResponse *response) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing AddNodesRequest"); if(server->config.maxNodesPerNodeManagement != 0 && request->nodesToAddSize > server->config.maxNodesPerNodeManagement) { @@ -34595,7 +36319,8 @@ Service_AddNodes(UA_Server *server, UA_Session *session, } response->responseHeader.serviceResult = - UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)Operation_addNode, NULL, + UA_Server_processServiceOperations(server, session, + (UA_ServiceOperation)Operation_addNode, NULL, &request->nodesToAddSize, &UA_TYPES[UA_TYPES_ADDNODESITEM], &response->resultsSize, &UA_TYPES[UA_TYPES_ADDNODESRESULT]); } @@ -34658,7 +36383,7 @@ UA_Server_addNode_begin(UA_Server *server, const UA_NodeClass nodeClass, UA_StatusCode UA_Server_addNode_finish(UA_Server *server, const UA_NodeId nodeId) { - return Operation_addNode_finish(server, &server->adminSession, &nodeId); + return AddNode_finish(server, &server->adminSession, &nodeId); } /****************/ @@ -34672,7 +36397,7 @@ Operation_deleteReference(UA_Server *server, UA_Session *session, void *context, /* Remove references to this node (in the other nodes) */ static void removeIncomingReferences(UA_Server *server, UA_Session *session, - const UA_Node *node) { + const UA_Node *node) { UA_DeleteReferencesItem item; UA_DeleteReferencesItem_init(&item); item.targetNodeId.nodeId = node->nodeId; @@ -34689,9 +36414,50 @@ removeIncomingReferences(UA_Server *server, UA_Session *session, } } +/* A node can only be deleted if it has at most one incoming hierarchical + * reference. If hierarchicalReferences is NULL, always remove. */ +static UA_Boolean +multipleHierarchies(size_t hierarchicalRefsSize, UA_ExpandedNodeId *hierarchicalRefs, + const UA_Node *node) { + if(!hierarchicalRefs) + return false; + + size_t incomingRefs = 0; + for(size_t i = 0; i < node->referencesSize; i++) { + const UA_NodeReferenceKind *k = &node->references[i]; + if(!k->isInverse) + continue; + + UA_Boolean hierarchical = false; + for(size_t j = 0; j < hierarchicalRefsSize; j++) { + if(UA_NodeId_equal(&hierarchicalRefs[j].nodeId, + &k->referenceTypeId)) { + hierarchical = true; + break; + } + } + if(!hierarchical) + continue; + + incomingRefs += k->targetIdsSize; + if(incomingRefs > 1) + return true; + } + + return false; +} + +/* Recursively call the destructors of this node and all child nodes. + * Deconstructs the parent before its children. */ static void -deconstructNode(UA_Server *server, UA_Session *session, - const UA_Node *node) { +recursiveDeconstructNode(UA_Server *server, UA_Session *session, + size_t hierarchicalRefsSize, + UA_ExpandedNodeId *hierarchicalRefs, + const UA_Node *node) { + /* Was the constructor called for the node? */ + if(!node->constructed) + return; + /* Call the type-level destructor */ void *context = node->context; /* No longer needed after this function */ if(node->nodeClass == UA_NODECLASS_OBJECT || @@ -34708,7 +36474,7 @@ deconstructNode(UA_Server *server, UA_Session *session, &session->sessionId, session->sessionHandle, &type->nodeId, type->context, &node->nodeId, &context); - UA_Nodestore_release(server, type); + UA_Nodestore_releaseNode(server->nsCtx, type); } } @@ -34717,15 +36483,11 @@ deconstructNode(UA_Server *server, UA_Session *session, server->config.nodeLifecycle.destructor(server, &session->sessionId, session->sessionHandle, &node->nodeId, context); -} -static void -deleteNodeOperation(UA_Server *server, UA_Session *session, void *context, - const UA_DeleteNodesItem *item, UA_StatusCode *result); + /* Set the constructed flag to false */ + UA_Server_editNode(server, &server->adminSession, &node->nodeId, + (UA_EditNodeCallback)setDeconstructedNode, context); -static void -removeChildren(UA_Server *server, UA_Session *session, - const UA_Node *node) { /* Browse to get all children of the node */ UA_BrowseDescription bd; UA_BrowseDescription_init(&bd); @@ -34733,8 +36495,6 @@ removeChildren(UA_Server *server, UA_Session *session, bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES); bd.includeSubtypes = true; bd.browseDirection = UA_BROWSEDIRECTION_FORWARD; - bd.nodeClassMask = UA_NODECLASS_OBJECT | UA_NODECLASS_VARIABLE | UA_NODECLASS_METHOD; - bd.resultMask = UA_BROWSERESULTMASK_NONE; UA_BrowseResult br; UA_BrowseResult_init(&br); @@ -34743,60 +36503,90 @@ removeChildren(UA_Server *server, UA_Session *session, if(br.statusCode != UA_STATUSCODE_GOOD) return; - UA_DeleteNodesItem item; - item.deleteTargetReferences = true; - - /* Remove every child */ + /* Deconstruct every child node */ for(size_t i = 0; i < br.referencesSize; ++i) { UA_ReferenceDescription *rd = &br.references[i]; - // check for self-reference to avoid endless loop - if(UA_NodeId_equal(&node->nodeId, &rd->nodeId.nodeId)) + const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId); + if(!child) continue; - item.nodeId = rd->nodeId.nodeId; - UA_StatusCode retval; - deleteNodeOperation(server, session, NULL, &item, &retval); + /* Only delete child nodes that have no other parent */ + if(!multipleHierarchies(hierarchicalRefsSize, hierarchicalRefs, child)) + recursiveDeconstructNode(server, session, hierarchicalRefsSize, + hierarchicalRefs, child); + UA_Nodestore_releaseNode(server->nsCtx, child); } UA_BrowseResult_deleteMembers(&br); } static void -removeDeconstructedNode(UA_Server *server, UA_Session *session, - const UA_Node *node, UA_Boolean removeTargetRefs) { - /* Remove all children of the node */ - removeChildren(server, session, node); +recursiveDeleteNode(UA_Server *server, UA_Session *session, + size_t hierarchicalRefsSize, + UA_ExpandedNodeId *hierarchicalRefs, + const UA_Node *node, UA_Boolean removeTargetRefs) { + /* Browse to get all children of the node */ + UA_BrowseDescription bd; + UA_BrowseDescription_init(&bd); + bd.nodeId = node->nodeId; + bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_AGGREGATES); + bd.includeSubtypes = true; + bd.browseDirection = UA_BROWSEDIRECTION_FORWARD; + + UA_BrowseResult br; + UA_BrowseResult_init(&br); + UA_UInt32 maxrefs = 0; + Operation_Browse(server, session, &maxrefs, &bd, &br); + if(br.statusCode != UA_STATUSCODE_GOOD) + return; + + /* Remove every child */ + for(size_t i = 0; i < br.referencesSize; ++i) { + UA_ReferenceDescription *rd = &br.references[i]; + /* Check for self-reference to avoid endless loop */ + if(UA_NodeId_equal(&node->nodeId, &rd->nodeId.nodeId)) + continue; + const UA_Node *child = UA_Nodestore_getNode(server->nsCtx, &rd->nodeId.nodeId); + if(!child) + continue; + /* Only delete child nodes that have no other parent */ + if(!multipleHierarchies(hierarchicalRefsSize, hierarchicalRefs, child)) + recursiveDeleteNode(server, session, hierarchicalRefsSize, + hierarchicalRefs, child, true); + UA_Nodestore_releaseNode(server->nsCtx, child); + } + + UA_BrowseResult_deleteMembers(&br); - /* Remove references to the node (not the references going out, as the node - * will be deleted anyway) */ if(removeTargetRefs) removeIncomingReferences(server, session, node); - /* Remove the node in the nodestore */ - UA_Nodestore_remove(server, &node->nodeId); + UA_Nodestore_removeNode(server->nsCtx, &node->nodeId); } static void deleteNodeOperation(UA_Server *server, UA_Session *session, void *context, const UA_DeleteNodesItem *item, UA_StatusCode *result) { /* Do not check access for server */ - if(session != &server->adminSession && server->config.accessControl.allowDeleteNode && + if(session != &server->adminSession && + server->config.accessControl.allowDeleteNode && !server->config.accessControl.allowDeleteNode(server, &server->config.accessControl, - &session->sessionId, session->sessionHandle, item)) { + &session->sessionId, + session->sessionHandle, item)) { *result = UA_STATUSCODE_BADUSERACCESSDENIED; return; } - const UA_Node *node = UA_Nodestore_get(server, &item->nodeId); + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &item->nodeId); if(!node) { *result = UA_STATUSCODE_BADNODEIDUNKNOWN; return; } if(UA_Node_hasSubTypeOrInstances(node)) { - UA_LOG_INFO_SESSION(server->config.logger, session, + UA_LOG_INFO_SESSION(&server->config.logger, session, "Delete Nodes: Cannot delete a type node " "with active instances or subtypes"); - UA_Nodestore_release(server, node); + UA_Nodestore_releaseNode(server->nsCtx, node); *result = UA_STATUSCODE_BADINTERNALERROR; return; } @@ -34804,15 +36594,33 @@ deleteNodeOperation(UA_Server *server, UA_Session *session, void *context, /* TODO: Check if the information model consistency is violated */ /* TODO: Check if the node is a mandatory child of a parent */ - deconstructNode(server, session, node); - removeDeconstructedNode(server, session, node, item->deleteTargetReferences); - UA_Nodestore_release(server, node); + /* A node can be referenced with hierarchical references from several + * parents in the information model. (But not in a circular way.) The + * hierarchical references are checked to see if a node can be deleted. + * Getting the type hierarchy can fail in case of low RAM. In that case the + * nodes are always deleted. */ + UA_ExpandedNodeId *hierarchicalRefs = NULL; + size_t hierarchicalRefsSize = 0; + UA_NodeId hr = UA_NODEID_NUMERIC(0, UA_NS0ID_HIERARCHICALREFERENCES); + browseRecursive(server, 1, &hr, 1, &subtypeId, UA_BROWSEDIRECTION_FORWARD, true, + &hierarchicalRefsSize, &hierarchicalRefs); + if(!hierarchicalRefs) { + UA_LOG_WARNING_SESSION(&server->config.logger, session, + "Delete Nodes: Cannot test for hierarchical " + "references. Deleting the node and all child nodes."); + } + recursiveDeconstructNode(server, session, hierarchicalRefsSize, hierarchicalRefs, node); + recursiveDeleteNode(server, session, hierarchicalRefsSize, hierarchicalRefs, node, + item->deleteTargetReferences); + UA_Array_delete(hierarchicalRefs, hierarchicalRefsSize, &UA_TYPES[UA_TYPES_EXPANDEDNODEID]); + + UA_Nodestore_releaseNode(server->nsCtx, node); } void Service_DeleteNodes(UA_Server *server, UA_Session *session, const UA_DeleteNodesRequest *request, UA_DeleteNodesResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing DeleteNodesRequest"); if(server->config.maxNodesPerNodeManagement != 0 && @@ -34822,8 +36630,10 @@ void Service_DeleteNodes(UA_Server *server, UA_Session *session, } response->responseHeader.serviceResult = - UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)deleteNodeOperation, NULL, - &request->nodesToDeleteSize, &UA_TYPES[UA_TYPES_DELETENODESITEM], + UA_Server_processServiceOperations(server, session, + (UA_ServiceOperation)deleteNodeOperation, + NULL, &request->nodesToDeleteSize, + &UA_TYPES[UA_TYPES_DELETENODESITEM], &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); } @@ -34859,8 +36669,9 @@ Operation_addReference(UA_Server *server, UA_Session *session, void *context, const UA_AddReferencesItem *item, UA_StatusCode *retval) { /* Do not check access for server */ if(session != &server->adminSession && server->config.accessControl.allowAddReference && - !server->config.accessControl.allowAddReference(server, &server->config.accessControl, - &session->sessionId, session->sessionHandle, item)) { + !server->config.accessControl. + allowAddReference(server, &server->config.accessControl, + &session->sessionId, session->sessionHandle, item)) { *retval = UA_STATUSCODE_BADUSERACCESSDENIED; return; } @@ -34876,10 +36687,10 @@ Operation_addReference(UA_Server *server, UA_Session *session, void *context, (UA_EditNodeCallback)addOneWayReference, /* cast away const because callback uses const anyway */ (UA_AddReferencesItem *)(uintptr_t)item); - UA_Boolean firstExisted = UA_FALSE; + UA_Boolean firstExisted = false; if(*retval == UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED) { *retval = UA_STATUSCODE_GOOD; - firstExisted = UA_TRUE; + firstExisted = true; } else if(*retval != UA_STATUSCODE_GOOD) return; @@ -34895,10 +36706,10 @@ Operation_addReference(UA_Server *server, UA_Session *session, void *context, (UA_EditNodeCallback)addOneWayReference, &secondItem); /* remove reference if the second direction failed */ - UA_Boolean secondExisted = UA_FALSE; + UA_Boolean secondExisted = false; if(*retval == UA_STATUSCODE_BADDUPLICATEREFERENCENOTALLOWED) { *retval = UA_STATUSCODE_GOOD; - secondExisted = UA_TRUE; + secondExisted = true; } else if(*retval != UA_STATUSCODE_GOOD && !firstExisted) { UA_DeleteReferencesItem deleteItem; deleteItem.sourceNodeId = item->sourceNodeId; @@ -34920,7 +36731,7 @@ Operation_addReference(UA_Server *server, UA_Session *session, void *context, void Service_AddReferences(UA_Server *server, UA_Session *session, const UA_AddReferencesRequest *request, UA_AddReferencesResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing AddReferencesRequest"); if(server->config.maxNodesPerNodeManagement != 0 && @@ -34930,8 +36741,10 @@ void Service_AddReferences(UA_Server *server, UA_Session *session, } response->responseHeader.serviceResult = - UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)Operation_addReference, NULL, - &request->referencesToAddSize, &UA_TYPES[UA_TYPES_ADDREFERENCESITEM], + UA_Server_processServiceOperations(server, session, + (UA_ServiceOperation)Operation_addReference, + NULL, &request->referencesToAddSize, + &UA_TYPES[UA_TYPES_ADDREFERENCESITEM], &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); } @@ -34960,9 +36773,12 @@ static void Operation_deleteReference(UA_Server *server, UA_Session *session, void *context, const UA_DeleteReferencesItem *item, UA_StatusCode *retval) { /* Do not check access for server */ - if(session != &server->adminSession && server->config.accessControl.allowDeleteReference && - !server->config.accessControl.allowDeleteReference(server, &server->config.accessControl, - &session->sessionId, session->sessionHandle, item)) { + if(session != &server->adminSession && + server->config.accessControl.allowDeleteReference && + !server->config.accessControl.allowDeleteReference(server, + &server->config.accessControl, + &session->sessionId, + session->sessionHandle, item)) { *retval = UA_STATUSCODE_BADUSERACCESSDENIED; return; } @@ -34993,7 +36809,7 @@ void Service_DeleteReferences(UA_Server *server, UA_Session *session, const UA_DeleteReferencesRequest *request, UA_DeleteReferencesResponse *response) { - UA_LOG_DEBUG_SESSION(server->config.logger, session, + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Processing DeleteReferencesRequest"); if(server->config.maxNodesPerNodeManagement != 0 && @@ -35003,8 +36819,10 @@ Service_DeleteReferences(UA_Server *server, UA_Session *session, } response->responseHeader.serviceResult = - UA_Server_processServiceOperations(server, session, (UA_ServiceOperation)Operation_deleteReference, NULL, - &request->referencesToDeleteSize, &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM], + UA_Server_processServiceOperations(server, session, + (UA_ServiceOperation)Operation_deleteReference, + NULL, &request->referencesToDeleteSize, + &UA_TYPES[UA_TYPES_DELETEREFERENCESITEM], &response->resultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]); } @@ -35077,7 +36895,8 @@ UA_Server_addDataSourceVariableNode(UA_Server *server, const UA_NodeId requested } /* Create the node and add it to the nodestore */ - UA_StatusCode retval = AddNode_raw(server, &server->adminSession, nodeContext, &item, outNewNodeId); + UA_StatusCode retval = AddNode_raw(server, &server->adminSession, nodeContext, + &item, outNewNodeId); if(retval != UA_STATUSCODE_GOOD) goto cleanup; @@ -35087,13 +36906,13 @@ UA_Server_addDataSourceVariableNode(UA_Server *server, const UA_NodeId requested goto cleanup; /* Typecheck and add references to parent and type definition */ - retval = AddNode_typeCheckAddRefs(server, &server->adminSession, outNewNodeId, &parentNodeId, - &referenceTypeId, &typeDefinition); + retval = AddNode_addRefs(server, &server->adminSession, outNewNodeId, &parentNodeId, + &referenceTypeId, &typeDefinition); if(retval != UA_STATUSCODE_GOOD) goto cleanup; /* Call the constructors */ - retval = Operation_addNode_finish(server, &server->adminSession, outNewNodeId); + retval = AddNode_finish(server, &server->adminSession, outNewNodeId); cleanup: if(outNewNodeId == &newNodeId) @@ -35133,8 +36952,7 @@ static const UA_NodeId hasproperty = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_HASPRO static const UA_NodeId propertytype = {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_PROPERTYTYPE}}; static UA_StatusCode -UA_Server_addMethodNodeEx_finish(UA_Server *server, const UA_NodeId nodeId, - UA_MethodCallback method, +UA_Server_addMethodNodeEx_finish(UA_Server *server, const UA_NodeId nodeId, UA_MethodCallback method, const size_t inputArgumentsSize, const UA_Argument *inputArguments, const UA_NodeId inputArgumentsRequestedNewNodeId, UA_NodeId *inputArgumentsOutNewNodeId, @@ -35188,11 +37006,13 @@ UA_Server_addMethodNodeEx_finish(UA_Server *server, const UA_NodeId nodeId, UA_UInt32 inputArgsSize32 = (UA_UInt32)inputArgumentsSize; attr.arrayDimensions = &inputArgsSize32; attr.arrayDimensionsSize = 1; - UA_Variant_setArray(&attr.value, (void*)(uintptr_t) inputArguments, + UA_Variant_setArray(&attr.value, (void *)(uintptr_t)inputArguments, inputArgumentsSize, &UA_TYPES[UA_TYPES_ARGUMENT]); - retval |= UA_Server_addVariableNode(server, inputArgumentsRequestedNewNodeId, nodeId, - hasproperty, UA_QUALIFIEDNAME(0, name), - propertytype, attr, NULL, &inputArgsId); + retval = UA_Server_addVariableNode(server, inputArgumentsRequestedNewNodeId, nodeId, + hasproperty, UA_QUALIFIEDNAME(0, name), + propertytype, attr, NULL, &inputArgsId); + if(retval != UA_STATUSCODE_GOOD) + goto error; } /* Add the Output Arguments VariableNode */ @@ -35205,32 +37025,40 @@ UA_Server_addMethodNodeEx_finish(UA_Server *server, const UA_NodeId nodeId, UA_UInt32 outputArgsSize32 = (UA_UInt32)outputArgumentsSize; attr.arrayDimensions = &outputArgsSize32; attr.arrayDimensionsSize = 1; - UA_Variant_setArray(&attr.value, (void*)(uintptr_t) outputArguments, + UA_Variant_setArray(&attr.value, (void *)(uintptr_t)outputArguments, outputArgumentsSize, &UA_TYPES[UA_TYPES_ARGUMENT]); - retval |= UA_Server_addVariableNode(server, outputArgumentsRequestedNewNodeId, nodeId, - hasproperty, UA_QUALIFIEDNAME(0, name), - propertytype, attr, NULL, &outputArgsId); + retval = UA_Server_addVariableNode(server, outputArgumentsRequestedNewNodeId, nodeId, + hasproperty, UA_QUALIFIEDNAME(0, name), + propertytype, attr, NULL, &outputArgsId); + if(retval != UA_STATUSCODE_GOOD) + goto error; } - retval |= UA_Server_setMethodNode_callback(server, nodeId, method); + retval = UA_Server_setMethodNode_callback(server, nodeId, method); + if(retval != UA_STATUSCODE_GOOD) + goto error; /* Call finish to add the parent reference */ - retval |= Operation_addNode_finish(server, &server->adminSession, &nodeId); + retval = AddNode_finish(server, &server->adminSession, &nodeId); + if(retval != UA_STATUSCODE_GOOD) + goto error; - if(retval != UA_STATUSCODE_GOOD) { - UA_Server_deleteNode(server, nodeId, true); - UA_Server_deleteNode(server, inputArgsId, true); - UA_Server_deleteNode(server, outputArgsId, true); - } else { - if(inputArgumentsOutNewNodeId != NULL) { - UA_NodeId_copy(&inputArgsId, inputArgumentsOutNewNodeId); + if(inputArgumentsOutNewNodeId != NULL) { + UA_NodeId_copy(&inputArgsId, inputArgumentsOutNewNodeId); } - if(outputArgumentsOutNewNodeId != NULL) { - UA_NodeId_copy(&outputArgsId, outputArgumentsOutNewNodeId); - } + if(outputArgumentsOutNewNodeId != NULL) { + UA_NodeId_copy(&outputArgsId, outputArgumentsOutNewNodeId); } UA_BrowseResult_deleteMembers(&br); return retval; + +error: + UA_Server_deleteNode(server, nodeId, true); + UA_Server_deleteNode(server, inputArgsId, true); + UA_Server_deleteNode(server, outputArgsId, true); + UA_BrowseResult_deleteMembers(&br); + + return retval; } UA_StatusCode @@ -35271,8 +37099,9 @@ UA_Server_addMethodNodeEx(UA_Server *server, const UA_NodeId requestedNewNodeId, outNewNodeId = &newId; } - UA_StatusCode retval = Operation_addNode_begin(server, &server->adminSession, nodeContext, - &item, &parentNodeId, &referenceTypeId, outNewNodeId); + UA_StatusCode retval = Operation_addNode_begin(server, &server->adminSession, + nodeContext, &item, &parentNodeId, + &referenceTypeId, outNewNodeId); if(retval != UA_STATUSCODE_GOOD) return retval; @@ -35347,74 +37176,40 @@ UA_Server_setNodeTypeLifecycle(UA_Server *server, UA_NodeId nodeId, * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2017 (c) Stefan Profanter, fortiss GmbH - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA */ -/* Enable POSIX features */ -#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL) -# define _XOPEN_SOURCE 600 -#endif -#ifndef _DEFAULT_SOURCE -# define _DEFAULT_SOURCE -#endif -/* On older systems we need to define _BSD_SOURCE. - * _DEFAULT_SOURCE is an alias for that. */ -#ifndef _BSD_SOURCE -# define _BSD_SOURCE -#endif - #if defined(UA_ENABLE_DISCOVERY) && defined(UA_ENABLE_DISCOVERY_MULTICAST) -#ifdef _MSC_VER -# ifndef UNDER_CE -# include <io.h> //access -# define access _access -# endif -#else -# include <unistd.h> //access -# include <sys/time.h> // struct timeval -#endif - -#include <fcntl.h> -#include <errno.h> -#ifdef _WIN32 -# define CLOSESOCKET(S) closesocket((SOCKET)S) -# define errno__ WSAGetLastError() -#else -# define CLOSESOCKET(S) close(S) -# define errno__ errno -#endif - - #ifdef UA_ENABLE_MULTITHREADING static void * multicastWorkerLoop(UA_Server *server) { struct timeval next_sleep = {.tv_sec = 0, .tv_usec = 0}; - volatile UA_Boolean *running = &server->mdnsRunning; + volatile UA_Boolean *running = &server->discoveryManager.mdnsRunning; fd_set fds; while(*running) { FD_ZERO(&fds); - FD_SET(server->mdnsSocket, &fds); - select(server->mdnsSocket + 1, &fds, 0, 0, &next_sleep); + UA_fd_set(server->discoveryManager.mdnsSocket, &fds); + select(server->discoveryManager.mdnsSocket + 1, &fds, 0, 0, &next_sleep); if(!*running) break; unsigned short retVal = - mdnsd_step(server->mdnsDaemon, server->mdnsSocket, - FD_ISSET(server->mdnsSocket, &fds), true, &next_sleep); + mdnsd_step(server->discoveryManager.mdnsDaemon, server->discoveryManager.mdnsSocket, + FD_ISSET(server->discoveryManager.mdnsSocket, &fds), true, &next_sleep); if(retVal == 1) { UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast error: Can not read from socket. %s", errno_str)); break; } else if (retVal == 2) { UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast error: Can not write to socket. %s", errno_str)); break; } @@ -35424,10 +37219,10 @@ multicastWorkerLoop(UA_Server *server) { static UA_StatusCode multicastListenStart(UA_Server* server) { - int err = pthread_create(&server->mdnsThread, NULL, + int err = pthread_create(&server->discoveryManager.mdnsThread, NULL, (void* (*)(void*))multicastWorkerLoop, server); if(err != 0) { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast error: Can not create multicast thread."); return UA_STATUSCODE_BADUNEXPECTEDERROR; } @@ -35436,12 +37231,13 @@ multicastListenStart(UA_Server* server) { static UA_StatusCode multicastListenStop(UA_Server* server) { - mdnsd_shutdown(server->mdnsDaemon); + mdnsd_shutdown(server->discoveryManager.mdnsDaemon); // wake up select - write(server->mdnsSocket, "\0", 1); - if(pthread_join(server->mdnsThread, NULL)) { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, - "Multicast error: Can not stop thread."); + if (write(server->discoveryManager.mdnsSocket, "\0", 1)) { + // TODO: if makes no sense here? + } // TODO: move to arch? + if (pthread_join(server->discoveryManager.mdnsThread, NULL)) { + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast error: Can not stop thread."); return UA_STATUSCODE_BADUNEXPECTEDERROR; } return UA_STATUSCODE_BADNOTIMPLEMENTED; @@ -35458,20 +37254,27 @@ addMdnsRecordForNetworkLayer(UA_Server *server, const UA_String *appName, UA_StatusCode retval = UA_parseEndpointUrl(&nl->discoveryUrl, &hostname, &port, &path); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_NETWORK, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Server url is invalid: %.*s", (int)nl->discoveryUrl.length, nl->discoveryUrl.data); return retval; } - UA_Discovery_addRecord(server, appName, &hostname, port, - &path, UA_DISCOVERY_TCP, UA_TRUE, - server->config.serverCapabilities, - &server->config.serverCapabilitiesSize); + + retval = UA_Discovery_addRecord(server, appName, &hostname, port, + &path, UA_DISCOVERY_TCP, true, + server->config.discovery.mdns.serverCapabilities, + server->config.discovery.mdns.serverCapabilitiesSize); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_NETWORK, + "Cannot add mDNS Record: %s", + UA_StatusCode_name(retval)); + return retval; + } return UA_STATUSCODE_GOOD; } void startMulticastDiscoveryServer(UA_Server *server) { - UA_String *appName = &server->config.mdnsServerName; + UA_String *appName = &server->config.discovery.mdns.mdnsServerName; for(size_t i = 0; i < server->config.networkLayersSize; i++) addMdnsRecordForNetworkLayer(server, appName, &server->config.networkLayers[i]); @@ -35483,14 +37286,18 @@ void startMulticastDiscoveryServer(UA_Server *server) { # endif } -void stopMulticastDiscoveryServer(UA_Server *server) { +void +stopMulticastDiscoveryServer(UA_Server *server) { + if (!server->discoveryManager.mdnsDaemon) + return; + char hostname[256]; - if(gethostname(hostname, 255) == 0) { + if(UA_gethostname(hostname, 255) == 0) { UA_String hnString = UA_STRING(hostname); - UA_Discovery_removeRecord(server, &server->config.mdnsServerName, - &hnString, 4840, UA_TRUE); + UA_Discovery_removeRecord(server, &server->config.discovery.mdns.mdnsServerName, + &hnString, 4840, true); } else { - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Could not get hostname for multicast discovery."); } @@ -35498,7 +37305,7 @@ void stopMulticastDiscoveryServer(UA_Server *server) { multicastListenStop(server); # else // send out last package with TTL = 0 - iterateMulticastDiscoveryServer(server, NULL, UA_FALSE); + iterateMulticastDiscoveryServer(server, NULL, false); # endif } @@ -35518,14 +37325,20 @@ filterServerRecord(size_t serverCapabilityFilterSize, UA_String *serverCapabilit void Service_FindServersOnNetwork(UA_Server *server, UA_Session *session, const UA_FindServersOnNetworkRequest *request, UA_FindServersOnNetworkResponse *response) { + if (!server->config.discovery.mdnsEnable) { + response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTIMPLEMENTED; + return; + } + /* Set LastCounterResetTime */ - UA_DateTime_copy(&server->serverOnNetworkRecordIdLastReset, + UA_DateTime_copy(&server->discoveryManager.serverOnNetworkRecordIdLastReset, &response->lastCounterResetTime); /* Compute the max number of records to return */ UA_UInt32 recordCount = 0; - if(request->startingRecordId < server->serverOnNetworkRecordIdCounter) - recordCount = server->serverOnNetworkRecordIdCounter - request->startingRecordId; + if(request->startingRecordId < server->discoveryManager.serverOnNetworkRecordIdCounter) + recordCount = server->discoveryManager.serverOnNetworkRecordIdCounter - + request->startingRecordId; if(request->maxRecordsToReturn && recordCount > request->maxRecordsToReturn) recordCount = UA_MIN(recordCount, request->maxRecordsToReturn); if(recordCount == 0) { @@ -35537,7 +37350,7 @@ void Service_FindServersOnNetwork(UA_Server *server, UA_Session *session, UA_UInt32 filteredCount = 0; UA_STACKARRAY(UA_ServerOnNetwork*, filtered, recordCount); serverOnNetwork_list_entry* current; - LIST_FOREACH(current, &server->serverOnNetwork, pointers) { + LIST_FOREACH(current, &server->discoveryManager.serverOnNetwork, pointers) { if(filteredCount >= recordCount) break; if(current->serverOnNetwork.recordId < request->startingRecordId) @@ -35566,16 +37379,16 @@ void Service_FindServersOnNetwork(UA_Server *server, UA_Session *session, } void -UA_Discovery_update_MdnsForDiscoveryUrl(UA_Server *server, const UA_String *serverName, - const UA_MdnsDiscoveryConfiguration *mdnsConfig, - const UA_String *discoveryUrl, - UA_Boolean isOnline, UA_Boolean updateTxt) { +UA_Server_updateMdnsForDiscoveryUrl(UA_Server *server, const UA_String *serverName, + const UA_MdnsDiscoveryConfiguration *mdnsConfig, + const UA_String *discoveryUrl, + UA_Boolean isOnline, UA_Boolean updateTxt) { UA_String hostname = UA_STRING_NULL; UA_UInt16 port = 4840; UA_String path = UA_STRING_NULL; UA_StatusCode retval = UA_parseEndpointUrl(discoveryUrl, &hostname, &port, &path); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_NETWORK, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Server url invalid: %.*s", (int)discoveryUrl->length, discoveryUrl->data); return; @@ -35586,7 +37399,7 @@ UA_Discovery_update_MdnsForDiscoveryUrl(UA_Server *server, const UA_String *serv UA_Discovery_removeRecord(server, serverName, &hostname, port, updateTxt); if(removeRetval != UA_STATUSCODE_GOOD) - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "Could not remove mDNS record for hostname %.*s.", (int)serverName->length, serverName->data); return; @@ -35602,9 +37415,9 @@ UA_Discovery_update_MdnsForDiscoveryUrl(UA_Server *server, const UA_String *serv UA_StatusCode addRetval = UA_Discovery_addRecord(server, serverName, &hostname, port, &path, UA_DISCOVERY_TCP, updateTxt, - capabilities, &capabilitiesSize); + capabilities, capabilitiesSize); if(addRetval != UA_STATUSCODE_GOOD) - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "Could not add mDNS record for hostname %.*s.", (int)serverName->length, serverName->data); } @@ -35613,122 +37426,15 @@ void UA_Server_setServerOnNetworkCallback(UA_Server *server, UA_Server_serverOnNetworkCallback cb, void* data) { - server->serverOnNetworkCallback = cb; - server->serverOnNetworkCallbackData = data; -} - -static void -socket_mdns_set_nonblocking(int sockfd) { -#ifdef _WIN32 - u_long iMode = 1; - ioctlsocket(sockfd, FIONBIO, &iMode); -#else - int opts = fcntl(sockfd, F_GETFL); - fcntl(sockfd, F_SETFL, opts|O_NONBLOCK); -#endif -} - -/* Create multicast 224.0.0.251:5353 socket */ -#ifdef _WIN32 -static SOCKET -#else -static int -#endif -discovery_createMulticastSocket(void) { -#ifdef _WIN32 - SOCKET s; -#else - int s; -#endif - int flag = 1, ittl = 255; - struct sockaddr_in in; - struct ip_mreq mc; - char ttl = (char)255; // publish to complete net, not only subnet. See: - // https://docs.oracle.com/cd/E23824_01/html/821-1602/sockets-137.html - - memset(&in, 0, sizeof(in)); - in.sin_family = AF_INET; - in.sin_port = htons(5353); - in.sin_addr.s_addr = 0; - -#ifdef _WIN32 - if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) - return INVALID_SOCKET; -#else - if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) - return -1; -#endif - -#ifdef SO_REUSEPORT - setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag)); -#endif - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)); - if(bind(s, (struct sockaddr *)&in, sizeof(in))) { - CLOSESOCKET(s); -#ifdef _WIN32 - return INVALID_SOCKET; -#else - return -1; -#endif - } - - mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251"); - mc.imr_interface.s_addr = htonl(INADDR_ANY); - setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mc, sizeof(mc)); - setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl)); - setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl, sizeof(ittl)); - - socket_mdns_set_nonblocking(s); - return s; -} - - -UA_StatusCode -initMulticastDiscoveryServer(UA_Server* server) { - server->mdnsDaemon = mdnsd_new(QCLASS_IN, 1000); -#ifdef _WIN32 - WORD wVersionRequested = MAKEWORD(2, 2); - WSADATA wsaData; - WSAStartup(wVersionRequested, &wsaData); -#endif - -#ifdef _WIN32 - if((server->mdnsSocket = discovery_createMulticastSocket()) == INVALID_SOCKET) { -#else - if((server->mdnsSocket = discovery_createMulticastSocket()) < 0) { -#endif - UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, - "Could not create multicast socket. Error: %s", errno_str)); - return UA_STATUSCODE_BADUNEXPECTEDERROR; - } - mdnsd_register_receive_callback(server->mdnsDaemon, - mdns_record_received, server); - return UA_STATUSCODE_GOOD; -} - -void destroyMulticastDiscoveryServer(UA_Server* server) { - mdnsd_shutdown(server->mdnsDaemon); - mdnsd_free(server->mdnsDaemon); -#ifdef _WIN32 - if(server->mdnsSocket != INVALID_SOCKET) { -#else - if(server->mdnsSocket >= 0) { -#endif - CLOSESOCKET(server->mdnsSocket); -#ifdef _WIN32 - server->mdnsSocket = INVALID_SOCKET; -#else - server->mdnsSocket = -1; -#endif - } + server->discoveryManager.serverOnNetworkCallback = cb; + server->discoveryManager.serverOnNetworkCallbackData = data; } static void UA_Discovery_multicastConflict(char *name, int type, void *arg) { // cppcheck-suppress unreadVariable UA_Server *server = (UA_Server*) arg; - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS name conflict detected: " "'%s' for type %d", name, type); } @@ -35753,19 +37459,19 @@ createFullServiceDomain(char *outServiceDomain, size_t maxLen, } } - /* Copy into outServiceDomain */ size_t offset = 0; - memcpy(&outServiceDomain[offset], servername->data, servernameLen); - offset += servernameLen; - if(hostnameLen > 0) { - memcpy(&outServiceDomain[offset], "-", 1); - ++offset; - memcpy(&outServiceDomain[offset], hostname->data, hostnameLen); - offset += hostnameLen; + if (hostnameLen > 0) { + UA_snprintf(outServiceDomain, maxLen + 1, "%.*s-%.*s", + (int) servernameLen, (char *) servername->data, + (int) hostnameLen, (char *) hostname->data); + offset = servernameLen + hostnameLen + 1; + } + else { + UA_snprintf(outServiceDomain, maxLen + 1, "%.*s", + (int) servernameLen, (char *) servername->data); + offset = servernameLen; } - memcpy(&outServiceDomain[offset], "._opcua-tcp._tcp.local.", 23); - offset += 23; - outServiceDomain[offset] = 0; + UA_snprintf(&outServiceDomain[offset], 24, "._opcua-tcp._tcp.local."); } /* Check if mDNS already has an entry for given hostname and port combination */ @@ -35773,14 +37479,14 @@ static UA_Boolean UA_Discovery_recordExists(UA_Server* server, const char* fullServiceDomain, unsigned short port, const UA_DiscoveryProtocol protocol) { // [servername]-[hostname]._opcua-tcp._tcp.local. 86400 IN SRV 0 5 port [hostname]. - mdns_record_t *r = mdnsd_get_published(server->mdnsDaemon, fullServiceDomain); + mdns_record_t *r = mdnsd_get_published(server->discoveryManager.mdnsDaemon, fullServiceDomain); while(r) { const mdns_answer_t *data = mdnsd_record_data(r); if(data->type == QTYPE_SRV && (port == 0 || data->srv.port == port)) - return UA_TRUE; + return true; r = mdnsd_record_next(r); } - return UA_FALSE; + return false; } static int @@ -35795,25 +37501,25 @@ discovery_multicastQueryAnswer(mdns_answer_t *a, void *arg) { /* Skip, if we already know about this server */ UA_Boolean exists = UA_Discovery_recordExists(server, a->rdname, 0, UA_DISCOVERY_TCP); - if(exists == UA_TRUE) + if(exists == true) return 0; - if(mdnsd_has_query(server->mdnsDaemon, a->rdname)) + if(mdnsd_has_query(server->discoveryManager.mdnsDaemon, a->rdname)) return 0; - UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "mDNS send query for: %s SRV&TXT %s", a->name, a->rdname); - mdnsd_query(server->mdnsDaemon, a->rdname, QTYPE_SRV, + mdnsd_query(server->discoveryManager.mdnsDaemon, a->rdname, QTYPE_SRV, discovery_multicastQueryAnswer, server); - mdnsd_query(server->mdnsDaemon, a->rdname, QTYPE_TXT, + mdnsd_query(server->discoveryManager.mdnsDaemon, a->rdname, QTYPE_TXT, discovery_multicastQueryAnswer, server); return 0; } UA_StatusCode UA_Discovery_multicastQuery(UA_Server* server) { - mdnsd_query(server->mdnsDaemon, "_opcua-tcp._tcp.local.", + mdnsd_query(server->discoveryManager.mdnsDaemon, "_opcua-tcp._tcp.local.", QTYPE_PTR,discovery_multicastQueryAnswer, server); return UA_STATUSCODE_GOOD; } @@ -35823,8 +37529,12 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername, const UA_String *hostname, UA_UInt16 port, const UA_String *path, const UA_DiscoveryProtocol protocol, UA_Boolean createTxt, const UA_String* capabilites, - size_t *capabilitiesSize) { - if(!capabilitiesSize || (*capabilitiesSize > 0 && !capabilites)) + const size_t capabilitiesSize) { + // we assume that the hostname is not an IP address, but a valid domain name + // It is required by the OPC UA spec (see Part 12, DiscoveryURL to DNS SRV mapping) + // to always use the hostname instead of the IP address + + if(capabilitiesSize > 0 && !capabilites) return UA_STATUSCODE_BADINVALIDARGUMENT; size_t hostnameLen = hostname->length; @@ -35835,21 +37545,21 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername, // use a limit for the hostname length to make sure full string fits into 63 // chars (limited by DNS spec) if(hostnameLen+servernameLen + 1 > 63) { // include dash between servername-hostname - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: Combination of hostname+servername exceeds " "maximum of 62 chars. It will be truncated."); } else if(hostnameLen > 63) { - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: Hostname length exceeds maximum of 63 chars. " "It will be truncated."); } - if(!server->mdnsMainSrvAdded) { + if(!server->discoveryManager.mdnsMainSrvAdded) { mdns_record_t *r = - mdnsd_shared(server->mdnsDaemon, "_services._dns-sd._udp.local.", + mdnsd_shared(server->discoveryManager.mdnsDaemon, "_services._dns-sd._udp.local.", QTYPE_PTR, 600); - mdnsd_set_host(server->mdnsDaemon, r, "_opcua-tcp._tcp.local."); - server->mdnsMainSrvAdded = UA_TRUE; + mdnsd_set_host(server->discoveryManager.mdnsDaemon, r, "_opcua-tcp._tcp.local."); + server->discoveryManager.mdnsMainSrvAdded = true; } // [servername]-[hostname]._opcua-tcp._tcp.local. @@ -35857,10 +37567,10 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername, createFullServiceDomain(fullServiceDomain, 63+24, servername, hostname); UA_Boolean exists = UA_Discovery_recordExists(server, fullServiceDomain, port, protocol); - if(exists == UA_TRUE) + if(exists == true) return UA_STATUSCODE_GOOD; - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: add record for domain: %s", fullServiceDomain); // _services._dns-sd._udp.local. PTR _opcua-tcp._tcp.local @@ -35868,11 +37578,11 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername, // check if there is already a PTR entry for the given service. // _opcua-tcp._tcp.local. PTR [servername]-[hostname]._opcua-tcp._tcp.local. - mdns_record_t *r = mdns_find_record(server->mdnsDaemon, QTYPE_PTR, + mdns_record_t *r = mdns_find_record(server->discoveryManager.mdnsDaemon, QTYPE_PTR, "_opcua-tcp._tcp.local.", fullServiceDomain); if(!r) { - r = mdnsd_shared(server->mdnsDaemon, "_opcua-tcp._tcp.local.", QTYPE_PTR, 600); - mdnsd_set_host(server->mdnsDaemon, r, fullServiceDomain); + r = mdnsd_shared(server->discoveryManager.mdnsDaemon, "_opcua-tcp._tcp.local.", QTYPE_PTR, 600); + mdnsd_set_host(server->discoveryManager.mdnsDaemon, r, fullServiceDomain); } /* The first 63 characters of the hostname (or less) */ @@ -35883,9 +37593,9 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername, localDomain[maxHostnameLen+1] = '\0'; // [servername]-[hostname]._opcua-tcp._tcp.local. 86400 IN SRV 0 5 port [hostname]. - r = mdnsd_unique(server->mdnsDaemon, fullServiceDomain, QTYPE_SRV, 600, + r = mdnsd_unique(server->discoveryManager.mdnsDaemon, fullServiceDomain, QTYPE_SRV, 600, UA_Discovery_multicastConflict, server); - mdnsd_set_srv(server->mdnsDaemon, r, 0, 0, port, localDomain); + mdnsd_set_srv(server->discoveryManager.mdnsDaemon, r, 0, 0, port, localDomain); // A/AAAA record for all ip addresses. // [servername]-[hostname]._opcua-tcp._tcp.local. A [ip]. @@ -35895,7 +37605,8 @@ UA_Discovery_addRecord(UA_Server *server, const UA_String *servername, // TXT record: [servername]-[hostname]._opcua-tcp._tcp.local. TXT path=/ caps=NA,DA,... UA_STACKARRAY(char, pathChars, path->length + 1); if(createTxt) { - memcpy(pathChars, path->data, path->length); + if(path->length > 0) + memcpy(pathChars, path->data, path->length); pathChars[path->length] = 0; mdns_create_txt(server, fullServiceDomain, pathChars, capabilites, capabilitiesSize, UA_Discovery_multicastConflict); @@ -35916,7 +37627,7 @@ UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername, return UA_STATUSCODE_BADOUTOFRANGE; if(hostnameLen+servernameLen+1 > 63) { // include dash between servername-hostname - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: Combination of hostname+servername exceeds " "maximum of 62 chars. It will be truncated."); } @@ -35925,26 +37636,26 @@ UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername, char fullServiceDomain[63 + 24]; createFullServiceDomain(fullServiceDomain, 63+24, servername, hostname); - UA_LOG_INFO(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: remove record for domain: %s", fullServiceDomain); // _opcua-tcp._tcp.local. PTR [servername]-[hostname]._opcua-tcp._tcp.local. - mdns_record_t *r = mdns_find_record(server->mdnsDaemon, QTYPE_PTR, + mdns_record_t *r = mdns_find_record(server->discoveryManager.mdnsDaemon, QTYPE_PTR, "_opcua-tcp._tcp.local.", fullServiceDomain); if(!r) { - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: could not remove record. " "PTR Record not found for domain: %s", fullServiceDomain); return UA_STATUSCODE_BADNOTHINGTODO; } - mdnsd_done(server->mdnsDaemon, r); + mdnsd_done(server->discoveryManager.mdnsDaemon, r); // looks for [servername]-[hostname]._opcua-tcp._tcp.local. 86400 IN SRV 0 5 port hostname.local. // and TXT record: [servername]-[hostname]._opcua-tcp._tcp.local. TXT path=/ caps=NA,DA,... // and A record: [servername]-[hostname]._opcua-tcp._tcp.local. A [ip] - mdns_record_t *r2 = mdnsd_get_published(server->mdnsDaemon, fullServiceDomain); + mdns_record_t *r2 = mdnsd_get_published(server->discoveryManager.mdnsDaemon, fullServiceDomain); if(!r2) { - UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: could not remove record. Record not " "found for domain: %s", fullServiceDomain); return UA_STATUSCODE_BADNOTHINGTODO; @@ -35956,7 +37667,7 @@ UA_Discovery_removeRecord(UA_Server *server, const UA_String *servername, if((removeTxt && data->type == QTYPE_TXT) || (removeTxt && data->type == QTYPE_A) || data->srv.port == port) { - mdnsd_done(server->mdnsDaemon, r2); + mdnsd_done(server->discoveryManager.mdnsDaemon, r2); } r2 = next; } @@ -35968,16 +37679,17 @@ UA_StatusCode iterateMulticastDiscoveryServer(UA_Server* server, UA_DateTime *nextRepeat, UA_Boolean processIn) { struct timeval next_sleep = { 0, 0 }; - unsigned short retval = mdnsd_step(server->mdnsDaemon, server->mdnsSocket, + unsigned short retval = mdnsd_step(server->discoveryManager.mdnsDaemon, + (int)server->discoveryManager.mdnsSocket, processIn, true, &next_sleep); if(retval == 1) { UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast error: Can not read from socket. %s", errno_str)); return UA_STATUSCODE_BADNOCOMMUNICATION; } else if(retval == 2) { UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_ERROR(server->config.logger, UA_LOGCATEGORY_SERVER, + UA_LOG_DEBUG(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast error: Can not write to socket. %s", errno_str)); return UA_STATUSCODE_BADNOCOMMUNICATION; } @@ -35997,7 +37709,7 @@ iterateMulticastDiscoveryServer(UA_Server* server, UA_DateTime *nextRepeat, * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2015-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015-2016 (c) Sten Grüner * Copyright 2015-2016 (c) Chris Iatrou * Copyright 2015 (c) hfaham @@ -36009,48 +37721,72 @@ iterateMulticastDiscoveryServer(UA_Server* server, UA_DateTime *nextRepeat, * Copyright 2017 (c) Stefan Profanter, fortiss GmbH * Copyright 2016 (c) Lykurg * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2018 (c) Kalycito Infotech Private Limited */ + +#define STATUS_CODE_BAD_POINTER 0x01 + /********************/ /* Client Lifecycle */ /********************/ static void -UA_Client_init(UA_Client* client, UA_ClientConfig config) { +UA_Client_init(UA_Client* client) { memset(client, 0, sizeof(UA_Client)); - /* TODO: Select policy according to the endpoint */ - UA_SecurityPolicy_None(&client->securityPolicy, NULL, UA_BYTESTRING_NULL, config.logger); - client->channel.securityPolicy = &client->securityPolicy; - client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE; - client->config = config; + UA_SecureChannel_init(&client->channel); if(client->config.stateCallback) client->config.stateCallback(client, client->state); + /* Catch error during async connection */ + client->connectStatus = UA_STATUSCODE_GOOD; + + UA_Timer_init(&client->timer); + UA_WorkQueue_init(&client->workQueue); } UA_Client * -UA_Client_new(UA_ClientConfig config) { +UA_Client_new() { UA_Client *client = (UA_Client*)UA_malloc(sizeof(UA_Client)); if(!client) return NULL; - UA_Client_init(client, config); + UA_Client_init(client); return client; } static void -UA_Client_deleteMembers(UA_Client* client) { +UA_ClientConfig_deleteMembers(UA_ClientConfig *config) { + UA_ApplicationDescription_deleteMembers(&config->clientDescription); + + UA_ExtensionObject_deleteMembers(&config->userIdentityToken); + UA_String_deleteMembers(&config->securityPolicyUri); + + UA_EndpointDescription_deleteMembers(&config->endpoint); + UA_UserTokenPolicy_deleteMembers(&config->userTokenPolicy); + + if(config->certificateVerification.deleteMembers) + config->certificateVerification.deleteMembers(&config->certificateVerification); + + /* Delete the SecurityPolicies */ + if(config->securityPolicies == 0) + return; + for(size_t i = 0; i < config->securityPoliciesSize; i++) + config->securityPolicies[i].deleteMembers(&config->securityPolicies[i]); + UA_free(config->securityPolicies); + config->securityPolicies = 0; +} + +static void +UA_Client_deleteMembers(UA_Client *client) { UA_Client_disconnect(client); - client->securityPolicy.deleteMembers(&client->securityPolicy); - UA_SecureChannel_deleteMembersCleanup(&client->channel); + /* Commented as UA_SecureChannel_deleteMembers already done + * in UA_Client_disconnect function */ + //UA_SecureChannel_deleteMembersCleanup(&client->channel); + if (client->connection.free) + client->connection.free(&client->connection); UA_Connection_deleteMembers(&client->connection); - if(client->endpointUrl.data) - UA_String_deleteMembers(&client->endpointUrl); - UA_UserTokenPolicy_deleteMembers(&client->token); UA_NodeId_deleteMembers(&client->authenticationToken); - if(client->username.data) - UA_String_deleteMembers(&client->username); - if(client->password.data) - UA_String_deleteMembers(&client->password); + UA_String_deleteMembers(&client->endpointUrl); /* Delete the async service calls */ UA_Client_AsyncService_removeAll(client, UA_STATUSCODE_BADSHUTDOWN); @@ -36059,12 +37795,20 @@ UA_Client_deleteMembers(UA_Client* client) { #ifdef UA_ENABLE_SUBSCRIPTIONS UA_Client_Subscriptions_clean(client); #endif + + /* Delete the timed work */ + UA_Timer_deleteMembers(&client->timer); + + /* Clean up the work queue */ + UA_WorkQueue_cleanup(&client->workQueue); + + UA_ClientConfig_deleteMembers(&client->config); } void UA_Client_reset(UA_Client* client) { UA_Client_deleteMembers(client); - UA_Client_init(client, client->config); + UA_Client_init(client); } void @@ -36078,11 +37822,11 @@ UA_Client_getState(UA_Client *client) { return client->state; } -void * -UA_Client_getContext(UA_Client *client) { +UA_ClientConfig * +UA_Client_getConfig(UA_Client *client) { if(!client) return NULL; - return client->config.clientContext; + return &client->config; } /****************/ @@ -36104,16 +37848,13 @@ typedef struct { static UA_StatusCode sendSymmetricServiceRequest(UA_Client *client, const void *request, const UA_DataType *requestType, UA_UInt32 *requestId) { - UA_StatusCode retval; - - /* If a message is pending in the chunk don't call UA_Client_manuallyRenewSecureChannel - * to prevent incomming message desynchronization */ - if(!client->connection.pendingMessage) { - /* Make sure we have a valid session */ - retval = UA_Client_manuallyRenewSecureChannel(client); - if(retval != UA_STATUSCODE_GOOD) - return retval; - } + /* Make sure we have a valid session */ + UA_StatusCode retval = UA_STATUSCODE_GOOD; + /* FIXME: this is just a dirty workaround. We need to rework some of the sync and async processing + * FIXME: in the client. Currently a lot of stuff is semi broken and in dire need of cleaning up.*/ + /*UA_StatusCode retval = openSecureChannel(client, true); + if(retval != UA_STATUSCODE_GOOD) + return retval;*/ /* Adjusting the request header. The const attribute is violated, but we * only touch the following members: */ @@ -36124,7 +37865,7 @@ sendSymmetricServiceRequest(UA_Client *client, const void *request, /* Send the request */ UA_UInt32 rqId = ++client->requestId; - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Sending a request of type %i", requestType->typeId.identifier.numeric); if (client->channel.nextSecurityToken.tokenId != 0) // Change to the new security token if the secure channel has been renewed. @@ -36167,12 +37908,12 @@ processAsyncResponse(UA_Client *client, UA_UInt32 requestId, const UA_NodeId *re UA_init(response, ac->responseType); if(UA_NodeId_equal(responseTypeId, &serviceFaultId)) { /* Decode as a ServiceFault, i.e. only the response header */ - UA_LOG_INFO(client->config.logger, UA_LOGCATEGORY_CLIENT, - "Received a ServiceFault response"); + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Received a ServiceFault response"); responseType = &UA_TYPES[UA_TYPES_SERVICEFAULT]; } else { /* Close the connection */ - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Reply contains the wrong service response"); retval = UA_STATUSCODE_BADCOMMUNICATIONERROR; goto process; @@ -36180,20 +37921,24 @@ processAsyncResponse(UA_Client *client, UA_UInt32 requestId, const UA_NodeId *re } /* Decode the response */ - retval = UA_decodeBinary(responseMessage, offset, response, - responseType, 0, NULL); + retval = UA_decodeBinary(responseMessage, offset, response, responseType, client->config.customDataTypes); process: if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Could not decode the response with id %u due to %s", requestId, UA_StatusCode_name(retval)); ((UA_ResponseHeader*)response)->serviceResult = retval; + } else if(((UA_ResponseHeader*)response)->serviceResult != UA_STATUSCODE_GOOD) { + /* Decode as a ServiceFault, i.e. only the response header */ + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "The ServiceResult has the StatusCode %s", + UA_StatusCode_name(((UA_ResponseHeader*)response)->serviceResult)); } /* Call the callback */ - if (ac->callback) - ac->callback(client, ac->userdata, requestId, response, ac->responseType); + if(ac->callback) + ac->callback(client, ac->userdata, requestId, response); UA_deleteMembers(response, ac->responseType); /* Remove the callback */ @@ -36205,7 +37950,7 @@ processAsyncResponse(UA_Client *client, UA_UInt32 requestId, const UA_NodeId *re /* Processes the received service response. Either with an async callback or by * decoding the message and returning it "upwards" in the * SyncResponseDescription. */ -static UA_StatusCode +static void processServiceResponse(void *application, UA_SecureChannel *channel, UA_MessageType messageType, UA_UInt32 requestId, const UA_ByteString *message) { @@ -36214,18 +37959,13 @@ processServiceResponse(void *application, UA_SecureChannel *channel, /* Must be OPN or MSG */ if(messageType != UA_MESSAGETYPE_OPN && messageType != UA_MESSAGETYPE_MSG) { - UA_LOG_TRACE_CHANNEL(rd->client->config.logger, channel, + UA_LOG_TRACE_CHANNEL(&rd->client->config.logger, channel, "Invalid message type"); - return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; + return; } - /* Has the SecureChannel timed out? - * TODO: Solve this for client and server together */ - if(rd->client->state >= UA_CLIENTSTATE_SECURECHANNEL && - (channel->securityToken.createdAt + - (channel->securityToken.revisedLifetime * UA_DATETIME_MSEC)) - < UA_DateTime_nowMonotonic()) - return UA_STATUSCODE_BADSECURECHANNELCLOSED; + /* Forward declaration for the goto */ + UA_NodeId expectedNodeId = UA_NODEID_NULL; /* Decode the data type identifier of the response */ size_t offset = 0; @@ -36244,32 +37984,38 @@ processServiceResponse(void *application, UA_SecureChannel *channel, /* Got the synchronous response */ rd->received = true; - /* Forward declaration for the goto */ - UA_NodeId expectedNodeId = UA_NODEID_NUMERIC(0, rd->responseType->binaryEncodingId); - /* Check that the response type matches */ + expectedNodeId = UA_NODEID_NUMERIC(0, rd->responseType->binaryEncodingId); if(!UA_NodeId_equal(&responseId, &expectedNodeId)) { if(UA_NodeId_equal(&responseId, &serviceFaultId)) { - UA_LOG_INFO(rd->client->config.logger, UA_LOGCATEGORY_CLIENT, - "Received a ServiceFault response"); UA_init(rd->response, rd->responseType); retval = UA_decodeBinary(message, &offset, rd->response, - &UA_TYPES[UA_TYPES_SERVICEFAULT], 0, NULL); + &UA_TYPES[UA_TYPES_SERVICEFAULT], + rd->client->config.customDataTypes); + if(retval != UA_STATUSCODE_GOOD) + ((UA_ResponseHeader*)rd->response)->serviceResult = retval; + UA_LOG_INFO(&rd->client->config.logger, UA_LOGCATEGORY_CLIENT, + "Received a ServiceFault response with StatusCode %s", + UA_StatusCode_name(((UA_ResponseHeader*)rd->response)->serviceResult)); } else { /* Close the connection */ - UA_LOG_ERROR(rd->client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_ERROR(&rd->client->config.logger, UA_LOGCATEGORY_CLIENT, "Reply contains the wrong service response"); retval = UA_STATUSCODE_BADCOMMUNICATIONERROR; } goto finish; } - UA_LOG_DEBUG(rd->client->config.logger, UA_LOGCATEGORY_CLIENT, +#ifdef UA_ENABLE_TYPENAMES + UA_LOG_DEBUG(&rd->client->config.logger, UA_LOGCATEGORY_CLIENT, + "Decode a message of type %s", rd->responseType->typeName); +#else + UA_LOG_DEBUG(&rd->client->config.logger, UA_LOGCATEGORY_CLIENT, "Decode a message of type %u", responseId.identifier.numeric); +#endif /* Decode the response */ retval = UA_decodeBinary(message, &offset, rd->response, rd->responseType, - rd->client->config.customDataTypesSize, rd->client->config.customDataTypes); finish: @@ -36277,7 +38023,7 @@ finish: if(retval != UA_STATUSCODE_GOOD) { if(retval == UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED) retval = UA_STATUSCODE_BADRESPONSETOOLARGE; - UA_LOG_INFO(rd->client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_INFO(&rd->client->config.logger, UA_LOGCATEGORY_CLIENT, "Error receiving the response with status code %s", UA_StatusCode_name(retval)); @@ -36286,23 +38032,23 @@ finish: respHeader->serviceResult = retval; } } - return retval; } /* Forward complete chunks directly to the securechannel */ static UA_StatusCode client_processChunk(void *application, UA_Connection *connection, UA_ByteString *chunk) { SyncResponseDescription *rd = (SyncResponseDescription*)application; - return UA_SecureChannel_processChunk(&rd->client->channel, chunk, - processServiceResponse, - rd, UA_TRUE); + UA_StatusCode retval = UA_SecureChannel_decryptAddChunk(&rd->client->channel, chunk, true); + if(retval != UA_STATUSCODE_GOOD) + return retval; + return UA_SecureChannel_persistIncompleteMessages(&rd->client->channel); } /* Receive and process messages until a synchronous message arrives or the * timout finishes */ UA_StatusCode receiveServiceResponse(UA_Client *client, void *response, const UA_DataType *responseType, - UA_DateTime maxDate, UA_UInt32 *synchronousRequestId) { + UA_DateTime maxDate, const UA_UInt32 *synchronousRequestId) { /* Prepare the response and the structure we give into processServiceResponse */ SyncResponseDescription rd = { client, false, 0, response, responseType }; @@ -36324,11 +38070,12 @@ receiveServiceResponse(UA_Client *client, void *response, const UA_DataType *res UA_UInt32 timeout = (UA_UInt32)(((maxDate - now) + (UA_DATETIME_MSEC - 1)) / UA_DATETIME_MSEC); retval = UA_Connection_receiveChunksBlocking(&client->connection, &rd, client_processChunk, timeout); + UA_SecureChannel_processCompleteMessages(&client->channel, &rd, processServiceResponse); if(retval != UA_STATUSCODE_GOOD && retval != UA_STATUSCODE_GOODNONCRITICALTIMEOUT) { if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED) setClientState(client, UA_CLIENTSTATE_DISCONNECTED); - UA_Client_close(client); + UA_Client_disconnect(client); break; } } while(!rd.received); @@ -36350,7 +38097,7 @@ __UA_Client_Service(UA_Client *client, const void *request, respHeader->serviceResult = UA_STATUSCODE_BADREQUESTTOOLARGE; else respHeader->serviceResult = retval; - UA_Client_close(client); + UA_Client_disconnect(client); return; } @@ -36360,13 +38107,50 @@ __UA_Client_Service(UA_Client *client, const void *request, retval = receiveServiceResponse(client, response, responseType, maxDate, &requestId); if(retval == UA_STATUSCODE_GOODNONCRITICALTIMEOUT) { /* In synchronous service, if we have don't have a reply we need to close the connection */ - UA_Client_close(client); + UA_Client_disconnect(client); retval = UA_STATUSCODE_BADCONNECTIONCLOSED; } if(retval != UA_STATUSCODE_GOOD) respHeader->serviceResult = retval; } +UA_StatusCode +receiveServiceResponseAsync(UA_Client *client, void *response, + const UA_DataType *responseType) { + SyncResponseDescription rd = { client, false, 0, response, responseType }; + + UA_StatusCode retval = UA_Connection_receiveChunksNonBlocking( + &client->connection, &rd, client_processChunk); + UA_SecureChannel_processCompleteMessages(&client->channel, &rd, processServiceResponse); + /*let client run when non critical timeout*/ + if(retval != UA_STATUSCODE_GOOD + && retval != UA_STATUSCODE_GOODNONCRITICALTIMEOUT) { + if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED) { + setClientState(client, UA_CLIENTSTATE_DISCONNECTED); + } + UA_Client_disconnect(client); + } + return retval; +} + +UA_StatusCode +receivePacketAsync(UA_Client *client) { + UA_StatusCode retval = UA_STATUSCODE_GOOD; + if (UA_Client_getState(client) == UA_CLIENTSTATE_DISCONNECTED || + UA_Client_getState(client) == UA_CLIENTSTATE_WAITING_FOR_ACK) { + retval = UA_Connection_receiveChunksNonBlocking(&client->connection, client, processACKResponseAsync); + } + else if(UA_Client_getState(client) == UA_CLIENTSTATE_CONNECTED) { + retval = UA_Connection_receiveChunksNonBlocking(&client->connection, client, processOPNResponseAsync); + } + if(retval != UA_STATUSCODE_GOOD && retval != UA_STATUSCODE_GOODNONCRITICALTIMEOUT) { + if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED) + setClientState(client, UA_CLIENTSTATE_DISCONNECTED); + UA_Client_disconnect(client); + } + return retval; +} + void UA_Client_AsyncService_cancel(UA_Client *client, AsyncServiceCall *ac, UA_StatusCode statusCode) { @@ -36376,8 +38160,8 @@ UA_Client_AsyncService_cancel(UA_Client *client, AsyncServiceCall *ac, UA_init(resp, ac->responseType); ((UA_ResponseHeader*)resp)->serviceResult = statusCode; - if (ac->callback) - ac->callback(client, ac->userdata, ac->requestId, resp, ac->responseType); + if(ac->callback) + ac->callback(client, ac->userdata, ac->requestId, resp); /* Clean up the response. Users might move data into it. For whatever reasons. */ UA_deleteMembers(resp, ac->responseType); @@ -36411,8 +38195,6 @@ __UA_Client_AsyncServiceEx(UA_Client *client, const void *request, /* Call the service and set the requestId */ UA_StatusCode retval = sendSymmetricServiceRequest(client, request, requestType, &ac->requestId); if(retval != UA_STATUSCODE_GOOD) { - ac->requestId = 0; - UA_Client_AsyncService_cancel(client, ac, UA_STATUSCODE_BADTIMEOUT); UA_free(ac); return retval; } @@ -36437,113 +38219,67 @@ __UA_Client_AsyncService(UA_Client *client, const void *request, client->config.timeout); } -static void -backgroundConnectivityCallback(UA_Client *client, void *userdata, - UA_UInt32 requestId, const UA_ReadResponse *response, - const UA_DataType *responseType) { - if(response->responseHeader.serviceResult == UA_STATUSCODE_BADTIMEOUT) { - if (client->config.inactivityCallback) - client->config.inactivityCallback(client); - } - client->pendingConnectivityCheck = false; - client->lastConnectivityCheck = UA_DateTime_nowMonotonic(); -} - -static UA_StatusCode -UA_Client_backgroundConnectivity(UA_Client *client) { - if(!client->config.connectivityCheckInterval) - return UA_STATUSCODE_GOOD; - - if (client->pendingConnectivityCheck) - return UA_STATUSCODE_GOOD; - - UA_DateTime now = UA_DateTime_nowMonotonic(); - UA_DateTime nextDate = client->lastConnectivityCheck + (UA_DateTime)(client->config.connectivityCheckInterval * UA_DATETIME_MSEC); - if(now <= nextDate) +UA_StatusCode +UA_Client_sendAsyncRequest(UA_Client *client, const void *request, + const UA_DataType *requestType, + UA_ClientAsyncServiceCallback callback, + const UA_DataType *responseType, void *userdata, + UA_UInt32 *requestId) { + if (UA_Client_getState(client) < UA_CLIENTSTATE_SECURECHANNEL) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Cient must be connected to send high-level requests"); return UA_STATUSCODE_GOOD; - - UA_ReadRequest request; - UA_ReadRequest_init(&request); - - UA_ReadValueId rvid; - UA_ReadValueId_init(&rvid); - rvid.attributeId = UA_ATTRIBUTEID_VALUE; - rvid.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE); - - request.nodesToRead = &rvid; - request.nodesToReadSize = 1; - - UA_StatusCode retval = __UA_Client_AsyncService(client, &request, &UA_TYPES[UA_TYPES_READREQUEST], - (UA_ClientAsyncServiceCallback)backgroundConnectivityCallback, - &UA_TYPES[UA_TYPES_READRESPONSE], NULL, NULL); - - client->pendingConnectivityCheck = true; - - return retval; + } + return __UA_Client_AsyncService(client, request, requestType, callback, + responseType, userdata, requestId); } -static void -asyncServiceTimeoutCheck(UA_Client *client) { - UA_DateTime now = UA_DateTime_nowMonotonic(); - - /* Timeout occurs, remove the callback */ - AsyncServiceCall *ac, *ac_tmp; - LIST_FOREACH_SAFE(ac, &client->asyncServiceCalls, pointers, ac_tmp) { - if (!ac->timeout) - continue; - - if (ac->start + (UA_DateTime)(ac->timeout * UA_DATETIME_MSEC) <= now) { - LIST_REMOVE(ac, pointers); - UA_Client_AsyncService_cancel(client, ac, UA_STATUSCODE_BADTIMEOUT); - UA_free(ac); - } - } +UA_StatusCode UA_EXPORT +UA_Client_addTimedCallback(UA_Client *client, UA_ClientCallback callback, + void *data, UA_DateTime date, UA_UInt64 *callbackId) { + return UA_Timer_addTimedCallback(&client->timer, (UA_ApplicationCallback) callback, + client, data, date, callbackId); } UA_StatusCode -UA_Client_runAsync(UA_Client *client, UA_UInt16 timeout) { - /* TODO: Call repeated jobs that are scheduled */ -#ifdef UA_ENABLE_SUBSCRIPTIONS - UA_StatusCode retvalPublish = UA_Client_Subscriptions_backgroundPublish(client); - if (retvalPublish != UA_STATUSCODE_GOOD) - return retvalPublish; -#endif - UA_StatusCode retval = UA_Client_manuallyRenewSecureChannel(client); - if (retval != UA_STATUSCODE_GOOD) - return retval; +UA_Client_addRepeatedCallback(UA_Client *client, UA_ClientCallback callback, + void *data, UA_Double interval_ms, UA_UInt64 *callbackId) { + return UA_Timer_addRepeatedCallback(&client->timer, (UA_ApplicationCallback) callback, + client, data, interval_ms, callbackId); +} - retval = UA_Client_backgroundConnectivity(client); - if(retval != UA_STATUSCODE_GOOD) - return retval; +UA_StatusCode +UA_Client_changeRepeatedCallbackInterval(UA_Client *client, UA_UInt64 callbackId, + UA_Double interval_ms) { + return UA_Timer_changeRepeatedCallbackInterval(&client->timer, callbackId, + interval_ms); +} - UA_DateTime maxDate = UA_DateTime_nowMonotonic() + (timeout * UA_DATETIME_MSEC); - retval = receiveServiceResponse(client, NULL, NULL, maxDate, NULL); - if(retval == UA_STATUSCODE_GOODNONCRITICALTIMEOUT) - retval = UA_STATUSCODE_GOOD; -#ifdef UA_ENABLE_SUBSCRIPTIONS - /* The inactivity check must be done after receiveServiceResponse */ - UA_Client_Subscriptions_backgroundPublishInactivityCheck(client); -#endif - asyncServiceTimeoutCheck(client); - return retval; +void +UA_Client_removeCallback(UA_Client *client, UA_UInt64 callbackId) { + UA_Timer_removeCallback(&client->timer, callbackId); } /*********************************** amalgamated original file "/home/jvoe/open62541/src/client/ua_client_connect.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2017-2019 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2018 (c) Kalycito Infotech Private Limited */ -#define UA_MINMESSAGESIZE 8192 +/* Size are refered in bytes */ +#define UA_MINMESSAGESIZE 8192 +#define UA_SESSION_LOCALNONCELENGTH 32 +#define MAX_DATA_SIZE 4096 /********************/ /* Set client state */ @@ -36561,8 +38297,8 @@ setClientState(UA_Client *client, UA_ClientState state) { /* Open the Connection */ /***********************/ -#define UA_BITMASK_MESSAGETYPE 0x00ffffff -#define UA_BITMASK_CHUNKTYPE 0xff000000 +#define UA_BITMASK_MESSAGETYPE 0x00ffffffu +#define UA_BITMASK_CHUNKTYPE 0xff000000u static UA_StatusCode processACKResponse(void *application, UA_Connection *connection, UA_ByteString *chunk) { @@ -36575,8 +38311,8 @@ processACKResponse(void *application, UA_Connection *connection, UA_ByteString * UA_TcpAcknowledgeMessage ackMessage; retval = UA_TcpMessageHeader_decodeBinary(chunk, &offset, &messageHeader); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO(client->config.logger, UA_LOGCATEGORY_NETWORK, - "Decoding ACK message failed"); + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK, + "Decoding ACK message failed"); return retval; } @@ -36590,39 +38326,30 @@ processACKResponse(void *application, UA_Connection *connection, UA_ByteString * UA_StatusCode error = *(UA_StatusCode*)(&chunk->data[offset]); UA_UInt32 len = *((UA_UInt32*)&chunk->data[offset + 4]); UA_Byte *data = (UA_Byte*)&chunk->data[offset + 4+4]; - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_NETWORK, + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Received ERR response. %s - %.*s", UA_StatusCode_name(error), len, data); - return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; + return error; } if (chunkType != UA_CHUNKTYPE_FINAL) { return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID; } - retval |= UA_TcpAcknowledgeMessage_decodeBinary(chunk, &offset, &ackMessage); + /* Decode the ACK message */ + retval = UA_TcpAcknowledgeMessage_decodeBinary(chunk, &offset, &ackMessage); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO(client->config.logger, UA_LOGCATEGORY_NETWORK, - "Decoding ACK message failed"); + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK, + "Decoding ACK message failed"); return retval; } + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Received ACK message"); - /* Store remote connection settings and adjust local configuration to not - * exceed the limits */ - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_NETWORK, "Received ACK message"); - connection->remoteConf.maxChunkCount = ackMessage.maxChunkCount; /* may be zero -> unlimited */ - connection->remoteConf.maxMessageSize = ackMessage.maxMessageSize; /* may be zero -> unlimited */ - connection->remoteConf.protocolVersion = ackMessage.protocolVersion; - connection->remoteConf.sendBufferSize = ackMessage.sendBufferSize; - connection->remoteConf.recvBufferSize = ackMessage.receiveBufferSize; - if(connection->remoteConf.recvBufferSize < connection->localConf.sendBufferSize) - connection->localConf.sendBufferSize = connection->remoteConf.recvBufferSize; - if(connection->remoteConf.sendBufferSize < connection->localConf.recvBufferSize) - connection->localConf.recvBufferSize = connection->remoteConf.sendBufferSize; - connection->state = UA_CONNECTION_ESTABLISHED; - return UA_STATUSCODE_GOOD; + /* Process the ACK message */ + return UA_Connection_processHELACK(connection, &client->config.localConnectionConfig, + (const UA_ConnectionConfig*)&ackMessage); } static UA_StatusCode -HelAckHandshake(UA_Client *client) { +HelAckHandshake(UA_Client *client, const UA_String endpointUrl) { /* Get a buffer */ UA_ByteString message; UA_Connection *conn = &client->connection; @@ -36632,24 +38359,28 @@ HelAckHandshake(UA_Client *client) { /* Prepare the HEL message and encode at offset 8 */ UA_TcpHelloMessage hello; - UA_String_copy(&client->endpointUrl, &hello.endpointUrl); /* must be less than 4096 bytes */ - hello.maxChunkCount = conn->localConf.maxChunkCount; - hello.maxMessageSize = conn->localConf.maxMessageSize; - hello.protocolVersion = conn->localConf.protocolVersion; - hello.receiveBufferSize = conn->localConf.recvBufferSize; - hello.sendBufferSize = conn->localConf.sendBufferSize; + /* just reference to avoid copy */ + hello.endpointUrl = endpointUrl; + memcpy(&hello, &client->config.localConnectionConfig, + sizeof(UA_ConnectionConfig)); /* same struct layout */ UA_Byte *bufPos = &message.data[8]; /* skip the header */ const UA_Byte *bufEnd = &message.data[message.length]; - retval = UA_TcpHelloMessage_encodeBinary(&hello, &bufPos, &bufEnd); + retval = UA_TcpHelloMessage_encodeBinary(&hello, &bufPos, bufEnd); + /* avoid deleting reference */ + hello.endpointUrl = UA_STRING_NULL; UA_TcpHelloMessage_deleteMembers(&hello); + if(retval != UA_STATUSCODE_GOOD) { + conn->releaseSendBuffer(conn, &message); + return retval; + } /* Encode the message header at offset 0 */ UA_TcpMessageHeader messageHeader; messageHeader.messageTypeAndChunkType = UA_CHUNKTYPE_FINAL + UA_MESSAGETYPE_HEL; messageHeader.messageSize = (UA_UInt32)((uintptr_t)bufPos - (uintptr_t)message.data); bufPos = message.data; - retval |= UA_TcpMessageHeader_encodeBinary(&messageHeader, &bufPos, &bufEnd); + retval = UA_TcpMessageHeader_encodeBinary(&messageHeader, &bufPos, bufEnd); if(retval != UA_STATUSCODE_GOOD) { conn->releaseSendBuffer(conn, &message); return retval; @@ -36659,33 +38390,43 @@ HelAckHandshake(UA_Client *client) { message.length = messageHeader.messageSize; retval = conn->send(conn, &message); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO(client->config.logger, UA_LOGCATEGORY_NETWORK, - "Sending HEL failed"); + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK, + "Sending HEL failed"); return retval; } - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_NETWORK, + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Sent HEL message"); /* Loop until we have a complete chunk */ retval = UA_Connection_receiveChunksBlocking(conn, client, processACKResponse, client->config.timeout); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_INFO(client->config.logger, UA_LOGCATEGORY_NETWORK, - "Receiving ACK message failed"); + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK, + "Receiving ACK message failed with %s", UA_StatusCode_name(retval)); if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED) client->state = UA_CLIENTSTATE_DISCONNECTED; - UA_Client_close(client); + UA_Client_disconnect(client); } return retval; } +UA_SecurityPolicy * +getSecurityPolicy(UA_Client *client, UA_String policyUri) { + for(size_t i = 0; i < client->config.securityPoliciesSize; i++) { + if(UA_String_equal(&policyUri, &client->config.securityPolicies[i].policyUri)) + return &client->config.securityPolicies[i]; + } + return NULL; +} + static void -processDecodedOPNResponse(UA_Client *client, UA_OpenSecureChannelResponse *response, UA_Boolean renew) { +processDecodedOPNResponse(UA_Client *client, UA_OpenSecureChannelResponse *response, + UA_Boolean renew) { /* Replace the token */ - if (renew) - client->channel.nextSecurityToken = response->securityToken; // Set the next token + if(renew) + client->channel.nextSecurityToken = response->securityToken; else - client->channel.securityToken = response->securityToken; // Set initial token + client->channel.securityToken = response->securityToken; /* Replace the nonce */ UA_ByteString_deleteMembers(&client->channel.remoteNonce); @@ -36693,11 +38434,13 @@ processDecodedOPNResponse(UA_Client *client, UA_OpenSecureChannelResponse *respo UA_ByteString_init(&response->serverNonce); if(client->channel.state == UA_SECURECHANNELSTATE_OPEN) - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, - "SecureChannel in the server renewed"); + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "SecureChannel renewed"); else - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, - "Opened SecureChannel acknowledged by the server"); + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Opened SecureChannel with SecurityPolicy %.*s", + (int)client->channel.securityPolicy->policyUri.length, + client->channel.securityPolicy->policyUri.data); /* Response.securityToken.revisedLifetime is UInt32 we need to cast it to * DateTime=Int64 we take 75% of lifetime to start renewing as described in @@ -36707,7 +38450,7 @@ processDecodedOPNResponse(UA_Client *client, UA_OpenSecureChannelResponse *respo (client->channel.securityToken.revisedLifetime * (UA_Double)UA_DATETIME_MSEC * 0.75); } -static UA_StatusCode +UA_StatusCode openSecureChannel(UA_Client *client, UA_Boolean renew) { /* Check if sc is still valid */ if(renew && client->nextChannelRenewal > UA_DateTime_nowMonotonic()) @@ -36724,14 +38467,17 @@ openSecureChannel(UA_Client *client, UA_Boolean renew) { opnSecRq.requestHeader.authenticationToken = client->authenticationToken; if(renew) { opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_RENEW; - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "Requesting to renew the SecureChannel"); } else { opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE; - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "Requesting to open a SecureChannel"); } - opnSecRq.securityMode = UA_MESSAGESECURITYMODE_NONE; + + /* Set the securityMode to input securityMode from client data */ + opnSecRq.securityMode = client->channel.securityMode; + opnSecRq.clientNonce = client->channel.localNonce; opnSecRq.requestedLifetime = client->config.secureChannelLifeTime; @@ -36741,13 +38487,13 @@ openSecureChannel(UA_Client *client, UA_Boolean renew) { UA_SecureChannel_sendAsymmetricOPNMessage(&client->channel, requestId, &opnSecRq, &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]); if(retval != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "Sending OPN message failed with error %s", UA_StatusCode_name(retval)); - UA_Client_close(client); + UA_Client_disconnect(client); return retval; } - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "OPN message sent"); + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "OPN message sent"); /* Increase nextChannelRenewal to avoid that we re-start renewal when * publish responses are received before the OPN response arrives. */ @@ -36764,7 +38510,9 @@ openSecureChannel(UA_Client *client, UA_Boolean renew) { &requestId); if(retval != UA_STATUSCODE_GOOD) { - UA_Client_close(client); + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + "Receiving service response failed with error %s", UA_StatusCode_name(retval)); + UA_Client_disconnect(client); return retval; } @@ -36773,6 +38521,186 @@ openSecureChannel(UA_Client *client, UA_Boolean renew) { return retval; } +/* Function to verify the signature corresponds to ClientNonce + * using the local certificate */ +static UA_StatusCode +checkClientSignature(const UA_SecureChannel *channel, + const UA_CreateSessionResponse *response) { + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN && + channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return UA_STATUSCODE_GOOD; + + if(!channel->securityPolicy) + return UA_STATUSCODE_BADINTERNALERROR; + + const UA_SecurityPolicy *sp = channel->securityPolicy; + const UA_ByteString *lc = &sp->localCertificate; + + size_t dataToVerifySize = lc->length + channel->localNonce.length; + UA_ByteString dataToVerify = UA_BYTESTRING_NULL; + UA_StatusCode retval = UA_ByteString_allocBuffer(&dataToVerify, dataToVerifySize); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + memcpy(dataToVerify.data, lc->data, lc->length); + memcpy(dataToVerify.data + lc->length, + channel->localNonce.data, channel->localNonce.length); + + retval = sp->certificateSigningAlgorithm. + verify(sp, channel->channelContext, &dataToVerify, + &response->serverSignature.signature); + UA_ByteString_deleteMembers(&dataToVerify); + return retval; +} + +/* Function to create a signature using remote certificate and nonce */ +#ifdef UA_ENABLE_ENCRYPTION +UA_StatusCode +signActivateSessionRequest(UA_SecureChannel *channel, + UA_ActivateSessionRequest *request) { + if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN && + channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) + return UA_STATUSCODE_GOOD; + + const UA_SecurityPolicy *sp = channel->securityPolicy; + UA_SignatureData *sd = &request->clientSignature; + + /* Prepare the signature */ + size_t signatureSize = sp->certificateSigningAlgorithm. + getLocalSignatureSize(sp, channel->channelContext); + UA_StatusCode retval = UA_String_copy(&sp->certificateSigningAlgorithm.uri, + &sd->algorithm); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = UA_ByteString_allocBuffer(&sd->signature, signatureSize); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* Allocate a temporary buffer */ + size_t dataToSignSize = channel->remoteCertificate.length + channel->remoteNonce.length; + if(dataToSignSize > MAX_DATA_SIZE) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString dataToSign; + retval = UA_ByteString_allocBuffer(&dataToSign, dataToSignSize); + if(retval != UA_STATUSCODE_GOOD) + return retval; /* sd->signature is cleaned up with the response */ + + /* Sign the signature */ + memcpy(dataToSign.data, channel->remoteCertificate.data, + channel->remoteCertificate.length); + memcpy(dataToSign.data + channel->remoteCertificate.length, + channel->remoteNonce.data, channel->remoteNonce.length); + retval = sp->certificateSigningAlgorithm.sign(sp, channel->channelContext, + &dataToSign, &sd->signature); + + /* Clean up */ + UA_ByteString_deleteMembers(&dataToSign); + return retval; +} + +UA_StatusCode +encryptUserIdentityToken(UA_Client *client, const UA_String *userTokenSecurityPolicy, + UA_ExtensionObject *userIdentityToken) { + UA_IssuedIdentityToken *iit = NULL; + UA_UserNameIdentityToken *unit = NULL; + UA_ByteString *tokenData; + if(userIdentityToken->content.decoded.type == &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]) { + iit = (UA_IssuedIdentityToken*)userIdentityToken->content.decoded.data; + tokenData = &iit->tokenData; + } else if(userIdentityToken->content.decoded.type == &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) { + unit = (UA_UserNameIdentityToken*)userIdentityToken->content.decoded.data; + tokenData = &unit->password; + } else { + return UA_STATUSCODE_GOOD; + } + + /* No encryption */ + const UA_String none = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None"); + if(userTokenSecurityPolicy->length == 0 || + UA_String_equal(userTokenSecurityPolicy, &none)) { + return UA_STATUSCODE_GOOD; + } + + UA_SecurityPolicy *sp = getSecurityPolicy(client, *userTokenSecurityPolicy); + if(!sp) { + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_NETWORK, + "Could not find the required SecurityPolicy for the UserToken"); + return UA_STATUSCODE_BADSECURITYPOLICYREJECTED; + } + + /* Create a temp channel context */ + + void *channelContext; + UA_StatusCode retval = sp->channelModule. + newContext(sp, &client->config.endpoint.serverCertificate, &channelContext); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_NETWORK, + "Could not instantiate the SecurityPolicy for the UserToken"); + return UA_STATUSCODE_BADINTERNALERROR; + } + + /* Compute the encrypted length (at least one byte padding) */ + size_t plainTextBlockSize = sp->asymmetricModule.cryptoModule. + encryptionAlgorithm.getRemotePlainTextBlockSize(sp, channelContext); + UA_UInt32 length = (UA_UInt32)(tokenData->length + client->channel.remoteNonce.length); + UA_UInt32 totalLength = length + 4; /* Including the length field */ + size_t blocks = totalLength / plainTextBlockSize; + if(totalLength % plainTextBlockSize != 0) + blocks++; + size_t overHead = + UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(sp, channelContext, + blocks * plainTextBlockSize); + + /* Allocate memory for encryption overhead */ + UA_ByteString encrypted; + retval = UA_ByteString_allocBuffer(&encrypted, (blocks * plainTextBlockSize) + overHead); + if(retval != UA_STATUSCODE_GOOD) { + sp->channelModule.deleteContext(channelContext); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + + UA_Byte *pos = encrypted.data; + const UA_Byte *end = &encrypted.data[encrypted.length]; + UA_UInt32_encodeBinary(&length, &pos, end); + memcpy(pos, tokenData->data, tokenData->length); + memcpy(&pos[tokenData->length], client->channel.remoteNonce.data, + client->channel.remoteNonce.length); + + /* Add padding + * + * 7.36.2.2 Legacy Encrypted Token Secret Format: A Client should not add any + * padding after the secret. If a Client adds padding then all bytes shall + * be zero. A Server shall check for padding added by Clients and ensure + * that all padding bytes are zeros. */ + size_t paddedLength = plainTextBlockSize * blocks; + for(size_t i = totalLength; i < paddedLength; i++) + encrypted.data[i] = 0; + encrypted.length = paddedLength; + + retval = sp->asymmetricModule.cryptoModule.encryptionAlgorithm.encrypt(sp, channelContext, + &encrypted); + encrypted.length = (blocks * plainTextBlockSize) + overHead; + + if(iit) { + retval |= UA_String_copy(&sp->asymmetricModule.cryptoModule.encryptionAlgorithm.uri, + &iit->encryptionAlgorithm); + } else { + retval |= UA_String_copy(&sp->asymmetricModule.cryptoModule.encryptionAlgorithm.uri, + &unit->encryptionAlgorithm); + } + + UA_ByteString_deleteMembers(tokenData); + *tokenData = encrypted; + + /* Delete the temp channel context */ + sp->channelModule.deleteContext(channelContext); + + return retval; +} +#endif + static UA_StatusCode activateSession(UA_Client *client) { UA_ActivateSessionRequest request; @@ -36780,24 +38708,42 @@ activateSession(UA_Client *client) { request.requestHeader.requestHandle = ++client->requestHandle; request.requestHeader.timestamp = UA_DateTime_now(); request.requestHeader.timeoutHint = 600000; + UA_StatusCode retval = + UA_ExtensionObject_copy(&client->config.userIdentityToken, &request.userIdentityToken); + if(retval != UA_STATUSCODE_GOOD) + return retval; - //manual ExtensionObject encoding of the identityToken - if(client->authenticationMethod == UA_CLIENTAUTHENTICATION_NONE) { - UA_AnonymousIdentityToken* identityToken = UA_AnonymousIdentityToken_new(); - UA_AnonymousIdentityToken_init(identityToken); - UA_String_copy(&client->token.policyId, &identityToken->policyId); - request.userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED; + /* If not token is set, use anonymous */ + if(request.userIdentityToken.encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY) { + UA_AnonymousIdentityToken *t = UA_AnonymousIdentityToken_new(); + if(!t) { + UA_ActivateSessionRequest_deleteMembers(&request); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + request.userIdentityToken.content.decoded.data = t; request.userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]; - request.userIdentityToken.content.decoded.data = identityToken; - } else { - UA_UserNameIdentityToken* identityToken = UA_UserNameIdentityToken_new(); - UA_UserNameIdentityToken_init(identityToken); - UA_String_copy(&client->token.policyId, &identityToken->policyId); - UA_String_copy(&client->username, &identityToken->userName); - UA_String_copy(&client->password, &identityToken->password); request.userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED; - request.userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]; - request.userIdentityToken.content.decoded.data = identityToken; + } + + /* Set the policy-Id from the endpoint. Every IdentityToken starts with a + * string. */ + retval = UA_String_copy(&client->config.userTokenPolicy.policyId, + (UA_String*)request.userIdentityToken.content.decoded.data); + +#ifdef UA_ENABLE_ENCRYPTION + /* Encrypt the UserIdentityToken */ + const UA_String *userTokenPolicy = &client->channel.securityPolicy->policyUri; + if(client->config.userTokenPolicy.securityPolicyUri.length > 0) + userTokenPolicy = &client->config.userTokenPolicy.securityPolicyUri; + retval |= encryptUserIdentityToken(client, userTokenPolicy, &request.userIdentityToken); + + /* This function call is to prepare a client signature */ + retval |= signActivateSessionRequest(&client->channel, &request); +#endif + + if(retval != UA_STATUSCODE_GOOD) { + UA_ActivateSessionRequest_deleteMembers(&request); + return retval; } UA_ActivateSessionResponse response; @@ -36805,12 +38751,12 @@ activateSession(UA_Client *client) { &response, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, "ActivateSession failed with error code %s", UA_StatusCode_name(response.responseHeader.serviceResult)); } - UA_StatusCode retval = response.responseHeader.serviceResult; + retval = response.responseHeader.serviceResult; UA_ActivateSessionRequest_deleteMembers(&request); UA_ActivateSessionResponse_deleteMembers(&response); return retval; @@ -36818,14 +38764,15 @@ activateSession(UA_Client *client) { /* Gets a list of endpoints. Memory is allocated for endpointDescription array */ UA_StatusCode -UA_Client_getEndpointsInternal(UA_Client *client, size_t* endpointDescriptionsSize, - UA_EndpointDescription** endpointDescriptions) { +UA_Client_getEndpointsInternal(UA_Client *client, const UA_String endpointUrl, + size_t *endpointDescriptionsSize, + UA_EndpointDescription **endpointDescriptions) { UA_GetEndpointsRequest request; UA_GetEndpointsRequest_init(&request); request.requestHeader.timestamp = UA_DateTime_now(); request.requestHeader.timeoutHint = 10000; // assume the endpointurl outlives the service call - request.endpointUrl = client->endpointUrl; + request.endpointUrl = endpointUrl; UA_GetEndpointsResponse response; __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST], @@ -36833,7 +38780,7 @@ UA_Client_getEndpointsInternal(UA_Client *client, size_t* endpointDescriptionsSi if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) { UA_StatusCode retval = response.responseHeader.serviceResult; - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, "GetEndpointRequest failed with error code %s", UA_StatusCode_name(retval)); UA_GetEndpointsResponse_deleteMembers(&response); @@ -36848,67 +38795,166 @@ UA_Client_getEndpointsInternal(UA_Client *client, size_t* endpointDescriptionsSi } static UA_StatusCode -getEndpoints(UA_Client *client) { +selectEndpoint(UA_Client *client, const UA_String endpointUrl) { UA_EndpointDescription* endpointArray = NULL; size_t endpointArraySize = 0; UA_StatusCode retval = - UA_Client_getEndpointsInternal(client, &endpointArraySize, &endpointArray); + UA_Client_getEndpointsInternal(client, endpointUrl, + &endpointArraySize, &endpointArray); if(retval != UA_STATUSCODE_GOOD) return retval; UA_Boolean endpointFound = false; UA_Boolean tokenFound = false; - UA_String securityNone = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None"); UA_String binaryTransport = UA_STRING("http://opcfoundation.org/UA-Profile/" "Transport/uatcp-uasc-uabinary"); - // TODO: compare endpoint information with client->endpointUri + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Found %lu endpoints", (long unsigned)endpointArraySize); for(size_t i = 0; i < endpointArraySize; ++i) { UA_EndpointDescription* endpoint = &endpointArray[i]; - /* look out for binary transport endpoints */ - /* Note: Siemens returns empty ProfileUrl, we will accept it as binary */ + /* Match Binary TransportProfile? + * Note: Siemens returns empty ProfileUrl, we will accept it as binary */ if(endpoint->transportProfileUri.length != 0 && !UA_String_equal(&endpoint->transportProfileUri, &binaryTransport)) continue; - /* look out for an endpoint without security */ - if(!UA_String_equal(&endpoint->securityPolicyUri, &securityNone)) + + /* Valid SecurityMode? */ + if(endpoint->securityMode < 1 || endpoint->securityMode > 3) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting endpoint %lu: invalid security mode", (long unsigned)i); continue; + } + + /* Selected SecurityMode? */ + if(client->config.securityMode > 0 && + client->config.securityMode != endpoint->securityMode) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting endpoint %lu: security mode doesn't match", (long unsigned)i); + continue; + } + + /* Matching SecurityPolicy? */ + if(client->config.securityPolicyUri.length > 0 && + !UA_String_equal(&client->config.securityPolicyUri, + &endpoint->securityPolicyUri)) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting endpoint %lu: security policy doesn't match", (long unsigned)i); + continue; + } + + /* SecurityPolicy available? */ + if(!getSecurityPolicy(client, endpoint->securityPolicyUri)) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting endpoint %lu: security policy not available", (long unsigned)i); + continue; + } - /* endpoint with no security found */ endpointFound = true; - /* look for a user token policy with an anonymous token */ + /* Select a matching UserTokenPolicy inside the endpoint */ + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Endpoint %lu has %lu user token policies", (long unsigned)i, (long unsigned)endpoint->userIdentityTokensSize); for(size_t j = 0; j < endpoint->userIdentityTokensSize; ++j) { UA_UserTokenPolicy* userToken = &endpoint->userIdentityTokens[j]; /* Usertokens also have a security policy... */ - if(userToken->securityPolicyUri.length > 0 && - !UA_String_equal(&userToken->securityPolicyUri, &securityNone)) + if (userToken->securityPolicyUri.length > 0 && + !getSecurityPolicy(client, userToken->securityPolicyUri)) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting UserTokenPolicy %lu in endpoint %lu: security policy '%.*s' not available", + (long unsigned)j, (long unsigned)i, + (int)userToken->securityPolicyUri.length, userToken->securityPolicyUri.data); continue; + } - /* UA_CLIENTAUTHENTICATION_NONE == UA_USERTOKENTYPE_ANONYMOUS - * UA_CLIENTAUTHENTICATION_USERNAME == UA_USERTOKENTYPE_USERNAME - * TODO: Check equivalence for other types when adding the support */ - if((int)client->authenticationMethod != (int)userToken->tokenType) + if(userToken->tokenType > 3) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting UserTokenPolicy %lu in endpoint %lu: invalid token type", (long unsigned)j, (long unsigned)i); continue; + } - /* Endpoint with matching usertokenpolicy found */ + /* Does the token type match the client configuration? */ + if (userToken->tokenType == UA_USERTOKENTYPE_ANONYMOUS && + client->config.userIdentityToken.content.decoded.type != &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN] && + client->config.userIdentityToken.content.decoded.type != NULL) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting UserTokenPolicy %lu (anonymous) in endpoint %lu: configuration doesn't match", (long unsigned)j, (long unsigned)i); + continue; + } + if (userToken->tokenType == UA_USERTOKENTYPE_USERNAME && + client->config.userIdentityToken.content.decoded.type != &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting UserTokenPolicy %lu (username) in endpoint %lu: configuration doesn't match", (long unsigned)j, (long unsigned)i); + continue; + } + if (userToken->tokenType == UA_USERTOKENTYPE_CERTIFICATE && + client->config.userIdentityToken.content.decoded.type != &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting UserTokenPolicy %lu (certificate) in endpoint %lu: configuration doesn't match", (long unsigned)j, (long unsigned)i); + continue; + } + if (userToken->tokenType == UA_USERTOKENTYPE_ISSUEDTOKEN && + client->config.userIdentityToken.content.decoded.type != &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN]) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Rejecting UserTokenPolicy %lu (token) in endpoint %lu: configuration doesn't match", (long unsigned)j, (long unsigned)i); + continue; + } + + /* Endpoint with matching UserTokenPolicy found. Copy to the configuration. */ tokenFound = true; - UA_UserTokenPolicy_deleteMembers(&client->token); - UA_UserTokenPolicy_copy(userToken, &client->token); + UA_EndpointDescription_deleteMembers(&client->config.endpoint); + UA_EndpointDescription temp = *endpoint; + temp.userIdentityTokensSize = 0; + temp.userIdentityTokens = NULL; + UA_UserTokenPolicy_deleteMembers(&client->config.userTokenPolicy); + + retval = UA_EndpointDescription_copy(&temp, &client->config.endpoint); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Copying endpoint description failed with error code %s", + UA_StatusCode_name(retval)); + break; + } + + retval = UA_UserTokenPolicy_copy(userToken, &client->config.userTokenPolicy); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Copying user token policy failed with error code %s", + UA_StatusCode_name(retval)); + break; + } + +#if UA_LOGLEVEL <= 300 + const char *securityModeNames[3] = {"None", "Sign", "SignAndEncrypt"}; + const char *userTokenTypeNames[4] = {"Anonymous", "UserName", + "Certificate", "IssuedToken"}; + UA_String *securityPolicyUri = &userToken->securityPolicyUri; + if(securityPolicyUri->length == 0) + securityPolicyUri = &endpoint->securityPolicyUri; + + /* Log the selected endpoint */ + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Selected Endpoint %.*s with SecurityMode %s and SecurityPolicy %.*s", + (int)endpoint->endpointUrl.length, endpoint->endpointUrl.data, + securityModeNames[endpoint->securityMode - 1], + (int)endpoint->securityPolicyUri.length, + endpoint->securityPolicyUri.data); + + /* Log the selected UserTokenPolicy */ + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Selected UserTokenPolicy %.*s with UserTokenType %s and SecurityPolicy %.*s", + (int)userToken->policyId.length, userToken->policyId.data, + userTokenTypeNames[userToken->tokenType], + (int)securityPolicyUri->length, securityPolicyUri->data); +#endif break; } + + if(tokenFound) + break; } UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); + if(retval != UA_STATUSCODE_GOOD) + return retval; + if(!endpointFound) { - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, "No suitable endpoint found"); retval = UA_STATUSCODE_BADINTERNALERROR; } else if(!tokenFound) { - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, "No suitable UserTokenPolicy found for the possible endpoints"); retval = UA_STATUSCODE_BADINTERNALERROR; } @@ -36919,148 +38965,349 @@ static UA_StatusCode createSession(UA_Client *client) { UA_CreateSessionRequest request; UA_CreateSessionRequest_init(&request); + UA_StatusCode retval = UA_STATUSCODE_GOOD; + + if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN || + client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { + if(client->channel.localNonce.length != UA_SESSION_LOCALNONCELENGTH) { + UA_ByteString_deleteMembers(&client->channel.localNonce); + retval = UA_ByteString_allocBuffer(&client->channel.localNonce, + UA_SESSION_LOCALNONCELENGTH); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } + + retval = client->channel.securityPolicy->symmetricModule. + generateNonce(client->channel.securityPolicy, &client->channel.localNonce); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } request.requestHeader.timestamp = UA_DateTime_now(); request.requestHeader.timeoutHint = 10000; UA_ByteString_copy(&client->channel.localNonce, &request.clientNonce); - request.requestedSessionTimeout = 1200000; + request.requestedSessionTimeout = client->config.requestedSessionTimeout; request.maxResponseMessageSize = UA_INT32_MAX; - UA_String_copy(&client->endpointUrl, &request.endpointUrl); + UA_String_copy(&client->config.endpoint.endpointUrl, &request.endpointUrl); + + UA_ApplicationDescription_copy(&client->config.clientDescription, + &request.clientDescription); + + if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN || + client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { + UA_ByteString_copy(&client->channel.securityPolicy->localCertificate, + &request.clientCertificate); + } UA_CreateSessionResponse response; __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST], &response, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); - UA_NodeId_copy(&response.authenticationToken, &client->authenticationToken); + if(response.responseHeader.serviceResult == UA_STATUSCODE_GOOD) { + /* Verify the encrypted response */ + if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN || + client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { - UA_StatusCode retval = response.responseHeader.serviceResult; + if(!UA_ByteString_equal(&response.serverCertificate, + &client->channel.remoteCertificate)) { + retval = UA_STATUSCODE_BADCERTIFICATEINVALID; + goto cleanup; + } + + /* Verify the client signature */ + retval = checkClientSignature(&client->channel, &response); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + } + + /* Copy nonce and and authenticationtoken */ + UA_ByteString_deleteMembers(&client->channel.remoteNonce); + retval |= UA_ByteString_copy(&response.serverNonce, &client->channel.remoteNonce); + + UA_NodeId_deleteMembers(&client->authenticationToken); + retval |= UA_NodeId_copy(&response.authenticationToken, &client->authenticationToken); + } + + retval |= response.responseHeader.serviceResult; + + cleanup: UA_CreateSessionRequest_deleteMembers(&request); UA_CreateSessionResponse_deleteMembers(&response); return retval; } UA_StatusCode -UA_Client_connectInternal(UA_Client *client, const char *endpointUrl, - UA_Boolean endpointsHandshake, UA_Boolean createNewSession) { +UA_Client_connectTCPSecureChannel(UA_Client *client, const UA_String endpointUrl) { if(client->state >= UA_CLIENTSTATE_CONNECTED) return UA_STATUSCODE_GOOD; + UA_ChannelSecurityToken_init(&client->channel.securityToken); client->channel.state = UA_SECURECHANNELSTATE_FRESH; client->channel.sendSequenceNumber = 0; client->requestId = 0; + /* Set the channel SecurityMode */ + client->channel.securityMode = client->config.endpoint.securityMode; + if(client->channel.securityMode == UA_MESSAGESECURITYMODE_INVALID) + client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE; + + /* Initialized the SecureChannel */ UA_StatusCode retval = UA_STATUSCODE_GOOD; - client->connection = - client->config.connectionFunc(client->config.localConnectionConfig, - endpointUrl, client->config.timeout, - client->config.logger); + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Initialize the SecurityPolicy context"); + if(!client->channel.securityPolicy) { + /* Set the channel SecurityPolicy to #None if no endpoint is selected */ + UA_String sps = client->config.endpoint.securityPolicyUri; + if(sps.length == 0) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "SecurityPolicy not specified -> use default #None"); + sps = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None"); + } + + UA_SecurityPolicy *sp = getSecurityPolicy(client, sps); + if(!sp) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Failed to find the required security policy"); + retval = UA_STATUSCODE_BADINTERNALERROR; + goto cleanup; + } + + + retval = UA_SecureChannel_setSecurityPolicy(&client->channel, sp, + &client->config.endpoint.serverCertificate); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Failed to set the security policy"); + goto cleanup; + } + } + + /* Open a TCP connection */ + client->connection = client->config.connectionFunc(client->config.localConnectionConfig, + endpointUrl, client->config.timeout, + &client->config.logger); if(client->connection.state != UA_CONNECTION_OPENING) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Opening the TCP socket failed"); retval = UA_STATUSCODE_BADCONNECTIONCLOSED; goto cleanup; } - UA_String_deleteMembers(&client->endpointUrl); - client->endpointUrl = UA_STRING_ALLOC(endpointUrl); - if(!client->endpointUrl.data) { - retval = UA_STATUSCODE_BADOUTOFMEMORY; - goto cleanup; - } + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "TCP connection established"); - /* Open a TCP connection */ - client->connection.localConf = client->config.localConnectionConfig; - retval = HelAckHandshake(client); - if(retval != UA_STATUSCODE_GOOD) + /* Perform the HEL/ACK handshake */ + client->connection.config = client->config.localConnectionConfig; + retval = HelAckHandshake(client, endpointUrl); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "HEL/ACK handshake failed"); goto cleanup; + } setClientState(client, UA_CLIENTSTATE_CONNECTED); - /* Open a SecureChannel. TODO: Select with endpoint */ + /* Open a SecureChannel. */ + retval = UA_SecureChannel_generateLocalNonce(&client->channel); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Generating a local nonce failed"); + goto cleanup; + } client->channel.connection = &client->connection; retval = openSecureChannel(client, false); - if(retval != UA_STATUSCODE_GOOD) + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Opening a secure channel failed"); goto cleanup; + } + retval = UA_SecureChannel_generateNewKeys(&client->channel); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Generating new keys failed"); + return retval; + } setClientState(client, UA_CLIENTSTATE_SECURECHANNEL); + return retval; + +cleanup: + UA_Client_disconnect(client); + return retval; +} + +UA_StatusCode +UA_Client_connectSession(UA_Client *client) { + if(client->state < UA_CLIENTSTATE_SECURECHANNEL) + return UA_STATUSCODE_BADINTERNALERROR; /* Delete async service. TODO: Move this from connect to the disconnect/cleanup phase */ UA_Client_AsyncService_removeAll(client, UA_STATUSCODE_BADSHUTDOWN); -#ifdef UA_ENABLE_SUBSCRIPTIONS - client->currentlyOutStandingPublishRequests = 0; -#endif - -// TODO: actually, reactivate an existing session is working, but currently republish is not implemented -// This option is disabled until we have a good implementation of the subscription recovery. + // TODO: actually, reactivate an existing session is working, but currently + // republish is not implemented This option is disabled until we have a good + // implementation of the subscription recovery. #ifdef UA_SESSION_RECOVERY /* Try to activate an existing Session for this SecureChannel */ if((!UA_NodeId_equal(&client->authenticationToken, &UA_NODEID_NULL)) && (createNewSession)) { - retval = activateSession(client); - if(retval == UA_STATUSCODE_BADSESSIONIDINVALID) { - /* Could not recover an old session. Remove authenticationToken */ - UA_NodeId_deleteMembers(&client->authenticationToken); - } else { - if(retval != UA_STATUSCODE_GOOD) - goto cleanup; - setClientState(client, UA_CLIENTSTATE_SESSION_RENEWED); - return retval; + UA_StatusCode res = activateSession(client); + if(res != UA_STATUSCODE_BADSESSIONIDINVALID) { + if(res == UA_STATUSCODE_GOOD) { + setClientState(client, UA_CLIENTSTATE_SESSION_RENEWED); + } else { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Could not activate the Session with StatusCode %s", + UA_StatusCode_name(retval)); + UA_Client_disconnect(client); + } + return res; } - } else { - UA_NodeId_deleteMembers(&client->authenticationToken); } -#else - UA_NodeId_deleteMembers(&client->authenticationToken); #endif /* UA_SESSION_RECOVERY */ - /* Get Endpoints */ - if(endpointsHandshake) { - retval = getEndpoints(client); - if(retval != UA_STATUSCODE_GOOD) - goto cleanup; - } + /* Could not recover an old session. Remove authenticationToken */ + UA_NodeId_deleteMembers(&client->authenticationToken); - /* Create the Session for this SecureChannel */ - if(createNewSession) { - retval = createSession(client); - if(retval != UA_STATUSCODE_GOOD) - goto cleanup; + /* Create a session */ + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Create a new session"); + UA_StatusCode retval = createSession(client); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Could not open a Session with StatusCode %s", + UA_StatusCode_name(retval)); + UA_Client_disconnect(client); + return retval; + } + + /* A new session has been created. We need to clean up the subscriptions */ #ifdef UA_ENABLE_SUBSCRIPTIONS - /* A new session has been created. We need to clean up the subscriptions */ - UA_Client_Subscriptions_clean(client); + UA_Client_Subscriptions_clean(client); + client->currentlyOutStandingPublishRequests = 0; #endif - retval = activateSession(client); + + /* Activate the session */ + retval = activateSession(client); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Could not activate the Session with StatusCode %s", + UA_StatusCode_name(retval)); + UA_Client_disconnect(client); + return retval; + } + setClientState(client, UA_CLIENTSTATE_SESSION); + return retval; +} + +#ifdef UA_ENABLE_ENCRYPTION +/* The local ApplicationURI has to match the certificates of the + * SecurityPolicies */ +static void +verifyClientApplicationURI(const UA_Client *client) { +#if UA_LOGLEVEL <= 400 + for(size_t i = 0; i < client->config.securityPoliciesSize; i++) { + UA_SecurityPolicy *sp = &client->config.securityPolicies[i]; + if(!sp->certificateVerification) + continue; + UA_StatusCode retval = + sp->certificateVerification-> + verifyApplicationURI(sp->certificateVerification->context, + &sp->localCertificate, + &client->config.clientDescription.applicationUri); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "The configured ApplicationURI does not match the URI " + "specified in the certificate for the SecurityPolicy %.*s", + (int)sp->policyUri.length, sp->policyUri.data); + } + } +#endif +} +#endif + +UA_StatusCode +UA_Client_connectInternal(UA_Client *client, const UA_String endpointUrl) { + if(client->state >= UA_CLIENTSTATE_CONNECTED) + return UA_STATUSCODE_GOOD; + + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Connecting to endpoint %.*s", (int)endpointUrl.length, + endpointUrl.data); + +#ifdef UA_ENABLE_ENCRYPTION + verifyClientApplicationURI(client); +#endif + + /* Get endpoints only if the description has not been touched (memset to zero) */ + UA_Byte test = 0; + UA_Byte *pos = (UA_Byte*)&client->config.endpoint; + for(size_t i = 0; i < sizeof(UA_EndpointDescription); i++) + test = test | pos[i]; + pos = (UA_Byte*)&client->config.userTokenPolicy; + for(size_t i = 0; i < sizeof(UA_UserTokenPolicy); i++) + test = test | pos[i]; + UA_Boolean getEndpoints = (test == 0); + + /* Connect up to the SecureChannel */ + UA_StatusCode retval = UA_Client_connectTCPSecureChannel(client, endpointUrl); + if (retval != UA_STATUSCODE_GOOD) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Couldn't connect the client to a TCP secure channel"); + goto cleanup; + } + + /* Get and select endpoints if required */ + if(getEndpoints) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Endpoint and UserTokenPolicy unconfigured, perform GetEndpoints"); + retval = selectEndpoint(client, endpointUrl); if(retval != UA_STATUSCODE_GOOD) goto cleanup; - setClientState(client, UA_CLIENTSTATE_SESSION); + + /* Reconnect with a new SecureChannel if the current one does not match + * the selected endpoint */ + if(!UA_String_equal(&client->config.endpoint.securityPolicyUri, + &client->channel.securityPolicy->policyUri)) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Disconnect to switch to a different SecurityPolicy"); + UA_Client_disconnect(client); + return UA_Client_connectInternal(client, endpointUrl); + } } + retval = UA_Client_connectSession(client); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + return retval; cleanup: - UA_Client_close(client); + UA_Client_disconnect(client); return retval; } UA_StatusCode UA_Client_connect(UA_Client *client, const char *endpointUrl) { - return UA_Client_connectInternal(client, endpointUrl, UA_TRUE, UA_TRUE); + return UA_Client_connectInternal(client, UA_STRING((char*)(uintptr_t)endpointUrl)); } UA_StatusCode -UA_Client_connect_username(UA_Client *client, const char *endpointUrl, - const char *username, const char *password) { - client->authenticationMethod = UA_CLIENTAUTHENTICATION_USERNAME; - client->username = UA_STRING_ALLOC(username); - client->password = UA_STRING_ALLOC(password); - return UA_Client_connect(client, endpointUrl); +UA_Client_connect_noSession(UA_Client *client, const char *endpointUrl) { + return UA_Client_connectTCPSecureChannel(client, UA_STRING((char*)(uintptr_t)endpointUrl)); } UA_StatusCode -UA_Client_manuallyRenewSecureChannel(UA_Client *client) { - UA_StatusCode retval = openSecureChannel(client, true); - if(retval != UA_STATUSCODE_GOOD) - UA_Client_close(client); - - return retval; +UA_Client_connect_username(UA_Client *client, const char *endpointUrl, + const char *username, const char *password) { + UA_UserNameIdentityToken* identityToken = UA_UserNameIdentityToken_new(); + if(!identityToken) + return UA_STATUSCODE_BADOUTOFMEMORY; + identityToken->userName = UA_STRING_ALLOC(username); + identityToken->password = UA_STRING_ALLOC(password); + UA_ExtensionObject_deleteMembers(&client->config.userIdentityToken); + client->config.userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED; + client->config.userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]; + client->config.userIdentityToken.content.decoded.data = identityToken; + return UA_Client_connect(client, endpointUrl); } /************************/ @@ -37095,7 +39342,8 @@ sendCloseSecureChannel(UA_Client *client) { UA_MESSAGETYPE_CLO, &request, &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); UA_CloseSecureChannelRequest_deleteMembers(&request); - UA_SecureChannel_deleteMembersCleanup(&client->channel); + UA_SecureChannel_close(&client->channel); + UA_SecureChannel_deleteMembers(&client->channel); } UA_StatusCode @@ -37115,34 +39363,747 @@ UA_Client_disconnect(UA_Client *client) { } /* Close the TCP connection */ - if(client->connection.state != UA_CONNECTION_CLOSED) - client->connection.close(&client->connection); + if(client->connection.state != UA_CONNECTION_CLOSED + && client->connection.state != UA_CONNECTION_OPENING) + /* UA_ClientConnectionTCP_init sets initial state to opening */ + if(client->connection.close != NULL) + client->connection.close(&client->connection); #ifdef UA_ENABLE_SUBSCRIPTIONS -// TODO REMOVE WHEN UA_SESSION_RECOVERY IS READY - /* We need to clean up the subscriptions */ - UA_Client_Subscriptions_clean(client); + // TODO REMOVE WHEN UA_SESSION_RECOVERY IS READY + /* We need to clean up the subscriptions */ + UA_Client_Subscriptions_clean(client); #endif + UA_SecureChannel_deleteMembers(&client->channel); + setClientState(client, UA_CLIENTSTATE_DISCONNECTED); return UA_STATUSCODE_GOOD; } +/*********************************** amalgamated original file "/home/jvoe/open62541/src/client/ua_client_connect_async.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + + +#define UA_MINMESSAGESIZE 8192 +#define UA_SESSION_LOCALNONCELENGTH 32 +#define MAX_DATA_SIZE 4096 + +/* Asynchronous client connection + * To prepare an async connection, UA_Client_connectAsync() is called, which does not connect the + * client directly. UA_Client_run_iterate() takes care of actually connecting the client: + * if client is disconnected: + * send hello msg and set the client state to be WAITING_FOR_ACK + * (see UA_Client_connect_iterate()) + * if client is waiting for the ACK: + * call the non-blocking receiving function and register processACKResponseAsync() as its callback + * (see receivePacketAsync()) + * if ACK is processed (callback called): + * processACKResponseAsync() calls openSecureChannelAsync() at the end, which prepares the request + * to open secure channel and the client is connected + * if client is connected: + * call the non-blocking receiving function and register processOPNResponse() as its callback + * (see receivePacketAsync()) + * if OPN-request processed (callback called) + * send session request, where the session response is put into a normal AsyncServiceCall, and when + * called, request to activate session is sent, where its response is again put into an AsyncServiceCall + * in the very last step responseActivateSession(): + * the user defined callback that is passed into UA_Client_connectAsync() is called and the + * async connection finalized. + * */ + +/***********************/ +/* Open the Connection */ +/***********************/ +static UA_StatusCode +openSecureChannelAsync(UA_Client *client/*, UA_Boolean renew*/); + +static UA_StatusCode +requestSession(UA_Client *client, UA_UInt32 *requestId); + +static UA_StatusCode +requestGetEndpoints(UA_Client *client, UA_UInt32 *requestId); + +/*receives hello ack, opens secure channel*/ +UA_StatusCode +processACKResponseAsync(void *application, UA_Connection *connection, + UA_ByteString *chunk) { + UA_Client *client = (UA_Client*)application; + + /* Decode the message */ + size_t offset = 0; + UA_TcpMessageHeader messageHeader; + UA_TcpAcknowledgeMessage ackMessage; + client->connectStatus = UA_TcpMessageHeader_decodeBinary (chunk, &offset, + &messageHeader); + client->connectStatus |= UA_TcpAcknowledgeMessage_decodeBinary( + chunk, &offset, &ackMessage); + if (client->connectStatus != UA_STATUSCODE_GOOD) { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_NETWORK, + "Decoding ACK message failed"); + return client->connectStatus; + } + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Received ACK message"); + + client->connectStatus = + UA_Connection_processHELACK(connection, &client->config.localConnectionConfig, + (const UA_ConnectionConfig*)&ackMessage); + if(client->connectStatus != UA_STATUSCODE_GOOD) + return client->connectStatus; + + client->state = UA_CLIENTSTATE_CONNECTED; + + /* Open a SecureChannel. TODO: Select with endpoint */ + client->channel.connection = &client->connection; + client->connectStatus = openSecureChannelAsync(client/*, false*/); + return client->connectStatus; +} + +static UA_StatusCode +sendHELMessage(UA_Client *client) { + /* Get a buffer */ + UA_ByteString message; + UA_Connection *conn = &client->connection; + UA_StatusCode retval = conn->getSendBuffer(conn, UA_MINMESSAGESIZE, &message); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* Prepare the HEL message and encode at offset 8 */ + UA_TcpHelloMessage hello; + UA_String_copy(&client->endpointUrl, &hello.endpointUrl); /* must be less than 4096 bytes */ + memcpy(&hello, &client->config.localConnectionConfig, + sizeof(UA_ConnectionConfig)); /* same struct layout */ + + UA_Byte *bufPos = &message.data[8]; /* skip the header */ + const UA_Byte *bufEnd = &message.data[message.length]; + client->connectStatus = UA_TcpHelloMessage_encodeBinary(&hello, &bufPos, bufEnd); + UA_TcpHelloMessage_deleteMembers (&hello); + + /* Encode the message header at offset 0 */ + UA_TcpMessageHeader messageHeader; + messageHeader.messageTypeAndChunkType = UA_CHUNKTYPE_FINAL + UA_MESSAGETYPE_HEL; + messageHeader.messageSize = (UA_UInt32) ((uintptr_t)bufPos - (uintptr_t)message.data); + bufPos = message.data; + retval = UA_TcpMessageHeader_encodeBinary(&messageHeader, &bufPos, bufEnd); + if(retval != UA_STATUSCODE_GOOD) { + conn->releaseSendBuffer(conn, &message); + return retval; + } + + /* Send the HEL message */ + message.length = messageHeader.messageSize; + retval = conn->send (conn, &message); + + if(retval == UA_STATUSCODE_GOOD) { + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Sent HEL message"); + } else { + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Sending HEL failed"); + } + return retval; +} + +static void +processDecodedOPNResponseAsync(void *application, UA_SecureChannel *channel, + UA_MessageType messageType, + UA_UInt32 requestId, + const UA_ByteString *message) { + /* Does the request id match? */ + UA_Client *client = (UA_Client*)application; + if(requestId != client->requestId) { + UA_Client_disconnect(client); + return; + } + + /* Is the content of the expected type? */ + size_t offset = 0; + UA_NodeId responseId; + UA_NodeId expectedId = UA_NODEID_NUMERIC( + 0, UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE].binaryEncodingId); + UA_StatusCode retval = UA_NodeId_decodeBinary(message, &offset, + &responseId); + if(retval != UA_STATUSCODE_GOOD) { + UA_Client_disconnect(client); + return; + } + if(!UA_NodeId_equal(&responseId, &expectedId)) { + UA_NodeId_deleteMembers(&responseId); + UA_Client_disconnect(client); + return; + } + UA_NodeId_deleteMembers (&responseId); + + /* Decode the response */ + UA_OpenSecureChannelResponse response; + retval = UA_OpenSecureChannelResponse_decodeBinary(message, &offset, + &response); + if(retval != UA_STATUSCODE_GOOD) { + UA_Client_disconnect(client); + return; + } + + /* Response.securityToken.revisedLifetime is UInt32 we need to cast it to + * DateTime=Int64 we take 75% of lifetime to start renewing as described in + * standard */ + client->nextChannelRenewal = UA_DateTime_nowMonotonic() + + (UA_DateTime) (response.securityToken.revisedLifetime + * (UA_Double) UA_DATETIME_MSEC * 0.75); + + /* Replace the token and nonce */ + UA_ChannelSecurityToken_deleteMembers(&client->channel.securityToken); + UA_ByteString_deleteMembers(&client->channel.remoteNonce); + client->channel.securityToken = response.securityToken; + client->channel.remoteNonce = response.serverNonce; + UA_ResponseHeader_deleteMembers(&response.responseHeader); /* the other members were moved */ + if(client->channel.state == UA_SECURECHANNELSTATE_OPEN) + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "SecureChannel renewed"); + else + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "SecureChannel opened"); + client->channel.state = UA_SECURECHANNELSTATE_OPEN; + + if(client->state < UA_CLIENTSTATE_SECURECHANNEL) + setClientState(client, UA_CLIENTSTATE_SECURECHANNEL); +} + +UA_StatusCode +processOPNResponseAsync(void *application, UA_Connection *connection, + UA_ByteString *chunk) { + UA_Client *client = (UA_Client*) application; + UA_StatusCode retval = UA_SecureChannel_decryptAddChunk(&client->channel, chunk, true); + client->connectStatus = retval; + if(retval != UA_STATUSCODE_GOOD) + goto error; + UA_SecureChannel_processCompleteMessages(&client->channel, client, processDecodedOPNResponseAsync); + + if(client->state < UA_CLIENTSTATE_SECURECHANNEL) { + retval = UA_STATUSCODE_BADSECURECHANNELCLOSED; + goto error; + } + + retval = UA_SecureChannel_persistIncompleteMessages(&client->channel); + if(retval != UA_STATUSCODE_GOOD) + goto error; + + retval = UA_SecureChannel_generateNewKeys(&client->channel); + if(retval != UA_STATUSCODE_GOOD) + goto error; + + /* Following requests and responses */ + UA_UInt32 reqId; + if(client->endpointsHandshake) + retval = requestGetEndpoints (client, &reqId); + else + retval = requestSession (client, &reqId); + + if(retval != UA_STATUSCODE_GOOD) + goto error; + + return retval; + +error: + UA_Client_disconnect(client); + + return retval; +} + +/* OPN messges to renew the channel are sent asynchronous */ +static UA_StatusCode +openSecureChannelAsync(UA_Client *client/*, UA_Boolean renew*/) { + /* Check if sc is still valid */ + /*if(renew && client->nextChannelRenewal - UA_DateTime_nowMonotonic () > 0) + return UA_STATUSCODE_GOOD;*/ + + UA_Connection *conn = &client->connection; + if(conn->state != UA_CONNECTION_ESTABLISHED) + return UA_STATUSCODE_BADSERVERNOTCONNECTED; + + /* Prepare the OpenSecureChannelRequest */ + UA_OpenSecureChannelRequest opnSecRq; + UA_OpenSecureChannelRequest_init(&opnSecRq); + opnSecRq.requestHeader.timestamp = UA_DateTime_now(); + opnSecRq.requestHeader.authenticationToken = client->authenticationToken; + /*if(renew) { + opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_RENEW; + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + "Requesting to renew the SecureChannel"); + } else {*/ + opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE; + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + "Requesting to open a SecureChannel"); + //} + opnSecRq.securityMode = client->channel.securityMode; + + opnSecRq.clientNonce = client->channel.localNonce; + opnSecRq.requestedLifetime = client->config.secureChannelLifeTime; + + /* Prepare the entry for the linked list */ + UA_UInt32 requestId = ++client->requestId; + /*AsyncServiceCall *ac = NULL; + if(renew) { + ac = (AsyncServiceCall*)UA_malloc(sizeof(AsyncServiceCall)); + if (!ac) + return UA_STATUSCODE_BADOUTOFMEMORY; + ac->callback = + (UA_ClientAsyncServiceCallback) processDecodedOPNResponseAsync; + ac->responseType = &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE]; + ac->requestId = requestId; + ac->userdata = NULL; + }*/ + + /* Send the OPN message */ + UA_StatusCode retval = UA_SecureChannel_sendAsymmetricOPNMessage ( + &client->channel, requestId, &opnSecRq, + &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]); + client->connectStatus = retval; + + if(retval != UA_STATUSCODE_GOOD) { + client->connectStatus = retval; + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + "Sending OPN message failed with error %s", + UA_StatusCode_name(retval)); + UA_Client_disconnect(client); + //if(renew) + // UA_free(ac); + return retval; + } + + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, + "OPN message sent"); + + /* Store the entry for async processing and return */ + /*if(renew) { + LIST_INSERT_HEAD(&client->asyncServiceCalls, ac, pointers); + return retval; + }*/ + return retval; +} + +static void +responseActivateSession(UA_Client *client, void *userdata, UA_UInt32 requestId, + void *response) { + UA_ActivateSessionResponse *activateResponse = + (UA_ActivateSessionResponse *) response; + if(activateResponse->responseHeader.serviceResult) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "ActivateSession failed with error code %s", + UA_StatusCode_name(activateResponse->responseHeader.serviceResult)); + } + client->connection.state = UA_CONNECTION_ESTABLISHED; + setClientState(client, UA_CLIENTSTATE_SESSION); + +#ifdef UA_ENABLE_SUBSCRIPTIONS + /* A new session has been created. We need to clean up the subscriptions */ + UA_Client_Subscriptions_clean(client); +#endif + + /* Call onConnect (client_async.c) callback */ + if(client->asyncConnectCall.callback) + client->asyncConnectCall.callback(client, client->asyncConnectCall.userdata, + requestId + 1, + &activateResponse->responseHeader.serviceResult); +} + +static UA_StatusCode +requestActivateSession (UA_Client *client, UA_UInt32 *requestId) { + UA_ActivateSessionRequest request; + UA_ActivateSessionRequest_init(&request); + request.requestHeader.requestHandle = ++client->requestHandle; + request.requestHeader.timestamp = UA_DateTime_now (); + request.requestHeader.timeoutHint = 600000; + UA_StatusCode retval = + UA_ExtensionObject_copy(&client->config.userIdentityToken, &request.userIdentityToken); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* If not token is set, use anonymous */ + if(request.userIdentityToken.encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY) { + UA_AnonymousIdentityToken *t = UA_AnonymousIdentityToken_new(); + if(!t) { + UA_ActivateSessionRequest_deleteMembers(&request); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + request.userIdentityToken.content.decoded.data = t; + request.userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]; + request.userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED; + } + + /* Set the policy-Id from the endpoint. Every IdentityToken starts with a + * string. */ + retval = UA_String_copy(&client->config.userTokenPolicy.policyId, + (UA_String*)request.userIdentityToken.content.decoded.data); + +#ifdef UA_ENABLE_ENCRYPTION + /* Encrypt the UserIdentityToken */ + const UA_String *userTokenPolicy = &client->channel.securityPolicy->policyUri; + if(client->config.userTokenPolicy.securityPolicyUri.length > 0) + userTokenPolicy = &client->config.userTokenPolicy.securityPolicyUri; + retval |= encryptUserIdentityToken(client, userTokenPolicy, &request.userIdentityToken); + + /* This function call is to prepare a client signature */ + retval |= signActivateSessionRequest(&client->channel, &request); +#endif + + if(retval != UA_STATUSCODE_GOOD) { + UA_ActivateSessionRequest_deleteMembers(&request); + client->connectStatus = retval; + return retval; + } + + retval = UA_Client_sendAsyncRequest ( + client, &request, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST], + (UA_ClientAsyncServiceCallback) responseActivateSession, + &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE], NULL, requestId); + + UA_ActivateSessionRequest_deleteMembers(&request); + client->connectStatus = retval; + return retval; +} + +/* Combination of UA_Client_getEndpointsInternal and getEndpoints */ +static void +responseGetEndpoints(UA_Client *client, void *userdata, UA_UInt32 requestId, + void *response) { + UA_EndpointDescription* endpointArray = NULL; + size_t endpointArraySize = 0; + UA_GetEndpointsResponse* resp; + resp = (UA_GetEndpointsResponse*)response; + + if (resp->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { + client->connectStatus = resp->responseHeader.serviceResult; + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "GetEndpointRequest failed with error code %s", + UA_StatusCode_name (client->connectStatus)); + UA_GetEndpointsResponse_deleteMembers(resp); + return; + } + endpointArray = resp->endpoints; + endpointArraySize = resp->endpointsSize; + resp->endpoints = NULL; + resp->endpointsSize = 0; + + UA_Boolean endpointFound = false; + UA_Boolean tokenFound = false; + UA_String securityNone = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None"); + UA_String binaryTransport = UA_STRING("http://opcfoundation.org/UA-Profile/" + "Transport/uatcp-uasc-uabinary"); + + // TODO: compare endpoint information with client->endpointUri + for(size_t i = 0; i < endpointArraySize; ++i) { + UA_EndpointDescription* endpoint = &endpointArray[i]; + /* look out for binary transport endpoints */ + /* Note: Siemens returns empty ProfileUrl, we will accept it as binary */ + if(endpoint->transportProfileUri.length != 0 + && !UA_String_equal (&endpoint->transportProfileUri, + &binaryTransport)) + continue; + + /* Look for an endpoint corresponding to the client security policy */ + if(!UA_String_equal(&endpoint->securityPolicyUri, &client->channel.securityPolicy->policyUri)) + continue; + + endpointFound = true; + + /* Look for a user token policy with an anonymous token */ + for(size_t j = 0; j < endpoint->userIdentityTokensSize; ++j) { + UA_UserTokenPolicy* userToken = &endpoint->userIdentityTokens[j]; + + /* Usertokens also have a security policy... */ + if(userToken->securityPolicyUri.length > 0 && + !UA_String_equal(&userToken->securityPolicyUri, &securityNone)) + continue; + + /* Does the token type match the client configuration? */ + if((userToken->tokenType == UA_USERTOKENTYPE_ANONYMOUS && + client->config.userIdentityToken.content.decoded.type != + &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN] && + client->config.userIdentityToken.content.decoded.type != NULL) || + (userToken->tokenType == UA_USERTOKENTYPE_USERNAME && + client->config.userIdentityToken.content.decoded.type != + &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN]) || + (userToken->tokenType == UA_USERTOKENTYPE_CERTIFICATE && + client->config.userIdentityToken.content.decoded.type != + &UA_TYPES[UA_TYPES_X509IDENTITYTOKEN]) || + (userToken->tokenType == UA_USERTOKENTYPE_ISSUEDTOKEN && + client->config.userIdentityToken.content.decoded.type != + &UA_TYPES[UA_TYPES_ISSUEDIDENTITYTOKEN])) + continue; + + /* Endpoint with matching usertokenpolicy found */ + tokenFound = true; + UA_EndpointDescription_deleteMembers(&client->config.endpoint); + UA_EndpointDescription_copy(endpoint, &client->config.endpoint); + UA_UserTokenPolicy_deleteMembers(&client->config.userTokenPolicy); + UA_UserTokenPolicy_copy(userToken, &client->config.userTokenPolicy); + break; + } + } + + UA_Array_delete(endpointArray, endpointArraySize, + &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); + + if(!endpointFound) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "No suitable endpoint found"); + client->connectStatus = UA_STATUSCODE_BADINTERNALERROR; + } else if(!tokenFound) { + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "No suitable UserTokenPolicy found for the possible endpoints"); + client->connectStatus = UA_STATUSCODE_BADINTERNALERROR; + } + requestSession(client, &requestId); +} + +static UA_StatusCode +requestGetEndpoints(UA_Client *client, UA_UInt32 *requestId) { + UA_GetEndpointsRequest request; + UA_GetEndpointsRequest_init(&request); + request.requestHeader.timestamp = UA_DateTime_now(); + request.requestHeader.timeoutHint = 10000; + /* assume the endpointurl outlives the service call */ + UA_String_copy(&client->endpointUrl, &request.endpointUrl); + + client->connectStatus = UA_Client_sendAsyncRequest( + client, &request, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST], + (UA_ClientAsyncServiceCallback) responseGetEndpoints, + &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE], NULL, requestId); + UA_GetEndpointsRequest_deleteMembers(&request); + return client->connectStatus; + +} + +static void +responseSessionCallback(UA_Client *client, void *userdata, UA_UInt32 requestId, + void *response) { + UA_CreateSessionResponse *sessionResponse = + (UA_CreateSessionResponse *)response; + UA_NodeId_copy(&sessionResponse->authenticationToken, + &client->authenticationToken); + requestActivateSession(client, &requestId); +} + +static UA_StatusCode +requestSession(UA_Client *client, UA_UInt32 *requestId) { + UA_CreateSessionRequest request; + UA_CreateSessionRequest_init(&request); + + UA_StatusCode retval = UA_STATUSCODE_GOOD; + if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN || + client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { + if(client->channel.localNonce.length != UA_SESSION_LOCALNONCELENGTH) { + UA_ByteString_deleteMembers(&client->channel.localNonce); + retval = UA_ByteString_allocBuffer(&client->channel.localNonce, + UA_SESSION_LOCALNONCELENGTH); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } + + retval = client->channel.securityPolicy->symmetricModule. + generateNonce(client->channel.securityPolicy, &client->channel.localNonce); + if(retval != UA_STATUSCODE_GOOD) + return retval; + } + + request.requestHeader.requestHandle = ++client->requestHandle; + request.requestHeader.timestamp = UA_DateTime_now(); + request.requestHeader.timeoutHint = 10000; + UA_ByteString_copy(&client->channel.localNonce, &request.clientNonce); + request.requestedSessionTimeout = client->config.requestedSessionTimeout; + request.maxResponseMessageSize = UA_INT32_MAX; + UA_String_copy(&client->config.endpoint.endpointUrl, &request.endpointUrl); + + UA_ApplicationDescription_copy(&client->config.clientDescription, + &request.clientDescription); + + retval = UA_Client_sendAsyncRequest ( + client, &request, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST], + (UA_ClientAsyncServiceCallback) responseSessionCallback, + &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE], NULL, requestId); + UA_CreateSessionRequest_deleteMembers(&request); + client->connectStatus = retval; + return client->connectStatus; +} + +UA_StatusCode +UA_Client_connect_iterate(UA_Client *client) { + UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Client connect iterate"); + if (client->connection.state == UA_CONNECTION_ESTABLISHED){ + if(client->state < UA_CLIENTSTATE_WAITING_FOR_ACK) { + client->connectStatus = sendHELMessage(client); + if(client->connectStatus == UA_STATUSCODE_GOOD) { + setClientState(client, UA_CLIENTSTATE_WAITING_FOR_ACK); + } else { + client->connection.close(&client->connection); + client->connection.free(&client->connection); + } + return client->connectStatus; + } + } + + /* If server is not connected */ + if(client->connection.state == UA_CONNECTION_CLOSED) { + client->connectStatus = UA_STATUSCODE_BADCONNECTIONCLOSED; + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK, + "No connection to server."); + } + + if(client->connectStatus != UA_STATUSCODE_GOOD) { + client->connection.close(&client->connection); + client->connection.free(&client->connection); + } + + return client->connectStatus; +} + UA_StatusCode -UA_Client_close(UA_Client *client) { +UA_Client_connect_async(UA_Client *client, const char *endpointUrl, + UA_ClientAsyncServiceCallback callback, + void *userdata) { + UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Client internal async"); + + if(client->state >= UA_CLIENTSTATE_WAITING_FOR_ACK) + return UA_STATUSCODE_GOOD; + + UA_ChannelSecurityToken_init(&client->channel.securityToken); + client->channel.state = UA_SECURECHANNELSTATE_FRESH; + client->endpointsHandshake = true; + client->channel.sendSequenceNumber = 0; + client->requestId = 0; + + UA_String_deleteMembers(&client->endpointUrl); + client->endpointUrl = UA_STRING_ALLOC(endpointUrl); + + UA_StatusCode retval = UA_STATUSCODE_GOOD; + client->connection = + client->config.initConnectionFunc(client->config.localConnectionConfig, + client->endpointUrl, + client->config.timeout, &client->config.logger); + if(client->connection.state != UA_CONNECTION_OPENING) { + UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Could not init async connection"); + retval = UA_STATUSCODE_BADCONNECTIONCLOSED; + goto cleanup; + } + + /* Set the channel SecurityMode if not done so far */ + if(client->channel.securityMode == UA_MESSAGESECURITYMODE_INVALID) + client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE; + + /* Set the channel SecurityPolicy if not done so far */ + if(!client->channel.securityPolicy) { + UA_SecurityPolicy *sp = + getSecurityPolicy(client, UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None")); + if(!sp) { + retval = UA_STATUSCODE_BADINTERNALERROR; + goto cleanup; + } + UA_ByteString remoteCertificate = UA_BYTESTRING_NULL; + retval = UA_SecureChannel_setSecurityPolicy(&client->channel, sp, + &remoteCertificate); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + } + + client->asyncConnectCall.callback = callback; + client->asyncConnectCall.userdata = userdata; + + if(!client->connection.connectCallbackID) { + UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Adding async connection callback"); + retval = UA_Client_addRepeatedCallback( + client, client->config.pollConnectionFunc, &client->connection, 100.0, + &client->connection.connectCallbackID); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + } + + retval = UA_SecureChannel_generateLocalNonce(&client->channel); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + + /* Delete async service. TODO: Move this from connect to the disconnect/cleanup phase */ + UA_Client_AsyncService_removeAll(client, UA_STATUSCODE_BADSHUTDOWN); + +#ifdef UA_ENABLE_SUBSCRIPTIONS + client->currentlyOutStandingPublishRequests = 0; +#endif + + UA_NodeId_deleteMembers(&client->authenticationToken); + + /* Generate new local and remote key */ + retval = UA_SecureChannel_generateNewKeys(&client->channel); + if(retval != UA_STATUSCODE_GOOD) + goto cleanup; + + return retval; + + cleanup: + UA_LOG_TRACE(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Failure during async connect"); + UA_Client_disconnect(client); + return retval; +} + +/* Async disconnection */ +static void +sendCloseSecureChannelAsync(UA_Client *client, void *userdata, + UA_UInt32 requestId, void *response) { + UA_NodeId_deleteMembers (&client->authenticationToken); client->requestHandle = 0; - if(client->state >= UA_CLIENTSTATE_SECURECHANNEL) - UA_SecureChannel_deleteMembersCleanup(&client->channel); + UA_SecureChannel *channel = &client->channel; + UA_CloseSecureChannelRequest request; + UA_CloseSecureChannelRequest_init(&request); + request.requestHeader.requestHandle = ++client->requestHandle; + request.requestHeader.timestamp = UA_DateTime_now(); + request.requestHeader.timeoutHint = 10000; + request.requestHeader.authenticationToken = client->authenticationToken; + UA_SecureChannel_sendSymmetricMessage( + channel, ++client->requestId, UA_MESSAGETYPE_CLO, &request, + &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]); + UA_SecureChannel_close(&client->channel); + UA_SecureChannel_deleteMembers(&client->channel); +} - /* Close the TCP connection */ - if(client->connection.state != UA_CONNECTION_CLOSED) +static void +sendCloseSessionAsync(UA_Client *client, UA_UInt32 *requestId) { + UA_CloseSessionRequest request; + UA_CloseSessionRequest_init(&request); + + request.requestHeader.timestamp = UA_DateTime_now(); + request.requestHeader.timeoutHint = 10000; + request.deleteSubscriptions = true; + + UA_Client_sendAsyncRequest( + client, &request, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST], + (UA_ClientAsyncServiceCallback) sendCloseSecureChannelAsync, + &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE], NULL, requestId); + +} + +UA_StatusCode +UA_Client_disconnect_async(UA_Client *client, UA_UInt32 *requestId) { + /* Is a session established? */ + if (client->state == UA_CLIENTSTATE_SESSION) { + client->state = UA_CLIENTSTATE_SESSION_DISCONNECTED; + sendCloseSessionAsync(client, requestId); + } + + /* Close the TCP connection + * shutdown and close (in tcp.c) are already async*/ + if (client->state >= UA_CLIENTSTATE_CONNECTED) client->connection.close(&client->connection); + else + UA_Client_removeRepeatedCallback(client, client->connection.connectCallbackID); #ifdef UA_ENABLE_SUBSCRIPTIONS // TODO REMOVE WHEN UA_SESSION_RECOVERY IS READY - /* We need to clean up the subscriptions */ - UA_Client_Subscriptions_clean(client); + /* We need to clean up the subscriptions */ + UA_Client_Subscriptions_clean(client); #endif setClientState(client, UA_CLIENTSTATE_DISCONNECTED); @@ -37155,7 +40116,7 @@ UA_Client_close(UA_Client *client) { * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB * Copyright 2017 (c) Stefan Profanter, fortiss GmbH */ @@ -37167,18 +40128,20 @@ UA_Client_getEndpoints(UA_Client *client, const char *serverUrl, UA_EndpointDescription** endpointDescriptions) { UA_Boolean connected = (client->state > UA_CLIENTSTATE_DISCONNECTED); /* Client is already connected to a different server */ - if(connected && strncmp((const char*)client->endpointUrl.data, serverUrl, - client->endpointUrl.length) != 0) { + if(connected && strncmp((const char*)client->config.endpoint.endpointUrl.data, serverUrl, + client->config.endpoint.endpointUrl.length) != 0) { return UA_STATUSCODE_BADINVALIDARGUMENT; } UA_StatusCode retval; + const UA_String url = UA_STRING((char*)(uintptr_t)serverUrl); if(!connected) { - retval = UA_Client_connectInternal(client, serverUrl, UA_FALSE, UA_FALSE); + retval = UA_Client_connectTCPSecureChannel(client, url); if(retval != UA_STATUSCODE_GOOD) return retval; } - retval = UA_Client_getEndpointsInternal(client, endpointDescriptionsSize, endpointDescriptions); + retval = UA_Client_getEndpointsInternal(client, url, endpointDescriptionsSize, + endpointDescriptions); if(!connected) UA_Client_disconnect(client); @@ -37193,13 +40156,15 @@ UA_Client_findServers(UA_Client *client, const char *serverUrl, UA_ApplicationDescription **registeredServers) { UA_Boolean connected = (client->state > UA_CLIENTSTATE_DISCONNECTED); /* Client is already connected to a different server */ - if(connected && strncmp((const char*)client->endpointUrl.data, serverUrl, - client->endpointUrl.length) != 0) { + if(connected && strncmp((const char*)client->config.endpoint.endpointUrl.data, serverUrl, + client->config.endpoint.endpointUrl.length) != 0) { return UA_STATUSCODE_BADINVALIDARGUMENT; } + UA_StatusCode retval; + const UA_String url = UA_STRING((char*)(uintptr_t)serverUrl); if(!connected) { - UA_StatusCode retval = UA_Client_connectInternal(client, serverUrl, UA_TRUE, UA_FALSE); + retval = UA_Client_connectTCPSecureChannel(client, url); if(retval != UA_STATUSCODE_GOOD) return retval; } @@ -37218,7 +40183,7 @@ UA_Client_findServers(UA_Client *client, const char *serverUrl, &response, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); /* Process the response */ - UA_StatusCode retval = response.responseHeader.serviceResult; + retval = response.responseHeader.serviceResult; if(retval == UA_STATUSCODE_GOOD) { *registeredServersSize = response.serversSize; *registeredServers = response.servers; @@ -37236,6 +40201,8 @@ UA_Client_findServers(UA_Client *client, const char *serverUrl, return retval; } +#ifdef UA_ENABLE_DISCOVERY + UA_StatusCode UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl, UA_UInt32 startingRecordId, UA_UInt32 maxRecordsToReturn, @@ -37243,13 +40210,15 @@ UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl, size_t *serverOnNetworkSize, UA_ServerOnNetwork **serverOnNetwork) { UA_Boolean connected = (client->state > UA_CLIENTSTATE_DISCONNECTED); /* Client is already connected to a different server */ - if(connected && strncmp((const char*)client->endpointUrl.data, serverUrl, - client->endpointUrl.length) != 0) { + if(connected && strncmp((const char*)client->config.endpoint.endpointUrl.data, serverUrl, + client->config.endpoint.endpointUrl.length) != 0) { return UA_STATUSCODE_BADINVALIDARGUMENT; } + UA_StatusCode retval; + const UA_String url = UA_STRING((char*)(uintptr_t)serverUrl); if(!connected) { - UA_StatusCode retval = UA_Client_connectInternal(client, serverUrl, UA_TRUE, UA_FALSE); + retval = UA_Client_connectTCPSecureChannel(client, url); if(retval != UA_STATUSCODE_GOOD) return retval; } @@ -37268,7 +40237,7 @@ UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl, &response, &UA_TYPES[UA_TYPES_FINDSERVERSONNETWORKRESPONSE]); /* Process the response */ - UA_StatusCode retval = response.responseHeader.serviceResult; + retval = response.responseHeader.serviceResult; if(retval == UA_STATUSCODE_GOOD) { *serverOnNetworkSize = response.serversSize; *serverOnNetwork = response.servers; @@ -37286,20 +40255,25 @@ UA_Client_findServersOnNetwork(UA_Client *client, const char *serverUrl, return retval; } +#endif + /*********************************** amalgamated original file "/home/jvoe/open62541/src/client/ua_client_highlevel.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2015-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015 (c) Oleksiy Vasylyev * Copyright 2017 (c) Florian Palm * Copyright 2016 (c) Chris Iatrou * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2018 (c) Fabian Arndt + * Copyright 2018 (c) Peter Rustler, basyskom GmbH */ + UA_StatusCode UA_Client_NamespaceGetIndex(UA_Client *client, UA_String *namespaceUri, UA_UInt16 *namespaceIndex) { @@ -37742,13 +40716,501 @@ UA_Client_readArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId return retval; } +/*********************/ +/* Historical Access */ +/*********************/ +#ifdef UA_ENABLE_HISTORIZING +static UA_HistoryReadResponse +__UA_Client_HistoryRead(UA_Client *client, const UA_NodeId *nodeId, + UA_ExtensionObject* details, UA_String indexRange, + UA_TimestampsToReturn timestampsToReturn, + UA_ByteString continuationPoint, UA_Boolean releaseConti) { + + UA_HistoryReadValueId item; + UA_HistoryReadValueId_init(&item); + + item.nodeId = *nodeId; + item.indexRange = indexRange; + item.continuationPoint = continuationPoint; + item.dataEncoding = UA_QUALIFIEDNAME(0, "Default Binary"); + + UA_HistoryReadRequest request; + UA_HistoryReadRequest_init(&request); + + request.nodesToRead = &item; + request.nodesToReadSize = 1; + request.timestampsToReturn = timestampsToReturn; // Defaults to Source + request.releaseContinuationPoints = releaseConti; // No values are returned, if true + + /* Build ReadDetails */ + request.historyReadDetails = *details; + + return UA_Client_Service_historyRead(client, request); +} + +static UA_StatusCode +__UA_Client_HistoryRead_service(UA_Client *client, const UA_NodeId *nodeId, + const UA_HistoricalIteratorCallback callback, + UA_ExtensionObject *details, UA_String indexRange, + UA_TimestampsToReturn timestampsToReturn, + void *callbackContext) { + + UA_ByteString continuationPoint = UA_BYTESTRING_NULL; + UA_Boolean continuationAvail = false; + UA_Boolean fetchMore = false; + UA_StatusCode retval = UA_STATUSCODE_GOOD; + + do { + /* We release the continuation point, if no more data is requested by the user */ + UA_Boolean cleanup = !fetchMore && continuationAvail; + UA_HistoryReadResponse response = + __UA_Client_HistoryRead(client, nodeId, details, indexRange, timestampsToReturn, continuationPoint, cleanup); + + if (cleanup) { + retval = response.responseHeader.serviceResult; +cleanup: UA_HistoryReadResponse_deleteMembers(&response); + UA_ByteString_deleteMembers(&continuationPoint); + return retval; + } + + retval = response.responseHeader.serviceResult; + if (retval == UA_STATUSCODE_GOOD) { + if (response.resultsSize == 1) + retval = response.results[0].statusCode; + else + retval = UA_STATUSCODE_BADUNEXPECTEDERROR; + } + if (retval != UA_STATUSCODE_GOOD) + goto cleanup; + + UA_HistoryReadResult *res = response.results; + + /* Clear old and check / store new continuation point */ + UA_ByteString_deleteMembers(&continuationPoint); + UA_ByteString_copy(&res->continuationPoint, &continuationPoint); + continuationAvail = !UA_ByteString_equal(&continuationPoint, &UA_BYTESTRING_NULL); + + /* Client callback with possibility to request further values */ + fetchMore = callback(client, nodeId, continuationAvail, &res->historyData, callbackContext); + + /* Regular cleanup */ + UA_HistoryReadResponse_deleteMembers(&response); + } while (continuationAvail); + + return retval; +} + +#ifdef UA_ENABLE_EXPERIMENTAL_HISTORIZING +UA_StatusCode +UA_Client_HistoryRead_events(UA_Client *client, const UA_NodeId *nodeId, + const UA_HistoricalIteratorCallback callback, + UA_DateTime startTime, UA_DateTime endTime, + UA_String indexRange, const UA_EventFilter filter, UA_UInt32 numValuesPerNode, + UA_TimestampsToReturn timestampsToReturn, void *callbackContext) { + + UA_ReadEventDetails details; + UA_ReadEventDetails_init(&details); + details.filter = filter; + + // At least two of the following parameters must be set + details.numValuesPerNode = numValuesPerNode; // 0 = return all / max server is capable of + details.startTime = startTime; + details.endTime = endTime; + + UA_ExtensionObject detailsExtensionObject; + UA_ExtensionObject_init(&detailsExtensionObject); + detailsExtensionObject.content.decoded.type = &UA_TYPES[UA_TYPES_READEVENTDETAILS]; + detailsExtensionObject.content.decoded.data = &details; + detailsExtensionObject.encoding = UA_EXTENSIONOBJECT_DECODED; + + return __UA_Client_HistoryRead_service(client, nodeId, callback, &detailsExtensionObject, + indexRange, timestampsToReturn, callbackContext); +} +#endif // UA_ENABLE_EXPERIMENTAL_HISTORIZING + +static UA_StatusCode +__UA_Client_HistoryRead_service_rawMod(UA_Client *client, const UA_NodeId *nodeId, + const UA_HistoricalIteratorCallback callback, + UA_DateTime startTime,UA_DateTime endTime, + UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 numValuesPerNode, + UA_Boolean readModified, UA_TimestampsToReturn timestampsToReturn, + void *callbackContext) { + + UA_ReadRawModifiedDetails details; + UA_ReadRawModifiedDetails_init(&details); + details.isReadModified = readModified; // Return only modified values + details.returnBounds = returnBounds; // Return values pre / post given range + + // At least two of the following parameters must be set + details.numValuesPerNode = numValuesPerNode; // 0 = return all / max server is capable of + details.startTime = startTime; + details.endTime = endTime; + + UA_ExtensionObject detailsExtensionObject; + UA_ExtensionObject_init(&detailsExtensionObject); + detailsExtensionObject.content.decoded.type = &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS]; + detailsExtensionObject.content.decoded.data = &details; + detailsExtensionObject.encoding = UA_EXTENSIONOBJECT_DECODED; + + return __UA_Client_HistoryRead_service(client, nodeId, callback, + &detailsExtensionObject, indexRange, + timestampsToReturn, callbackContext); +} + +UA_StatusCode +UA_Client_HistoryRead_raw(UA_Client *client, const UA_NodeId *nodeId, + const UA_HistoricalIteratorCallback callback, + UA_DateTime startTime, UA_DateTime endTime, + UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 numValuesPerNode, + UA_TimestampsToReturn timestampsToReturn, void *callbackContext) { + + return __UA_Client_HistoryRead_service_rawMod(client, nodeId, callback, startTime, endTime, indexRange, returnBounds, + numValuesPerNode, false, timestampsToReturn, callbackContext); +} + +#ifdef UA_ENABLE_EXPERIMENTAL_HISTORIZING +UA_StatusCode +UA_Client_HistoryRead_modified(UA_Client *client, const UA_NodeId *nodeId, + const UA_HistoricalIteratorCallback callback, + UA_DateTime startTime, UA_DateTime endTime, + UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 maxItems, + UA_TimestampsToReturn timestampsToReturn, void *callbackContext) { + + return __UA_Client_HistoryRead_service_rawMod(client, nodeId, callback, startTime, endTime, indexRange, returnBounds, + maxItems, true, timestampsToReturn, callbackContext); +} +#endif // UA_ENABLE_EXPERIMENTAL_HISTORIZING + +static UA_HistoryUpdateResponse +__UA_Client_HistoryUpdate(UA_Client *client, + void *details, + size_t typeId) +{ + UA_HistoryUpdateRequest request; + UA_HistoryUpdateRequest_init(&request); + + UA_ExtensionObject extension; + UA_ExtensionObject_init(&extension); + request.historyUpdateDetailsSize = 1; + request.historyUpdateDetails = &extension; + + extension.encoding = UA_EXTENSIONOBJECT_DECODED; + extension.content.decoded.type = &UA_TYPES[typeId]; + extension.content.decoded.data = details; + + UA_HistoryUpdateResponse response; + response = UA_Client_Service_historyUpdate(client, request); + //UA_HistoryUpdateRequest_deleteMembers(&request); + return response; +} + +static UA_StatusCode +__UA_Client_HistoryUpdate_updateData(UA_Client *client, + const UA_NodeId *nodeId, + UA_PerformUpdateType type, + UA_DataValue *value) +{ + UA_StatusCode ret = UA_STATUSCODE_GOOD; + UA_UpdateDataDetails details; + UA_UpdateDataDetails_init(&details); + + details.performInsertReplace = type; + details.updateValuesSize = 1; + details.updateValues = value; + UA_NodeId_copy(nodeId, &details.nodeId); + + UA_HistoryUpdateResponse response; + response = __UA_Client_HistoryUpdate(client, &details, UA_TYPES_UPDATEDATADETAILS); + if (response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) { + ret = response.responseHeader.serviceResult; + goto cleanup; + } + if (response.resultsSize != 1 || response.results[0].operationResultsSize != 1) { + ret = UA_STATUSCODE_BADUNEXPECTEDERROR; + goto cleanup; + } + if (response.results[0].statusCode != UA_STATUSCODE_GOOD) { + ret = response.results[0].statusCode; + goto cleanup; + } + ret = response.results[0].operationResults[0]; +cleanup: + UA_HistoryUpdateResponse_deleteMembers(&response); + UA_NodeId_deleteMembers(&details.nodeId); + return ret; +} + +UA_StatusCode +UA_Client_HistoryUpdate_insert(UA_Client *client, + const UA_NodeId *nodeId, + UA_DataValue *value) +{ + return __UA_Client_HistoryUpdate_updateData(client, + nodeId, + UA_PERFORMUPDATETYPE_INSERT, + value); +} + +UA_StatusCode +UA_Client_HistoryUpdate_replace(UA_Client *client, + const UA_NodeId *nodeId, + UA_DataValue *value) +{ + return __UA_Client_HistoryUpdate_updateData(client, + nodeId, + UA_PERFORMUPDATETYPE_REPLACE, + value); +} + +UA_StatusCode +UA_Client_HistoryUpdate_update(UA_Client *client, + const UA_NodeId *nodeId, + UA_DataValue *value) +{ + return __UA_Client_HistoryUpdate_updateData(client, + nodeId, + UA_PERFORMUPDATETYPE_UPDATE, + value); +} + +UA_StatusCode +UA_Client_HistoryUpdate_deleteRaw(UA_Client *client, + const UA_NodeId *nodeId, + UA_DateTime startTimestamp, + UA_DateTime endTimestamp) +{ + UA_StatusCode ret = UA_STATUSCODE_GOOD; + + UA_DeleteRawModifiedDetails details; + UA_DeleteRawModifiedDetails_init(&details); + + details.isDeleteModified = false; + details.startTime = startTimestamp; + details.endTime = endTimestamp; + UA_NodeId_copy(nodeId, &details.nodeId); + + UA_HistoryUpdateResponse response; + response = __UA_Client_HistoryUpdate(client, &details, UA_TYPES_DELETERAWMODIFIEDDETAILS); + if (response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) { + ret = response.responseHeader.serviceResult; + goto cleanup; + } + if (response.resultsSize != 1) { + ret = UA_STATUSCODE_BADUNEXPECTEDERROR; + goto cleanup; + } + + ret = response.results[0].statusCode; + +cleanup: + UA_HistoryUpdateResponse_deleteMembers(&response); + UA_NodeId_deleteMembers(&details.nodeId); + return ret; +} +#endif // UA_ENABLE_HISTORIZING + +/* Async Functions */ + +static +void ValueAttributeRead(UA_Client *client, void *userdata, + UA_UInt32 requestId, void *response) { + if(!response) + return; + + /* Find the callback for the response */ + CustomCallback *cc; + LIST_FOREACH(cc, &client->customCallbacks, pointers) { + if(cc->callbackId == requestId) + break; + } + if(!cc) + return; + + UA_ReadResponse *rr = (UA_ReadResponse *) response; + UA_DataValue *res = rr->results; + UA_Boolean done = false; + if(rr->resultsSize == 1 && res != NULL && res->hasValue) { + if(cc->attributeId == UA_ATTRIBUTEID_VALUE) { + /* Call directly with the variant */ + cc->callback(client, userdata, requestId, &res->value); + done = true; + } else if(UA_Variant_isScalar(&res->value) && + res->value.type == cc->outDataType) { + /* Unpack the value */ + UA_STACKARRAY(UA_Byte, value, cc->outDataType->memSize); + memcpy(&value, res->value.data, cc->outDataType->memSize); + cc->callback(client, userdata, requestId, &value); + done = true; + } + } + + /* Could not process, delete the callback anyway */ + if(!done) + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Cannot process the response to the async read " + "request %u", requestId); + + LIST_REMOVE(cc, pointers); + UA_free(cc); +} + +/*Read Attributes*/ +UA_StatusCode __UA_Client_readAttribute_async(UA_Client *client, + const UA_NodeId *nodeId, UA_AttributeId attributeId, + const UA_DataType *outDataType, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + UA_ReadValueId item; + UA_ReadValueId_init(&item); + item.nodeId = *nodeId; + item.attributeId = attributeId; + UA_ReadRequest request; + UA_ReadRequest_init(&request); + request.nodesToRead = &item; + request.nodesToReadSize = 1; + + __UA_Client_AsyncService(client, &request, &UA_TYPES[UA_TYPES_READREQUEST], + ValueAttributeRead, &UA_TYPES[UA_TYPES_READRESPONSE], + userdata, reqId); + + CustomCallback *cc = (CustomCallback*) UA_malloc(sizeof(CustomCallback)); + if (!cc) + return UA_STATUSCODE_BADOUTOFMEMORY; + cc->callback = callback; + cc->callbackId = *reqId; + + cc->attributeId = attributeId; + cc->outDataType = outDataType; + + LIST_INSERT_HEAD(&client->customCallbacks, cc, pointers); + + return UA_STATUSCODE_GOOD; +} + +/*Write Attributes*/ +UA_StatusCode __UA_Client_writeAttribute_async(UA_Client *client, + const UA_NodeId *nodeId, UA_AttributeId attributeId, const void *in, + const UA_DataType *inDataType, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + if (!in) + return UA_STATUSCODE_BADTYPEMISMATCH; + + UA_WriteValue wValue; + UA_WriteValue_init(&wValue); + wValue.nodeId = *nodeId; + wValue.attributeId = attributeId; + if (attributeId == UA_ATTRIBUTEID_VALUE) + wValue.value.value = *(const UA_Variant*) in; + else + /* hack. is never written into. */ + UA_Variant_setScalar(&wValue.value.value, (void*) (uintptr_t) in, + inDataType); + wValue.value.hasValue = true; + UA_WriteRequest wReq; + UA_WriteRequest_init(&wReq); + wReq.nodesToWrite = &wValue; + wReq.nodesToWriteSize = 1; + + return __UA_Client_AsyncService(client, &wReq, + &UA_TYPES[UA_TYPES_WRITEREQUEST], callback, + &UA_TYPES[UA_TYPES_WRITERESPONSE], userdata, reqId); +} + +/*Node Management*/ + +UA_StatusCode UA_EXPORT +__UA_Client_addNode_async(UA_Client *client, const UA_NodeClass nodeClass, + const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId, + const UA_NodeId referenceTypeId, const UA_QualifiedName browseName, + const UA_NodeId typeDefinition, const UA_NodeAttributes *attr, + const UA_DataType *attributeType, UA_NodeId *outNewNodeId, + UA_ClientAsyncServiceCallback callback, void *userdata, + UA_UInt32 *reqId) { + UA_AddNodesRequest request; + UA_AddNodesRequest_init(&request); + UA_AddNodesItem item; + UA_AddNodesItem_init(&item); + item.parentNodeId.nodeId = parentNodeId; + item.referenceTypeId = referenceTypeId; + item.requestedNewNodeId.nodeId = requestedNewNodeId; + item.browseName = browseName; + item.nodeClass = nodeClass; + item.typeDefinition.nodeId = typeDefinition; + item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE; + item.nodeAttributes.content.decoded.type = attributeType; + item.nodeAttributes.content.decoded.data = (void*) (uintptr_t) attr; // hack. is not written into. + request.nodesToAdd = &item; + request.nodesToAddSize = 1; + + return __UA_Client_AsyncService(client, &request, + &UA_TYPES[UA_TYPES_ADDNODESREQUEST], callback, + &UA_TYPES[UA_TYPES_ADDNODESRESPONSE], userdata, reqId); + +} + +/* Misc Highlevel Functions */ +#ifdef UA_ENABLE_METHODCALLS +UA_StatusCode __UA_Client_call_async(UA_Client *client, + const UA_NodeId objectId, const UA_NodeId methodId, size_t inputSize, + const UA_Variant *input, UA_ClientAsyncServiceCallback callback, + void *userdata, UA_UInt32 *reqId) { + + UA_CallRequest request; + UA_CallRequest_init(&request); + UA_CallMethodRequest item; + UA_CallMethodRequest_init(&item); + item.methodId = methodId; + item.objectId = objectId; + item.inputArguments = (UA_Variant *) (void*) (uintptr_t) input; // cast const... + item.inputArgumentsSize = inputSize; + request.methodsToCall = &item; + request.methodsToCallSize = 1; + + return __UA_Client_AsyncService(client, &request, + &UA_TYPES[UA_TYPES_CALLREQUEST], callback, + &UA_TYPES[UA_TYPES_CALLRESPONSE], userdata, reqId); +} +#endif + +UA_StatusCode __UA_Client_translateBrowsePathsToNodeIds_async(UA_Client *client, + char *paths[], UA_UInt32 ids[], size_t pathSize, + UA_ClientAsyncServiceCallback callback, void *userdata, + UA_UInt32 *reqId) { + + UA_BrowsePath browsePath; + UA_BrowsePath_init(&browsePath); + browsePath.startingNode = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); + browsePath.relativePath.elements = (UA_RelativePathElement*) UA_Array_new( + pathSize, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); + if (!browsePath.relativePath.elements) + return UA_STATUSCODE_BADOUTOFMEMORY; + browsePath.relativePath.elementsSize = pathSize; + + UA_TranslateBrowsePathsToNodeIdsRequest request; + UA_TranslateBrowsePathsToNodeIdsRequest_init(&request); + request.browsePaths = &browsePath; + request.browsePathsSize = 1; + + UA_StatusCode retval = __UA_Client_AsyncService(client, &request, + &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSREQUEST], callback, + &UA_TYPES[UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE], userdata, + reqId); + if (retval != UA_STATUSCODE_GOOD) { + UA_Array_delete(browsePath.relativePath.elements, + browsePath.relativePath.elementsSize, + &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); + return retval; + } + UA_BrowsePath_deleteMembers(&browsePath); + return retval; +} + /*********************************** amalgamated original file "/home/jvoe/open62541/src/client/ua_client_subscriptions.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2015-2018 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2015 (c) Oleksiy Vasylyev * Copyright 2016 (c) Sten Grüner * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA @@ -37758,6 +41220,7 @@ UA_Client_readArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId */ + #ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ /*****************/ @@ -37881,7 +41344,8 @@ UA_Client_Subscriptions_delete(UA_Client *client, const UA_DeleteSubscriptionsRe /* Loop over the removed subscriptions and remove internally */ for(size_t i = 0; i < request.subscriptionIdsSize; i++) { - if(response.results[i] != UA_STATUSCODE_GOOD && response.results[i] != UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID) { + if(response.results[i] != UA_STATUSCODE_GOOD && + response.results[i] != UA_STATUSCODE_BADSUBSCRIPTIONIDINVALID) { /* Something was wrong, reinsert the subscription in the list */ if (subs[i]) LIST_INSERT_HEAD(&client->subscriptions, subs[i], listEntry); @@ -37889,14 +41353,13 @@ UA_Client_Subscriptions_delete(UA_Client *client, const UA_DeleteSubscriptionsRe } if(!subs[i]) { - UA_LOG_INFO(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "No internal representation of subscription %u", request.subscriptionIds[i]); continue; - } else { - LIST_INSERT_HEAD(&client->subscriptions, subs[i], listEntry); } - + + LIST_INSERT_HEAD(&client->subscriptions, subs[i], listEntry); UA_Client_Subscription_deleteInternal(client, subs[i]); } @@ -37944,6 +41407,7 @@ UA_Client_Subscriptions_deleteSingle(UA_Client *client, UA_UInt32 subscriptionId void UA_Client_MonitoredItem_remove(UA_Client *client, UA_Client_Subscription *sub, UA_Client_MonitoredItem *mon) { + // NOLINTNEXTLINE LIST_REMOVE(mon, listEntry); if(mon->deleteCallback) mon->deleteCallback(client, sub->subscriptionId, sub->context, @@ -38021,6 +41485,10 @@ __UA_Client_MonitoredItems_create(UA_Client *client, newMon->isEventMonitoredItem = (request->itemsToCreate[i].itemToMonitor.attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER); LIST_INSERT_HEAD(&sub->monitoredItems, newMon, listEntry); + + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Subscription %u | Added a MonitoredItem with handle %u", + sub->subscriptionId, newMon->clientHandle); } return; @@ -38081,11 +41549,11 @@ UA_Client_MonitoredItems_createDataChange(UA_Client *client, UA_UInt32 subscript UA_CreateMonitoredItemsResponse UA_EXPORT UA_Client_MonitoredItems_createEvents(UA_Client *client, const UA_CreateMonitoredItemsRequest request, void **contexts, - UA_Client_EventNotificationCallback *callbacks, - UA_Client_DeleteMonitoredItemCallback *deleteCallbacks) { + UA_Client_EventNotificationCallback *callback, + UA_Client_DeleteMonitoredItemCallback *deleteCallback) { UA_CreateMonitoredItemsResponse response; __UA_Client_MonitoredItems_create(client, &request, contexts, - (void**)(uintptr_t)callbacks, deleteCallbacks, &response); + (void**)(uintptr_t)callback, deleteCallback, &response); return response; } @@ -38103,7 +41571,14 @@ UA_Client_MonitoredItems_createEvent(UA_Client *client, UA_UInt32 subscriptionId UA_CreateMonitoredItemsResponse response = UA_Client_MonitoredItems_createEvents(client, request, &context, &callback, &deleteCallback); + UA_StatusCode retval = response.responseHeader.serviceResult; UA_MonitoredItemCreateResult result; + UA_MonitoredItemCreateResult_init(&result); + if(retval != UA_STATUSCODE_GOOD) { + UA_CreateMonitoredItemsResponse_deleteMembers(&response); + result.statusCode = retval; + return result; + } UA_MonitoredItemCreateResult_copy(response.results , &result); UA_CreateMonitoredItemsResponse_deleteMembers(&response); return result; @@ -38120,7 +41595,7 @@ UA_Client_MonitoredItems_delete(UA_Client *client, const UA_DeleteMonitoredItems UA_Client_Subscription *sub = findSubscription(client, request.subscriptionId); if(!sub) { - UA_LOG_INFO(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_CLIENT, "No internal representation of subscription %u", request.subscriptionId); return response; @@ -38137,7 +41612,8 @@ UA_Client_MonitoredItems_delete(UA_Client *client, const UA_DeleteMonitoredItems /* Delete the internal representation */ UA_Client_MonitoredItem *mon; LIST_FOREACH(mon, &sub->monitoredItems, listEntry) { - if(mon->monitoredItemId == request.monitoredItemIds[i]) { + // NOLINTNEXTLINE + if (mon->monitoredItemId == request.monitoredItemIds[i]) { UA_Client_MonitoredItem_remove(client, sub, mon); break; } @@ -38270,14 +41746,14 @@ processDataChangeNotification(UA_Client *client, UA_Client_Subscription *sub, } if(!mon) { - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Could not process a notification with clienthandle %u on subscription %u", min->clientHandle, sub->subscriptionId); continue; } if(mon->isEventMonitoredItem) { - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_CLIENT, "MonitoredItem is configured for Events. But received a " "DataChangeNotification."); continue; @@ -38298,19 +41774,19 @@ processEventNotification(UA_Client *client, UA_Client_Subscription *sub, /* Find the MonitoredItem */ UA_Client_MonitoredItem *mon; LIST_FOREACH(mon, &sub->monitoredItems, listEntry) { - if(mon->monitoredItemId == eventFieldList->clientHandle) + if(mon->clientHandle == eventFieldList->clientHandle) break; } if(!mon) { - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Could not process a notification with clienthandle %u on subscription %u", eventFieldList->clientHandle, sub->subscriptionId); continue; } if(!mon->isEventMonitoredItem) { - UA_LOG_DEBUG(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_CLIENT, "MonitoredItem is configured for DataChanges. But received a " "EventNotification."); continue; @@ -38351,13 +41827,13 @@ processNotificationMessage(UA_Client *client, UA_Client_Subscription *sub, sub->statusChangeCallback(client, sub->subscriptionId, sub->context, (UA_StatusChangeNotification*)msg->content.decoded.data); } else { - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Dropped a StatusChangeNotification since no callback is registered"); } return; } - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Unknown notification message type"); } @@ -38371,11 +41847,11 @@ UA_Client_Subscriptions_processPublishResponse(UA_Client *client, UA_PublishRequ if(response->responseHeader.serviceResult == UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS) { if(client->config.outStandingPublishRequests > 1) { client->config.outStandingPublishRequests--; - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Too many publishrequest, reduce outStandingPublishRequests to %d", client->config.outStandingPublishRequests); } else { - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Too many publishrequest when outStandingPublishRequests = 1"); UA_Client_Subscriptions_deleteSingle(client, response->subscriptionId); } @@ -38392,22 +41868,33 @@ UA_Client_Subscriptions_processPublishResponse(UA_Client *client, UA_PublishRequ if(response->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONCLOSED) { if(client->state >= UA_CLIENTSTATE_SESSION) { - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Received Publish Response with code %s", UA_StatusCode_name(response->responseHeader.serviceResult)); + UA_Client_Subscription* sub = findSubscription(client, response->subscriptionId); + if (sub != NULL) + UA_Client_Subscription_deleteInternal(client, sub); } return; } if(response->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONIDINVALID) { - UA_Client_close(client); /* TODO: This should be handled before the process callback */ - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_Client_disconnect(client); /* TODO: This should be handled before the process callback */ + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Received BadSessionIdInvalid"); return; } + if(response->responseHeader.serviceResult == UA_STATUSCODE_BADTIMEOUT) { + if (client->config.inactivityCallback) + client->config.inactivityCallback(client); + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, + "Received Timeout for Publish Response"); + return; + } + if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Received Publish Response with code %s", UA_StatusCode_name(response->responseHeader.serviceResult)); return; @@ -38416,7 +41903,7 @@ UA_Client_Subscriptions_processPublishResponse(UA_Client *client, UA_PublishRequ UA_Client_Subscription *sub = findSubscription(client, response->subscriptionId); if(!sub) { response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR; - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Received Publish Response for a non-existant subscription"); return; } @@ -38425,14 +41912,14 @@ UA_Client_Subscriptions_processPublishResponse(UA_Client *client, UA_PublishRequ /* Detect missing message - OPC Unified Architecture, Part 4 5.13.1.1 e) */ if(UA_Client_Subscriptions_nextSequenceNumber(sub->sequenceNumber) != msg->sequenceNumber) { - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Invalid subscription sequence number: expected %u but got %u", UA_Client_Subscriptions_nextSequenceNumber(sub->sequenceNumber), msg->sequenceNumber); /* This is an error. But we do not abort the connection. Some server * SDKs misbehave from time to time and send out-of-order sequence * numbers. (Probably some multi-threading synchronization issue.) */ - /* UA_Client_close(client); + /* UA_Client_disconnect(client); return; */ } /* According to f), a keep-alive message contains no notifications and has the sequence number @@ -38453,7 +41940,7 @@ UA_Client_Subscriptions_processPublishResponse(UA_Client *client, UA_PublishRequ UA_Client_NotificationsAckNumber *tmpAck = (UA_Client_NotificationsAckNumber*) UA_malloc(sizeof(UA_Client_NotificationsAckNumber)); if(!tmpAck) { - UA_LOG_WARNING(client->config.logger, UA_LOGCATEGORY_CLIENT, + UA_LOG_WARNING(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Not enough memory to store the acknowledgement for a publish " "message on subscription %u", sub->subscriptionId); break; @@ -38467,7 +41954,7 @@ UA_Client_Subscriptions_processPublishResponse(UA_Client *client, UA_PublishRequ static void processPublishResponseAsync(UA_Client *client, void *userdata, UA_UInt32 requestId, - void *response, const UA_DataType *responseType) { + void *response) { UA_PublishRequest *req = (UA_PublishRequest*)userdata; UA_PublishResponse *res = (UA_PublishResponse*)response; @@ -38515,8 +42002,9 @@ UA_Client_Subscriptions_backgroundPublishInactivityCheck(UA_Client *client) { sub->lastActivity = UA_DateTime_nowMonotonic(); if(client->config.subscriptionInactivityCallback) - client->config.subscriptionInactivityCallback(client, sub->subscriptionId, sub->context); - UA_LOG_ERROR(client->config.logger, UA_LOGCATEGORY_CLIENT, + client->config.subscriptionInactivityCallback(client, sub->subscriptionId, + sub->context); + UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT, "Inactivity for Subscription %u.", sub->subscriptionId); } } @@ -38562,384 +42050,155 @@ UA_Client_Subscriptions_backgroundPublish(UA_Client *client) { #endif /* UA_ENABLE_SUBSCRIPTIONS */ -/*********************************** amalgamated original file "/home/jvoe/open62541/src/client/ua_client_subscriptions_deprecated.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/src/client/ua_client_worker.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * Copyright 2015-2018 (c) Julius Pfrommer, Fraunhofer IOSB - * Copyright 2015 (c) Oleksiy Vasylyev - * Copyright 2016 (c) Sten Grüner - * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA - * Copyright 2016-2017 (c) Florian Palm - * Copyright 2017 (c) Frank Meerkötter - * Copyright 2017 (c) Stefan Profanter, fortiss GmbH - */ - - -#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ - -const UA_SubscriptionSettings UA_SubscriptionSettings_default = { - 500.0, /* .requestedPublishingInterval */ - 10000, /* .requestedLifetimeCount */ - 1, /* .requestedMaxKeepAliveCount */ - 0, /* .maxNotificationsPerPublish */ - true, /* .publishingEnabled */ - 0 /* .priority */ -}; - -UA_StatusCode -UA_Client_Subscriptions_new(UA_Client *client, UA_SubscriptionSettings settings, - UA_UInt32 *newSubscriptionId) { - UA_CreateSubscriptionRequest request; - UA_CreateSubscriptionRequest_init(&request); - request.requestedPublishingInterval = settings.requestedPublishingInterval; - request.requestedLifetimeCount = settings.requestedLifetimeCount; - request.requestedMaxKeepAliveCount = settings.requestedMaxKeepAliveCount; - request.maxNotificationsPerPublish = settings.maxNotificationsPerPublish; - request.publishingEnabled = settings.publishingEnabled; - request.priority = settings.priority; - - UA_CreateSubscriptionResponse response = - UA_Client_Subscriptions_create(client, request, NULL, NULL, NULL); - - UA_StatusCode retval = response.responseHeader.serviceResult; - if(retval == UA_STATUSCODE_GOOD && newSubscriptionId) - *newSubscriptionId = response.subscriptionId; - - UA_CreateSubscriptionResponse_deleteMembers(&response); - return retval; -} - -UA_StatusCode -UA_Client_Subscriptions_remove(UA_Client *client, UA_UInt32 subscriptionId) { - UA_DeleteSubscriptionsRequest request; - UA_DeleteSubscriptionsRequest_init(&request); - request.subscriptionIdsSize = 1; - request.subscriptionIds = &subscriptionId; - - UA_DeleteSubscriptionsResponse response = - UA_Client_Subscriptions_delete(client, request); - - UA_StatusCode retval = response.responseHeader.serviceResult; - if(retval == UA_STATUSCODE_GOOD) { - if(response.resultsSize != 1) - retval = UA_STATUSCODE_BADINTERNALERROR; - } - - if(retval == UA_STATUSCODE_GOOD) - retval = response.results[0]; - - UA_DeleteSubscriptionsResponse_deleteMembers(&response); - return retval; -} - -UA_StatusCode -UA_Client_Subscriptions_manuallySendPublishRequest(UA_Client *client) { - if(client->state < UA_CLIENTSTATE_SESSION) - return UA_STATUSCODE_BADSERVERNOTCONNECTED; + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - UA_StatusCode retval = UA_STATUSCODE_GOOD; +static void +asyncServiceTimeoutCheck(UA_Client *client) { UA_DateTime now = UA_DateTime_nowMonotonic(); - UA_DateTime maxDate = now + (UA_DateTime)(client->config.timeout * UA_DATETIME_MSEC); - UA_Boolean moreNotifications = true; - while(moreNotifications) { - UA_PublishRequest request; - UA_PublishRequest_init(&request); - retval = UA_Client_preparePublishRequest(client, &request); - if(retval != UA_STATUSCODE_GOOD) - return retval; - - /* Manually increase the number of sent publish requests. Otherwise we - * send out one too many when we process async responses when we wait - * for the correct publish response. The - * currentlyOutStandingPublishRequests will be reduced during processing - * of the response. */ - client->currentlyOutStandingPublishRequests++; + /* Timeout occurs, remove the callback */ + AsyncServiceCall *ac, *ac_tmp; + LIST_FOREACH_SAFE(ac, &client->asyncServiceCalls, pointers, ac_tmp) { + if(!ac->timeout) + continue; - UA_PublishResponse response; - __UA_Client_Service(client, - &request, &UA_TYPES[UA_TYPES_PUBLISHREQUEST], - &response, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); - UA_Client_Subscriptions_processPublishResponse(client, &request, &response); - UA_PublishRequest_deleteMembers(&request); - - now = UA_DateTime_nowMonotonic(); - if(now > maxDate) { - moreNotifications = UA_FALSE; - retval = UA_STATUSCODE_GOODNONCRITICALTIMEOUT; - } else { - moreNotifications = response.moreNotifications; + if(ac->start + (UA_DateTime)(ac->timeout * UA_DATETIME_MSEC) <= now) { + LIST_REMOVE(ac, pointers); + UA_Client_AsyncService_cancel(client, ac, UA_STATUSCODE_BADTIMEOUT); + UA_free(ac); } - - UA_PublishResponse_deleteMembers(&response); - UA_PublishRequest_deleteMembers(&request); } - - if(client->state < UA_CLIENTSTATE_SESSION) - return UA_STATUSCODE_BADSERVERNOTCONNECTED; - - return retval; } -/* Callbacks for the MonitoredItems. The callbacks for the deprecated API are - * wrapped. The wrapper is cleaned up upon destruction. */ - -typedef struct { - UA_MonitoredItemHandlingFunction origCallback; - void *context; -} dataChangeCallbackWrapper; - static void -dataChangeCallback(UA_Client *client, UA_UInt32 subId, void *subContext, - UA_UInt32 monId, void *monContext, UA_DataValue *value) { - dataChangeCallbackWrapper *wrapper = (dataChangeCallbackWrapper*)monContext; - wrapper->origCallback(client, monId, value, wrapper->context); +backgroundConnectivityCallback(UA_Client *client, void *userdata, + UA_UInt32 requestId, const UA_ReadResponse *response) { + if(response->responseHeader.serviceResult == UA_STATUSCODE_BADTIMEOUT) { + if (client->config.inactivityCallback) + client->config.inactivityCallback(client); + } + client->pendingConnectivityCheck = false; + client->lastConnectivityCheck = UA_DateTime_nowMonotonic(); } -typedef struct { - UA_MonitoredEventHandlingFunction origCallback; - void *context; -} eventCallbackWrapper; +static UA_StatusCode +UA_Client_backgroundConnectivity(UA_Client *client) { + if(!client->config.connectivityCheckInterval) + return UA_STATUSCODE_GOOD; -static void -eventCallback(UA_Client *client, UA_UInt32 subId, void *subContext, - UA_UInt32 monId, void *monContext, size_t nEventFields, - UA_Variant *eventFields) { - eventCallbackWrapper *wrapper = (eventCallbackWrapper*)monContext; - wrapper->origCallback(client, monId, nEventFields, eventFields, wrapper->context); -} + if (client->pendingConnectivityCheck) + return UA_STATUSCODE_GOOD; -static void -deleteMonitoredItemCallback(UA_Client *client, UA_UInt32 subId, void *subContext, - UA_UInt32 monId, void *monContext) { - UA_free(monContext); -} - -static UA_StatusCode -addMonitoredItems(UA_Client *client, const UA_UInt32 subscriptionId, - UA_MonitoredItemCreateRequest *items, size_t itemsSize, - UA_MonitoredItemHandlingFunction *hfs, void **hfContexts, - UA_StatusCode *itemResults, UA_UInt32 *newMonitoredItemIds) { - /* Create array of wrappers and callbacks */ - UA_STACKARRAY(dataChangeCallbackWrapper*, wrappers, itemsSize); - UA_STACKARRAY(UA_Client_DeleteMonitoredItemCallback, deleteCbs, itemsSize); - UA_STACKARRAY(UA_Client_DataChangeNotificationCallback, wrapperCbs, itemsSize); - - for(size_t i = 0; i < itemsSize; i++) { - wrappers[i] = (dataChangeCallbackWrapper*)UA_malloc(sizeof(dataChangeCallbackWrapper)); - if(!wrappers[i]) { - for(size_t j = 0; j < i; j++) - UA_free(wrappers[j]); - return UA_STATUSCODE_BADOUTOFMEMORY; - } - wrappers[i]->origCallback = (UA_MonitoredItemHandlingFunction)(uintptr_t)hfs[i]; - wrappers[i]->context = hfContexts[i]; + UA_DateTime now = UA_DateTime_nowMonotonic(); + UA_DateTime nextDate = client->lastConnectivityCheck + (UA_DateTime)(client->config.connectivityCheckInterval * UA_DATETIME_MSEC); - deleteCbs[i] = deleteMonitoredItemCallback; - wrapperCbs[i] = dataChangeCallback; - } + if(now <= nextDate) + return UA_STATUSCODE_GOOD; - /* Prepare the request */ - UA_CreateMonitoredItemsRequest request; - UA_CreateMonitoredItemsRequest_init(&request); - request.subscriptionId = subscriptionId; - request.itemsToCreateSize = itemsSize; - request.itemsToCreate = items; + UA_ReadRequest request; + UA_ReadRequest_init(&request); - /* Process and return */ - UA_CreateMonitoredItemsResponse response = - UA_Client_MonitoredItems_createDataChanges(client, request, (void**)wrappers, - wrapperCbs, deleteCbs); + UA_ReadValueId rvid; + UA_ReadValueId_init(&rvid); + rvid.attributeId = UA_ATTRIBUTEID_VALUE; + rvid.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_STATE); - UA_StatusCode retval = response.responseHeader.serviceResult; - if(retval == UA_STATUSCODE_GOOD && response.resultsSize != itemsSize) - retval = UA_STATUSCODE_BADINTERNALERROR; + request.nodesToRead = &rvid; + request.nodesToReadSize = 1; - if(retval == UA_STATUSCODE_GOOD) { - for(size_t i = 0; i < itemsSize; i++) { - itemResults[i] = response.results[i].statusCode; - newMonitoredItemIds[i] = response.results[i].monitoredItemId; - } - } + UA_StatusCode retval = __UA_Client_AsyncService(client, &request, &UA_TYPES[UA_TYPES_READREQUEST], + (UA_ClientAsyncServiceCallback)backgroundConnectivityCallback, + &UA_TYPES[UA_TYPES_READRESPONSE], NULL, NULL); - UA_CreateMonitoredItemsResponse_deleteMembers(&response); - return retval; -} + client->pendingConnectivityCheck = true; -UA_StatusCode -UA_Client_Subscriptions_addMonitoredItems(UA_Client *client, const UA_UInt32 subscriptionId, - UA_MonitoredItemCreateRequest *items, size_t itemsSize, - UA_MonitoredItemHandlingFunction *hfs, - void **hfContexts, UA_StatusCode *itemResults, - UA_UInt32 *newMonitoredItemIds) { - return addMonitoredItems(client, subscriptionId, items, itemsSize, hfs, hfContexts, itemResults, - newMonitoredItemIds); + return retval; } -UA_StatusCode -UA_Client_Subscriptions_addMonitoredItem(UA_Client *client, UA_UInt32 subscriptionId, - UA_NodeId nodeId, UA_UInt32 attributeID, - UA_MonitoredItemHandlingFunction hf, void *hfContext, - UA_UInt32 *newMonitoredItemId, UA_Double samplingInterval) { - UA_MonitoredItemCreateRequest item; - UA_MonitoredItemCreateRequest_init(&item); - item.itemToMonitor.nodeId = nodeId; - item.itemToMonitor.attributeId = attributeID; - item.monitoringMode = UA_MONITORINGMODE_REPORTING; - item.requestedParameters.samplingInterval = samplingInterval; - item.requestedParameters.discardOldest = true; - item.requestedParameters.queueSize = 1; - - UA_StatusCode retval_item = UA_STATUSCODE_GOOD; - UA_StatusCode retval = - addMonitoredItems(client, subscriptionId, &item, 1, - (UA_MonitoredItemHandlingFunction*)(uintptr_t)&hf, - &hfContext, &retval_item, newMonitoredItemId); - return retval | retval_item; -} - -static UA_StatusCode -addMonitoredEvents(UA_Client *client, const UA_UInt32 subscriptionId, - UA_MonitoredItemCreateRequest *items, size_t itemsSize, - UA_MonitoredEventHandlingFunction *hfs, - void **hfContexts, UA_StatusCode *itemResults, - UA_UInt32 *newMonitoredItemIds) { - /* Create array of wrappers and callbacks */ - UA_STACKARRAY(eventCallbackWrapper*, wrappers, itemsSize); - UA_STACKARRAY(UA_Client_DeleteMonitoredItemCallback, deleteCbs, itemsSize); - UA_STACKARRAY(UA_Client_EventNotificationCallback, wrapperCbs, itemsSize); - - for(size_t i = 0; i < itemsSize; i++) { - wrappers[i] = (eventCallbackWrapper*)UA_malloc(sizeof(eventCallbackWrapper)); - if(!wrappers[i]) { - for(size_t j = 0; j < i; j++) - UA_free(wrappers[j]); - return UA_STATUSCODE_BADOUTOFMEMORY; - } - wrappers[i]->origCallback = (UA_MonitoredEventHandlingFunction)(uintptr_t)hfs[i]; - wrappers[i]->context = hfContexts[i]; - - deleteCbs[i] = deleteMonitoredItemCallback; - wrapperCbs[i] = eventCallback; - } - - /* Prepare the request */ - UA_CreateMonitoredItemsRequest request; - UA_CreateMonitoredItemsRequest_init(&request); - request.subscriptionId = subscriptionId; - request.itemsToCreateSize = itemsSize; - request.itemsToCreate = items; +/** + * Main Client Loop + * ---------------- + * Start: Spin up the workers and the network layer + * Iterate: Process repeated callbacks and events in the network layer. + * This part can be driven from an external main-loop in an + * event-driven single-threaded architecture. + * Stop: Stop workers, finish all callbacks, stop the network layer, + * clean up */ - /* Process and return */ - UA_CreateMonitoredItemsResponse response = - UA_Client_MonitoredItems_createEvents(client, request, (void**)wrappers, - wrapperCbs, deleteCbs); +static void +clientExecuteRepeatedCallback(UA_Client *client, UA_ApplicationCallback cb, + void *callbackApplication, void *data) { + cb(callbackApplication, data); + /* TODO: Use workers in the client + * UA_WorkQueue_enqueue(&client->workQueue, cb, callbackApplication, data); */ +} - UA_StatusCode retval = response.responseHeader.serviceResult; - if(retval == UA_STATUSCODE_GOOD && response.resultsSize != itemsSize) - retval = UA_STATUSCODE_BADINTERNALERROR; +UA_StatusCode UA_Client_run_iterate(UA_Client *client, UA_UInt16 timeout) { +// TODO connectivity check & timeout features for the async implementation (timeout == 0) + UA_StatusCode retval = UA_STATUSCODE_GOOD; +#ifdef UA_ENABLE_SUBSCRIPTIONS + UA_StatusCode retvalPublish = UA_Client_Subscriptions_backgroundPublish(client); + if(client->state >= UA_CLIENTSTATE_SESSION && retvalPublish != UA_STATUSCODE_GOOD) + return retvalPublish; +#endif + /* Make sure we have an open channel */ - if(retval == UA_STATUSCODE_GOOD) { - for(size_t i = 0; i < itemsSize; i++) - itemResults[i] = response.results[i].statusCode; - } + /************************************************************/ + /* FIXME: This is a dirty workaround */ + if(client->state >= UA_CLIENTSTATE_SECURECHANNEL) + retval = openSecureChannel(client, true); + /* FIXME: Will most likely break somewhere in the future */ + /************************************************************/ - UA_CreateMonitoredItemsResponse_deleteMembers(&response); - return retval; -} + if(timeout) { + if(retval != UA_STATUSCODE_GOOD) + return retval; -UA_StatusCode -UA_Client_Subscriptions_addMonitoredEvents(UA_Client *client, const UA_UInt32 subscriptionId, - UA_MonitoredItemCreateRequest *items, size_t itemsSize, - UA_MonitoredEventHandlingFunction *hfs, - void **hfContexts, UA_StatusCode *itemResults, - UA_UInt32 *newMonitoredItemIds) { - return addMonitoredEvents(client, subscriptionId, items, itemsSize, hfs, - hfContexts, itemResults, newMonitoredItemIds); -} + retval = UA_Client_backgroundConnectivity(client); + if(retval != UA_STATUSCODE_GOOD) + return retval; -UA_StatusCode -UA_Client_Subscriptions_addMonitoredEvent(UA_Client *client, UA_UInt32 subscriptionId, - const UA_NodeId nodeId, UA_UInt32 attributeID, - const UA_SimpleAttributeOperand *selectClauses, - size_t selectClausesSize, - const UA_ContentFilterElement *whereClauses, - size_t whereClausesSize, - const UA_MonitoredEventHandlingFunction hf, - void *hfContext, UA_UInt32 *newMonitoredItemId) { - UA_MonitoredItemCreateRequest item; - UA_MonitoredItemCreateRequest_init(&item); - item.itemToMonitor.nodeId = nodeId; - item.itemToMonitor.attributeId = attributeID; - item.monitoringMode = UA_MONITORINGMODE_REPORTING; - item.requestedParameters.samplingInterval = 0; - item.requestedParameters.discardOldest = false; + UA_DateTime maxDate = UA_DateTime_nowMonotonic() + (timeout * UA_DATETIME_MSEC); + retval = receiveServiceResponse(client, NULL, NULL, maxDate, NULL); + if(retval == UA_STATUSCODE_GOODNONCRITICALTIMEOUT) + retval = UA_STATUSCODE_GOOD; + } else { + UA_DateTime now = UA_DateTime_nowMonotonic(); + UA_Timer_process(&client->timer, now, + (UA_TimerExecutionCallback)clientExecuteRepeatedCallback, client); - UA_EventFilter *evFilter = UA_EventFilter_new(); - if(!evFilter) - return UA_STATUSCODE_BADOUTOFMEMORY; - UA_EventFilter_init(evFilter); - evFilter->selectClausesSize = selectClausesSize; - evFilter->selectClauses = (UA_SimpleAttributeOperand*)(uintptr_t)selectClauses; - evFilter->whereClause.elementsSize = whereClausesSize; - evFilter->whereClause.elements = (UA_ContentFilterElement*)(uintptr_t)whereClauses; - - item.requestedParameters.filter.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE; - item.requestedParameters.filter.content.decoded.type = &UA_TYPES[UA_TYPES_EVENTFILTER]; - item.requestedParameters.filter.content.decoded.data = evFilter; - UA_StatusCode retval_item = UA_STATUSCODE_GOOD; - UA_StatusCode retval = addMonitoredEvents(client, subscriptionId, &item, 1, - (UA_MonitoredEventHandlingFunction*)(uintptr_t)&hf, - &hfContext, &retval_item, newMonitoredItemId); - UA_free(evFilter); - return retval | retval_item; -} - -static UA_StatusCode -removeMonitoredItems(UA_Client *client, UA_UInt32 subscriptionId, - UA_UInt32 *monitoredItemIds, size_t itemsSize, - UA_StatusCode *itemResults) { - UA_DeleteMonitoredItemsRequest request; - UA_DeleteMonitoredItemsRequest_init(&request); - request.subscriptionId = subscriptionId; - request.monitoredItemIdsSize = itemsSize; - request.monitoredItemIds = monitoredItemIds; + UA_ClientState cs = UA_Client_getState(client); + retval = UA_Client_connect_iterate(client); - UA_DeleteMonitoredItemsResponse response = UA_Client_MonitoredItems_delete(client, request); - UA_StatusCode retval = response.responseHeader.serviceResult; - if(retval == UA_STATUSCODE_GOOD) { - if(response.resultsSize != itemsSize) { - retval = UA_STATUSCODE_BADINTERNALERROR; + /* Connection failed, drop the rest */ + if(retval != UA_STATUSCODE_GOOD) + return retval; + if((cs == UA_CLIENTSTATE_SECURECHANNEL) || (cs == UA_CLIENTSTATE_SESSION)) { + /* Check for new data */ + retval = receiveServiceResponseAsync(client, NULL, NULL); } else { - for(size_t i = 0; i < itemsSize; i++) - itemResults[i] = response.results[i]; + retval = receivePacketAsync(client); } } - UA_DeleteMonitoredItemsResponse_deleteMembers(&response); - return retval; -} - -UA_StatusCode -UA_Client_Subscriptions_removeMonitoredItems(UA_Client *client, UA_UInt32 subscriptionId, - UA_UInt32 *monitoredItemIds, size_t itemsSize, - UA_StatusCode *itemResults) { - return removeMonitoredItems(client, subscriptionId, monitoredItemIds, itemsSize, itemResults); -} +#ifdef UA_ENABLE_SUBSCRIPTIONS + /* The inactivity check must be done after receiveServiceResponse*/ + UA_Client_Subscriptions_backgroundPublishInactivityCheck(client); +#endif + asyncServiceTimeoutCheck(client); -UA_StatusCode -UA_Client_Subscriptions_removeMonitoredItem(UA_Client *client, UA_UInt32 subscriptionId, - UA_UInt32 monitoredItemId) { - UA_StatusCode retval_item = UA_STATUSCODE_GOOD; - UA_StatusCode retval = removeMonitoredItems(client, subscriptionId, &monitoredItemId, 1, &retval_item); - return retval | retval_item; +#ifndef UA_ENABLE_MULTITHREADING + /* Process delayed callbacks when all callbacks and network events are + * done */ + UA_WorkQueue_manuallyProcessDelayed(&client->workQueue); +#endif + return retval; } -#endif /* UA_ENABLE_SUBSCRIPTIONS */ - /*********************************** amalgamated original file "/home/jvoe/open62541/deps/libc_time.c" ***********************************/ /* Originally released by the musl project (http://www.musl-libc.org/) under the @@ -39025,6 +42284,93 @@ int __secs_to_tm(long long t, struct mytm *tm) { return 0; } +int __month_to_secs(int month, int is_leap) +{ + static const int secs_through_month[] = { + 0, 31*86400, 59*86400, 90*86400, + 120*86400, 151*86400, 181*86400, 212*86400, + 243*86400, 273*86400, 304*86400, 334*86400 }; + int t = secs_through_month[month]; + if (is_leap && month >= 2) t+=86400; + return t; +} + +long long __year_to_secs(long long year, int *is_leap) +{ + if (year-(int)2ULL <= 136) { + int y = (int)year; + int leaps = (y-68)>>2; + if (!((y-68)&3)) { + leaps--; + if (is_leap) *is_leap = 1; + } else if (is_leap) *is_leap = 0; + return 31536000*(y-70) + 86400*leaps; + } + + int cycles, centuries, leaps, rem; + + //if (!is_leap) is_leap = &(int){0}; + int is_leap_val = 0; + if (!is_leap){ + is_leap = &is_leap_val; + } + cycles = (int)((year-100) / 400); + rem = (int)((year-100) % 400); + /* Comparison is always false because rem >= 0. + if (rem < 0) { + cycles--; + rem += 400; + } */ + if (!rem) { + *is_leap = 1; + centuries = 0; + leaps = 0; + } else { + if (rem >= 200) { + if (rem >= 300) centuries = 3, rem -= 300; + else centuries = 2, rem -= 200; + } else { + if (rem >= 100) centuries = 1, rem -= 100; + else centuries = 0; + } + if (!rem) { + *is_leap = 0; + leaps = 0; + } else { + leaps = (rem / (int)4U); + rem %= (int)4U; + *is_leap = !rem; + } + } + + leaps += 97*cycles + 24*centuries - *is_leap; + + return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400; +} + +long long __tm_to_secs(const struct mytm *tm) +{ + int is_leap; + long long year = tm->tm_year; + int month = tm->tm_mon; + if (month >= 12 || month < 0) { + int adj = month / 12; + month %= 12; + if (month < 0) { + adj--; + month += 12; + } + year += adj; + } + long long t = __year_to_secs(year, &is_leap); + t += __month_to_secs(month, is_leap); + t += 86400LL * (tm->tm_mday-1); + t += 3600LL * tm->tm_hour; + t += 60LL * tm->tm_min; + t += tm->tm_sec; + return t; +} + /*********************************** amalgamated original file "/home/jvoe/open62541/deps/pcg_basic.c" ***********************************/ /* @@ -39067,1132 +42413,6519 @@ uint32_t pcg32_random_r(pcg32_random_t* rng) { return (xorshifted >> rot) | (xorshifted << ((~rot + 1u) & 31)); /* was (xorshifted >> rot) | (xorshifted << ((-rot) & 31)) */ } -/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_network_tcp.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/deps/base64.c" ***********************************/ -/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. - * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. - * - * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB - * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH - * Copyright 2017 (c) frax2222 - * Copyright 2017 (c) Jose Cabral - * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA - */ +/* -/* Enable POSIX features */ -#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL) -# define _XOPEN_SOURCE 600 -#endif -#ifndef _DEFAULT_SOURCE -# define _DEFAULT_SOURCE -#endif -/* On older systems we need to define _BSD_SOURCE. - * _DEFAULT_SOURCE is an alias for that. */ -#ifndef _BSD_SOURCE -# define _BSD_SOURCE -#endif + https://github.com/superwills/NibbleAndAHalf + base64.h -- Fast base64 encoding and decoding. + version 1.0.0, April 17, 2013 143a -/* Disable some security warnings on MSVC */ -#ifdef _MSC_VER -# define _CRT_SECURE_NO_WARNINGS -#endif + Copyright (C) 2013 William Sherif -/* Assume that Windows versions are newer than Windows XP */ -#if defined(__MINGW32__) && (!defined(WINVER) || WINVER < 0x501) -# undef WINVER -# undef _WIN32_WINDOWS -# undef _WIN32_WINNT -# define WINVER 0x0501 -# define _WIN32_WINDOWS 0x0501 -# define _WIN32_WINNT 0x0501 -#endif + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: -#include <stdio.h> // snprintf -#include <string.h> // memset + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. -#if !defined(UA_FREERTOS) -# include <errno.h> -#else -# define AI_PASSIVE 0x01 -# define TRUE 1 -# define FALSE 0 -# define ioctl ioctlsocket -#endif + William Sherif + will.sherif@gmail.com -#ifdef _WIN32 -# include <winsock2.h> -# include <ws2tcpip.h> -# define CLOSESOCKET(S) closesocket((SOCKET)S) -# define ssize_t int -# define WIN32_INT (int) -# define OPTVAL_TYPE char -# define ERR_CONNECTION_PROGRESS WSAEWOULDBLOCK -# define UA_sleep_ms(X) Sleep(X) -#else /* _WIN32 */ -# if defined(UA_FREERTOS) -# define UA_FREERTOS_HOSTNAME "10.200.4.114" -static inline int gethostname_freertos(char* name, size_t len){ - if(strlen(UA_FREERTOS_HOSTNAME) > (len)) - return -1; - strcpy(name, UA_FREERTOS_HOSTNAME); - return 0; -} -#define gethostname gethostname_freertos -# include <lwip/tcpip.h> -# include <lwip/netdb.h> -# define CLOSESOCKET(S) lwip_close(S) -# define sockaddr_storage sockaddr -# ifdef BYTE_ORDER -# undef BYTE_ORDER -# endif -# define UA_sleep_ms(X) vTaskDelay(pdMS_TO_TICKS(X)) -# else /* Not freeRTOS */ -# define CLOSESOCKET(S) close(S) -# include <arpa/inet.h> -# include <netinet/in.h> -# include <netdb.h> -# include <sys/ioctl.h> -# if defined(_WRS_KERNEL) -# include <hostLib.h> -# include <selectLib.h> -# define UA_sleep_ms(X) \ - { \ - struct timespec timeToSleep; \ - timeToSleep.tv_sec = X / 1000; \ - timeToSleep.tv_nsec = 1000000 * (X % 1000); \ - nanosleep(&timeToSleep, NULL); \ - } -# else /* defined(_WRS_KERNEL) */ -# include <sys/select.h> -# define UA_sleep_ms(X) usleep(X * 1000) -# endif /* defined(_WRS_KERNEL) */ -# endif /* Not freeRTOS */ - -# define SOCKET int -# define WIN32_INT -# define OPTVAL_TYPE int -# define ERR_CONNECTION_PROGRESS EINPROGRESS - - -# include <fcntl.h> -# include <unistd.h> // read, write, close - -# ifdef __QNX__ -# include <sys/socket.h> -# endif -# if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -# include <sys/param.h> -# if defined(BSD) -# include<sys/socket.h> -# endif -# endif -# if !defined(__CYGWIN__) && !defined(UA_FREERTOS) -# include <netinet/tcp.h> -# endif -#endif /* _WIN32 */ - -/* unsigned int for windows and workaround to a glibc bug */ -/* Additionally if GNU_LIBRARY is not defined, it may be using - * musl libc (e.g. Docker Alpine) */ -#if defined(_WIN32) || defined(__OpenBSD__) || \ - (defined(__GNU_LIBRARY__) && (__GNU_LIBRARY__ <= 6) && \ - (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 16) || \ - !defined(__GNU_LIBRARY__)) -# define UA_fd_set(fd, fds) FD_SET((unsigned int)fd, fds) -# define UA_fd_isset(fd, fds) FD_ISSET((unsigned int)fd, fds) -#else -# define UA_fd_set(fd, fds) FD_SET(fd, fds) -# define UA_fd_isset(fd, fds) FD_ISSET(fd, fds) -#endif + YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz -#ifdef UNDER_CE -# define errno WSAGetLastError() -#endif +*/ -#ifdef _WIN32 -# define errno__ WSAGetLastError() -# define INTERRUPTED WSAEINTR -# define WOULDBLOCK WSAEWOULDBLOCK -# define AGAIN WSAEWOULDBLOCK -#else -# define errno__ errno -# define INTERRUPTED EINTR -# define WOULDBLOCK EWOULDBLOCK -# define AGAIN EAGAIN -#endif +#include <stdio.h> +#include <stdlib.h> + +static const char* b64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ; + +// maps A=>0,B=>1.. +static const unsigned char unb64[]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40 + 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50 + 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60 + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70 + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90 + 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100 + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110 + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120 + 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250 + 0, 0, 0, 0, 0, 0, +}; // This array has 256 elements + +// Converts binary data of length=len to base64 characters. +// Length of the resultant string is stored in flen +// (you must pass pointer flen). +char* UA_base64( const void* binaryData, int len, int *flen ) +{ + const unsigned char* bin = (const unsigned char*) binaryData ; + char* res ; + + int rc = 0 ; // result counter + int byteNo ; // I need this after the loop + + int modulusLen = len % 3 ; + int pad = ((modulusLen&1)<<1) + ((modulusLen&2)>>1) ; // 2 gives 1 and 1 gives 2, but 0 gives 0. + + *flen = 4*(len + pad)/3 ; + res = (char*) malloc( (size_t)(*flen + 1) ) ; // and one for the null + if( !res ) + { + puts( "ERROR: base64 could not allocate enough memory." ) ; + puts( "I must stop because I could not get enough" ) ; + return 0; + } -/****************************/ -/* Generic Socket Functions */ -/****************************/ + for( byteNo = 0 ; byteNo <= len-3 ; byteNo+=3 ) + { + unsigned char BYTE0=bin[byteNo]; + unsigned char BYTE1=bin[byteNo+1]; + unsigned char BYTE2=bin[byteNo+2]; + res[rc++] = b64[ BYTE0 >> 2 ] ; + res[rc++] = b64[ ((0x3&BYTE0)<<4) + (BYTE1 >> 4) ] ; + res[rc++] = b64[ ((0x0f&BYTE1)<<2) + (BYTE2>>6) ] ; + res[rc++] = b64[ 0x3f&BYTE2 ] ; + } -static UA_StatusCode -connection_getsendbuffer(UA_Connection *connection, - size_t length, UA_ByteString *buf) { - if(length > connection->remoteConf.recvBufferSize) - return UA_STATUSCODE_BADCOMMUNICATIONERROR; - return UA_ByteString_allocBuffer(buf, length); + if( pad==2 ) + { + res[rc++] = b64[ bin[byteNo] >> 2 ] ; + res[rc++] = b64[ (0x3&bin[byteNo])<<4 ] ; + res[rc++] = '='; + res[rc++] = '='; + } + else if( pad==1 ) + { + res[rc++] = b64[ bin[byteNo] >> 2 ] ; + res[rc++] = b64[ ((0x3&bin[byteNo])<<4) + (bin[byteNo+1] >> 4) ] ; + res[rc++] = b64[ (0x0f&bin[byteNo+1])<<2 ] ; + res[rc++] = '='; + } + + res[rc]=0; // NULL TERMINATOR! ;) + return res ; } -static void -connection_releasesendbuffer(UA_Connection *connection, - UA_ByteString *buf) { - UA_ByteString_deleteMembers(buf); +unsigned char* UA_unbase64( const char* ascii, int len, int *flen ) +{ + const unsigned char *safeAsciiPtr = (const unsigned char*)ascii ; + unsigned char *bin ; + int cb=0; + int charNo; + int pad = 0 ; + + if( len < 2 ) { // 2 accesses below would be OOB. + // catch empty string, return NULL as result. + puts( "ERROR: You passed an invalid base64 string (too short). You get NULL back." ) ; + *flen=0; + return 0 ; + } + if( safeAsciiPtr[ len-1 ]=='=' ) ++pad ; + if( safeAsciiPtr[ len-2 ]=='=' ) ++pad ; + + *flen = 3*len/4 - pad ; + bin = (unsigned char*)malloc( (size_t) (*flen) ) ; + if( !bin ) + { + puts( "ERROR: unbase64 could not allocate enough memory." ) ; + puts( "I must stop because I could not get enough" ) ; + return 0; + } + + for( charNo=0; charNo <= len - 4 - pad ; charNo+=4 ) + { + int A=unb64[safeAsciiPtr[charNo]]; + int B=unb64[safeAsciiPtr[charNo+1]]; + int C=unb64[safeAsciiPtr[charNo+2]]; + int D=unb64[safeAsciiPtr[charNo+3]]; + + bin[cb++] = (unsigned char)((A<<2) | (B>>4)) ; + bin[cb++] = (unsigned char)((B<<4) | (C>>2)) ; + bin[cb++] = (unsigned char)((C<<6) | (D)) ; + } + + if( pad==1 ) + { + int A=unb64[safeAsciiPtr[charNo]]; + int B=unb64[safeAsciiPtr[charNo+1]]; + int C=unb64[safeAsciiPtr[charNo+2]]; + + bin[cb++] = (unsigned char)((A<<2) | (B>>4)) ; + bin[cb++] = (unsigned char)((B<<4) | (C>>2)) ; + } + else if( pad==2 ) + { + int A=unb64[safeAsciiPtr[charNo]]; + int B=unb64[safeAsciiPtr[charNo+1]]; + + bin[cb++] = (unsigned char)((A<<2) | (B>>4)) ; + } + + return bin ; } -static void -connection_releaserecvbuffer(UA_Connection *connection, - UA_ByteString *buf) { - UA_ByteString_deleteMembers(buf); + +/*********************************** amalgamated original file "/home/jvoe/open62541/build/src_generated/open62541/namespace0_generated.c" ***********************************/ + +/* WARNING: This is a generated file. + * Any manual changes will be overwritten. */ + + + +/* HasAddIn - ns=0;i=17604 */ + +static UA_StatusCode function_namespace0_generated_0_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; +attr.inverseName = UA_LOCALIZEDTEXT("", "AddInOf"); +attr.displayName = UA_LOCALIZEDTEXT("", "HasAddIn"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, +UA_NODEID_NUMERIC(ns[0], 17604), +UA_NODEID_NUMERIC(ns[0], 32), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "HasAddIn"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); +return retVal; } -static UA_StatusCode -connection_write(UA_Connection *connection, UA_ByteString *buf) { - if(connection->state == UA_CONNECTION_CLOSED) { - UA_ByteString_deleteMembers(buf); - return UA_STATUSCODE_BADCONNECTIONCLOSED; - } +static UA_StatusCode function_namespace0_generated_0_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 17604) +); +} - /* Prevent OS signals when sending to a closed socket */ - int flags = 0; -#ifdef MSG_NOSIGNAL - flags |= MSG_NOSIGNAL; +/* HasInterface - ns=0;i=17603 */ + +static UA_StatusCode function_namespace0_generated_1_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; +attr.inverseName = UA_LOCALIZEDTEXT("", "InterfaceOf"); +attr.displayName = UA_LOCALIZEDTEXT("", "HasInterface"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, +UA_NODEID_NUMERIC(ns[0], 17603), +UA_NODEID_NUMERIC(ns[0], 32), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "HasInterface"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_1_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 17603) +); +} + +/* ExpandedNodeId - ns=0;i=18 */ + +static UA_StatusCode function_namespace0_generated_2_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ExpandedNodeId"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 18), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ExpandedNodeId"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_2_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 18) +); +} + +/* StatusCode - ns=0;i=19 */ + +static UA_StatusCode function_namespace0_generated_3_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "StatusCode"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 19), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "StatusCode"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_3_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 19) +); +} + +/* ByteString - ns=0;i=15 */ + +static UA_StatusCode function_namespace0_generated_4_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ByteString"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 15), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ByteString"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_4_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 15) +); +} + +/* Image - ns=0;i=30 */ + +static UA_StatusCode function_namespace0_generated_5_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.isAbstract = true; +attr.displayName = UA_LOCALIZEDTEXT("", "Image"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 30), +UA_NODEID_NUMERIC(ns[0], 15), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Image"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_5_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 30) +); +} + +/* DataValue - ns=0;i=23 */ + +static UA_StatusCode function_namespace0_generated_6_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "DataValue"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 23), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "DataValue"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_6_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 23) +); +} + +/* Structure - ns=0;i=22 */ + +static UA_StatusCode function_namespace0_generated_7_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.isAbstract = true; +attr.displayName = UA_LOCALIZEDTEXT("", "Structure"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 22), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Structure"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_7_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 22) +); +} + +/* BuildInfo - ns=0;i=338 */ + +static UA_StatusCode function_namespace0_generated_8_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "BuildInfo"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 338), +UA_NODEID_NUMERIC(ns[0], 22), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "BuildInfo"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_8_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 338) +); +} + +/* ServerStatusDataType - ns=0;i=862 */ + +static UA_StatusCode function_namespace0_generated_9_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerStatusDataType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 862), +UA_NODEID_NUMERIC(ns[0], 22), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerStatusDataType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_9_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 862) +); +} + +/* EnumValueType - ns=0;i=7594 */ + +static UA_StatusCode function_namespace0_generated_10_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "EnumValueType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 7594), +UA_NODEID_NUMERIC(ns[0], 22), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "EnumValueType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_10_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 7594) +); +} + +/* ServerDiagnosticsSummaryDataType - ns=0;i=859 */ + +static UA_StatusCode function_namespace0_generated_11_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnosticsSummaryDataType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 859), +UA_NODEID_NUMERIC(ns[0], 22), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerDiagnosticsSummaryDataType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_11_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 859) +); +} + +/* SignedSoftwareCertificate - ns=0;i=344 */ + +static UA_StatusCode function_namespace0_generated_12_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "SignedSoftwareCertificate"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 344), +UA_NODEID_NUMERIC(ns[0], 22), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "SignedSoftwareCertificate"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_12_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 344) +); +} + +/* Argument - ns=0;i=296 */ + +static UA_StatusCode function_namespace0_generated_13_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Argument"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 296), +UA_NODEID_NUMERIC(ns[0], 22), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Argument"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_13_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 296) +); +} + +/* LocalizedText - ns=0;i=21 */ + +static UA_StatusCode function_namespace0_generated_14_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "LocalizedText"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 21), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "LocalizedText"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_14_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 21) +); +} + +/* QualifiedName - ns=0;i=20 */ + +static UA_StatusCode function_namespace0_generated_15_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "QualifiedName"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 20), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "QualifiedName"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_15_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 20) +); +} + +/* Number - ns=0;i=26 */ + +static UA_StatusCode function_namespace0_generated_16_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.isAbstract = true; +attr.displayName = UA_LOCALIZEDTEXT("", "Number"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 26), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Number"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_16_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 26) +); +} + +/* Decimal - ns=0;i=50 */ + +static UA_StatusCode function_namespace0_generated_17_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Decimal"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 50), +UA_NODEID_NUMERIC(ns[0], 26), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Decimal"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_17_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 50) +); +} + +/* UInteger - ns=0;i=28 */ + +static UA_StatusCode function_namespace0_generated_18_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.isAbstract = true; +attr.displayName = UA_LOCALIZEDTEXT("", "UInteger"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 28), +UA_NODEID_NUMERIC(ns[0], 26), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "UInteger"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_18_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 28) +); +} + +/* UInt16 - ns=0;i=5 */ + +static UA_StatusCode function_namespace0_generated_19_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "UInt16"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 5), +UA_NODEID_NUMERIC(ns[0], 28), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "UInt16"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_19_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 5) +); +} + +/* UInt32 - ns=0;i=7 */ + +static UA_StatusCode function_namespace0_generated_20_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "UInt32"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 7), +UA_NODEID_NUMERIC(ns[0], 28), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "UInt32"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_20_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 7) +); +} + +/* UInt64 - ns=0;i=9 */ + +static UA_StatusCode function_namespace0_generated_21_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "UInt64"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 9), +UA_NODEID_NUMERIC(ns[0], 28), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "UInt64"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_21_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 9) +); +} + +/* Byte - ns=0;i=3 */ + +static UA_StatusCode function_namespace0_generated_22_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Byte"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 3), +UA_NODEID_NUMERIC(ns[0], 28), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Byte"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_22_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 3) +); +} + +/* Integer - ns=0;i=27 */ + +static UA_StatusCode function_namespace0_generated_23_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.isAbstract = true; +attr.displayName = UA_LOCALIZEDTEXT("", "Integer"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 27), +UA_NODEID_NUMERIC(ns[0], 26), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Integer"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_23_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 27) +); +} + +/* SByte - ns=0;i=2 */ + +static UA_StatusCode function_namespace0_generated_24_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "SByte"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 2), +UA_NODEID_NUMERIC(ns[0], 27), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "SByte"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_24_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2) +); +} + +/* Int64 - ns=0;i=8 */ + +static UA_StatusCode function_namespace0_generated_25_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Int64"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 8), +UA_NODEID_NUMERIC(ns[0], 27), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Int64"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_25_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 8) +); +} + +/* Int32 - ns=0;i=6 */ + +static UA_StatusCode function_namespace0_generated_26_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Int32"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 6), +UA_NODEID_NUMERIC(ns[0], 27), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Int32"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_26_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 6) +); +} + +/* Int16 - ns=0;i=4 */ + +static UA_StatusCode function_namespace0_generated_27_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Int16"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 4), +UA_NODEID_NUMERIC(ns[0], 27), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Int16"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_27_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 4) +); +} + +/* Float - ns=0;i=10 */ + +static UA_StatusCode function_namespace0_generated_28_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Float"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 10), +UA_NODEID_NUMERIC(ns[0], 26), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Float"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_28_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 10) +); +} + +/* Double - ns=0;i=11 */ + +static UA_StatusCode function_namespace0_generated_29_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Double"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 11), +UA_NODEID_NUMERIC(ns[0], 26), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Double"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_29_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11) +); +} + +/* Duration - ns=0;i=290 */ + +static UA_StatusCode function_namespace0_generated_30_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Duration"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 290), +UA_NODEID_NUMERIC(ns[0], 11), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Duration"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_30_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 290) +); +} + +/* DiagnosticInfo - ns=0;i=25 */ + +static UA_StatusCode function_namespace0_generated_31_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "DiagnosticInfo"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 25), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "DiagnosticInfo"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_31_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 25) +); +} + +/* Enumeration - ns=0;i=29 */ + +static UA_StatusCode function_namespace0_generated_32_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.isAbstract = true; +attr.displayName = UA_LOCALIZEDTEXT("", "Enumeration"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 29), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Enumeration"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_32_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 29) +); +} + +/* NamingRuleType - ns=0;i=120 */ + +static UA_StatusCode function_namespace0_generated_33_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "NamingRuleType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 120), +UA_NODEID_NUMERIC(ns[0], 29), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "NamingRuleType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_33_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 120) +); +} + +/* EnumValues - ns=0;i=12169 */ + +static UA_StatusCode function_namespace0_generated_34_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7594); +UA_EnumValueType variablenode_ns_0_i_12169_variant_DataContents[3]; + +UA_init(&variablenode_ns_0_i_12169_variant_DataContents[0], &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +variablenode_ns_0_i_12169_variant_DataContents[0].value = (UA_Int64) 1; +variablenode_ns_0_i_12169_variant_DataContents[0].displayName = UA_LOCALIZEDTEXT("", "Mandatory"); +variablenode_ns_0_i_12169_variant_DataContents[0].description = UA_LOCALIZEDTEXT("", "The BrowseName must appear in all instances of the type."); + +UA_init(&variablenode_ns_0_i_12169_variant_DataContents[1], &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +variablenode_ns_0_i_12169_variant_DataContents[1].value = (UA_Int64) 2; +variablenode_ns_0_i_12169_variant_DataContents[1].displayName = UA_LOCALIZEDTEXT("", "Optional"); +variablenode_ns_0_i_12169_variant_DataContents[1].description = UA_LOCALIZEDTEXT("", "The BrowseName may appear in an instance of the type."); + +UA_init(&variablenode_ns_0_i_12169_variant_DataContents[2], &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +variablenode_ns_0_i_12169_variant_DataContents[2].value = (UA_Int64) 3; +variablenode_ns_0_i_12169_variant_DataContents[2].displayName = UA_LOCALIZEDTEXT("", "Constraint"); +variablenode_ns_0_i_12169_variant_DataContents[2].description = UA_LOCALIZEDTEXT("", "The modelling rule defines a constraint and the BrowseName is not used in an instance of the type."); +UA_Variant_setArray(&attr.value, &variablenode_ns_0_i_12169_variant_DataContents, (UA_Int32) 3, &UA_TYPES[UA_TYPES_ENUMVALUETYPE]); +attr.displayName = UA_LOCALIZEDTEXT("", "EnumValues"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 12169), +UA_NODEID_NUMERIC(ns[0], 120), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "EnumValues"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); + + + +return retVal; +} + +static UA_StatusCode function_namespace0_generated_34_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 12169) +); +} + +/* RedundancySupport - ns=0;i=851 */ + +static UA_StatusCode function_namespace0_generated_35_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "RedundancySupport"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 851), +UA_NODEID_NUMERIC(ns[0], 29), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "RedundancySupport"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_35_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 851) +); +} + +/* EnumStrings - ns=0;i=7611 */ + +static UA_StatusCode function_namespace0_generated_36_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 21); +UA_LocalizedText variablenode_ns_0_i_7611_variant_DataContents[6]; +variablenode_ns_0_i_7611_variant_DataContents[0] = UA_LOCALIZEDTEXT("", "None"); +variablenode_ns_0_i_7611_variant_DataContents[1] = UA_LOCALIZEDTEXT("", "Cold"); +variablenode_ns_0_i_7611_variant_DataContents[2] = UA_LOCALIZEDTEXT("", "Warm"); +variablenode_ns_0_i_7611_variant_DataContents[3] = UA_LOCALIZEDTEXT("", "Hot"); +variablenode_ns_0_i_7611_variant_DataContents[4] = UA_LOCALIZEDTEXT("", "Transparent"); +variablenode_ns_0_i_7611_variant_DataContents[5] = UA_LOCALIZEDTEXT("", "HotAndMirrored"); +UA_Variant_setArray(&attr.value, &variablenode_ns_0_i_7611_variant_DataContents, (UA_Int32) 6, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); +attr.displayName = UA_LOCALIZEDTEXT("", "EnumStrings"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 7611), +UA_NODEID_NUMERIC(ns[0], 851), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "EnumStrings"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_36_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 7611) +); +} + +/* ServerState - ns=0;i=852 */ + +static UA_StatusCode function_namespace0_generated_37_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerState"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 852), +UA_NODEID_NUMERIC(ns[0], 29), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerState"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_37_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 852) +); +} + +/* HasHistoricalConfiguration - ns=0;i=56 */ + +static UA_StatusCode function_namespace0_generated_38_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; +attr.inverseName = UA_LOCALIZEDTEXT("", "HistoricalConfigurationOf"); +attr.displayName = UA_LOCALIZEDTEXT("", "HasHistoricalConfiguration"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, +UA_NODEID_NUMERIC(ns[0], 56), +UA_NODEID_NUMERIC(ns[0], 44), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "HasHistoricalConfiguration"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_38_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 56) +); +} + +/* HasEffect - ns=0;i=54 */ + +static UA_StatusCode function_namespace0_generated_39_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; +attr.inverseName = UA_LOCALIZEDTEXT("", "MayBeEffectedBy"); +attr.displayName = UA_LOCALIZEDTEXT("", "HasEffect"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, +UA_NODEID_NUMERIC(ns[0], 54), +UA_NODEID_NUMERIC(ns[0], 32), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "HasEffect"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_39_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 54) +); +} + +/* ToState - ns=0;i=52 */ + +static UA_StatusCode function_namespace0_generated_40_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; +attr.inverseName = UA_LOCALIZEDTEXT("", "FromTransition"); +attr.displayName = UA_LOCALIZEDTEXT("", "ToState"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, +UA_NODEID_NUMERIC(ns[0], 52), +UA_NODEID_NUMERIC(ns[0], 32), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ToState"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_40_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 52) +); +} + +/* HasCause - ns=0;i=53 */ + +static UA_StatusCode function_namespace0_generated_41_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; +attr.inverseName = UA_LOCALIZEDTEXT("", "MayBeCausedBy"); +attr.displayName = UA_LOCALIZEDTEXT("", "HasCause"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, +UA_NODEID_NUMERIC(ns[0], 53), +UA_NODEID_NUMERIC(ns[0], 32), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "HasCause"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_41_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 53) +); +} + +/* FromState - ns=0;i=51 */ + +static UA_StatusCode function_namespace0_generated_42_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ReferenceTypeAttributes attr = UA_ReferenceTypeAttributes_default; +attr.inverseName = UA_LOCALIZEDTEXT("", "ToTransition"); +attr.displayName = UA_LOCALIZEDTEXT("", "FromState"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_REFERENCETYPE, +UA_NODEID_NUMERIC(ns[0], 51), +UA_NODEID_NUMERIC(ns[0], 32), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "FromState"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_42_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 51) +); +} + +/* String - ns=0;i=12 */ + +static UA_StatusCode function_namespace0_generated_43_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "String"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 12), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "String"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_43_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 12) +); +} + +/* LocaleId - ns=0;i=295 */ + +static UA_StatusCode function_namespace0_generated_44_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "LocaleId"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 295), +UA_NODEID_NUMERIC(ns[0], 12), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "LocaleId"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_44_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 295) +); +} + +/* DateTime - ns=0;i=13 */ + +static UA_StatusCode function_namespace0_generated_45_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "DateTime"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 13), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "DateTime"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_45_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 13) +); +} + +/* UtcTime - ns=0;i=294 */ + +static UA_StatusCode function_namespace0_generated_46_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "UtcTime"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 294), +UA_NODEID_NUMERIC(ns[0], 13), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "UtcTime"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_46_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 294) +); +} + +/* NodeId - ns=0;i=17 */ + +static UA_StatusCode function_namespace0_generated_47_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "NodeId"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 17), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "NodeId"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_47_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 17) +); +} + +/* Guid - ns=0;i=14 */ + +static UA_StatusCode function_namespace0_generated_48_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Guid"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 14), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Guid"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_48_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 14) +); +} + +/* Boolean - ns=0;i=1 */ + +static UA_StatusCode function_namespace0_generated_49_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Boolean"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 1), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "Boolean"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_49_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 1) +); +} + +/* XmlElement - ns=0;i=16 */ + +static UA_StatusCode function_namespace0_generated_50_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_DataTypeAttributes attr = UA_DataTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "XmlElement"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_DATATYPE, +UA_NODEID_NUMERIC(ns[0], 16), +UA_NODEID_NUMERIC(ns[0], 24), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "XmlElement"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_50_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 16) +); +} + +/* ServerDiagnosticsType - ns=0;i=2020 */ + +static UA_StatusCode function_namespace0_generated_51_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnosticsType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 2020), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerDiagnosticsType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_51_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2020) +); +} + +/* Default Binary - ns=0;i=3062 */ + +static UA_StatusCode function_namespace0_generated_52_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Default Binary"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 3062), +UA_NODEID_NUMERIC(ns[0], 0), +UA_NODEID_NUMERIC(ns[0], 0), +UA_QUALIFIEDNAME(ns[0], "Default Binary"), +UA_NODEID_NUMERIC(ns[0], 58), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_52_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 3062) +); +} + +/* Default XML - ns=0;i=3063 */ + +static UA_StatusCode function_namespace0_generated_53_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Default XML"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 3063), +UA_NODEID_NUMERIC(ns[0], 0), +UA_NODEID_NUMERIC(ns[0], 0), +UA_QUALIFIEDNAME(ns[0], "Default XML"), +UA_NODEID_NUMERIC(ns[0], 58), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_53_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 3063) +); +} + +/* ServerStatusType - ns=0;i=2138 */ + +static UA_StatusCode function_namespace0_generated_54_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 862); +attr.displayName = UA_LOCALIZEDTEXT("", "ServerStatusType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, +UA_NODEID_NUMERIC(ns[0], 2138), +UA_NODEID_NUMERIC(ns[0], 63), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerStatusType"), +UA_NODEID_NUMERIC(ns[0], 0), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_54_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2138) +); +} + +/* VendorServerInfoType - ns=0;i=2033 */ + +static UA_StatusCode function_namespace0_generated_55_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "VendorServerInfoType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 2033), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "VendorServerInfoType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_55_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2033) +); +} + +/* DataTypeDescriptionType - ns=0;i=69 */ + +static UA_StatusCode function_namespace0_generated_56_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeDescriptionType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, +UA_NODEID_NUMERIC(ns[0], 69), +UA_NODEID_NUMERIC(ns[0], 63), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "DataTypeDescriptionType"), +UA_NODEID_NUMERIC(ns[0], 0), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_56_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 69) +); +} + +/* DictionaryFragment - ns=0;i=105 */ + +static UA_StatusCode function_namespace0_generated_57_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 15); +attr.displayName = UA_LOCALIZEDTEXT("", "DictionaryFragment"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 105), +UA_NODEID_NUMERIC(ns[0], 69), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "DictionaryFragment"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_57_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 105) +); +} + +/* DataTypeVersion - ns=0;i=104 */ + +static UA_StatusCode function_namespace0_generated_58_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeVersion"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 104), +UA_NODEID_NUMERIC(ns[0], 69), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "DataTypeVersion"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_58_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 104) +); +} + +/* DataTypeDictionaryType - ns=0;i=72 */ + +static UA_StatusCode function_namespace0_generated_59_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 15); +attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeDictionaryType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, +UA_NODEID_NUMERIC(ns[0], 72), +UA_NODEID_NUMERIC(ns[0], 63), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "DataTypeDictionaryType"), +UA_NODEID_NUMERIC(ns[0], 0), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_59_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 72) +); +} + +/* NamespaceUri - ns=0;i=107 */ + +static UA_StatusCode function_namespace0_generated_60_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "NamespaceUri"); +#ifdef UA_ENABLE_NODESET_COMPILER_DESCRIPTIONS +attr.description = UA_LOCALIZEDTEXT("", "A URI that uniquely identifies the dictionary."); #endif +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 107), +UA_NODEID_NUMERIC(ns[0], 72), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "NamespaceUri"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} - /* Send the full buffer. This may require several calls to send */ - size_t nWritten = 0; - do { - ssize_t n = 0; - do { - size_t bytes_to_send = buf->length - nWritten; - n = send((SOCKET)connection->sockfd, - (const char*)buf->data + nWritten, - WIN32_INT bytes_to_send, flags); - if(n < 0 && errno__ != INTERRUPTED && errno__ != AGAIN) { - connection->close(connection); - UA_ByteString_deleteMembers(buf); - return UA_STATUSCODE_BADCONNECTIONCLOSED; - } - } while(n < 0); - nWritten += (size_t)n; - } while(nWritten < buf->length); +static UA_StatusCode function_namespace0_generated_60_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 107) +); +} - /* Free the buffer */ - UA_ByteString_deleteMembers(buf); - return UA_STATUSCODE_GOOD; +/* DataTypeVersion - ns=0;i=106 */ + +static UA_StatusCode function_namespace0_generated_61_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeVersion"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 106), +UA_NODEID_NUMERIC(ns[0], 72), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "DataTypeVersion"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; } -static UA_StatusCode -connection_recv(UA_Connection *connection, UA_ByteString *response, - UA_UInt32 timeout) { - if(connection->state == UA_CONNECTION_CLOSED) - return UA_STATUSCODE_BADCONNECTIONCLOSED; +static UA_StatusCode function_namespace0_generated_61_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 106) +); +} - /* Listen on the socket for the given timeout until a message arrives */ - if(timeout > 0) { - fd_set fdset; - FD_ZERO(&fdset); - UA_fd_set(connection->sockfd, &fdset); - UA_UInt32 timeout_usec = timeout * 1000; - struct timeval tmptv = {(long int)(timeout_usec / 1000000), - (long int)(timeout_usec % 1000000)}; - int resultsize = select(connection->sockfd+1, &fdset, NULL, - NULL, &tmptv); +/* DataTypeSystemType - ns=0;i=75 */ - /* No result */ - if(resultsize == 0) - return UA_STATUSCODE_GOODNONCRITICALTIMEOUT; +static UA_StatusCode function_namespace0_generated_62_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeSystemType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 75), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "DataTypeSystemType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} - if(resultsize == -1) { - /* The call to select was interrupted manually. Act as if it timed - * out */ - if(errno == EINTR) - return UA_STATUSCODE_GOODNONCRITICALTIMEOUT; +static UA_StatusCode function_namespace0_generated_62_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 75) +); +} - /* The error cannot be recovered. Close the connection. */ - connection->close(connection); - return UA_STATUSCODE_BADCONNECTIONCLOSED; - } - } +/* OPC Binary - ns=0;i=93 */ - response->data = (UA_Byte*) - UA_malloc(connection->localConf.recvBufferSize); - if(!response->data) { - response->length = 0; - return UA_STATUSCODE_BADOUTOFMEMORY; /* not enough memory retry */ - } +static UA_StatusCode function_namespace0_generated_63_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "OPC Binary"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 93), +UA_NODEID_NUMERIC(ns[0], 90), +UA_NODEID_NUMERIC(ns[0], 35), +UA_QUALIFIEDNAME(ns[0], "OPC Binary"), +UA_NODEID_NUMERIC(ns[0], 75), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} - /* Get the received packet(s) */ - ssize_t ret = recv(connection->sockfd, (char*)response->data, - connection->localConf.recvBufferSize, 0); +static UA_StatusCode function_namespace0_generated_63_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 93) +); +} - /* The remote side closed the connection */ - if(ret == 0) { - UA_ByteString_deleteMembers(response); - connection->close(connection); - return UA_STATUSCODE_BADCONNECTIONCLOSED; - } +/* Opc.Ua - ns=0;i=7617 */ - /* Error case */ - if(ret < 0) { - UA_ByteString_deleteMembers(response); - if(errno__ == INTERRUPTED || (timeout > 0) ? - false : (errno__ == EAGAIN || errno__ == WOULDBLOCK)) - return UA_STATUSCODE_GOOD; /* statuscode_good but no data -> retry */ - connection->close(connection); - return UA_STATUSCODE_BADCONNECTIONCLOSED; - } +static UA_StatusCode function_namespace0_generated_64_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 15); +UA_ByteString *variablenode_ns_0_i_7617_variant_DataContents = UA_ByteString_new(); +if (!variablenode_ns_0_i_7617_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; +UA_ByteString_init(variablenode_ns_0_i_7617_variant_DataContents); +*variablenode_ns_0_i_7617_variant_DataContents = UA_BYTESTRING_NULL; +UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_7617_variant_DataContents, &UA_TYPES[UA_TYPES_BYTESTRING]); +attr.displayName = UA_LOCALIZEDTEXT("", "Opc.Ua"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 7617), +UA_NODEID_NUMERIC(ns[0], 93), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "Opc.Ua"), +UA_NODEID_NUMERIC(ns[0], 72), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +variablenode_ns_0_i_7617_variant_DataContents->data = NULL; +variablenode_ns_0_i_7617_variant_DataContents->length = 0; +UA_ByteString_delete(variablenode_ns_0_i_7617_variant_DataContents); +return retVal; +} - /* Set the length of the received buffer */ - response->length = (size_t)ret; - return UA_STATUSCODE_GOOD; +static UA_StatusCode function_namespace0_generated_64_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 7617) +); } -static UA_StatusCode -socket_set_nonblocking(SOCKET sockfd) { -#ifdef _WIN32 - u_long iMode = 1; - if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR) - return UA_STATUSCODE_BADINTERNALERROR; -#elif defined(_WRS_KERNEL) || defined(UA_FREERTOS) - int on = TRUE; - if(ioctl(sockfd, FIONBIO, &on) < 0) - return UA_STATUSCODE_BADINTERNALERROR; +/* Argument - ns=0;i=7650 */ + +static UA_StatusCode function_namespace0_generated_65_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +UA_String *variablenode_ns_0_i_7650_variant_DataContents = UA_String_new(); +if (!variablenode_ns_0_i_7650_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; +UA_String_init(variablenode_ns_0_i_7650_variant_DataContents); +*variablenode_ns_0_i_7650_variant_DataContents = UA_STRING_ALLOC("Argument"); +UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_7650_variant_DataContents, &UA_TYPES[UA_TYPES_STRING]); +attr.displayName = UA_LOCALIZEDTEXT("", "Argument"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 7650), +UA_NODEID_NUMERIC(ns[0], 7617), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "Argument"), +UA_NODEID_NUMERIC(ns[0], 69), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +UA_String_delete(variablenode_ns_0_i_7650_variant_DataContents); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_65_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 7650) +); +} + +/* EnumValueType - ns=0;i=7656 */ + +static UA_StatusCode function_namespace0_generated_66_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +UA_String *variablenode_ns_0_i_7656_variant_DataContents = UA_String_new(); +if (!variablenode_ns_0_i_7656_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; +UA_String_init(variablenode_ns_0_i_7656_variant_DataContents); +*variablenode_ns_0_i_7656_variant_DataContents = UA_STRING_ALLOC("EnumValueType"); +UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_7656_variant_DataContents, &UA_TYPES[UA_TYPES_STRING]); +attr.displayName = UA_LOCALIZEDTEXT("", "EnumValueType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 7656), +UA_NODEID_NUMERIC(ns[0], 7617), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "EnumValueType"), +UA_NODEID_NUMERIC(ns[0], 69), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +UA_String_delete(variablenode_ns_0_i_7656_variant_DataContents); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_66_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 7656) +); +} + +/* XML Schema - ns=0;i=92 */ + +static UA_StatusCode function_namespace0_generated_67_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "XML Schema"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 92), +UA_NODEID_NUMERIC(ns[0], 90), +UA_NODEID_NUMERIC(ns[0], 35), +UA_QUALIFIEDNAME(ns[0], "XML Schema"), +UA_NODEID_NUMERIC(ns[0], 75), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_67_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 92) +); +} + +/* DataTypeEncodingType - ns=0;i=76 */ + +static UA_StatusCode function_namespace0_generated_68_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "DataTypeEncodingType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 76), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "DataTypeEncodingType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_68_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 76) +); +} + +/* Default Binary - ns=0;i=8251 */ + +static UA_StatusCode function_namespace0_generated_69_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Default Binary"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 8251), +UA_NODEID_NUMERIC(ns[0], 0), +UA_NODEID_NUMERIC(ns[0], 0), +UA_QUALIFIEDNAME(ns[0], "Default Binary"), +UA_NODEID_NUMERIC(ns[0], 76), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 8251), UA_NODEID_NUMERIC(ns[0], 38), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7594), false); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 8251), UA_NODEID_NUMERIC(ns[0], 39), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7656), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_69_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 8251) +); +} + +/* Default Binary - ns=0;i=298 */ + +static UA_StatusCode function_namespace0_generated_70_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Default Binary"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 298), +UA_NODEID_NUMERIC(ns[0], 0), +UA_NODEID_NUMERIC(ns[0], 0), +UA_QUALIFIEDNAME(ns[0], "Default Binary"), +UA_NODEID_NUMERIC(ns[0], 76), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 298), UA_NODEID_NUMERIC(ns[0], 38), UA_EXPANDEDNODEID_NUMERIC(ns[0], 296), false); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 298), UA_NODEID_NUMERIC(ns[0], 39), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7650), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_70_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 298) +); +} + +/* ModellingRuleType - ns=0;i=77 */ + +static UA_StatusCode function_namespace0_generated_71_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ModellingRuleType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 77), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ModellingRuleType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_71_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 77) +); +} + +/* Mandatory - ns=0;i=78 */ + +static UA_StatusCode function_namespace0_generated_72_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Mandatory"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 78), +UA_NODEID_NUMERIC(ns[0], 0), +UA_NODEID_NUMERIC(ns[0], 0), +UA_QUALIFIEDNAME(ns[0], "Mandatory"), +UA_NODEID_NUMERIC(ns[0], 77), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 12169), false); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 78), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 7611), false); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_72_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 78) +); +} + +/* NamingRule - ns=0;i=112 */ + +static UA_StatusCode function_namespace0_generated_73_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 120); +UA_Int32 *variablenode_ns_0_i_112_variant_DataContents = UA_Int32_new(); +if (!variablenode_ns_0_i_112_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; +UA_Int32_init(variablenode_ns_0_i_112_variant_DataContents); +*variablenode_ns_0_i_112_variant_DataContents = (UA_Int32) 1; +UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_112_variant_DataContents, &UA_TYPES[UA_TYPES_INT32]); +attr.displayName = UA_LOCALIZEDTEXT("", "NamingRule"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 112), +UA_NODEID_NUMERIC(ns[0], 78), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "NamingRule"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +UA_Int32_delete(variablenode_ns_0_i_112_variant_DataContents); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_73_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 112) +); +} + +/* NamingRule - ns=0;i=111 */ + +static UA_StatusCode function_namespace0_generated_74_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 120); +UA_Int32 *variablenode_ns_0_i_111_variant_DataContents = UA_Int32_new(); +if (!variablenode_ns_0_i_111_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; +UA_Int32_init(variablenode_ns_0_i_111_variant_DataContents); +*variablenode_ns_0_i_111_variant_DataContents = (UA_Int32) 1; +UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_111_variant_DataContents, &UA_TYPES[UA_TYPES_INT32]); +attr.displayName = UA_LOCALIZEDTEXT("", "NamingRule"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 111), +UA_NODEID_NUMERIC(ns[0], 77), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "NamingRule"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +UA_Int32_delete(variablenode_ns_0_i_111_variant_DataContents); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 111), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_74_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 111) +); +} + +/* Optional - ns=0;i=80 */ + +static UA_StatusCode function_namespace0_generated_75_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "Optional"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 80), +UA_NODEID_NUMERIC(ns[0], 0), +UA_NODEID_NUMERIC(ns[0], 0), +UA_QUALIFIEDNAME(ns[0], "Optional"), +UA_NODEID_NUMERIC(ns[0], 77), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 104), false); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 105), false); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 107), false); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 80), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 106), false); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_75_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 80) +); +} + +/* NamingRule - ns=0;i=113 */ + +static UA_StatusCode function_namespace0_generated_76_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 120); +UA_Int32 *variablenode_ns_0_i_113_variant_DataContents = UA_Int32_new(); +if (!variablenode_ns_0_i_113_variant_DataContents) return UA_STATUSCODE_BADOUTOFMEMORY; +UA_Int32_init(variablenode_ns_0_i_113_variant_DataContents); +*variablenode_ns_0_i_113_variant_DataContents = (UA_Int32) 2; +UA_Variant_setScalar(&attr.value, variablenode_ns_0_i_113_variant_DataContents, &UA_TYPES[UA_TYPES_INT32]); +attr.displayName = UA_LOCALIZEDTEXT("", "NamingRule"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 113), +UA_NODEID_NUMERIC(ns[0], 80), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "NamingRule"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +UA_Int32_delete(variablenode_ns_0_i_113_variant_DataContents); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_76_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 113) +); +} + +/* ServerRedundancyType - ns=0;i=2034 */ + +static UA_StatusCode function_namespace0_generated_77_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerRedundancyType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 2034), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerRedundancyType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_77_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2034) +); +} + +/* RedundancySupport - ns=0;i=2035 */ + +static UA_StatusCode function_namespace0_generated_78_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 851); +attr.displayName = UA_LOCALIZEDTEXT("", "RedundancySupport"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2035), +UA_NODEID_NUMERIC(ns[0], 2034), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "RedundancySupport"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2035), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_78_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2035) +); +} + +/* BuildInfoType - ns=0;i=3051 */ + +static UA_StatusCode function_namespace0_generated_79_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 338); +attr.displayName = UA_LOCALIZEDTEXT("", "BuildInfoType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, +UA_NODEID_NUMERIC(ns[0], 3051), +UA_NODEID_NUMERIC(ns[0], 63), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "BuildInfoType"), +UA_NODEID_NUMERIC(ns[0], 0), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_79_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 3051) +); +} + +/* ServerDiagnosticsSummaryType - ns=0;i=2150 */ + +static UA_StatusCode function_namespace0_generated_80_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableTypeAttributes attr = UA_VariableTypeAttributes_default; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 859); +attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnosticsSummaryType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLETYPE, +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 63), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerDiagnosticsSummaryType"), +UA_NODEID_NUMERIC(ns[0], 0), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_80_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2150) +); +} + +/* PublishingIntervalCount - ns=0;i=2159 */ + +static UA_StatusCode function_namespace0_generated_81_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "PublishingIntervalCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2159), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "PublishingIntervalCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2159), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_81_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2159) +); +} + +/* SecurityRejectedSessionCount - ns=0;i=2154 */ + +static UA_StatusCode function_namespace0_generated_82_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SecurityRejectedSessionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2154), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SecurityRejectedSessionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2154), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_82_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2154) +); +} + +/* SecurityRejectedRequestsCount - ns=0;i=2162 */ + +static UA_StatusCode function_namespace0_generated_83_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SecurityRejectedRequestsCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2162), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SecurityRejectedRequestsCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2162), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_83_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2162) +); +} + +/* RejectedRequestsCount - ns=0;i=2163 */ + +static UA_StatusCode function_namespace0_generated_84_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "RejectedRequestsCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2163), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "RejectedRequestsCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2163), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_84_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2163) +); +} + +/* RejectedSessionCount - ns=0;i=2155 */ + +static UA_StatusCode function_namespace0_generated_85_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "RejectedSessionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2155), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "RejectedSessionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2155), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_85_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2155) +); +} + +/* CumulatedSubscriptionCount - ns=0;i=2161 */ + +static UA_StatusCode function_namespace0_generated_86_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "CumulatedSubscriptionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2161), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CumulatedSubscriptionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2161), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_86_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2161) +); +} + +/* CumulatedSessionCount - ns=0;i=2153 */ + +static UA_StatusCode function_namespace0_generated_87_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "CumulatedSessionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2153), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CumulatedSessionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2153), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_87_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2153) +); +} + +/* CurrentSessionCount - ns=0;i=2152 */ + +static UA_StatusCode function_namespace0_generated_88_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "CurrentSessionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2152), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CurrentSessionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2152), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_88_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2152) +); +} + +/* ServerViewCount - ns=0;i=2151 */ + +static UA_StatusCode function_namespace0_generated_89_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "ServerViewCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2151), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ServerViewCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2151), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_89_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2151) +); +} + +/* SessionTimeoutCount - ns=0;i=2156 */ + +static UA_StatusCode function_namespace0_generated_90_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SessionTimeoutCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2156), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SessionTimeoutCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2156), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_90_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2156) +); +} + +/* CurrentSubscriptionCount - ns=0;i=2160 */ + +static UA_StatusCode function_namespace0_generated_91_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "CurrentSubscriptionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2160), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CurrentSubscriptionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2160), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_91_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2160) +); +} + +/* SessionAbortCount - ns=0;i=2157 */ + +static UA_StatusCode function_namespace0_generated_92_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SessionAbortCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2157), +UA_NODEID_NUMERIC(ns[0], 2150), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SessionAbortCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2157), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_92_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2157) +); +} + +/* ServerType - ns=0;i=2004 */ + +static UA_StatusCode function_namespace0_generated_93_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 2004), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_93_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2004) +); +} + +/* Server - ns=0;i=2253 */ + +static UA_StatusCode function_namespace0_generated_94_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.eventNotifier = true; +attr.displayName = UA_LOCALIZEDTEXT("", "Server"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 85), +UA_NODEID_NUMERIC(ns[0], 35), +UA_QUALIFIEDNAME(ns[0], "Server"), +UA_NODEID_NUMERIC(ns[0], 2004), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_94_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2253) +); +} + +/* Auditing - ns=0;i=2994 */ + +static UA_StatusCode function_namespace0_generated_95_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 1); +attr.displayName = UA_LOCALIZEDTEXT("", "Auditing"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2994), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "Auditing"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_95_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2994) +); +} + +/* GetMonitoredItems - ns=0;i=11492 */ + +static UA_StatusCode function_namespace0_generated_96_begin(UA_Server *server, UA_UInt16* ns) { +#ifdef UA_ENABLE_METHODCALLS +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_MethodAttributes attr = UA_MethodAttributes_default; +attr.executable = true; +attr.userExecutable = true; +attr.displayName = UA_LOCALIZEDTEXT("", "GetMonitoredItems"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_METHOD, +UA_NODEID_NUMERIC(ns[0], 11492), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "GetMonitoredItems"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_METHODATTRIBUTES],NULL, NULL); +return retVal; #else - int opts = fcntl(sockfd, F_GETFL); - if(opts < 0 || fcntl(sockfd, F_SETFL, opts|O_NONBLOCK) < 0) - return UA_STATUSCODE_BADINTERNALERROR; -#endif - return UA_STATUSCODE_GOOD; +return UA_STATUSCODE_GOOD; +#endif /* UA_ENABLE_METHODCALLS */ } -static UA_StatusCode -socket_set_blocking(SOCKET sockfd) { -#ifdef _WIN32 - u_long iMode = 0; - if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR) - return UA_STATUSCODE_BADINTERNALERROR; -#elif defined(_WRS_KERNEL) || defined(UA_FREERTOS) - int on = FALSE; - if(ioctl(sockfd, FIONBIO, &on) < 0) - return UA_STATUSCODE_BADINTERNALERROR; +static UA_StatusCode function_namespace0_generated_96_finish(UA_Server *server, UA_UInt16* ns) { +#ifdef UA_ENABLE_METHODCALLS +return UA_Server_addMethodNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11492) +, NULL, 0, NULL, 0, NULL); #else - int opts = fcntl(sockfd, F_GETFL); - if(opts < 0 || fcntl(sockfd, F_SETFL, opts & (~O_NONBLOCK)) < 0) - return UA_STATUSCODE_BADINTERNALERROR; -#endif - return UA_STATUSCODE_GOOD; +return UA_STATUSCODE_GOOD; +#endif /* UA_ENABLE_METHODCALLS */ } -/***************************/ -/* Server NetworkLayer TCP */ -/***************************/ +/* OutputArguments - ns=0;i=11494 */ -#define MAXBACKLOG 100 -#define NOHELLOTIMEOUT 120000 /* timeout in ms before close the connection - * if server does not receive Hello Message */ +static UA_StatusCode function_namespace0_generated_97_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 296); +UA_Argument variablenode_ns_0_i_11494_variant_DataContents[2]; + +UA_init(&variablenode_ns_0_i_11494_variant_DataContents[0], &UA_TYPES[UA_TYPES_ARGUMENT]); +variablenode_ns_0_i_11494_variant_DataContents[0].name = UA_STRING("ServerHandles"); +variablenode_ns_0_i_11494_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(ns[0], 7); +variablenode_ns_0_i_11494_variant_DataContents[0].valueRank = (UA_Int32) 1; +UA_STACKARRAY(UA_UInt32, variablenode_ns_0_i_11494_variant_DataContents0_arrayDimensions, 1); +UA_init(variablenode_ns_0_i_11494_variant_DataContents0_arrayDimensions, &UA_TYPES[UA_TYPES_UINT32]); +variablenode_ns_0_i_11494_variant_DataContents0_arrayDimensions[0] = (UA_UInt32) 0; +variablenode_ns_0_i_11494_variant_DataContents[0].arrayDimensions = variablenode_ns_0_i_11494_variant_DataContents0_arrayDimensions; + +UA_init(&variablenode_ns_0_i_11494_variant_DataContents[1], &UA_TYPES[UA_TYPES_ARGUMENT]); +variablenode_ns_0_i_11494_variant_DataContents[1].name = UA_STRING("ClientHandles"); +variablenode_ns_0_i_11494_variant_DataContents[1].dataType = UA_NODEID_NUMERIC(ns[0], 7); +variablenode_ns_0_i_11494_variant_DataContents[1].valueRank = (UA_Int32) 1; +UA_STACKARRAY(UA_UInt32, variablenode_ns_0_i_11494_variant_DataContents1_arrayDimensions, 1); +UA_init(variablenode_ns_0_i_11494_variant_DataContents1_arrayDimensions, &UA_TYPES[UA_TYPES_UINT32]); +variablenode_ns_0_i_11494_variant_DataContents1_arrayDimensions[0] = (UA_UInt32) 0; +variablenode_ns_0_i_11494_variant_DataContents[1].arrayDimensions = variablenode_ns_0_i_11494_variant_DataContents1_arrayDimensions; +UA_Variant_setArray(&attr.value, &variablenode_ns_0_i_11494_variant_DataContents, (UA_Int32) 2, &UA_TYPES[UA_TYPES_ARGUMENT]); +attr.displayName = UA_LOCALIZEDTEXT("", "OutputArguments"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11494), +UA_NODEID_NUMERIC(ns[0], 11492), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "OutputArguments"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); -typedef struct ConnectionEntry { - UA_Connection connection; - LIST_ENTRY(ConnectionEntry) pointers; -} ConnectionEntry; -typedef struct { - UA_Logger logger; - UA_ConnectionConfig conf; - UA_UInt16 port; - UA_Int32 serverSockets[FD_SETSIZE]; - UA_UInt16 serverSocketsSize; - LIST_HEAD(, ConnectionEntry) connections; -} ServerNetworkLayerTCP; +return retVal; +} -static void -ServerNetworkLayerTCP_freeConnection(UA_Connection *connection) { - UA_Connection_deleteMembers(connection); - UA_free(connection); +static UA_StatusCode function_namespace0_generated_97_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11494) +); } -/* This performs only 'shutdown'. 'close' is called when the shutdown - * socket is returned from select. */ -static void -ServerNetworkLayerTCP_close(UA_Connection *connection) { - if (connection->state == UA_CONNECTION_CLOSED) - return; - shutdown((SOCKET)connection->sockfd, 2); - connection->state = UA_CONNECTION_CLOSED; +/* InputArguments - ns=0;i=11493 */ + +static UA_StatusCode function_namespace0_generated_98_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 296); +UA_Argument variablenode_ns_0_i_11493_variant_DataContents[1]; + +UA_init(&variablenode_ns_0_i_11493_variant_DataContents[0], &UA_TYPES[UA_TYPES_ARGUMENT]); +variablenode_ns_0_i_11493_variant_DataContents[0].name = UA_STRING("SubscriptionId"); +variablenode_ns_0_i_11493_variant_DataContents[0].dataType = UA_NODEID_NUMERIC(ns[0], 7); +variablenode_ns_0_i_11493_variant_DataContents[0].valueRank = (UA_Int32) -1; +UA_Variant_setArray(&attr.value, &variablenode_ns_0_i_11493_variant_DataContents, (UA_Int32) 1, &UA_TYPES[UA_TYPES_ARGUMENT]); +attr.displayName = UA_LOCALIZEDTEXT("", "InputArguments"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11493), +UA_NODEID_NUMERIC(ns[0], 11492), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "InputArguments"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); + +return retVal; +} + +static UA_StatusCode function_namespace0_generated_98_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11493) +); +} + +/* ServerStatus - ns=0;i=2256 */ + +static UA_StatusCode function_namespace0_generated_99_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 862); +attr.displayName = UA_LOCALIZEDTEXT("", "ServerStatus"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2256), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ServerStatus"), +UA_NODEID_NUMERIC(ns[0], 2138), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_99_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2256) +); +} + +/* BuildInfo - ns=0;i=2260 */ + +static UA_StatusCode function_namespace0_generated_100_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 338); +attr.displayName = UA_LOCALIZEDTEXT("", "BuildInfo"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2260), +UA_NODEID_NUMERIC(ns[0], 2256), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "BuildInfo"), +UA_NODEID_NUMERIC(ns[0], 3051), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_100_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2260) +); +} + +/* BuildDate - ns=0;i=2266 */ + +static UA_StatusCode function_namespace0_generated_101_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 294); +attr.displayName = UA_LOCALIZEDTEXT("", "BuildDate"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2266), +UA_NODEID_NUMERIC(ns[0], 2260), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "BuildDate"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_101_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2266) +); +} + +/* BuildNumber - ns=0;i=2265 */ + +static UA_StatusCode function_namespace0_generated_102_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "BuildNumber"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2265), +UA_NODEID_NUMERIC(ns[0], 2260), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "BuildNumber"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_102_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2265) +); +} + +/* SoftwareVersion - ns=0;i=2264 */ + +static UA_StatusCode function_namespace0_generated_103_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "SoftwareVersion"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2264), +UA_NODEID_NUMERIC(ns[0], 2260), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SoftwareVersion"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_103_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2264) +); +} + +/* ManufacturerName - ns=0;i=2263 */ + +static UA_StatusCode function_namespace0_generated_104_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "ManufacturerName"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2263), +UA_NODEID_NUMERIC(ns[0], 2260), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ManufacturerName"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_104_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2263) +); +} + +/* ProductUri - ns=0;i=2262 */ + +static UA_StatusCode function_namespace0_generated_105_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "ProductUri"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2262), +UA_NODEID_NUMERIC(ns[0], 2260), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ProductUri"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_105_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2262) +); +} + +/* ProductName - ns=0;i=2261 */ + +static UA_StatusCode function_namespace0_generated_106_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "ProductName"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2261), +UA_NODEID_NUMERIC(ns[0], 2260), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ProductName"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_106_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2261) +); +} + +/* ShutdownReason - ns=0;i=2993 */ + +static UA_StatusCode function_namespace0_generated_107_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 21); +attr.displayName = UA_LOCALIZEDTEXT("", "ShutdownReason"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2993), +UA_NODEID_NUMERIC(ns[0], 2256), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ShutdownReason"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_107_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2993) +); +} + +/* State - ns=0;i=2259 */ + +static UA_StatusCode function_namespace0_generated_108_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 852); +attr.displayName = UA_LOCALIZEDTEXT("", "State"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2259), +UA_NODEID_NUMERIC(ns[0], 2256), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "State"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_108_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2259) +); +} + +/* CurrentTime - ns=0;i=2258 */ + +static UA_StatusCode function_namespace0_generated_109_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 294); +attr.displayName = UA_LOCALIZEDTEXT("", "CurrentTime"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2258), +UA_NODEID_NUMERIC(ns[0], 2256), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CurrentTime"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_109_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2258) +); +} + +/* StartTime - ns=0;i=2257 */ + +static UA_StatusCode function_namespace0_generated_110_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 294); +attr.displayName = UA_LOCALIZEDTEXT("", "StartTime"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2257), +UA_NODEID_NUMERIC(ns[0], 2256), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "StartTime"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_110_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2257) +); +} + +/* SecondsTillShutdown - ns=0;i=2992 */ + +static UA_StatusCode function_namespace0_generated_111_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SecondsTillShutdown"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2992), +UA_NODEID_NUMERIC(ns[0], 2256), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SecondsTillShutdown"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_111_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2992) +); +} + +/* ServerDiagnostics - ns=0;i=2274 */ + +static UA_StatusCode function_namespace0_generated_112_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnostics"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 2274), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ServerDiagnostics"), +UA_NODEID_NUMERIC(ns[0], 2020), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_112_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2274) +); +} + +/* ServerDiagnosticsSummary - ns=0;i=2275 */ + +static UA_StatusCode function_namespace0_generated_113_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 859); +attr.displayName = UA_LOCALIZEDTEXT("", "ServerDiagnosticsSummary"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 2274), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ServerDiagnosticsSummary"), +UA_NODEID_NUMERIC(ns[0], 2150), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_113_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2275) +); +} + +/* SecurityRejectedRequestsCount - ns=0;i=2287 */ + +static UA_StatusCode function_namespace0_generated_114_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SecurityRejectedRequestsCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2287), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SecurityRejectedRequestsCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_114_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2287) +); +} + +/* CumulatedSubscriptionCount - ns=0;i=2286 */ + +static UA_StatusCode function_namespace0_generated_115_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "CumulatedSubscriptionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2286), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CumulatedSubscriptionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_115_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2286) +); +} + +/* CurrentSubscriptionCount - ns=0;i=2285 */ + +static UA_StatusCode function_namespace0_generated_116_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "CurrentSubscriptionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2285), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CurrentSubscriptionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_116_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2285) +); +} + +/* PublishingIntervalCount - ns=0;i=2284 */ + +static UA_StatusCode function_namespace0_generated_117_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "PublishingIntervalCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2284), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "PublishingIntervalCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_117_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2284) +); +} + +/* SessionAbortCount - ns=0;i=2282 */ + +static UA_StatusCode function_namespace0_generated_118_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SessionAbortCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2282), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SessionAbortCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_118_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2282) +); +} + +/* SessionTimeoutCount - ns=0;i=2281 */ + +static UA_StatusCode function_namespace0_generated_119_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SessionTimeoutCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2281), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SessionTimeoutCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_119_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2281) +); +} + +/* RejectedSessionCount - ns=0;i=3705 */ + +static UA_StatusCode function_namespace0_generated_120_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "RejectedSessionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 3705), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "RejectedSessionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_120_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 3705) +); +} + +/* RejectedRequestsCount - ns=0;i=2288 */ + +static UA_StatusCode function_namespace0_generated_121_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "RejectedRequestsCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2288), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "RejectedRequestsCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_121_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2288) +); +} + +/* ServerViewCount - ns=0;i=2276 */ + +static UA_StatusCode function_namespace0_generated_122_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "ServerViewCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2276), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ServerViewCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_122_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2276) +); +} + +/* CurrentSessionCount - ns=0;i=2277 */ + +static UA_StatusCode function_namespace0_generated_123_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "CurrentSessionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2277), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CurrentSessionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_123_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2277) +); +} + +/* CumulatedSessionCount - ns=0;i=2278 */ + +static UA_StatusCode function_namespace0_generated_124_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "CumulatedSessionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2278), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "CumulatedSessionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_124_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2278) +); +} + +/* SecurityRejectedSessionCount - ns=0;i=2279 */ + +static UA_StatusCode function_namespace0_generated_125_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "SecurityRejectedSessionCount"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2279), +UA_NODEID_NUMERIC(ns[0], 2275), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "SecurityRejectedSessionCount"), +UA_NODEID_NUMERIC(ns[0], 63), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_125_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2279) +); +} + +/* EnabledFlag - ns=0;i=2294 */ + +static UA_StatusCode function_namespace0_generated_126_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 3; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 1); +attr.displayName = UA_LOCALIZEDTEXT("", "EnabledFlag"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2294), +UA_NODEID_NUMERIC(ns[0], 2274), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "EnabledFlag"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_126_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2294) +); +} + +/* VendorServerInfo - ns=0;i=2295 */ + +static UA_StatusCode function_namespace0_generated_127_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "VendorServerInfo"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 2295), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "VendorServerInfo"), +UA_NODEID_NUMERIC(ns[0], 2033), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_127_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2295) +); +} + +/* NamespaceArray - ns=0;i=2255 */ + +static UA_StatusCode function_namespace0_generated_128_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "NamespaceArray"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2255), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "NamespaceArray"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_128_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2255) +); +} + +/* ServerArray - ns=0;i=2254 */ + +static UA_StatusCode function_namespace0_generated_129_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "ServerArray"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2254), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "ServerArray"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_129_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2254) +); +} + +/* ServiceLevel - ns=0;i=2267 */ + +static UA_StatusCode function_namespace0_generated_130_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 1000.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 3); +attr.displayName = UA_LOCALIZEDTEXT("", "ServiceLevel"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2267), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "ServiceLevel"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_130_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2267) +); +} + +/* ServerRedundancy - ns=0;i=2296 */ + +static UA_StatusCode function_namespace0_generated_131_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerRedundancy"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 2296), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ServerRedundancy"), +UA_NODEID_NUMERIC(ns[0], 2034), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_131_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2296) +); +} + +/* RedundancySupport - ns=0;i=3709 */ + +static UA_StatusCode function_namespace0_generated_132_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 851); +attr.displayName = UA_LOCALIZEDTEXT("", "RedundancySupport"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 3709), +UA_NODEID_NUMERIC(ns[0], 2296), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "RedundancySupport"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_132_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 3709) +); +} + +/* VendorServerInfo - ns=0;i=2011 */ + +static UA_StatusCode function_namespace0_generated_133_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "VendorServerInfo"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 2011), +UA_NODEID_NUMERIC(ns[0], 2004), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "VendorServerInfo"), +UA_NODEID_NUMERIC(ns[0], 2033), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 2011), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 78), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_133_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2011) +); +} + +/* InterfaceTypes - ns=0;i=17708 */ + +static UA_StatusCode function_namespace0_generated_134_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "InterfaceTypes"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 17708), +UA_NODEID_NUMERIC(ns[0], 86), +UA_NODEID_NUMERIC(ns[0], 35), +UA_QUALIFIEDNAME(ns[0], "InterfaceTypes"), +UA_NODEID_NUMERIC(ns[0], 61), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_134_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 17708) +); +} + +/* BaseInterfaceType - ns=0;i=17602 */ + +static UA_StatusCode function_namespace0_generated_135_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.isAbstract = true; +attr.displayName = UA_LOCALIZEDTEXT("", "BaseInterfaceType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 17602), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "BaseInterfaceType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 17602), UA_NODEID_NUMERIC(ns[0], 35), UA_EXPANDEDNODEID_NUMERIC(ns[0], 17708), false); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_135_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 17602) +); +} + +/* OperationLimitsType - ns=0;i=11564 */ + +static UA_StatusCode function_namespace0_generated_136_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "OperationLimitsType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 61), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "OperationLimitsType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_136_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11564) +); +} + +/* MaxNodesPerWrite - ns=0;i=11567 */ + +static UA_StatusCode function_namespace0_generated_137_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerWrite"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11567), +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerWrite"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11567), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_137_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11567) +); +} + +/* MaxNodesPerRead - ns=0;i=11565 */ + +static UA_StatusCode function_namespace0_generated_138_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerRead"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11565), +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerRead"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11565), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_138_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11565) +); +} + +/* MaxNodesPerMethodCall - ns=0;i=11569 */ + +static UA_StatusCode function_namespace0_generated_139_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerMethodCall"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11569), +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerMethodCall"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11569), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_139_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11569) +); +} + +/* MaxNodesPerRegisterNodes - ns=0;i=11571 */ + +static UA_StatusCode function_namespace0_generated_140_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerRegisterNodes"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11571), +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerRegisterNodes"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11571), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_140_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11571) +); +} + +/* MaxNodesPerBrowse - ns=0;i=11570 */ + +static UA_StatusCode function_namespace0_generated_141_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerBrowse"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11570), +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerBrowse"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11570), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_141_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11570) +); +} + +/* MaxNodesPerNodeManagement - ns=0;i=11573 */ + +static UA_StatusCode function_namespace0_generated_142_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerNodeManagement"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11573), +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerNodeManagement"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11573), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_142_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11573) +); +} + +/* MaxNodesPerTranslateBrowsePathsToNodeIds - ns=0;i=11572 */ + +static UA_StatusCode function_namespace0_generated_143_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerTranslateBrowsePathsToNodeIds"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11572), +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerTranslateBrowsePathsToNodeIds"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11572), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_143_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11572) +); +} + +/* MaxMonitoredItemsPerCall - ns=0;i=11574 */ + +static UA_StatusCode function_namespace0_generated_144_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxMonitoredItemsPerCall"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11574), +UA_NODEID_NUMERIC(ns[0], 11564), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxMonitoredItemsPerCall"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11574), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_144_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11574) +); +} + +/* ServerCapabilitiesType - ns=0;i=2013 */ + +static UA_StatusCode function_namespace0_generated_145_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectTypeAttributes attr = UA_ObjectTypeAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerCapabilitiesType"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECTTYPE, +UA_NODEID_NUMERIC(ns[0], 2013), +UA_NODEID_NUMERIC(ns[0], 58), +UA_NODEID_NUMERIC(ns[0], 45), +UA_QUALIFIEDNAME(ns[0], "ServerCapabilitiesType"), + UA_NODEID_NULL, +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_145_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2013) +); +} + +/* OperationLimits - ns=0;i=11551 */ + +static UA_StatusCode function_namespace0_generated_146_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "OperationLimits"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 11551), +UA_NODEID_NUMERIC(ns[0], 2013), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "OperationLimits"), +UA_NODEID_NUMERIC(ns[0], 11564), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +retVal |= UA_Server_addReference(server, UA_NODEID_NUMERIC(ns[0], 11551), UA_NODEID_NUMERIC(ns[0], 37), UA_EXPANDEDNODEID_NUMERIC(ns[0], 80), true); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_146_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11551) +); +} + +/* ServerCapabilities - ns=0;i=2268 */ + +static UA_StatusCode function_namespace0_generated_147_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ServerCapabilities"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 2253), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ServerCapabilities"), +UA_NODEID_NUMERIC(ns[0], 2013), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_147_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2268) +); +} + +/* ServerProfileArray - ns=0;i=2269 */ + +static UA_StatusCode function_namespace0_generated_148_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 12); +attr.displayName = UA_LOCALIZEDTEXT("", "ServerProfileArray"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2269), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "ServerProfileArray"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_148_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2269) +); +} + +/* AggregateFunctions - ns=0;i=2997 */ + +static UA_StatusCode function_namespace0_generated_149_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "AggregateFunctions"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 2997), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "AggregateFunctions"), +UA_NODEID_NUMERIC(ns[0], 61), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_149_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2997) +); +} + +/* ModellingRules - ns=0;i=2996 */ + +static UA_StatusCode function_namespace0_generated_150_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "ModellingRules"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 2996), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "ModellingRules"), +UA_NODEID_NUMERIC(ns[0], 61), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_150_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2996) +); +} + +/* OperationLimits - ns=0;i=11704 */ + +static UA_StatusCode function_namespace0_generated_151_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_ObjectAttributes attr = UA_ObjectAttributes_default; +attr.displayName = UA_LOCALIZEDTEXT("", "OperationLimits"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_OBJECT, +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 47), +UA_QUALIFIEDNAME(ns[0], "OperationLimits"), +UA_NODEID_NUMERIC(ns[0], 11564), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_151_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11704) +); +} + +/* MaxNodesPerWrite - ns=0;i=11707 */ + +static UA_StatusCode function_namespace0_generated_152_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerWrite"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11707), +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerWrite"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_152_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11707) +); +} + +/* MaxNodesPerRead - ns=0;i=11705 */ + +static UA_StatusCode function_namespace0_generated_153_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerRead"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11705), +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerRead"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_153_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11705) +); +} + +/* MaxMonitoredItemsPerCall - ns=0;i=11714 */ + +static UA_StatusCode function_namespace0_generated_154_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxMonitoredItemsPerCall"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11714), +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxMonitoredItemsPerCall"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_154_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11714) +); +} + +/* MaxNodesPerRegisterNodes - ns=0;i=11711 */ + +static UA_StatusCode function_namespace0_generated_155_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerRegisterNodes"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11711), +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerRegisterNodes"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_155_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11711) +); +} + +/* MaxNodesPerBrowse - ns=0;i=11710 */ + +static UA_StatusCode function_namespace0_generated_156_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerBrowse"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11710), +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerBrowse"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_156_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11710) +); +} + +/* MaxNodesPerNodeManagement - ns=0;i=11713 */ + +static UA_StatusCode function_namespace0_generated_157_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerNodeManagement"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11713), +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerNodeManagement"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_157_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11713) +); +} + +/* MaxNodesPerTranslateBrowsePathsToNodeIds - ns=0;i=11712 */ + +static UA_StatusCode function_namespace0_generated_158_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerTranslateBrowsePathsToNodeIds"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11712), +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerTranslateBrowsePathsToNodeIds"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_158_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11712) +); +} + +/* MaxNodesPerMethodCall - ns=0;i=11709 */ + +static UA_StatusCode function_namespace0_generated_159_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 7); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxNodesPerMethodCall"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 11709), +UA_NODEID_NUMERIC(ns[0], 11704), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxNodesPerMethodCall"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_159_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 11709) +); +} + +/* SoftwareCertificates - ns=0;i=3704 */ + +static UA_StatusCode function_namespace0_generated_160_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 344); +attr.displayName = UA_LOCALIZEDTEXT("", "SoftwareCertificates"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 3704), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "SoftwareCertificates"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_160_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 3704) +); +} + +/* MinSupportedSampleRate - ns=0;i=2272 */ + +static UA_StatusCode function_namespace0_generated_161_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 290); +attr.displayName = UA_LOCALIZEDTEXT("", "MinSupportedSampleRate"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2272), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MinSupportedSampleRate"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_161_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2272) +); +} + +/* LocaleIdArray - ns=0;i=2271 */ + +static UA_StatusCode function_namespace0_generated_162_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +attr.valueRank = 1; +attr.arrayDimensionsSize = 1; +UA_UInt32 arrayDimensions[1]; +arrayDimensions[0] = 0; +attr.arrayDimensions = &arrayDimensions[0]; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 295); +attr.displayName = UA_LOCALIZEDTEXT("", "LocaleIdArray"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2271), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "LocaleIdArray"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_162_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2271) +); +} + +/* MaxQueryContinuationPoints - ns=0;i=2736 */ + +static UA_StatusCode function_namespace0_generated_163_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 5); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxQueryContinuationPoints"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2736), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxQueryContinuationPoints"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_163_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2736) +); +} + +/* MaxHistoryContinuationPoints - ns=0;i=2737 */ + +static UA_StatusCode function_namespace0_generated_164_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 5); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxHistoryContinuationPoints"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2737), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxHistoryContinuationPoints"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_164_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2737) +); +} + +/* MaxBrowseContinuationPoints - ns=0;i=2735 */ + +static UA_StatusCode function_namespace0_generated_165_begin(UA_Server *server, UA_UInt16* ns) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +UA_VariableAttributes attr = UA_VariableAttributes_default; +attr.minimumSamplingInterval = 0.000000; +attr.userAccessLevel = 1; +attr.accessLevel = 1; +/* Value rank inherited */ +attr.valueRank = -1; +attr.dataType = UA_NODEID_NUMERIC(ns[0], 5); +attr.displayName = UA_LOCALIZEDTEXT("", "MaxBrowseContinuationPoints"); +retVal |= UA_Server_addNode_begin(server, UA_NODECLASS_VARIABLE, +UA_NODEID_NUMERIC(ns[0], 2735), +UA_NODEID_NUMERIC(ns[0], 2268), +UA_NODEID_NUMERIC(ns[0], 46), +UA_QUALIFIEDNAME(ns[0], "MaxBrowseContinuationPoints"), +UA_NODEID_NUMERIC(ns[0], 68), +(const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],NULL, NULL); +return retVal; +} + +static UA_StatusCode function_namespace0_generated_165_finish(UA_Server *server, UA_UInt16* ns) { +return UA_Server_addNode_finish(server, +UA_NODEID_NUMERIC(ns[0], 2735) +); +} + +UA_StatusCode namespace0_generated(UA_Server *server) { +UA_StatusCode retVal = UA_STATUSCODE_GOOD; +/* Use namespace ids generated by the server */ +UA_UInt16 ns[1]; +ns[0] = UA_Server_addNamespace(server, "http://opcfoundation.org/UA/"); +bool dummy = ( +!(retVal = function_namespace0_generated_0_begin(server, ns)) && +!(retVal = function_namespace0_generated_1_begin(server, ns)) && +!(retVal = function_namespace0_generated_2_begin(server, ns)) && +!(retVal = function_namespace0_generated_3_begin(server, ns)) && +!(retVal = function_namespace0_generated_4_begin(server, ns)) && +!(retVal = function_namespace0_generated_5_begin(server, ns)) && +!(retVal = function_namespace0_generated_6_begin(server, ns)) && +!(retVal = function_namespace0_generated_7_begin(server, ns)) && +!(retVal = function_namespace0_generated_8_begin(server, ns)) && +!(retVal = function_namespace0_generated_9_begin(server, ns)) && +!(retVal = function_namespace0_generated_10_begin(server, ns)) && +!(retVal = function_namespace0_generated_11_begin(server, ns)) && +!(retVal = function_namespace0_generated_12_begin(server, ns)) && +!(retVal = function_namespace0_generated_13_begin(server, ns)) && +!(retVal = function_namespace0_generated_14_begin(server, ns)) && +!(retVal = function_namespace0_generated_15_begin(server, ns)) && +!(retVal = function_namespace0_generated_16_begin(server, ns)) && +!(retVal = function_namespace0_generated_17_begin(server, ns)) && +!(retVal = function_namespace0_generated_18_begin(server, ns)) && +!(retVal = function_namespace0_generated_19_begin(server, ns)) && +!(retVal = function_namespace0_generated_20_begin(server, ns)) && +!(retVal = function_namespace0_generated_21_begin(server, ns)) && +!(retVal = function_namespace0_generated_22_begin(server, ns)) && +!(retVal = function_namespace0_generated_23_begin(server, ns)) && +!(retVal = function_namespace0_generated_24_begin(server, ns)) && +!(retVal = function_namespace0_generated_25_begin(server, ns)) && +!(retVal = function_namespace0_generated_26_begin(server, ns)) && +!(retVal = function_namespace0_generated_27_begin(server, ns)) && +!(retVal = function_namespace0_generated_28_begin(server, ns)) && +!(retVal = function_namespace0_generated_29_begin(server, ns)) && +!(retVal = function_namespace0_generated_30_begin(server, ns)) && +!(retVal = function_namespace0_generated_31_begin(server, ns)) && +!(retVal = function_namespace0_generated_32_begin(server, ns)) && +!(retVal = function_namespace0_generated_33_begin(server, ns)) && +!(retVal = function_namespace0_generated_34_begin(server, ns)) && +!(retVal = function_namespace0_generated_35_begin(server, ns)) && +!(retVal = function_namespace0_generated_36_begin(server, ns)) && +!(retVal = function_namespace0_generated_37_begin(server, ns)) && +!(retVal = function_namespace0_generated_38_begin(server, ns)) && +!(retVal = function_namespace0_generated_39_begin(server, ns)) && +!(retVal = function_namespace0_generated_40_begin(server, ns)) && +!(retVal = function_namespace0_generated_41_begin(server, ns)) && +!(retVal = function_namespace0_generated_42_begin(server, ns)) && +!(retVal = function_namespace0_generated_43_begin(server, ns)) && +!(retVal = function_namespace0_generated_44_begin(server, ns)) && +!(retVal = function_namespace0_generated_45_begin(server, ns)) && +!(retVal = function_namespace0_generated_46_begin(server, ns)) && +!(retVal = function_namespace0_generated_47_begin(server, ns)) && +!(retVal = function_namespace0_generated_48_begin(server, ns)) && +!(retVal = function_namespace0_generated_49_begin(server, ns)) && +!(retVal = function_namespace0_generated_50_begin(server, ns)) && +!(retVal = function_namespace0_generated_51_begin(server, ns)) && +!(retVal = function_namespace0_generated_52_begin(server, ns)) && +!(retVal = function_namespace0_generated_53_begin(server, ns)) && +!(retVal = function_namespace0_generated_54_begin(server, ns)) && +!(retVal = function_namespace0_generated_55_begin(server, ns)) && +!(retVal = function_namespace0_generated_56_begin(server, ns)) && +!(retVal = function_namespace0_generated_57_begin(server, ns)) && +!(retVal = function_namespace0_generated_58_begin(server, ns)) && +!(retVal = function_namespace0_generated_59_begin(server, ns)) && +!(retVal = function_namespace0_generated_60_begin(server, ns)) && +!(retVal = function_namespace0_generated_61_begin(server, ns)) && +!(retVal = function_namespace0_generated_62_begin(server, ns)) && +!(retVal = function_namespace0_generated_63_begin(server, ns)) && +!(retVal = function_namespace0_generated_64_begin(server, ns)) && +!(retVal = function_namespace0_generated_65_begin(server, ns)) && +!(retVal = function_namespace0_generated_66_begin(server, ns)) && +!(retVal = function_namespace0_generated_67_begin(server, ns)) && +!(retVal = function_namespace0_generated_68_begin(server, ns)) && +!(retVal = function_namespace0_generated_69_begin(server, ns)) && +!(retVal = function_namespace0_generated_70_begin(server, ns)) && +!(retVal = function_namespace0_generated_71_begin(server, ns)) && +!(retVal = function_namespace0_generated_72_begin(server, ns)) && +!(retVal = function_namespace0_generated_73_begin(server, ns)) && +!(retVal = function_namespace0_generated_74_begin(server, ns)) && +!(retVal = function_namespace0_generated_75_begin(server, ns)) && +!(retVal = function_namespace0_generated_76_begin(server, ns)) && +!(retVal = function_namespace0_generated_77_begin(server, ns)) && +!(retVal = function_namespace0_generated_78_begin(server, ns)) && +!(retVal = function_namespace0_generated_79_begin(server, ns)) && +!(retVal = function_namespace0_generated_80_begin(server, ns)) && +!(retVal = function_namespace0_generated_81_begin(server, ns)) && +!(retVal = function_namespace0_generated_82_begin(server, ns)) && +!(retVal = function_namespace0_generated_83_begin(server, ns)) && +!(retVal = function_namespace0_generated_84_begin(server, ns)) && +!(retVal = function_namespace0_generated_85_begin(server, ns)) && +!(retVal = function_namespace0_generated_86_begin(server, ns)) && +!(retVal = function_namespace0_generated_87_begin(server, ns)) && +!(retVal = function_namespace0_generated_88_begin(server, ns)) && +!(retVal = function_namespace0_generated_89_begin(server, ns)) && +!(retVal = function_namespace0_generated_90_begin(server, ns)) && +!(retVal = function_namespace0_generated_91_begin(server, ns)) && +!(retVal = function_namespace0_generated_92_begin(server, ns)) && +!(retVal = function_namespace0_generated_93_begin(server, ns)) && +!(retVal = function_namespace0_generated_94_begin(server, ns)) && +!(retVal = function_namespace0_generated_95_begin(server, ns)) && +!(retVal = function_namespace0_generated_96_begin(server, ns)) && +!(retVal = function_namespace0_generated_97_begin(server, ns)) && +!(retVal = function_namespace0_generated_98_begin(server, ns)) && +!(retVal = function_namespace0_generated_99_begin(server, ns)) && +!(retVal = function_namespace0_generated_100_begin(server, ns)) && +!(retVal = function_namespace0_generated_101_begin(server, ns)) && +!(retVal = function_namespace0_generated_102_begin(server, ns)) && +!(retVal = function_namespace0_generated_103_begin(server, ns)) && +!(retVal = function_namespace0_generated_104_begin(server, ns)) && +!(retVal = function_namespace0_generated_105_begin(server, ns)) && +!(retVal = function_namespace0_generated_106_begin(server, ns)) && +!(retVal = function_namespace0_generated_107_begin(server, ns)) && +!(retVal = function_namespace0_generated_108_begin(server, ns)) && +!(retVal = function_namespace0_generated_109_begin(server, ns)) && +!(retVal = function_namespace0_generated_110_begin(server, ns)) && +!(retVal = function_namespace0_generated_111_begin(server, ns)) && +!(retVal = function_namespace0_generated_112_begin(server, ns)) && +!(retVal = function_namespace0_generated_113_begin(server, ns)) && +!(retVal = function_namespace0_generated_114_begin(server, ns)) && +!(retVal = function_namespace0_generated_115_begin(server, ns)) && +!(retVal = function_namespace0_generated_116_begin(server, ns)) && +!(retVal = function_namespace0_generated_117_begin(server, ns)) && +!(retVal = function_namespace0_generated_118_begin(server, ns)) && +!(retVal = function_namespace0_generated_119_begin(server, ns)) && +!(retVal = function_namespace0_generated_120_begin(server, ns)) && +!(retVal = function_namespace0_generated_121_begin(server, ns)) && +!(retVal = function_namespace0_generated_122_begin(server, ns)) && +!(retVal = function_namespace0_generated_123_begin(server, ns)) && +!(retVal = function_namespace0_generated_124_begin(server, ns)) && +!(retVal = function_namespace0_generated_125_begin(server, ns)) && +!(retVal = function_namespace0_generated_126_begin(server, ns)) && +!(retVal = function_namespace0_generated_127_begin(server, ns)) && +!(retVal = function_namespace0_generated_128_begin(server, ns)) && +!(retVal = function_namespace0_generated_129_begin(server, ns)) && +!(retVal = function_namespace0_generated_130_begin(server, ns)) && +!(retVal = function_namespace0_generated_131_begin(server, ns)) && +!(retVal = function_namespace0_generated_132_begin(server, ns)) && +!(retVal = function_namespace0_generated_133_begin(server, ns)) && +!(retVal = function_namespace0_generated_134_begin(server, ns)) && +!(retVal = function_namespace0_generated_135_begin(server, ns)) && +!(retVal = function_namespace0_generated_136_begin(server, ns)) && +!(retVal = function_namespace0_generated_137_begin(server, ns)) && +!(retVal = function_namespace0_generated_138_begin(server, ns)) && +!(retVal = function_namespace0_generated_139_begin(server, ns)) && +!(retVal = function_namespace0_generated_140_begin(server, ns)) && +!(retVal = function_namespace0_generated_141_begin(server, ns)) && +!(retVal = function_namespace0_generated_142_begin(server, ns)) && +!(retVal = function_namespace0_generated_143_begin(server, ns)) && +!(retVal = function_namespace0_generated_144_begin(server, ns)) && +!(retVal = function_namespace0_generated_145_begin(server, ns)) && +!(retVal = function_namespace0_generated_146_begin(server, ns)) && +!(retVal = function_namespace0_generated_147_begin(server, ns)) && +!(retVal = function_namespace0_generated_148_begin(server, ns)) && +!(retVal = function_namespace0_generated_149_begin(server, ns)) && +!(retVal = function_namespace0_generated_150_begin(server, ns)) && +!(retVal = function_namespace0_generated_151_begin(server, ns)) && +!(retVal = function_namespace0_generated_152_begin(server, ns)) && +!(retVal = function_namespace0_generated_153_begin(server, ns)) && +!(retVal = function_namespace0_generated_154_begin(server, ns)) && +!(retVal = function_namespace0_generated_155_begin(server, ns)) && +!(retVal = function_namespace0_generated_156_begin(server, ns)) && +!(retVal = function_namespace0_generated_157_begin(server, ns)) && +!(retVal = function_namespace0_generated_158_begin(server, ns)) && +!(retVal = function_namespace0_generated_159_begin(server, ns)) && +!(retVal = function_namespace0_generated_160_begin(server, ns)) && +!(retVal = function_namespace0_generated_161_begin(server, ns)) && +!(retVal = function_namespace0_generated_162_begin(server, ns)) && +!(retVal = function_namespace0_generated_163_begin(server, ns)) && +!(retVal = function_namespace0_generated_164_begin(server, ns)) && +!(retVal = function_namespace0_generated_165_begin(server, ns)) && +!(retVal = function_namespace0_generated_165_finish(server, ns)) && +!(retVal = function_namespace0_generated_164_finish(server, ns)) && +!(retVal = function_namespace0_generated_163_finish(server, ns)) && +!(retVal = function_namespace0_generated_162_finish(server, ns)) && +!(retVal = function_namespace0_generated_161_finish(server, ns)) && +!(retVal = function_namespace0_generated_160_finish(server, ns)) && +!(retVal = function_namespace0_generated_159_finish(server, ns)) && +!(retVal = function_namespace0_generated_158_finish(server, ns)) && +!(retVal = function_namespace0_generated_157_finish(server, ns)) && +!(retVal = function_namespace0_generated_156_finish(server, ns)) && +!(retVal = function_namespace0_generated_155_finish(server, ns)) && +!(retVal = function_namespace0_generated_154_finish(server, ns)) && +!(retVal = function_namespace0_generated_153_finish(server, ns)) && +!(retVal = function_namespace0_generated_152_finish(server, ns)) && +!(retVal = function_namespace0_generated_151_finish(server, ns)) && +!(retVal = function_namespace0_generated_150_finish(server, ns)) && +!(retVal = function_namespace0_generated_149_finish(server, ns)) && +!(retVal = function_namespace0_generated_148_finish(server, ns)) && +!(retVal = function_namespace0_generated_147_finish(server, ns)) && +!(retVal = function_namespace0_generated_146_finish(server, ns)) && +!(retVal = function_namespace0_generated_145_finish(server, ns)) && +!(retVal = function_namespace0_generated_144_finish(server, ns)) && +!(retVal = function_namespace0_generated_143_finish(server, ns)) && +!(retVal = function_namespace0_generated_142_finish(server, ns)) && +!(retVal = function_namespace0_generated_141_finish(server, ns)) && +!(retVal = function_namespace0_generated_140_finish(server, ns)) && +!(retVal = function_namespace0_generated_139_finish(server, ns)) && +!(retVal = function_namespace0_generated_138_finish(server, ns)) && +!(retVal = function_namespace0_generated_137_finish(server, ns)) && +!(retVal = function_namespace0_generated_136_finish(server, ns)) && +!(retVal = function_namespace0_generated_135_finish(server, ns)) && +!(retVal = function_namespace0_generated_134_finish(server, ns)) && +!(retVal = function_namespace0_generated_133_finish(server, ns)) && +!(retVal = function_namespace0_generated_132_finish(server, ns)) && +!(retVal = function_namespace0_generated_131_finish(server, ns)) && +!(retVal = function_namespace0_generated_130_finish(server, ns)) && +!(retVal = function_namespace0_generated_129_finish(server, ns)) && +!(retVal = function_namespace0_generated_128_finish(server, ns)) && +!(retVal = function_namespace0_generated_127_finish(server, ns)) && +!(retVal = function_namespace0_generated_126_finish(server, ns)) && +!(retVal = function_namespace0_generated_125_finish(server, ns)) && +!(retVal = function_namespace0_generated_124_finish(server, ns)) && +!(retVal = function_namespace0_generated_123_finish(server, ns)) && +!(retVal = function_namespace0_generated_122_finish(server, ns)) && +!(retVal = function_namespace0_generated_121_finish(server, ns)) && +!(retVal = function_namespace0_generated_120_finish(server, ns)) && +!(retVal = function_namespace0_generated_119_finish(server, ns)) && +!(retVal = function_namespace0_generated_118_finish(server, ns)) && +!(retVal = function_namespace0_generated_117_finish(server, ns)) && +!(retVal = function_namespace0_generated_116_finish(server, ns)) && +!(retVal = function_namespace0_generated_115_finish(server, ns)) && +!(retVal = function_namespace0_generated_114_finish(server, ns)) && +!(retVal = function_namespace0_generated_113_finish(server, ns)) && +!(retVal = function_namespace0_generated_112_finish(server, ns)) && +!(retVal = function_namespace0_generated_111_finish(server, ns)) && +!(retVal = function_namespace0_generated_110_finish(server, ns)) && +!(retVal = function_namespace0_generated_109_finish(server, ns)) && +!(retVal = function_namespace0_generated_108_finish(server, ns)) && +!(retVal = function_namespace0_generated_107_finish(server, ns)) && +!(retVal = function_namespace0_generated_106_finish(server, ns)) && +!(retVal = function_namespace0_generated_105_finish(server, ns)) && +!(retVal = function_namespace0_generated_104_finish(server, ns)) && +!(retVal = function_namespace0_generated_103_finish(server, ns)) && +!(retVal = function_namespace0_generated_102_finish(server, ns)) && +!(retVal = function_namespace0_generated_101_finish(server, ns)) && +!(retVal = function_namespace0_generated_100_finish(server, ns)) && +!(retVal = function_namespace0_generated_99_finish(server, ns)) && +!(retVal = function_namespace0_generated_98_finish(server, ns)) && +!(retVal = function_namespace0_generated_97_finish(server, ns)) && +!(retVal = function_namespace0_generated_96_finish(server, ns)) && +!(retVal = function_namespace0_generated_95_finish(server, ns)) && +!(retVal = function_namespace0_generated_94_finish(server, ns)) && +!(retVal = function_namespace0_generated_93_finish(server, ns)) && +!(retVal = function_namespace0_generated_92_finish(server, ns)) && +!(retVal = function_namespace0_generated_91_finish(server, ns)) && +!(retVal = function_namespace0_generated_90_finish(server, ns)) && +!(retVal = function_namespace0_generated_89_finish(server, ns)) && +!(retVal = function_namespace0_generated_88_finish(server, ns)) && +!(retVal = function_namespace0_generated_87_finish(server, ns)) && +!(retVal = function_namespace0_generated_86_finish(server, ns)) && +!(retVal = function_namespace0_generated_85_finish(server, ns)) && +!(retVal = function_namespace0_generated_84_finish(server, ns)) && +!(retVal = function_namespace0_generated_83_finish(server, ns)) && +!(retVal = function_namespace0_generated_82_finish(server, ns)) && +!(retVal = function_namespace0_generated_81_finish(server, ns)) && +!(retVal = function_namespace0_generated_80_finish(server, ns)) && +!(retVal = function_namespace0_generated_79_finish(server, ns)) && +!(retVal = function_namespace0_generated_78_finish(server, ns)) && +!(retVal = function_namespace0_generated_77_finish(server, ns)) && +!(retVal = function_namespace0_generated_76_finish(server, ns)) && +!(retVal = function_namespace0_generated_75_finish(server, ns)) && +!(retVal = function_namespace0_generated_74_finish(server, ns)) && +!(retVal = function_namespace0_generated_73_finish(server, ns)) && +!(retVal = function_namespace0_generated_72_finish(server, ns)) && +!(retVal = function_namespace0_generated_71_finish(server, ns)) && +!(retVal = function_namespace0_generated_70_finish(server, ns)) && +!(retVal = function_namespace0_generated_69_finish(server, ns)) && +!(retVal = function_namespace0_generated_68_finish(server, ns)) && +!(retVal = function_namespace0_generated_67_finish(server, ns)) && +!(retVal = function_namespace0_generated_66_finish(server, ns)) && +!(retVal = function_namespace0_generated_65_finish(server, ns)) && +!(retVal = function_namespace0_generated_64_finish(server, ns)) && +!(retVal = function_namespace0_generated_63_finish(server, ns)) && +!(retVal = function_namespace0_generated_62_finish(server, ns)) && +!(retVal = function_namespace0_generated_61_finish(server, ns)) && +!(retVal = function_namespace0_generated_60_finish(server, ns)) && +!(retVal = function_namespace0_generated_59_finish(server, ns)) && +!(retVal = function_namespace0_generated_58_finish(server, ns)) && +!(retVal = function_namespace0_generated_57_finish(server, ns)) && +!(retVal = function_namespace0_generated_56_finish(server, ns)) && +!(retVal = function_namespace0_generated_55_finish(server, ns)) && +!(retVal = function_namespace0_generated_54_finish(server, ns)) && +!(retVal = function_namespace0_generated_53_finish(server, ns)) && +!(retVal = function_namespace0_generated_52_finish(server, ns)) && +!(retVal = function_namespace0_generated_51_finish(server, ns)) && +!(retVal = function_namespace0_generated_50_finish(server, ns)) && +!(retVal = function_namespace0_generated_49_finish(server, ns)) && +!(retVal = function_namespace0_generated_48_finish(server, ns)) && +!(retVal = function_namespace0_generated_47_finish(server, ns)) && +!(retVal = function_namespace0_generated_46_finish(server, ns)) && +!(retVal = function_namespace0_generated_45_finish(server, ns)) && +!(retVal = function_namespace0_generated_44_finish(server, ns)) && +!(retVal = function_namespace0_generated_43_finish(server, ns)) && +!(retVal = function_namespace0_generated_42_finish(server, ns)) && +!(retVal = function_namespace0_generated_41_finish(server, ns)) && +!(retVal = function_namespace0_generated_40_finish(server, ns)) && +!(retVal = function_namespace0_generated_39_finish(server, ns)) && +!(retVal = function_namespace0_generated_38_finish(server, ns)) && +!(retVal = function_namespace0_generated_37_finish(server, ns)) && +!(retVal = function_namespace0_generated_36_finish(server, ns)) && +!(retVal = function_namespace0_generated_35_finish(server, ns)) && +!(retVal = function_namespace0_generated_34_finish(server, ns)) && +!(retVal = function_namespace0_generated_33_finish(server, ns)) && +!(retVal = function_namespace0_generated_32_finish(server, ns)) && +!(retVal = function_namespace0_generated_31_finish(server, ns)) && +!(retVal = function_namespace0_generated_30_finish(server, ns)) && +!(retVal = function_namespace0_generated_29_finish(server, ns)) && +!(retVal = function_namespace0_generated_28_finish(server, ns)) && +!(retVal = function_namespace0_generated_27_finish(server, ns)) && +!(retVal = function_namespace0_generated_26_finish(server, ns)) && +!(retVal = function_namespace0_generated_25_finish(server, ns)) && +!(retVal = function_namespace0_generated_24_finish(server, ns)) && +!(retVal = function_namespace0_generated_23_finish(server, ns)) && +!(retVal = function_namespace0_generated_22_finish(server, ns)) && +!(retVal = function_namespace0_generated_21_finish(server, ns)) && +!(retVal = function_namespace0_generated_20_finish(server, ns)) && +!(retVal = function_namespace0_generated_19_finish(server, ns)) && +!(retVal = function_namespace0_generated_18_finish(server, ns)) && +!(retVal = function_namespace0_generated_17_finish(server, ns)) && +!(retVal = function_namespace0_generated_16_finish(server, ns)) && +!(retVal = function_namespace0_generated_15_finish(server, ns)) && +!(retVal = function_namespace0_generated_14_finish(server, ns)) && +!(retVal = function_namespace0_generated_13_finish(server, ns)) && +!(retVal = function_namespace0_generated_12_finish(server, ns)) && +!(retVal = function_namespace0_generated_11_finish(server, ns)) && +!(retVal = function_namespace0_generated_10_finish(server, ns)) && +!(retVal = function_namespace0_generated_9_finish(server, ns)) && +!(retVal = function_namespace0_generated_8_finish(server, ns)) && +!(retVal = function_namespace0_generated_7_finish(server, ns)) && +!(retVal = function_namespace0_generated_6_finish(server, ns)) && +!(retVal = function_namespace0_generated_5_finish(server, ns)) && +!(retVal = function_namespace0_generated_4_finish(server, ns)) && +!(retVal = function_namespace0_generated_3_finish(server, ns)) && +!(retVal = function_namespace0_generated_2_finish(server, ns)) && +!(retVal = function_namespace0_generated_1_finish(server, ns)) && +!(retVal = function_namespace0_generated_0_finish(server, ns)) +); (void)(dummy); +return retVal; +} + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_discovery_manager.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2014, 2017 (c) Florian Palm + * Copyright 2015-2016, 2019 (c) Sten Grüner + * Copyright 2015 (c) Chris Iatrou + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Julian Grothoff + */ + + +#ifdef UA_ENABLE_DISCOVERY + +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + +#ifndef IN_ZERONET +#define IN_ZERONET(addr) ((addr & IN_CLASSA_NET) == 0) +#endif + +/* Create multicast 224.0.0.251:5353 socket */ +static UA_SOCKET +discovery_createMulticastSocket(UA_Server* server) { + UA_SOCKET s; + int flag = 1, ittl = 255; + struct sockaddr_in in; + struct ip_mreq mc; + char ttl = (char)255; // publish to complete net, not only subnet. See: + // https://docs.oracle.com/cd/E23824_01/html/821-1602/sockets-137.html + + memset(&in, 0, sizeof(in)); + in.sin_family = AF_INET; + in.sin_port = htons(5353); + in.sin_addr.s_addr = 0; + + if((s = UA_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == UA_INVALID_SOCKET) + return UA_INVALID_SOCKET; + +#ifdef SO_REUSEPORT + UA_setsockopt(s, SOL_SOCKET, SO_REUSEPORT, (char *)&flag, sizeof(flag)); +#endif + UA_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)); + if(UA_bind(s, (struct sockaddr *)&in, sizeof(in))) { + UA_close(s); + return UA_INVALID_SOCKET; + } + + /* Custom outbound multicast interface */ + size_t length = server->config.discovery.mdnsInterfaceIP.length; + if(length > 0){ + char* interfaceName = (char*)UA_malloc(length+1); + if (!interfaceName) { + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Multicast DNS: cannot alloc memory for iface name"); + return 0; + } + struct in_addr ina; + memset(&ina, 0, sizeof(ina)); + memcpy(interfaceName, server->config.discovery.mdnsInterfaceIP.data, length); + interfaceName[length] = '\0'; + inet_pton(AF_INET, interfaceName, &ina); + UA_free(interfaceName); + /* Set interface for outbound multicast */ + if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char*)&ina, sizeof(ina)) < 0) + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Multicast DNS: failed setting IP_MULTICAST_IF to %s: %s", inet_ntoa(ina), strerror(errno)); + } + + /* Check outbound multicast interface parameters */ + struct in_addr interface_addr; + socklen_t addr_size = sizeof(struct in_addr); + if (getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char*)&interface_addr, &addr_size) < 0) { + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Multicast DNS: getsockopt(IP_MULTICAST_IF) failed"); + } + + if(IN_ZERONET(ntohl(interface_addr.s_addr))){ + UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Multicast DNS: outbound interface 0.0.0.0, it means that the first OS interface is used (you can explicitly set the interface by using 'discovery.mdnsInterfaceIP' config parameter)"); + }else{ + char buf[16]; + inet_ntop(AF_INET, &interface_addr, buf, 16); + UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_NETWORK, "Multicast DNS: outbound interface is %s", buf); + } + + mc.imr_multiaddr.s_addr = inet_addr("224.0.0.251"); + mc.imr_interface.s_addr = htonl(INADDR_ANY); + UA_setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mc, sizeof(mc)); + UA_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl)); + UA_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl, sizeof(ittl)); + + UA_socket_set_nonblocking(s); //TODO: check return value + return s; } static UA_StatusCode -ServerNetworkLayerTCP_add(ServerNetworkLayerTCP *layer, UA_Int32 newsockfd, - struct sockaddr_storage *remote) { - /* Set nonblocking */ - socket_set_nonblocking(newsockfd); +initMulticastDiscoveryServer(UA_DiscoveryManager *dm, UA_Server* server) { + server->discoveryManager.mdnsDaemon = mdnsd_new(QCLASS_IN, 1000); + UA_initialize_architecture_network(); - /* Do not merge packets on the socket (disable Nagle's algorithm) */ - int dummy = 1; - if(setsockopt(newsockfd, IPPROTO_TCP, TCP_NODELAY, - (const char *)&dummy, sizeof(dummy)) < 0) { + if((server->discoveryManager.mdnsSocket = discovery_createMulticastSocket(server)) == UA_INVALID_SOCKET) { UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_ERROR(layer->logger, UA_LOGCATEGORY_NETWORK, - "Cannot set socket option TCP_NODELAY. Error: %s", - errno_str)); + UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, + "Could not create multicast socket. Error: %s", errno_str)); return UA_STATUSCODE_BADUNEXPECTEDERROR; } + mdnsd_register_receive_callback(server->discoveryManager.mdnsDaemon, + mdns_record_received, server); + return UA_STATUSCODE_GOOD; +} -#if !defined(UA_FREERTOS) - /* Get the peer name for logging */ - char remote_name[100]; - int res = getnameinfo((struct sockaddr*)remote, - sizeof(struct sockaddr_storage), - remote_name, sizeof(remote_name), - NULL, 0, NI_NUMERICHOST); - if(res == 0) { - UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | New connection over TCP from %s", - (int)newsockfd, remote_name); - } else { - UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | New connection over TCP, " - "getnameinfo failed with error: %s", - (int)newsockfd, errno_str)); +static void +destroyMulticastDiscoveryServer(UA_DiscoveryManager *dm) { + if (!dm->mdnsDaemon) + return; + + mdnsd_shutdown(dm->mdnsDaemon); + mdnsd_free(dm->mdnsDaemon); + + if(dm->mdnsSocket != UA_INVALID_SOCKET) { + UA_close(dm->mdnsSocket); + dm->mdnsSocket = UA_INVALID_SOCKET; } -#endif - /* Allocate and initialize the connection */ - ConnectionEntry *e = (ConnectionEntry*)UA_malloc(sizeof(ConnectionEntry)); - if(!e){ - CLOSESOCKET(newsockfd); - return UA_STATUSCODE_BADOUTOFMEMORY; +} + +#endif /* UA_ENABLE_DISCOVERY_MULTICAST */ + +void +UA_DiscoveryManager_init(UA_DiscoveryManager *dm, UA_Server *server) { + LIST_INIT(&dm->registeredServers); + dm->registeredServersSize = 0; + LIST_INIT(&dm->periodicServerRegisterCallbacks); + dm->registerServerCallback = NULL; + dm->registerServerCallbackData = NULL; + +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + dm->mdnsDaemon = NULL; + dm->mdnsSocket = UA_INVALID_SOCKET; + dm->mdnsMainSrvAdded = false; + if(server->config.discovery.mdnsEnable) + initMulticastDiscoveryServer(dm, server); + + LIST_INIT(&dm->serverOnNetwork); + dm->serverOnNetworkSize = 0; + dm->serverOnNetworkRecordIdCounter = 0; + dm->serverOnNetworkRecordIdLastReset = UA_DateTime_now(); + memset(dm->serverOnNetworkHash, 0, + sizeof(struct serverOnNetwork_hash_entry*) * SERVER_ON_NETWORK_HASH_PRIME); + + dm->serverOnNetworkCallback = NULL; + dm->serverOnNetworkCallbackData = NULL; +#endif /* UA_ENABLE_DISCOVERY_MULTICAST */ +} + +void +UA_DiscoveryManager_deleteMembers(UA_DiscoveryManager *dm, UA_Server *server) { + registeredServer_list_entry *rs, *rs_tmp; + LIST_FOREACH_SAFE(rs, &dm->registeredServers, pointers, rs_tmp) { + LIST_REMOVE(rs, pointers); + UA_RegisteredServer_deleteMembers(&rs->registeredServer); + UA_free(rs); + } + periodicServerRegisterCallback_entry *ps, *ps_tmp; + LIST_FOREACH_SAFE(ps, &dm->periodicServerRegisterCallbacks, pointers, ps_tmp) { + LIST_REMOVE(ps, pointers); + UA_free(ps->callback); + UA_free(ps); } - UA_Connection *c = &e->connection; - memset(c, 0, sizeof(UA_Connection)); - c->sockfd = newsockfd; - c->handle = layer; - c->localConf = layer->conf; - c->remoteConf = layer->conf; - c->send = connection_write; - c->close = ServerNetworkLayerTCP_close; - c->free = ServerNetworkLayerTCP_freeConnection; - c->getSendBuffer = connection_getsendbuffer; - c->releaseSendBuffer = connection_releasesendbuffer; - c->releaseRecvBuffer = connection_releaserecvbuffer; - c->state = UA_CONNECTION_OPENING; - c->openingDate = UA_DateTime_nowMonotonic(); +# ifdef UA_ENABLE_DISCOVERY_MULTICAST + if(server->config.discovery.mdnsEnable) + destroyMulticastDiscoveryServer(dm); - /* Add to the linked list */ - LIST_INSERT_HEAD(&layer->connections, e, pointers); - return UA_STATUSCODE_GOOD; + serverOnNetwork_list_entry *son, *son_tmp; + LIST_FOREACH_SAFE(son, &dm->serverOnNetwork, pointers, son_tmp) { + LIST_REMOVE(son, pointers); + UA_ServerOnNetwork_deleteMembers(&son->serverOnNetwork); + if(son->pathTmp) + UA_free(son->pathTmp); + UA_free(son); + } + + for(size_t i = 0; i < SERVER_ON_NETWORK_HASH_PRIME; i++) { + serverOnNetwork_hash_entry* currHash = dm->serverOnNetworkHash[i]; + while(currHash) { + serverOnNetwork_hash_entry* nextHash = currHash->next; + UA_free(currHash); + currHash = nextHash; + } + } + +# endif /* UA_ENABLE_DISCOVERY_MULTICAST */ } -static void -addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) { - /* Create the server socket */ - SOCKET newsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); -#ifdef _WIN32 - if(newsock == INVALID_SOCKET) -#else - if(newsock < 0) -#endif - { - UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, - "Error opening the server socket"); - return; +#endif /* UA_ENABLE_DISCOVERY */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_subscription.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2015-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2015 (c) Chris Iatrou + * Copyright 2015-2016 (c) Sten Grüner + * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2015 (c) Joakim L. Gilje + * Copyright 2016-2017 (c) Florian Palm + * Copyright 2015-2016 (c) Oleksiy Vasylyev + * Copyright 2017 (c) frax2222 + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Ari Breitkreuz, fortiss GmbH + * Copyright 2017 (c) Mattias Bornhager + * Copyright 2018 (c) Hilscher Gesellschaft für Systemautomation mbH (Author: Martin Lang) + */ + + +#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ + +UA_Subscription * +UA_Subscription_new(UA_Session *session, UA_UInt32 subscriptionId) { + /* Allocate the memory */ + UA_Subscription *newSub = + (UA_Subscription*)UA_calloc(1, sizeof(UA_Subscription)); + if(!newSub) + return NULL; + + /* Remaining members are covered by calloc zeroing out the memory */ + newSub->session = session; + newSub->subscriptionId = subscriptionId; + newSub->state = UA_SUBSCRIPTIONSTATE_NORMAL; /* The first publish response is sent immediately */ + /* Even if the first publish response is a keepalive the sequence number is 1. + * This can happen by a subscription without a monitored item (see CTT test scripts). */ + newSub->nextSequenceNumber = 1; + TAILQ_INIT(&newSub->retransmissionQueue); + TAILQ_INIT(&newSub->notificationQueue); + return newSub; +} + +void +UA_Subscription_deleteMembers(UA_Server *server, UA_Subscription *sub) { + Subscription_unregisterPublishCallback(server, sub); + + /* Delete monitored Items */ + UA_MonitoredItem *mon, *tmp_mon; + LIST_FOREACH_SAFE(mon, &sub->monitoredItems, listEntry, tmp_mon) { + LIST_REMOVE(mon, listEntry); + UA_LOG_INFO_SESSION(&server->config.logger, sub->session, + "Subscription %u | MonitoredItem %i | " + "Deleted the MonitoredItem", sub->subscriptionId, + mon->monitoredItemId); + UA_MonitoredItem_delete(server, mon); } + UA_assert(server->numMonitoredItems >= sub->monitoredItemsSize); + server->numMonitoredItems -= sub->monitoredItemsSize; + sub->monitoredItemsSize = 0; - /* Some Linux distributions have net.ipv6.bindv6only not activated. So - * sockets can double-bind to IPv4 and IPv6. This leads to problems. Use - * AF_INET6 sockets only for IPv6. */ + /* Delete Retransmission Queue */ + UA_NotificationMessageEntry *nme, *nme_tmp; + TAILQ_FOREACH_SAFE(nme, &sub->retransmissionQueue, listEntry, nme_tmp) { + TAILQ_REMOVE(&sub->retransmissionQueue, nme, listEntry); + UA_NotificationMessage_deleteMembers(&nme->message); + UA_free(nme); + --sub->session->totalRetransmissionQueueSize; + --sub->retransmissionQueueSize; + } + UA_assert(sub->retransmissionQueueSize == 0); - int optval = 1; -#if !defined(UA_FREERTOS) - if(ai->ai_family == AF_INET6 && - setsockopt(newsock, IPPROTO_IPV6, IPV6_V6ONLY, - (const char*)&optval, sizeof(optval)) == -1) { - UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, - "Could not set an IPv6 socket to IPv6 only"); - CLOSESOCKET(newsock); - return; + UA_LOG_INFO_SESSION(&server->config.logger, sub->session, + "Subscription %u | Deleted the Subscription", + sub->subscriptionId); +} + +UA_MonitoredItem * +UA_Subscription_getMonitoredItem(UA_Subscription *sub, UA_UInt32 monitoredItemId) { + UA_MonitoredItem *mon; + LIST_FOREACH(mon, &sub->monitoredItems, listEntry) { + if(mon->monitoredItemId == monitoredItemId) + break; } -#endif - if(setsockopt(newsock, SOL_SOCKET, SO_REUSEADDR, - (const char *)&optval, sizeof(optval)) == -1) { - UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, - "Could not make the socket reusable"); - CLOSESOCKET(newsock); - return; + return mon; +} + +UA_StatusCode +UA_Subscription_deleteMonitoredItem(UA_Server *server, UA_Subscription *sub, + UA_UInt32 monitoredItemId) { + /* Find the MonitoredItem */ + UA_MonitoredItem *mon; + LIST_FOREACH(mon, &sub->monitoredItems, listEntry) { + if(mon->monitoredItemId == monitoredItemId) + break; } + if(!mon) + return UA_STATUSCODE_BADMONITOREDITEMIDINVALID; + UA_LOG_INFO_SESSION(&server->config.logger, sub->session, + "Subscription %u | MonitoredItem %i | " + "Delete the MonitoredItem", sub->subscriptionId, + mon->monitoredItemId); - if(socket_set_nonblocking(newsock) != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, - "Could not set the server socket to nonblocking"); - CLOSESOCKET(newsock); - return; + /* Remove the MonitoredItem */ + LIST_REMOVE(mon, listEntry); + UA_assert(sub->monitoredItemsSize > 0); + UA_assert(server->numMonitoredItems > 0); + sub->monitoredItemsSize--; + server->numMonitoredItems--; + + /* Remove content and delayed free */ + UA_MonitoredItem_delete(server, mon); + + return UA_STATUSCODE_GOOD; +} + +void +UA_Subscription_addMonitoredItem(UA_Server *server, UA_Subscription *sub, UA_MonitoredItem *newMon) { + sub->monitoredItemsSize++; + server->numMonitoredItems++; + LIST_INSERT_HEAD(&sub->monitoredItems, newMon, listEntry); +} + +static void +removeOldestRetransmissionMessage(UA_Session *session) { + UA_NotificationMessageEntry *oldestEntry = NULL; + UA_Subscription *oldestSub = NULL; + + UA_Subscription *sub; + LIST_FOREACH(sub, &session->serverSubscriptions, listEntry) { + UA_NotificationMessageEntry *first = + TAILQ_LAST(&sub->retransmissionQueue, ListOfNotificationMessages); + if(!first) + continue; + if(!oldestEntry || oldestEntry->message.publishTime > first->message.publishTime) { + oldestEntry = first; + oldestSub = sub; + } } + UA_assert(oldestEntry); + UA_assert(oldestSub); - /* Bind socket to address */ - if(bind(newsock, ai->ai_addr, WIN32_INT ai->ai_addrlen) < 0) { - UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, - "Error binding a server socket: %s", errno_str)); - CLOSESOCKET(newsock); - return; + TAILQ_REMOVE(&oldestSub->retransmissionQueue, oldestEntry, listEntry); + UA_NotificationMessage_deleteMembers(&oldestEntry->message); + UA_free(oldestEntry); + --session->totalRetransmissionQueueSize; + --oldestSub->retransmissionQueueSize; +} + +static void +UA_Subscription_addRetransmissionMessage(UA_Server *server, UA_Subscription *sub, + UA_NotificationMessageEntry *entry) { + /* Release the oldest entry if there is not enough space */ + if(server->config.maxRetransmissionQueueSize > 0 && + sub->session->totalRetransmissionQueueSize >= server->config.maxRetransmissionQueueSize) { + UA_LOG_WARNING_SESSION(&server->config.logger, sub->session, "Subscription %u | " + "Retransmission queue overflow", sub->subscriptionId); + removeOldestRetransmissionMessage(sub->session); } - /* Start listening */ - if(listen(newsock, MAXBACKLOG) < 0) { - UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, - "Error listening on server socket: %s", errno_str)); - CLOSESOCKET(newsock); - return; + /* Add entry */ + TAILQ_INSERT_TAIL(&sub->retransmissionQueue, entry, listEntry); + ++sub->session->totalRetransmissionQueueSize; + ++sub->retransmissionQueueSize; +} + +UA_StatusCode +UA_Subscription_removeRetransmissionMessage(UA_Subscription *sub, UA_UInt32 sequenceNumber) { + /* Find the retransmission message */ + UA_NotificationMessageEntry *entry; + TAILQ_FOREACH(entry, &sub->retransmissionQueue, listEntry) { + if(entry->message.sequenceNumber == sequenceNumber) + break; } + if(!entry) + return UA_STATUSCODE_BADSEQUENCENUMBERUNKNOWN; - layer->serverSockets[layer->serverSocketsSize] = (UA_Int32)newsock; - layer->serverSocketsSize++; + /* Remove the retransmission message */ + TAILQ_REMOVE(&sub->retransmissionQueue, entry, listEntry); + --sub->session->totalRetransmissionQueueSize; + --sub->retransmissionQueueSize; + UA_NotificationMessage_deleteMembers(&entry->message); + UA_free(entry); + return UA_STATUSCODE_GOOD; } static UA_StatusCode -ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHostname) { -#ifdef _WIN32 - WORD wVersionRequested = MAKEWORD(2, 2); - WSADATA wsaData; - WSAStartup(wVersionRequested, &wsaData); +prepareNotificationMessage(UA_Server *server, UA_Subscription *sub, + UA_NotificationMessage *message, size_t notifications) { + UA_assert(notifications > 0); + + /* Allocate an ExtensionObject for events and data */ + message->notificationData = (UA_ExtensionObject*) + UA_Array_new(2, &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]); + if(!message->notificationData) + return UA_STATUSCODE_BADOUTOFMEMORY; + message->notificationDataSize = 2; + + /* Pre-allocate DataChangeNotifications */ + size_t notificationDataIdx = 0; + UA_DataChangeNotification *dcn = NULL; + if(sub->dataChangeNotifications > 0) { + dcn = UA_DataChangeNotification_new(); + if(!dcn) { + UA_NotificationMessage_deleteMembers(message); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + message->notificationData->encoding = UA_EXTENSIONOBJECT_DECODED; + message->notificationData->content.decoded.data = dcn; + message->notificationData->content.decoded.type = &UA_TYPES[UA_TYPES_DATACHANGENOTIFICATION]; + + size_t dcnSize = sub->dataChangeNotifications; + if(dcnSize > notifications) + dcnSize = notifications; + dcn->monitoredItems = (UA_MonitoredItemNotification*) + UA_Array_new(dcnSize, &UA_TYPES[UA_TYPES_MONITOREDITEMNOTIFICATION]); + if(!dcn->monitoredItems) { + UA_NotificationMessage_deleteMembers(message); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + dcn->monitoredItemsSize = dcnSize; + notificationDataIdx++; + } + +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + UA_EventNotificationList *enl = NULL; + UA_StatusChangeNotification *scn = NULL; + /* Pre-allocate either StatusChange or EventNotifications. Sending a + * (single) StatusChangeNotification has priority. */ + if(sub->statusChangeNotifications > 0) { + scn = UA_StatusChangeNotification_new(); + if(!scn) { + UA_NotificationMessage_deleteMembers(message); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + message->notificationData[notificationDataIdx].encoding = UA_EXTENSIONOBJECT_DECODED; + message->notificationData[notificationDataIdx].content.decoded.data = scn; + message->notificationData[notificationDataIdx].content.decoded.type = &UA_TYPES[UA_TYPES_STATUSCHANGENOTIFICATION]; + notificationDataIdx++; + } else if(sub->eventNotifications > 0) { + enl = UA_EventNotificationList_new(); + if(!enl) { + UA_NotificationMessage_deleteMembers(message); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + message->notificationData[notificationDataIdx].encoding = UA_EXTENSIONOBJECT_DECODED; + message->notificationData[notificationDataIdx].content.decoded.data = enl; + message->notificationData[notificationDataIdx].content.decoded.type = &UA_TYPES[UA_TYPES_EVENTNOTIFICATIONLIST]; + + size_t enlSize = sub->eventNotifications; + if(enlSize > notifications) + enlSize = notifications; + enl->events = (UA_EventFieldList*) UA_Array_new(enlSize, &UA_TYPES[UA_TYPES_EVENTFIELDLIST]); + if(!enl->events) { + UA_NotificationMessage_deleteMembers(message); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + enl->eventsSize = enlSize; + notificationDataIdx++; + } #endif - ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle; + UA_assert(notificationDataIdx > 0); + message->notificationDataSize = notificationDataIdx; - /* Get the discovery url from the hostname */ - UA_String du = UA_STRING_NULL; - if (customHostname->length) { - char discoveryUrl[256]; -#ifndef _MSC_VER - du.length = (size_t)snprintf(discoveryUrl, 255, "opc.tcp://%.*s:%d/", - (int)customHostname->length, - customHostname->data, - layer->port); -#else - du.length = (size_t)_snprintf_s(discoveryUrl, 255, _TRUNCATE, - "opc.tcp://%.*s:%d/", - (int)customHostname->length, - customHostname->data, - layer->port); + /* <-- The point of no return --> */ + + size_t totalNotifications = 0; /* How many notifications were moved to the response overall? */ + size_t dcnPos = 0; /* How many DataChangeNotifications were put into the list? */ +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + size_t enlPos = 0; /* How many EventNotifications were moved into the list */ #endif - du.data = (UA_Byte*)discoveryUrl; - }else{ - char hostname[256]; - if(gethostname(hostname, 255) == 0) { - char discoveryUrl[256]; -#ifndef _MSC_VER - du.length = (size_t)snprintf(discoveryUrl, 255, "opc.tcp://%s:%d/", - hostname, layer->port); -#else - du.length = (size_t)_snprintf_s(discoveryUrl, 255, _TRUNCATE, - "opc.tcp://%s:%d/", hostname, - layer->port); + UA_Notification *notification, *notification_tmp; + TAILQ_FOREACH_SAFE(notification, &sub->notificationQueue, globalEntry, notification_tmp) { + if(totalNotifications >= notifications) + break; + + UA_MonitoredItem *mon = notification->mon; + + /* Remove from the queues and decrease the counters */ + UA_Notification_dequeue(server, notification); + + /* Move the content to the response */ +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + + UA_assert(enl != NULL); /* Have at least one event notification */ + + /* Move the content to the response */ + UA_EventFieldList *efl = &enl->events[enlPos]; + *efl = notification->data.event.fields; + UA_EventFieldList_init(¬ification->data.event.fields); + efl->clientHandle = mon->clientHandle; + + enlPos++; + } else #endif - du.data = (UA_Byte*)discoveryUrl; + { + UA_assert(dcn != NULL); /* Have at least one change notification */ + /* Move the content to the response */ + UA_MonitoredItemNotification *min = &dcn->monitoredItems[dcnPos]; + min->clientHandle = mon->clientHandle; + min->value = notification->data.value; + UA_DataValue_init(¬ification->data.value); /* Reset after the value has been moved */ + dcnPos++; } + + UA_Notification_delete(notification); + totalNotifications++; } - UA_String_copy(&du, &nl->discoveryUrl); - /* Get addrinfo of the server and create server sockets */ - char portno[6]; -#ifndef _MSC_VER - snprintf(portno, 6, "%d", layer->port); -#else - _snprintf_s(portno, 6, _TRUNCATE, "%d", layer->port); -#endif - struct addrinfo hints, *res; - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; -#if defined(UA_FREERTOS) - hints.ai_protocol = IPPROTO_TCP; - char hostname[] = UA_FREERTOS_HOSTNAME; - if(getaddrinfo(hostname, portno, &hints, &res) != 0) -#else - if(getaddrinfo(NULL, portno, &hints, &res) != 0) -#endif - return UA_STATUSCODE_BADINTERNALERROR; + /* Set sizes */ + if(dcn) { + dcn->monitoredItemsSize = dcnPos; + if(dcnPos == 0) { + UA_free(dcn->monitoredItems); + dcn->monitoredItems = NULL; + } + } - /* There might be serveral addrinfos (for different network cards, - * IPv4/IPv6). Add a server socket for all of them. */ - struct addrinfo *ai = res; - for(layer->serverSocketsSize = 0; - layer->serverSocketsSize < FD_SETSIZE && ai != NULL; - ai = ai->ai_next) - addServerSocket(layer, ai); - freeaddrinfo(res); +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(enl) { + enl->eventsSize = enlPos; + if(enlPos == 0) { + UA_free(enl->events); + enl->events = NULL; + } + } +#endif - UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, - "TCP network layer listening on %.*s", - (int)nl->discoveryUrl.length, nl->discoveryUrl.data); return UA_STATUSCODE_GOOD; } -/* After every select, reset the sockets to listen on */ -static UA_Int32 -setFDSet(ServerNetworkLayerTCP *layer, fd_set *fdset) { - FD_ZERO(fdset); - UA_Int32 highestfd = 0; - for(UA_UInt16 i = 0; i < layer->serverSocketsSize; i++) { - UA_fd_set(layer->serverSockets[i], fdset); - if(layer->serverSockets[i] > highestfd) - highestfd = layer->serverSockets[i]; +/* According to OPC Unified Architecture, Part 4 5.13.1.1 i) The value 0 is + * never used for the sequence number */ +static UA_UInt32 +UA_Subscription_nextSequenceNumber(UA_UInt32 sequenceNumber) { + UA_UInt32 nextSequenceNumber = sequenceNumber + 1; + if(nextSequenceNumber == 0) + nextSequenceNumber = 1; + return nextSequenceNumber; +} + +static void +publishCallback(UA_Server *server, UA_Subscription *sub) { + sub->readyNotifications = sub->notificationQueueSize; + UA_Subscription_publish(server, sub); +} + +void +UA_Subscription_publish(UA_Server *server, UA_Subscription *sub) { + UA_LOG_DEBUG_SESSION(&server->config.logger, sub->session, "Subscription %u | " + "Publish Callback", sub->subscriptionId); + /* Dequeue a response */ + UA_PublishResponseEntry *pre = UA_Session_dequeuePublishReq(sub->session); + if(pre) { + sub->currentLifetimeCount = 0; /* Reset the LifetimeCounter */ + } else { + UA_LOG_DEBUG_SESSION(&server->config.logger, sub->session, + "Subscription %u | The publish queue is empty", + sub->subscriptionId); + ++sub->currentLifetimeCount; + + if(sub->currentLifetimeCount > sub->lifeTimeCount) { + UA_LOG_DEBUG_SESSION(&server->config.logger, sub->session, + "Subscription %u | End of lifetime " + "for subscription", sub->subscriptionId); + UA_Session_deleteSubscription(server, sub->session, sub->subscriptionId); + /* TODO: send a StatusChangeNotification with Bad_Timeout */ + return; + } } - ConnectionEntry *e; - LIST_FOREACH(e, &layer->connections, pointers) { - UA_fd_set(e->connection.sockfd, fdset); - if(e->connection.sockfd > highestfd) - highestfd = e->connection.sockfd; + /* If there are several late publish responses... */ + if(sub->readyNotifications > sub->notificationQueueSize) + sub->readyNotifications = sub->notificationQueueSize; + + /* Count the available notifications */ + UA_UInt32 notifications = sub->readyNotifications; + if(!sub->publishingEnabled) + notifications = 0; + + UA_Boolean moreNotifications = false; + if(notifications > sub->notificationsPerPublish) { + notifications = sub->notificationsPerPublish; + moreNotifications = true; } - return highestfd; -} + /* Return if no notifications and no keepalive */ + if(notifications == 0) { + ++sub->currentKeepAliveCount; + if(sub->currentKeepAliveCount < sub->maxKeepAliveCount) { + if(pre) + UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */ + return; + } + UA_LOG_DEBUG_SESSION(&server->config.logger, sub->session, + "Subscription %u | Sending a KeepAlive", + sub->subscriptionId); + } -static UA_StatusCode -ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server, - UA_UInt16 timeout) { - /* Every open socket can generate two jobs */ - ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle; + /* We want to send a response. Is the channel open? */ + UA_SecureChannel *channel = sub->session->header.channel; + if(!channel || !pre) { + UA_LOG_DEBUG_SESSION(&server->config.logger, sub->session, + "Subscription %u | Want to send a publish response but can't. " + "The subscription is late.", sub->subscriptionId); + sub->state = UA_SUBSCRIPTIONSTATE_LATE; + if(pre) + UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */ + return; + } - if (layer->serverSocketsSize == 0) - return UA_STATUSCODE_GOOD; + /* Prepare the response */ + UA_PublishResponse *response = &pre->response; + UA_NotificationMessage *message = &response->notificationMessage; + UA_NotificationMessageEntry *retransmission = NULL; + if(notifications > 0) { + if(server->config.enableRetransmissionQueue) { + /* Allocate the retransmission entry */ + retransmission = (UA_NotificationMessageEntry*)UA_malloc(sizeof(UA_NotificationMessageEntry)); + if(!retransmission) { + UA_LOG_WARNING_SESSION(&server->config.logger, sub->session, + "Subscription %u | Could not allocate memory for retransmission. " + "The subscription is late.", sub->subscriptionId); + sub->state = UA_SUBSCRIPTIONSTATE_LATE; + UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */ + return; + } + } - /* Listen on open sockets (including the server) */ - fd_set fdset, errset; - UA_Int32 highestfd = setFDSet(layer, &fdset); - setFDSet(layer, &errset); - struct timeval tmptv = {0, timeout * 1000}; - if (select(highestfd+1, &fdset, NULL, &errset, &tmptv) < 0) { - UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, - "Socket select failed with %s", errno_str)); - // we will retry, so do not return bad - return UA_STATUSCODE_GOOD; + /* Prepare the response */ + UA_StatusCode retval = prepareNotificationMessage(server, sub, message, notifications); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING_SESSION(&server->config.logger, sub->session, + "Subscription %u | Could not prepare the notification message. " + "The subscription is late.", sub->subscriptionId); + /* If the retransmission queue is enabled a retransmission message is allocated */ + if(retransmission) + UA_free(retransmission); + sub->state = UA_SUBSCRIPTIONSTATE_LATE; + UA_Session_queuePublishReq(sub->session, pre, true); /* Re-enqueue */ + return; + } } - /* Accept new connections via the server sockets */ - for(UA_UInt16 i = 0; i < layer->serverSocketsSize; i++) { - if(!UA_fd_isset(layer->serverSockets[i], &fdset)) - continue; + /* <-- The point of no return --> */ - struct sockaddr_storage remote; - socklen_t remote_size = sizeof(remote); - SOCKET newsockfd = accept((SOCKET)layer->serverSockets[i], - (struct sockaddr*)&remote, &remote_size); -#ifdef _WIN32 - if(newsockfd == INVALID_SOCKET) -#else - if(newsockfd < 0) -#endif - continue; + /* Adjust the number of ready notifications */ + UA_assert(sub->readyNotifications >= notifications); + sub->readyNotifications -= notifications; - UA_LOG_TRACE(layer->logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | New TCP connection on server socket %i", - (int)newsockfd, layer->serverSockets[i]); + /* Set up the response */ + response->responseHeader.timestamp = UA_DateTime_now(); + response->subscriptionId = sub->subscriptionId; + response->moreNotifications = moreNotifications; + message->publishTime = response->responseHeader.timestamp; + + /* Set sequence number to message. Started at 1 which is given + * during creating a new subscription. The 1 is required for + * initial publish response with or without an monitored item. */ + message->sequenceNumber = sub->nextSequenceNumber; - ServerNetworkLayerTCP_add(layer, (UA_Int32)newsockfd, &remote); + if(notifications > 0) { + /* If the retransmission queue is enabled a retransmission message is allocated */ + if(retransmission) { + /* Put the notification message into the retransmission queue. This + * needs to be done here, so that the message itself is included in the + * available sequence numbers for acknowledgement. */ + retransmission->message = response->notificationMessage; + UA_Subscription_addRetransmissionMessage(server, sub, retransmission); + } + /* Only if a notification was created, the sequence number must be increased. + * For a keepalive the sequence number can be reused. */ + sub->nextSequenceNumber = UA_Subscription_nextSequenceNumber(sub->nextSequenceNumber); } - /* Read from established sockets */ - ConnectionEntry *e, *e_tmp; - UA_DateTime now = UA_DateTime_nowMonotonic(); - LIST_FOREACH_SAFE(e, &layer->connections, pointers, e_tmp) { - if ((e->connection.state == UA_CONNECTION_OPENING) && - (now > (e->connection.openingDate + (NOHELLOTIMEOUT * UA_DATETIME_MSEC)))){ - UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | Closed by the server (no Hello Message)", - e->connection.sockfd); - LIST_REMOVE(e, pointers); - CLOSESOCKET(e->connection.sockfd); - UA_Server_removeConnection(server, &e->connection); - continue; + /* Get the available sequence numbers from the retransmission queue */ + size_t available = sub->retransmissionQueueSize; + UA_STACKARRAY(UA_UInt32, seqNumbers, available); + if(available > 0) { + response->availableSequenceNumbers = seqNumbers; + response->availableSequenceNumbersSize = available; + size_t i = 0; + UA_NotificationMessageEntry *nme; + TAILQ_FOREACH(nme, &sub->retransmissionQueue, listEntry) { + response->availableSequenceNumbers[i] = nme->message.sequenceNumber; + ++i; } + } - if(!UA_fd_isset(e->connection.sockfd, &errset) && - !UA_fd_isset(e->connection.sockfd, &fdset)) - continue; + /* Send the response */ + UA_LOG_DEBUG_SESSION(&server->config.logger, sub->session, + "Subscription %u | Sending out a publish response " + "with %u notifications", sub->subscriptionId, + (UA_UInt32)notifications); + UA_SecureChannel_sendSymmetricMessage(sub->session->header.channel, pre->requestId, + UA_MESSAGETYPE_MSG, response, + &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); - UA_LOG_TRACE(layer->logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | Activity on the socket", - e->connection.sockfd); + /* Reset subscription state to normal */ + sub->state = UA_SUBSCRIPTIONSTATE_NORMAL; + sub->currentKeepAliveCount = 0; - UA_ByteString buf = UA_BYTESTRING_NULL; - UA_StatusCode retval = connection_recv(&e->connection, &buf, 0); + /* Free the response */ + UA_Array_delete(response->results, response->resultsSize, &UA_TYPES[UA_TYPES_UINT32]); + UA_free(pre); /* No need for UA_PublishResponse_deleteMembers */ - if(retval == UA_STATUSCODE_GOOD) { - /* Process packets */ - UA_Server_processBinaryMessage(server, &e->connection, &buf); - connection_releaserecvbuffer(&e->connection, &buf); - } else if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED) { - /* The socket is shutdown but not closed */ - UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, - "Connection %i | Closed", - e->connection.sockfd); - LIST_REMOVE(e, pointers); - CLOSESOCKET(e->connection.sockfd); - UA_Server_removeConnection(server, &e->connection); - } - } - return UA_STATUSCODE_GOOD; + /* Repeat sending responses if there are more notifications to send */ + if(moreNotifications) + UA_Subscription_publish(server, sub); } -static void -ServerNetworkLayerTCP_stop(UA_ServerNetworkLayer *nl, UA_Server *server) { - ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle; - UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, - "Shutting down the TCP network layer"); +UA_Boolean +UA_Subscription_reachedPublishReqLimit(UA_Server *server, UA_Session *session) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Reached number of publish request limit"); - /* Close the server sockets */ - for(UA_UInt16 i = 0; i < layer->serverSocketsSize; i++) { - shutdown((SOCKET)layer->serverSockets[i], 2); - CLOSESOCKET(layer->serverSockets[i]); + /* Dequeue a response */ + UA_PublishResponseEntry *pre = UA_Session_dequeuePublishReq(session); + + /* Cannot publish without a response */ + if(!pre) { + UA_LOG_FATAL_SESSION(&server->config.logger, session, "No publish requests available"); + return false; } - layer->serverSocketsSize = 0; - /* Close open connections */ - ConnectionEntry *e; - LIST_FOREACH(e, &layer->connections, pointers) - ServerNetworkLayerTCP_close(&e->connection); + /* <-- The point of no return --> */ - /* Run recv on client sockets. This picks up the closed sockets and frees - * the connection. */ - ServerNetworkLayerTCP_listen(nl, server, 0); + UA_PublishResponse *response = &pre->response; + UA_NotificationMessage *message = &response->notificationMessage; -#ifdef _WIN32 - WSACleanup(); -#endif -} + /* Set up the response. Note that this response has no related subscription id */ + response->responseHeader.timestamp = UA_DateTime_now(); + response->responseHeader.serviceResult = UA_STATUSCODE_BADTOOMANYPUBLISHREQUESTS; + response->subscriptionId = 0; + response->moreNotifications = false; + message->publishTime = response->responseHeader.timestamp; + message->sequenceNumber = 0; + response->availableSequenceNumbersSize = 0; -/* run only when the server is stopped */ -static void -ServerNetworkLayerTCP_deleteMembers(UA_ServerNetworkLayer *nl) { - ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle; - UA_String_deleteMembers(&nl->discoveryUrl); + /* Send the response */ + UA_LOG_DEBUG_SESSION(&server->config.logger, session, + "Sending out a publish response triggered by too many publish requests"); + UA_SecureChannel_sendSymmetricMessage(session->header.channel, pre->requestId, + UA_MESSAGETYPE_MSG, response, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); - /* Hard-close and remove remaining connections. The server is no longer - * running. So this is safe. */ - ConnectionEntry *e, *e_tmp; - LIST_FOREACH_SAFE(e, &layer->connections, pointers, e_tmp) { - LIST_REMOVE(e, pointers); - CLOSESOCKET(e->connection.sockfd); - UA_free(e); - } + /* Free the response */ + UA_Array_delete(response->results, response->resultsSize, &UA_TYPES[UA_TYPES_UINT32]); + UA_free(pre); /* no need for UA_PublishResponse_deleteMembers */ - /* Free the layer */ - UA_free(layer); + return true; } -UA_ServerNetworkLayer -UA_ServerNetworkLayerTCP(UA_ConnectionConfig conf, UA_UInt16 port, UA_Logger logger) { - UA_ServerNetworkLayer nl; - memset(&nl, 0, sizeof(UA_ServerNetworkLayer)); - nl.start = ServerNetworkLayerTCP_start; - nl.listen = ServerNetworkLayerTCP_listen; - nl.stop = ServerNetworkLayerTCP_stop; - nl.deleteMembers = ServerNetworkLayerTCP_deleteMembers; +UA_StatusCode +Subscription_registerPublishCallback(UA_Server *server, UA_Subscription *sub) { + UA_LOG_DEBUG_SESSION(&server->config.logger, sub->session, + "Subscription %u | Register subscription " + "publishing callback", sub->subscriptionId); - ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP*) - UA_calloc(1,sizeof(ServerNetworkLayerTCP)); - if(!layer) - return nl; - nl.handle = layer; + if(sub->publishCallbackIsRegistered) + return UA_STATUSCODE_GOOD; - layer->logger = (logger != NULL ? logger : UA_Log_Stdout); - layer->conf = conf; - layer->port = port; + UA_StatusCode retval = + UA_Server_addRepeatedCallback(server, (UA_ServerCallback)publishCallback, + sub, (UA_UInt32)sub->publishingInterval, &sub->publishCallbackId); + if(retval != UA_STATUSCODE_GOOD) + return retval; - return nl; + sub->publishCallbackIsRegistered = true; + return UA_STATUSCODE_GOOD; } -/***************************/ -/* Client NetworkLayer TCP */ -/***************************/ +void +Subscription_unregisterPublishCallback(UA_Server *server, UA_Subscription *sub) { + UA_LOG_DEBUG_SESSION(&server->config.logger, sub->session, "Subscription %u | " + "Unregister subscription publishing callback", sub->subscriptionId); -static void -ClientNetworkLayerTCP_close(UA_Connection *connection) { - if (connection->state == UA_CONNECTION_CLOSED) + if(!sub->publishCallbackIsRegistered) return; - shutdown((SOCKET)connection->sockfd, 2); - CLOSESOCKET(connection->sockfd); - connection->state = UA_CONNECTION_CLOSED; + + UA_Server_removeRepeatedCallback(server, sub->publishCallbackId); + sub->publishCallbackIsRegistered = false; } -UA_Connection -UA_ClientConnectionTCP(UA_ConnectionConfig conf, - const char *endpointUrl, const UA_UInt32 timeout, - UA_Logger logger) { -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - wVersionRequested = MAKEWORD(2, 2); - WSAStartup(wVersionRequested, &wsaData); -#endif +/* When the session has publish requests stored but the last subscription is + * deleted... Send out empty responses */ +void +UA_Subscription_answerPublishRequestsNoSubscription(UA_Server *server, UA_Session *session) { + /* No session or there are remaining subscriptions */ + if(!session || LIST_FIRST(&session->serverSubscriptions)) + return; - if(logger == NULL) { - logger = UA_Log_Stdout; + /* Send a response for every queued request */ + UA_PublishResponseEntry *pre; + while((pre = UA_Session_dequeuePublishReq(session))) { + UA_PublishResponse *response = &pre->response; + response->responseHeader.serviceResult = UA_STATUSCODE_BADNOSUBSCRIPTION; + response->responseHeader.timestamp = UA_DateTime_now(); + UA_SecureChannel_sendSymmetricMessage(session->header.channel, pre->requestId, UA_MESSAGETYPE_MSG, + response, &UA_TYPES[UA_TYPES_PUBLISHRESPONSE]); + UA_PublishResponse_deleteMembers(response); + UA_free(pre); } +} - UA_Connection connection; - memset(&connection, 0, sizeof(UA_Connection)); - connection.state = UA_CONNECTION_CLOSED; - connection.localConf = conf; - connection.remoteConf = conf; - connection.send = connection_write; - connection.recv = connection_recv; - connection.close = ClientNetworkLayerTCP_close; - connection.free = NULL; - connection.getSendBuffer = connection_getsendbuffer; - connection.releaseSendBuffer = connection_releasesendbuffer; - connection.releaseRecvBuffer = connection_releaserecvbuffer; +#endif /* UA_ENABLE_SUBSCRIPTIONS */ - UA_String endpointUrlString = UA_STRING((char*)(uintptr_t)endpointUrl); - UA_String hostnameString = UA_STRING_NULL; - UA_String pathString = UA_STRING_NULL; - UA_UInt16 port = 0; - char hostname[512]; +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_subscription_monitoreditem.c" ***********************************/ - UA_StatusCode parse_retval = - UA_parseEndpointUrl(&endpointUrlString, &hostnameString, - &port, &pathString); - if(parse_retval != UA_STATUSCODE_GOOD || hostnameString.length > 511) { - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "Server url is invalid: %s", endpointUrl); - return connection; +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2017-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH + * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2018 (c) Fabian Arndt, Root-Core + */ + + +#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ + +/****************/ +/* Notification */ +/****************/ + +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + +static const UA_NodeId overflowEventType = + {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_EVENTQUEUEOVERFLOWEVENTTYPE}}; +static const UA_NodeId simpleOverflowEventType = + {0, UA_NODEIDTYPE_NUMERIC, {UA_NS0ID_SIMPLEOVERFLOWEVENTTYPE}}; + +static UA_Boolean +UA_Notification_isOverflowEvent(UA_Server *server, UA_Notification *n) { + UA_MonitoredItem *mon = n->mon; + if(mon->attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER) + return false; + + UA_EventFieldList *efl = &n->data.event.fields; + if(efl->eventFieldsSize >= 1 && + efl->eventFields[0].type == &UA_TYPES[UA_TYPES_NODEID] && + isNodeInTree(server->nsCtx, (const UA_NodeId *)efl->eventFields[0].data, + &overflowEventType, &subtypeId, 1)) { + return true; } - memcpy(hostname, hostnameString.data, hostnameString.length); - hostname[hostnameString.length] = 0; - if(port == 0) { - port = 4840; - UA_LOG_INFO(logger, UA_LOGCATEGORY_NETWORK, - "No port defined, using default port %d", port); + return false; +} + +/* The specification states in Part 4 5.12.1.5 that an EventQueueOverflowEvent + * "is generated when the first Event has to be discarded [...] without + * discarding any other event". So only generate one for all deleted events. */ +static UA_StatusCode +createEventOverflowNotification(UA_Server *server, UA_Subscription *sub, + UA_MonitoredItem *mon, UA_Notification *indicator) { + /* Avoid two redundant overflow events in a row */ + if(UA_Notification_isOverflowEvent(server, indicator)) + return UA_STATUSCODE_GOOD; + + /* A notification is inserted into the queue which includes only the + * NodeId of the overflowEventType. It is up to the client to check for + * possible overflows. */ + + /* Allocate the notification */ + UA_Notification *overflowNotification = (UA_Notification *) + UA_malloc(sizeof(UA_Notification)); + if(!overflowNotification) + return UA_STATUSCODE_BADOUTOFMEMORY;; + + /* Set the notification fields */ + overflowNotification->mon = mon; + UA_EventFieldList_init(&overflowNotification->data.event.fields); + overflowNotification->data.event.fields.eventFields = UA_Variant_new(); + if(!overflowNotification->data.event.fields.eventFields) { + UA_free(overflowNotification); + return UA_STATUSCODE_BADOUTOFMEMORY;; + } + overflowNotification->data.event.fields.eventFieldsSize = 1; + UA_StatusCode retval = + UA_Variant_setScalarCopy(overflowNotification->data.event.fields.eventFields, + &simpleOverflowEventType, &UA_TYPES[UA_TYPES_NODEID]); + if(retval != UA_STATUSCODE_GOOD) { + UA_EventFieldList_deleteMembers(&overflowNotification->data.event.fields); + UA_free(overflowNotification); + return retval; } - struct addrinfo hints, *server; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; -#if defined(UA_FREERTOS) - hints.ai_protocol = IPPROTO_TCP; + /* Insert before the "indicator notification". This is either first in the + * queue (if the oldest notification was removed) or before the new event + * that remains the last element of the queue. */ + TAILQ_INSERT_BEFORE(indicator, overflowNotification, listEntry); + ++mon->eventOverflows; + ++mon->queueSize; + + TAILQ_NEXT(overflowNotification, globalEntry) = UA_SUBSCRIPTION_QUEUE_SENTINEL; + if(mon->monitoringMode == UA_MONITORINGMODE_REPORTING) { + TAILQ_INSERT_BEFORE(indicator, overflowNotification, globalEntry); + ++sub->notificationQueueSize; + ++sub->eventNotifications; + } + return UA_STATUSCODE_GOOD; +} + #endif - char portStr[6]; -#ifndef _MSC_VER - snprintf(portStr, 6, "%d", port); -#else - _snprintf_s(portStr, 6, _TRUNCATE, "%d", port); + +/* !!! The enqueue and dequeue operations need to match the reporting + * disable/enable logic in Operation_SetMonitoringMode !!! */ + +void +UA_Notification_enqueue(UA_Server *server, UA_Subscription *sub, + UA_MonitoredItem *mon, UA_Notification *n) { + /* Add to the MonitoredItem */ + TAILQ_INSERT_TAIL(&mon->queue, n, listEntry); + ++mon->queueSize; + +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER && + UA_Notification_isOverflowEvent(server, n)) + ++mon->eventOverflows; #endif - int error = getaddrinfo(hostname, portStr, &hints, &server); - if(error != 0 || !server) { -#if !defined(UA_FREERTOS) - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "DNS lookup of %s failed with error %s", - hostname, gai_strerror(error)); -#else - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "DNS lookup of %s failed with error", - hostname); + /* Add to the subscription if reporting is enabled */ + TAILQ_NEXT(n, globalEntry) = UA_SUBSCRIPTION_QUEUE_SENTINEL; + if(mon->monitoringMode == UA_MONITORINGMODE_REPORTING) { + TAILQ_INSERT_TAIL(&sub->notificationQueue, n, globalEntry); + ++sub->notificationQueueSize; +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + ++sub->eventNotifications; + } else #endif - return connection; + { + ++sub->dataChangeNotifications; + } } - UA_Boolean connected = UA_FALSE; - UA_DateTime dtTimeout = timeout * UA_DATETIME_MSEC; - UA_DateTime connStart = UA_DateTime_nowMonotonic(); - SOCKET clientsockfd; + /* Ensure enough space is available in the MonitoredItem. Do this only after + * adding the new Notification. */ + UA_MonitoredItem_ensureQueueSpace(server, mon); +} - /* On linux connect may immediately return with ECONNREFUSED but we still - * want to try to connect. So use a loop and retry until timeout is - * reached. */ - do { - /* Get a socket */ - clientsockfd = socket(server->ai_family, - server->ai_socktype, - server->ai_protocol); - #ifdef _WIN32 - if(clientsockfd == INVALID_SOCKET) { - #else - if(clientsockfd < 0) { - #endif - UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "Could not create client socket: %s", errno_str)); - freeaddrinfo(server); - return connection; +void +UA_Notification_dequeue(UA_Server *server, UA_Notification *n) { + UA_MonitoredItem *mon = n->mon; + UA_Subscription *sub = mon->subscription; + + /* Remove from the MonitoredItem queue */ +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER && + UA_Notification_isOverflowEvent(server, n)) + --mon->eventOverflows; +#endif + TAILQ_REMOVE(&mon->queue, n, listEntry); + --mon->queueSize; + + /* Remove from the subscription's queue */ + if(TAILQ_NEXT(n, globalEntry) != UA_SUBSCRIPTION_QUEUE_SENTINEL) { +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + --sub->eventNotifications; + } else +#endif + { + --sub->dataChangeNotifications; } + TAILQ_REMOVE(&sub->notificationQueue, n, globalEntry); + --sub->notificationQueueSize; + } +} - connection.state = UA_CONNECTION_OPENING; +void +UA_Notification_delete(UA_Notification *n) { +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + UA_MonitoredItem *mon = n->mon; + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + UA_EventFieldList_deleteMembers(&n->data.event.fields); + /* EventFilterResult currently isn't being used + * UA_EventFilterResult_delete(notification->data.event->result); */ + } else +#endif + { + UA_DataValue_deleteMembers(&n->data.value); + } + UA_free(n); +} - /* Connect to the server */ - connection.sockfd = (UA_Int32) clientsockfd; /* cast for win32 */ +/*****************/ +/* MonitoredItem */ +/*****************/ - /* Non blocking connect to be able to timeout */ - if (socket_set_nonblocking(clientsockfd) != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "Could not set the client socket to nonblocking"); - ClientNetworkLayerTCP_close(&connection); - freeaddrinfo(server); - return connection; - } +void +UA_MonitoredItem_init(UA_MonitoredItem *mon, UA_Subscription *sub) { + memset(mon, 0, sizeof(UA_MonitoredItem)); + mon->subscription = sub; + TAILQ_INIT(&mon->queue); +} - /* Non blocking connect */ - error = connect(clientsockfd, server->ai_addr, WIN32_INT server->ai_addrlen); +void +UA_MonitoredItem_delete(UA_Server *server, UA_MonitoredItem *monitoredItem) { + /* Remove the sampling callback */ + UA_MonitoredItem_unregisterSampleCallback(server, monitoredItem); - if ((error == -1) && (errno__ != ERR_CONNECTION_PROGRESS)) { - ClientNetworkLayerTCP_close(&connection); - UA_LOG_SOCKET_ERRNO_WRAP( - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "Connection to %s failed with error: %s", - endpointUrl, errno_str)); - freeaddrinfo(server); - return connection; + /* Remove the queued notifications if attached to a subscription (not a + * local MonitoredItem) */ + if(monitoredItem->subscription) { + UA_Notification *notification, *notification_tmp; + TAILQ_FOREACH_SAFE(notification, &monitoredItem->queue, + listEntry, notification_tmp) { + /* Remove the item from the queues and free the memory */ + UA_Notification_dequeue(server, notification); + UA_Notification_delete(notification); } + } - /* Use select to wait and check if connected */ - if (error == -1 && (errno__ == ERR_CONNECTION_PROGRESS)) { - /* connection in progress. Wait until connected using select */ - UA_DateTime timeSinceStart = UA_DateTime_nowMonotonic() - connStart; - if(timeSinceStart > dtTimeout) - break; +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(monitoredItem->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + /* Remove the monitored item from the node queue */ + UA_Server_editNode(server, NULL, &monitoredItem->monitoredNodeId, + UA_MonitoredItem_removeNodeEventCallback, monitoredItem); + UA_EventFilter_clear(&monitoredItem->filter.eventFilter); + } else +#endif + { + /* UA_DataChangeFilter does not hold dynamic content we need to free */ + /* UA_DataChangeFilter_clear(&monitoredItem->filter.dataChangeFilter); */ + } - fd_set fdset; - FD_ZERO(&fdset); - UA_fd_set(clientsockfd, &fdset); - UA_DateTime timeout_usec = (dtTimeout - timeSinceStart) / UA_DATETIME_USEC; - struct timeval tmptv = {(long int) (timeout_usec / 1000000), - (long int) (timeout_usec % 1000000)}; + /* Deregister MonitoredItem in userland */ + if(server->config.monitoredItemRegisterCallback && monitoredItem->registered) { + /* Get the session context. Local MonitoredItems don't have a subscription. */ + UA_Session *session = NULL; + if(monitoredItem->subscription) + session = monitoredItem->subscription->session; + if(!session) + session = &server->adminSession; - int resultsize = select((UA_Int32)(clientsockfd + 1), NULL, &fdset, NULL, &tmptv); + /* Get the node context */ + void *targetContext = NULL; + UA_Server_getNodeContext(server, monitoredItem->monitoredNodeId, &targetContext); - if(resultsize == 1) { -#ifdef _WIN32 - /* Windows does not have any getsockopt equivalent and it is not - * needed there */ - connected = true; - break; -#else - OPTVAL_TYPE so_error; - socklen_t len = sizeof so_error; + /* Deregister */ + server->config.monitoredItemRegisterCallback(server, &session->sessionId, + session->sessionHandle, + &monitoredItem->monitoredNodeId, + targetContext, monitoredItem->attributeId, true); + } - int ret = getsockopt(clientsockfd, SOL_SOCKET, SO_ERROR, &so_error, &len); + /* Remove the monitored item */ + if(monitoredItem->listEntry.le_prev != NULL) + LIST_REMOVE(monitoredItem, listEntry); + UA_String_deleteMembers(&monitoredItem->indexRange); + UA_ByteString_deleteMembers(&monitoredItem->lastSampledValue); + UA_Variant_deleteMembers(&monitoredItem->lastValue); + UA_NodeId_deleteMembers(&monitoredItem->monitoredNodeId); - if (ret != 0 || so_error != 0) { - /* on connection refused we should still try to connect */ - /* connection refused happens on localhost or local ip without timeout */ - if (so_error != ECONNREFUSED) { - ClientNetworkLayerTCP_close(&connection); - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "Connection to %s failed with error: %s", - endpointUrl, strerror(ret == 0 ? so_error : errno__)); - freeaddrinfo(server); - return connection; - } - /* wait until we try a again. Do not make this too small, otherwise the - * timeout is somehow wrong */ - UA_sleep_ms(100); - } else { - connected = true; - break; - } + /* No actual callback, just remove the structure */ + monitoredItem->delayedFreePointers.callback = NULL; + UA_WorkQueue_enqueueDelayed(&server->workQueue, &monitoredItem->delayedFreePointers); +} + +UA_StatusCode +UA_MonitoredItem_ensureQueueSpace(UA_Server *server, UA_MonitoredItem *mon) { + /* Assert: The eventoverflow are counted in the queue size; There can be + * only one eventoverflow more than normal entries */ + UA_assert(mon->queueSize >= mon->eventOverflows); + UA_assert(mon->eventOverflows <= mon->queueSize - mon->eventOverflows + 1); + + /* Nothing to do */ + if(mon->queueSize - mon->eventOverflows <= mon->maxQueueSize) + return UA_STATUSCODE_GOOD; + +#ifdef __clang_analyzer__ + return UA_STATUSCODE_GOOD; +#endif + + /* Remove notifications until the queue size is reached */ + UA_Subscription *sub = mon->subscription; + while(mon->queueSize - mon->eventOverflows > mon->maxQueueSize) { + /* At least two notifications that are not eventOverflows in the queue */ + UA_assert(mon->queueSize - mon->eventOverflows >= 2); + + /* Select the next notification to delete. Skip over overflow events. */ + UA_Notification *del = NULL; + if(mon->discardOldest) { + /* Remove the oldest */ + del = TAILQ_FIRST(&mon->queue); +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + while(UA_Notification_isOverflowEvent(server, del)) + del = TAILQ_NEXT(del, listEntry); /* skip overflow events */ #endif - } } else { - connected = true; - break; + /* Remove the second newest (to keep the up-to-date notification). + * The last entry is not an OverflowEvent -- we just added it. */ + del = TAILQ_LAST(&mon->queue, NotificationQueue); + del = TAILQ_PREV(del, NotificationQueue, listEntry); +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + while(UA_Notification_isOverflowEvent(server, del)) + del = TAILQ_PREV(del, NotificationQueue, listEntry); /* skip overflow events */ +#endif } - ClientNetworkLayerTCP_close(&connection); - } while ((UA_DateTime_nowMonotonic() - connStart) < dtTimeout); - - freeaddrinfo(server); + UA_assert(del); /* There must have been one entry that can be deleted */ + + /* If reporting is activated (entries are also in the subscriptions + * global queue): Move the entry after del in the per-MonitoredItem + * queue right after del in the global queue. (It is already right after + * del in the per-MonitoredItem queue.) This is required so we don't + * starve MonitoredItems with a high sampling interval by always + * removing their first appearance in the gloal queue for the + * Subscription. */ + if(TAILQ_NEXT(del, globalEntry) != UA_SUBSCRIPTION_QUEUE_SENTINEL) { + UA_Notification *after_del = TAILQ_NEXT(del, listEntry); + UA_assert(after_del); /* There must be one remaining element after del */ + TAILQ_REMOVE(&sub->notificationQueue, after_del, globalEntry); + TAILQ_INSERT_AFTER(&sub->notificationQueue, del, after_del, globalEntry); + } - if(!connected) { - /* connection timeout */ - if (connection.state != UA_CONNECTION_CLOSED) - ClientNetworkLayerTCP_close(&connection); - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "Trying to connect to %s timed out", - endpointUrl); - return connection; + /* Delete the notification */ + UA_Notification_dequeue(server, del); + UA_Notification_delete(del); } + /* Get the element where the overflow shall be announced (infobits or + * overflowevent) */ + UA_Notification *indicator; + if(mon->discardOldest) + indicator = TAILQ_FIRST(&mon->queue); + else + indicator = TAILQ_LAST(&mon->queue, NotificationQueue); + UA_assert(indicator); - /* We are connected. Reset socket to blocking */ - if(socket_set_blocking(clientsockfd) != UA_STATUSCODE_GOOD) { - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "Could not set the client socket to blocking"); - ClientNetworkLayerTCP_close(&connection); - return connection; + /* Create an overflow notification */ +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) { + return createEventOverflowNotification(server, sub, mon, indicator); + } else +#endif + { + /* Set the infobits of a datachange notification */ + if(mon->maxQueueSize > 1) { + /* Add the infobits either to the newest or the new last entry */ + indicator->data.value.hasStatus = true; + indicator->data.value.status |= + (UA_STATUSCODE_INFOTYPE_DATAVALUE | UA_STATUSCODE_INFOBITS_OVERFLOW); + } } + return UA_STATUSCODE_GOOD; +} -#ifdef SO_NOSIGPIPE - int val = 1; - int sso_result = setsockopt(connection.sockfd, SOL_SOCKET, - SO_NOSIGPIPE, (void*)&val, sizeof(val)); - if(sso_result < 0) - UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, - "Couldn't set SO_NOSIGPIPE"); -#endif +UA_StatusCode +UA_MonitoredItem_registerSampleCallback(UA_Server *server, UA_MonitoredItem *mon) { + if(mon->sampleCallbackIsRegistered) + return UA_STATUSCODE_GOOD; - return connection; + /* Only DataChange MonitoredItems have a callback with a sampling interval */ + if(mon->attributeId == UA_ATTRIBUTEID_EVENTNOTIFIER) + return UA_STATUSCODE_GOOD; + + UA_StatusCode retval = + UA_Server_addRepeatedCallback(server, (UA_ServerCallback)UA_MonitoredItem_sampleCallback, + mon, mon->samplingInterval, &mon->sampleCallbackId); + if(retval == UA_STATUSCODE_GOOD) + mon->sampleCallbackIsRegistered = true; + return retval; +} + +void +UA_MonitoredItem_unregisterSampleCallback(UA_Server *server, UA_MonitoredItem *mon) { + if(!mon->sampleCallbackIsRegistered) + return; + UA_Server_removeRepeatedCallback(server, mon->sampleCallbackId); + mon->sampleCallbackIsRegistered = false; } -/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_clock.c" ***********************************/ +#endif /* UA_ENABLE_SUBSCRIPTIONS */ -/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. - * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. +/*********************************** amalgamated original file "/home/jvoe/open62541/src/server/ua_subscription_datachange.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Stefan Profanter, fortiss GmbH - * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2018 (c) Ari Breitkreuz, fortiss GmbH + * Copyright 2018 (c) Thomas Stalder, Blue Time Concept SA + * Copyright 2018 (c) Fabian Arndt, Root-Core */ -/* Enable POSIX features */ -#if !defined(_XOPEN_SOURCE) && !defined(_WRS_KERNEL) -# define _XOPEN_SOURCE 600 -#endif -#ifndef _DEFAULT_SOURCE -# define _DEFAULT_SOURCE -#endif -/* On older systems we need to define _BSD_SOURCE. - * _DEFAULT_SOURCE is an alias for that. */ -#ifndef _BSD_SOURCE -# define _BSD_SOURCE -#endif -#include <time.h> -#ifdef _WIN32 -/* Backup definition of SLIST_ENTRY on mingw winnt.h */ -# ifdef SLIST_ENTRY -# pragma push_macro("SLIST_ENTRY") -# undef SLIST_ENTRY -# define POP_SLIST_ENTRY -# endif -# include <windows.h> -/* restore definition */ -# ifdef POP_SLIST_ENTRY -# undef SLIST_ENTRY -# undef POP_SLIST_ENTRY -# pragma pop_macro("SLIST_ENTRY") -# endif -#else -# include <sys/time.h> +#ifdef UA_ENABLE_DA +#include <math.h> // fabs #endif -#if defined(__APPLE__) || defined(__MACH__) -# include <mach/clock.h> -# include <mach/mach.h> -#endif +#ifdef UA_ENABLE_SUBSCRIPTIONS /* conditional compilation */ + +#define UA_VALUENCODING_MAXSTACK 512 + +#define ABS_SUBTRACT_TYPE_INDEPENDENT(a,b) ((a)>(b)?(a)-(b):(b)-(a)) + +static UA_Boolean +outOfDeadBand(const void *data1, const void *data2, const size_t arrayPos, + const UA_DataType *type, const UA_Double deadbandValue) { + if(type == &UA_TYPES[UA_TYPES_BOOLEAN]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Boolean*)data1)[arrayPos], + ((const UA_Boolean*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_SBYTE]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_SByte*)data1)[arrayPos], + ((const UA_SByte*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_BYTE]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Byte*)data1)[arrayPos], + ((const UA_Byte*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_INT16]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int16*)data1)[arrayPos], + ((const UA_Int16*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_UINT16]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt16*)data1)[arrayPos], + ((const UA_UInt16*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_INT32]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int32*)data1)[arrayPos], + ((const UA_Int32*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_UINT32]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt32*)data1)[arrayPos], + ((const UA_UInt32*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_INT64]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int64*)data1)[arrayPos], + ((const UA_Int64*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_UINT64]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt64*)data1)[arrayPos], + ((const UA_UInt64*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_FLOAT]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Float*)data1)[arrayPos], + ((const UA_Float*)data2)[arrayPos]) <= deadbandValue) + return false; + } else if(type == &UA_TYPES[UA_TYPES_DOUBLE]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Double*)data1)[arrayPos], + ((const UA_Double*)data2)[arrayPos]) <= deadbandValue) + return false; + } + return true; +} + +#ifdef UA_ENABLE_DA +static UA_INLINE UA_Boolean +outOfPercentDeadBand(const void *data1, const void *data2, const size_t index, + const UA_DataType *type, const UA_Double deadbandValue, UA_Range* range) { + if(type == &UA_TYPES[UA_TYPES_SBYTE]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_SByte*)data1)[index], + ((const UA_SByte*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_SByte*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_BYTE]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Byte*)data1)[index], + ((const UA_Byte*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_Byte*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_INT16]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int16*)data1)[index], + ((const UA_Int16*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_Int16*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_UINT16]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt16*)data1)[index], + ((const UA_UInt16*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_UInt16*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_INT32]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int32*)data1)[index], + ((const UA_Int32*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_Int32*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_UINT32]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt32*)data1)[index], + ((const UA_UInt32*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_UInt32*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_INT64]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Int64*)data1)[index], + ((const UA_Int64*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_Int64*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_UINT64]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_UInt64*)data1)[index], + ((const UA_UInt64*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_UInt64*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_FLOAT]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Float*)data1)[index], + ((const UA_Float*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_Float*)data1 > range->high) + return false; + } else if(type == &UA_TYPES[UA_TYPES_DOUBLE]) { + if(ABS_SUBTRACT_TYPE_INDEPENDENT(((const UA_Double*)data1)[index], + ((const UA_Double*)data2)[index]) <= (deadbandValue/100.0)*(fabs(range->high - range->low)) || + *(const UA_Double*)data1 > range->high) + return false; + } + return true; +} +#endif /* UA_ENABLE_DA */ +static UA_INLINE UA_Boolean +updateNeededForFilteredValue(const UA_Variant *value, const UA_Variant *oldValue, + const UA_Double deadbandValue) { + if(value->arrayLength != oldValue->arrayLength) + return true; -#if defined(UA_FREERTOS) -#include <task.h> + if(value->type != oldValue->type) + return true; + + if (UA_Variant_isScalar(value)) { + return outOfDeadBand(value->data, oldValue->data, 0, value->type, deadbandValue); + } + for (size_t i = 0; i < value->arrayLength; ++i) { + if (outOfDeadBand(value->data, oldValue->data, i, value->type, deadbandValue)) + return true; + } + return false; +} + +#ifdef UA_ENABLE_DA +static UA_INLINE UA_Boolean +updateNeededForFilteredPercentValue(const UA_Variant *value, const UA_Variant *oldValue, + const UA_Double deadbandValue, UA_Range* euRange) { + if(value->arrayLength != oldValue->arrayLength) + return true; + + if(value->type != oldValue->type) + return true; + + if (UA_Variant_isScalar(value)) { + return outOfPercentDeadBand(value->data, oldValue->data, 0, value->type, deadbandValue, euRange); + } + for (size_t i = 0; i < value->arrayLength; ++i) { + if (outOfPercentDeadBand(value->data, oldValue->data, i, value->type, deadbandValue, euRange)) + return true; + } + return false; +} + +static UA_Boolean +updateNeededForStatusCode(const UA_DataValue *value, const UA_MonitoredItem *mon) { + if (UA_Variant_isScalar(&value->value)) { + if(value->status != mon->lastStatus) + return true; + } + return false; +} #endif -UA_DateTime UA_DateTime_now(void) { -#if defined(_WIN32) - /* Windows filetime has the same definition as UA_DateTime */ - FILETIME ft; - SYSTEMTIME st; - GetSystemTime(&st); - SystemTimeToFileTime(&st, &ft); - ULARGE_INTEGER ul; - ul.LowPart = ft.dwLowDateTime; - ul.HighPart = ft.dwHighDateTime; - return (UA_DateTime)ul.QuadPart; -#else - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * UA_DATETIME_SEC) + (tv.tv_usec * UA_DATETIME_USEC) + UA_DATETIME_UNIX_EPOCH; + +/* When a change is detected, encoding contains the heap-allocated binary + * encoded value. The default for changed is false. */ +static UA_StatusCode +detectValueChangeWithFilter(UA_Server *server, UA_MonitoredItem *mon, UA_DataValue *value, + UA_ByteString *encoding, UA_Boolean *changed) { + if(UA_DataType_isNumeric(value->value.type) && + (mon->filter.dataChangeFilter.trigger == UA_DATACHANGETRIGGER_STATUSVALUE || + mon->filter.dataChangeFilter.trigger == UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP)) { + if(mon->filter.dataChangeFilter.deadbandType == UA_DEADBANDTYPE_ABSOLUTE) { + if(!updateNeededForFilteredValue(&value->value, &mon->lastValue, + mon->filter.dataChangeFilter.deadbandValue)) + return UA_STATUSCODE_GOOD; + } +#ifdef UA_ENABLE_DA + else if(mon->filter.dataChangeFilter.deadbandType == UA_DEADBANDTYPE_PERCENT) { + UA_QualifiedName qn = UA_QUALIFIEDNAME(0, "EURange"); + UA_BrowsePathResult bpr = UA_Server_browseSimplifiedBrowsePath(server, mon->monitoredNodeId, 1, &qn); + if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) { //if branch is not entried, property has been found + UA_BrowsePathResult_deleteMembers(&bpr); + return UA_STATUSCODE_GOOD; + } + const UA_VariableNode* node = + (const UA_VariableNode*) UA_Nodestore_getNode(server->nsCtx, &bpr.targets->targetId.nodeId); + UA_Range* euRange = (UA_Range*) node->value.data.value.value.data; + if(!updateNeededForFilteredPercentValue(&value->value, &mon->lastValue, + mon->filter.dataChangeFilter.deadbandValue, euRange)) { + if(!updateNeededForStatusCode(value, mon)) //when same value, but different status code is written + return UA_STATUSCODE_GOOD; + } + } #endif + } + + /* Stack-allocate some memory for the value encoding. We might heap-allocate + * more memory if needed. This is just enough for scalars and small + * structures. */ + UA_STACKARRAY(UA_Byte, stackValueEncoding, UA_VALUENCODING_MAXSTACK); + UA_ByteString valueEncoding; + valueEncoding.data = stackValueEncoding; + valueEncoding.length = UA_VALUENCODING_MAXSTACK; + + /* Encode the value */ + UA_Byte *bufPos = valueEncoding.data; + const UA_Byte *bufEnd = &valueEncoding.data[valueEncoding.length]; + UA_StatusCode retval = UA_encodeBinary(value, &UA_TYPES[UA_TYPES_DATAVALUE], + &bufPos, &bufEnd, NULL, NULL); + if(retval == UA_STATUSCODE_BADENCODINGERROR) { + size_t binsize = UA_calcSizeBinary(value, &UA_TYPES[UA_TYPES_DATAVALUE]); + if(binsize == 0) + return UA_STATUSCODE_BADENCODINGERROR; + + if(binsize > UA_VALUENCODING_MAXSTACK) { + retval = UA_ByteString_allocBuffer(&valueEncoding, binsize); + if(retval == UA_STATUSCODE_GOOD) { + bufPos = valueEncoding.data; + bufEnd = &valueEncoding.data[valueEncoding.length]; + retval = UA_encodeBinary(value, &UA_TYPES[UA_TYPES_DATAVALUE], + &bufPos, &bufEnd, NULL, NULL); + } + } + } + if(retval != UA_STATUSCODE_GOOD) { + if(valueEncoding.data != stackValueEncoding) + UA_ByteString_deleteMembers(&valueEncoding); + return retval; + } + + /* Has the value changed? */ + valueEncoding.length = (uintptr_t)bufPos - (uintptr_t)valueEncoding.data; + *changed = (!mon->lastSampledValue.data || + !UA_String_equal(&valueEncoding, &mon->lastSampledValue)); + + /* No change */ + if(!(*changed)) { + if(valueEncoding.data != stackValueEncoding) + UA_ByteString_deleteMembers(&valueEncoding); + return UA_STATUSCODE_GOOD; + } + + /* Change detected. Copy encoding on the heap if necessary. */ + if(valueEncoding.data == stackValueEncoding) + return UA_ByteString_copy(&valueEncoding, encoding); + + *encoding = valueEncoding; + return UA_STATUSCODE_GOOD; } -/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */ -UA_Int64 UA_DateTime_localTimeUtcOffset(void) { - time_t gmt, rawtime = time(NULL); +/* Has this sample changed from the last one? The method may allocate additional + * space for the encoding buffer. Detect the change in encoding->data. */ +static UA_StatusCode +detectValueChange(UA_Server *server, UA_MonitoredItem *mon, + UA_DataValue value, UA_ByteString *encoding, UA_Boolean *changed) { + /* Apply Filter */ + if(mon->filter.dataChangeFilter.trigger == UA_DATACHANGETRIGGER_STATUS) + value.hasValue = false; -#ifdef _WIN32 - struct tm ptm; - gmtime_s(&ptm, &rawtime); - // Request that mktime() looksup dst in timezone database - ptm.tm_isdst = -1; - gmt = mktime(&ptm); -#else - struct tm *ptm; - struct tm gbuf; - ptm = gmtime_r(&rawtime, &gbuf); - // Request that mktime() looksup dst in timezone database - ptm->tm_isdst = -1; - gmt = mktime(ptm); -#endif + value.hasServerTimestamp = false; + value.hasServerPicoseconds = false; + if(mon->filter.dataChangeFilter.trigger < UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP) { + value.hasSourceTimestamp = false; + value.hasSourcePicoseconds = false; + } - return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC); + /* Detect the value change */ + return detectValueChangeWithFilter(server, mon, &value, encoding, changed); } -UA_DateTime UA_DateTime_nowMonotonic(void) { -#if defined(_WIN32) - LARGE_INTEGER freq, ticks; - QueryPerformanceFrequency(&freq); - QueryPerformanceCounter(&ticks); - UA_Double ticks2dt = UA_DATETIME_SEC / (UA_Double)freq.QuadPart; - return (UA_DateTime)(ticks.QuadPart * ticks2dt); -#elif defined(__APPLE__) || defined(__MACH__) - /* OS X does not have clock_gettime, use clock_get_time */ - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - return (mts.tv_sec * UA_DATETIME_SEC) + (mts.tv_nsec / 100); -#elif !defined(CLOCK_MONOTONIC_RAW) -# if defined(UA_FREERTOS) - portTickType TaskTime = xTaskGetTickCount(); - UA_DateTimeStruct UATime; - UATime.milliSec = (UA_UInt16) TaskTime; - struct timespec ts; - ts.tv_sec = UATime.milliSec/1000; - ts.tv_nsec = (UATime.milliSec % 1000)* 1000000; - return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100); -# else - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100); -# endif -#else - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC_RAW, &ts); - return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100); +/* movedValue returns whether the sample was moved to the notification. The + * default is false. */ +static UA_StatusCode +sampleCallbackWithValue(UA_Server *server, UA_Session *session, + UA_Subscription *sub, UA_MonitoredItem *mon, + UA_DataValue *value, UA_Boolean *movedValue) { + UA_assert(mon->attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER); + + /* Contains heap-allocated binary encoding of the value if a change was detected */ + UA_ByteString binValueEncoding = UA_BYTESTRING_NULL; + + /* Has the value changed? Allocates memory in binValueEncoding if necessary. + * value is edited internally so we make a shallow copy. */ + UA_Boolean changed = false; + UA_StatusCode retval = detectValueChange(server, mon, *value, &binValueEncoding, &changed); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING_SESSION(&server->config.logger, session, "Subscription %u | " + "MonitoredItem %i | Value change detection failed with StatusCode %s", + sub ? sub->subscriptionId : 0, mon->monitoredItemId, + UA_StatusCode_name(retval)); + return retval; + } + if(!changed) { + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Subscription %u | " + "MonitoredItem %i | The value has not changed", + sub ? sub->subscriptionId : 0, mon->monitoredItemId); + return UA_STATUSCODE_GOOD; + } + + /* The MonitoredItem is attached to a subscription (not server-local). + * Prepare a notification and enqueue it. */ + if(sub) { + /* Allocate a new notification */ + UA_Notification *newNotification = (UA_Notification *)UA_malloc(sizeof(UA_Notification)); + if(!newNotification) { + UA_ByteString_deleteMembers(&binValueEncoding); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + + if(value->value.storageType == UA_VARIANT_DATA) { + newNotification->data.value = *value; /* Move the value to the notification */ + *movedValue = true; + } else { /* => (value->value.storageType == UA_VARIANT_DATA_NODELETE) */ + retval = UA_DataValue_copy(value, &newNotification->data.value); + if(retval != UA_STATUSCODE_GOOD) { + UA_ByteString_deleteMembers(&binValueEncoding); + UA_free(newNotification); + return retval; + } + } + + /* <-- Point of no return --> */ + + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Subscription %u | " + "MonitoredItem %i | Enqueue a new notification", + sub ? sub->subscriptionId : 0, mon->monitoredItemId); + + newNotification->mon = mon; + UA_Notification_enqueue(server, sub, mon, newNotification); + } + + /* Store the encoding for comparison */ + UA_ByteString_deleteMembers(&mon->lastSampledValue); + mon->lastSampledValue = binValueEncoding; + + /* Store the value for filter comparison (we don't want to decode + * lastSampledValue in every iteration). Don't test the return code here. If + * this fails, lastValue is empty and a notification will be forced for the + * next deadband comparison. */ + if((mon->filter.dataChangeFilter.deadbandType == UA_DEADBANDTYPE_NONE || + mon->filter.dataChangeFilter.deadbandType == UA_DEADBANDTYPE_ABSOLUTE || + mon->filter.dataChangeFilter.deadbandType == UA_DEADBANDTYPE_PERCENT) && + (mon->filter.dataChangeFilter.trigger == UA_DATACHANGETRIGGER_STATUS || + mon->filter.dataChangeFilter.trigger == UA_DATACHANGETRIGGER_STATUSVALUE || + mon->filter.dataChangeFilter.trigger == UA_DATACHANGETRIGGER_STATUSVALUETIMESTAMP)) { + UA_Variant_deleteMembers(&mon->lastValue); + UA_Variant_copy(&value->value, &mon->lastValue); +#ifdef UA_ENABLE_DA + UA_StatusCode_deleteMembers(&mon->lastStatus); + UA_StatusCode_copy(&value->status, &mon->lastStatus); #endif + } + + /* Call the local callback if the MonitoredItem is not attached to a + * subscription. Do this at the very end. Because the callback might delete + * the subscription. */ + if(!sub) { + UA_LocalMonitoredItem *localMon = (UA_LocalMonitoredItem*) mon; + void *nodeContext = NULL; + UA_Server_getNodeContext(server, mon->monitoredNodeId, &nodeContext); + localMon->callback.dataChangeCallback(server, mon->monitoredItemId, + localMon->context, + &mon->monitoredNodeId, + nodeContext, mon->attributeId, + value); + } + + return UA_STATUSCODE_GOOD; } +void +UA_MonitoredItem_sampleCallback(UA_Server *server, UA_MonitoredItem *monitoredItem) { + UA_Subscription *sub = monitoredItem->subscription; + UA_Session *session = &server->adminSession; + if(sub) + session = sub->session; + + UA_LOG_DEBUG_SESSION(&server->config.logger, session, "Subscription %u | " + "MonitoredItem %i | Sample callback called", + sub ? sub->subscriptionId : 0, monitoredItem->monitoredItemId); + + UA_assert(monitoredItem->attributeId != UA_ATTRIBUTEID_EVENTNOTIFIER); + + /* Get the node */ + const UA_Node *node = UA_Nodestore_getNode(server->nsCtx, &monitoredItem->monitoredNodeId); + + /* Sample the value. The sample can still point into the node. */ + UA_DataValue value; + UA_DataValue_init(&value); + if(node) { + UA_ReadValueId rvid; + UA_ReadValueId_init(&rvid); + rvid.nodeId = monitoredItem->monitoredNodeId; + rvid.attributeId = monitoredItem->attributeId; + rvid.indexRange = monitoredItem->indexRange; + ReadWithNode(node, server, session, monitoredItem->timestampsToReturn, &rvid, &value); + } else { + value.hasStatus = true; + value.status = UA_STATUSCODE_BADNODEIDUNKNOWN; + } + + /* Operate on the sample */ + UA_Boolean movedValue = false; + UA_StatusCode retval = sampleCallbackWithValue(server, session, sub, monitoredItem, &value, &movedValue); + if(retval != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING_SESSION(&server->config.logger, session, "Subscription %u | " + "MonitoredItem %i | Sampling returned the statuscode %s", + sub ? sub->subscriptionId : 0, monitoredItem->monitoredItemId, + UA_StatusCode_name(retval)); + } + + /* Delete the sample if it was not moved to the notification. */ + if(!movedValue) + UA_DataValue_deleteMembers(&value); /* Does nothing for UA_VARIANT_DATA_NODELETE */ + if(node) + UA_Nodestore_releaseNode(server->nsCtx, node); +} + +#endif /* UA_ENABLE_SUBSCRIPTIONS */ + /*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_log_stdout.c" ***********************************/ /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. - * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. * - * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2016-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA */ + #include <stdio.h> +#ifdef UA_ENABLE_MULTITHREADING +#include <pthread.h> +static pthread_mutex_t printf_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + /* ANSI escape sequences for color output taken from here: * https://stackoverflow.com/questions/3219393/stdlib-and-colored-output-in-c*/ -#ifdef _WIN32 -# define ANSI_COLOR_RED "" -# define ANSI_COLOR_GREEN "" -# define ANSI_COLOR_YELLOW "" -# define ANSI_COLOR_BLUE "" -# define ANSI_COLOR_MAGENTA "" -# define ANSI_COLOR_CYAN "" -# define ANSI_COLOR_RESET "" -#else +#ifdef UA_ENABLE_LOG_COLORS # define ANSI_COLOR_RED "\x1b[31m" # define ANSI_COLOR_GREEN "\x1b[32m" # define ANSI_COLOR_YELLOW "\x1b[33m" @@ -40200,11 +48933,14 @@ UA_DateTime UA_DateTime_nowMonotonic(void) { # define ANSI_COLOR_MAGENTA "\x1b[35m" # define ANSI_COLOR_CYAN "\x1b[36m" # define ANSI_COLOR_RESET "\x1b[0m" -#endif - -#ifdef UA_ENABLE_MULTITHREADING -#include <pthread.h> -static pthread_mutex_t printf_mutex = PTHREAD_MUTEX_INITIALIZER; +#else +# define ANSI_COLOR_RED "" +# define ANSI_COLOR_GREEN "" +# define ANSI_COLOR_YELLOW "" +# define ANSI_COLOR_BLUE "" +# define ANSI_COLOR_MAGENTA "" +# define ANSI_COLOR_CYAN "" +# define ANSI_COLOR_RESET "" #endif const char *logLevelNames[6] = {"trace", "debug", @@ -40216,11 +48952,11 @@ const char *logCategoryNames[7] = {"network", "channel", "session", "server", "client", "userland", "securitypolicy"}; #ifdef __clang__ -__attribute__((__format__(__printf__, 3 , 0))) +__attribute__((__format__(__printf__, 4 , 0))) #endif void -UA_Log_Stdout(UA_LogLevel level, UA_LogCategory category, - const char *msg, va_list args) { +UA_Log_Stdout_log(void *_, UA_LogLevel level, UA_LogCategory category, + const char *msg, va_list args) { UA_Int64 tOffset = UA_DateTime_localTimeUtcOffset(); UA_DateTimeStruct dts = UA_DateTime_toStruct(UA_DateTime_now() + tOffset); @@ -40240,12 +48976,20 @@ UA_Log_Stdout(UA_LogLevel level, UA_LogCategory category, #endif } +void +UA_Log_Stdout_clear(void *logContext) { + +} + +const UA_Logger UA_Log_Stdout_ = {UA_Log_Stdout_log, NULL, UA_Log_Stdout_clear}; +const UA_Logger *UA_Log_Stdout = &UA_Log_Stdout_; + /*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_accesscontrol_default.c" ***********************************/ /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. * - * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Stefan Profanter, fortiss GmbH */ @@ -40270,6 +49014,8 @@ const UA_String username_policy = UA_STRING_STATIC(USERNAME_POLICY); static UA_StatusCode activateSession_default(UA_Server *server, UA_AccessControl *ac, + const UA_EndpointDescription *endpointDescription, + const UA_ByteString *secureChannelRemoteCertificate, const UA_NodeId *sessionId, const UA_ExtensionObject *userIdentityToken, void **sessionContext) { @@ -40316,9 +49062,9 @@ activateSession_default(UA_Server *server, UA_AccessControl *ac, if(!UA_String_equal(&userToken->policyId, &username_policy)) return UA_STATUSCODE_BADIDENTITYTOKENINVALID; - /* TODO: Support encrypted username/password over unencrypted SecureChannels */ - if(userToken->encryptionAlgorithm.length > 0) - return UA_STATUSCODE_BADIDENTITYTOKENINVALID; + /* The userToken has been decrypted by the server before forwarding + * it to the plugin. This information can be used here. */ + /* if(userToken->encryptionAlgorithm.length > 0) {} */ /* Empty username and password */ if(userToken->userName.length == 0 && userToken->password.length == 0) @@ -40408,6 +49154,27 @@ allowDeleteReference_default(UA_Server *server, UA_AccessControl *ac, return true; } +#ifdef UA_ENABLE_HISTORIZING +static UA_Boolean +allowHistoryUpdateUpdateData_default(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, + UA_PerformUpdateType performInsertReplace, + const UA_DataValue *value) { + return true; +} + +static UA_Boolean +allowHistoryUpdateDeleteRawModified_default(UA_Server *server, UA_AccessControl *ac, + const UA_NodeId *sessionId, void *sessionContext, + const UA_NodeId *nodeId, + UA_DateTime startTimestamp, + UA_DateTime endTimestamp, + bool isDeleteModified) { + return true; +} +#endif + /***************************************/ /* Create Delete Access Control Plugin */ /***************************************/ @@ -40416,37 +49183,52 @@ static void deleteMembers_default(UA_AccessControl *ac) { UA_Array_delete((void*)(uintptr_t)ac->userTokenPolicies, ac->userTokenPoliciesSize, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); + ac->userTokenPolicies = NULL; + ac->userTokenPoliciesSize = 0; AccessControlContext *context = (AccessControlContext*)ac->context; - for(size_t i = 0; i < context->usernamePasswordLoginSize; i++) { - UA_String_deleteMembers(&context->usernamePasswordLogin[i].username); - UA_String_deleteMembers(&context->usernamePasswordLogin[i].password); + + if (context) { + for(size_t i = 0; i < context->usernamePasswordLoginSize; i++) { + UA_String_deleteMembers(&context->usernamePasswordLogin[i].username); + UA_String_deleteMembers(&context->usernamePasswordLogin[i].password); + } + if(context->usernamePasswordLoginSize > 0) + UA_free(context->usernamePasswordLogin); + UA_free(ac->context); } - if(context->usernamePasswordLoginSize > 0) - UA_free(context->usernamePasswordLogin); - UA_free(ac->context); } -UA_AccessControl -UA_AccessControl_default(UA_Boolean allowAnonymous, size_t usernamePasswordLoginSize, +UA_StatusCode +UA_AccessControl_default(UA_ServerConfig *config, UA_Boolean allowAnonymous, + const UA_ByteString *userTokenPolicyUri, + size_t usernamePasswordLoginSize, const UA_UsernamePasswordLogin *usernamePasswordLogin) { + UA_AccessControl *ac = &config->accessControl; + ac->deleteMembers = deleteMembers_default; + ac->activateSession = activateSession_default; + ac->closeSession = closeSession_default; + ac->getUserRightsMask = getUserRightsMask_default; + ac->getUserAccessLevel = getUserAccessLevel_default; + ac->getUserExecutable = getUserExecutable_default; + ac->getUserExecutableOnObject = getUserExecutableOnObject_default; + ac->allowAddNode = allowAddNode_default; + ac->allowAddReference = allowAddReference_default; + +#ifdef UA_ENABLE_HISTORIZING + ac->allowHistoryUpdateUpdateData = allowHistoryUpdateUpdateData_default; + ac->allowHistoryUpdateDeleteRawModified = allowHistoryUpdateDeleteRawModified_default; +#endif + + ac->allowDeleteNode = allowDeleteNode_default; + ac->allowDeleteReference = allowDeleteReference_default; + AccessControlContext *context = (AccessControlContext*) - UA_malloc(sizeof(AccessControlContext)); - - UA_AccessControl ac; - memset(&ac, 0, sizeof(ac)); - ac.context = context; - ac.deleteMembers = deleteMembers_default; - ac.activateSession = activateSession_default; - ac.closeSession = closeSession_default; - ac.getUserRightsMask = getUserRightsMask_default; - ac.getUserAccessLevel = getUserAccessLevel_default; - ac.getUserExecutable = getUserExecutable_default; - ac.getUserExecutableOnObject = getUserExecutableOnObject_default; - ac.allowAddNode = allowAddNode_default; - ac.allowAddReference = allowAddReference_default; - ac.allowDeleteNode = allowDeleteNode_default; - ac.allowDeleteReference = allowDeleteReference_default; + UA_malloc(sizeof(AccessControlContext)); + if (!context) + return UA_STATUSCODE_BADOUTOFMEMORY; + memset(context, 0, sizeof(AccessControlContext)); + ac->context = context; /* Allow anonymous? */ context->allowAnonymous = allowAnonymous; @@ -40456,7 +49238,7 @@ UA_AccessControl_default(UA_Boolean allowAnonymous, size_t usernamePasswordLogin context->usernamePasswordLogin = (UA_UsernamePasswordLogin*) UA_malloc(usernamePasswordLoginSize * sizeof(UA_UsernamePasswordLogin)); if(!context->usernamePasswordLogin) - return ac; + return UA_STATUSCODE_BADOUTOFMEMORY; context->usernamePasswordLoginSize = usernamePasswordLoginSize; for(size_t i = 0; i < usernamePasswordLoginSize; i++) { UA_String_copy(&usernamePasswordLogin[i].username, &context->usernamePasswordLogin[i].username); @@ -40470,44 +49252,64 @@ UA_AccessControl_default(UA_Boolean allowAnonymous, size_t usernamePasswordLogin policies++; if(usernamePasswordLoginSize > 0) policies++; - ac.userTokenPoliciesSize = 0; - ac.userTokenPolicies = (UA_UserTokenPolicy *) + ac->userTokenPoliciesSize = 0; + ac->userTokenPolicies = (UA_UserTokenPolicy *) UA_Array_new(policies, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); - if(!ac.userTokenPolicies) - return ac; - ac.userTokenPoliciesSize = policies; + if(!ac->userTokenPolicies) + return UA_STATUSCODE_BADOUTOFMEMORY; + ac->userTokenPoliciesSize = policies; policies = 0; if(allowAnonymous) { - ac.userTokenPolicies[policies].tokenType = UA_USERTOKENTYPE_ANONYMOUS; - ac.userTokenPolicies[policies].policyId = UA_STRING_ALLOC(ANONYMOUS_POLICY); + ac->userTokenPolicies[policies].tokenType = UA_USERTOKENTYPE_ANONYMOUS; + ac->userTokenPolicies[policies].policyId = UA_STRING_ALLOC(ANONYMOUS_POLICY); + if (!ac->userTokenPolicies[policies].policyId.data) + return UA_STATUSCODE_BADOUTOFMEMORY; policies++; } if(usernamePasswordLoginSize > 0) { - ac.userTokenPolicies[policies].tokenType = UA_USERTOKENTYPE_USERNAME; - ac.userTokenPolicies[policies].policyId = UA_STRING_ALLOC(USERNAME_POLICY); - /* No encryption of username/password supported at the moment */ - ac.userTokenPolicies[policies].securityPolicyUri = - UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#None"); + ac->userTokenPolicies[policies].tokenType = UA_USERTOKENTYPE_USERNAME; + ac->userTokenPolicies[policies].policyId = UA_STRING_ALLOC(USERNAME_POLICY); + if(!ac->userTokenPolicies[policies].policyId.data) + return UA_STATUSCODE_BADOUTOFMEMORY; + +#if UA_LOGLEVEL <= 400 + const UA_String noneUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None"); + if(UA_ByteString_equal(userTokenPolicyUri, &noneUri)) { + UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_SERVER, + "Username/Password configured, but no encrypting SecurityPolicy. " + "This can leak credentials on the network."); + } +#endif + return UA_ByteString_copy(userTokenPolicyUri, + &ac->userTokenPolicies[policies].securityPolicyUri); } - return ac; + return UA_STATUSCODE_GOOD; } -/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_pki_certificate.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_pki_default.c" ***********************************/ /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. - * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. * * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2019 (c) Kalycito Infotech Private Limited + * Copyright 2019 (c) Julius Pfrommer, Fraunhofer IOSB */ #ifdef UA_ENABLE_ENCRYPTION #include <mbedtls/x509.h> #include <mbedtls/x509_crt.h> +#include <mbedtls/error.h> #endif +#define REMOTECERTIFICATETRUSTED 1 +#define ISSUERKNOWN 2 +#define DUALPARENT 3 +#define PARENTFOUND 4 + /************/ /* AllowAll */ /************/ @@ -40539,10 +49341,143 @@ void UA_CertificateVerification_AcceptAll(UA_CertificateVerification *cv) { #ifdef UA_ENABLE_ENCRYPTION typedef struct { + /* If the folders are defined, we use them to reload the certificates during + * runtime */ + UA_String trustListFolder; + UA_String issuerListFolder; + UA_String revocationListFolder; + mbedtls_x509_crt certificateTrustList; + mbedtls_x509_crt certificateIssuerList; mbedtls_x509_crl certificateRevocationList; } CertInfo; +#if __linux__ /* Linux only so far */ + +#include <dirent.h> +#include <limits.h> + +static UA_StatusCode +fileNamesFromFolder(const UA_String *folder, size_t *pathsSize, UA_String **paths) { + char buf[PATH_MAX + 1]; + if(folder->length > PATH_MAX) + return UA_STATUSCODE_BADINTERNALERROR; + + memcpy(buf, folder->data, folder->length); + buf[folder->length] = 0; + + DIR *dir = opendir(buf); + if(!dir) + return UA_STATUSCODE_BADINTERNALERROR; + + *paths = (UA_String*)UA_Array_new(256, &UA_TYPES[UA_TYPES_STRING]); + if(*paths == NULL) { + closedir(dir); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + + struct dirent *ent; + char buf2[PATH_MAX + 1]; + realpath(buf, buf2); + size_t pathlen = strlen(buf2); + *pathsSize = 0; + while((ent = readdir (dir)) != NULL && *pathsSize < 256) { + if(ent->d_type != DT_REG) + continue; + buf2[pathlen] = '/'; + buf2[pathlen+1] = 0; + strcat(buf2, ent->d_name); + (*paths)[*pathsSize] = UA_STRING_ALLOC(buf2); + *pathsSize += 1; + } + closedir(dir); + + if(*pathsSize == 0) { + UA_free(*paths); + *paths = NULL; + } + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +reloadCertificates(CertInfo *ci) { + UA_StatusCode retval = UA_STATUSCODE_GOOD; + int err = 0; + + /* Load the trustlists */ + if(ci->trustListFolder.length > 0) { + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Reloading the trust-list"); + mbedtls_x509_crt_free(&ci->certificateTrustList); + mbedtls_x509_crt_init(&ci->certificateTrustList); + + char f[PATH_MAX]; + memcpy(f, ci->trustListFolder.data, ci->trustListFolder.length); + f[ci->trustListFolder.length] = 0; + err = mbedtls_x509_crt_parse_path(&ci->certificateTrustList, f); + if(err == 0) { + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Loaded certificate from %s", f); + } else { + char errBuff[300]; + mbedtls_strerror(err, errBuff, 300); + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Failed to load certificate from %s", f); + } + } + + /* Load the revocationlists */ + if(ci->revocationListFolder.length > 0) { + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Reloading the revocation-list"); + size_t pathsSize = 0; + UA_String *paths = NULL; + retval = fileNamesFromFolder(&ci->revocationListFolder, &pathsSize, &paths); + if(retval != UA_STATUSCODE_GOOD) + return retval; + mbedtls_x509_crl_free(&ci->certificateRevocationList); + mbedtls_x509_crl_init(&ci->certificateRevocationList); + for(size_t i = 0; i < pathsSize; i++) { + char f[PATH_MAX]; + memcpy(f, paths[i].data, paths[i].length); + f[paths[i].length] = 0; + err = mbedtls_x509_crl_parse_file(&ci->certificateRevocationList, f); + if(err == 0) { + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Loaded certificate from %.*s", + (int)paths[i].length, paths[i].data); + } else { + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Failed to load certificate from %.*s", + (int)paths[i].length, paths[i].data); + } + } + UA_Array_delete(paths, pathsSize, &UA_TYPES[UA_TYPES_STRING]); + paths = NULL; + pathsSize = 0; + } + + /* Load the issuerlists */ + if(ci->issuerListFolder.length > 0) { + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Reloading the issuer-list"); + mbedtls_x509_crt_free(&ci->certificateIssuerList); + mbedtls_x509_crt_init(&ci->certificateIssuerList); + char f[PATH_MAX]; + memcpy(f, ci->issuerListFolder.data, ci->issuerListFolder.length); + f[ci->issuerListFolder.length] = 0; + err = mbedtls_x509_crt_parse_path(&ci->certificateIssuerList, f); + if(err == 0) { + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Loaded certificate from %s", f); + } else { + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Failed to load certificate from %s", f); + } + } + + return retval; +} + +#endif + static UA_StatusCode certificateVerification_verify(void *verificationContext, const UA_ByteString *certificate) { @@ -40550,8 +49485,37 @@ certificateVerification_verify(void *verificationContext, if(!ci) return UA_STATUSCODE_BADINTERNALERROR; +#if __linux__ /* Reload certificates if folder paths are specified */ + reloadCertificates(ci); +#endif + + /* if(ci->certificateTrustList.raw.len == 0) { */ + /* UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, */ + /* "No Trustlist loaded. Accepting the certificate."); */ + /* return UA_STATUSCODE_GOOD; */ + /* } */ + /* Parse the certificate */ mbedtls_x509_crt remoteCertificate; + + /* Temporary Object to parse the trustList */ + mbedtls_x509_crt *tempCert; + + /* Temporary Object to parse the revocationList */ + mbedtls_x509_crl *tempCrl; + + /* Temporary Object to identify the parent CA when there is no intermediate CA */ + mbedtls_x509_crt *parentCert; + + /* Temporary Object to identify the parent CA when there is intermediate CA */ + mbedtls_x509_crt *parentCert_2; + + /* Flag value to identify if the issuer certificate is found */ + int issuerKnown = 0; + + /* Flag value to identify if the parent certificate found */ + int parentFound = 0; + mbedtls_x509_crt_init(&remoteCertificate); int mbedErr = mbedtls_x509_crt_parse(&remoteCertificate, certificate->data, certificate->length); @@ -40575,7 +49539,144 @@ certificateVerification_verify(void *verificationContext, &ci->certificateRevocationList, &crtProfile, NULL, &flags, NULL, NULL); + /* Flag to check if the remote certificate is trusted or not */ + int TRUSTED = 0; + + /* Check if the remoteCertificate is present in the trustList while mbedErr value is not zero */ + if(mbedErr && !(flags & MBEDTLS_X509_BADCERT_EXPIRED) && !(flags & MBEDTLS_X509_BADCERT_FUTURE)) { + for(tempCert = &ci->certificateTrustList; tempCert != NULL; tempCert = tempCert->next) { + if(remoteCertificate.raw.len == tempCert->raw.len && + memcmp(remoteCertificate.raw.p, tempCert->raw.p, remoteCertificate.raw.len) == 0) { + TRUSTED = REMOTECERTIFICATETRUSTED; + break; + } + } + } + + /* If the remote certificate is present in the trustList then check if the issuer certificate + * of remoteCertificate is present in issuerList */ + if(TRUSTED && mbedErr) { + mbedErr = mbedtls_x509_crt_verify_with_profile(&remoteCertificate, + &ci->certificateIssuerList, + &ci->certificateRevocationList, + &crtProfile, NULL, &flags, NULL, NULL); + + /* Check if the parent certificate has a CRL file available */ + if(!mbedErr) { + /* Flag value to identify if that there is an intermediate CA present */ + int dualParent = 0; + + /* Identify the topmost parent certificate for the remoteCertificate */ + for( parentCert = &ci->certificateIssuerList; parentCert != NULL; parentCert = parentCert->next ) { + if(memcmp(remoteCertificate.issuer_raw.p, parentCert->subject_raw.p, parentCert->subject_raw.len) == 0) { + for(parentCert_2 = &ci->certificateTrustList; parentCert_2 != NULL; parentCert_2 = parentCert_2->next) { + if(memcmp(parentCert->issuer_raw.p, parentCert_2->subject_raw.p, parentCert_2->subject_raw.len) == 0) { + dualParent = DUALPARENT; + parentFound = PARENTFOUND; + break; + } + + } + + parentFound = PARENTFOUND; + } + + if(parentFound == PARENTFOUND) { + break; + } + + } + + /* Check if there is an intermediate certificate between the topmost parent + * certificate and child certificate + * If yes the topmost parent certificate is to be checked whether it has a + * CRL file avaiable */ + if(dualParent == DUALPARENT && parentFound == PARENTFOUND) { + parentCert = parentCert_2; + } + + /* If a parent certificate is found traverse the revocationList and identify + * if there is any CRL file that corresponds to the parentCertificate */ + if(parentFound == PARENTFOUND) { + tempCrl = &ci->certificateRevocationList; + while(tempCrl != NULL) { + if(tempCrl->version != 0 && + tempCrl->issuer_raw.len == parentCert->subject_raw.len && + memcmp(tempCrl->issuer_raw.p, + parentCert->subject_raw.p, + tempCrl->issuer_raw.len) == 0) { + issuerKnown = ISSUERKNOWN; + break; + } + + tempCrl = tempCrl->next; + } + + /* If the CRL file corresponding to the parent certificate is not present + * then return UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN */ + if(!issuerKnown) { + return UA_STATUSCODE_BADCERTIFICATEISSUERREVOCATIONUNKNOWN; + } + + } + + } + + } + else if(!mbedErr && !TRUSTED) { + /* This else if section is to identify if the parent certificate which is present in trustList + * has CRL file corresponding to it */ + + /* Identify the parent certificate of the remoteCertificate */ + for(parentCert = &ci->certificateTrustList; parentCert != NULL; parentCert = parentCert->next) { + if(memcmp(remoteCertificate.issuer_raw.p, parentCert->subject_raw.p, parentCert->subject_raw.len) == 0) { + parentFound = PARENTFOUND; + break; + } + + } + + /* If the parent certificate is found traverse the revocationList and identify + * if there is any CRL file that corresponds to the parentCertificate */ + if(parentFound == PARENTFOUND && + memcmp(remoteCertificate.issuer_raw.p, remoteCertificate.subject_raw.p, remoteCertificate.subject_raw.len) != 0) { + tempCrl = &ci->certificateRevocationList; + while(tempCrl != NULL) { + if(tempCrl->version != 0 && + tempCrl->issuer_raw.len == parentCert->subject_raw.len && + memcmp(tempCrl->issuer_raw.p, + parentCert->subject_raw.p, + tempCrl->issuer_raw.len) == 0) { + issuerKnown = ISSUERKNOWN; + break; + } + + tempCrl = tempCrl->next; + } + + /* If the CRL file corresponding to the parent certificate is not present + * then return UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN */ + if(!issuerKnown) { + return UA_STATUSCODE_BADCERTIFICATEREVOCATIONUNKNOWN; + } + + } + + } + // TODO: Extend verification + + /* This condition will check whether the certificate is a User certificate + * or a CA certificate. If the MBEDTLS_X509_KU_KEY_CERT_SIGN and + * MBEDTLS_X509_KU_CRL_SIGN of key_usage are set, then the certificate + * shall be condidered as CA Certificate and cannot be used to establish a + * connection. Refer the test case CTT/Security/Security Certificate Validation/029.js + * for more details */ + if((remoteCertificate.key_usage & MBEDTLS_X509_KU_KEY_CERT_SIGN) && + (remoteCertificate.key_usage & MBEDTLS_X509_KU_CRL_SIGN)) { + return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED; + } + UA_StatusCode retval = UA_STATUSCODE_GOOD; if(mbedErr) { /* char buff[100]; */ @@ -40584,13 +49685,13 @@ certificateVerification_verify(void *verificationContext, /* UA_LOGCATEGORY_SECURITYPOLICY, */ /* "Verifying the certificate failed with error: %s", buff); */ - if(flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) { + if(flags & (uint32_t)MBEDTLS_X509_BADCERT_NOT_TRUSTED) { retval = UA_STATUSCODE_BADCERTIFICATEUNTRUSTED; - } else if (flags & MBEDTLS_X509_BADCERT_FUTURE || - flags & MBEDTLS_X509_BADCERT_EXPIRED) { + } else if(flags & (uint32_t)MBEDTLS_X509_BADCERT_FUTURE || + flags & (uint32_t)MBEDTLS_X509_BADCERT_EXPIRED) { retval = UA_STATUSCODE_BADCERTIFICATETIMEINVALID; - } else if(flags & MBEDTLS_X509_BADCERT_REVOKED || - flags & MBEDTLS_X509_BADCRL_EXPIRED) { + } else if(flags & (uint32_t)MBEDTLS_X509_BADCERT_REVOKED || + flags & (uint32_t)MBEDTLS_X509_BADCRL_EXPIRED) { retval = UA_STATUSCODE_BADCERTIFICATEREVOKED; } else { retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; @@ -40680,6 +49781,10 @@ certificateVerification_deleteMembers(UA_CertificateVerification *cv) { return; mbedtls_x509_crt_free(&ci->certificateTrustList); mbedtls_x509_crl_free(&ci->certificateRevocationList); + mbedtls_x509_crt_free(&ci->certificateIssuerList); + UA_String_clear(&ci->trustListFolder); + UA_String_clear(&ci->issuerListFolder); + UA_String_clear(&ci->revocationListFolder); UA_free(ci); cv->context = NULL; } @@ -40688,13 +49793,17 @@ UA_StatusCode UA_CertificateVerification_Trustlist(UA_CertificateVerification *cv, const UA_ByteString *certificateTrustList, size_t certificateTrustListSize, + const UA_ByteString *certificateIssuerList, + size_t certificateIssuerListSize, const UA_ByteString *certificateRevocationList, size_t certificateRevocationListSize) { - CertInfo *ci = (CertInfo*)malloc(sizeof(CertInfo)); + CertInfo *ci = (CertInfo*)UA_malloc(sizeof(CertInfo)); if(!ci) return UA_STATUSCODE_BADOUTOFMEMORY; + memset(ci, 0, sizeof(CertInfo)); mbedtls_x509_crt_init(&ci->certificateTrustList); mbedtls_x509_crl_init(&ci->certificateRevocationList); + mbedtls_x509_crt_init(&ci->certificateIssuerList); cv->context = (void*)ci; if(certificateTrustListSize > 0) @@ -40706,23 +49815,66 @@ UA_CertificateVerification_Trustlist(UA_CertificateVerification *cv, int err = 0; for(size_t i = 0; i < certificateTrustListSize; i++) { - err |= mbedtls_x509_crt_parse(&ci->certificateTrustList, - certificateTrustList[i].data, - certificateTrustList[i].length); + err = mbedtls_x509_crt_parse(&ci->certificateTrustList, + certificateTrustList[i].data, + certificateTrustList[i].length); + if(err) + goto error; + } + for(size_t i = 0; i < certificateIssuerListSize; i++) { + err = mbedtls_x509_crt_parse(&ci->certificateIssuerList, + certificateIssuerList[i].data, + certificateIssuerList[i].length); + if(err) + goto error; } for(size_t i = 0; i < certificateRevocationListSize; i++) { - err |= mbedtls_x509_crl_parse(&ci->certificateRevocationList, - certificateRevocationList[i].data, - certificateRevocationList[i].length); + err = mbedtls_x509_crl_parse(&ci->certificateRevocationList, + certificateRevocationList[i].data, + certificateRevocationList[i].length); + if(err) + goto error; } - if(err) { - certificateVerification_deleteMembers(cv); - return UA_STATUSCODE_BADINTERNALERROR; - } return UA_STATUSCODE_GOOD; +error: + certificateVerification_deleteMembers(cv); + return UA_STATUSCODE_BADINTERNALERROR; } +#if __linux__ /* Linux only so far */ + +UA_StatusCode +UA_CertificateVerification_CertFolders(UA_CertificateVerification *cv, + const char *trustListFolder, + const char *issuerListFolder, + const char *revocationListFolder) { + CertInfo *ci = (CertInfo*)UA_malloc(sizeof(CertInfo)); + if(!ci) + return UA_STATUSCODE_BADOUTOFMEMORY; + memset(ci, 0, sizeof(CertInfo)); + mbedtls_x509_crt_init(&ci->certificateTrustList); + mbedtls_x509_crl_init(&ci->certificateRevocationList); + mbedtls_x509_crt_init(&ci->certificateIssuerList); + + /* Only set the folder paths. They will be reloaded during runtime. + * TODO: Add a more efficient reloading of only the changes */ + ci->trustListFolder = UA_STRING_ALLOC(trustListFolder); + ci->issuerListFolder = UA_STRING_ALLOC(issuerListFolder); + ci->revocationListFolder = UA_STRING_ALLOC(revocationListFolder); + + reloadCertificates(ci); + + cv->context = (void*)ci; + cv->verifyCertificate = certificateVerification_verify; + cv->deleteMembers = certificateVerification_deleteMembers; + cv->verifyApplicationURI = certificateVerification_verifyApplicationURI; + + return UA_STATUSCODE_GOOD; +} + +#endif + #endif /*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_nodestore_default.c" ***********************************/ @@ -40730,149 +49882,73 @@ UA_CertificateVerification_Trustlist(UA_CertificateVerification *cv, /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. * + * Copyright 2014-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Julian Grothoff * Copyright 2017 (c) Stefan Profanter, fortiss GmbH */ -/* container_of */ -#define container_of(ptr, type, member) \ - (type *)((uintptr_t)ptr - offsetof(type,member)) +#ifndef UA_ENABLE_CUSTOM_NODESTORE #ifdef UA_ENABLE_MULTITHREADING #include <pthread.h> #define BEGIN_CRITSECT(NODEMAP) pthread_mutex_lock(&(NODEMAP)->mutex) #define END_CRITSECT(NODEMAP) pthread_mutex_unlock(&(NODEMAP)->mutex) #else -#define BEGIN_CRITSECT(NODEMAP) -#define END_CRITSECT(NODEMAP) +#define BEGIN_CRITSECT(NODEMAP) do {} while(0) +#define END_CRITSECT(NODEMAP) do {} while(0) #endif -/* The default Nodestore is simply a hash-map from NodeIds to Nodes. To find an - * entry, iterate over candidate positions according to the NodeId hash. - * - * - Tombstone or non-matching NodeId: continue searching - * - Matching NodeId: Return the entry - * - NULL: Abort the search */ +/* container_of */ +#define container_of(ptr, type, member) \ + (type *)((uintptr_t)ptr - offsetof(type,member)) + +struct NodeEntry; +typedef struct NodeEntry NodeEntry; -typedef struct UA_NodeMapEntry { - struct UA_NodeMapEntry *orig; /* the version this is a copy from (or NULL) */ +struct NodeEntry { + ZIP_ENTRY(NodeEntry) zipfields; + UA_UInt32 nodeIdHash; UA_UInt16 refCount; /* How many consumers have a reference to the node? */ UA_Boolean deleted; /* Node was marked as deleted and can be deleted when refCount == 0 */ - UA_Node node; -} UA_NodeMapEntry; - -#define UA_NODEMAP_MINSIZE 64 -#define UA_NODEMAP_TOMBSTONE ((UA_NodeMapEntry*)0x01) - -typedef struct { - UA_NodeMapEntry **entries; - UA_UInt32 size; - UA_UInt32 count; - UA_UInt32 sizePrimeIndex; -#ifdef UA_ENABLE_MULTITHREADING - pthread_mutex_t mutex; /* Protect access */ -#endif -} UA_NodeMap; - -/*********************/ -/* HashMap Utilities */ -/*********************/ - -/* The size of the hash-map is always a prime number. They are chosen to be - * close to the next power of 2. So the size ca. doubles with each prime. */ -static UA_UInt32 const primes[] = { - 7, 13, 31, 61, 127, 251, - 509, 1021, 2039, 4093, 8191, 16381, - 32749, 65521, 131071, 262139, 524287, 1048573, - 2097143, 4194301, 8388593, 16777213, 33554393, 67108859, - 134217689, 268435399, 536870909, 1073741789, 2147483647, 4294967291 + NodeEntry *orig; /* If a copy is made to replace a node, track that we + * replace only the node from which the copy was made. + * Important for concurrent operations. */ + UA_NodeId nodeId; /* This is actually a UA_Node that also starts with a NodeId */ }; -static UA_UInt32 mod(UA_UInt32 h, UA_UInt32 size) { return h % size; } -static UA_UInt32 mod2(UA_UInt32 h, UA_UInt32 size) { return 1 + (h % (size - 2)); } +/* Absolute ordering for NodeIds */ +static enum ZIP_CMP +cmpNodeId(const void *a, const void *b) { + const NodeEntry *aa = (const NodeEntry*)a; + const NodeEntry *bb = (const NodeEntry*)b; -static UA_UInt16 -higher_prime_index(UA_UInt32 n) { - UA_UInt16 low = 0; - UA_UInt16 high = (UA_UInt16)(sizeof(primes) / sizeof(UA_UInt32)); - while(low != high) { - UA_UInt16 mid = (UA_UInt16)(low + ((high - low) / 2)); - if(n > primes[mid]) - low = (UA_UInt16)(mid + 1); - else - high = mid; - } - return low; -} - -/* returns an empty slot or null if the nodeid exists or if no empty slot is found. */ -static UA_NodeMapEntry ** -findFreeSlot(const UA_NodeMap *ns, const UA_NodeId *nodeid) { - UA_NodeMapEntry **retval = NULL; - UA_UInt32 h = UA_NodeId_hash(nodeid); - UA_UInt32 size = ns->size; - UA_UInt64 idx = mod(h, size); // use 64 bit container to avoid overflow - UA_UInt32 startIdx = (UA_UInt32)idx; - UA_UInt32 hash2 = mod2(h, size); - UA_NodeMapEntry *entry = NULL; + /* Compare hash */ + if(aa->nodeIdHash < bb->nodeIdHash) + return ZIP_CMP_LESS; + if(aa->nodeIdHash > bb->nodeIdHash) + return ZIP_CMP_MORE; - do { - entry = ns->entries[(UA_UInt32)idx]; - if(entry > UA_NODEMAP_TOMBSTONE && - UA_NodeId_equal(&entry->node.nodeId, nodeid)) - return NULL; - if(!retval && entry <= UA_NODEMAP_TOMBSTONE) - retval = &ns->entries[(UA_UInt32)idx]; - idx += hash2; - if(idx >= size) - idx -= size; - } while((UA_UInt32)idx != startIdx && entry); - - /* NULL is returned if there is no free slot (idx == startIdx). - * Otherwise the first free slot is returned after we are sure, - * that the node id cannot be found in the used hashmap (!entry). */ - return retval; + /* Compore nodes in detail */ + return (enum ZIP_CMP)UA_NodeId_order(&aa->nodeId, &bb->nodeId); } -/* The occupancy of the table after the call will be about 50% */ -static UA_StatusCode -expand(UA_NodeMap *ns) { - UA_UInt32 osize = ns->size; - UA_UInt32 count = ns->count; - /* Resize only when table after removal of unused elements is either too - full or too empty */ - if(count * 2 < osize && (count * 8 > osize || osize <= UA_NODEMAP_MINSIZE)) - return UA_STATUSCODE_GOOD; +ZIP_HEAD(NodeTree, NodeEntry); +typedef struct NodeTree NodeTree; - UA_NodeMapEntry **oentries = ns->entries; - UA_UInt32 nindex = higher_prime_index(count * 2); - UA_UInt32 nsize = primes[nindex]; - UA_NodeMapEntry **nentries = (UA_NodeMapEntry **)UA_calloc(nsize, sizeof(UA_NodeMapEntry*)); - if(!nentries) - return UA_STATUSCODE_BADOUTOFMEMORY; - - ns->entries = nentries; - ns->size = nsize; - ns->sizePrimeIndex = nindex; - - /* recompute the position of every entry and insert the pointer */ - for(size_t i = 0, j = 0; i < osize && j < count; ++i) { - if(oentries[i] <= UA_NODEMAP_TOMBSTONE) - continue; - UA_NodeMapEntry **e = findFreeSlot(ns, &oentries[i]->node.nodeId); - UA_assert(e); - *e = oentries[i]; - ++j; - } +typedef struct { + NodeTree root; +#ifdef UA_ENABLE_MULTITHREADING + pthread_mutex_t mutex; /* Protect access */ +#endif +} NodeMap; - UA_free(oentries); - return UA_STATUSCODE_GOOD; -} +ZIP_PROTTYPE(NodeTree, NodeEntry, NodeEntry) +ZIP_IMPL(NodeTree, NodeEntry, zipfields, NodeEntry, zipfields, cmpNodeId) -static UA_NodeMapEntry * +static NodeEntry * newEntry(UA_NodeClass nodeClass) { - size_t size = sizeof(UA_NodeMapEntry) - sizeof(UA_Node); + size_t size = sizeof(NodeEntry) - sizeof(UA_NodeId); switch(nodeClass) { case UA_NODECLASS_OBJECT: size += sizeof(UA_ObjectNode); @@ -40901,337 +49977,279 @@ newEntry(UA_NodeClass nodeClass) { default: return NULL; } - UA_NodeMapEntry *entry = (UA_NodeMapEntry*)UA_calloc(1, size); + NodeEntry *entry = (NodeEntry*)UA_calloc(1, size); if(!entry) return NULL; - entry->node.nodeClass = nodeClass; + UA_Node *node = (UA_Node*)&entry->nodeId; + node->nodeClass = nodeClass; return entry; } static void -deleteEntry(UA_NodeMapEntry *entry) { - UA_Node_deleteMembers(&entry->node); +deleteEntry(NodeEntry *entry) { + UA_Node_deleteMembers((UA_Node*)&entry->nodeId); UA_free(entry); } static void -cleanupEntry(UA_NodeMapEntry *entry) { +cleanupEntry(NodeEntry *entry) { if(entry->deleted && entry->refCount == 0) deleteEntry(entry); } -static UA_StatusCode -clearSlot(UA_NodeMap *ns, UA_NodeMapEntry **slot) { - (*slot)->deleted = true; - cleanupEntry(*slot); - *slot = UA_NODEMAP_TOMBSTONE; - --ns->count; - /* Downsize the hashmap if it is very empty */ - if(ns->count * 8 < ns->size && ns->size > 32) - expand(ns); /* Can fail. Just continue with the bigger hashmap. */ - return UA_STATUSCODE_GOOD; -} - -static UA_NodeMapEntry ** -findOccupiedSlot(const UA_NodeMap *ns, const UA_NodeId *nodeid) { - UA_UInt32 h = UA_NodeId_hash(nodeid); - UA_UInt32 size = ns->size; - UA_UInt64 idx = mod(h, size); // use 64 bit container to avoid overflow - UA_UInt32 hash2 = mod2(h, size); - UA_UInt32 startIdx = (UA_UInt32)idx; - UA_NodeMapEntry *entry = NULL; - - do { - entry = ns->entries[(UA_UInt32)idx]; - if(entry > UA_NODEMAP_TOMBSTONE && - UA_NodeId_equal(&entry->node.nodeId, nodeid)) - return &ns->entries[(UA_UInt32)idx]; - idx += hash2; - if(idx >= size) - idx -= size; - } while((UA_UInt32)idx != startIdx && entry); - - /* NULL is returned if there is no free slot (idx == startIdx) - * and the node id is not found or if the end of the used slots (!entry) - * is reached. */ - return NULL; -} - /***********************/ /* Interface functions */ /***********************/ -static UA_Node * -UA_NodeMap_newNode(void *context, UA_NodeClass nodeClass) { - UA_NodeMapEntry *entry = newEntry(nodeClass); +/* Not yet inserted into the NodeMap */ +UA_Node * +UA_Nodestore_newNode(void *nsCtx, UA_NodeClass nodeClass) { + NodeEntry *entry = newEntry(nodeClass); if(!entry) return NULL; - return &entry->node; + return (UA_Node*)&entry->nodeId; } -static void -UA_NodeMap_deleteNode(void *context, UA_Node *node) { -#ifdef UA_ENABLE_MULTITHREADING - UA_NodeMap *ns = (UA_NodeMap*)context; -#endif - BEGIN_CRITSECT(ns); - UA_NodeMapEntry *entry = container_of(node, UA_NodeMapEntry, node); - UA_assert(&entry->node == node); - deleteEntry(entry); - END_CRITSECT(ns); +/* Not yet inserted into the NodeMap */ +void +UA_Nodestore_deleteNode(void *nsCtx, UA_Node *node) { + deleteEntry(container_of(node, NodeEntry, nodeId)); } -static const UA_Node * -UA_NodeMap_getNode(void *context, const UA_NodeId *nodeid) { - UA_NodeMap *ns = (UA_NodeMap*)context; +const UA_Node * +UA_Nodestore_getNode(void *nsCtx, const UA_NodeId *nodeId) { + NodeMap *ns = (NodeMap*)nsCtx; BEGIN_CRITSECT(ns); - UA_NodeMapEntry **entry = findOccupiedSlot(ns, nodeid); + NodeEntry dummy; + dummy.nodeIdHash = UA_NodeId_hash(nodeId); + dummy.nodeId = *nodeId; + NodeEntry *entry = ZIP_FIND(NodeTree, &ns->root, &dummy); if(!entry) { END_CRITSECT(ns); return NULL; } - ++(*entry)->refCount; + ++entry->refCount; END_CRITSECT(ns); - return (const UA_Node*)&(*entry)->node; + return (const UA_Node*)&entry->nodeId; } -static void -UA_NodeMap_releaseNode(void *context, const UA_Node *node) { - if (!node) +void +UA_Nodestore_releaseNode(void *nsCtx, const UA_Node *node) { + if(!node) return; #ifdef UA_ENABLE_MULTITHREADING - UA_NodeMap *ns = (UA_NodeMap*)context; + NodeMap *ns = (NodeMap*)nsCtx; #endif BEGIN_CRITSECT(ns); - UA_NodeMapEntry *entry = container_of(node, UA_NodeMapEntry, node); - UA_assert(&entry->node == node); + NodeEntry *entry = container_of(node, NodeEntry, nodeId); UA_assert(entry->refCount > 0); --entry->refCount; cleanupEntry(entry); END_CRITSECT(ns); } -static UA_StatusCode -UA_NodeMap_getNodeCopy(void *context, const UA_NodeId *nodeid, - UA_Node **outNode) { - UA_NodeMap *ns = (UA_NodeMap*)context; - BEGIN_CRITSECT(ns); - UA_NodeMapEntry **slot = findOccupiedSlot(ns, nodeid); - if(!slot) { - END_CRITSECT(ns); +UA_StatusCode +UA_Nodestore_getNodeCopy(void *nsCtx, const UA_NodeId *nodeId, + UA_Node **outNode) { + /* Find the node */ + const UA_Node *node = UA_Nodestore_getNode(nsCtx, nodeId); + if(!node) return UA_STATUSCODE_BADNODEIDUNKNOWN; - } - UA_NodeMapEntry *entry = *slot; - UA_NodeMapEntry *newItem = newEntry(entry->node.nodeClass); - if(!newItem) { - END_CRITSECT(ns); + + /* Create the new entry */ + NodeEntry *ne = newEntry(node->nodeClass); + if(!ne) { + UA_Nodestore_releaseNode(nsCtx, node); return UA_STATUSCODE_BADOUTOFMEMORY; } - UA_StatusCode retval = UA_Node_copy(&entry->node, &newItem->node); - if(retval == UA_STATUSCODE_GOOD) { - newItem->orig = entry; // store the pointer to the original - *outNode = &newItem->node; - } else { - deleteEntry(newItem); + + /* Copy the node content */ + UA_Node *nnode = (UA_Node*)&ne->nodeId; + UA_StatusCode retval = UA_Node_copy(node, nnode); + UA_Nodestore_releaseNode(nsCtx, node); + if(retval != UA_STATUSCODE_GOOD) { + deleteEntry(ne); + return retval; } - END_CRITSECT(ns); - return retval; -} -static UA_StatusCode -UA_NodeMap_removeNode(void *context, const UA_NodeId *nodeid) { - UA_NodeMap *ns = (UA_NodeMap*)context; - BEGIN_CRITSECT(ns); - UA_NodeMapEntry **slot = findOccupiedSlot(ns, nodeid); - UA_StatusCode retval = UA_STATUSCODE_GOOD; - if(slot) - retval = clearSlot(ns, slot); - else - retval = UA_STATUSCODE_BADNODEIDUNKNOWN; - END_CRITSECT(ns); - return retval; + ne->orig = container_of(node, NodeEntry, nodeId); + *outNode = nnode; + return UA_STATUSCODE_GOOD; } -static UA_StatusCode -UA_NodeMap_insertNode(void *context, UA_Node *node, - UA_NodeId *addedNodeId) { - UA_NodeMap *ns = (UA_NodeMap*)context; +UA_StatusCode +UA_Nodestore_insertNode(void *nsCtx, UA_Node *node, UA_NodeId *addedNodeId) { + NodeEntry *entry = container_of(node, NodeEntry, nodeId); + NodeMap *ns = (NodeMap*)nsCtx; BEGIN_CRITSECT(ns); - if(ns->size * 3 <= ns->count * 4) { - if(expand(ns) != UA_STATUSCODE_GOOD) { - END_CRITSECT(ns); - return UA_STATUSCODE_BADINTERNALERROR; - } - } - UA_NodeMapEntry **slot; + /* Ensure that the NodeId is unique */ + NodeEntry dummy; + dummy.nodeId = node->nodeId; if(node->nodeId.identifierType == UA_NODEIDTYPE_NUMERIC && - node->nodeId.identifier.numeric == 0) { - /* create a random nodeid */ - /* start at least with 50,000 to make sure we don not conflict with nodes from the spec */ - /* if we find a conflict, we just try another identifier until we have tried all possible identifiers */ - /* since the size is prime and we don't change the increase val, we will reach the starting id again */ - /* E.g. adding a nodeset will create children while there are still other nodes which need to be created */ - /* Thus the node ids may collide */ - UA_UInt32 size = ns->size; - UA_UInt64 identifier = mod(50000 + size+1, size); // start value, use 64 bit container to avoid overflow - UA_UInt32 increase = mod2(ns->count+1, size); - UA_UInt32 startId = (UA_UInt32)identifier; // mod ensures us that the id is a valid 32 bit - - do { - node->nodeId.identifier.numeric = (UA_UInt32)identifier; - slot = findFreeSlot(ns, &node->nodeId); - if(slot) - break; - identifier += increase; - if(identifier >= size) - identifier -= size; - } while((UA_UInt32)identifier != startId); - - if (!slot) { - END_CRITSECT(ns); - return UA_STATUSCODE_BADOUTOFMEMORY; - } + node->nodeId.identifier.numeric == 0) { + do { /* Create a random nodeid until we find an unoccupied id */ + node->nodeId.identifier.numeric = UA_UInt32_random(); + dummy.nodeId.identifier.numeric = node->nodeId.identifier.numeric; + dummy.nodeIdHash = UA_NodeId_hash(&node->nodeId); + } while(ZIP_FIND(NodeTree, &ns->root, &dummy)); } else { - slot = findFreeSlot(ns, &node->nodeId); - if(!slot) { - deleteEntry(container_of(node, UA_NodeMapEntry, node)); + dummy.nodeIdHash = UA_NodeId_hash(&node->nodeId); + if(ZIP_FIND(NodeTree, &ns->root, &dummy)) { /* The nodeid exists */ + deleteEntry(entry); END_CRITSECT(ns); return UA_STATUSCODE_BADNODEIDEXISTS; } } - *slot = container_of(node, UA_NodeMapEntry, node); - ++ns->count; - UA_assert(&(*slot)->node == node); - - UA_StatusCode retval = UA_STATUSCODE_GOOD; + /* Copy the NodeId */ if(addedNodeId) { - retval = UA_NodeId_copy(&node->nodeId, addedNodeId); - if(retval != UA_STATUSCODE_GOOD) - clearSlot(ns, slot); + UA_StatusCode retval = UA_NodeId_copy(&node->nodeId, addedNodeId); + if(retval != UA_STATUSCODE_GOOD) { + deleteEntry(entry); + END_CRITSECT(ns); + return retval; + } } + /* Insert the node */ + entry->nodeIdHash = dummy.nodeIdHash; + ZIP_INSERT(NodeTree, &ns->root, entry, ZIP_FFS32(UA_UInt32_random())); END_CRITSECT(ns); - return retval; + return UA_STATUSCODE_GOOD; } -static UA_StatusCode -UA_NodeMap_replaceNode(void *context, UA_Node *node) { - UA_NodeMap *ns = (UA_NodeMap*)context; - BEGIN_CRITSECT(ns); - UA_NodeMapEntry **slot = findOccupiedSlot(ns, &node->nodeId); - if(!slot) { - END_CRITSECT(ns); +UA_StatusCode +UA_Nodestore_replaceNode(void *nsCtx, UA_Node *node) { + /* Find the node */ + const UA_Node *oldNode = UA_Nodestore_getNode(nsCtx, &node->nodeId); + if(!oldNode) return UA_STATUSCODE_BADNODEIDUNKNOWN; + + /* Test if the copy is current */ + NodeEntry *entry = container_of(node, NodeEntry, nodeId); + NodeEntry *oldEntry = container_of(oldNode, NodeEntry, nodeId); + if(oldEntry != entry->orig) { + /* The node was already updated since the copy was made */ + deleteEntry(entry); + UA_Nodestore_releaseNode(nsCtx, oldNode); + return UA_STATUSCODE_BADINTERNALERROR; } - UA_NodeMapEntry *newEntryContainer = container_of(node, UA_NodeMapEntry, node); - if(*slot != newEntryContainer->orig) { - /* The node was updated since the copy was made */ - deleteEntry(newEntryContainer); + + /* Replace */ + NodeMap *ns = (NodeMap*)nsCtx; + BEGIN_CRITSECT(ns); + ZIP_REMOVE(NodeTree, &ns->root, oldEntry); + entry->nodeIdHash = oldEntry->nodeIdHash; + ZIP_INSERT(NodeTree, &ns->root, entry, ZIP_RANK(entry, zipfields)); + oldEntry->deleted = true; + END_CRITSECT(ns); + + UA_Nodestore_releaseNode(nsCtx, oldNode); + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +UA_Nodestore_removeNode(void *nsCtx, const UA_NodeId *nodeId) { + NodeMap *ns = (NodeMap*)nsCtx; + BEGIN_CRITSECT(ns); + NodeEntry dummy; + dummy.nodeIdHash = UA_NodeId_hash(nodeId); + dummy.nodeId = *nodeId; + NodeEntry *entry = ZIP_FIND(NodeTree, &ns->root, &dummy); + if(!entry) { END_CRITSECT(ns); - return UA_STATUSCODE_BADINTERNALERROR; + return UA_STATUSCODE_BADNODEIDUNKNOWN; } - (*slot)->deleted = true; - cleanupEntry(*slot); - *slot = newEntryContainer; + ZIP_REMOVE(NodeTree, &ns->root, entry); + entry->deleted = true; + cleanupEntry(entry); END_CRITSECT(ns); return UA_STATUSCODE_GOOD; } +struct VisitorData { + UA_NodestoreVisitor visitor; + void *visitorContext; +}; + static void -UA_NodeMap_iterate(void *context, void *visitorContext, - UA_NodestoreVisitor visitor) { - UA_NodeMap *ns = (UA_NodeMap*)context; +nodeVisitor(NodeEntry *entry, void *data) { + struct VisitorData *d = (struct VisitorData*)data; + d->visitor(d->visitorContext, (UA_Node*)&entry->nodeId); +} + +void +UA_Nodestore_iterate(void *nsCtx, UA_NodestoreVisitor visitor, + void *visitorCtx) { + struct VisitorData d; + d.visitor = visitor; + d.visitorContext = visitorCtx; + NodeMap *ns = (NodeMap*)nsCtx; BEGIN_CRITSECT(ns); - for(UA_UInt32 i = 0; i < ns->size; ++i) { - if(ns->entries[i] > UA_NODEMAP_TOMBSTONE) { - END_CRITSECT(ns); - UA_NodeMapEntry *entry = ns->entries[i]; - entry->refCount++; - visitor(visitorContext, &entry->node); - entry->refCount--; - cleanupEntry(entry); - BEGIN_CRITSECT(ns); - } - } + ZIP_ITER(NodeTree, &ns->root, nodeVisitor, &d); END_CRITSECT(ns); } static void -UA_NodeMap_delete(void *context) { - UA_NodeMap *ns = (UA_NodeMap*)context; -#ifdef UA_ENABLE_MULTITHREADING - pthread_mutex_destroy(&ns->mutex); -#endif - UA_UInt32 size = ns->size; - UA_NodeMapEntry **entries = ns->entries; - for(UA_UInt32 i = 0; i < size; ++i) { - if(entries[i] > UA_NODEMAP_TOMBSTONE) { - /* On debugging builds, check that all nodes were release */ - UA_assert(entries[i]->refCount == 0); - /* Delete the node */ - deleteEntry(entries[i]); - } - } - UA_free(ns->entries); - UA_free(ns); +deleteNodeVisitor(NodeEntry *entry, void *data) { + deleteEntry(entry); } +/***********************/ +/* Nodestore Lifecycle */ +/***********************/ + +const UA_Boolean inPlaceEditAllowed = true; + UA_StatusCode -UA_Nodestore_default_new(UA_Nodestore *ns) { +UA_Nodestore_new(void **nsCtx) { /* Allocate and initialize the nodemap */ - UA_NodeMap *nodemap = (UA_NodeMap*)UA_malloc(sizeof(UA_NodeMap)); + NodeMap *nodemap = (NodeMap*)UA_malloc(sizeof(NodeMap)); if(!nodemap) return UA_STATUSCODE_BADOUTOFMEMORY; - nodemap->sizePrimeIndex = higher_prime_index(UA_NODEMAP_MINSIZE); - nodemap->size = primes[nodemap->sizePrimeIndex]; - nodemap->count = 0; - nodemap->entries = (UA_NodeMapEntry**) - UA_calloc(nodemap->size, sizeof(UA_NodeMapEntry*)); - if(!nodemap->entries) { - UA_free(nodemap); - return UA_STATUSCODE_BADOUTOFMEMORY; - } #ifdef UA_ENABLE_MULTITHREADING pthread_mutex_init(&nodemap->mutex, NULL); #endif - /* Populate the nodestore */ - ns->context = nodemap; - ns->deleteNodestore = UA_NodeMap_delete; - ns->inPlaceEditAllowed = true; - ns->newNode = UA_NodeMap_newNode; - ns->deleteNode = UA_NodeMap_deleteNode; - ns->getNode = UA_NodeMap_getNode; - ns->releaseNode = UA_NodeMap_releaseNode; - ns->getNodeCopy = UA_NodeMap_getNodeCopy; - ns->insertNode = UA_NodeMap_insertNode; - ns->replaceNode = UA_NodeMap_replaceNode; - ns->removeNode = UA_NodeMap_removeNode; - ns->iterate = UA_NodeMap_iterate; + ZIP_INIT(&nodemap->root); + /* Populate the nodestore */ + *nsCtx = (void*)nodemap; return UA_STATUSCODE_GOOD; } +void +UA_Nodestore_delete(void *nsCtx) { + if (!nsCtx) + return; + + NodeMap *ns = (NodeMap*)nsCtx; +#ifdef UA_ENABLE_MULTITHREADING + pthread_mutex_destroy(&ns->mutex); +#endif + ZIP_ITER(NodeTree, &ns->root, deleteNodeVisitor, NULL); + UA_free(ns); +} + +#endif /* UA_ENABLE_CUSTOM_NODESTORE */ + /*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_config_default.c" ***********************************/ /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. * - * Copyright 2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) * Copyright 2017 (c) Julian Grothoff * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB * Copyright 2017 (c) Stefan Profanter, fortiss GmbH * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA * Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG + * Copyright 2018 (c) Fabian Arndt, Root-Core + * Copyright 2019 (c) Kalycito Infotech Private Limited */ -#ifdef UA_ENABLE_ENCRYPTION -#endif - - /* Struct initialization works across ANSI C/C99/C++ if it is done when the * variable is first declared. Assigning values to existing structs is * heterogeneous across the three. */ @@ -41268,147 +50286,60 @@ const UA_ConnectionConfig UA_ConnectionConfig_default = { #define PRODUCT_URI "http://open62541.org" #define APPLICATION_NAME "open62541-based OPC UA Application" #define APPLICATION_URI "urn:unconfigured:application" +#define APPLICATION_URI_SERVER "urn:open62541.server.application" #define STRINGIFY(arg) #arg #define VERSION(MAJOR, MINOR, PATCH, LABEL) \ STRINGIFY(MAJOR) "." STRINGIFY(MINOR) "." STRINGIFY(PATCH) LABEL static UA_StatusCode -createSecurityPolicyNoneEndpoint(UA_ServerConfig *conf, UA_Endpoint *endpoint, - const UA_ByteString localCertificate) { - UA_EndpointDescription_init(&endpoint->endpointDescription); - - UA_SecurityPolicy_None(&endpoint->securityPolicy, NULL, localCertificate, conf->logger); - endpoint->endpointDescription.securityMode = UA_MESSAGESECURITYMODE_NONE; - endpoint->endpointDescription.securityPolicyUri = - UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#None"); - endpoint->endpointDescription.transportProfileUri = +createEndpoint(UA_ServerConfig *conf, UA_EndpointDescription *endpoint, + const UA_SecurityPolicy *securityPolicy, + UA_MessageSecurityMode securityMode) { + UA_EndpointDescription_init(endpoint); + + endpoint->securityMode = securityMode; + UA_String_copy(&securityPolicy->policyUri, &endpoint->securityPolicyUri); + endpoint->transportProfileUri = UA_STRING_ALLOC("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary"); + /* Add security level value for the corresponding message security mode */ + endpoint->securityLevel = (UA_Byte) securityMode; + /* Enable all login mechanisms from the access control plugin */ UA_StatusCode retval = UA_Array_copy(conf->accessControl.userTokenPolicies, conf->accessControl.userTokenPoliciesSize, - (void **)&endpoint->endpointDescription.userIdentityTokens, + (void **)&endpoint->userIdentityTokens, &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); if(retval != UA_STATUSCODE_GOOD) return retval; - endpoint->endpointDescription.userIdentityTokensSize = - conf->accessControl.userTokenPoliciesSize; + endpoint->userIdentityTokensSize = conf->accessControl.userTokenPoliciesSize; - UA_String_copy(&localCertificate, &endpoint->endpointDescription.serverCertificate); - UA_ApplicationDescription_copy(&conf->applicationDescription, - &endpoint->endpointDescription.server); + UA_String_copy(&securityPolicy->localCertificate, &endpoint->serverCertificate); + UA_ApplicationDescription_copy(&conf->applicationDescription, &endpoint->server); return UA_STATUSCODE_GOOD; } -void -UA_ServerConfig_set_customHostname(UA_ServerConfig *config, const UA_String customHostname) { - if(!config) - return; - UA_String_deleteMembers(&config->customHostname); - UA_String_copy(&customHostname, &config->customHostname); -} - -#ifdef UA_ENABLE_ENCRYPTION - -static UA_StatusCode -createSecurityPolicyBasic128Rsa15Endpoint(UA_ServerConfig *const conf, - UA_Endpoint *endpoint, - UA_MessageSecurityMode securityMode, - const UA_ByteString localCertificate, - const UA_ByteString localPrivateKey) { - UA_EndpointDescription_init(&endpoint->endpointDescription); - - UA_StatusCode retval = - UA_SecurityPolicy_Basic128Rsa15(&endpoint->securityPolicy, &conf->certificateVerification, - localCertificate, localPrivateKey, conf->logger); - if(retval != UA_STATUSCODE_GOOD) { - endpoint->securityPolicy.deleteMembers(&endpoint->securityPolicy); - return retval; - } - - endpoint->endpointDescription.securityMode = securityMode; - endpoint->endpointDescription.securityPolicyUri = - UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15"); - endpoint->endpointDescription.transportProfileUri = - UA_STRING_ALLOC("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary"); - - /* Enable all login mechanisms from the access control plugin */ - retval = UA_Array_copy(conf->accessControl.userTokenPolicies, - conf->accessControl.userTokenPoliciesSize, - (void **)&endpoint->endpointDescription.userIdentityTokens, - &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); - if(retval != UA_STATUSCODE_GOOD) - return retval; - endpoint->endpointDescription.userIdentityTokensSize = - conf->accessControl.userTokenPoliciesSize; - - UA_String_copy(&localCertificate, &endpoint->endpointDescription.serverCertificate); - UA_ApplicationDescription_copy(&conf->applicationDescription, - &endpoint->endpointDescription.server); - - return UA_STATUSCODE_GOOD; -} - -static UA_StatusCode -createSecurityPolicyBasic256Sha256Endpoint(UA_ServerConfig *const conf, - UA_Endpoint *endpoint, - UA_MessageSecurityMode securityMode, - const UA_ByteString localCertificate, - const UA_ByteString localPrivateKey) { - UA_EndpointDescription_init(&endpoint->endpointDescription); - - UA_StatusCode retval = - UA_SecurityPolicy_Basic256Sha256(&endpoint->securityPolicy, &conf->certificateVerification, localCertificate, - localPrivateKey, conf->logger); - if(retval != UA_STATUSCODE_GOOD) { - endpoint->securityPolicy.deleteMembers(&endpoint->securityPolicy); - return retval; - } - - endpoint->endpointDescription.securityMode = securityMode; - endpoint->endpointDescription.securityPolicyUri = - UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256"); - endpoint->endpointDescription.transportProfileUri = - UA_STRING_ALLOC("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary"); - - /* Enable all login mechanisms from the access control plugin */ - retval = UA_Array_copy(conf->accessControl.userTokenPolicies, - conf->accessControl.userTokenPoliciesSize, - (void **)&endpoint->endpointDescription.userIdentityTokens, - &UA_TYPES[UA_TYPES_USERTOKENPOLICY]); - if(retval != UA_STATUSCODE_GOOD) - return retval; - endpoint->endpointDescription.userIdentityTokensSize = - conf->accessControl.userTokenPoliciesSize; - - UA_String_copy(&localCertificate, &endpoint->endpointDescription.serverCertificate); - UA_ApplicationDescription_copy(&conf->applicationDescription, - &endpoint->endpointDescription.server); - - return UA_STATUSCODE_GOOD; -} - -#endif - -const size_t usernamePasswordsSize = 2; -UA_UsernamePasswordLogin usernamePasswords[2] = { +static const size_t usernamePasswordsSize = 2; +static UA_UsernamePasswordLogin usernamePasswords[2] = { {UA_STRING_STATIC("user1"), UA_STRING_STATIC("password")}, {UA_STRING_STATIC("user2"), UA_STRING_STATIC("password1")}}; -static UA_ServerConfig * -createDefaultConfig(void) { - UA_ServerConfig *conf = (UA_ServerConfig *)UA_malloc(sizeof(UA_ServerConfig)); - if(!conf) - return NULL; +static UA_StatusCode +setDefaultConfig(UA_ServerConfig *conf) { + if (!conf) + return UA_STATUSCODE_BADINVALIDARGUMENT; /* Zero out.. All members have a valid initial value */ + UA_ServerConfig_clean(conf); memset(conf, 0, sizeof(UA_ServerConfig)); /* --> Start setting the default static config <-- */ conf->nThreads = 1; - conf->logger = UA_Log_Stdout; + conf->logger = UA_Log_Stdout_; + + conf->shutdownDelay = 0.0; /* Server Description */ conf->buildInfo.productUri = UA_STRING_ALLOC(PRODUCT_URI); @@ -41417,12 +50348,14 @@ createDefaultConfig(void) { conf->buildInfo.softwareVersion = UA_STRING_ALLOC(VERSION(UA_OPEN62541_VER_MAJOR, UA_OPEN62541_VER_MINOR, UA_OPEN62541_VER_PATCH, UA_OPEN62541_VER_LABEL)); - conf->buildInfo.buildNumber = UA_STRING_ALLOC(__DATE__ - " " - __TIME__); - conf->buildInfo.buildDate = 0; + #ifdef UA_PACK_DEBIAN + conf->buildInfo.buildNumber = UA_STRING_ALLOC("deb"); + #else + conf->buildInfo.buildNumber = UA_STRING_ALLOC(__DATE__ " " __TIME__); + #endif + conf->buildInfo.buildDate = UA_DateTime_now(); - conf->applicationDescription.applicationUri = UA_STRING_ALLOC(APPLICATION_URI); + conf->applicationDescription.applicationUri = UA_STRING_ALLOC(APPLICATION_URI_SERVER); conf->applicationDescription.productUri = UA_STRING_ALLOC(PRODUCT_URI); conf->applicationDescription.applicationName = UA_LOCALIZEDTEXT_ALLOC("en", APPLICATION_NAME); @@ -41432,10 +50365,9 @@ createDefaultConfig(void) { /* conf->applicationDescription.discoveryUrlsSize = 0; */ /* conf->applicationDescription.discoveryUrls = NULL; */ -#ifdef UA_ENABLE_DISCOVERY - /* conf->mdnsServerName = UA_STRING_NULL; */ - /* conf->serverCapabilitiesSize = 0; */ - /* conf->serverCapabilities = NULL; */ +#ifdef UA_ENABLE_DISCOVERY_MULTICAST + UA_MdnsDiscoveryConfiguration_init(&conf->discovery.mdns); + conf->discovery.mdnsInterfaceIP = UA_STRING_NULL; #endif /* Custom DataTypes */ @@ -41458,8 +50390,8 @@ createDefaultConfig(void) { conf->nodeLifecycle.constructor = NULL; conf->nodeLifecycle.destructor = NULL; - /* Access Control. Anonymous Login only. */ - conf->accessControl = UA_AccessControl_default(true, usernamePasswordsSize, usernamePasswords); + /* Relax constraints for the InformationModel */ + conf->relaxEmptyValueConstraint = true; /* Allow empty values */ /* Limits for SecureChannels */ conf->maxSecureChannels = 40; @@ -41474,404 +50406,586 @@ createDefaultConfig(void) { conf->lifeTimeCountLimits = UA_UINT32RANGE(3, 15000); conf->keepAliveCountLimits = UA_UINT32RANGE(1, 100); conf->maxNotificationsPerPublish = 1000; + conf->enableRetransmissionQueue = true; conf->maxRetransmissionQueueSize = 0; /* unlimited */ +#ifdef UA_ENABLE_SUBSCRIPTIONS_EVENTS + conf->maxEventsPerNode = 0; /* unlimited */ +#endif /* Limits for MonitoredItems */ conf->samplingIntervalLimits = UA_DURATIONRANGE(50.0, 24.0 * 3600.0 * 1000.0); conf->queueSizeLimits = UA_UINT32RANGE(1, 100); #ifdef UA_ENABLE_DISCOVERY - conf->discoveryCleanupTimeout = 60 * 60; + conf->discovery.cleanupTimeout = 60 * 60; +#endif + +#ifdef UA_ENABLE_HISTORIZING + /* conf->accessHistoryDataCapability = UA_FALSE; */ + /* conf->maxReturnDataValues = 0; */ + + /* conf->accessHistoryEventsCapability = UA_FALSE; */ + /* conf->maxReturnEventValues = 0; */ + + /* conf->insertDataCapability = UA_FALSE; */ + /* conf->insertEventCapability = UA_FALSE; */ + /* conf->insertAnnotationsCapability = UA_FALSE; */ + + /* conf->replaceDataCapability = UA_FALSE; */ + /* conf->replaceEventCapability = UA_FALSE; */ + + /* conf->updateDataCapability = UA_FALSE; */ + /* conf->updateEventCapability = UA_FALSE; */ + + /* conf->deleteRawCapability = UA_FALSE; */ + /* conf->deleteEventCapability = UA_FALSE; */ + /* conf->deleteAtTimeDataCapability = UA_FALSE; */ #endif /* --> Finish setting the default static config <-- */ - return conf; + return UA_STATUSCODE_GOOD; +} + +UA_EXPORT UA_StatusCode +UA_ServerConfig_setBasics(UA_ServerConfig* conf) { + return setDefaultConfig(conf); } static UA_StatusCode -addDefaultNetworkLayers(UA_ServerConfig *conf, UA_UInt16 portNumber) { +addDefaultNetworkLayers(UA_ServerConfig *conf, UA_UInt16 portNumber, + UA_UInt32 sendBufferSize, UA_UInt32 recvBufferSize) { + return UA_ServerConfig_addNetworkLayerTCP(conf, portNumber, sendBufferSize, recvBufferSize); +} + +static UA_StatusCode +addDiscoveryUrl(UA_ServerConfig *config, UA_UInt16 portNumber) { + config->applicationDescription.discoveryUrlsSize = 1; + UA_String *discurl = (UA_String *) UA_Array_new(1, &UA_TYPES[UA_TYPES_STRING]); + char discoveryUrlBuffer[220]; + if (config->customHostname.length) { + UA_snprintf(discoveryUrlBuffer, 220, "opc.tcp://%.*s:%d/", + (int)config->customHostname.length, + config->customHostname.data, + portNumber); + } else { + char hostnameBuffer[200]; + if(UA_gethostname(hostnameBuffer, 200) == 0) { + UA_snprintf(discoveryUrlBuffer, 220, "opc.tcp://%s:%d/", hostnameBuffer, portNumber); + } else { + UA_LOG_ERROR(&config->logger, UA_LOGCATEGORY_NETWORK, "Could not get the hostname"); + } + } + discurl[0] = UA_String_fromChars(discoveryUrlBuffer); + config->applicationDescription.discoveryUrls = discurl; + return UA_STATUSCODE_GOOD; +} + +UA_EXPORT UA_StatusCode +UA_ServerConfig_addNetworkLayerTCP(UA_ServerConfig *conf, UA_UInt16 portNumber, + UA_UInt32 sendBufferSize, UA_UInt32 recvBufferSize) { /* Add a network layer */ - conf->networkLayers = (UA_ServerNetworkLayer *) - UA_malloc(sizeof(UA_ServerNetworkLayer)); - if(!conf->networkLayers) + UA_ServerNetworkLayer *tmp = (UA_ServerNetworkLayer *) + UA_realloc(conf->networkLayers, sizeof(UA_ServerNetworkLayer) * (1 + conf->networkLayersSize)); + if(!tmp) return UA_STATUSCODE_BADOUTOFMEMORY; + conf->networkLayers = tmp; - conf->networkLayers[0] = - UA_ServerNetworkLayerTCP(UA_ConnectionConfig_default, portNumber, conf->logger); - if (!conf->networkLayers[0].handle) + UA_ConnectionConfig config = UA_ConnectionConfig_default; + if (sendBufferSize > 0) + config.sendBufferSize = sendBufferSize; + if (recvBufferSize > 0) + config.recvBufferSize = recvBufferSize; + + conf->networkLayers[conf->networkLayersSize] = + UA_ServerNetworkLayerTCP(config, portNumber, &conf->logger); + if (!conf->networkLayers[conf->networkLayersSize].handle) return UA_STATUSCODE_BADOUTOFMEMORY; - conf->networkLayersSize = 1; + conf->networkLayersSize++; return UA_STATUSCODE_GOOD; } -UA_ServerConfig * -UA_ServerConfig_new_minimal(UA_UInt16 portNumber, - const UA_ByteString *certificate) { - UA_ServerConfig *conf = createDefaultConfig(); - - UA_StatusCode retval = UA_Nodestore_default_new(&conf->nodestore); - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } - - if(addDefaultNetworkLayers(conf, portNumber) != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } - - /* Allocate the endpoint */ - conf->endpoints = (UA_Endpoint *)UA_malloc(sizeof(UA_Endpoint)); - if(!conf->endpoints) { - UA_ServerConfig_delete(conf); - return NULL; - } - conf->endpointsSize = 1; +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyNone(UA_ServerConfig *config, + const UA_ByteString *certificate) { + UA_StatusCode retval; - /* Populate the endpoint */ + /* Allocate the SecurityPolicies */ + UA_SecurityPolicy *tmp = (UA_SecurityPolicy *) + UA_realloc(config->securityPolicies, sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize)); + if(!tmp) + return UA_STATUSCODE_BADOUTOFMEMORY; + config->securityPolicies = tmp; + + /* Populate the SecurityPolicies */ UA_ByteString localCertificate = UA_BYTESTRING_NULL; if(certificate) localCertificate = *certificate; - retval = - createSecurityPolicyNoneEndpoint(conf, &conf->endpoints[0], localCertificate); - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } + retval = UA_SecurityPolicy_None(&config->securityPolicies[config->securityPoliciesSize], NULL, + localCertificate, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->securityPoliciesSize++; - return conf; + return UA_STATUSCODE_GOOD; } -#ifdef UA_ENABLE_ENCRYPTION +UA_EXPORT UA_StatusCode +UA_ServerConfig_addEndpoint(UA_ServerConfig *config, const UA_String securityPolicyUri, + UA_MessageSecurityMode securityMode) +{ + UA_StatusCode retval; -UA_ServerConfig * -UA_ServerConfig_new_basic128rsa15(UA_UInt16 portNumber, - const UA_ByteString *certificate, - const UA_ByteString *privateKey, - const UA_ByteString *trustList, - size_t trustListSize, - const UA_ByteString *revocationList, - size_t revocationListSize) { - UA_ServerConfig *conf = createDefaultConfig(); - - UA_StatusCode retval = UA_CertificateVerification_Trustlist(&conf->certificateVerification, - trustList, trustListSize, - revocationList, revocationListSize); - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + /* Allocate the endpoint */ + UA_EndpointDescription * tmp = (UA_EndpointDescription *) + UA_realloc(config->endpoints, sizeof(UA_EndpointDescription) * (1 + config->endpointsSize)); + if(!tmp) { + return UA_STATUSCODE_BADOUTOFMEMORY; } + config->endpoints = tmp; - retval = UA_Nodestore_default_new(&conf->nodestore); - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + /* Lookup the security policy */ + const UA_SecurityPolicy *policy = NULL; + for (size_t i = 0; i < config->securityPoliciesSize; ++i) { + if (UA_String_equal(&securityPolicyUri, &config->securityPolicies[i].policyUri)) { + policy = &config->securityPolicies[i]; + break; + } } + if (!policy) + return UA_STATUSCODE_BADINVALIDARGUMENT; - if(addDefaultNetworkLayers(conf, portNumber) != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } + /* Populate the endpoint */ + retval = createEndpoint(config, &config->endpoints[config->endpointsSize], + policy, securityMode); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->endpointsSize++; - if(trustListSize == 0) - UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "No CA trust-list provided. Any remote certificate will be accepted."); + return UA_STATUSCODE_GOOD; +} + +UA_EXPORT UA_StatusCode +UA_ServerConfig_addAllEndpoints(UA_ServerConfig *config) { + UA_StatusCode retval; /* Allocate the endpoints */ - conf->endpointsSize = 0; - conf->endpoints = (UA_Endpoint *)UA_malloc(sizeof(UA_Endpoint) * 3); - if(!conf->endpoints) { - UA_ServerConfig_delete(conf); - return NULL; + UA_EndpointDescription * tmp = (UA_EndpointDescription *) + UA_realloc(config->endpoints, sizeof(UA_EndpointDescription) * (2 * config->securityPoliciesSize + config->endpointsSize)); + if(!tmp) { + return UA_STATUSCODE_BADOUTOFMEMORY; } + config->endpoints = tmp; /* Populate the endpoints */ - ++conf->endpointsSize; - retval = createSecurityPolicyNoneEndpoint(conf, &conf->endpoints[0], *certificate); - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } - - ++conf->endpointsSize; - retval = createSecurityPolicyBasic128Rsa15Endpoint(conf, &conf->endpoints[1], - UA_MESSAGESECURITYMODE_SIGN, *certificate, - *privateKey); - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } + for (size_t i = 0; i < config->securityPoliciesSize; ++i) { + if (UA_String_equal(&UA_SECURITY_POLICY_NONE_URI, &config->securityPolicies[i].policyUri)) { + retval = createEndpoint(config, &config->endpoints[config->endpointsSize], + &config->securityPolicies[i], UA_MESSAGESECURITYMODE_NONE); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->endpointsSize++; + } else { + retval = createEndpoint(config, &config->endpoints[config->endpointsSize], + &config->securityPolicies[i], UA_MESSAGESECURITYMODE_SIGN); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->endpointsSize++; - ++conf->endpointsSize; - retval = createSecurityPolicyBasic128Rsa15Endpoint(conf, &conf->endpoints[2], - UA_MESSAGESECURITYMODE_SIGNANDENCRYPT, *certificate, - *privateKey); - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + retval = createEndpoint(config, &config->endpoints[config->endpointsSize], + &config->securityPolicies[i], UA_MESSAGESECURITYMODE_SIGNANDENCRYPT); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->endpointsSize++; + } } - return conf; + return UA_STATUSCODE_GOOD; } -UA_ServerConfig * -UA_ServerConfig_new_basic256sha256(UA_UInt16 portNumber, - const UA_ByteString *certificate, - const UA_ByteString *privateKey, - const UA_ByteString *trustList, - size_t trustListSize, - const UA_ByteString *revocationList, - size_t revocationListSize) { - UA_ServerConfig *conf = createDefaultConfig(); +UA_EXPORT UA_StatusCode +UA_ServerConfig_setMinimalCustomBuffer(UA_ServerConfig *config, UA_UInt16 portNumber, + const UA_ByteString *certificate, + UA_UInt32 sendBufferSize, + UA_UInt32 recvBufferSize) { + if (!config) + return UA_STATUSCODE_BADINVALIDARGUMENT; - UA_StatusCode retval = UA_CertificateVerification_Trustlist(&conf->certificateVerification, - trustList, trustListSize, - revocationList, revocationListSize); + UA_StatusCode retval = setDefaultConfig(config); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(config); + return retval; } - retval = UA_Nodestore_default_new(&conf->nodestore); + retval = addDefaultNetworkLayers(config, portNumber, sendBufferSize, recvBufferSize); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } - - if(addDefaultNetworkLayers(conf, portNumber) != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(config); + return retval; } - - if(trustListSize == 0) - UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "No CA trust-list provided. Any remote certificate will be accepted."); - - /* Allocate the endpoints */ - conf->endpointsSize = 0; - conf->endpoints = (UA_Endpoint *)UA_malloc(sizeof(UA_Endpoint) * 3); - if(!conf->endpoints) { - UA_ServerConfig_delete(conf); - return NULL; + + retval = addDiscoveryUrl(config, portNumber); + if (retval != UA_STATUSCODE_GOOD) { + UA_ServerConfig_clean(config); + return retval; } - /* Populate the endpoints */ - ++conf->endpointsSize; - retval = createSecurityPolicyNoneEndpoint(conf, &conf->endpoints[0], *certificate); + /* Allocate the SecurityPolicies */ + retval = UA_ServerConfig_addSecurityPolicyNone(config, certificate); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(config); + return retval; } - ++conf->endpointsSize; - retval = createSecurityPolicyBasic256Sha256Endpoint(conf, &conf->endpoints[1], - UA_MESSAGESECURITYMODE_SIGN, *certificate, - *privateKey); + /* Initialize the Access Control plugin */ + retval = UA_AccessControl_default(config, true, + &config->securityPolicies[config->securityPoliciesSize-1].policyUri, + usernamePasswordsSize, usernamePasswords); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(config); + return retval; } - ++conf->endpointsSize; - retval = createSecurityPolicyBasic256Sha256Endpoint(conf, &conf->endpoints[2], - UA_MESSAGESECURITYMODE_SIGNANDENCRYPT, *certificate, - *privateKey); + /* Allocate the endpoint */ + retval = UA_ServerConfig_addEndpoint(config, UA_SECURITY_POLICY_NONE_URI, UA_MESSAGESECURITYMODE_NONE); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(config); + return retval; } - return conf; + return UA_STATUSCODE_GOOD; } -UA_ServerConfig * -UA_ServerConfig_new_allSecurityPolicies(UA_UInt16 portNumber, - const UA_ByteString *certificate, - const UA_ByteString *privateKey, - const UA_ByteString *trustList, - size_t trustListSize, - const UA_ByteString *revocationList, - size_t revocationListSize) { - UA_ServerConfig *conf = createDefaultConfig(); +#ifdef UA_ENABLE_ENCRYPTION - UA_StatusCode retval = UA_CertificateVerification_Trustlist(&conf->certificateVerification, - trustList, trustListSize, - revocationList, revocationListSize); - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyBasic128Rsa15(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey) { + UA_StatusCode retval; + + /* Allocate the SecurityPolicies */ + UA_SecurityPolicy *tmp = (UA_SecurityPolicy *) + UA_realloc(config->securityPolicies, sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize)); + if(!tmp) + return UA_STATUSCODE_BADOUTOFMEMORY; + config->securityPolicies = tmp; + + /* Populate the SecurityPolicies */ + UA_ByteString localCertificate = UA_BYTESTRING_NULL; + UA_ByteString localPrivateKey = UA_BYTESTRING_NULL; + if(certificate) + localCertificate = *certificate; + if(privateKey) + localPrivateKey = *privateKey; + retval = UA_SecurityPolicy_Basic128Rsa15(&config->securityPolicies[config->securityPoliciesSize], + &config->certificateVerification, + localCertificate, localPrivateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->securityPoliciesSize++; + + return UA_STATUSCODE_GOOD; +} + +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyBasic256(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey) { + UA_StatusCode retval; + + /* Allocate the SecurityPolicies */ + UA_SecurityPolicy *tmp = (UA_SecurityPolicy *) + UA_realloc(config->securityPolicies, sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize)); + if(!tmp) + return UA_STATUSCODE_BADOUTOFMEMORY; + config->securityPolicies = tmp; + + /* Populate the SecurityPolicies */ + UA_ByteString localCertificate = UA_BYTESTRING_NULL; + UA_ByteString localPrivateKey = UA_BYTESTRING_NULL; + if(certificate) + localCertificate = *certificate; + if(privateKey) + localPrivateKey = *privateKey; + retval = UA_SecurityPolicy_Basic256(&config->securityPolicies[config->securityPoliciesSize], + &config->certificateVerification, + localCertificate, localPrivateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->securityPoliciesSize++; + + return UA_STATUSCODE_GOOD; +} + +UA_EXPORT UA_StatusCode +UA_ServerConfig_addSecurityPolicyBasic256Sha256(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey) { + UA_StatusCode retval; + + /* Allocate the SecurityPolicies */ + UA_SecurityPolicy *tmp = (UA_SecurityPolicy *) + UA_realloc(config->securityPolicies, sizeof(UA_SecurityPolicy) * (1 + config->securityPoliciesSize)); + if(!tmp) + return UA_STATUSCODE_BADOUTOFMEMORY; + config->securityPolicies = tmp; + + /* Populate the SecurityPolicies */ + UA_ByteString localCertificate = UA_BYTESTRING_NULL; + UA_ByteString localPrivateKey = UA_BYTESTRING_NULL; + if(certificate) + localCertificate = *certificate; + if(privateKey) + localPrivateKey = *privateKey; + retval = UA_SecurityPolicy_Basic256Sha256(&config->securityPolicies[config->securityPoliciesSize], + &config->certificateVerification, + localCertificate, localPrivateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->securityPoliciesSize++; + + return UA_STATUSCODE_GOOD; +} + +UA_EXPORT UA_StatusCode +UA_ServerConfig_addAllSecurityPolicies(UA_ServerConfig *config, + const UA_ByteString *certificate, + const UA_ByteString *privateKey) { + UA_StatusCode retval; + + /* Allocate the SecurityPolicies */ + UA_SecurityPolicy *tmp = (UA_SecurityPolicy *) + UA_realloc(config->securityPolicies, sizeof(UA_SecurityPolicy) * (4 + config->securityPoliciesSize)); + if(!tmp) + return UA_STATUSCODE_BADOUTOFMEMORY; + config->securityPolicies = tmp; + + /* Populate the SecurityPolicies */ + UA_ByteString localCertificate = UA_BYTESTRING_NULL; + UA_ByteString localPrivateKey = UA_BYTESTRING_NULL; + if(certificate) + localCertificate = *certificate; + if(privateKey) + localPrivateKey = *privateKey; - retval = UA_Nodestore_default_new(&conf->nodestore); + retval = UA_SecurityPolicy_None(&config->securityPolicies[config->securityPoliciesSize], NULL, + localCertificate, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->securityPoliciesSize++; + + retval = UA_SecurityPolicy_Basic128Rsa15(&config->securityPolicies[config->securityPoliciesSize], + &config->certificateVerification, + localCertificate, localPrivateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->securityPoliciesSize++; + + retval = UA_SecurityPolicy_Basic256(&config->securityPolicies[config->securityPoliciesSize], + &config->certificateVerification, + localCertificate, localPrivateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->securityPoliciesSize++; + + retval = UA_SecurityPolicy_Basic256Sha256(&config->securityPolicies[config->securityPoliciesSize], + &config->certificateVerification, + localCertificate, localPrivateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + config->securityPoliciesSize++; + + return retval; +} + +UA_EXPORT UA_StatusCode +UA_ServerConfig_setDefaultWithSecurityPolicies(UA_ServerConfig *conf, + UA_UInt16 portNumber, + const UA_ByteString *certificate, + const UA_ByteString *privateKey, + const UA_ByteString *trustList, + size_t trustListSize, + const UA_ByteString *issuerList, + size_t issuerListSize, + const UA_ByteString *revocationList, + size_t revocationListSize) { + UA_StatusCode retval = setDefaultConfig(conf); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(conf); + return retval; } - if(addDefaultNetworkLayers(conf, portNumber) != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; - } + retval = UA_CertificateVerification_Trustlist(&conf->certificateVerification, + trustList, trustListSize, + issuerList, issuerListSize, + revocationList, revocationListSize); + if (retval != UA_STATUSCODE_GOOD) + return retval; if(trustListSize == 0) - UA_LOG_WARNING(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, - "No CA trust-list provided. Any remote certificate will be accepted."); - - /* Allocate the endpoints */ - conf->endpointsSize = 0; - conf->endpoints = (UA_Endpoint *)UA_malloc(sizeof(UA_Endpoint) * 5); - if(!conf->endpoints) { - UA_ServerConfig_delete(conf); - return NULL; - } + UA_LOG_WARNING(&conf->logger, UA_LOGCATEGORY_USERLAND, + "No CA trust-list provided. " + "Any remote certificate will be accepted."); - /* Populate the endpoints */ - retval = createSecurityPolicyNoneEndpoint(conf, &conf->endpoints[conf->endpointsSize], *certificate); - ++conf->endpointsSize; + retval = addDefaultNetworkLayers(conf, portNumber, 0, 0); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(conf); + return retval; } - retval = createSecurityPolicyBasic128Rsa15Endpoint(conf, &conf->endpoints[conf->endpointsSize], - UA_MESSAGESECURITYMODE_SIGN, *certificate, - *privateKey); - ++conf->endpointsSize; - if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + retval = addDiscoveryUrl(conf, portNumber); + if (retval != UA_STATUSCODE_GOOD) { + UA_ServerConfig_clean(conf); + return retval; } - retval = createSecurityPolicyBasic128Rsa15Endpoint(conf, &conf->endpoints[conf->endpointsSize], - UA_MESSAGESECURITYMODE_SIGNANDENCRYPT, *certificate, - *privateKey); - ++conf->endpointsSize; + retval = UA_ServerConfig_addAllSecurityPolicies(conf, certificate, privateKey); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(conf); + return retval; } - retval = createSecurityPolicyBasic256Sha256Endpoint(conf, &conf->endpoints[conf->endpointsSize], - UA_MESSAGESECURITYMODE_SIGN, *certificate, - *privateKey); - ++conf->endpointsSize; + retval = UA_AccessControl_default(conf, true, + &conf->securityPolicies[conf->securityPoliciesSize-1].policyUri, + usernamePasswordsSize, usernamePasswords); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(conf); + return retval; } - retval = createSecurityPolicyBasic256Sha256Endpoint(conf, &conf->endpoints[conf->endpointsSize], - UA_MESSAGESECURITYMODE_SIGNANDENCRYPT, *certificate, - *privateKey); - ++conf->endpointsSize; + retval = UA_ServerConfig_addAllEndpoints(conf); if(retval != UA_STATUSCODE_GOOD) { - UA_ServerConfig_delete(conf); - return NULL; + UA_ServerConfig_clean(conf); + return retval; } - return conf; + return UA_STATUSCODE_GOOD; } - #endif -void -UA_ServerConfig_delete(UA_ServerConfig *config) { - if(!config) - return; +/***************************/ +/* Default Client Settings */ +/***************************/ - /* Server Description */ - UA_BuildInfo_deleteMembers(&config->buildInfo); - UA_ApplicationDescription_deleteMembers(&config->applicationDescription); -#ifdef UA_ENABLE_DISCOVERY - UA_String_deleteMembers(&config->mdnsServerName); - UA_Array_delete(config->serverCapabilities, config->serverCapabilitiesSize, - &UA_TYPES[UA_TYPES_STRING]); - config->serverCapabilities = NULL; - config->serverCapabilitiesSize = 0; -#endif +static UA_INLINE void +UA_ClientConnectionTCP_poll_callback(UA_Client *client, void *data) { + UA_ClientConnectionTCP_poll(client, data); +} - /* Nodestore */ - if(config->nodestore.deleteNodestore) - config->nodestore.deleteNodestore(config->nodestore.context); +UA_StatusCode +UA_ClientConfig_setDefault(UA_ClientConfig *config) { + config->timeout = 5000; + config->secureChannelLifeTime = 10 * 60 * 1000; /* 10 minutes */ - /* Custom DataTypes */ - for(size_t i = 0; i < config->customDataTypesSize; ++i) - UA_free(config->customDataTypes[i].members); - UA_free(config->customDataTypes); - config->customDataTypes = NULL; - config->customDataTypesSize = 0; + config->logger.log = UA_Log_Stdout_log; + config->logger.context = NULL; + config->logger.clear = UA_Log_Stdout_clear; - /* Networking */ - for(size_t i = 0; i < config->networkLayersSize; ++i) - config->networkLayers[i].deleteMembers(&config->networkLayers[i]); - UA_free(config->networkLayers); - config->networkLayers = NULL; - config->networkLayersSize = 0; - UA_String_deleteMembers(&config->customHostname); - config->customHostname = UA_STRING_NULL; + config->localConnectionConfig = UA_ConnectionConfig_default; - for(size_t i = 0; i < config->endpointsSize; ++i) { - UA_SecurityPolicy *policy = &config->endpoints[i].securityPolicy; - policy->deleteMembers(policy); - UA_EndpointDescription_deleteMembers(&config->endpoints[i].endpointDescription); + /* Certificate Verification that accepts every certificate. Can be + * overwritten when the policy is specialized. */ + UA_CertificateVerification_AcceptAll(&config->certificateVerification); + + /* With encryption enabled, the applicationUri needs to match the URI from + * the certificate */ + config->clientDescription.applicationUri = UA_STRING_ALLOC(APPLICATION_URI); + config->clientDescription.applicationType = UA_APPLICATIONTYPE_CLIENT; + + if(config->securityPoliciesSize > 0) { + UA_LOG_ERROR(&config->logger, UA_LOGCATEGORY_NETWORK, + "Could not initialize a config that already has SecurityPolicies"); + return UA_STATUSCODE_BADINTERNALERROR; } - UA_free(config->endpoints); - config->endpoints = NULL; - config->endpointsSize = 0; - /* Certificate Validation */ - config->certificateVerification.deleteMembers(&config->certificateVerification); + config->securityPolicies = (UA_SecurityPolicy*)UA_malloc(sizeof(UA_SecurityPolicy)); + if(!config->securityPolicies) + return UA_STATUSCODE_BADOUTOFMEMORY; + UA_StatusCode retval = UA_SecurityPolicy_None(config->securityPolicies, NULL, + UA_BYTESTRING_NULL, &config->logger); + if(retval != UA_STATUSCODE_GOOD) { + UA_free(config->securityPolicies); + config->securityPolicies = NULL; + return retval; + } + config->securityPoliciesSize = 1; - /* Access Control */ - config->accessControl.deleteMembers(&config->accessControl); + config->connectionFunc = UA_ClientConnectionTCP; + config->initConnectionFunc = UA_ClientConnectionTCP_init; /* for async client */ + config->pollConnectionFunc = UA_ClientConnectionTCP_poll_callback; /* for async connection */ - UA_free(config); -} + config->customDataTypes = NULL; + config->stateCallback = NULL; + config->connectivityCheckInterval = 0; -/***************************/ -/* Default Client Settings */ -/***************************/ + config->requestedSessionTimeout = 1200000; /* requestedSessionTimeout */ + + config->inactivityCallback = NULL; + config->clientContext = NULL; -const UA_ClientConfig UA_ClientConfig_default = { - 5000, /* .timeout, 5 seconds */ - 10 * 60 * 1000, /* .secureChannelLifeTime, 10 minutes */ - UA_Log_Stdout, /* .logger */ - { /* .localConnectionConfig */ - 0, /* .protocolVersion */ - 65535, /* .sendBufferSize, 64k per chunk */ - 65535, /* .recvBufferSize, 64k per chunk */ - 0, /* .maxMessageSize, 0 -> unlimited */ - 0 /* .maxChunkCount, 0 -> unlimited */ - }, - UA_ClientConnectionTCP, /* .connectionFunc */ - - 0, /* .customDataTypesSize */ - NULL, /*.customDataTypes */ - - NULL, /*.stateCallback */ -#ifdef UA_ENABLE_SUBSCRIPTIONS - NULL, /*.subscriptionInactivityCallback */ -#endif - NULL, /*.inactivityCallback */ - NULL, /*.clientContext */ #ifdef UA_ENABLE_SUBSCRIPTIONS - 10, /* .outStandingPublishRequests */ + config->outStandingPublishRequests = 10; + config->subscriptionInactivityCallback = NULL; #endif - 0 /* .connectivityCheckInterval */ -}; -UA_ClientConfig UA_Server_getClientConfig(void) -{ - return UA_ClientConfig_default; + return UA_STATUSCODE_GOOD; +} + +#ifdef UA_ENABLE_ENCRYPTION +UA_StatusCode +UA_ClientConfig_setDefaultEncryption(UA_ClientConfig *config, + UA_ByteString localCertificate, UA_ByteString privateKey, + const UA_ByteString *trustList, size_t trustListSize, + const UA_ByteString *revocationList, size_t revocationListSize) { + UA_StatusCode retval = UA_ClientConfig_setDefault(config); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + retval = UA_CertificateVerification_Trustlist(&config->certificateVerification, + trustList, trustListSize, + NULL, 0, + revocationList, revocationListSize); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + /* Populate SecurityPolicies */ + UA_SecurityPolicy *sp = (UA_SecurityPolicy*) + UA_realloc(config->securityPolicies, sizeof(UA_SecurityPolicy) * 4); + if(!sp) + return UA_STATUSCODE_BADOUTOFMEMORY; + config->securityPolicies = sp; + + retval = UA_SecurityPolicy_Basic128Rsa15(&config->securityPolicies[1], + &config->certificateVerification, + localCertificate, privateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + ++config->securityPoliciesSize; + + retval = UA_SecurityPolicy_Basic256(&config->securityPolicies[2], + &config->certificateVerification, + localCertificate, privateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + ++config->securityPoliciesSize; + + retval = UA_SecurityPolicy_Basic256Sha256(&config->securityPolicies[3], + &config->certificateVerification, + localCertificate, privateKey, &config->logger); + if(retval != UA_STATUSCODE_GOOD) + return retval; + ++config->securityPoliciesSize; + + return UA_STATUSCODE_GOOD; } +#endif -/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_securitypolicy_none.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/securityPolicies/ua_securitypolicy_none.c" ***********************************/ /* This work is licensed under a Creative Commons CCZero 1.0 Universal License. - * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. * * Copyright 2017-2018 (c) Mark Giraud, Fraunhofer IOSB * Copyright 2017 (c) Stefan Profanter, fortiss GmbH @@ -41941,6 +51055,9 @@ generateNonce_none(const UA_SecurityPolicy *securityPolicy, UA_ByteString *out) if(securityPolicy == NULL || out == NULL) return UA_STATUSCODE_BADINTERNALERROR; + if(out->length == 0) + return UA_STATUSCODE_GOOD; + /* Fill blocks of four byte */ size_t i = 0; while(i + 3 < out->length) { @@ -41979,14 +51096,25 @@ compareCertificate_none(const void *channelContext, return UA_STATUSCODE_GOOD; } +static UA_StatusCode +updateCertificateAndPrivateKey_none(UA_SecurityPolicy *policy, + const UA_ByteString newCertificate, + const UA_ByteString newPrivateKey) { + UA_ByteString_deleteMembers(&policy->localCertificate); + UA_ByteString_copy(&newCertificate, &policy->localCertificate); + return UA_STATUSCODE_GOOD; +} + + static void policy_deletemembers_none(UA_SecurityPolicy *policy) { UA_ByteString_deleteMembers(&policy->localCertificate); } UA_StatusCode -UA_SecurityPolicy_None(UA_SecurityPolicy *policy, UA_CertificateVerification *certificateVerification, - const UA_ByteString localCertificate, UA_Logger logger) { +UA_SecurityPolicy_None(UA_SecurityPolicy *policy, + UA_CertificateVerification *certificateVerification, + const UA_ByteString localCertificate, const UA_Logger *logger) { policy->policyContext = (void *)(uintptr_t)logger; policy->policyUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None"); policy->logger = logger; @@ -42037,33 +51165,280 @@ UA_SecurityPolicy_None(UA_SecurityPolicy *policy, UA_CertificateVerification *ce policy->channelModule.setRemoteSymSigningKey = setContextValue_none; policy->channelModule.setRemoteSymIv = setContextValue_none; policy->channelModule.compareCertificate = compareCertificate_none; + policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_none; policy->deleteMembers = policy_deletemembers_none; return UA_STATUSCODE_GOOD; } -/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_securitypolicy_basic128rsa15.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/securityPolicies/securitypolicy_mbedtls_common.c" ***********************************/ + + +#ifdef UA_ENABLE_ENCRYPTION + + +#include <mbedtls/aes.h> +#include <mbedtls/ctr_drbg.h> +#include <mbedtls/entropy.h> +#include <mbedtls/entropy_poll.h> +#include <mbedtls/error.h> +#include <mbedtls/md.h> +#include <mbedtls/sha1.h> +#include <mbedtls/version.h> +#include <mbedtls/x509_crt.h> + +void +swapBuffers(UA_ByteString *const bufA, UA_ByteString *const bufB) { + UA_ByteString tmp = *bufA; + *bufA = *bufB; + *bufB = tmp; +} + +void +mbedtls_hmac(mbedtls_md_context_t *context, const UA_ByteString *key, + const UA_ByteString *in, unsigned char *out) { + mbedtls_md_hmac_starts(context, key->data, key->length); + mbedtls_md_hmac_update(context, in->data, in->length); + mbedtls_md_hmac_finish(context, out); +} + +UA_StatusCode +mbedtls_generateKey(mbedtls_md_context_t *context, + const UA_ByteString *secret, const UA_ByteString *seed, + UA_ByteString *out) { + size_t hashLen = (size_t)mbedtls_md_get_size(context->md_info); + + UA_ByteString A_and_seed; + UA_ByteString_allocBuffer(&A_and_seed, hashLen + seed->length); + memcpy(A_and_seed.data + hashLen, seed->data, seed->length); + + UA_ByteString ANext_and_seed; + UA_ByteString_allocBuffer(&ANext_and_seed, hashLen + seed->length); + memcpy(ANext_and_seed.data + hashLen, seed->data, seed->length); + + UA_ByteString A = { + hashLen, + A_and_seed.data + }; + + UA_ByteString ANext = { + hashLen, + ANext_and_seed.data + }; + + mbedtls_hmac(context, secret, seed, A.data); + + UA_StatusCode retval = 0; + for(size_t offset = 0; offset < out->length; offset += hashLen) { + UA_ByteString outSegment = { + hashLen, + out->data + offset + }; + UA_Boolean bufferAllocated = UA_FALSE; + // Not enough room in out buffer to write the hash. + if(offset + hashLen > out->length) { + outSegment.data = NULL; + outSegment.length = 0; + retval = UA_ByteString_allocBuffer(&outSegment, hashLen); + if(retval != UA_STATUSCODE_GOOD) { + UA_ByteString_deleteMembers(&A_and_seed); + UA_ByteString_deleteMembers(&ANext_and_seed); + return retval; + } + bufferAllocated = UA_TRUE; + } + + mbedtls_hmac(context, secret, &A_and_seed, outSegment.data); + mbedtls_hmac(context, secret, &A, ANext.data); + + if(retval != UA_STATUSCODE_GOOD) { + if(bufferAllocated) + UA_ByteString_deleteMembers(&outSegment); + UA_ByteString_deleteMembers(&A_and_seed); + UA_ByteString_deleteMembers(&ANext_and_seed); + return retval; + } + + if(bufferAllocated) { + memcpy(out->data + offset, outSegment.data, out->length - offset); + UA_ByteString_deleteMembers(&outSegment); + } + + swapBuffers(&ANext_and_seed, &A_and_seed); + swapBuffers(&ANext, &A); + } + + UA_ByteString_deleteMembers(&A_and_seed); + UA_ByteString_deleteMembers(&ANext_and_seed); + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +mbedtls_verifySig_sha1(mbedtls_x509_crt *certificate, const UA_ByteString *message, + const UA_ByteString *signature) { + /* Compute the sha1 hash */ + unsigned char hash[UA_SHA1_LENGTH]; +#if MBEDTLS_VERSION_NUMBER >= 0x02070000 + mbedtls_sha1_ret(message->data, message->length, hash); +#else + mbedtls_sha1(message->data, message->length, hash); +#endif + + /* Set the RSA settings */ + mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(certificate->pk); + if(!rsaContext) + return UA_STATUSCODE_BADINTERNALERROR; + mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0); + + /* Verify */ + int mbedErr = mbedtls_pk_verify(&certificate->pk, + MBEDTLS_MD_SHA1, hash, UA_SHA1_LENGTH, + signature->data, signature->length); + if(mbedErr) + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +mbedtls_sign_sha1(mbedtls_pk_context *localPrivateKey, + mbedtls_ctr_drbg_context *drbgContext, + const UA_ByteString *message, + UA_ByteString *signature) { + unsigned char hash[UA_SHA1_LENGTH]; +#if MBEDTLS_VERSION_NUMBER >= 0x02070000 + mbedtls_sha1_ret(message->data, message->length, hash); +#else + mbedtls_sha1(message->data, message->length, hash); +#endif + + mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(*localPrivateKey); + mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0); + + size_t sigLen = 0; + int mbedErr = mbedtls_pk_sign(localPrivateKey, MBEDTLS_MD_SHA1, hash, + UA_SHA1_LENGTH, signature->data, &sigLen, + mbedtls_ctr_drbg_random, drbgContext); + if(mbedErr) + return UA_STATUSCODE_BADINTERNALERROR; + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +mbedtls_thumbprint_sha1(const UA_ByteString *certificate, + UA_ByteString *thumbprint) { + if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL)) + return UA_STATUSCODE_BADINTERNALERROR; + + if(thumbprint->length != UA_SHA1_LENGTH) + return UA_STATUSCODE_BADINTERNALERROR; + + /* The certificate thumbprint is always a 20 bit sha1 hash, see Part 4 of the Specification. */ +#if MBEDTLS_VERSION_NUMBER >= 0x02070000 + mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data); +#else + mbedtls_sha1(certificate->data, certificate->length, thumbprint->data); +#endif + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +mbedtls_encrypt_rsaOaep(mbedtls_rsa_context *context, + mbedtls_ctr_drbg_context *drbgContext, + UA_ByteString *data, const size_t plainTextBlockSize) { + if(data->length % plainTextBlockSize != 0) + return UA_STATUSCODE_BADINTERNALERROR; + + size_t max_blocks = data->length / plainTextBlockSize; + + UA_ByteString encrypted; + UA_StatusCode retval = UA_ByteString_allocBuffer(&encrypted, max_blocks * context->len); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + size_t lenDataToEncrypt = data->length; + size_t inOffset = 0; + size_t offset = 0; + const unsigned char *label = NULL; + while(lenDataToEncrypt >= plainTextBlockSize) { + int mbedErr = mbedtls_rsa_rsaes_oaep_encrypt(context, mbedtls_ctr_drbg_random, + drbgContext, MBEDTLS_RSA_PUBLIC, + label, 0, plainTextBlockSize, + data->data + inOffset, encrypted.data + offset); + if(mbedErr) { + UA_ByteString_deleteMembers(&encrypted); + return UA_STATUSCODE_BADINTERNALERROR; + } + + inOffset += plainTextBlockSize; + offset += context->len; + lenDataToEncrypt -= plainTextBlockSize; + } + + memcpy(data->data, encrypted.data, offset); + UA_ByteString_deleteMembers(&encrypted); + return UA_STATUSCODE_GOOD; +} + +UA_StatusCode +mbedtls_decrypt_rsaOaep(mbedtls_pk_context *localPrivateKey, + mbedtls_ctr_drbg_context *drbgContext, + UA_ByteString *data) { + mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(*localPrivateKey); + mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1); + + if(data->length % rsaContext->len != 0) + return UA_STATUSCODE_BADINTERNALERROR; + + size_t inOffset = 0; + size_t outOffset = 0; + size_t outLength = 0; + unsigned char buf[512]; + + while(inOffset < data->length) { + int mbedErr = mbedtls_rsa_rsaes_oaep_decrypt(rsaContext, mbedtls_ctr_drbg_random, + drbgContext, MBEDTLS_RSA_PRIVATE, + NULL, 0, &outLength, + data->data + inOffset, + buf, 512); + if(mbedErr) + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; + + memcpy(data->data + outOffset, buf, outLength); + inOffset += rsaContext->len; + outOffset += outLength; + } + + data->length = outOffset; + return UA_STATUSCODE_GOOD; +} + +#endif + +/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/securityPolicies/ua_securitypolicy_basic128rsa15.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2019 (c) Kalycito Infotech Private Limited + * */ #ifdef UA_ENABLE_ENCRYPTION + + #include <mbedtls/aes.h> -#include <mbedtls/md.h> -#include <mbedtls/x509_crt.h> #include <mbedtls/ctr_drbg.h> #include <mbedtls/entropy.h> #include <mbedtls/entropy_poll.h> #include <mbedtls/error.h> -#include <mbedtls/version.h> +#include <mbedtls/md.h> #include <mbedtls/sha1.h> - +#include <mbedtls/version.h> +#include <mbedtls/x509_crt.h> /* Notes: * mbedTLS' AES allows in-place encryption and decryption. Sow we don't have to @@ -42072,31 +51447,12 @@ UA_SecurityPolicy_None(UA_SecurityPolicy *policy, UA_CertificateVerification *ce */ #define UA_SECURITYPOLICY_BASIC128RSA15_RSAPADDING_LEN 11 -#define UA_SHA1_LENGTH 20 #define UA_SECURITYPOLICY_BASIC128RSA15_SYM_KEY_LENGTH 16 #define UA_BASIC128RSA15_SYM_SIGNING_KEY_LENGTH 16 #define UA_SECURITYPOLICY_BASIC128RSA15_SYM_ENCRYPTION_BLOCK_SIZE 16 #define UA_SECURITYPOLICY_BASIC128RSA15_SYM_PLAIN_TEXT_BLOCK_SIZE 16 #define UA_SECURITYPOLICY_BASIC128RSA15_MINASYMKEYLENGTH 128 -#define UA_SECURITYPOLICY_BASIC128RSA15_MAXASYMKEYLENGTH 256 - -#define UA_LOG_MBEDERR \ - char errBuff[300]; \ - mbedtls_strerror(mbedErr, errBuff, 300); \ - UA_LOG_WARNING(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, \ - "mbedTLS returned an error: %s", errBuff); \ - -#define UA_MBEDTLS_ERRORHANDLING(errorcode) \ - if(mbedErr) { \ - UA_LOG_MBEDERR \ - retval = errorcode; \ - } - -#define UA_MBEDTLS_ERRORHANDLING_RETURN(errorcode) \ - if(mbedErr) { \ - UA_LOG_MBEDERR \ - return errorcode; \ - } +#define UA_SECURITYPOLICY_BASIC128RSA15_MAXASYMKEYLENGTH 512 typedef struct { const UA_SecurityPolicy *securityPolicy; @@ -42122,7 +51478,6 @@ typedef struct { mbedtls_x509_crt remoteCertificate; } Basic128Rsa15_ChannelContext; - /********************/ /* AsymmetricModule */ /********************/ @@ -42135,24 +51490,7 @@ asym_verify_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || message == NULL || signature == NULL || cc == NULL) return UA_STATUSCODE_BADINTERNALERROR; - /* Compute the sha1 hash */ - unsigned char hash[UA_SHA1_LENGTH]; -#if MBEDTLS_VERSION_NUMBER >= 0x02070000 - mbedtls_sha1_ret(message->data, message->length, hash); -#else - mbedtls_sha1(message->data, message->length, hash); -#endif - - /* Set the RSA settings */ - mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk); - mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0); - - /* Verify */ - int mbedErr = mbedtls_pk_verify(&cc->remoteCertificate.pk, - MBEDTLS_MD_SHA1, hash, UA_SHA1_LENGTH, - signature->data, signature->length); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED); - return UA_STATUSCODE_GOOD; + return mbedtls_verifySig_sha1(&cc->remoteCertificate, message, signature); } static UA_StatusCode @@ -42163,25 +51501,9 @@ asym_sign_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || message == NULL || signature == NULL || cc == NULL) return UA_STATUSCODE_BADINTERNALERROR; - unsigned char hash[UA_SHA1_LENGTH]; -#if MBEDTLS_VERSION_NUMBER >= 0x02070000 - mbedtls_sha1_ret(message->data, message->length, hash); -#else - mbedtls_sha1(message->data, message->length, hash); -#endif - Basic128Rsa15_PolicyContext *pc = cc->policyContext; - mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(pc->localPrivateKey); - mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0); - - size_t sigLen = 0; - int mbedErr = mbedtls_pk_sign(&pc->localPrivateKey, - MBEDTLS_MD_SHA1, hash, - UA_SHA1_LENGTH, signature->data, - &sigLen, mbedtls_ctr_drbg_random, - &pc->drbgContext); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR); - return UA_STATUSCODE_GOOD; + return mbedtls_sign_sha1(&pc->localPrivateKey, &pc->drbgContext, + message, signature); } static size_t @@ -42237,10 +51559,9 @@ asym_encrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, encrypted.length - offset, mbedtls_ctr_drbg_random, &pc->drbgContext); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR); - if(retval != UA_STATUSCODE_GOOD) { + if(mbedErr) { UA_ByteString_deleteMembers(&encrypted); - return retval; + return UA_STATUSCODE_BADINTERNALERROR; } inOffset += plainTextBlockSize; @@ -42261,45 +51582,31 @@ asym_decrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || cc == NULL || data == NULL) return UA_STATUSCODE_BADINTERNALERROR; - mbedtls_rsa_context *rsaContext = - mbedtls_pk_rsa(cc->policyContext->localPrivateKey); + mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->policyContext->localPrivateKey); mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V15, 0); if(data->length % rsaContext->len != 0) return UA_STATUSCODE_BADINTERNALERROR; - UA_ByteString decrypted; - UA_StatusCode retval = UA_ByteString_allocBuffer(&decrypted, data->length); - if(retval != UA_STATUSCODE_GOOD) - return retval; - - size_t lenDataToDecrypt = data->length; size_t inOffset = 0; - size_t offset = 0; + size_t outOffset = 0; size_t outLength = 0; - while(lenDataToDecrypt >= rsaContext->len) { + unsigned char buf[512]; + + while(inOffset < data->length) { int mbedErr = mbedtls_pk_decrypt(&cc->policyContext->localPrivateKey, data->data + inOffset, rsaContext->len, - decrypted.data + offset, &outLength, - decrypted.length - offset, NULL, NULL); + buf, &outLength, 512, NULL, NULL); if(mbedErr) - UA_ByteString_deleteMembers(&decrypted); // TODO: Maybe change error macro to jump to cleanup? - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED); + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; + memcpy(data->data + outOffset, buf, outLength); inOffset += rsaContext->len; - offset += outLength; - lenDataToDecrypt -= rsaContext->len; - } - - if(lenDataToDecrypt == 0) { - memcpy(data->data, decrypted.data, offset); - data->length = offset; - } else { - retval = UA_STATUSCODE_BADINTERNALERROR; + outOffset += outLength; } - UA_ByteString_deleteMembers(&decrypted); - return retval; + data->length = outOffset; + return UA_STATUSCODE_GOOD; } static size_t @@ -42328,19 +51635,7 @@ asym_makeThumbprint_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, UA_ByteString *thumbprint) { if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL) return UA_STATUSCODE_BADINTERNALERROR; - - if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL)) - return UA_STATUSCODE_BADINTERNALERROR; - - if(thumbprint->length != UA_SHA1_LENGTH) - return UA_STATUSCODE_BADINTERNALERROR; - -#if MBEDTLS_VERSION_NUMBER >= 0x02070000 - mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data); -#else - mbedtls_sha1(certificate->data, certificate->length, thumbprint->data); -#endif - return UA_STATUSCODE_GOOD; + return mbedtls_thumbprint_sha1(certificate, thumbprint); } static UA_StatusCode @@ -42360,14 +51655,6 @@ asymmetricModule_compareCertificateThumbprint_sp_basic128rsa15(const UA_Security /* SymmetricModule */ /*******************/ -static void -md_hmac(mbedtls_md_context_t *context, const UA_ByteString *key, - const UA_ByteString *in, unsigned char out[20]) { - mbedtls_md_hmac_starts(context, key->data, key->length); - mbedtls_md_hmac_update(context, in->data, in->length); - mbedtls_md_hmac_finish(context, out); -} - static UA_StatusCode sym_verify_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, Basic128Rsa15_ChannelContext *cc, @@ -42387,10 +51674,10 @@ sym_verify_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext; unsigned char mac[UA_SHA1_LENGTH]; - md_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac); + mbedtls_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac); /* Compare with Signature */ - if(memcmp(signature->data, mac, UA_SHA1_LENGTH) != 0) + if(!UA_constantTimeEqual(signature->data, mac, UA_SHA1_LENGTH)) return UA_STATUSCODE_BADSECURITYCHECKSFAILED; return UA_STATUSCODE_GOOD; } @@ -42403,8 +51690,8 @@ sym_sign_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, if(signature->length != UA_SHA1_LENGTH) return UA_STATUSCODE_BADINTERNALERROR; - md_hmac(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey, - message, signature->data); + mbedtls_hmac(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey, + message, signature->data); return UA_STATUSCODE_GOOD; } @@ -42463,7 +51750,8 @@ sym_encrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8); mbedtls_aes_context aesContext; int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + return UA_STATUSCODE_BADINTERNALERROR; UA_ByteString ivCopy; UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy); @@ -42472,7 +51760,8 @@ sym_encrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length, ivCopy.data, data->data, data->data); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + retval = UA_STATUSCODE_BADINTERNALERROR; UA_ByteString_deleteMembers(&ivCopy); return retval; } @@ -42484,8 +51773,8 @@ sym_decrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || cc == NULL || data == NULL) return UA_STATUSCODE_BADINTERNALERROR; - size_t encryptionBlockSize = - securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.getLocalBlockSize(securityPolicy, cc); + size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule. + encryptionAlgorithm.getRemoteBlockSize(securityPolicy, cc); if(cc->remoteSymIv.length != encryptionBlockSize) return UA_STATUSCODE_BADINTERNALERROR; @@ -42499,7 +51788,8 @@ sym_decrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8); mbedtls_aes_context aesContext; int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + return UA_STATUSCODE_BADINTERNALERROR; UA_ByteString ivCopy; UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy); @@ -42508,18 +51798,12 @@ sym_decrypt_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length, ivCopy.data, data->data, data->data); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + retval = UA_STATUSCODE_BADINTERNALERROR; UA_ByteString_deleteMembers(&ivCopy); return retval; } -static void -swapBuffers(UA_ByteString *const bufA, UA_ByteString *const bufB) { - UA_ByteString tmp = *bufA; - *bufA = *bufB; - *bufB = tmp; -} - static UA_StatusCode sym_generateKey_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, const UA_ByteString *secret, const UA_ByteString *seed, @@ -42530,73 +51814,7 @@ sym_generateKey_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext; - size_t hashLen = 0; - const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); - hashLen = (size_t)mbedtls_md_get_size(mdInfo); - - UA_ByteString A_and_seed; - UA_ByteString_allocBuffer(&A_and_seed, hashLen + seed->length); - memcpy(A_and_seed.data + hashLen, seed->data, seed->length); - - UA_ByteString ANext_and_seed; - UA_ByteString_allocBuffer(&ANext_and_seed, hashLen + seed->length); - memcpy(ANext_and_seed.data + hashLen, seed->data, seed->length); - - UA_ByteString A = { - hashLen, - A_and_seed.data - }; - - UA_ByteString ANext = { - hashLen, - ANext_and_seed.data - }; - - md_hmac(&pc->sha1MdContext, secret, seed, A.data); - - UA_StatusCode retval = 0; - for(size_t offset = 0; offset < out->length; offset += hashLen) { - UA_ByteString outSegment = { - hashLen, - out->data + offset - }; - UA_Boolean bufferAllocated = UA_FALSE; - // Not enough room in out buffer to write the hash. - if(offset + hashLen > out->length) { - outSegment.data = NULL; - outSegment.length = 0; - retval |= UA_ByteString_allocBuffer(&outSegment, hashLen); - if(retval != UA_STATUSCODE_GOOD) { - UA_ByteString_deleteMembers(&A_and_seed); - UA_ByteString_deleteMembers(&ANext_and_seed); - return retval; - } - bufferAllocated = UA_TRUE; - } - - md_hmac(&pc->sha1MdContext, secret, &A_and_seed, outSegment.data); - md_hmac(&pc->sha1MdContext, secret, &A, ANext.data); - - if(retval != UA_STATUSCODE_GOOD) { - if(bufferAllocated) - UA_ByteString_deleteMembers(&outSegment); - UA_ByteString_deleteMembers(&A_and_seed); - UA_ByteString_deleteMembers(&ANext_and_seed); - return retval; - } - - if(bufferAllocated) { - memcpy(out->data + offset, outSegment.data, out->length - offset); - UA_ByteString_deleteMembers(&outSegment); - } - - swapBuffers(&ANext_and_seed, &A_and_seed); - swapBuffers(&ANext, &A); - } - - UA_ByteString_deleteMembers(&A_and_seed); - UA_ByteString_deleteMembers(&ANext_and_seed); - return UA_STATUSCODE_GOOD; + return mbedtls_generateKey(&pc->sha1MdContext, secret, seed, out); } static UA_StatusCode @@ -42605,11 +51823,12 @@ sym_generateNonce_sp_basic128rsa15(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || securityPolicy->policyContext == NULL || out == NULL) return UA_STATUSCODE_BADINTERNALERROR; - Basic128Rsa15_PolicyContext *data = + Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext; - int mbedErr = mbedtls_ctr_drbg_random(&data->drbgContext, out->data, out->length); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADUNEXPECTEDERROR); + int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length); + if(mbedErr) + return UA_STATUSCODE_BADUNEXPECTEDERROR; return UA_STATUSCODE_GOOD; } @@ -42625,12 +51844,11 @@ parseRemoteCertificate_sp_basic128rsa15(Basic128Rsa15_ChannelContext *cc, if(remoteCertificate == NULL || cc == NULL) return UA_STATUSCODE_BADINTERNALERROR; - const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy; - /* Parse the certificate */ int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data, remoteCertificate->length); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED); + if(mbedErr) + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; /* Check the key length */ mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk); @@ -42759,15 +51977,11 @@ channelContext_compareCertificate_sp_basic128rsa15(const Basic128Rsa15_ChannelCo if(cc == NULL || certificate == NULL) return UA_STATUSCODE_BADINTERNALERROR; - const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy; - mbedtls_x509_crt cert; mbedtls_x509_crt_init(&cert); int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length); - if(mbedErr) { - UA_LOG_MBEDERR; + if(mbedErr) return UA_STATUSCODE_BADSECURITYCHECKSFAILED; - } UA_StatusCode retval = UA_STATUSCODE_GOOD; if(cert.raw.len != cc->remoteCertificate.raw.len || @@ -42806,6 +52020,54 @@ deleteMembers_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy) { } static UA_StatusCode +updateCertificateAndPrivateKey_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy, + const UA_ByteString newCertificate, + const UA_ByteString newPrivateKey) { + if(securityPolicy == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + if(securityPolicy->policyContext == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + Basic128Rsa15_PolicyContext *pc = (Basic128Rsa15_PolicyContext *)securityPolicy->policyContext; + + UA_ByteString_deleteMembers(&securityPolicy->localCertificate); + + UA_StatusCode retval = UA_ByteString_allocBuffer(&securityPolicy->localCertificate, newCertificate.length + 1); + if(retval != UA_STATUSCODE_GOOD) + return retval; + memcpy(securityPolicy->localCertificate.data, newCertificate.data, newCertificate.length); + securityPolicy->localCertificate.data[newCertificate.length] = '\0'; + securityPolicy->localCertificate.length--; + + /* Set the new private key */ + mbedtls_pk_free(&pc->localPrivateKey); + mbedtls_pk_init(&pc->localPrivateKey); + int mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, + newPrivateKey.data, newPrivateKey.length, + NULL, 0); + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; + goto error; + } + + retval = asym_makeThumbprint_sp_basic128rsa15(pc->securityPolicy, + &securityPolicy->localCertificate, + &pc->localCertThumbprint); + if(retval != UA_STATUSCODE_GOOD) + goto error; + + return retval; + + error: + UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Could not update certificate and private key"); + if(securityPolicy->policyContext != NULL) + deleteMembers_sp_basic128rsa15(securityPolicy); + return retval; +} + +static UA_StatusCode policyContext_newContext_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy, const UA_ByteString localPrivateKey) { UA_StatusCode retval = UA_STATUSCODE_GOOD; @@ -42831,34 +52093,38 @@ policyContext_newContext_sp_basic128rsa15(UA_SecurityPolicy *securityPolicy, /* Initialized the message digest */ const mbedtls_md_info_t *const mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); int mbedErr = mbedtls_md_setup(&pc->sha1MdContext, mdInfo, MBEDTLS_MD_SHA1); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADOUTOFMEMORY); - if(retval != UA_STATUSCODE_GOOD) + if(mbedErr) { + retval = UA_STATUSCODE_BADOUTOFMEMORY; goto error; + } /* Add the system entropy source */ mbedErr = mbedtls_entropy_add_source(&pc->entropyContext, mbedtls_platform_entropy_poll, NULL, 0, MBEDTLS_ENTROPY_SOURCE_STRONG); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED); - if(retval != UA_STATUSCODE_GOOD) + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; goto error; + } /* Seed the RNG */ char *personalization = "open62541-drbg"; mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func, &pc->entropyContext, (const unsigned char *)personalization, 14); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED); - if(retval != UA_STATUSCODE_GOOD) + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; goto error; + } /* Set the private key */ mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, localPrivateKey.data, localPrivateKey.length, NULL, 0); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED); - if(retval != UA_STATUSCODE_GOOD) + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; goto error; + } /* Set the local certificate thumbprint */ retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH); @@ -42881,9 +52147,10 @@ error: } UA_StatusCode -UA_SecurityPolicy_Basic128Rsa15(UA_SecurityPolicy *policy, UA_CertificateVerification *certificateVerification, - const UA_ByteString localCertificate, const UA_ByteString localPrivateKey, - UA_Logger logger) { +UA_SecurityPolicy_Basic128Rsa15(UA_SecurityPolicy *policy, + UA_CertificateVerification *certificateVerification, + const UA_ByteString localCertificate, + const UA_ByteString localPrivateKey, const UA_Logger *logger) { memset(policy, 0, sizeof(UA_SecurityPolicy)); policy->logger = logger; @@ -42923,7 +52190,7 @@ UA_SecurityPolicy_Basic128Rsa15(UA_SecurityPolicy *policy, UA_CertificateVerific UA_SecurityPolicyEncryptionAlgorithm *asym_encryptionAlgorithm = &asymmetricModule->cryptoModule.encryptionAlgorithm; - asym_encryptionAlgorithm->uri = UA_STRING("TODO: ALG URI"); + asym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#rsa-1_5"); asym_encryptionAlgorithm->encrypt = (UA_StatusCode(*)(const UA_SecurityPolicy *, void *, UA_ByteString *))asym_encrypt_sp_basic128rsa15; asym_encryptionAlgorithm->decrypt = @@ -43010,14 +52277,15 @@ UA_SecurityPolicy_Basic128Rsa15(UA_SecurityPolicy *policy, UA_CertificateVerific channelModule->compareCertificate = (UA_StatusCode (*)(const void *, const UA_ByteString *)) channelContext_compareCertificate_sp_basic128rsa15; + policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_basic128rsa15; policy->deleteMembers = deleteMembers_sp_basic128rsa15; return policyContext_newContext_sp_basic128rsa15(policy, localPrivateKey); } -#endif /* UA_ENABLE_ENCRYPTION */ +#endif -/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/ua_securitypolicy_basic256sha256.c" ***********************************/ +/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/securityPolicies/ua_securitypolicy_basic256.c" ***********************************/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -43025,22 +52293,840 @@ UA_SecurityPolicy_Basic128Rsa15(UA_SecurityPolicy *policy, UA_CertificateVerific * * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB * Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG + * Copyright 2019 (c) Kalycito Infotech Private Limited + * */ #ifdef UA_ENABLE_ENCRYPTION + + #include <mbedtls/aes.h> -#include <mbedtls/md.h> -#include <mbedtls/sha256.h> -#include <mbedtls/x509_crt.h> -#include <mbedtls/ctr_drbg.h> #include <mbedtls/entropy.h> #include <mbedtls/entropy_poll.h> #include <mbedtls/error.h> -#include <mbedtls/version.h> #include <mbedtls/sha1.h> +#include <mbedtls/version.h> + +/* Notes: + * mbedTLS' AES allows in-place encryption and decryption. Sow we don't have to + * allocate temp buffers. + * https://tls.mbed.org/discussions/generic/in-place-decryption-with-aes256-same-input-output-buffer + */ +#define UA_SECURITYPOLICY_BASIC256SHA1_RSAPADDING_LEN 42 +#define UA_SHA1_LENGTH 20 +#define UA_BASIC256_SYM_SIGNING_KEY_LENGTH 24 +#define UA_SECURITYPOLICY_BASIC256_SYM_KEY_LENGTH 32 +#define UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_BLOCK_SIZE 16 +#define UA_SECURITYPOLICY_BASIC256_SYM_PLAIN_TEXT_BLOCK_SIZE 16 +#define UA_SECURITYPOLICY_BASIC256_MINASYMKEYLENGTH 128 +#define UA_SECURITYPOLICY_BASIC256_MAXASYMKEYLENGTH 512 + +typedef struct { + const UA_SecurityPolicy *securityPolicy; + UA_ByteString localCertThumbprint; + + mbedtls_ctr_drbg_context drbgContext; + mbedtls_entropy_context entropyContext; + mbedtls_md_context_t sha1MdContext; + mbedtls_pk_context localPrivateKey; +} Basic256_PolicyContext; + +typedef struct { + Basic256_PolicyContext *policyContext; + + UA_ByteString localSymSigningKey; + UA_ByteString localSymEncryptingKey; + UA_ByteString localSymIv; + + UA_ByteString remoteSymSigningKey; + UA_ByteString remoteSymEncryptingKey; + UA_ByteString remoteSymIv; + + mbedtls_x509_crt remoteCertificate; +} Basic256_ChannelContext; + +/********************/ +/* AsymmetricModule */ +/********************/ + +/* VERIFY AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */ +static UA_StatusCode +asym_verify_sp_basic256(const UA_SecurityPolicy *securityPolicy, + Basic256_ChannelContext *cc, + const UA_ByteString *message, + const UA_ByteString *signature) { + if(securityPolicy == NULL || message == NULL || signature == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + return mbedtls_verifySig_sha1(&cc->remoteCertificate, message, signature); +} + +/* AsymmetricSignatureAlgorithm_RSA-PKCS15-SHA2-256 */ +static UA_StatusCode +asym_sign_sp_basic256(const UA_SecurityPolicy *securityPolicy, + Basic256_ChannelContext *cc, + const UA_ByteString *message, + UA_ByteString *signature) { + if(securityPolicy == NULL || message == NULL || signature == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + Basic256_PolicyContext *pc = cc->policyContext; + return mbedtls_sign_sha1(&pc->localPrivateKey, &pc->drbgContext, + message, signature); +} + +static size_t +asym_getLocalSignatureSize_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const Basic256_ChannelContext *cc) { + if(securityPolicy == NULL || cc == NULL) + return 0; + return mbedtls_pk_rsa(cc->policyContext->localPrivateKey)->len; +} + +static size_t +asym_getRemoteSignatureSize_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const Basic256_ChannelContext *cc) { + if(securityPolicy == NULL || cc == NULL) + return 0; + return mbedtls_pk_rsa(cc->remoteCertificate.pk)->len; +} + +/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */ +static UA_StatusCode +asym_encrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy, + Basic256_ChannelContext *cc, + UA_ByteString *data) { + if(securityPolicy == NULL || cc == NULL || data == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + const size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule. + encryptionAlgorithm.getRemotePlainTextBlockSize(securityPolicy, cc); + + mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk); + mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1); + + return mbedtls_encrypt_rsaOaep(remoteRsaContext, &cc->policyContext->drbgContext, + data, plainTextBlockSize); +} + +/* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */ +static UA_StatusCode +asym_decrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy, + Basic256_ChannelContext *cc, + UA_ByteString *data) { + if(securityPolicy == NULL || cc == NULL || data == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + return mbedtls_decrypt_rsaOaep(&cc->policyContext->localPrivateKey, + &cc->policyContext->drbgContext, data); +} + +static size_t +asym_getRemoteEncryptionKeyLength_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const Basic256_ChannelContext *cc) { + return mbedtls_pk_get_len(&cc->remoteCertificate.pk) * 8; +} + +static size_t +asym_getRemoteBlockSize_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const Basic256_ChannelContext *cc) { + mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk); + return rsaContext->len; +} + +static size_t +asym_getRemotePlainTextBlockSize_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const Basic256_ChannelContext *cc) { + mbedtls_rsa_context *const rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk); + return rsaContext->len - UA_SECURITYPOLICY_BASIC256SHA1_RSAPADDING_LEN; +} + +static UA_StatusCode +asym_makeThumbprint_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *certificate, + UA_ByteString *thumbprint) { + if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + return mbedtls_thumbprint_sha1(certificate, thumbprint); +} + +static UA_StatusCode +asymmetricModule_compareCertificateThumbprint_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *certificateThumbprint) { + if(securityPolicy == NULL || certificateThumbprint == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + Basic256_PolicyContext *pc = (Basic256_PolicyContext *)securityPolicy->policyContext; + if(!UA_ByteString_equal(certificateThumbprint, &pc->localCertThumbprint)) + return UA_STATUSCODE_BADCERTIFICATEINVALID; + + return UA_STATUSCODE_GOOD; +} + +/*******************/ +/* SymmetricModule */ +/*******************/ + +static UA_StatusCode +sym_verify_sp_basic256(const UA_SecurityPolicy *securityPolicy, + Basic256_ChannelContext *cc, + const UA_ByteString *message, + const UA_ByteString *signature) { + if(securityPolicy == NULL || cc == NULL || message == NULL || signature == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + /* Compute MAC */ + if(signature->length != UA_SHA1_LENGTH) { + UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Signature size does not have the desired size defined by the security policy"); + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; + } + + Basic256_PolicyContext *pc = + (Basic256_PolicyContext *)securityPolicy->policyContext; + + unsigned char mac[UA_SHA1_LENGTH]; + mbedtls_hmac(&pc->sha1MdContext, &cc->remoteSymSigningKey, message, mac); + + /* Compare with Signature */ + if(!UA_constantTimeEqual(signature->data, mac, UA_SHA1_LENGTH)) + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +sym_sign_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const Basic256_ChannelContext *cc, + const UA_ByteString *message, + UA_ByteString *signature) { + if(signature->length != UA_SHA1_LENGTH) + return UA_STATUSCODE_BADINTERNALERROR; + + mbedtls_hmac(&cc->policyContext->sha1MdContext, &cc->localSymSigningKey, + message, signature->data); + return UA_STATUSCODE_GOOD; +} + +static size_t +sym_getSignatureSize_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const void *channelContext) { + return UA_SHA1_LENGTH; +} + +static size_t +sym_getSigningKeyLength_sp_basic256(const UA_SecurityPolicy *const securityPolicy, + const void *const channelContext) { + return UA_BASIC256_SYM_SIGNING_KEY_LENGTH; +} + +static size_t +sym_getEncryptionKeyLength_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const void *channelContext) { + return UA_SECURITYPOLICY_BASIC256_SYM_KEY_LENGTH; +} + +static size_t +sym_getEncryptionBlockSize_sp_basic256(const UA_SecurityPolicy *const securityPolicy, + const void *const channelContext) { + return UA_SECURITYPOLICY_BASIC256_SYM_ENCRYPTION_BLOCK_SIZE; +} + +static size_t +sym_getPlainTextBlockSize_sp_basic256(const UA_SecurityPolicy *const securityPolicy, + const void *const channelContext) { + return UA_SECURITYPOLICY_BASIC256_SYM_PLAIN_TEXT_BLOCK_SIZE; +} + +static UA_StatusCode +sym_encrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const Basic256_ChannelContext *cc, + UA_ByteString *data) { + if(securityPolicy == NULL || cc == NULL || data == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + if(cc->localSymIv.length != + securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm. + getLocalBlockSize(securityPolicy, cc)) + return UA_STATUSCODE_BADINTERNALERROR; + + size_t plainTextBlockSize = + securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm. + getLocalPlainTextBlockSize(securityPolicy, cc); + + if(data->length % plainTextBlockSize != 0) { + UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Length of data to encrypt is not a multiple of the plain text block size." + "Padding might not have been calculated appropriately."); + return UA_STATUSCODE_BADINTERNALERROR; + } + + /* Keylength in bits */ + unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8); + mbedtls_aes_context aesContext; + int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength); + if(mbedErr) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString ivCopy; + UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length, + ivCopy.data, data->data, data->data); + if(mbedErr) + retval = UA_STATUSCODE_BADINTERNALERROR; + UA_ByteString_deleteMembers(&ivCopy); + return retval; +} + +static UA_StatusCode +sym_decrypt_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const Basic256_ChannelContext *cc, + UA_ByteString *data) { + if(securityPolicy == NULL || cc == NULL || data == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + size_t encryptionBlockSize = + securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm. + getRemoteBlockSize(securityPolicy, cc); + + if(cc->remoteSymIv.length != encryptionBlockSize) + return UA_STATUSCODE_BADINTERNALERROR; + + if(data->length % encryptionBlockSize != 0) { + UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Length of data to decrypt is not a multiple of the encryptingBlock size."); + return UA_STATUSCODE_BADINTERNALERROR; + } + + unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8); + mbedtls_aes_context aesContext; + int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength); + if(mbedErr) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString ivCopy; + UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy); + if(retval != UA_STATUSCODE_GOOD) + return retval; + + mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length, + ivCopy.data, data->data, data->data); + if(mbedErr) + retval = UA_STATUSCODE_BADINTERNALERROR; + UA_ByteString_deleteMembers(&ivCopy); + return retval; +} + +static UA_StatusCode +sym_generateKey_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *secret, const UA_ByteString *seed, + UA_ByteString *out) { + if(securityPolicy == NULL || secret == NULL || seed == NULL || out == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + Basic256_PolicyContext *pc = + (Basic256_PolicyContext *)securityPolicy->policyContext; + + return mbedtls_generateKey(&pc->sha1MdContext, secret, seed, out); +} + +static UA_StatusCode +sym_generateNonce_sp_basic256(const UA_SecurityPolicy *securityPolicy, + UA_ByteString *out) { + if(securityPolicy == NULL || securityPolicy->policyContext == NULL || out == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + Basic256_PolicyContext *pc = + (Basic256_PolicyContext *)securityPolicy->policyContext; + + int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length); + if(mbedErr) + return UA_STATUSCODE_BADUNEXPECTEDERROR; + + return UA_STATUSCODE_GOOD; +} + +/*****************/ +/* ChannelModule */ +/*****************/ + +/* Assumes that the certificate has been verified externally */ +static UA_StatusCode +parseRemoteCertificate_sp_basic256(Basic256_ChannelContext *cc, + const UA_ByteString *remoteCertificate) { + if(remoteCertificate == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + /* Parse the certificate */ + int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data, + remoteCertificate->length); + if(mbedErr) + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; + + /* Check the key length */ + mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk); + if(rsaContext->len < UA_SECURITYPOLICY_BASIC256_MINASYMKEYLENGTH || + rsaContext->len > UA_SECURITYPOLICY_BASIC256_MAXASYMKEYLENGTH) + return UA_STATUSCODE_BADCERTIFICATEUSENOTALLOWED; + + return UA_STATUSCODE_GOOD; +} + +static void +channelContext_deleteContext_sp_basic256(Basic256_ChannelContext *cc) { + UA_ByteString_deleteMembers(&cc->localSymSigningKey); + UA_ByteString_deleteMembers(&cc->localSymEncryptingKey); + UA_ByteString_deleteMembers(&cc->localSymIv); + + UA_ByteString_deleteMembers(&cc->remoteSymSigningKey); + UA_ByteString_deleteMembers(&cc->remoteSymEncryptingKey); + UA_ByteString_deleteMembers(&cc->remoteSymIv); + + mbedtls_x509_crt_free(&cc->remoteCertificate); + + UA_free(cc); +} + +static UA_StatusCode +channelContext_newContext_sp_basic256(const UA_SecurityPolicy *securityPolicy, + const UA_ByteString *remoteCertificate, + void **pp_contextData) { + if(securityPolicy == NULL || remoteCertificate == NULL || pp_contextData == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + /* Allocate the channel context */ + *pp_contextData = UA_malloc(sizeof(Basic256_ChannelContext)); + if(*pp_contextData == NULL) + return UA_STATUSCODE_BADOUTOFMEMORY; + + Basic256_ChannelContext *cc = (Basic256_ChannelContext *)*pp_contextData; + + /* Initialize the channel context */ + cc->policyContext = (Basic256_PolicyContext *)securityPolicy->policyContext; + + UA_ByteString_init(&cc->localSymSigningKey); + UA_ByteString_init(&cc->localSymEncryptingKey); + UA_ByteString_init(&cc->localSymIv); + + UA_ByteString_init(&cc->remoteSymSigningKey); + UA_ByteString_init(&cc->remoteSymEncryptingKey); + UA_ByteString_init(&cc->remoteSymIv); + + mbedtls_x509_crt_init(&cc->remoteCertificate); + + // TODO: this can be optimized so that we dont allocate memory before parsing the certificate + UA_StatusCode retval = parseRemoteCertificate_sp_basic256(cc, remoteCertificate); + if(retval != UA_STATUSCODE_GOOD) { + channelContext_deleteContext_sp_basic256(cc); + *pp_contextData = NULL; + } + return retval; +} + +static UA_StatusCode +channelContext_setLocalSymEncryptingKey_sp_basic256(Basic256_ChannelContext *cc, + const UA_ByteString *key) { + if(key == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString_deleteMembers(&cc->localSymEncryptingKey); + return UA_ByteString_copy(key, &cc->localSymEncryptingKey); +} + +static UA_StatusCode +channelContext_setLocalSymSigningKey_sp_basic256(Basic256_ChannelContext *cc, + const UA_ByteString *key) { + if(key == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString_deleteMembers(&cc->localSymSigningKey); + return UA_ByteString_copy(key, &cc->localSymSigningKey); +} + + +static UA_StatusCode +channelContext_setLocalSymIv_sp_basic256(Basic256_ChannelContext *cc, + const UA_ByteString *iv) { + if(iv == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString_deleteMembers(&cc->localSymIv); + return UA_ByteString_copy(iv, &cc->localSymIv); +} + +static UA_StatusCode +channelContext_setRemoteSymEncryptingKey_sp_basic256(Basic256_ChannelContext *cc, + const UA_ByteString *key) { + if(key == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString_deleteMembers(&cc->remoteSymEncryptingKey); + return UA_ByteString_copy(key, &cc->remoteSymEncryptingKey); +} + +static UA_StatusCode +channelContext_setRemoteSymSigningKey_sp_basic256(Basic256_ChannelContext *cc, + const UA_ByteString *key) { + if(key == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString_deleteMembers(&cc->remoteSymSigningKey); + return UA_ByteString_copy(key, &cc->remoteSymSigningKey); +} + +static UA_StatusCode +channelContext_setRemoteSymIv_sp_basic256(Basic256_ChannelContext *cc, + const UA_ByteString *iv) { + if(iv == NULL || cc == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + UA_ByteString_deleteMembers(&cc->remoteSymIv); + return UA_ByteString_copy(iv, &cc->remoteSymIv); +} + +static UA_StatusCode +channelContext_compareCertificate_sp_basic256(const Basic256_ChannelContext *cc, + const UA_ByteString *certificate) { + if(cc == NULL || certificate == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + mbedtls_x509_crt cert; + mbedtls_x509_crt_init(&cert); + int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length); + if(mbedErr) + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; + + UA_StatusCode retval = UA_STATUSCODE_GOOD; + if(cert.raw.len != cc->remoteCertificate.raw.len || + memcmp(cert.raw.p, cc->remoteCertificate.raw.p, cert.raw.len) != 0) + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; + + mbedtls_x509_crt_free(&cert); + return retval; +} + +static void +deleteMembers_sp_basic256(UA_SecurityPolicy *securityPolicy) { + if(securityPolicy == NULL) + return; + + if(securityPolicy->policyContext == NULL) + return; + + UA_ByteString_deleteMembers(&securityPolicy->localCertificate); + + /* delete all allocated members in the context */ + Basic256_PolicyContext *pc = (Basic256_PolicyContext *) + securityPolicy->policyContext; + + mbedtls_ctr_drbg_free(&pc->drbgContext); + mbedtls_entropy_free(&pc->entropyContext); + mbedtls_pk_free(&pc->localPrivateKey); + mbedtls_md_free(&pc->sha1MdContext); + UA_ByteString_deleteMembers(&pc->localCertThumbprint); + + UA_LOG_DEBUG(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Deleted members of EndpointContext for sp_basic256"); + + UA_free(pc); + securityPolicy->policyContext = NULL; +} + +static UA_StatusCode +updateCertificateAndPrivateKey_sp_basic256(UA_SecurityPolicy *securityPolicy, + const UA_ByteString newCertificate, + const UA_ByteString newPrivateKey) { + if(securityPolicy == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + if(securityPolicy->policyContext == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + Basic256_PolicyContext *pc = (Basic256_PolicyContext *) + securityPolicy->policyContext; + + UA_ByteString_deleteMembers(&securityPolicy->localCertificate); + + UA_StatusCode retval = UA_ByteString_allocBuffer(&securityPolicy->localCertificate, + newCertificate.length + 1); + if(retval != UA_STATUSCODE_GOOD) + return retval; + memcpy(securityPolicy->localCertificate.data, newCertificate.data, newCertificate.length); + securityPolicy->localCertificate.data[newCertificate.length] = '\0'; + securityPolicy->localCertificate.length--; + + /* Set the new private key */ + mbedtls_pk_free(&pc->localPrivateKey); + mbedtls_pk_init(&pc->localPrivateKey); + int mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, + newPrivateKey.data, newPrivateKey.length, + NULL, 0); + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; + goto error; + } + + retval = asym_makeThumbprint_sp_basic256(pc->securityPolicy, + &securityPolicy->localCertificate, + &pc->localCertThumbprint); + if(retval != UA_STATUSCODE_GOOD) + goto error; + + return retval; + + error: + UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Could not update certificate and private key"); + if(securityPolicy->policyContext != NULL) + deleteMembers_sp_basic256(securityPolicy); + return retval; +} + +static UA_StatusCode +policyContext_newContext_sp_basic256(UA_SecurityPolicy *securityPolicy, + const UA_ByteString localPrivateKey) { + UA_StatusCode retval = UA_STATUSCODE_GOOD; + if(securityPolicy == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + Basic256_PolicyContext *pc = (Basic256_PolicyContext *) + UA_malloc(sizeof(Basic256_PolicyContext)); + securityPolicy->policyContext = (void *)pc; + if(!pc) { + retval = UA_STATUSCODE_BADOUTOFMEMORY; + goto error; + } + + /* Initialize the PolicyContext */ + memset(pc, 0, sizeof(Basic256_PolicyContext)); + mbedtls_ctr_drbg_init(&pc->drbgContext); + mbedtls_entropy_init(&pc->entropyContext); + mbedtls_pk_init(&pc->localPrivateKey); + mbedtls_md_init(&pc->sha1MdContext); + pc->securityPolicy = securityPolicy; + + /* Initialized the message digest */ + const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + int mbedErr = mbedtls_md_setup(&pc->sha1MdContext, mdInfo, MBEDTLS_MD_SHA1); + if(mbedErr) { + retval = UA_STATUSCODE_BADOUTOFMEMORY; + goto error; + } + + /* Add the system entropy source */ + mbedErr = mbedtls_entropy_add_source(&pc->entropyContext, + mbedtls_platform_entropy_poll, NULL, 0, + MBEDTLS_ENTROPY_SOURCE_STRONG); + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; + goto error; + } + + /* Seed the RNG */ + char *personalization = "open62541-drbg"; + mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func, + &pc->entropyContext, + (const unsigned char *)personalization, 14); + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; + goto error; + } + + /* Set the private key */ + mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, localPrivateKey.data, + localPrivateKey.length, NULL, 0); + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; + goto error; + } + + /* Set the local certificate thumbprint */ + retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH); + if(retval != UA_STATUSCODE_GOOD) + goto error; + retval = asym_makeThumbprint_sp_basic256(pc->securityPolicy, + &securityPolicy->localCertificate, + &pc->localCertThumbprint); + if(retval != UA_STATUSCODE_GOOD) + goto error; + + return UA_STATUSCODE_GOOD; + +error: + UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Could not create securityContext"); + if(securityPolicy->policyContext != NULL) + deleteMembers_sp_basic256(securityPolicy); + return retval; +} + +UA_StatusCode +UA_SecurityPolicy_Basic256(UA_SecurityPolicy *policy, + UA_CertificateVerification *certificateVerification, + const UA_ByteString localCertificate, + const UA_ByteString localPrivateKey, const UA_Logger *logger) { + memset(policy, 0, sizeof(UA_SecurityPolicy)); + policy->logger = logger; + + policy->policyUri = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#Basic256"); + + UA_SecurityPolicyAsymmetricModule *const asymmetricModule = &policy->asymmetricModule; + UA_SecurityPolicySymmetricModule *const symmetricModule = &policy->symmetricModule; + UA_SecurityPolicyChannelModule *const channelModule = &policy->channelModule; + + /* Copy the certificate and add a NULL to the end */ + UA_StatusCode retval = + UA_ByteString_allocBuffer(&policy->localCertificate, localCertificate.length + 1); + if(retval != UA_STATUSCODE_GOOD) + return retval; + memcpy(policy->localCertificate.data, localCertificate.data, localCertificate.length); + policy->localCertificate.data[localCertificate.length] = '\0'; + policy->localCertificate.length--; + policy->certificateVerification = certificateVerification; + + /* AsymmetricModule */ + UA_SecurityPolicySignatureAlgorithm *asym_signatureAlgorithm = + &asymmetricModule->cryptoModule.signatureAlgorithm; + asym_signatureAlgorithm->uri = + UA_STRING("http://www.w3.org/2000/09/xmldsig#rsa-sha1\0"); + asym_signatureAlgorithm->verify = + (UA_StatusCode (*)(const UA_SecurityPolicy *, void *, + const UA_ByteString *, const UA_ByteString *))asym_verify_sp_basic256; + asym_signatureAlgorithm->sign = + (UA_StatusCode (*)(const UA_SecurityPolicy *, void *, + const UA_ByteString *, UA_ByteString *))asym_sign_sp_basic256; + asym_signatureAlgorithm->getLocalSignatureSize = + (size_t (*)(const UA_SecurityPolicy *, const void *))asym_getLocalSignatureSize_sp_basic256; + asym_signatureAlgorithm->getRemoteSignatureSize = + (size_t (*)(const UA_SecurityPolicy *, const void *))asym_getRemoteSignatureSize_sp_basic256; + asym_signatureAlgorithm->getLocalKeyLength = NULL; // TODO: Write function + asym_signatureAlgorithm->getRemoteKeyLength = NULL; // TODO: Write function + + UA_SecurityPolicyEncryptionAlgorithm *asym_encryptionAlgorithm = + &asymmetricModule->cryptoModule.encryptionAlgorithm; + asym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#rsa-oaep\0"); + asym_encryptionAlgorithm->encrypt = + (UA_StatusCode(*)(const UA_SecurityPolicy *, void *, UA_ByteString *))asym_encrypt_sp_basic256; + asym_encryptionAlgorithm->decrypt = + (UA_StatusCode(*)(const UA_SecurityPolicy *, void *, UA_ByteString *)) + asym_decrypt_sp_basic256; + asym_encryptionAlgorithm->getLocalKeyLength = NULL; // TODO: Write function + asym_encryptionAlgorithm->getRemoteKeyLength = + (size_t (*)(const UA_SecurityPolicy *, const void *))asym_getRemoteEncryptionKeyLength_sp_basic256; + asym_encryptionAlgorithm->getLocalBlockSize = NULL; // TODO: Write function + asym_encryptionAlgorithm->getRemoteBlockSize = (size_t (*)(const UA_SecurityPolicy *, + const void *))asym_getRemoteBlockSize_sp_basic256; + asym_encryptionAlgorithm->getLocalPlainTextBlockSize = NULL; // TODO: Write function + asym_encryptionAlgorithm->getRemotePlainTextBlockSize = + (size_t (*)(const UA_SecurityPolicy *, const void *))asym_getRemotePlainTextBlockSize_sp_basic256; + + asymmetricModule->makeCertificateThumbprint = asym_makeThumbprint_sp_basic256; + asymmetricModule->compareCertificateThumbprint = + asymmetricModule_compareCertificateThumbprint_sp_basic256; + + /* SymmetricModule */ + symmetricModule->generateKey = sym_generateKey_sp_basic256; + symmetricModule->generateNonce = sym_generateNonce_sp_basic256; + + UA_SecurityPolicySignatureAlgorithm *sym_signatureAlgorithm = + &symmetricModule->cryptoModule.signatureAlgorithm; + sym_signatureAlgorithm->uri = + UA_STRING("http://www.w3.org/2000/09/xmldsig#hmac-sha1\0"); + sym_signatureAlgorithm->verify = + (UA_StatusCode (*)(const UA_SecurityPolicy *, void *, const UA_ByteString *, + const UA_ByteString *))sym_verify_sp_basic256; + sym_signatureAlgorithm->sign = + (UA_StatusCode (*)(const UA_SecurityPolicy *, void *, + const UA_ByteString *, UA_ByteString *))sym_sign_sp_basic256; + sym_signatureAlgorithm->getLocalSignatureSize = sym_getSignatureSize_sp_basic256; + sym_signatureAlgorithm->getRemoteSignatureSize = sym_getSignatureSize_sp_basic256; + sym_signatureAlgorithm->getLocalKeyLength = + (size_t (*)(const UA_SecurityPolicy *, + const void *))sym_getSigningKeyLength_sp_basic256; + sym_signatureAlgorithm->getRemoteKeyLength = + (size_t (*)(const UA_SecurityPolicy *, + const void *))sym_getSigningKeyLength_sp_basic256; + + UA_SecurityPolicyEncryptionAlgorithm *sym_encryptionAlgorithm = + &symmetricModule->cryptoModule.encryptionAlgorithm; + sym_encryptionAlgorithm->uri = UA_STRING("http://www.w3.org/2001/04/xmlenc#aes256-cbc\0"); + sym_encryptionAlgorithm->encrypt = + (UA_StatusCode(*)(const UA_SecurityPolicy *, void *, UA_ByteString *))sym_encrypt_sp_basic256; + sym_encryptionAlgorithm->decrypt = + (UA_StatusCode(*)(const UA_SecurityPolicy *, void *, UA_ByteString *))sym_decrypt_sp_basic256; + sym_encryptionAlgorithm->getLocalKeyLength = sym_getEncryptionKeyLength_sp_basic256; + sym_encryptionAlgorithm->getRemoteKeyLength = sym_getEncryptionKeyLength_sp_basic256; + sym_encryptionAlgorithm->getLocalBlockSize = + (size_t (*)(const UA_SecurityPolicy *, const void *))sym_getEncryptionBlockSize_sp_basic256; + sym_encryptionAlgorithm->getRemoteBlockSize = + (size_t (*)(const UA_SecurityPolicy *, const void *))sym_getEncryptionBlockSize_sp_basic256; + sym_encryptionAlgorithm->getLocalPlainTextBlockSize = + (size_t (*)(const UA_SecurityPolicy *, const void *))sym_getPlainTextBlockSize_sp_basic256; + sym_encryptionAlgorithm->getRemotePlainTextBlockSize = + (size_t (*)(const UA_SecurityPolicy *, const void *))sym_getPlainTextBlockSize_sp_basic256; + symmetricModule->secureChannelNonceLength = 32; + + // Use the same signature algorithm as the asymmetric component for certificate signing (see standard) + policy->certificateSigningAlgorithm = policy->asymmetricModule.cryptoModule.signatureAlgorithm; + + /* ChannelModule */ + channelModule->newContext = channelContext_newContext_sp_basic256; + channelModule->deleteContext = (void (*)(void *)) + channelContext_deleteContext_sp_basic256; + + channelModule->setLocalSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *)) + channelContext_setLocalSymEncryptingKey_sp_basic256; + channelModule->setLocalSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *)) + channelContext_setLocalSymSigningKey_sp_basic256; + channelModule->setLocalSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *)) + channelContext_setLocalSymIv_sp_basic256; + + channelModule->setRemoteSymEncryptingKey = (UA_StatusCode (*)(void *, const UA_ByteString *)) + channelContext_setRemoteSymEncryptingKey_sp_basic256; + channelModule->setRemoteSymSigningKey = (UA_StatusCode (*)(void *, const UA_ByteString *)) + channelContext_setRemoteSymSigningKey_sp_basic256; + channelModule->setRemoteSymIv = (UA_StatusCode (*)(void *, const UA_ByteString *)) + channelContext_setRemoteSymIv_sp_basic256; + + channelModule->compareCertificate = (UA_StatusCode (*)(const void *, const UA_ByteString *)) + channelContext_compareCertificate_sp_basic256; + + policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_basic256; + policy->deleteMembers = deleteMembers_sp_basic256; + + return policyContext_newContext_sp_basic256(policy, localPrivateKey); +} + +#endif + +/*********************************** amalgamated original file "/home/jvoe/open62541/plugins/securityPolicies/ua_securitypolicy_basic256sha256.c" ***********************************/ + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB + * Copyright 2018 (c) Daniel Feist, Precitec GmbH & Co. KG + */ + + +#ifdef UA_ENABLE_ENCRYPTION + + +#include <mbedtls/aes.h> +#include <mbedtls/ctr_drbg.h> +#include <mbedtls/entropy.h> +#include <mbedtls/entropy_poll.h> +#include <mbedtls/error.h> +#include <mbedtls/md.h> +#include <mbedtls/sha1.h> +#include <mbedtls/sha256.h> +#include <mbedtls/version.h> +#include <mbedtls/x509_crt.h> /* Notes: * mbedTLS' AES allows in-place encryption and decryption. Sow we don't have to @@ -43058,24 +53144,6 @@ UA_SecurityPolicy_Basic128Rsa15(UA_SecurityPolicy *policy, UA_CertificateVerific #define UA_SECURITYPOLICY_BASIC256SHA256_MINASYMKEYLENGTH 256 #define UA_SECURITYPOLICY_BASIC256SHA256_MAXASYMKEYLENGTH 512 -#define UA_LOG_MBEDERR \ - char errBuff[300]; \ - mbedtls_strerror(mbedErr, errBuff, 300); \ - UA_LOG_WARNING(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, \ - "mbedTLS returned an error: %s", errBuff); \ - -#define UA_MBEDTLS_ERRORHANDLING(errorcode) \ - if(mbedErr) { \ - UA_LOG_MBEDERR \ - retval = errorcode; \ - } - -#define UA_MBEDTLS_ERRORHANDLING_RETURN(errorcode) \ - if(mbedErr) { \ - UA_LOG_MBEDERR \ - return errorcode; \ - } - typedef struct { const UA_SecurityPolicy *securityPolicy; UA_ByteString localCertThumbprint; @@ -43131,12 +53199,12 @@ asym_verify_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256, UA_SHA256_LENGTH, hash, signature->data); */ - int mbedErr = mbedtls_pk_verify(&cc->remoteCertificate.pk, MBEDTLS_MD_SHA256, hash, UA_SHA256_LENGTH, signature->data, signature->length); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED); + if(mbedErr) + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; return UA_STATUSCODE_GOOD; } @@ -43170,7 +53238,8 @@ asym_sign_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, UA_SHA256_LENGTH, signature->data, &sigLen, mbedtls_ctr_drbg_random, &pc->drbgContext); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + return UA_STATUSCODE_BADINTERNALERROR; return UA_STATUSCODE_GOOD; } @@ -43200,48 +53269,14 @@ asym_encrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || cc == NULL || data == NULL) return UA_STATUSCODE_BADINTERNALERROR; - const size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule.encryptionAlgorithm. - getRemotePlainTextBlockSize(securityPolicy, cc); - - if(data->length % plainTextBlockSize != 0) - return UA_STATUSCODE_BADINTERNALERROR; + const size_t plainTextBlockSize = securityPolicy->asymmetricModule.cryptoModule. + encryptionAlgorithm.getRemotePlainTextBlockSize(securityPolicy, cc); mbedtls_rsa_context *remoteRsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk); mbedtls_rsa_set_padding(remoteRsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1); - UA_ByteString encrypted; - const size_t bufferOverhead = - UA_SecurityPolicy_getRemoteAsymEncryptionBufferLengthOverhead(securityPolicy, cc, data->length); - UA_StatusCode retval = UA_ByteString_allocBuffer(&encrypted, data->length + bufferOverhead); - if(retval != UA_STATUSCODE_GOOD) - return retval; - - size_t lenDataToEncrypt = data->length; - size_t inOffset = 0; - size_t offset = 0; - const unsigned char *label = NULL; - Basic256Sha256_PolicyContext *pc = cc->policyContext; - while(lenDataToEncrypt >= plainTextBlockSize) { - int mbedErr = mbedtls_rsa_rsaes_oaep_encrypt(remoteRsaContext, mbedtls_ctr_drbg_random, - &pc->drbgContext, MBEDTLS_RSA_PUBLIC, - label, 0, plainTextBlockSize, - data->data + inOffset, encrypted.data + offset); - - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR); - if(retval != UA_STATUSCODE_GOOD) { - UA_ByteString_deleteMembers(&encrypted); - return retval; - } - - inOffset += plainTextBlockSize; - offset += remoteRsaContext->len; - lenDataToEncrypt -= plainTextBlockSize; - } - - memcpy(data->data, encrypted.data, offset); - UA_ByteString_deleteMembers(&encrypted); - - return UA_STATUSCODE_GOOD; + return mbedtls_encrypt_rsaOaep(remoteRsaContext, &cc->policyContext->drbgContext, + data, plainTextBlockSize); } /* AsymmetricEncryptionAlgorithm_RSA-OAEP-SHA1 */ @@ -43251,52 +53286,8 @@ asym_decrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, UA_ByteString *data) { if(securityPolicy == NULL || cc == NULL || data == NULL) return UA_STATUSCODE_BADINTERNALERROR; - - mbedtls_rsa_context *rsaContext = - mbedtls_pk_rsa(cc->policyContext->localPrivateKey); - - mbedtls_rsa_set_padding(rsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1); - - if(data->length % rsaContext->len != 0) - return UA_STATUSCODE_BADINTERNALERROR; - - UA_ByteString decrypted; - UA_StatusCode retval = UA_ByteString_allocBuffer(&decrypted, data->length); - if(retval != UA_STATUSCODE_GOOD) - return retval; - - size_t lenDataToDecrypt = data->length; - size_t inOffset = 0; - size_t offset = 0; - size_t outLength = 0; - const unsigned char *label = NULL; - Basic256Sha256_PolicyContext *pc = cc->policyContext; - - while(lenDataToDecrypt >= rsaContext->len) { - int mbedErr = mbedtls_rsa_rsaes_oaep_decrypt(rsaContext, mbedtls_ctr_drbg_random, - &pc->drbgContext, MBEDTLS_RSA_PRIVATE, - label, 0, &outLength, - data->data + inOffset, - decrypted.data + offset, - decrypted.length - offset); - if(mbedErr) - UA_ByteString_deleteMembers(&decrypted); // TODO: Maybe change error macro to jump to cleanup? - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED); - - inOffset += rsaContext->len; - offset += outLength; - lenDataToDecrypt -= rsaContext->len; - } - - if(lenDataToDecrypt == 0) { - memcpy(data->data, decrypted.data, offset); - data->length = offset; - } else { - retval = UA_STATUSCODE_BADINTERNALERROR; - } - - UA_ByteString_deleteMembers(&decrypted); - return retval; + return mbedtls_decrypt_rsaOaep(&cc->policyContext->localPrivateKey, + &cc->policyContext->drbgContext, data); } static size_t @@ -43325,20 +53316,7 @@ asym_makeThumbprint_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, UA_ByteString *thumbprint) { if(securityPolicy == NULL || certificate == NULL || thumbprint == NULL) return UA_STATUSCODE_BADINTERNALERROR; - - if(UA_ByteString_equal(certificate, &UA_BYTESTRING_NULL)) - return UA_STATUSCODE_BADINTERNALERROR; - - if(thumbprint->length != UA_SHA1_LENGTH) - return UA_STATUSCODE_BADINTERNALERROR; - - /* The certificate thumbprint is always a 20 bit sha1 hash, see Part 4 of the Specification. */ -#if MBEDTLS_VERSION_NUMBER >= 0x02070000 - mbedtls_sha1_ret(certificate->data, certificate->length, thumbprint->data); -#else - mbedtls_sha1(certificate->data, certificate->length, thumbprint->data); -#endif - return UA_STATUSCODE_GOOD; + return mbedtls_thumbprint_sha1(certificate, thumbprint); } static UA_StatusCode @@ -43358,14 +53336,6 @@ asymmetricModule_compareCertificateThumbprint_sp_basic256sha256(const UA_Securit /* SymmetricModule */ /*******************/ -static void -md_hmac_Basic256Sha256(mbedtls_md_context_t *context, const UA_ByteString *key, - const UA_ByteString *in, unsigned char out[32]) { - mbedtls_md_hmac_starts(context, key->data, key->length); - mbedtls_md_hmac_update(context, in->data, in->length); - mbedtls_md_hmac_finish(context, out); -} - static UA_StatusCode sym_verify_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, Basic256Sha256_ChannelContext *cc, @@ -43385,10 +53355,10 @@ sym_verify_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, (Basic256Sha256_PolicyContext *)securityPolicy->policyContext; unsigned char mac[UA_SHA256_LENGTH]; - md_hmac_Basic256Sha256(&pc->sha256MdContext, &cc->remoteSymSigningKey, message, mac); + mbedtls_hmac(&pc->sha256MdContext, &cc->remoteSymSigningKey, message, mac); /* Compare with Signature */ - if(memcmp(signature->data, mac, UA_SHA256_LENGTH) != 0) + if(!UA_constantTimeEqual(signature->data, mac, UA_SHA256_LENGTH)) return UA_STATUSCODE_BADSECURITYCHECKSFAILED; return UA_STATUSCODE_GOOD; } @@ -43401,8 +53371,8 @@ sym_sign_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, if(signature->length != UA_SHA256_LENGTH) return UA_STATUSCODE_BADINTERNALERROR; - md_hmac_Basic256Sha256(&cc->policyContext->sha256MdContext, &cc->localSymSigningKey, - message, signature->data); + mbedtls_hmac(&cc->policyContext->sha256MdContext, &cc->localSymSigningKey, + message, signature->data); return UA_STATUSCODE_GOOD; } @@ -43443,17 +53413,17 @@ sym_encrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || cc == NULL || data == NULL) return UA_STATUSCODE_BADINTERNALERROR; - if(cc->localSymIv.length != - securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.getLocalBlockSize(securityPolicy, cc)) + if(cc->localSymIv.length != securityPolicy->symmetricModule.cryptoModule. + encryptionAlgorithm.getLocalBlockSize(securityPolicy, cc)) return UA_STATUSCODE_BADINTERNALERROR; - size_t plainTextBlockSize = - securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.getLocalPlainTextBlockSize(securityPolicy, cc); + size_t plainTextBlockSize = securityPolicy->symmetricModule.cryptoModule. + encryptionAlgorithm.getLocalPlainTextBlockSize(securityPolicy, cc); if(data->length % plainTextBlockSize != 0) { UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, "Length of data to encrypt is not a multiple of the plain text block size." - "Padding might not have been calculated appropriately."); + "Padding might not have been calculated appropriately."); return UA_STATUSCODE_BADINTERNALERROR; } @@ -43461,7 +53431,8 @@ sym_encrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, unsigned int keylength = (unsigned int)(cc->localSymEncryptingKey.length * 8); mbedtls_aes_context aesContext; int mbedErr = mbedtls_aes_setkey_enc(&aesContext, cc->localSymEncryptingKey.data, keylength); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + return UA_STATUSCODE_BADINTERNALERROR; UA_ByteString ivCopy; UA_StatusCode retval = UA_ByteString_copy(&cc->localSymIv, &ivCopy); @@ -43470,7 +53441,8 @@ sym_encrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_ENCRYPT, data->length, ivCopy.data, data->data, data->data); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + retval = UA_STATUSCODE_BADINTERNALERROR; UA_ByteString_deleteMembers(&ivCopy); return retval; } @@ -43482,8 +53454,8 @@ sym_decrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || cc == NULL || data == NULL) return UA_STATUSCODE_BADINTERNALERROR; - size_t encryptionBlockSize = - securityPolicy->symmetricModule.cryptoModule.encryptionAlgorithm.getLocalBlockSize(securityPolicy, cc); + size_t encryptionBlockSize = securityPolicy->symmetricModule.cryptoModule. + encryptionAlgorithm.getRemoteBlockSize(securityPolicy, cc); if(cc->remoteSymIv.length != encryptionBlockSize) return UA_STATUSCODE_BADINTERNALERROR; @@ -43497,7 +53469,8 @@ sym_decrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, unsigned int keylength = (unsigned int)(cc->remoteSymEncryptingKey.length * 8); mbedtls_aes_context aesContext; int mbedErr = mbedtls_aes_setkey_dec(&aesContext, cc->remoteSymEncryptingKey.data, keylength); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + return UA_STATUSCODE_BADINTERNALERROR; UA_ByteString ivCopy; UA_StatusCode retval = UA_ByteString_copy(&cc->remoteSymIv, &ivCopy); @@ -43506,18 +53479,12 @@ sym_decrypt_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, mbedErr = mbedtls_aes_crypt_cbc(&aesContext, MBEDTLS_AES_DECRYPT, data->length, ivCopy.data, data->data, data->data); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADINTERNALERROR); + if(mbedErr) + retval = UA_STATUSCODE_BADINTERNALERROR; UA_ByteString_deleteMembers(&ivCopy); return retval; } -static void -swapBuffers_Basic256Sha256(UA_ByteString *const bufA, UA_ByteString *const bufB) { - UA_ByteString tmp = *bufA; - *bufA = *bufB; - *bufB = tmp; -} - static UA_StatusCode sym_generateKey_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, const UA_ByteString *secret, const UA_ByteString *seed, @@ -43528,73 +53495,7 @@ sym_generateKey_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, Basic256Sha256_PolicyContext *pc = (Basic256Sha256_PolicyContext *)securityPolicy->policyContext; - size_t hashLen = 0; - const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); - hashLen = (size_t)mbedtls_md_get_size(mdInfo); - - UA_ByteString A_and_seed; - UA_ByteString_allocBuffer(&A_and_seed, hashLen + seed->length); - memcpy(A_and_seed.data + hashLen, seed->data, seed->length); - - UA_ByteString ANext_and_seed; - UA_ByteString_allocBuffer(&ANext_and_seed, hashLen + seed->length); - memcpy(ANext_and_seed.data + hashLen, seed->data, seed->length); - - UA_ByteString A = { - hashLen, - A_and_seed.data - }; - - UA_ByteString ANext = { - hashLen, - ANext_and_seed.data - }; - - md_hmac_Basic256Sha256(&pc->sha256MdContext, secret, seed, A.data); - - UA_StatusCode retval = 0; - for(size_t offset = 0; offset < out->length; offset += hashLen) { - UA_ByteString outSegment = { - hashLen, - out->data + offset - }; - UA_Boolean bufferAllocated = UA_FALSE; - // Not enough room in out buffer to write the hash. - if(offset + hashLen > out->length) { - outSegment.data = NULL; - outSegment.length = 0; - retval |= UA_ByteString_allocBuffer(&outSegment, hashLen); - if(retval != UA_STATUSCODE_GOOD) { - UA_ByteString_deleteMembers(&A_and_seed); - UA_ByteString_deleteMembers(&ANext_and_seed); - return retval; - } - bufferAllocated = UA_TRUE; - } - - md_hmac_Basic256Sha256(&pc->sha256MdContext, secret, &A_and_seed, outSegment.data); - md_hmac_Basic256Sha256(&pc->sha256MdContext, secret, &A, ANext.data); - - if(retval != UA_STATUSCODE_GOOD) { - if(bufferAllocated) - UA_ByteString_deleteMembers(&outSegment); - UA_ByteString_deleteMembers(&A_and_seed); - UA_ByteString_deleteMembers(&ANext_and_seed); - return retval; - } - - if(bufferAllocated) { - memcpy(out->data + offset, outSegment.data, out->length - offset); - UA_ByteString_deleteMembers(&outSegment); - } - - swapBuffers_Basic256Sha256(&ANext_and_seed, &A_and_seed); - swapBuffers_Basic256Sha256(&ANext, &A); - } - - UA_ByteString_deleteMembers(&A_and_seed); - UA_ByteString_deleteMembers(&ANext_and_seed); - return UA_STATUSCODE_GOOD; + return mbedtls_generateKey(&pc->sha256MdContext, secret, seed, out); } static UA_StatusCode @@ -43603,12 +53504,11 @@ sym_generateNonce_sp_basic256sha256(const UA_SecurityPolicy *securityPolicy, if(securityPolicy == NULL || securityPolicy->policyContext == NULL || out == NULL) return UA_STATUSCODE_BADINTERNALERROR; - Basic256Sha256_PolicyContext *data = + Basic256Sha256_PolicyContext *pc = (Basic256Sha256_PolicyContext *)securityPolicy->policyContext; - - int mbedErr = mbedtls_ctr_drbg_random(&data->drbgContext, out->data, out->length); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADUNEXPECTEDERROR); - + int mbedErr = mbedtls_ctr_drbg_random(&pc->drbgContext, out->data, out->length); + if(mbedErr) + return UA_STATUSCODE_BADUNEXPECTEDERROR; return UA_STATUSCODE_GOOD; } @@ -43623,12 +53523,11 @@ parseRemoteCertificate_sp_basic256sha256(Basic256Sha256_ChannelContext *cc, if(remoteCertificate == NULL || cc == NULL) return UA_STATUSCODE_BADINTERNALERROR; - const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy; - /* Parse the certificate */ int mbedErr = mbedtls_x509_crt_parse(&cc->remoteCertificate, remoteCertificate->data, remoteCertificate->length); - UA_MBEDTLS_ERRORHANDLING_RETURN(UA_STATUSCODE_BADSECURITYCHECKSFAILED); + if(mbedErr) + return UA_STATUSCODE_BADSECURITYCHECKSFAILED; /* Check the key length */ mbedtls_rsa_context *rsaContext = mbedtls_pk_rsa(cc->remoteCertificate.pk); @@ -43757,15 +53656,11 @@ channelContext_compareCertificate_sp_basic256sha256(const Basic256Sha256_Channel if(cc == NULL || certificate == NULL) return UA_STATUSCODE_BADINTERNALERROR; - const UA_SecurityPolicy *securityPolicy = cc->policyContext->securityPolicy; - mbedtls_x509_crt cert; mbedtls_x509_crt_init(&cert); int mbedErr = mbedtls_x509_crt_parse(&cert, certificate->data, certificate->length); - if(mbedErr) { - UA_LOG_MBEDERR; + if(mbedErr) return UA_STATUSCODE_BADSECURITYCHECKSFAILED; - } UA_StatusCode retval = UA_STATUSCODE_GOOD; if(cert.raw.len != cc->remoteCertificate.raw.len || @@ -43804,6 +53699,55 @@ deleteMembers_sp_basic256sha256(UA_SecurityPolicy *securityPolicy) { } static UA_StatusCode +updateCertificateAndPrivateKey_sp_basic256sha256(UA_SecurityPolicy *securityPolicy, + const UA_ByteString newCertificate, + const UA_ByteString newPrivateKey) { + if(securityPolicy == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + if(securityPolicy->policyContext == NULL) + return UA_STATUSCODE_BADINTERNALERROR; + + Basic256Sha256_PolicyContext *pc = + (Basic256Sha256_PolicyContext *) securityPolicy->policyContext; + + UA_ByteString_deleteMembers(&securityPolicy->localCertificate); + + UA_StatusCode retval = UA_ByteString_allocBuffer(&securityPolicy->localCertificate, + newCertificate.length + 1); + if(retval != UA_STATUSCODE_GOOD) + return retval; + memcpy(securityPolicy->localCertificate.data, newCertificate.data, newCertificate.length); + securityPolicy->localCertificate.data[newCertificate.length] = '\0'; + securityPolicy->localCertificate.length--; + + /* Set the new private key */ + mbedtls_pk_free(&pc->localPrivateKey); + mbedtls_pk_init(&pc->localPrivateKey); + int mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, newPrivateKey.data, + newPrivateKey.length, NULL, 0); + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; + goto error; + } + + retval = asym_makeThumbprint_sp_basic256sha256(pc->securityPolicy, + &securityPolicy->localCertificate, + &pc->localCertThumbprint); + if(retval != UA_STATUSCODE_GOOD) + goto error; + + return retval; + + error: + UA_LOG_ERROR(securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, + "Could not update certificate and private key"); + if(securityPolicy->policyContext != NULL) + deleteMembers_sp_basic256sha256(securityPolicy); + return retval; +} + +static UA_StatusCode policyContext_newContext_sp_basic256sha256(UA_SecurityPolicy *securityPolicy, const UA_ByteString localPrivateKey) { UA_StatusCode retval = UA_STATUSCODE_GOOD; @@ -43829,34 +53773,37 @@ policyContext_newContext_sp_basic256sha256(UA_SecurityPolicy *securityPolicy, /* Initialized the message digest */ const mbedtls_md_info_t *const mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); int mbedErr = mbedtls_md_setup(&pc->sha256MdContext, mdInfo, MBEDTLS_MD_SHA256); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADOUTOFMEMORY); - if(retval != UA_STATUSCODE_GOOD) + if(mbedErr) { + retval = UA_STATUSCODE_BADOUTOFMEMORY; goto error; + } /* Add the system entropy source */ mbedErr = mbedtls_entropy_add_source(&pc->entropyContext, mbedtls_platform_entropy_poll, NULL, 0, MBEDTLS_ENTROPY_SOURCE_STRONG); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED); - if(retval != UA_STATUSCODE_GOOD) + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; goto error; + } /* Seed the RNG */ char *personalization = "open62541-drbg"; mbedErr = mbedtls_ctr_drbg_seed(&pc->drbgContext, mbedtls_entropy_func, &pc->entropyContext, (const unsigned char *)personalization, 14); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED); - if(retval != UA_STATUSCODE_GOOD) + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; goto error; + } /* Set the private key */ - mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, - localPrivateKey.data, localPrivateKey.length, - NULL, 0); - UA_MBEDTLS_ERRORHANDLING(UA_STATUSCODE_BADSECURITYCHECKSFAILED); - if(retval != UA_STATUSCODE_GOOD) + mbedErr = mbedtls_pk_parse_key(&pc->localPrivateKey, localPrivateKey.data, + localPrivateKey.length, NULL, 0); + if(mbedErr) { + retval = UA_STATUSCODE_BADSECURITYCHECKSFAILED; goto error; + } /* Set the local certificate thumbprint */ retval = UA_ByteString_allocBuffer(&pc->localCertThumbprint, UA_SHA1_LENGTH); @@ -43879,9 +53826,10 @@ error: } UA_StatusCode -UA_SecurityPolicy_Basic256Sha256(UA_SecurityPolicy *policy, UA_CertificateVerification *certificateVerification, - const UA_ByteString localCertificate, const UA_ByteString localPrivateKey, - UA_Logger logger) { +UA_SecurityPolicy_Basic256Sha256(UA_SecurityPolicy *policy, + UA_CertificateVerification *certificateVerification, + const UA_ByteString localCertificate, + const UA_ByteString localPrivateKey, const UA_Logger *logger) { memset(policy, 0, sizeof(UA_SecurityPolicy)); policy->logger = logger; @@ -44008,9 +53956,1247 @@ UA_SecurityPolicy_Basic256Sha256(UA_SecurityPolicy *policy, UA_CertificateVerifi channelModule->compareCertificate = (UA_StatusCode (*)(const void *, const UA_ByteString *)) channelContext_compareCertificate_sp_basic256sha256; + policy->updateCertificateAndPrivateKey = updateCertificateAndPrivateKey_sp_basic256sha256; policy->deleteMembers = deleteMembers_sp_basic256sha256; return policyContext_newContext_sp_basic256sha256(policy, localPrivateKey); } -#endif /* UA_ENABLE_ENCRYPTION */ +#endif + +/*********************************** amalgamated original file "/home/jvoe/open62541/arch/posix/ua_clock.c" ***********************************/ + +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA + */ + +#ifdef UA_ARCHITECTURE_POSIX + + +#include <time.h> + +#include <sys/time.h> + +#if defined(__APPLE__) || defined(__MACH__) +# include <mach/clock.h> +# include <mach/mach.h> +#endif + +UA_DateTime UA_DateTime_now(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec * UA_DATETIME_SEC) + (tv.tv_usec * UA_DATETIME_USEC) + UA_DATETIME_UNIX_EPOCH; +} + +/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */ +UA_Int64 UA_DateTime_localTimeUtcOffset(void) { + time_t gmt, rawtime = time(NULL); + struct tm *ptm; + struct tm gbuf; + ptm = gmtime_r(&rawtime, &gbuf); + // Request that mktime() looksup dst in timezone database + ptm->tm_isdst = -1; + gmt = mktime(ptm); + return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC); +} + +UA_DateTime UA_DateTime_nowMonotonic(void) { +#if defined(__APPLE__) || defined(__MACH__) + /* OS X does not have clock_gettime, use clock_get_time */ + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + return (mts.tv_sec * UA_DATETIME_SEC) + (mts.tv_nsec / 100); +#elif !defined(CLOCK_MONOTONIC_RAW) + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100); +#else + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + return (ts.tv_sec * UA_DATETIME_SEC) + (ts.tv_nsec / 100); +#endif +} + +#endif /* UA_ARCHITECTURE_POSIX */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/arch/posix/ua_architecture_functions.c" ***********************************/ + +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2018 (c) Jose Cabral, fortiss GmbH + */ + +#ifdef UA_ARCHITECTURE_POSIX + + +/* Global malloc singletons */ +#ifdef UA_ENABLE_MALLOC_SINGLETON +void * (*UA_globalMalloc)(size_t size) = malloc; +void (*UA_globalFree)(void *ptr) = free; +void * (*UA_globalCalloc)(size_t nelem, size_t elsize) = calloc; +void * (*UA_globalRealloc)(void *ptr, size_t size) = realloc; +#endif + +unsigned int UA_socket_set_blocking(UA_SOCKET sockfd){ + int opts = fcntl(sockfd, F_GETFL); + if(opts < 0 || fcntl(sockfd, F_SETFL, opts & (~O_NONBLOCK)) < 0) + return UA_STATUSCODE_BADINTERNALERROR; + return UA_STATUSCODE_GOOD; +} + +unsigned int UA_socket_set_nonblocking(UA_SOCKET sockfd){ + int opts = fcntl(sockfd, F_GETFL); + if(opts < 0 || fcntl(sockfd, F_SETFL, opts | O_NONBLOCK) < 0) + return UA_STATUSCODE_BADINTERNALERROR; + return UA_STATUSCODE_GOOD; +} + +void UA_initialize_architecture_network(void){ +} + +void UA_deinitialize_architecture_network(void){ +} + +#endif /* UA_ARCHITECTURE_POSIX */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/arch/win32/ua_clock.c" ***********************************/ + +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2016-2017 (c) Julius Pfrommer, Fraunhofer IOSB + * Copyright 2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) Thomas Stalder + */ + +#ifdef UA_ARCHITECTURE_WIN32 + +#ifndef _BSD_SOURCE +# define _BSD_SOURCE +#endif + + +#include <time.h> +/* Backup definition of SLIST_ENTRY on mingw winnt.h */ +# ifdef SLIST_ENTRY +# pragma push_macro("SLIST_ENTRY") +# undef SLIST_ENTRY +# define POP_SLIST_ENTRY +# endif +# include <windows.h> +/* restore definition */ +# ifdef POP_SLIST_ENTRY +# undef SLIST_ENTRY +# undef POP_SLIST_ENTRY +# pragma pop_macro("SLIST_ENTRY") +# endif + +UA_DateTime UA_DateTime_now(void) { + /* Windows filetime has the same definition as UA_DateTime */ + FILETIME ft; + SYSTEMTIME st; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + ULARGE_INTEGER ul; + ul.LowPart = ft.dwLowDateTime; + ul.HighPart = ft.dwHighDateTime; + return (UA_DateTime)ul.QuadPart; +} + +/* Credit to https://stackoverflow.com/questions/13804095/get-the-time-zone-gmt-offset-in-c */ +UA_Int64 UA_DateTime_localTimeUtcOffset(void) { + time_t gmt, rawtime = time(NULL); + + struct tm ptm; + gmtime_s(&ptm, &rawtime); + // Request that mktime() looksup dst in timezone database + ptm.tm_isdst = -1; + gmt = mktime(&ptm); + + return (UA_Int64) (difftime(rawtime, gmt) * UA_DATETIME_SEC); +} + +UA_DateTime UA_DateTime_nowMonotonic(void) { + LARGE_INTEGER freq, ticks; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&ticks); + UA_Double ticks2dt = UA_DATETIME_SEC / (UA_Double)freq.QuadPart; + return (UA_DateTime)(ticks.QuadPart * ticks2dt); +} + +#endif /* UA_ARCHITECTURE_WIN32 */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/arch/win32/ua_architecture_functions.c" ***********************************/ + +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2018 (c) Jose Cabral, fortiss GmbH + */ + +#ifdef UA_ARCHITECTURE_WIN32 + + +unsigned int UA_socket_set_blocking(UA_SOCKET sockfd){ + u_long iMode = 0; + if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR) + return UA_STATUSCODE_BADINTERNALERROR; + return UA_STATUSCODE_GOOD;; +} + +unsigned int UA_socket_set_nonblocking(UA_SOCKET sockfd){ + u_long iMode = 1; + if(ioctlsocket(sockfd, FIONBIO, &iMode) != NO_ERROR) + return UA_STATUSCODE_BADINTERNALERROR; + return UA_STATUSCODE_GOOD;; +} + +void UA_initialize_architecture_network(void){ + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 2), &wsaData); +} + +void UA_deinitialize_architecture_network(void){ + WSACleanup(); +} + +#endif /* UA_ARCHITECTURE_WIN32 */ + +/*********************************** amalgamated original file "/home/jvoe/open62541/arch/network_tcp.c" ***********************************/ + +/* This work is licensed under a Creative Commons CCZero 1.0 Universal License. + * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. + * + * Copyright 2016-2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer) + * Copyright 2016-2017 (c) Stefan Profanter, fortiss GmbH + * Copyright 2017 (c) frax2222 + * Copyright 2017 (c) Jose Cabral + * Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA + */ + +#define UA_INTERNAL + + + +#include <string.h> // memset + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +/****************************/ +/* Generic Socket Functions */ +/****************************/ + +static UA_StatusCode +connection_getsendbuffer(UA_Connection *connection, + size_t length, UA_ByteString *buf) { + if(length > connection->config.sendBufferSize) + return UA_STATUSCODE_BADCOMMUNICATIONERROR; + return UA_ByteString_allocBuffer(buf, length); +} + +static void +connection_releasesendbuffer(UA_Connection *connection, + UA_ByteString *buf) { + UA_ByteString_deleteMembers(buf); +} + +static void +connection_releaserecvbuffer(UA_Connection *connection, + UA_ByteString *buf) { + UA_ByteString_deleteMembers(buf); +} + +static UA_StatusCode +connection_write(UA_Connection *connection, UA_ByteString *buf) { + if(connection->state == UA_CONNECTION_CLOSED) { + UA_ByteString_deleteMembers(buf); + return UA_STATUSCODE_BADCONNECTIONCLOSED; + } + + /* Prevent OS signals when sending to a closed socket */ + int flags = 0; + flags |= MSG_NOSIGNAL; + + /* Send the full buffer. This may require several calls to send */ + size_t nWritten = 0; + do { + ssize_t n = 0; + do { + size_t bytes_to_send = buf->length - nWritten; + n = UA_send(connection->sockfd, + (const char*)buf->data + nWritten, + bytes_to_send, flags); + if(n < 0 && UA_ERRNO != UA_INTERRUPTED && UA_ERRNO != UA_AGAIN) { + connection->close(connection); + UA_ByteString_deleteMembers(buf); + return UA_STATUSCODE_BADCONNECTIONCLOSED; + } + } while(n < 0); + nWritten += (size_t)n; + } while(nWritten < buf->length); + + /* Free the buffer */ + UA_ByteString_deleteMembers(buf); + return UA_STATUSCODE_GOOD; +} + +static UA_StatusCode +connection_recv(UA_Connection *connection, UA_ByteString *response, + UA_UInt32 timeout) { + if(connection->state == UA_CONNECTION_CLOSED) + return UA_STATUSCODE_BADCONNECTIONCLOSED; + + /* Listen on the socket for the given timeout until a message arrives */ + if(timeout > 0) { + fd_set fdset; + FD_ZERO(&fdset); + UA_fd_set(connection->sockfd, &fdset); + UA_UInt32 timeout_usec = timeout * 1000; + struct timeval tmptv = {(long int)(timeout_usec / 1000000), + (int)(timeout_usec % 1000000)}; + int resultsize = UA_select(connection->sockfd+1, &fdset, NULL, + NULL, &tmptv); + + /* No result */ + if(resultsize == 0) + return UA_STATUSCODE_GOODNONCRITICALTIMEOUT; + + if(resultsize == -1) { + /* The call to select was interrupted manually. Act as if it timed + * out */ + if(UA_ERRNO == EINTR) + return UA_STATUSCODE_GOODNONCRITICALTIMEOUT; + + /* The error cannot be recovered. Close the connection. */ + connection->close(connection); + return UA_STATUSCODE_BADCONNECTIONCLOSED; + } + } + + response->data = (UA_Byte*)UA_malloc(connection->config.recvBufferSize); + if(!response->data) { + response->length = 0; + return UA_STATUSCODE_BADOUTOFMEMORY; /* not enough memory retry */ + } + +#ifdef _WIN32 + // windows requires int parameter for length + int offset = (int)connection->incompleteChunk.length; + int remaining = connection->config.recvBufferSize - offset; +#else + size_t offset = connection->incompleteChunk.length; + size_t remaining = connection->config.recvBufferSize - offset; +#endif + + /* Get the received packet(s) */ + ssize_t ret = UA_recv(connection->sockfd, (char*)&response->data[offset], + remaining, 0); + + /* The remote side closed the connection */ + if(ret == 0) { + UA_ByteString_deleteMembers(response); + connection->close(connection); + return UA_STATUSCODE_BADCONNECTIONCLOSED; + } + + /* Error case */ + if(ret < 0) { + UA_ByteString_deleteMembers(response); + if(UA_ERRNO == UA_INTERRUPTED || (timeout > 0) ? + false : (UA_ERRNO == UA_EAGAIN || UA_ERRNO == UA_WOULDBLOCK)) + return UA_STATUSCODE_GOOD; /* statuscode_good but no data -> retry */ + connection->close(connection); + return UA_STATUSCODE_BADCONNECTIONCLOSED; + } + + /* Preprend the last incompleteChunk into the buffer */ + if (connection->incompleteChunk.length > 0) { + memcpy(response->data, connection->incompleteChunk.data, + connection->incompleteChunk.length); + UA_ByteString_deleteMembers(&connection->incompleteChunk); + } + + /* Set the length of the received buffer */ + response->length = offset + (size_t)ret; + return UA_STATUSCODE_GOOD; +} + + +/***************************/ +/* Server NetworkLayer TCP */ +/***************************/ + +#define MAXBACKLOG 100 +#define NOHELLOTIMEOUT 120000 /* timeout in ms before close the connection + * if server does not receive Hello Message */ + +typedef struct ConnectionEntry { + UA_Connection connection; + LIST_ENTRY(ConnectionEntry) pointers; +} ConnectionEntry; + +typedef struct { + const UA_Logger *logger; + UA_UInt16 port; + UA_SOCKET serverSockets[FD_SETSIZE]; + UA_UInt16 serverSocketsSize; + LIST_HEAD(, ConnectionEntry) connections; +} ServerNetworkLayerTCP; + +static void +ServerNetworkLayerTCP_freeConnection(UA_Connection *connection) { + UA_Connection_deleteMembers(connection); + UA_free(connection); +} + +/* This performs only 'shutdown'. 'close' is called when the shutdown + * socket is returned from select. */ +static void +ServerNetworkLayerTCP_close(UA_Connection *connection) { + if (connection->state == UA_CONNECTION_CLOSED) + return; + UA_shutdown((UA_SOCKET)connection->sockfd, 2); + connection->state = UA_CONNECTION_CLOSED; +} + +static UA_StatusCode +ServerNetworkLayerTCP_add(UA_ServerNetworkLayer *nl, ServerNetworkLayerTCP *layer, + UA_Int32 newsockfd, struct sockaddr_storage *remote) { + /* Set nonblocking */ + UA_socket_set_nonblocking(newsockfd);//TODO: check return value + + /* Do not merge packets on the socket (disable Nagle's algorithm) */ + int dummy = 1; + if(UA_setsockopt(newsockfd, IPPROTO_TCP, TCP_NODELAY, + (const char *)&dummy, sizeof(dummy)) < 0) { + UA_LOG_SOCKET_ERRNO_WRAP( + UA_LOG_ERROR(layer->logger, UA_LOGCATEGORY_NETWORK, + "Cannot set socket option TCP_NODELAY. Error: %s", + errno_str)); + return UA_STATUSCODE_BADUNEXPECTEDERROR; + } + +#if defined(UA_getnameinfo) + /* Get the peer name for logging */ + char remote_name[100]; + int res = UA_getnameinfo((struct sockaddr*)remote, + sizeof(struct sockaddr_storage), + remote_name, sizeof(remote_name), + NULL, 0, NI_NUMERICHOST); + if(res == 0) { + UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | New connection over TCP from %s", + (int)newsockfd, remote_name); + } else { + UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | New connection over TCP, " + "getnameinfo failed with error: %s", + (int)newsockfd, errno_str)); + } +#else + UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | New connection over TCP", + (int)newsockfd); +#endif + /* Allocate and initialize the connection */ + ConnectionEntry *e = (ConnectionEntry*)UA_malloc(sizeof(ConnectionEntry)); + if(!e){ + UA_close(newsockfd); + return UA_STATUSCODE_BADOUTOFMEMORY; + } + + UA_Connection *c = &e->connection; + memset(c, 0, sizeof(UA_Connection)); + c->sockfd = newsockfd; + c->handle = layer; + c->config = nl->localConnectionConfig; + c->send = connection_write; + c->close = ServerNetworkLayerTCP_close; + c->free = ServerNetworkLayerTCP_freeConnection; + c->getSendBuffer = connection_getsendbuffer; + c->releaseSendBuffer = connection_releasesendbuffer; + c->releaseRecvBuffer = connection_releaserecvbuffer; + c->state = UA_CONNECTION_OPENING; + c->openingDate = UA_DateTime_nowMonotonic(); + + /* Add to the linked list */ + LIST_INSERT_HEAD(&layer->connections, e, pointers); + return UA_STATUSCODE_GOOD; +} + +static void +addServerSocket(ServerNetworkLayerTCP *layer, struct addrinfo *ai) { + /* Create the server socket */ + UA_SOCKET newsock = UA_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if(newsock == UA_INVALID_SOCKET) + { + UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, + "Error opening the server socket"); + return; + } + + /* Some Linux distributions have net.ipv6.bindv6only not activated. So + * sockets can double-bind to IPv4 and IPv6. This leads to problems. Use + * AF_INET6 sockets only for IPv6. */ + + int optval = 1; +#if UA_IPV6 + if(ai->ai_family == AF_INET6 && + UA_setsockopt(newsock, IPPROTO_IPV6, IPV6_V6ONLY, + (const char*)&optval, sizeof(optval)) == -1) { + UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, + "Could not set an IPv6 socket to IPv6 only"); + UA_close(newsock); + return; + } +#endif + if(UA_setsockopt(newsock, SOL_SOCKET, SO_REUSEADDR, + (const char *)&optval, sizeof(optval)) == -1) { + UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, + "Could not make the socket reusable"); + UA_close(newsock); + return; + } + + + if(UA_socket_set_nonblocking(newsock) != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, + "Could not set the server socket to nonblocking"); + UA_close(newsock); + return; + } + + /* Bind socket to address */ + if(UA_bind(newsock, ai->ai_addr, (socklen_t)ai->ai_addrlen) < 0) { + UA_LOG_SOCKET_ERRNO_WRAP( + UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, + "Error binding a server socket: %s", errno_str)); + UA_close(newsock); + return; + } + + /* Start listening */ + if(UA_listen(newsock, MAXBACKLOG) < 0) { + UA_LOG_SOCKET_ERRNO_WRAP( + UA_LOG_WARNING(layer->logger, UA_LOGCATEGORY_NETWORK, + "Error listening on server socket: %s", errno_str)); + UA_close(newsock); + return; + } + + if (layer->port == 0) { + /* Port was automatically chosen. Read it from the OS */ + struct sockaddr_in returned_addr; + memset(&returned_addr, 0, sizeof(returned_addr)); + socklen_t len = sizeof(returned_addr); + UA_getsockname(newsock, (struct sockaddr *)&returned_addr, &len); + layer->port = ntohs(returned_addr.sin_port); + } + + layer->serverSockets[layer->serverSocketsSize] = newsock; + layer->serverSocketsSize++; +} + +static UA_StatusCode +ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, const UA_String *customHostname) { + UA_initialize_architecture_network(); + + ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle; + + /* Get addrinfo of the server and create server sockets */ + char portno[6]; + UA_snprintf(portno, 6, "%d", layer->port); + struct addrinfo hints, *res; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = IPPROTO_TCP; + if(UA_getaddrinfo(NULL, portno, &hints, &res) != 0) + return UA_STATUSCODE_BADINTERNALERROR; + + /* There might be serveral addrinfos (for different network cards, + * IPv4/IPv6). Add a server socket for all of them. */ + struct addrinfo *ai = res; + for(layer->serverSocketsSize = 0; + layer->serverSocketsSize < FD_SETSIZE && ai != NULL; + ai = ai->ai_next) + addServerSocket(layer, ai); + UA_freeaddrinfo(res); + + /* Get the discovery url from the hostname */ + UA_String du = UA_STRING_NULL; + char discoveryUrlBuffer[256]; + char hostnameBuffer[256]; + if (customHostname->length) { + du.length = (size_t)UA_snprintf(discoveryUrlBuffer, 255, "opc.tcp://%.*s:%d/", + (int)customHostname->length, + customHostname->data, + layer->port); + du.data = (UA_Byte*)discoveryUrlBuffer; + }else{ + if(UA_gethostname(hostnameBuffer, 255) == 0) { + du.length = (size_t)UA_snprintf(discoveryUrlBuffer, 255, "opc.tcp://%s:%d/", + hostnameBuffer, layer->port); + du.data = (UA_Byte*)discoveryUrlBuffer; + } else { + UA_LOG_ERROR(layer->logger, UA_LOGCATEGORY_NETWORK, "Could not get the hostname"); + } + } + UA_String_copy(&du, &nl->discoveryUrl); + + UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, + "TCP network layer listening on %.*s", + (int)nl->discoveryUrl.length, nl->discoveryUrl.data); + return UA_STATUSCODE_GOOD; +} + +/* After every select, reset the sockets to listen on */ +static UA_Int32 +setFDSet(ServerNetworkLayerTCP *layer, fd_set *fdset) { + FD_ZERO(fdset); + UA_Int32 highestfd = 0; + for(UA_UInt16 i = 0; i < layer->serverSocketsSize; i++) { + UA_fd_set(layer->serverSockets[i], fdset); + if((UA_Int32)layer->serverSockets[i] > highestfd) + highestfd = (UA_Int32)layer->serverSockets[i]; + } + + ConnectionEntry *e; + LIST_FOREACH(e, &layer->connections, pointers) { + UA_fd_set(e->connection.sockfd, fdset); + if((UA_Int32)e->connection.sockfd > highestfd) + highestfd = (UA_Int32)e->connection.sockfd; + } + + return highestfd; +} + +static UA_StatusCode +ServerNetworkLayerTCP_listen(UA_ServerNetworkLayer *nl, UA_Server *server, + UA_UInt16 timeout) { + /* Every open socket can generate two jobs */ + ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle; + + if (layer->serverSocketsSize == 0) + return UA_STATUSCODE_GOOD; + + /* Listen on open sockets (including the server) */ + fd_set fdset, errset; + UA_Int32 highestfd = setFDSet(layer, &fdset); + setFDSet(layer, &errset); + struct timeval tmptv = {0, timeout * 1000}; + if (UA_select(highestfd+1, &fdset, NULL, &errset, &tmptv) < 0) { + UA_LOG_SOCKET_ERRNO_WRAP( + UA_LOG_DEBUG(layer->logger, UA_LOGCATEGORY_NETWORK, + "Socket select failed with %s", errno_str)); + // we will retry, so do not return bad + return UA_STATUSCODE_GOOD; + } + + /* Accept new connections via the server sockets */ + for(UA_UInt16 i = 0; i < layer->serverSocketsSize; i++) { + if(!UA_fd_isset(layer->serverSockets[i], &fdset)) + continue; + + struct sockaddr_storage remote; + socklen_t remote_size = sizeof(remote); + UA_SOCKET newsockfd = UA_accept((UA_SOCKET)layer->serverSockets[i], + (struct sockaddr*)&remote, &remote_size); + if(newsockfd == UA_INVALID_SOCKET) + continue; + + UA_LOG_TRACE(layer->logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | New TCP connection on server socket %i", + (int)newsockfd, (int)(layer->serverSockets[i])); + + ServerNetworkLayerTCP_add(nl, layer, (UA_Int32)newsockfd, &remote); + } + + /* Read from established sockets */ + ConnectionEntry *e, *e_tmp; + UA_DateTime now = UA_DateTime_nowMonotonic(); + LIST_FOREACH_SAFE(e, &layer->connections, pointers, e_tmp) { + if ((e->connection.state == UA_CONNECTION_OPENING) && + (now > (e->connection.openingDate + (NOHELLOTIMEOUT * UA_DATETIME_MSEC)))){ + UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | Closed by the server (no Hello Message)", + (int)(e->connection.sockfd)); + LIST_REMOVE(e, pointers); + UA_close(e->connection.sockfd); + UA_Server_removeConnection(server, &e->connection); + continue; + } + + if(!UA_fd_isset(e->connection.sockfd, &errset) && + !UA_fd_isset(e->connection.sockfd, &fdset)) + continue; + + UA_LOG_TRACE(layer->logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | Activity on the socket", + (int)(e->connection.sockfd)); + + UA_ByteString buf = UA_BYTESTRING_NULL; + UA_StatusCode retval = connection_recv(&e->connection, &buf, 0); + + if(retval == UA_STATUSCODE_GOOD) { + /* Process packets */ + UA_Server_processBinaryMessage(server, &e->connection, &buf); + connection_releaserecvbuffer(&e->connection, &buf); + } else if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED) { + /* The socket is shutdown but not closed */ + UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, + "Connection %i | Closed", + (int)(e->connection.sockfd)); + LIST_REMOVE(e, pointers); + UA_close(e->connection.sockfd); + UA_Server_removeConnection(server, &e->connection); + } + } + return UA_STATUSCODE_GOOD; +} + +static void +ServerNetworkLayerTCP_stop(UA_ServerNetworkLayer *nl, UA_Server *server) { + ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle; + UA_LOG_INFO(layer->logger, UA_LOGCATEGORY_NETWORK, + "Shutting down the TCP network layer"); + + /* Close the server sockets */ + for(UA_UInt16 i = 0; i < layer->serverSocketsSize; i++) { + UA_shutdown(layer->serverSockets[i], 2); + UA_close(layer->serverSockets[i]); + } + layer->serverSocketsSize = 0; + + /* Close open connections */ + ConnectionEntry *e; + LIST_FOREACH(e, &layer->connections, pointers) + ServerNetworkLayerTCP_close(&e->connection); + + /* Run recv on client sockets. This picks up the closed sockets and frees + * the connection. */ + ServerNetworkLayerTCP_listen(nl, server, 0); + + UA_deinitialize_architecture_network(); +} + +/* run only when the server is stopped */ +static void +ServerNetworkLayerTCP_deleteMembers(UA_ServerNetworkLayer *nl) { + ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP *)nl->handle; + UA_String_deleteMembers(&nl->discoveryUrl); + + /* Hard-close and remove remaining connections. The server is no longer + * running. So this is safe. */ + ConnectionEntry *e, *e_tmp; + LIST_FOREACH_SAFE(e, &layer->connections, pointers, e_tmp) { + LIST_REMOVE(e, pointers); + UA_close(e->connection.sockfd); + UA_free(e); + } + + /* Free the layer */ + UA_free(layer); +} + +UA_ServerNetworkLayer +UA_ServerNetworkLayerTCP(UA_ConnectionConfig config, UA_UInt16 port, + UA_Logger *logger) { + UA_ServerNetworkLayer nl; + memset(&nl, 0, sizeof(UA_ServerNetworkLayer)); + nl.deleteMembers = ServerNetworkLayerTCP_deleteMembers; + nl.localConnectionConfig = config; + nl.start = ServerNetworkLayerTCP_start; + nl.listen = ServerNetworkLayerTCP_listen; + nl.stop = ServerNetworkLayerTCP_stop; + nl.handle = NULL; + + ServerNetworkLayerTCP *layer = (ServerNetworkLayerTCP*) + UA_calloc(1,sizeof(ServerNetworkLayerTCP)); + if(!layer) + return nl; + nl.handle = layer; + + layer->logger = logger; + layer->port = port; + + return nl; +} + +typedef struct TCPClientConnection { + struct addrinfo hints, *server; + UA_DateTime connStart; + char* endpointURL; + UA_UInt32 timeout; +} TCPClientConnection; + +/***************************/ +/* Client NetworkLayer TCP */ +/***************************/ + +static void +ClientNetworkLayerTCP_close(UA_Connection *connection) { + if (connection->state == UA_CONNECTION_CLOSED) + return; + + if(connection->sockfd != UA_INVALID_SOCKET) { + UA_shutdown(connection->sockfd, 2); + UA_close(connection->sockfd); + } + connection->state = UA_CONNECTION_CLOSED; +} + +static void +ClientNetworkLayerTCP_free(UA_Connection *connection) { + if(connection->handle) { + TCPClientConnection *tcpConnection = (TCPClientConnection *)connection->handle; + if(tcpConnection->server) + UA_freeaddrinfo(tcpConnection->server); + UA_free(tcpConnection); + connection->handle = NULL; + } +} + +UA_StatusCode UA_ClientConnectionTCP_poll(UA_Client *client, void *data) { + UA_Connection *connection = (UA_Connection*) data; + + if (connection->state == UA_CONNECTION_CLOSED) + return UA_STATUSCODE_BADDISCONNECT; + + TCPClientConnection *tcpConnection = + (TCPClientConnection*) connection->handle; + + UA_DateTime connStart = UA_DateTime_nowMonotonic(); + UA_SOCKET clientsockfd = connection->sockfd; + + UA_ClientConfig *config = UA_Client_getConfig(client); + + if (connection->state == UA_CONNECTION_ESTABLISHED) { + UA_Client_removeRepeatedCallback(client, connection->connectCallbackID); + connection->connectCallbackID = 0; + return UA_STATUSCODE_GOOD; + } + if ((UA_Double) (UA_DateTime_nowMonotonic() - tcpConnection->connStart) + > tcpConnection->timeout* UA_DATETIME_MSEC ) { + // connection timeout + ClientNetworkLayerTCP_close(connection); + UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, + "Timed out"); + return UA_STATUSCODE_BADDISCONNECT; + + } + /* On linux connect may immediately return with ECONNREFUSED but we still want to try to connect */ + /* Thus use a loop and retry until timeout is reached */ + + /* Get a socket */ + if(clientsockfd <= 0) { + clientsockfd = UA_socket(tcpConnection->server->ai_family, + tcpConnection->server->ai_socktype, + tcpConnection->server->ai_protocol); + connection->sockfd = (UA_Int32)clientsockfd; /* cast for win32 */ + } + + if(clientsockfd == UA_INVALID_SOCKET) { + UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, + "Could not create client socket: %s", strerror(UA_ERRNO)); + ClientNetworkLayerTCP_close(connection); + return UA_STATUSCODE_BADDISCONNECT; + } + + /* Non blocking connect to be able to timeout */ + if(UA_socket_set_nonblocking(clientsockfd) != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, + "Could not set the client socket to nonblocking"); + ClientNetworkLayerTCP_close(connection); + return UA_STATUSCODE_BADDISCONNECT; + } + + /* Non blocking connect */ + int error = UA_connect(clientsockfd, tcpConnection->server->ai_addr, + tcpConnection->server->ai_addrlen); + + if ((error == -1) && (UA_ERRNO != UA_ERR_CONNECTION_PROGRESS)) { + ClientNetworkLayerTCP_close(connection); + UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, + "Connection to failed with error: %s", strerror(UA_ERRNO)); + return UA_STATUSCODE_BADDISCONNECT; + } + + /* Use select to wait and check if connected */ + if (error == -1 && (UA_ERRNO == UA_ERR_CONNECTION_PROGRESS)) { + /* connection in progress. Wait until connected using select */ + + UA_UInt32 timeSinceStart = (UA_UInt32) + ((UA_Double) (UA_DateTime_nowMonotonic() - connStart) / UA_DATETIME_MSEC); +#ifdef _OS9000 + /* OS-9 can't use select for checking write sockets. + * Therefore, we need to use connect until success or failed + */ + UA_UInt32 timeout_usec = (tcpConnection->timeout - timeSinceStart) + * 1000; + int resultsize = 0; + do { + u_int32 time = 0x80000001; + signal_code sig; + + timeout_usec -= 1000000/256; // Sleep 1/256 second + if (timeout_usec < 0) + break; + + _os_sleep(&time,&sig); + error = connect(clientsockfd, tcpConnection->server->ai_addr, + tcpConnection->server->ai_addrlen); + if ((error == -1 && UA_ERRNO == EISCONN) || (error == 0)) + resultsize = 1; + if (error == -1 && UA_ERRNO != EALREADY && UA_ERRNO != EINPROGRESS) + break; + } + while(resultsize == 0); +#else + fd_set fdset; + FD_ZERO(&fdset); + UA_fd_set(clientsockfd, &fdset); + UA_UInt32 timeout_usec = (tcpConnection->timeout - timeSinceStart) + * 1000; + struct timeval tmptv = { (long int) (timeout_usec / 1000000), + (int) (timeout_usec % 1000000) }; + + int resultsize = UA_select((UA_Int32) (clientsockfd + 1), NULL, &fdset, + NULL, &tmptv); +#endif + if (resultsize == 1) { + /* Windows does not have any getsockopt equivalent and it is not needed there */ +#ifdef _WIN32 + connection->sockfd = clientsockfd; + connection->state = UA_CONNECTION_ESTABLISHED; + return UA_STATUSCODE_GOOD; +#else + OPTVAL_TYPE so_error; + socklen_t len = sizeof so_error; + + int ret = UA_getsockopt(clientsockfd, SOL_SOCKET, SO_ERROR, &so_error, + &len); + + if (ret != 0 || so_error != 0) { + /* on connection refused we should still try to connect */ + /* connection refused happens on localhost or local ip without timeout */ + if (so_error != ECONNREFUSED) { + // general error + ClientNetworkLayerTCP_close(connection); + UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, + "Connection to failed with error: %s", + strerror(ret == 0 ? so_error : UA_ERRNO)); + return UA_STATUSCODE_BADDISCONNECT; + } + /* wait until we try a again. Do not make this too small, otherwise the + * timeout is somehow wrong */ + + } else { + connection->state = UA_CONNECTION_ESTABLISHED; + return UA_STATUSCODE_GOOD; + } +#endif + } + } else { + connection->state = UA_CONNECTION_ESTABLISHED; + return UA_STATUSCODE_GOOD; + } + +#ifdef SO_NOSIGPIPE + int val = 1; + int sso_result = setsockopt(connection->sockfd, SOL_SOCKET, + SO_NOSIGPIPE, (void*)&val, sizeof(val)); + if(sso_result < 0) + UA_LOG_WARNING(&config->logger, UA_LOGCATEGORY_NETWORK, + "Couldn't set SO_NOSIGPIPE"); +#endif + + return UA_STATUSCODE_GOOD; + +} + +UA_Connection +UA_ClientConnectionTCP_init(UA_ConnectionConfig config, const UA_String endpointUrl, + UA_UInt32 timeout, UA_Logger *logger) { + UA_Connection connection; + memset(&connection, 0, sizeof(UA_Connection)); + + connection.state = UA_CONNECTION_OPENING; + connection.config = config; + connection.send = connection_write; + connection.recv = connection_recv; + connection.close = ClientNetworkLayerTCP_close; + connection.free = ClientNetworkLayerTCP_free; + connection.getSendBuffer = connection_getsendbuffer; + connection.releaseSendBuffer = connection_releasesendbuffer; + connection.releaseRecvBuffer = connection_releaserecvbuffer; + + TCPClientConnection *tcpClientConnection = (TCPClientConnection*) UA_malloc( + sizeof(TCPClientConnection)); + connection.handle = (void*) tcpClientConnection; + tcpClientConnection->timeout = timeout; + UA_String hostnameString = UA_STRING_NULL; + UA_String pathString = UA_STRING_NULL; + UA_UInt16 port = 0; + char hostname[512]; + tcpClientConnection->connStart = UA_DateTime_nowMonotonic(); + + UA_StatusCode parse_retval = UA_parseEndpointUrl(&endpointUrl, + &hostnameString, &port, &pathString); + if (parse_retval != UA_STATUSCODE_GOOD || hostnameString.length > 511) { + UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Server url is invalid: %.*s", + (int)endpointUrl.length, endpointUrl.data); + connection.state = UA_CONNECTION_CLOSED; + return connection; + } + memcpy(hostname, hostnameString.data, hostnameString.length); + hostname[hostnameString.length] = 0; + + if (port == 0) { + port = 4840; + UA_LOG_INFO(logger, UA_LOGCATEGORY_NETWORK, + "No port defined, using default port %d", port); + } + + memset(&tcpClientConnection->hints, 0, sizeof(tcpClientConnection->hints)); + tcpClientConnection->hints.ai_family = AF_UNSPEC; + tcpClientConnection->hints.ai_socktype = SOCK_STREAM; + char portStr[6]; + UA_snprintf(portStr, 6, "%d", port); + int error = UA_getaddrinfo(hostname, portStr, &tcpClientConnection->hints, + &tcpClientConnection->server); + if (error != 0 || !tcpClientConnection->server) { + UA_LOG_SOCKET_ERRNO_GAI_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "DNS lookup of %s failed with error %s", hostname, errno_str)); + connection.state = UA_CONNECTION_CLOSED; + return connection; + } + return connection; +} + +UA_Connection +UA_ClientConnectionTCP(UA_ConnectionConfig config, const UA_String endpointUrl, + UA_UInt32 timeout, UA_Logger *logger) { + UA_initialize_architecture_network(); + + UA_Connection connection; + memset(&connection, 0, sizeof(UA_Connection)); + connection.state = UA_CONNECTION_CLOSED; + connection.config = config; + connection.send = connection_write; + connection.recv = connection_recv; + connection.close = ClientNetworkLayerTCP_close; + connection.free = ClientNetworkLayerTCP_free; + connection.getSendBuffer = connection_getsendbuffer; + connection.releaseSendBuffer = connection_releasesendbuffer; + connection.releaseRecvBuffer = connection_releaserecvbuffer; + connection.handle = NULL; + + UA_String hostnameString = UA_STRING_NULL; + UA_String pathString = UA_STRING_NULL; + UA_UInt16 port = 0; + char hostname[512]; + + UA_StatusCode parse_retval = + UA_parseEndpointUrl(&endpointUrl, &hostnameString, &port, &pathString); + if(parse_retval != UA_STATUSCODE_GOOD || hostnameString.length > 511) { + UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Server url is invalid: %.*s", + (int)endpointUrl.length, endpointUrl.data); + return connection; + } + memcpy(hostname, hostnameString.data, hostnameString.length); + hostname[hostnameString.length] = 0; + + if(port == 0) { + port = 4840; + UA_LOG_INFO(logger, UA_LOGCATEGORY_NETWORK, + "No port defined, using default port %d", port); + } + + struct addrinfo hints, *server; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + char portStr[6]; + UA_snprintf(portStr, 6, "%d", port); + int error = UA_getaddrinfo(hostname, portStr, &hints, &server); + if(error != 0 || !server) { + UA_LOG_SOCKET_ERRNO_GAI_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "DNS lookup of %s failed with error %s", hostname, errno_str)); + return connection; + } + + UA_Boolean connected = false; + UA_DateTime dtTimeout = timeout * UA_DATETIME_MSEC; + UA_DateTime connStart = UA_DateTime_nowMonotonic(); + UA_SOCKET clientsockfd; + + /* On linux connect may immediately return with ECONNREFUSED but we still + * want to try to connect. So use a loop and retry until timeout is + * reached. */ + do { + /* Get a socket */ + clientsockfd = UA_socket(server->ai_family, + server->ai_socktype, + server->ai_protocol); + if(clientsockfd == UA_INVALID_SOCKET) { + UA_LOG_SOCKET_ERRNO_WRAP(UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Could not create client socket: %s", errno_str)); + UA_freeaddrinfo(server); + return connection; + } + + connection.state = UA_CONNECTION_OPENING; + + /* Connect to the server */ + connection.sockfd = clientsockfd; + + /* Non blocking connect to be able to timeout */ + if (UA_socket_set_nonblocking(clientsockfd) != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Could not set the client socket to nonblocking"); + ClientNetworkLayerTCP_close(&connection); + UA_freeaddrinfo(server); + return connection; + } + + /* Non blocking connect */ + error = UA_connect(clientsockfd, server->ai_addr, (socklen_t)server->ai_addrlen); + + if ((error == -1) && (UA_ERRNO != UA_ERR_CONNECTION_PROGRESS)) { + ClientNetworkLayerTCP_close(&connection); + UA_LOG_SOCKET_ERRNO_WRAP( + UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Connection to %.*s failed with error: %s", + (int)endpointUrl.length, endpointUrl.data, errno_str)); + UA_freeaddrinfo(server); + return connection; + } + + /* Use select to wait and check if connected */ + if (error == -1 && (UA_ERRNO == UA_ERR_CONNECTION_PROGRESS)) { + /* connection in progress. Wait until connected using select */ + UA_DateTime timeSinceStart = UA_DateTime_nowMonotonic() - connStart; + if(timeSinceStart > dtTimeout) + break; + +#ifdef _OS9000 + /* OS-9 can't use select for checking write sockets. + * Therefore, we need to use connect until success or failed + */ + UA_DateTime timeout_usec = (dtTimeout - timeSinceStart) / UA_DATETIME_USEC; + int resultsize = 0; + do { + u_int32 time = 0x80000001; + signal_code sig; + + timeout_usec -= 1000000/256; // Sleep 1/256 second + if (timeout_usec < 0) + break; + + _os_sleep(&time,&sig); + error = connect(clientsockfd, server->ai_addr, server->ai_addrlen); + if ((error == -1 && UA_ERRNO == EISCONN) || (error == 0)) + resultsize = 1; + if (error == -1 && UA_ERRNO != EALREADY && UA_ERRNO != EINPROGRESS) + break; + } + while(resultsize == 0); +#else + fd_set fdset; + FD_ZERO(&fdset); + UA_fd_set(clientsockfd, &fdset); + UA_DateTime timeout_usec = (dtTimeout - timeSinceStart) / UA_DATETIME_USEC; + struct timeval tmptv = {(long int) (timeout_usec / 1000000), + (int) (timeout_usec % 1000000)}; + + int resultsize = UA_select((UA_Int32)(clientsockfd + 1), NULL, &fdset, NULL, &tmptv); +#endif + + if(resultsize == 1) { +#ifdef _WIN32 + /* Windows does not have any getsockopt equivalent and it is not + * needed there */ + connected = true; + break; +#else + OPTVAL_TYPE so_error; + socklen_t len = sizeof so_error; + + int ret = UA_getsockopt(clientsockfd, SOL_SOCKET, SO_ERROR, &so_error, &len); + + if (ret != 0 || so_error != 0) { + /* on connection refused we should still try to connect */ + /* connection refused happens on localhost or local ip without timeout */ + if (so_error != ECONNREFUSED) { + ClientNetworkLayerTCP_close(&connection); + UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Connection to %.*s failed with error: %s", + (int)endpointUrl.length, endpointUrl.data, + strerror(ret == 0 ? so_error : UA_ERRNO)); + UA_freeaddrinfo(server); + return connection; + } + /* wait until we try a again. Do not make this too small, otherwise the + * timeout is somehow wrong */ + UA_sleep_ms(100); + } else { + connected = true; + break; + } +#endif + } + } else { + connected = true; + break; + } + ClientNetworkLayerTCP_close(&connection); + + } while ((UA_DateTime_nowMonotonic() - connStart) < dtTimeout); + + UA_freeaddrinfo(server); + + if(!connected) { + /* connection timeout */ + if (connection.state != UA_CONNECTION_CLOSED) + ClientNetworkLayerTCP_close(&connection); + UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Trying to connect to %.*s timed out", + (int)endpointUrl.length, endpointUrl.data); + return connection; + } + + + /* We are connected. Reset socket to blocking */ + if(UA_socket_set_blocking(clientsockfd) != UA_STATUSCODE_GOOD) { + UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Could not set the client socket to blocking"); + ClientNetworkLayerTCP_close(&connection); + return connection; + } + +#ifdef SO_NOSIGPIPE + int val = 1; + int sso_result = UA_setsockopt(connection.sockfd, SOL_SOCKET, + SO_NOSIGPIPE, (void*)&val, sizeof(val)); + if(sso_result < 0) + UA_LOG_WARNING(logger, UA_LOGCATEGORY_NETWORK, + "Couldn't set SO_NOSIGPIPE"); +#endif + + return connection; +} |