|
@@ -18,8 +18,197 @@ deletion. The following functions are present for all data types ``T``.
|
|
|
``void T_delete(T *ptr)``
|
|
|
Delete the content of the data type and the memory for the data type itself.
|
|
|
|
|
|
-Here's a small example for the UA_String data type. UA_String will be introduced
|
|
|
-in more detail later on, but you should be able to follow the example already.
|
|
|
+The builtin data types
|
|
|
+----------------------
|
|
|
+
|
|
|
+OPC UA defines 25 builtin data types. All other data types are combinations of
|
|
|
+the 25 builtin data types.
|
|
|
+
|
|
|
+UA_Boolean
|
|
|
+^^^^^^^^^^
|
|
|
+
|
|
|
+A two-state logical value (true or false).
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef bool UA_Boolean;
|
|
|
+ #define UA_TRUE true
|
|
|
+ #define UA_FALSE false
|
|
|
+
|
|
|
+UA_SByte
|
|
|
+^^^^^^^^
|
|
|
+
|
|
|
+An integer value between -128 and 127.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef int8_t UA_SByte;
|
|
|
+
|
|
|
+UA_Byte
|
|
|
+^^^^^^^
|
|
|
+
|
|
|
+An integer value between 0 and 256.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef uint8_t UA_Byte;
|
|
|
+
|
|
|
+UA_Int16
|
|
|
+^^^^^^^^
|
|
|
+
|
|
|
+An integer value between -32,768 and 32,767.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef int16_t UA_Int16;
|
|
|
+
|
|
|
+UA_UInt16
|
|
|
+^^^^^^^^^
|
|
|
+
|
|
|
+An integer value between 0 and 65,535.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef uint16_t UA_UInt16;
|
|
|
+
|
|
|
+UA_Int32
|
|
|
+^^^^^^^^
|
|
|
+
|
|
|
+An integer value between -2,147,483,648 and 2,147,483,647.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef int32_t UA_Int32;
|
|
|
+
|
|
|
+UA_UInt32
|
|
|
+^^^^^^^^^
|
|
|
+
|
|
|
+An integer value between 0 and 4,294,967,295.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef uint32_t UA_UInt32;
|
|
|
+
|
|
|
+UA_Int64
|
|
|
+^^^^^^^^
|
|
|
+
|
|
|
+An integer value between -10,223,372,036,854,775,808 and 9,223,372,036,854,775,807.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef int64_t UA_Int64;
|
|
|
+
|
|
|
+UA_UInt64
|
|
|
+^^^^^^^^^
|
|
|
+
|
|
|
+An integer value between 0 and 18,446,744,073,709,551,615.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef uint64_t UA_UInt64;
|
|
|
+
|
|
|
+UA_Float
|
|
|
+^^^^^^^^
|
|
|
+
|
|
|
+An IEEE single precision (32 bit) floating point value.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef float UA_Float;
|
|
|
+
|
|
|
+UA_Double
|
|
|
+^^^^^^^^^
|
|
|
+
|
|
|
+An IEEE double precision (64 bit) floating point value.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef double UA_Double;
|
|
|
+
|
|
|
+UA_DateTime
|
|
|
+^^^^^^^^^^^
|
|
|
+
|
|
|
+An instance in time. A DateTime value is encoded as a 64-bit signed integer
|
|
|
+which represents the number of 100 nanosecond intervals since January 1, 1601
|
|
|
+(UTC).
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef UA_Int64 UA_DateTime;
|
|
|
+
|
|
|
+The following functions and definitions are used with UA_DateTime.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ UA_DateTime UA_DateTime_now(void);
|
|
|
+
|
|
|
+ typedef struct UA_DateTimeStruct {
|
|
|
+ UA_UInt16 nanoSec;
|
|
|
+ UA_UInt16 microSec;
|
|
|
+ UA_UInt16 milliSec;
|
|
|
+ UA_UInt16 sec;
|
|
|
+ UA_UInt16 min;
|
|
|
+ UA_UInt16 hour;
|
|
|
+ UA_UInt16 day;
|
|
|
+ UA_UInt16 month;
|
|
|
+ UA_UInt16 year;
|
|
|
+ } UA_DateTimeStruct;
|
|
|
+
|
|
|
+ UA_DateTimeStruct UA_EXPORT UA_DateTime_toStruct(UA_DateTime time);
|
|
|
+
|
|
|
+ UA_String UA_EXPORT UA_DateTime_toString(UA_DateTime time);
|
|
|
+
|
|
|
+UA_Guid
|
|
|
+^^^^^^^
|
|
|
+
|
|
|
+A 16 byte value that can be used as a globally unique identifier.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ UA_UInt32 data1;
|
|
|
+ UA_UInt16 data2;
|
|
|
+ UA_UInt16 data3;
|
|
|
+ UA_Byte data4[8];
|
|
|
+ } UA_Guid;
|
|
|
+
|
|
|
+The following functions and definitions are used with UA_Guid.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ UA_Boolean UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2);
|
|
|
+
|
|
|
+ UA_Guid UA_Guid_random(UA_UInt32 *seed);
|
|
|
+
|
|
|
+UA_String
|
|
|
+^^^^^^^^^
|
|
|
+
|
|
|
+A sequence of Unicode characters. See also the section :ref:`array-handling` for
|
|
|
+the usage of arrays in open62541.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ size_t length; // The length of the string
|
|
|
+ UA_Byte *data; // The string's content (not null-terminated)
|
|
|
+ } UA_String;
|
|
|
+
|
|
|
+The following functions and definitions are used with UA_String.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ extern const UA_String UA_STRING_NULL;
|
|
|
+
|
|
|
+ UA_String UA_STRING(char *chars);
|
|
|
+
|
|
|
+ #define UA_STRING_ALLOC(CHARS) UA_String_fromChars(CHARS)
|
|
|
+
|
|
|
+ /** Copies the content on the heap. Returns a null-string when alloc fails */
|
|
|
+ UA_String UA_String_fromChars(char const src[]);
|
|
|
+
|
|
|
+ UA_Boolean UA_String_equal(const UA_String *s1, const UA_String *s2);
|
|
|
+
|
|
|
+Here's a small example for the usage of UA_String.
|
|
|
|
|
|
.. code-block:: c
|
|
|
|
|
@@ -44,63 +233,445 @@ in more detail later on, but you should be able to follow the example already.
|
|
|
UA_String_delete(s3); /* Free the string buffer and the string itself */
|
|
|
UA_String_deleteMembers(&s4); /* Again, delete only the string buffer */
|
|
|
|
|
|
-The builtin data types
|
|
|
-----------------------
|
|
|
+UA_ByteString
|
|
|
+^^^^^^^^^^^^^
|
|
|
|
|
|
-OPC UA defines 25 builtin data types. All other data types are combinations of
|
|
|
-the 25 builtin data types.
|
|
|
+A sequence of octets.
|
|
|
|
|
|
-*TODO*
|
|
|
+.. code-block:: c
|
|
|
|
|
|
-Generic Data Type Handling
|
|
|
---------------------------
|
|
|
+ typedef UA_String UA_ByteString;
|
|
|
+
|
|
|
+UA_XmlEelement
|
|
|
+^^^^^^^^^^^^^^
|
|
|
|
|
|
-All standard-defined types are described with an ``UA_DataType`` structure.
|
|
|
+An XML element.
|
|
|
|
|
|
-.. doxygenstruct:: UA_DataType
|
|
|
- :members:
|
|
|
+.. code-block:: c
|
|
|
|
|
|
-.. c:var:: const UA_DataType UA_TYPES[UA_TYPES_COUNT]
|
|
|
+ typedef UA_String UA_XmlElement;
|
|
|
|
|
|
- The datatypes defined in the standard are stored in the ``UA_TYPES`` array.
|
|
|
- A typical function call is ``UA_Array_new(&data_ptr, 20, &UA_TYPES[UA_TYPES_STRING])``.
|
|
|
+UA_NodeId
|
|
|
+^^^^^^^^^
|
|
|
|
|
|
-.. doxygenfunction:: UA_new
|
|
|
-.. doxygenfunction:: UA_init
|
|
|
-.. doxygenfunction:: UA_copy
|
|
|
-.. doxygenfunction:: UA_deleteMembers
|
|
|
-.. doxygenfunction:: UA_delete
|
|
|
+An identifier for a node in the address space of an OPC UA Server.
|
|
|
|
|
|
-For all datatypes, there are also macros with syntactic sugar over calling the
|
|
|
-generic functions with a pointer into the ``UA_TYPES`` array.
|
|
|
+.. code-block:: c
|
|
|
|
|
|
-.. c:function:: <typename>_new()
|
|
|
+ enum UA_NodeIdType {
|
|
|
+ UA_NODEIDTYPE_NUMERIC = 0, // On the wire, this can be 0, 1 or 2 (shortened numeric nodeids)
|
|
|
+ UA_NODEIDTYPE_STRING = 3,
|
|
|
+ UA_NODEIDTYPE_GUID = 4,
|
|
|
+ UA_NODEIDTYPE_BYTESTRING = 5
|
|
|
+ };
|
|
|
|
|
|
- Allocates the memory for the type and runs _init on the returned variable.
|
|
|
- Returns null if no memory could be allocated.
|
|
|
+ typedef struct {
|
|
|
+ UA_UInt16 namespaceIndex;
|
|
|
+ enum UA_NodeIdType identifierType;
|
|
|
+ union {
|
|
|
+ UA_UInt32 numeric;
|
|
|
+ UA_String string;
|
|
|
+ UA_Guid guid;
|
|
|
+ UA_ByteString byteString;
|
|
|
+ } identifier;
|
|
|
+ } UA_NodeId;
|
|
|
|
|
|
-.. c:function:: <typename>_init(<typename> *value)
|
|
|
+The following functions and definitions are used with UA_NodeId.
|
|
|
|
|
|
- Sets all members of the type to a default value, usually zero. Arrays (e.g.
|
|
|
- for strings) are set to a length of -1.
|
|
|
+.. code-block:: c
|
|
|
|
|
|
-.. c:function:: <typename>_copy(<typename> *src, <typename> *dst)
|
|
|
+ UA_Boolean UA_NodeId_isNull(const UA_NodeId *p);
|
|
|
|
|
|
- Copies a datatype. This performs a deep copy iterating over the members.
|
|
|
- Copying into variants with an external data source is not permitted. If
|
|
|
- copying fails, a deleteMembers is performed and an error code returned.
|
|
|
+ UA_Boolean UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2);
|
|
|
|
|
|
-.. c:function:: <typename>_deleteMembers(<typename> *value)
|
|
|
+ extern const UA_NodeId UA_NODEID_NULL;
|
|
|
|
|
|
- Frees the memory of dynamically sized members of a datatype (e.g. arrays).
|
|
|
+ UA_NodeId UA_NODEID_NUMERIC(UA_UInt16 nsIndex, UA_Int32 identifier);
|
|
|
|
|
|
-.. c:function:: <typename>_delete(<typename> *value)
|
|
|
+ UA_NodeId UA_NODEID_STRING(UA_UInt16 nsIndex, char *chars) {
|
|
|
|
|
|
- Frees the memory of the datatype and its dynamically allocated members.
|
|
|
+ UA_NodeId UA_NODEID_STRING_ALLOC(UA_UInt16 nsIndex, const char *chars);
|
|
|
+
|
|
|
+ UA_NodeId UA_NODEID_GUID(UA_UInt16 nsIndex, UA_Guid guid);
|
|
|
+
|
|
|
+ UA_NodeId UA_NODEID_BYTESTRING(UA_UInt16 nsIndex, char *chars);
|
|
|
+
|
|
|
+ UA_NodeId UA_NODEID_BYTESTRING_ALLOC(UA_UInt16 nsIndex, const char *chars);
|
|
|
+
|
|
|
+UA_ExpandedNodeId
|
|
|
+^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+A NodeId that allows the namespace URI to be specified instead of an index.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ UA_NodeId nodeId;
|
|
|
+ UA_String namespaceUri;
|
|
|
+ UA_UInt32 serverIndex;
|
|
|
+ } UA_ExpandedNodeId;
|
|
|
+
|
|
|
+The following functions and definitions are used with UA_ExpandedNodeId.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ UA_ExpandedNodeId UA_EXPANDEDNODEID_NUMERIC(UA_UInt16 nsIndex, UA_Int32 identifier);
|
|
|
+
|
|
|
+ UA_ExpandedNodeId UA_EXPANDEDNODEID_STRING(UA_UInt16 nsIndex, char *chars);
|
|
|
+
|
|
|
+ UA_ExpandedNodeId UA_EXPANDEDNODEID_STRING_ALLOC(UA_UInt16 nsIndex, const char *chars);
|
|
|
+
|
|
|
+ UA_ExpandedNodeId UA_EXPANDEDNODEID_STRING_GUID(UA_UInt16 nsIndex, UA_Guid guid);
|
|
|
+
|
|
|
+ UA_ExpandedNodeId UA_EXPANDEDNODEID_BYTESTRING(UA_UInt16 nsIndex, char *chars);
|
|
|
+
|
|
|
+ UA_ExpandedNodeId UA_EXPANDEDNODEID_BYTESTRING_ALLOC(UA_UInt16 nsIndex, const char *chars);
|
|
|
+
|
|
|
+UA_QualifiedName
|
|
|
+^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+A name qualified by a namespace.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ UA_UInt16 namespaceIndex;
|
|
|
+ UA_String name;
|
|
|
+ } UA_QualifiedName;
|
|
|
+
|
|
|
+The following functions and definitions are used with UA_QualifiedName.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ UA_QualifiedName UA_QUALIFIEDNAME(UA_UInt16 nsIndex, char *chars);
|
|
|
+
|
|
|
+ UA_QualifiedName UA_QUALIFIEDNAME_ALLOC(UA_UInt16 nsIndex, const char *chars);
|
|
|
+
|
|
|
+UA_LocalizedText
|
|
|
+^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+Human readable text with an optional locale identifier.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ UA_String locale;
|
|
|
+ UA_String text;
|
|
|
+ } UA_LocalizedText;
|
|
|
+
|
|
|
+The following functions and definitions are used with UA_LocalizedText.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ UA_LocalizedText UA_LOCALIZEDTEXT(char *locale, char *text);
|
|
|
+
|
|
|
+ UA_LocalizedText UA_LOCALIZEDTEXT_ALLOC(const char *locale, const char *text);
|
|
|
+
|
|
|
+UA_ExtensionObject
|
|
|
+^^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+A structure that contains an application specific data type that may not be
|
|
|
+recognized by the receiver.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ enum {
|
|
|
+ UA_EXTENSIONOBJECT_ENCODED_NOBODY = 0,
|
|
|
+ UA_EXTENSIONOBJECT_ENCODED_BYTESTRING = 1,
|
|
|
+ UA_EXTENSIONOBJECT_ENCODED_XML = 2,
|
|
|
+ UA_EXTENSIONOBJECT_DECODED = 3, ///< There is a pointer to the decoded data
|
|
|
+ UA_EXTENSIONOBJECT_DECODED_NODELETE = 4 ///< Don't delete the decoded data at the lifecycle end
|
|
|
+ } encoding;
|
|
|
+ union {
|
|
|
+ struct {
|
|
|
+ UA_NodeId typeId; ///< The nodeid of the datatype
|
|
|
+ UA_ByteString body; ///< The bytestring of the encoded data
|
|
|
+ } encoded;
|
|
|
+ struct {
|
|
|
+ const UA_DataType *type;
|
|
|
+ void *data;
|
|
|
+ } decoded;
|
|
|
+ } content;
|
|
|
+ } UA_ExtensionObject;
|
|
|
+
|
|
|
+UA_Variant
|
|
|
+^^^^^^^^^^
|
|
|
+
|
|
|
+Stores (arrays of) any data type. Please see section :ref:`generic-handling` for
|
|
|
+the usage of UA_DataType. The semantics of the arrayLength field is explained in
|
|
|
+section :ref:`array-handling`.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ const UA_DataType *type; // The data type description
|
|
|
+ enum {
|
|
|
+ UA_VARIANT_DATA, /* The data has the same lifecycle as the variant */
|
|
|
+ UA_VARIANT_DATA_NODELETE, /* The data is "borrowed" by the variant and shall not be
|
|
|
+ deleted at the end of the variant's lifecycle. */
|
|
|
+ } storageType;
|
|
|
+ size_t arrayLength; // The number of elements in the data array
|
|
|
+ void *data; // Points to the scalar or array data
|
|
|
+ size_t arrayDimensionsSize; // The number of dimensions the data-array has
|
|
|
+ UA_UInt32 *arrayDimensions; // The length of each dimension of the data-array
|
|
|
+ } UA_Variant;
|
|
|
+
|
|
|
+ /* NumericRanges are used to indicate subsets of a (multidimensional) variant
|
|
|
+ * array. NumericRange has no official type structure in the standard. On the
|
|
|
+ * wire, it only exists as an encoded string, such as "1:2,0:3,5". The colon
|
|
|
+ * separates min/max index and the comma separates dimensions. A single value
|
|
|
+ * indicates a range with a single element (min==max). */
|
|
|
+ typedef struct {
|
|
|
+ size_t dimensionsSize;
|
|
|
+ struct UA_NumericRangeDimension {
|
|
|
+ UA_UInt32 min;
|
|
|
+ UA_UInt32 max;
|
|
|
+ } *dimensions;
|
|
|
+ } UA_NumericRange;
|
|
|
+
|
|
|
+
|
|
|
+The following functions and definitions are used with UA_Variant.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns true if the variant contains a scalar value. Note that empty
|
|
|
+ * variants contain an array of length -1 (undefined).
|
|
|
+ *
|
|
|
+ * @param v The variant
|
|
|
+ * @return Does the variant contain a scalar value.
|
|
|
+ */
|
|
|
+ UA_Boolean UA_Variant_isScalar(const UA_Variant *v);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set the variant to a scalar value that already resides in memory. The value
|
|
|
+ * takes on the lifecycle of the variant and is deleted with it.
|
|
|
+ *
|
|
|
+ * @param v The variant
|
|
|
+ * @param p A pointer to the value data
|
|
|
+ * @param type The datatype of the value in question
|
|
|
+ */
|
|
|
+ UA_Variant_setScalar(UA_Variant *v, void * UA_RESTRICT p, const UA_DataType *type);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set the variant to a scalar value that is copied from an existing variable.
|
|
|
+ *
|
|
|
+ * @param v The variant
|
|
|
+ * @param p A pointer to the value data
|
|
|
+ * @param type The datatype of the value
|
|
|
+ * @return Indicates whether the operation succeeded or returns an error code
|
|
|
+ */
|
|
|
+ UA_StatusCode UA_Variant_setScalarCopy(UA_Variant *v, const void *p, const UA_DataType *type);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set the variant to an array that already resides in memory. The array takes
|
|
|
+ * on the lifecycle of the variant and is deleted with it.
|
|
|
+ *
|
|
|
+ * @param v The variant
|
|
|
+ * @param array A pointer to the array data
|
|
|
+ * @param arraySize The size of the array
|
|
|
+ * @param type The datatype of the array
|
|
|
+ */
|
|
|
+ void UA_Variant_setArray(UA_Variant *v, void * UA_RESTRICT array,
|
|
|
+ size_t arraySize, const UA_DataType *type);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set the variant to an array that is copied from an existing array.
|
|
|
+ *
|
|
|
+ * @param v The variant
|
|
|
+ * @param array A pointer to the array data
|
|
|
+ * @param arraySize The size of the array
|
|
|
+ * @param type The datatype of the array
|
|
|
+ * @return Indicates whether the operation succeeded or returns an error code
|
|
|
+ */
|
|
|
+ UA_StatusCode UA_Variant_setArrayCopy(UA_Variant *v, const void *array,
|
|
|
+ size_t arraySize, const UA_DataType *type);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Copy the variant, but use only a subset of the (multidimensional) array
|
|
|
+ * into a variant. Returns an error code if the variant is not an array or if
|
|
|
+ * the indicated range does not fit.
|
|
|
+ *
|
|
|
+ * @param src The source variant
|
|
|
+ * @param dst The target variant
|
|
|
+ * @param range The range of the copied data
|
|
|
+ * @return Returns UA_STATUSCODE_GOOD or an error code
|
|
|
+ */
|
|
|
+ UA_StatusCode UA_Variant_copyRange(const UA_Variant *src, UA_Variant *dst,
|
|
|
+ const UA_NumericRange range);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Insert a range of data into an existing variant. The data array can't be
|
|
|
+ * reused afterwards if it contains types without a fixed size (e.g. strings)
|
|
|
+ * since the members are moved into the variant and take on its lifecycle.
|
|
|
+ *
|
|
|
+ * @param v The variant
|
|
|
+ * @param dataArray The data array. The type must match the variant
|
|
|
+ * @param dataArraySize The length of the data array. This is checked to match the range size.
|
|
|
+ * @param range The range of where the new data is inserted
|
|
|
+ * @return Returns UA_STATUSCODE_GOOD or an error code
|
|
|
+ */
|
|
|
+ UA_StatusCode UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array,
|
|
|
+ size_t arraySize, const UA_NumericRange range);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Deep-copy a range of data into an existing variant.
|
|
|
+ *
|
|
|
+ * @param v The variant
|
|
|
+ * @param dataArray The data array. The type must match the variant
|
|
|
+ * @param dataArraySize The length of the data array. This is checked to match the range size.
|
|
|
+ * @param range The range of where the new data is inserted
|
|
|
+ * @return Returns UA_STATUSCODE_GOOD or an error code
|
|
|
+ */
|
|
|
+ UA_StatusCode UA_Variant_setRangeCopy(UA_Variant *v, const void *array,
|
|
|
+ size_t arraySize, const UA_NumericRange range);
|
|
|
+
|
|
|
+UA_DataValue
|
|
|
+^^^^^^^^^^^^
|
|
|
+
|
|
|
+A data value with an associated status code and timestamps.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ UA_Boolean hasValue : 1;
|
|
|
+ UA_Boolean hasStatus : 1;
|
|
|
+ UA_Boolean hasSourceTimestamp : 1;
|
|
|
+ UA_Boolean hasServerTimestamp : 1;
|
|
|
+ UA_Boolean hasSourcePicoseconds : 1;
|
|
|
+ UA_Boolean hasServerPicoseconds : 1;
|
|
|
+ UA_Variant value;
|
|
|
+ UA_StatusCode status;
|
|
|
+ UA_DateTime sourceTimestamp;
|
|
|
+ UA_Int16 sourcePicoseconds;
|
|
|
+ UA_DateTime serverTimestamp;
|
|
|
+ UA_Int16 serverPicoseconds;
|
|
|
+ } UA_DataValue;
|
|
|
+
|
|
|
+UA_DiagnosticInfo
|
|
|
+^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+A structure that contains detailed error and diagnostic information associated
|
|
|
+with a StatusCode.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct UA_DiagnosticInfo {
|
|
|
+ UA_Boolean hasSymbolicId : 1;
|
|
|
+ UA_Boolean hasNamespaceUri : 1;
|
|
|
+ UA_Boolean hasLocalizedText : 1;
|
|
|
+ UA_Boolean hasLocale : 1;
|
|
|
+ UA_Boolean hasAdditionalInfo : 1;
|
|
|
+ UA_Boolean hasInnerStatusCode : 1;
|
|
|
+ UA_Boolean hasInnerDiagnosticInfo : 1;
|
|
|
+ UA_Int32 symbolicId;
|
|
|
+ UA_Int32 namespaceUri;
|
|
|
+ UA_Int32 localizedText;
|
|
|
+ UA_Int32 locale;
|
|
|
+ UA_String additionalInfo;
|
|
|
+ UA_StatusCode innerStatusCode;
|
|
|
+ struct UA_DiagnosticInfo *innerDiagnosticInfo;
|
|
|
+ } UA_DiagnosticInfo;
|
|
|
+
|
|
|
+.. _generic-handling:
|
|
|
+
|
|
|
+Generic Data Type Handling
|
|
|
+--------------------------
|
|
|
+
|
|
|
+All standard-defined data types are described with an ``UA_DataType`` structure.
|
|
|
+In addition to the 25 builtin data types, OPC UA defines many more. But they are
|
|
|
+mere combinations of the builtin data types. We handle all types in a unified
|
|
|
+way by storing their internal structure. So it is not necessary to define
|
|
|
+specialized functions for all additional types.
|
|
|
+
|
|
|
+The ``UA_TYPES`` array contains the description of every standard-defined data
|
|
|
+type.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ extern const UA_DataType UA_TYPES[UA_TYPES_COUNT];
|
|
|
+
|
|
|
+The following is an excerpt from ``ua_types_generated.h`` with the definition of
|
|
|
+OPC UA read requests. This file is auto-generated from the XML-description of
|
|
|
+the OPC UA data types that is part of the ISO/IEC 62541 standard.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ typedef struct {
|
|
|
+ UA_RequestHeader requestHeader;
|
|
|
+ UA_Double maxAge;
|
|
|
+ UA_TimestampsToReturn timestampsToReturn;
|
|
|
+ size_t nodesToReadSize;
|
|
|
+ UA_ReadValueId *nodesToRead;
|
|
|
+ } UA_ReadRequest;
|
|
|
+
|
|
|
+ #define UA_TYPES_READREQUEST 118
|
|
|
+
|
|
|
+ static UA_INLINE void UA_ReadRequest_init(UA_ReadRequest *p) {
|
|
|
+ memset(p, 0, sizeof(UA_ReadRequest)); }
|
|
|
+
|
|
|
+ static UA_INLINE void UA_ReadRequest_delete(UA_ReadRequest *p) {
|
|
|
+ UA_delete(p, &UA_TYPES[UA_TYPES_READREQUEST]); }
|
|
|
+
|
|
|
+ static UA_INLINE void UA_ReadRequest_deleteMembers(UA_ReadRequest *p) {
|
|
|
+ UA_deleteMembers(p, &UA_TYPES[UA_TYPES_READREQUEST]); }
|
|
|
+
|
|
|
+ static UA_INLINE UA_ReadRequest * UA_ReadRequest_new(void) {
|
|
|
+ return (UA_ReadRequest*) UA_new(&UA_TYPES[UA_TYPES_READREQUEST]); }
|
|
|
+
|
|
|
+ static UA_INLINE UA_StatusCode
|
|
|
+ UA_ReadRequest_copy(const UA_ReadRequest *src, UA_ReadRequest *dst) {
|
|
|
+ return UA_copy(src, dst, &UA_TYPES[UA_TYPES_READREQUEST]); }
|
|
|
+
|
|
|
+.. _array-handling:
|
|
|
|
|
|
Array Handling
|
|
|
--------------
|
|
|
-
|
|
|
-.. doxygenfunction:: UA_Array_new
|
|
|
-.. doxygenfunction:: UA_Array_copy
|
|
|
-.. doxygenfunction:: UA_Array_delete
|
|
|
+
|
|
|
+In OPC UA, all arrays can be undefined, have length 0 or a positive length. In
|
|
|
+data structures, all arrays are represented by a ``size_t`` length field and an
|
|
|
+appropriate pointer directly afterwards. In order to distinguish between
|
|
|
+undefined and length-zero arrays, we define the following.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ #define UA_EMPTY_ARRAY_SENTINEL ((void*)0x01)
|
|
|
+
|
|
|
+- size == 0 and data == NULL: The array is undefined
|
|
|
+- size == 0 and data == ``UA_EMPTY_ARRAY_SENTINEL``: The array has length 0
|
|
|
+- size > 0: The array at the given memory address has the given size
|
|
|
+
|
|
|
+The following functions are defined for array handling.
|
|
|
+
|
|
|
+.. code-block:: c
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Allocates and initializes an array of variables of a specific type
|
|
|
+ *
|
|
|
+ * @param size The requested array length
|
|
|
+ * @param type The datatype description
|
|
|
+ * @return Returns the memory location of the variable or (void*)0 if no memory could be allocated
|
|
|
+ */
|
|
|
+ void * UA_Array_new(size_t size, const UA_DataType *type);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Allocates and copies an array. dst is set to (void*)0 if not enough memory is available.
|
|
|
+ *
|
|
|
+ * @param src The memory location of the source array
|
|
|
+ * @param src_size The size of the array
|
|
|
+ * @param dst The location of the pointer to the new array
|
|
|
+ * @param type The datatype of the array members
|
|
|
+ * @return Returns whether copying succeeded
|
|
|
+ */
|
|
|
+ UA_StatusCode UA_Array_copy(const void *src, size_t src_size, void **dst,
|
|
|
+ const UA_DataType *type);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Deletes an array.
|
|
|
+ *
|
|
|
+ * @param p The memory location of the array
|
|
|
+ * @param size The size of the array
|
|
|
+ * @param type The datatype of the array members
|
|
|
+ */
|
|
|
+ void UA_Array_delete(void *p, size_t size, const UA_DataType *type);
|