123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- /* 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/. */
- #ifndef UA_SERVER_NODES_H_
- #define UA_SERVER_NODES_H_
- /* !!! Warning !!!
- *
- * If you are not developing a nodestore plugin, then you should not work with
- * the definitions from this file directly. The underlying node structures are
- * not meant to be used directly by end users. Please use the public server API
- * / OPC UA services to interact with the information model. */
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include "ua_server.h"
- /**
- * .. _information-modelling:
- *
- * Information Modelling
- * =====================
- *
- * Information modelling in OPC UA combines concepts from object-orientation and
- * semantic modelling. At the core, an OPC UA information model is a graph made
- * up of
- *
- * - Nodes: There are eight possible Node types (variable, object, method, ...)
- * - References: Typed and directed relations between two nodes
- *
- * Every node is identified by a unique (within the server) :ref:`nodeid`.
- * Reference are triples of the form ``(source-nodeid, referencetype-nodeid,
- * target-nodeid)``. An example reference between nodes is a
- * ``hasTypeDefinition`` reference between a Variable and its VariableType. Some
- * ReferenceTypes are *hierarchic* and must not form *directed loops*. See the
- * section on :ref:`ReferenceTypes <referencetypenode>` for more details on
- * possible references and their semantics.
- *
- * **Warning!!** The structures defined in this section are only relevant for
- * the developers of custom Nodestores. The interaction with the information
- * model is possible only via the OPC UA :ref:`services`. So the following
- * sections are purely informational so that users may have a clear mental
- * model of the underlying representation.
- *
- * Base Node Attributes
- * --------------------
- *
- * Nodes contain attributes according to their node type. The base node
- * attributes are common to all node types. In the OPC UA :ref:`services`,
- * attributes are referred to via the :ref:`nodeid` of the containing node and
- * an integer :ref:`attribute-id`.
- *
- * Internally, open62541 uses ``UA_Node`` in places where the exact node type is
- * not known or not important. The ``nodeClass`` attribute is used to ensure the
- * correctness of casting from ``UA_Node`` to a specific node type. */
- /* List of reference targets with the same reference type and direction */
- typedef struct {
- UA_NodeId referenceTypeId;
- UA_Boolean isInverse;
- size_t targetIdsSize;
- UA_ExpandedNodeId *targetIds;
- } UA_NodeReferenceKind;
- #define UA_NODE_BASEATTRIBUTES \
- UA_NodeId nodeId; \
- UA_NodeClass nodeClass; \
- UA_QualifiedName browseName; \
- UA_LocalizedText displayName; \
- UA_LocalizedText description; \
- UA_UInt32 writeMask; \
- size_t referencesSize; \
- UA_NodeReferenceKind *references; \
- \
- /* Members specific to open62541 */ \
- void *context;
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- } UA_Node;
- /**
- * VariableNode
- * ------------
- *
- * Variables store values in a :ref:`datavalue` together with
- * metadata for introspection. Most notably, the attributes data type, value
- * rank and array dimensions constrain the possible values the variable can take
- * on.
- *
- * Variables come in two flavours: properties and datavariables. Properties are
- * related to a parent with a ``hasProperty`` reference and may not have child
- * nodes themselves. Datavariables may contain properties (``hasProperty``) and
- * also datavariables (``hasComponents``).
- *
- * All variables are instances of some :ref:`variabletypenode` in return
- * constraining the possible data type, value rank and array dimensions
- * attributes.
- *
- * Data Type
- * ^^^^^^^^^
- *
- * The (scalar) data type of the variable is constrained to be of a specific
- * type or one of its children in the type hierarchy. The data type is given as
- * a NodeId pointing to a :ref:`datatypenode` in the type hierarchy. See the
- * Section :ref:`datatypenode` for more details.
- *
- * If the data type attribute points to ``UInt32``, then the value attribute
- * must be of that exact type since ``UInt32`` does not have children in the
- * type hierarchy. If the data type attribute points ``Number``, then the type
- * of the value attribute may still be ``UInt32``, but also ``Float`` or
- * ``Byte``.
- *
- * Consistency between the data type attribute in the variable and its
- * :ref:`VariableTypeNode` is ensured.
- *
- * Value Rank
- * ^^^^^^^^^^
- *
- * This attribute indicates whether the value attribute of the variable is an
- * array and how many dimensions the array has. It may have the following
- * values:
- *
- * - ``n >= 1``: the value is an array with the specified number of dimensions
- * - ``n = 0``: the value is an array with one or more dimensions
- * - ``n = -1``: the value is a scalar
- * - ``n = -2``: the value can be a scalar or an array with any number of dimensions
- * - ``n = -3``: the value can be a scalar or a one dimensional array
- *
- * Consistency between the value rank attribute in the variable and its
- * :ref:`variabletypenode` is ensured.
- *
- * Array Dimensions
- * ^^^^^^^^^^^^^^^^
- *
- * If the value rank permits the value to be a (multi-dimensional) array, the
- * exact length in each dimensions can be further constrained with this
- * attribute.
- *
- * - For positive lengths, the variable value is guaranteed to be of the same
- * length in this dimension.
- * - The dimension length zero is a wildcard and the actual value may have any
- * length in this dimension.
- *
- * Consistency between the array dimensions attribute in the variable and its
- * :ref:`variabletypenode` is ensured. */
- /* Indicates whether a variable contains data inline or whether it points to an
- * external data source */
- typedef enum {
- UA_VALUESOURCE_DATA,
- UA_VALUESOURCE_DATASOURCE
- } UA_ValueSource;
- #define UA_NODE_VARIABLEATTRIBUTES \
- /* Constraints on possible values */ \
- UA_NodeId dataType; \
- UA_Int32 valueRank; \
- size_t arrayDimensionsSize; \
- UA_UInt32 *arrayDimensions; \
- \
- /* The current value */ \
- UA_ValueSource valueSource; \
- union { \
- struct { \
- UA_DataValue value; \
- UA_ValueCallback callback; \
- } data; \
- UA_DataSource dataSource; \
- } value;
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- UA_NODE_VARIABLEATTRIBUTES
- UA_Byte accessLevel;
- UA_Double minimumSamplingInterval;
- UA_Boolean historizing; /* currently unsupported */
- } UA_VariableNode;
- /**
- * .. _variabletypenode:
- *
- * VariableTypeNode
- * ----------------
- *
- * VariableTypes are used to provide type definitions for variables.
- * VariableTypes constrain the data type, value rank and array dimensions
- * attributes of variable instances. Furthermore, instantiating from a specific
- * variable type may provide semantic information. For example, an instance from
- * ``MotorTemperatureVariableType`` is more meaningful than a float variable
- * instantiated from ``BaseDataVariable``. */
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- UA_NODE_VARIABLEATTRIBUTES
- UA_Boolean isAbstract;
- /* Members specific to open62541 */
- UA_NodeTypeLifecycle lifecycle;
- } UA_VariableTypeNode;
- /**
- * .. _methodnode:
- *
- * MethodNode
- * ----------
- *
- * Methods define callable functions and are invoked using the :ref:`Call
- * <method-services>` service. MethodNodes may have special properties (variable
- * childen with a ``hasProperty`` reference) with the :ref:`qualifiedname` ``(0,
- * "InputArguments")`` and ``(0, "OutputArguments")``. The input and output
- * arguments are both described via an array of ``UA_Argument``. While the Call
- * service uses a generic array of :ref:`variant` for input and output, the
- * actual argument values are checked to match the signature of the MethodNode.
- *
- * Note that the same MethodNode may be referenced from several objects (and
- * object types). For this, the NodeId of the method *and of the object
- * providing context* is part of a Call request message. */
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- UA_Boolean executable;
- /* Members specific to open62541 */
- UA_MethodCallback method;
- } UA_MethodNode;
- /**
- * ObjectNode
- * ----------
- *
- * Objects are used to represent systems, system components, real-world objects
- * and software objects. Objects are instances of an :ref:`object
- * type<objecttypenode>` and may contain variables, methods and further
- * objects. */
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- UA_Byte eventNotifier;
- } UA_ObjectNode;
- /**
- * .. _objecttypenode:
- *
- * ObjectTypeNode
- * --------------
- *
- * ObjectTypes provide definitions for Objects. Abstract objects cannot be
- * instantiated. See :ref:`node-lifecycle` for the use of constructor and
- * destructor callbacks. */
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- UA_Boolean isAbstract;
- /* Members specific to open62541 */
- UA_NodeTypeLifecycle lifecycle;
- } UA_ObjectTypeNode;
- /**
- * .. _referencetypenode:
- *
- * ReferenceTypeNode
- * -----------------
- *
- * Each reference between two nodes is typed with a ReferenceType that gives
- * meaning to the relation. The OPC UA standard defines a set of ReferenceTypes
- * as a mandatory part of OPC UA information models.
- *
- * - Abstract ReferenceTypes cannot be used in actual references and are only
- * used to structure the ReferenceTypes hierarchy
- * - Symmetric references have the same meaning from the perspective of the
- * source and target node
- *
- * The figure below shows the hierarchy of the standard ReferenceTypes (arrows
- * indicate a ``hasSubType`` relation). Refer to Part 3 of the OPC UA
- * specification for the full semantics of each ReferenceType.
- *
- * .. graphviz::
- *
- * digraph tree {
- *
- * node [height=0, shape=box, fillcolor="#E5E5E5", concentrate=true]
- *
- * references [label="References\n(Abstract, Symmetric)"]
- * hierarchical_references [label="HierarchicalReferences\n(Abstract)"]
- * references -> hierarchical_references
- *
- * nonhierarchical_references [label="NonHierarchicalReferences\n(Abstract, Symmetric)"]
- * references -> nonhierarchical_references
- *
- * haschild [label="HasChild\n(Abstract)"]
- * hierarchical_references -> haschild
- *
- * aggregates [label="Aggregates\n(Abstract)"]
- * haschild -> aggregates
- *
- * organizes [label="Organizes"]
- * hierarchical_references -> organizes
- *
- * hascomponent [label="HasComponent"]
- * aggregates -> hascomponent
- *
- * hasorderedcomponent [label="HasOrderedComponent"]
- * hascomponent -> hasorderedcomponent
- *
- * hasproperty [label="HasProperty"]
- * aggregates -> hasproperty
- *
- * hassubtype [label="HasSubtype"]
- * haschild -> hassubtype
- *
- * hasmodellingrule [label="HasModellingRule"]
- * nonhierarchical_references -> hasmodellingrule
- *
- * hastypedefinition [label="HasTypeDefinition"]
- * nonhierarchical_references -> hastypedefinition
- *
- * hasencoding [label="HasEncoding"]
- * nonhierarchical_references -> hasencoding
- *
- * hasdescription [label="HasDescription"]
- * nonhierarchical_references -> hasdescription
- *
- * haseventsource [label="HasEventSource"]
- * hierarchical_references -> haseventsource
- *
- * hasnotifier [label="HasNotifier"]
- * hierarchical_references -> hasnotifier
- *
- * generatesevent [label="GeneratesEvent"]
- * nonhierarchical_references -> generatesevent
- *
- * alwaysgeneratesevent [label="AlwaysGeneratesEvent"]
- * generatesevent -> alwaysgeneratesevent
- *
- * {rank=same hierarchical_references nonhierarchical_references}
- * {rank=same generatesevent haseventsource hasmodellingrule
- * hasencoding hassubtype}
- * {rank=same alwaysgeneratesevent hasproperty}
- *
- * }
- *
- * The ReferenceType hierarchy can be extended with user-defined ReferenceTypes.
- * Many Companion Specifications for OPC UA define new ReferenceTypes to be used
- * in their domain of interest.
- *
- * For the following example of custom ReferenceTypes, we attempt to model the
- * structure of a technical system. For this, we introduce two custom
- * ReferenceTypes. First, the hierarchical ``contains`` ReferenceType indicates
- * that a system (represented by an OPC UA object) contains a component (or
- * subsystem). This gives rise to a tree-structure of containment relations. For
- * example, the motor (object) is contained in the car and the crankshaft is
- * contained in the motor. Second, the symmetric ``connectedTo`` ReferenceType
- * indicates that two components are connected. For example, the motor's
- * crankshaft is connected to the gear box. Connections are independent of the
- * containment hierarchy and can induce a general graph-structure. Further
- * subtypes of ``connectedTo`` could be used to differentiate between physical,
- * electrical and information related connections. A client can then learn the
- * layout of a (physical) system represented in an OPC UA information model
- * based on a common understanding of just two custom reference types. */
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- UA_Boolean isAbstract;
- UA_Boolean symmetric;
- UA_LocalizedText inverseName;
- } UA_ReferenceTypeNode;
- /**
- * .. _datatypenode:
- *
- * DataTypeNode
- * ------------
- *
- * DataTypes represent simple and structured data types. DataTypes may contain
- * arrays. But they always describe the structure of a single instance. In
- * open62541, DataTypeNodes in the information model hierarchy are matched to
- * ``UA_DataType`` type descriptions for :ref:`generic-types` via their NodeId.
- *
- * Abstract DataTypes (e.g. ``Number``) cannot be the type of actual values.
- * They are used to constrain values to possible child DataTypes (e.g.
- * ``UInt32``). */
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- UA_Boolean isAbstract;
- } UA_DataTypeNode;
- /**
- * ViewNode
- * --------
- *
- * Each View defines a subset of the Nodes in the AddressSpace. Views can be
- * used when browsing an information model to focus on a subset of nodes and
- * references only. ViewNodes can be created and be interacted with. But their
- * use in the :ref:`Browse<view-services>` service is currently unsupported in
- * open62541. */
- typedef struct {
- UA_NODE_BASEATTRIBUTES
- UA_Byte eventNotifier;
- UA_Boolean containsNoLoops;
- } UA_ViewNode;
- /**
- * Nodestore Plugin API
- * --------------------
- * The following definitions are used for implementing custom node storage
- * backends. **Most users will want to use the default nodestore and don't need
- * to work with the nodestore API**.
- *
- * Outside of custom nodestore implementations, users should not manually edit
- * nodes. Please use the OPC UA services for that. Otherwise, all consistency
- * checks are omitted. This can crash the application eventually. */
- typedef void (*UA_NodestoreVisitor)(void *visitorContext, const UA_Node *node);
- typedef struct {
- /* Nodestore context and lifecycle */
- void *context;
- void (*deleteNodestore)(void *nodestoreContext);
- /* For non-multithreaded access, some nodestores allow that nodes are edited
- * without a copy/replace. This is not possible when the node is only an
- * intermediate representation and stored e.g. in a database backend. */
- UA_Boolean inPlaceEditAllowed;
- /* The following definitions are used to create empty nodes of the different
- * node types. The memory is managed by the nodestore. Therefore, the node
- * has to be removed via a special deleteNode function. (If the new node is
- * not added to the nodestore.) */
- UA_Node * (*newNode)(void *nodestoreContext, UA_NodeClass nodeClass);
- void (*deleteNode)(void *nodestoreContext, UA_Node *node);
- /* ``Get`` returns a pointer to an immutable node. ``Release`` indicates
- * that the pointer is no longer accessed afterwards. */
- const UA_Node * (*getNode)(void *nodestoreContext, const UA_NodeId *nodeId);
- void (*releaseNode)(void *nodestoreContext, const UA_Node *node);
- /* Returns an editable copy of a node (needs to be deleted with the
- * deleteNode function or inserted / replaced into the nodestore). */
- UA_StatusCode (*getNodeCopy)(void *nodestoreContext, const UA_NodeId *nodeId,
- UA_Node **outNode);
- /* Inserts a new node into the nodestore. If the NodeId is zero, then a
- * fresh numeric NodeId is assigned. If insertion fails, the node is
- * deleted. */
- UA_StatusCode (*insertNode)(void *nodestoreContext, UA_Node *node,
- UA_NodeId *addedNodeId);
- /* To replace a node, get an editable copy of the node, edit and replace
- * with this function. If the node was already replaced since the copy was
- * made, UA_STATUSCODE_BADINTERNALERROR is returned. If the NodeId is not
- * found, UA_STATUSCODE_BADNODEIDUNKNOWN is returned. In both error cases,
- * the editable node is deleted. */
- UA_StatusCode (*replaceNode)(void *nodestoreContext, UA_Node *node);
- /* Removes a node from the nodestore. */
- UA_StatusCode (*removeNode)(void *nodestoreContext, const UA_NodeId *nodeId);
- /* Execute a callback for every node in the nodestore. */
- void (*iterate)(void *nodestoreContext, void* visitorContext,
- UA_NodestoreVisitor visitor);
- } UA_Nodestore;
- /**
- * The following methods specialize internally for the different node classes
- * (distinguished by the nodeClass member) */
- /* Attributes must be of a matching type (VariableAttributes, ObjectAttributes,
- * and so on). The attributes are copied. Note that the attributes structs do
- * not contain NodeId, NodeClass and BrowseName. The NodeClass of the node needs
- * to be correctly set before calling this method. UA_Node_deleteMembers is
- * called on the node when an error occurs internally. */
- UA_StatusCode UA_EXPORT
- UA_Node_setAttributes(UA_Node *node, const void *attributes,
- const UA_DataType *attributeType);
- /* Reset the destination node and copy the content of the source */
- UA_StatusCode UA_EXPORT
- UA_Node_copy(const UA_Node *src, UA_Node *dst);
- /* Allocate new node and copy the values from src */
- UA_EXPORT UA_Node *
- UA_Node_copy_alloc(const UA_Node *src);
- /* Add a single reference to the node */
- UA_StatusCode UA_EXPORT
- UA_Node_addReference(UA_Node *node, const UA_AddReferencesItem *item);
- /* Delete a single reference from the node */
- UA_StatusCode UA_EXPORT
- UA_Node_deleteReference(UA_Node *node, const UA_DeleteReferencesItem *item);
- /* Delete all references of the node */
- void UA_EXPORT
- UA_Node_deleteReferences(UA_Node *node);
- /* Remove all malloc'ed members of the node */
- void UA_EXPORT
- UA_Node_deleteMembers(UA_Node *node);
- #ifdef __cplusplus
- } // extern "C"
- #endif
- #endif /* UA_SERVER_NODES_H_ */
|