Kaynağa Gözat

Merge remote-tracking branch 'upstream/master'

Leon Urbas 11 yıl önce
ebeveyn
işleme
0b2d70f7a6

+ 7 - 7
examples/src/Makefile.am

@@ -1,21 +1,21 @@
+if MULTITHREADING
+MT_LDADD = -lpthread
+else
+MT_LDADD =
+endif
 
 bin_PROGRAMS= $(top_builddir)/bin/exampleServer $(top_builddir)/bin/exampleServerMT $(top_builddir)/bin/exampleServerACPLT
 #__top_builddir__bin_exampleServer_LDFLAGS = -all-static
 __top_builddir__bin_exampleServer_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include
 __top_builddir__bin_exampleServer_SOURCES = opcuaServer.c networklayer.c
-__top_builddir__bin_exampleServer_LDADD= $(top_builddir)/lib/libopen62541.a
+__top_builddir__bin_exampleServer_LDADD= $(top_builddir)/lib/libopen62541.a $(MT_LDADD)
 
 __top_builddir__bin_exampleServerMT_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include
 __top_builddir__bin_exampleServerMT_SOURCES = opcuaServerMT.c networklayer.c
-if MULTITHREADING
-MT_LDADD = -lpthread
-else
-MT_LDADD =
-endif
 __top_builddir__bin_exampleServerMT_LDADD= $(top_builddir)/lib/libopen62541.a $(MT_LDADD)
 
 __top_builddir__bin_exampleServerACPLT_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include
 __top_builddir__bin_exampleServerACPLT_SOURCES = opcuaServerACPLT.c 
-__top_builddir__bin_exampleServerACPLT_LDADD= $(top_builddir)/lib/libopen62541.a
+__top_builddir__bin_exampleServerACPLT_LDADD= $(top_builddir)/lib/libopen62541.a $(MT_LDADD)
 
 AM_CFLAGS = $(GLOBAL_AM_CFLAGS)

+ 5 - 5
src/Makefile.am

@@ -38,7 +38,7 @@ libopen62541_la_LDFLAGS = -avoid-version -no-undefined
 #						ua_stackInternalTypes.c\
 #						ua_namespace.h\
 #						ua_namespace.c
-						
+
 #libopen62541_ladir = $(top_builddir)/include . $(top_builddir)/src . $(top_builddir)/src/util					
 
 #libopen62541_la_HEADERS = opcua.h\
@@ -53,7 +53,7 @@ libopen62541_la_LDFLAGS = -avoid-version -no-undefined
 #						ua_stackInternalTypes.h\
 #						ua_list.h\
 #						ua_indexedList.h
-						
+
 libopen62541_la_SOURCES = opcua.c\
 						ua_basictypes.c\
 						ua_namespace_0.c\
@@ -62,9 +62,9 @@ libopen62541_la_SOURCES = opcua.c\
 						ua_secureLayer.c\
 						util/ua_list.c\
 						util/ua_indexedList.c\
-						ua_namespace.c
-						
-						
+						ua_namespace.c\
+						ua_services_attribute.c\
+						ua_services_session.c
 
 #bin_PROGRAMS= $(top_builddir)/bin/open62541.out
 #__top_builddir__bin_libOpen62541_out_SOURCES = opcuaServer.c

+ 14 - 0
src/ua_application.h

@@ -0,0 +1,14 @@
+#ifndef OPCUA_APPLICATION_H_
+#define OPCUA_APPLICATION_H_
+
+#include "opcua.h"
+#include "ua_namespace.h"
+#include "ua_statuscodes.h"
+#include "ua_indexedList.h"
+
+typedef struct UA_Application_T {
+	UA_ApplicationDescription *description;
+	UA_indexedList_List *namespaces; // each entry is a namespace
+} UA_Application;
+
+#endif

+ 6 - 5
src/ua_connection.h

@@ -3,6 +3,7 @@
 
 #include "opcua.h"
 #include "ua_stackInternalTypes.h"
+#include "ua_application.h"
 
 enum UA_MessageType
 {
@@ -54,12 +55,17 @@ typedef struct T_UA_TL_connection
 	struct T_SL_Channel* secureChannel;
 } UA_TL_connection;
 
+typedef struct UA_Session_T {
+	UA_Int32 dummy;
+	UA_Application *application;
+} UA_Session;
 
 /* Secure Layer Channel */
 typedef struct T_SL_Channel
 {
 	UA_String secureChannelId;
 	UA_TL_connection* tlConnection;
+	UA_Session *session; // equals UA_Null iff no session is active
 
 	UA_AsymmetricAlgorithmSecurityHeader remoteAsymAlgSettings;
 	UA_AsymmetricAlgorithmSecurityHeader localAsymAlgSettings;
@@ -75,9 +81,4 @@ typedef struct T_SL_Channel
 
 } UA_SL_Channel;
 
-struct SS_connection
-{
-	UA_Int32 dummy;
-};
-
 #endif /* OPCUA_CONNECTIONHELPER_H_ */

+ 6 - 42
src/ua_secureLayer.c

@@ -5,6 +5,7 @@
 #include "ua_secureLayer.h"
 #include "ua_stackInternalTypes.h"
 #include "ua_statuscodes.h"
+#include "ua_services.h"
 
 #define SIZE_SECURECHANNEL_HEADER 12
 #define SIZE_SEQHEADER_HEADER 8
@@ -126,28 +127,15 @@ START_HANDLER(GetEndpoints)
 END_HANDLER
 
 START_HANDLER(CreateSession)
-	UA_String_printf("CreateSession Service - endpointUrl=", &(p->endpointUrl));
-	// FIXME: create session
-	r->sessionId.encodingByte = UA_NODEIDTYPE_FOURBYTE;
-	r->sessionId.namespace = 1;
-	r->sessionId.identifier.numeric = 666;
+	 service_createsession(channel, p, r);
 END_HANDLER
 
 START_HANDLER(ActivateSession)
-#pragma GCC diagnostic ignored "-Wunused-variable"
-// FIXME: activate session
-	UA_NodeId_printf("ActivateSession - authToken=", &(p->requestHeader.authenticationToken));
-	// 321 == AnonymousIdentityToken_Encoding_DefaultBinary
-	UA_NodeId_printf("ActivateSession - uIdToken.type=", &(p->userIdentityToken.typeId));
-	UA_ByteString_printx_hex("ActivateSession - uIdToken.body=", &(p->userIdentityToken.body));
-
+	 service_activatesession(channel, p, r);
 END_HANDLER
 
 START_HANDLER(CloseSession)
-#pragma GCC diagnostic ignored "-Wunused-variable"
-
-	// FIXME: close session
-
+	 service_closesession(channel, p, r);
 END_HANDLER
 
 START_HANDLER(Browse)
@@ -161,32 +149,8 @@ START_HANDLER(Browse)
 END_HANDLER
 
 START_HANDLER(Read)
-#pragma GCC diagnostic ignored "-Wunused-variable"
-	UA_Int32 i = 0;
-
-	r->resultsSize = p->nodesToReadSize;
-
-	if (r->resultsSize > 0) {
-		UA_Array_new((void**)&(r->results),r->resultsSize,UA_DATAVALUE);
-		for (i=0;i < r->resultsSize; i++) {
-			UA_NodeId_printf("ReadService - nodesToRead=", &(p->nodesToRead[i]->nodeId));
-			//FIXME: search the object in the namespace
-			if (p->nodesToRead[i]->nodeId.identifier.numeric == 2255) { // Server_NameSpaceArray alias namespace table
-				r->results[i]->encodingMask = UA_DATAVALUE_ENCODINGMASK_VARIANT & UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
-				r->results[i]->status = UA_STATUSCODE_GOOD;
-				r->results[i]->value.encodingMask = UA_INT32_NS0;
-				r->results[i]->value.vt = &UA_[UA_INT32];
-				r->results[i]->value.arrayLength = 1;
-				UA_Array_new((void**)&(r->results[i]->value.data),1,UA_INT32);
-				*(UA_Int32*) (r->results[i]->value.data[0]) = 1;
-			} else {
-				// FIXME: Status Codes
-				// r->results[i]->statusCode = UA_STATUSCODE_BAD_NODEIDUNKNOWN;
-				r->results[i]->status = -1;
-			}
-		}
-	}
-
+     // FIXME: Check if session is active 
+	 service_read(channel->session->application, p, r);
 END_HANDLER
 
 START_HANDLER(CreateSubscription)

+ 66 - 0
src/ua_services.h

@@ -0,0 +1,66 @@
+#ifndef UA_SERVICES_H_
+#define UA_SERVICES_H_
+
+#include "opcua.h"
+#include "ua_application.h"
+#include "ua_statuscodes.h"
+#include "ua_transportLayer.h"
+
+/* Part 4: 5.4 Discovery Service Set */
+// service_findservers
+// service_getendpoints
+// service_registerserver
+
+/* Part 4: 5.5 SecureChannel Service Set */
+// service_opensecurechannel
+// service_closesecurechannel
+
+/* Part 4: 5.6 Session Service Set */
+UA_Int32 service_createsession(UA_SL_Channel *channel, UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
+UA_Int32 service_activatesession(UA_SL_Channel *channel, UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
+UA_Int32 service_closesession(UA_SL_Channel *channel, UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
+// service_cancel
+
+/* Part 4: 5.7 NodeManagement Service Set */
+// service_addnodes
+// service_addreferences
+// service_deletenodes
+// service_deletereferences
+
+/* Part 4: 5.8 View Service Set */
+// service_browse
+// service_browsenext
+// service_translatebrowsepathstonodeids
+// service_registernodes
+// service_unregisternodes
+
+/* Part 4: 5.9 Query Service Set */
+// service_queryfirst
+// service_querynext
+
+/* Part 4: 5.10 Attribute Service Set */
+UA_Int32 service_read(UA_Application *app, UA_ReadRequest *request, UA_ReadResponse *response);
+// service_historyread;
+// service_write;
+// service_historyupdate;
+
+/* Part 4: 5.11 Method Service Set */
+// service_call
+
+/* Part 4: 5.12 MonitoredItem Service Set */
+// service_createmonitoreditems
+// service_modifymonitoreditems
+// service_setmonitoringmode
+// service_settriggering
+// service_deletemonitoreditems
+
+/* Part 4: 5.13 Subscription Service Set */
+// service_createsubscription
+// service_modifysubscription
+// service_setpublishingmode
+// service_publish
+// service_republish
+// service_transfersubscription
+// service_deletesubscription
+
+#endif

+ 169 - 0
src/ua_services_attribute.c

@@ -0,0 +1,169 @@
+#include "ua_services.h"
+
+enum UA_AttributeId {
+	UA_ATTRIBUTEID_NODEID = 1,
+	UA_ATTRIBUTEID_NODECLASS = 2,
+	UA_ATTRIBUTEID_BROWSENAME = 3,
+	UA_ATTRIBUTEID_DISPLAYNAME = 4,
+	UA_ATTRIBUTEID_DESCRIPTION = 5,
+	UA_ATTRIBUTEID_WRITEMASK = 6,
+	UA_ATTRIBUTEID_USERWRITEMASK = 7,
+	UA_ATTRIBUTEID_ISABSTRACT = 8,
+	UA_ATTRIBUTEID_SYMMETRIC = 9,
+	UA_ATTRIBUTEID_INVERSENAME = 10,
+	UA_ATTRIBUTEID_CONTAINSNOLOOPS = 11,
+	UA_ATTRIBUTEID_EVENTNOTIFIER = 12,
+	UA_ATTRIBUTEID_VALUE = 13,
+	UA_ATTRIBUTEID_DATATYPE = 14,
+	UA_ATTRIBUTEID_VALUERANK = 15,
+	UA_ATTRIBUTEID_ARRAYDIMENSIONS = 16,
+	UA_ATTRIBUTEID_ACCESSLEVEL = 17,
+	UA_ATTRIBUTEID_USERACCESSLEVEL = 18,
+	UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL = 19,
+	UA_ATTRIBUTEID_HISTORIZING = 20,
+	UA_ATTRIBUTEID_EXECUTABLE = 21,
+	UA_ATTRIBUTEID_USEREXECUTABLE = 22
+};
+
+static UA_DataValue * service_read_node(UA_Application *app, UA_ReadValueId *id) {
+	UA_DataValue *v;
+	UA_alloc((void **) &v, sizeof(UA_DataValue));
+	
+	UA_NodeId *nodeid = &id->nodeId;
+	namespace *ns = UA_indexedList_findValue(app->namespaces, nodeid->namespace);
+
+	if (ns == UA_NULL) {
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNODEIDUNKNOWN;
+		return v;
+	}
+	
+	UA_Node *node = UA_NULL;
+	ns_lock *lock = UA_NULL;
+	UA_Int32 result = get_node(ns, nodeid, &node, &lock);
+	if(result != UA_SUCCESS) {
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNODEIDUNKNOWN;
+		return v;
+	}
+
+	switch(id->attributeId) {
+	case UA_ATTRIBUTEID_NODEID:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_NODECLASS:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_BROWSENAME:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_DISPLAYNAME:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_DESCRIPTION:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_WRITEMASK:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_USERWRITEMASK:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_ISABSTRACT:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_SYMMETRIC:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_INVERSENAME:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_EVENTNOTIFIER:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_VALUE:
+		if (node->nodeClass != UA_NODECLASS_VARIABLE) {
+			v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+			v->status = UA_STATUSCODE_BADNOTREADABLE;
+			break;
+		}
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE | UA_DATAVALUE_ENCODINGMASK_VARIANT;
+		v->status = UA_STATUSCODE_GOOD;
+		v->value = ((UA_VariableNode *)node)->value; // be careful not to release the node before encoding the message
+		break;
+	case UA_ATTRIBUTEID_DATATYPE:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_VALUERANK:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_ACCESSLEVEL:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_USERACCESSLEVEL:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_HISTORIZING:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_EXECUTABLE:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	case UA_ATTRIBUTEID_USEREXECUTABLE:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADNOTREADABLE;
+		break;
+	default:
+		v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
+		v->status = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
+		break;
+	}
+	release_node(lock);
+	return v;
+}
+
+UA_Int32 service_read(UA_Application *app, UA_ReadRequest *request, UA_ReadResponse *response ) {
+	if(app == UA_NULL) {
+		return UA_ERROR; // TODO: Return error message
+	}
+
+	UA_alloc((void **)response, sizeof(UA_ReadResponse));
+	int readsize = request->nodesToReadSize > 0 ? request->nodesToReadSize : 0;
+	response->resultsSize = readsize;
+	UA_alloc((void **)&response->results, sizeof(void *)*readsize);
+	for(int i=0;i<readsize;i++) {
+		response->results[i] = service_read_node(app, request->nodesToRead[i]);
+	}
+	response->diagnosticInfosSize = -1;
+	return UA_SUCCESS;
+}
+

+ 30 - 0
src/ua_services_session.c

@@ -0,0 +1,30 @@
+#include "ua_services.h"
+
+UA_Int32 service_createsession(UA_SL_Channel *channel, UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) {
+	UA_String_printf("CreateSession Service - endpointUrl=", &(request->endpointUrl));
+	// FIXME: create session
+	response->sessionId.encodingByte = UA_NODEIDTYPE_FOURBYTE;
+	response->sessionId.namespace = 1;
+	response->sessionId.identifier.numeric = 666;
+	return UA_SUCCESS;
+}
+
+UA_Int32 service_activatesession(UA_SL_Channel *channel, UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response) {
+	// FIXME: activate session
+	UA_NodeId_printf("ActivateSession - authToken=", &(request->requestHeader.authenticationToken));
+	// 321 == AnonymousIdentityToken_Encoding_DefaultBinary
+	UA_NodeId_printf("ActivateSession - uIdToken.type=", &(request->userIdentityToken.typeId));
+	UA_ByteString_printx_hex("ActivateSession - uIdToken.body=", &(request->userIdentityToken.body));
+
+	// FIXME: channel->application = <Application Ptr>
+	
+	return UA_SUCCESS;
+}
+
+UA_Int32 service_closesession(UA_SL_Channel *channel, UA_CloseSessionRequest *request, UA_CloseSessionResponse *response) {
+
+	channel->session = UA_NULL;
+	// FIXME: set response
+	
+	return UA_SUCCESS;
+}