Browse Source

Merge pull request #1197 from open62541/feature/custom_types

Create examples for custom datatypes
Stefan Profanter 6 years ago
parent
commit
de446d6d4a

+ 3 - 0
examples/CMakeLists.txt

@@ -70,6 +70,9 @@ add_example(server_repeated_job server_repeated_job.c)
 
 add_example(server_inheritance server_inheritance.c)
 
+add_example(custom_datatype_client custom_datatype/client_types_custom.c)
+add_example(custom_datatype_server custom_datatype/server_types_custom.c)
+
 if(UA_BUILD_EXAMPLES_NODESET_COMPILER)
   if(BUILD_SHARED_LIBS)
     message(FATAL_ERROR "The nodeset compiler currently requires static linking to access internal API")

+ 41 - 0
examples/custom_datatype/client_types_custom.c

@@ -0,0 +1,41 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
+
+#include <stdio.h>
+#include "open62541.h"
+#include "custom_datatype.h"
+
+int main(void) {
+	UA_ClientConfig config = UA_ClientConfig_default;
+
+    /* Make your custom datatype known to the stack */
+    UA_DataType types[1];
+    types[0] = PointType;
+    config.customDataTypes = types;
+    config.customDataTypesSize = 1;
+
+	UA_Client *client = UA_Client_new(config);
+	UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
+	if (retval != UA_STATUSCODE_GOOD) {
+		UA_Client_delete(client);
+		return (int)retval;
+	}
+	
+	UA_Variant value; /* Variants can hold scalar values and arrays of any type */
+	UA_Variant_init(&value);
+	
+	 UA_NodeId nodeId =
+		UA_NODEID_STRING(1, "3D.Point");
+
+	retval = UA_Client_readValueAttribute(client, nodeId, &value);
+			
+	if (retval == UA_STATUSCODE_GOOD) {
+		Point *p = (Point *)value.data;
+		printf("Point = %f, %f, %f \n", p->x, p->y, p->z);
+	}
+
+	/* Clean up */
+	UA_Variant_deleteMembers(&value);
+	UA_Client_delete(client); /* Disconnects the client internally */
+	return UA_STATUSCODE_GOOD;
+}

+ 51 - 0
examples/custom_datatype/custom_datatype.h

@@ -0,0 +1,51 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
+
+typedef struct {
+    UA_Float x;
+    UA_Float y;
+    UA_Float z;
+} Point;
+
+/* The datatype description for the Point datatype */
+#define Point_padding_y offsetof(Point,y) - offsetof(Point,x) - sizeof(UA_Float)
+#define Point_padding_z offsetof(Point,z) - offsetof(Point,y) - sizeof(UA_Float)
+
+static UA_DataTypeMember Point_members[3] = {
+        /* x */
+        {
+                "x", /* .memberName */
+                UA_TYPES_FLOAT,  /* .memberTypeIndex, points into UA_TYPES since namespaceZero is true */
+                0,               /* .padding */
+                true,            /* .namespaceZero, see .memberTypeIndex */
+                false            /* .isArray */
+        },
+
+        /* y */
+        {
+                "y",
+                UA_TYPES_FLOAT, Point_padding_y, true, false
+        },
+
+        /* z */
+        {
+                "y",
+                UA_TYPES_FLOAT, Point_padding_z, true, false
+        }
+};
+
+static const UA_DataType PointType = {
+        "Point",             /* .typeName */
+        {1, UA_NODEIDTYPE_NUMERIC, {4242}}, /* .typeId */
+        sizeof(Point),                   /* .memSize */
+        0,                               /* .typeIndex, in the array of custom types */
+        3,                               /* .membersSize */
+        false,                           /* .builtin */
+        true,                            /* .pointerFree */
+        false,                           /* .overlayable (depends on endianness and
+                                         the absence of padding) */
+        0,                               /* .binaryEncodingId, the numeric
+                                         identifier used on the wire (the
+                                         namespaceindex is from .typeId) */
+        Point_members
+};

+ 86 - 0
examples/custom_datatype/server_types_custom.c

@@ -0,0 +1,86 @@
+/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
+ * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
+
+#include <signal.h>
+#include <open62541.h>
+#include "custom_datatype.h"
+
+UA_Boolean running = true;
+
+static void stopHandler(int sig) {
+    UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
+    running = false;
+}
+
+static void
+add3PointDataType(UA_Server *server) {
+    UA_VariableTypeAttributes dattr = UA_VariableTypeAttributes_default;
+    dattr.description = UA_LOCALIZEDTEXT("en_US", "3D Point");
+    dattr.displayName = UA_LOCALIZEDTEXT("en_US", "3D Point");
+    dattr.dataType = PointType.typeId;
+    dattr.valueRank = -1;
+
+    Point p;
+    p.x = 0.0;
+    p.y = 0.0;
+    p.z = 0.0;
+    UA_Variant_setScalar(&dattr.value, &p, &PointType);
+
+
+    UA_Server_addVariableTypeNode(server, PointType.typeId,
+                                  UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
+                                  UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
+                                  UA_QUALIFIEDNAME(1, "3D.Point"),
+                                  UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
+                                  dattr,
+                                  NULL, NULL
+    );
+
+}
+
+static void
+add3DPointVariable(UA_Server *server) {
+    Point p;
+    p.x = 3.0;
+    p.y = 4.0;
+    p.z = 5.0;
+    UA_VariableAttributes vattr = UA_VariableAttributes_default;
+    vattr.description = UA_LOCALIZEDTEXT("en_US", "3D Point");
+    vattr.displayName = UA_LOCALIZEDTEXT("en_US", "3D Point");
+    vattr.dataType = PointType.typeId;
+    vattr.valueRank = -1;
+    UA_Variant_setScalar(&vattr.value, &p, &PointType);
+
+    UA_Server_addVariableNode(server, UA_NODEID_STRING(1, "3D.Point"),
+                              UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
+                              UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
+                              UA_QUALIFIEDNAME(1, "3D.Point"),
+                              PointType.typeId,
+                              vattr,
+                              NULL,
+                              NULL
+    );
+}
+
+int main(void) {
+    signal(SIGINT, stopHandler);
+    signal(SIGTERM, stopHandler);
+
+    UA_ServerConfig *config = UA_ServerConfig_new_default();
+    /* Make your custom datatype known to the stack */
+    UA_DataType types[1];
+    types[0] = PointType;
+    config->customDataTypes = types;
+    config->customDataTypesSize = 1;
+
+    UA_Server *server = UA_Server_new(config);
+
+    add3PointDataType(server);
+    add3DPointVariable(server);
+
+    UA_Server_run(server, &running);
+
+    UA_Server_delete(server);
+    UA_ServerConfig_delete(config);
+    return 0;
+}