Ver código fonte

Merge branch 'master' of https://github.com/acplt/open62541

markusgraube 11 anos atrás
pai
commit
141cb3860a

+ 7 - 0
Makefile.am

@@ -1,3 +1,10 @@
+
+if DEBUG
+AM_CFLAGS = -g -O0
+else
+AM_CFLAGS = -O2
+endif
+
 if HAVE_CHECK
 if HAVE_CHECK
     SUBS=src . tests .
     SUBS=src . tests .
 else 
 else 

+ 1 - 0
examples/src/Makefile.am

@@ -1,3 +1,4 @@
+
 bin_PROGRAMS= $(top_builddir)/bin/exampleServer
 bin_PROGRAMS= $(top_builddir)/bin/exampleServer
 __top_builddir__bin_exampleServer_LDFLAGS = -all-static
 __top_builddir__bin_exampleServer_LDFLAGS = -all-static
 __top_builddir__bin_exampleServer_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include
 __top_builddir__bin_exampleServer_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include

+ 6 - 1
examples/src/opcuaServer.c

@@ -58,14 +58,18 @@ void server_init()
 void server_run()
 void server_run()
 {
 {
 	UA_connection connection;
 	UA_connection connection;
+
 	UA_ByteString slMessage;
 	UA_ByteString slMessage;
-	TL_initConnectionObject(&connection);
+
 	char optval;
 	char optval;
 	int sockfd, newsockfd, portno, clilen;
 	int sockfd, newsockfd, portno, clilen;
 	char buffer[BUFFER_SIZE];
 	char buffer[BUFFER_SIZE];
 	struct sockaddr_in serv_addr, cli_addr;
 	struct sockaddr_in serv_addr, cli_addr;
 	int  n;
 	int  n;
 
 
+	TL_initConnectionObject(&connection);
+	SL_initConnectionObject(&connection);
+
 	/* First call to socket() function */
 	/* First call to socket() function */
 	sockfd = socket(AF_INET, SOCK_STREAM, 0);
 	sockfd = socket(AF_INET, SOCK_STREAM, 0);
 	if (sockfd < 0)
 	if (sockfd < 0)
@@ -108,6 +112,7 @@ void server_run()
 		perror("ERROR on accept");
 		perror("ERROR on accept");
 		exit(1);
 		exit(1);
 	}
 	}
+
 	printf("One connection accepted");
 	printf("One connection accepted");
 	while(1)
 	while(1)
 	{
 	{

+ 22 - 0
src/Makefile.am

@@ -1,3 +1,21 @@
+
+#__top_builddir__bin_stackTest_out_SOURCES =	opcuaServer.c\
+#											opcua_builtInDatatypes.c\
+#											opcua_binaryEncDec.c\
+#											opcua_transportLayer.c\
+#											opcua_builtInDatatypes.h\
+#											opcua_binaryEncDec.h\
+#											opcua_transportLayer.h\
+#											opcua_advancedDatatypes.h\
+#											opcua_types.h\
+#											opcua_connectionHelper.h\
+#											tcp_layer.h
+
+#lib_LTLIBRARIES = libstack.la
+#libstack_la_SOURCES = opcua_transportLayer.c\
+#					  opcua_transportLayer.h\
+#					  opcua_advancedDatatypes.h\
+#					  opcua_connectionHelper.h	
 lib_LTLIBRARIES = libopen62541.la
 lib_LTLIBRARIES = libopen62541.la
 libopen62541_la_LDFLAGS = -avoid-version -no-undefined
 libopen62541_la_LDFLAGS = -avoid-version -no-undefined
 libopen62541_la_SOURCES = opcua_builtInDatatypes.c\
 libopen62541_la_SOURCES = opcua_builtInDatatypes.c\
@@ -23,6 +41,10 @@ libopen62541_la_SOURCES = opcua_builtInDatatypes.c\
 						util/UA_indexedList.c						
 						util/UA_indexedList.c						
 libopen62541_la_CFLAGS = -I $(top_builddir)/include
 libopen62541_la_CFLAGS = -I $(top_builddir)/include
 
 
+#bin_PROGRAMS= $(top_builddir)/bin/open62541.out
+#__top_builddir__bin_libOpen62541_out_SOURCES = opcuaServer.c
+#libOpen62541_la_LIBADD = ../lib/libOpen62541.la		  										
+
 .PHONY: convenience-link clean-convenience-link
 .PHONY: convenience-link clean-convenience-link
 
 
 convenience-link: $(lib_LTLIBRARIES)
 convenience-link: $(lib_LTLIBRARIES)

+ 126 - 16
src/opcua_binaryEncDec.c

@@ -430,24 +430,128 @@ Int32 decoder_decodeBuiltInDatatype(char const * srcBuf, Int32 type, Int32 *pos,
  }
  }
 
 
 
 
-/* not tested, needs to be reimplemented */
-Int32 encode_builtInDatatypeArray(void* data[], Int32 size, Int32 type,
-		Int32 *pos, char *dstBuf) {
-	int i;
+ /* not tested */
+Int32 encoder_encodeBuiltInDatatypeArray(void **data, Int32 size, Int32 arrayType, Int32 *pos, char *dstBuf)
+{
+	Int32 i;
+	Int32 type;
+	void* pElement = NULL;
+	//encode the length
+	encoder_encodeBuiltInDatatype((void*) (&size), INT32, pos, dstBuf);
 
 
-	printf("encode_builtInDatatypeArray - size=%d, data=%p\n", size, data);
+	if(data != NULL)
+	{
+		pElement = *data;
+	}
 
 
-	// encode length of array
-	encodeUInt32(size, pos, dstBuf);
+	//get the element type from array type
+	type = arrayType - 128; //TODO replace with define
 
 
-	// now iterate over array
+	//encode data elements
 	for (i = 0; i < size; i++) {
 	for (i = 0; i < size; i++) {
-		printf("encode_builtInDatatypeArray - pItem=%p", data[i]);
-		if (type == BYTE_STRING) {
-			UA_ByteString* p = (UA_ByteString*) data[i];
-			printf(", item={l=%d,m=%.*s\n}", p->Length, p->Length, p->Data);
-		} else {
-			printf("\n");
+		switch(type)
+		{
+		case BOOLEAN:
+			encoder_encodeBuiltInDatatype((Boolean*)pElement, type, pos, dstBuf);
+			pElement = (Boolean*)pElement + 1;
+			break;
+		case SBYTE:
+			encoder_encodeBuiltInDatatype((SByte*)pElement, type, pos, dstBuf);
+			pElement = (SByte*)pElement + 1;
+			break;
+		case BYTE:
+			encoder_encodeBuiltInDatatype((Byte*)pElement, type, pos, dstBuf);
+			pElement = (Byte*)pElement + 1;
+			break;
+		case INT16:
+			encoder_encodeBuiltInDatatype((Int16*)pElement, type, pos, dstBuf);
+			pElement = (Int16*)pElement + 1;
+			break;
+		case UINT16:
+			encoder_encodeBuiltInDatatype((UInt16*)pElement, type, pos, dstBuf);
+			pElement = (UInt16*)pElement + 1;
+			break;
+		case INT32:
+			encoder_encodeBuiltInDatatype((Int32*)pElement, type, pos, dstBuf);
+			pElement = (Int32*)pElement + 1;
+			break;
+		case UINT32:
+			encoder_encodeBuiltInDatatype((UInt32*)pElement, type, pos, dstBuf);
+			pElement = (UInt32*)pElement + 1;
+			break;
+		case INT64:
+			encoder_encodeBuiltInDatatype((Int64*)pElement, type, pos, dstBuf);
+			pElement = (Int64*)pElement + 1;
+			break;
+		case UINT64:
+			encoder_encodeBuiltInDatatype((UInt64*)pElement, type, pos, dstBuf);
+			pElement = (UInt64*)pElement + 1;
+			break;
+		case FLOAT:
+			encoder_encodeBuiltInDatatype((Float*)pElement, type, pos, dstBuf);
+			pElement = (Float*)pElement + 1;
+			break;
+		case DOUBLE:
+			encoder_encodeBuiltInDatatype((Double*)pElement, type, pos, dstBuf);
+			pElement = (Double*)pElement + 1;
+			break;
+		case STRING:
+			encoder_encodeBuiltInDatatype((UA_String*)pElement, type, pos, dstBuf);
+			pElement = (UA_String*)pElement + 1;
+			break;
+		case DATE_TIME:
+			encoder_encodeBuiltInDatatype((UA_DateTime*)pElement, type, pos, dstBuf);
+			pElement = (UA_DateTime*)pElement + 1;
+			break;
+		case GUID:
+			encoder_encodeBuiltInDatatype((UA_Guid*)pElement, type, pos, dstBuf);
+			pElement = (UA_Guid*)pElement + 1;
+			break;
+		case BYTE_STRING:
+			encoder_encodeBuiltInDatatype((UA_ByteString*)pElement, type, pos, dstBuf);
+			pElement = (UA_ByteString*)pElement + 1;
+			break;
+		case XML_ELEMENT:
+			encoder_encodeBuiltInDatatype((UA_XmlElement*)pElement, type, pos, dstBuf);
+			pElement = (UA_XmlElement*)pElement + 1;
+			break;
+		case NODE_ID:
+			encoder_encodeBuiltInDatatype((UA_NodeId*)pElement, type, pos, dstBuf);
+			pElement = (UA_NodeId*)pElement + 1;
+			break;
+		case EXPANDED_NODE_ID:
+			encoder_encodeBuiltInDatatype((UA_ExpandedNodeId*)pElement, type, pos, dstBuf);
+			pElement = (UA_ExpandedNodeId*)pElement + 1;
+			break;
+		case STATUS_CODE:
+			encoder_encodeBuiltInDatatype((UA_StatusCode*)pElement, type, pos, dstBuf);
+			pElement = (UA_StatusCode*)pElement + 1;
+			break;
+		case QUALIFIED_NAME:
+			encoder_encodeBuiltInDatatype((UA_QualifiedName*)pElement, type, pos, dstBuf);
+			pElement = (UA_QualifiedName*)pElement + 1;
+			break;
+		case LOCALIZED_TEXT:
+			encoder_encodeBuiltInDatatype((UA_LocalizedText*)pElement, type, pos, dstBuf);
+			pElement = (UA_LocalizedText*)pElement + 1;
+			break;
+		case EXTENSION_OBJECT:
+			encoder_encodeBuiltInDatatype((UA_ExtensionObject*)pElement, type, pos, dstBuf);
+			pElement = (UA_ExtensionObject*)pElement + 1;
+			break;
+		case DATA_VALUE:
+			encoder_encodeBuiltInDatatype((UA_DataValue*)pElement, type, pos, dstBuf);
+			pElement = (UA_DataValue*)pElement + 1;
+			break;
+		case VARIANT:
+			encoder_encodeBuiltInDatatype((UA_Variant*)pElement, type, pos, dstBuf);
+			pElement = (UA_Variant*)pElement + 1;
+			break;
+		case DIAGNOSTIC_INFO:
+			encoder_encodeBuiltInDatatype((UA_DiagnosticInfo*)pElement, type, pos, dstBuf);
+			pElement = (UA_DiagnosticInfo*)pElement + 1;
+
+			break;
 		}
 		}
 		encoder_encodeBuiltInDatatype(data[i], type, pos, dstBuf);
 		encoder_encodeBuiltInDatatype(data[i], type, pos, dstBuf);
 	}
 	}
@@ -1415,8 +1519,14 @@ Int32 encodeResponseHeader(UA_AD_ResponseHeader const * responseHeader,
 	encodeIntegerId(responseHeader->requestHandle, pos, dstBuf->Data);
 	encodeIntegerId(responseHeader->requestHandle, pos, dstBuf->Data);
 	encodeUInt32(responseHeader->serviceResult, pos, dstBuf->Data);
 	encodeUInt32(responseHeader->serviceResult, pos, dstBuf->Data);
 	encodeDiagnosticInfo(responseHeader->serviceDiagnostics, pos, dstBuf->Data);
 	encodeDiagnosticInfo(responseHeader->serviceDiagnostics, pos, dstBuf->Data);
-	encode_builtInDatatypeArray(responseHeader->stringTable, responseHeader->noOfStringTable, BYTE_STRING, pos, dstBuf->Data);
-	encodeExtensionObject(responseHeader->additionalHeader,pos, dstBuf->Data);
+
+	encoder_encodeBuiltInDatatypeArray(responseHeader->stringTable,
+			responseHeader->noOfStringTable, STRING_ARRAY, pos, dstBuf->Data);
+
+	encodeExtensionObject(responseHeader->additionalHeader, pos, dstBuf->Data);
+
+	//Kodieren von String Datentypen
+
 	return 0;
 	return 0;
 }
 }
 Int32 extensionObject_calcSize(UA_ExtensionObject *extensionObject) {
 Int32 extensionObject_calcSize(UA_ExtensionObject *extensionObject) {

+ 13 - 0
src/opcua_binaryEncDec.h

@@ -39,6 +39,19 @@ Int32 decoder_decodeBuiltInDatatype(char const * srcBuf, Int32 type, Int32 *pos,
  */
  */
 Int32 encoder_encodeBuiltInDatatype(void *data, Int32 type, Int32 *pos, char *dstBuf);
 Int32 encoder_encodeBuiltInDatatype(void *data, Int32 type, Int32 *pos, char *dstBuf);
 
 
+
+/**
+ *
+ * @param data
+ * @param size
+ * @param type
+ * @param pos
+ * @param dstBuf
+ * @return
+ */
+Int32 encoder_encodeBuiltInDatatypeArray(void **data, Int32 size,
+		Int32 arrayType, Int32 *pos,
+		char *dstBuf);
 /**
 /**
  *
  *
  * @param buf
  * @param buf

+ 12 - 0
src/opcua_builtInDatatypes.c

@@ -54,6 +54,18 @@ void UA_ByteString_printx(char* label, UA_ByteString* string) {
 	}
 	}
 	printf("}}\n");
 	printf("}}\n");
 }
 }
+void UA_ByteString_printx_hex(char* label, UA_ByteString* string) {
+	int i;
+	printf("%s {Length=%d, Data=", label, string->Length);
+	if (string->Length > 0) {
+		for (i = 0; i < string->Length; i++) {
+			printf("%c%x", i == 0 ? '{' : ',', (string->Data)[i]);
+		}
+	} else {
+		printf("{");
+	}
+	printf("}}\n");
+}
 
 
 void UA_NodeId_printf(char* label, UA_NodeId* node) {
 void UA_NodeId_printf(char* label, UA_NodeId* node) {
 	printf("%s {EncodingByte=%d, Namespace=%d, ", label,
 	printf("%s {EncodingByte=%d, Namespace=%d, ", label,

+ 14 - 2
src/opcua_connectionHelper.h

@@ -52,20 +52,32 @@ struct TL_connection
 	TL_buffer localConf;
 	TL_buffer localConf;
 	UA_String endpointURL;
 	UA_String endpointURL;
 };
 };
+typedef struct
+{
+	UA_ByteString SecurityPolicyUri;
+	UA_ByteString SenderCertificate;
+	UA_ByteString ReceiverCertificateThumbprint;
+
+}AsymmetricAlgSecuritySettings;
+
 
 
 
 
 struct SL_connection
 struct SL_connection
 {
 {
-
+	AsymmetricAlgSecuritySettings remoteAsymAlgSettings;
+	AsymmetricAlgSecuritySettings localtAsymAlgSettings;
+/*
 	UA_ByteString SecurityPolicyUri;
 	UA_ByteString SecurityPolicyUri;
 	UA_ByteString SenderCertificate;
 	UA_ByteString SenderCertificate;
 	UA_ByteString ReceiverCertificateThumbprint;
 	UA_ByteString ReceiverCertificateThumbprint;
+*/
 	UInt32 sequenceNumber;
 	UInt32 sequenceNumber;
 	UInt32 requestType;
 	UInt32 requestType;
 	UA_String secureChannelId;
 	UA_String secureChannelId;
 	//UInt32 UInt32_secureChannelId;
 	//UInt32 UInt32_secureChannelId;
 	UInt32 securityMode;
 	UInt32 securityMode;
-	UA_ByteString clientNonce;
+	UA_ByteString remoteNonce;
+	UA_ByteString localNonce;
 	UInt32 connectionState;
 	UInt32 connectionState;
 	SL_ChannelSecurityToken securityToken;
 	SL_ChannelSecurityToken securityToken;
 	UInt32 requestId; // request Id of the current request
 	UInt32 requestId; // request Id of the current request

+ 229 - 42
src/opcua_secureChannelLayer.c

@@ -8,36 +8,147 @@
 #include <stdio.h>
 #include <stdio.h>
 #include "opcua_time.h"
 #include "opcua_time.h"
 
 
+#define SIZE_SECURECHANNEL_HEADER 12
+#define SIZE_SEQHEADER_HEADER 8
+
+
+/*
+ * inits a connection object for secure channel layer
+ */
+Int32 SL_initConnectionObject(UA_connection *connection)
+{
+
+	//TODO: fill with valid information
+	connection->secureLayer.localtAsymAlgSettings.ReceiverCertificateThumbprint.Data = NULL;
+	connection->secureLayer.localtAsymAlgSettings.ReceiverCertificateThumbprint.Length = 0;
+
+	connection->secureLayer.localtAsymAlgSettings.SecurityPolicyUri.Data = "http://opcfoundation.org/UA/SecurityPolicy#None";
+	connection->secureLayer.localtAsymAlgSettings.SecurityPolicyUri.Length = 47;
+
+	connection->secureLayer.localtAsymAlgSettings.SenderCertificate.Data = NULL;
+	connection->secureLayer.localtAsymAlgSettings.SenderCertificate.Length = 0;
+
+	connection->secureLayer.remoteNonce.Data = NULL;
+	connection->secureLayer.remoteNonce.Length = 0;
+
+	connection->secureLayer.localNonce.Data = (Byte*)opcua_malloc(sizeof(Byte));
+	*connection->secureLayer.localNonce.Data = sizeof(Byte);
+	connection->secureLayer.localNonce.Length = 1;
+
+	connection->secureLayer.connectionState = connectionState_CLOSED;
+
+	connection->secureLayer.requestId = 0;
+
+	connection->secureLayer.requestType = 0;
+
+	connection->secureLayer.secureChannelId.Data = NULL;
+	connection->secureLayer.secureChannelId.Length = 0;
+
+	connection->secureLayer.securityMode = securityMode_INVALID;
+	//TODO set a valid start secureChannelId number
+	connection->secureLayer.securityToken.secureChannelId = 25;
+
+	//TODO set a valid start TokenId
+	connection->secureLayer.securityToken.tokenId = 1;
+	connection->secureLayer.sequenceNumber = 1;
+
+	return UA_NO_ERROR;
+}
+
 Int32 SL_send(UA_connection *connection, UA_ByteString responseMessage, Int32 type)
 Int32 SL_send(UA_connection *connection, UA_ByteString responseMessage, Int32 type)
 {
 {
 	UInt32 sequenceNumber;
 	UInt32 sequenceNumber;
 	UInt32 requestId;
 	UInt32 requestId;
-	char securityPolicy[] = "http://opcfoundation.org/UA/SecurityPolicy#None";
-	SL_AsymmetricAlgorithmSecurityHeader AAS_header;
-
+	Int32 pos;
+	Int32 sizeAsymAlgHeader;
+	UA_ByteString responsePacket;
+	Int32 packetSize;
+	Int32 sizePadding;
+	Int32 sizeSignature;
+
+
+	sizeAsymAlgHeader = 3 * sizeof(UInt32) +
+			connection->secureLayer.localtAsymAlgSettings.SecurityPolicyUri.Length +
+			connection->secureLayer.localtAsymAlgSettings.SenderCertificate.Length +
+			connection->secureLayer.localtAsymAlgSettings.ReceiverCertificateThumbprint.Length;
+	pos = 0;
 	//sequence header
 	//sequence header
 	sequenceNumber = connection->secureLayer.sequenceNumber;
 	sequenceNumber = connection->secureLayer.sequenceNumber;
-	requestId = connection->secureLayer.requestId;
+    requestId = connection->secureLayer.requestId;
 
 
 
 
 	if(type == 449) //openSecureChannelResponse -> asymmetric algorithm
 	if(type == 449) //openSecureChannelResponse -> asymmetric algorithm
 	{
 	{
-		AAS_header.SecurityPolicyUri.Length = strlen(securityPolicy);
-		AAS_header.SecurityPolicyUri.Data = securityPolicy;
-		AAS_header.SenderCertificate.Length = -1;
-		AAS_header.ReceiverThumbprint.Length = -1;
-	}
-	else
-	{
-		//TODO add Symmetric Security
+		//TODO fill with valid sizes
+		sizePadding = 0;
+		sizeSignature = 0;
+
+		//TODO: size calculation need
+		packetSize = SIZE_SECURECHANNEL_HEADER +
+				SIZE_SEQHEADER_HEADER +
+				sizeAsymAlgHeader +
+				responseMessage.Length +
+				sizePadding +
+				sizeSignature;
+
+		//get memory for response
+		responsePacket.Data = (char*)opcua_malloc(packetSize);
+
+		responsePacket.Length = packetSize;
+
+		/*---encode Secure Conversation Message Header ---*/
+		//encode MessageType - OPN message
+		responsePacket.Data[0] = 'O';
+		responsePacket.Data[1] = 'P';
+		responsePacket.Data[2] = 'N';
+		pos += 3;
+		//encode Chunk Type - set to final
+		responsePacket.Data[3] = 'F';
+		pos += 1;
+		encoder_encodeBuiltInDatatype(&packetSize,INT32,&pos,responsePacket.Data);
+		encoder_encodeBuiltInDatatype(&(connection->secureLayer.securityToken.secureChannelId),
+				INT32,&pos,responsePacket.Data);
+
+		/*---encode Asymmetric Algorithm Header ---*/
+		encoder_encodeBuiltInDatatype(&(connection->secureLayer.localtAsymAlgSettings.SecurityPolicyUri),
+						BYTE_STRING,&pos,responsePacket.Data);
+		encoder_encodeBuiltInDatatype(&(connection->secureLayer.localtAsymAlgSettings.SenderCertificate),
+						BYTE_STRING,&pos,responsePacket.Data );
+		encoder_encodeBuiltInDatatype(&(connection->secureLayer.localtAsymAlgSettings.ReceiverCertificateThumbprint),
+						BYTE_STRING,&pos,responsePacket.Data );
 	}
 	}
+
+
+
+
+	/*---encode Sequence Header ---*/
+	encoder_encodeBuiltInDatatype(&sequenceNumber,UINT32,&pos,responsePacket.Data);
+	encoder_encodeBuiltInDatatype(&requestId,UINT32,&pos,responsePacket.Data);
+
+	/*---add encoded Message ---*/
+	memcpy(&(responsePacket.Data[pos]), responseMessage.Data, responseMessage.Length);
+
+	/* sign Data*/
+
+	/* encrypt Data */
+
+	/* send Data */
+	TL_send(connection,&responsePacket);
+
+
 	return UA_NO_ERROR;
 	return UA_NO_ERROR;
 }
 }
+
 /*
 /*
  * opens a secure channel
  * opens a secure channel
  */
  */
-Int32 SL_openSecureChannel(UA_connection *connection, IntegerId requestHandle, UA_StatusCode serviceResult, UA_DiagnosticInfo *serviceDiagnostics)
+Int32 SL_openSecureChannel(UA_connection *connection,
+		UA_AD_RequestHeader *requestHeader,
+		UA_StatusCode serviceResult)
 {
 {
+
+
+
 	UA_AD_ResponseHeader responseHeader;
 	UA_AD_ResponseHeader responseHeader;
 	UA_ExtensionObject additionalHeader;
 	UA_ExtensionObject additionalHeader;
 	SL_ChannelSecurityToken securityToken;
 	SL_ChannelSecurityToken securityToken;
@@ -46,17 +157,32 @@ Int32 SL_openSecureChannel(UA_connection *connection, IntegerId requestHandle, U
 	//sizes for memory allocation
 	//sizes for memory allocation
 	Int32 sizeResponse;
 	Int32 sizeResponse;
 	Int32 sizeRespHeader;
 	Int32 sizeRespHeader;
+	Int32 sizeResponseType;
 	Int32 sizeRespMessage;
 	Int32 sizeRespMessage;
 	Int32 sizeSecurityToken;
 	Int32 sizeSecurityToken;
 	UA_ByteString response;
 	UA_ByteString response;
 	UInt32 serverProtocolVersion;
 	UInt32 serverProtocolVersion;
-	Int32 pos = 0;
+	Int32 pos;
+	UA_DiagnosticInfo serviceDiagnostics;
 
 
+	if(requestHeader->returnDiagnostics != 0)
+	{
+		printf("SL_openSecureChannel - diagnostics demanded by the client\n");
+		printf("SL_openSecureChannel - retrieving diagnostics not implemented!\n");
+		//TODO fill with demanded information part 4, 7.8 - Table 123
+		serviceDiagnostics.EncodingMask = 0;
+	}
+	else
+	{
+		serviceDiagnostics.EncodingMask = 0;
+	}
 	/*--------------type ----------------------*/
 	/*--------------type ----------------------*/
+
 	//Four Bytes Encoding
 	//Four Bytes Encoding
 	responseType.EncodingByte = NIEVT_FOUR_BYTE;
 	responseType.EncodingByte = NIEVT_FOUR_BYTE;
-	responseType.Namespace = 0;
+	//openSecureChannelResponse = 449
 	responseType.Identifier.Numeric = 449;
 	responseType.Identifier.Numeric = 449;
+	responseType.Namespace = 0;
 
 
 	/*--------------responseHeader-------------*/
 	/*--------------responseHeader-------------*/
 
 
@@ -69,68 +195,113 @@ Int32 SL_openSecureChannel(UA_connection *connection, IntegerId requestHandle, U
 	 * 		addtionalHeader Extensible Parameter
 	 * 		addtionalHeader Extensible Parameter
 	 */
 	 */
 	//current time
 	//current time
-	responseHeader.timestamp = opcua_getTime();
+
+	responseHeader.timestamp = opcua_time_now();
 	//request Handle which client sent
 	//request Handle which client sent
-	responseHeader.requestHandle = requestHandle;
+	responseHeader.requestHandle = requestHeader->requestHandle;
 	// StatusCode which informs client about quality of response
 	// StatusCode which informs client about quality of response
 	responseHeader.serviceResult = serviceResult;
 	responseHeader.serviceResult = serviceResult;
 	//retrieve diagnosticInfo if client demands
 	//retrieve diagnosticInfo if client demands
-	responseHeader.serviceDiagnostics = serviceDiagnostics;
+	responseHeader.serviceDiagnostics = &serviceDiagnostics;
 
 
 	//text of fields defined in the serviceDiagnostics
 	//text of fields defined in the serviceDiagnostics
 	responseHeader.noOfStringTable = 0;
 	responseHeader.noOfStringTable = 0;
 	responseHeader.stringTable = NULL;
 	responseHeader.stringTable = NULL;
 
 
+
 	// no additional header
 	// no additional header
-	responseHeader.additionalHeader = &the_empty_UA_ExtensionObject;
+	additionalHeader.Encoding = 0;
+
+	additionalHeader.Body.Data = NULL;
+	additionalHeader.Body.Length = 0;
 
 
+	additionalHeader.TypeId.EncodingByte = 0;
+	additionalHeader.TypeId.Namespace = 0;
+	additionalHeader.TypeId.Identifier.Numeric = 0;
 
 
+	responseHeader.additionalHeader = &additionalHeader;
+	printf("SL_openSecureChannel - built response header\n");
+
+	//calculate the size
+	sizeRespHeader = responseHeader_calcSize(&responseHeader);
+	printf("SL_openSecureChannel - size response header =%d\n",sizeRespHeader);
 	/*--------------responseMessage-------------*/
 	/*--------------responseMessage-------------*/
 	/* 	Res-2) UInt32 ServerProtocolVersion
 	/* 	Res-2) UInt32 ServerProtocolVersion
 	 * 	Res-3) SecurityToken channelSecurityToken
 	 * 	Res-3) SecurityToken channelSecurityToken
 	 *  Res-5) ByteString ServerNonce
 	 *  Res-5) ByteString ServerNonce
 	*/
 	*/
+
 	//                  secureChannelId + TokenId + CreatedAt + RevisedLifetime
 	//                  secureChannelId + TokenId + CreatedAt + RevisedLifetime
 	sizeSecurityToken = sizeof(UInt32) + sizeof(UInt32) + sizeof(UA_DateTime) + sizeof(Int32);
 	sizeSecurityToken = sizeof(UInt32) + sizeof(UInt32) + sizeof(UA_DateTime) + sizeof(Int32);
 
 
-	serverProtocolVersion = connection->transportLayer.localConf.protocolVersion;
+	//ignore server nonce
+	serverNonce.Length = -1;
+	serverNonce.Data = NULL;
+
+	serverNonce.Length = connection->secureLayer.localNonce.Length;
+	serverNonce.Data = connection->secureLayer.localNonce.Data;
 
 
-	//fill toke structure with default server information
+	//fill token structure with default server information
 	securityToken.secureChannelId = connection->secureLayer.securityToken.secureChannelId;
 	securityToken.secureChannelId = connection->secureLayer.securityToken.secureChannelId;
 	securityToken.tokenId = connection->secureLayer.securityToken.tokenId;
 	securityToken.tokenId = connection->secureLayer.securityToken.tokenId;
-	securityToken.createdAt = opcua_getTime();
+	securityToken.createdAt = opcua_time_now();
 	securityToken.revisedLifetime = connection->secureLayer.securityToken.revisedLifetime;
 	securityToken.revisedLifetime = connection->secureLayer.securityToken.revisedLifetime;
 
 
-	// server nonce
-	serverNonce.Length = -1;
+	serverProtocolVersion = connection->transportLayer.localConf.protocolVersion;
 
 
-	//calculate the size
-	sizeRespHeader = responseHeader_calcSize(&responseHeader);
 	//                ProtocolVersion + SecurityToken + Nonce
 	//                ProtocolVersion + SecurityToken + Nonce
-	sizeRespMessage = sizeof(Int32) + sizeSecurityToken + UAByteString_calcSize(&serverNonce);
+	sizeRespMessage = sizeof(UInt32) + serverNonce.Length + sizeof(Int32) + sizeSecurityToken;
+	printf("SL_openSecureChannel - size of response message=%d\n",sizeRespMessage);
+
 
 
 	//get memory for response
 	//get memory for response
-	response.Length = nodeId_calcSize(&responseType) + sizeRespHeader + sizeRespMessage;
-	response.Data = (char*) opcua_malloc(response.Length);
+	sizeResponseType = nodeId_calcSize(&responseType);
+
+	response.Length = sizeResponseType + sizeRespHeader + sizeRespMessage;
 
 
+	//get memory for response
+	response.Data = (char*)opcua_malloc(nodeId_calcSize(&responseType) + sizeRespHeader + sizeRespMessage);
+	pos = 0;
 	//encode responseType (NodeId)
 	//encode responseType (NodeId)
-	encoder_encodeBuiltInDatatype(&responseType,NODE_ID,&pos,response.Data);
+	UA_NodeId_printf("SL_openSecureChannel - TypeId =",&responseType);
+	encoder_encodeBuiltInDatatype(&responseType, NODE_ID, &pos, response.Data);
+
 	//encode header
 	//encode header
-	encodeResponseHeader(&responseHeader,&pos, &response);
+	printf("SL_openSecureChannel - encoding response header \n");
+
+	encodeResponseHeader(&responseHeader, &pos, &response);
+	printf("SL_openSecureChannel - response header encoded \n");
+
 	//encode message
 	//encode message
+	printf("SL_openSecureChannel - serverProtocolVersion = %d \n",serverProtocolVersion);
 	encoder_encodeBuiltInDatatype(&serverProtocolVersion, UINT32, &pos,response.Data);
 	encoder_encodeBuiltInDatatype(&serverProtocolVersion, UINT32, &pos,response.Data);
-	encoder_encodeBuiltInDatatype(&securityToken.secureChannelId, UINT32, &pos,response.Data);
-	encoder_encodeBuiltInDatatype(&securityToken.tokenId, INT32, &pos,response.Data);
-	encoder_encodeBuiltInDatatype(&securityToken.createdAt, DATE_TIME, &pos,response.Data);
-	encoder_encodeBuiltInDatatype(&securityToken.revisedLifetime, INT32, &pos,response.Data);
+	printf("SL_openSecureChannel - secureChannelId = %d \n",securityToken.secureChannelId);
+	encoder_encodeBuiltInDatatype(&(securityToken.secureChannelId), UINT32, &pos,response.Data);
+	printf("SL_openSecureChannel - tokenId = %d \n",securityToken.tokenId);
+	encoder_encodeBuiltInDatatype(&(securityToken.tokenId), INT32, &pos,response.Data);
+
+	encoder_encodeBuiltInDatatype(&(securityToken.createdAt), DATE_TIME, &pos,response.Data);
+	printf("SL_openSecureChannel - revisedLifetime = %d \n",securityToken.revisedLifetime);
+	encoder_encodeBuiltInDatatype(&(securityToken.revisedLifetime), INT32, &pos,response.Data);
+
 	encoder_encodeBuiltInDatatype(&serverNonce, BYTE_STRING, &pos,response.Data);
 	encoder_encodeBuiltInDatatype(&serverNonce, BYTE_STRING, &pos,response.Data);
 
 
+	printf("SL_openSecureChannel - response.Length = %d \n",response.Length);
 	//449 = openSecureChannelResponse
 	//449 = openSecureChannelResponse
-	UA_ByteString_printx("SL_processMessage - response=", &response);
-	SL_send(connection,response,449);
+	SL_send(connection, response, 449);
 
 
 	return UA_NO_ERROR;
 	return UA_NO_ERROR;
 }
 }
+/*
+Int32 SL_openSecureChannel_responseMessage_calcSize(SL_Response *response,
+		Int32* sizeInOut) {
+	Int32 length = 0;
+	length += sizeof(response->SecurityToken);
+	length += UAString_calcSize(response->ServerNonce);
+	length += sizeof(response->ServerProtocolVersion);
+	return length;
+}
+*/
 /*
 /*
  * closes a secureChannel (server side)
  * closes a secureChannel (server side)
  */
  */
@@ -148,11 +319,16 @@ Int32 SL_processMessage(UA_connection *connection, UA_ByteString message) {
 	UA_DiagnosticInfo serviceDiagnostics;
 	UA_DiagnosticInfo serviceDiagnostics;
 
 
 	Int32 pos = 0;
 	Int32 pos = 0;
-	// Every Message starts with a NodeID which names the serviceRequestType
+	UA_AD_RequestHeader requestHeader;
+	UInt32 clientProtocolVersion;
 	UA_NodeId serviceRequestType;
 	UA_NodeId serviceRequestType;
+	Int32 requestType;
+	Int32 securityMode;
+	Int32 requestedLifetime;
+	UA_ByteString clientNonce;
+	UA_StatusCode serviceResult;
 
 
-
-
+	// Every Message starts with a NodeID which names the serviceRequestType
 	decoder_decodeBuiltInDatatype(message.Data, NODE_ID, &pos,
 	decoder_decodeBuiltInDatatype(message.Data, NODE_ID, &pos,
 			&serviceRequestType);
 			&serviceRequestType);
 	UA_NodeId_printf("SL_processMessage - serviceRequestType=",
 	UA_NodeId_printf("SL_processMessage - serviceRequestType=",
@@ -232,6 +408,8 @@ Int32 SL_processMessage(UA_connection *connection, UA_ByteString message) {
 		printf("SL_processMessage - securityMode=%d\n", securityMode);
 		printf("SL_processMessage - securityMode=%d\n", securityMode);
 		switch (securityMode) {
 		switch (securityMode) {
 		case securityMode_INVALID:
 		case securityMode_INVALID:
+			connection->secureLayer.remoteNonce.Data = NULL;
+			connection->secureLayer.remoteNonce.Length = 0;
 			printf("SL_processMessage - client demands no security \n");
 			printf("SL_processMessage - client demands no security \n");
 			break;
 			break;
 
 
@@ -258,11 +436,12 @@ Int32 SL_processMessage(UA_connection *connection, UA_ByteString message) {
 		//TODO process requestedLifetime
 		//TODO process requestedLifetime
 
 
 		// 62541-4 §7.27 "The requestHandle given by the Client to the request."
 		// 62541-4 §7.27 "The requestHandle given by the Client to the request."
-		return SL_openSecureChannel(connection, requestHeader.requestHandle, SC_Good, &serviceDiagnostics);
+		return SL_openSecureChannel(connection, &requestHeader, SC_Good);
 	} else {
 	} else {
 		printf("SL_processMessage - unknown service request");
 		printf("SL_processMessage - unknown service request");
 		//TODO change error code
 		//TODO change error code
 		return UA_ERROR;
 		return UA_ERROR;
+
 	}
 	}
 	return UA_NO_ERROR;
 	return UA_NO_ERROR;
 }
 }
@@ -304,7 +483,7 @@ void SL_receive(UA_connection *connection, UA_ByteString *serviceMessage) {
 			if (SCM_Header.SecureChannelId != 0) {
 			if (SCM_Header.SecureChannelId != 0) {
 
 
 				iTmp = UA_ByteString_compare(
 				iTmp = UA_ByteString_compare(
-						&(connection->secureLayer.SenderCertificate),
+						&(connection->secureLayer.remoteAsymAlgSettings.SenderCertificate),
 						&(AAS_Header.SenderCertificate));
 						&(AAS_Header.SenderCertificate));
 				if (iTmp != UA_EQUAL) {
 				if (iTmp != UA_EQUAL) {
 					printf("SL_receive - UA_ERROR_BadSecureChannelUnknown \n");
 					printf("SL_receive - UA_ERROR_BadSecureChannelUnknown \n");
@@ -312,6 +491,10 @@ void SL_receive(UA_connection *connection, UA_ByteString *serviceMessage) {
 				}
 				}
 
 
 			}
 			}
+			else
+			{
+				//TODO invalid securechannelId
+			}
 
 
 			decodeSequenceHeader(&secureChannelPacket, &pos, &SequenceHeader);
 			decodeSequenceHeader(&secureChannelPacket, &pos, &SequenceHeader);
 			printf("SL_receive - SequenceHeader.RequestId=%d\n",
 			printf("SL_receive - SequenceHeader.RequestId=%d\n",
@@ -431,6 +614,7 @@ Int32 decodeSCMHeader(UA_ByteString *rawMessage, Int32 *pos,
 	return UA_NO_ERROR;
 	return UA_NO_ERROR;
 
 
 }
 }
+/*
 Int32 encodeSCMHeader(SL_SecureConversationMessageHeader *SC_Header, Int32 *pos,
 Int32 encodeSCMHeader(SL_SecureConversationMessageHeader *SC_Header, Int32 *pos,
 		AD_RawMessage *rawMessage) {
 		AD_RawMessage *rawMessage) {
 	const char *type = "ERR";
 	const char *type = "ERR";
@@ -461,8 +645,11 @@ Int32 encodeSCMHeader(SL_SecureConversationMessageHeader *SC_Header, Int32 *pos,
 
 
 	return UA_NO_ERROR;
 	return UA_NO_ERROR;
 }
 }
+*/
+
 Int32 decodeSequenceHeader(UA_ByteString *rawMessage, Int32 *pos,
 Int32 decodeSequenceHeader(UA_ByteString *rawMessage, Int32 *pos,
 		SL_SequenceHeader *SequenceHeader) {
 		SL_SequenceHeader *SequenceHeader) {
+	decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->SequenceNumber));
 	decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->RequestId));
 	decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->RequestId));
 	decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->SequenceNumber));
 	decodeUInt32(rawMessage->Data, pos, &(SequenceHeader->SequenceNumber));
 	return UA_NO_ERROR;
 	return UA_NO_ERROR;

+ 16 - 1
src/opcua_secureChannelLayer.h

@@ -13,7 +13,7 @@
 #include "opcua_connectionHelper.h"
 #include "opcua_connectionHelper.h"
 
 
 static const Int32 SL_HEADER_LENGTH = 0;
 static const Int32 SL_HEADER_LENGTH = 0;
-
+#define TOKEN_LIFETIME 30000
 typedef enum
 typedef enum
 {
 {
 	securityToken_ISSUE = 0,
 	securityToken_ISSUE = 0,
@@ -81,6 +81,21 @@ typedef struct _SL_ResponseHeader
     UA_ExtensionObject additionalHeader;
     UA_ExtensionObject additionalHeader;
 }SL_ResponseHeader;
 }SL_ResponseHeader;
 */
 */
+
+/**
+ *
+ * @param connection
+ * @return
+ */
+Int32 SL_initConnectionObject(UA_connection *connection);
+
+/**
+ *
+ * @param connection
+ * @param response
+ * @param sizeInOut
+ * @return
+ */
 Int32 SL_openSecureChannel_responseMessage_get(UA_connection *connection,
 Int32 SL_openSecureChannel_responseMessage_get(UA_connection *connection,
 		SL_Response *response, Int32* sizeInOut);
 		SL_Response *response, Int32* sizeInOut);
 
 

+ 2 - 0
src/opcua_time.c

@@ -27,3 +27,5 @@ UA_DateTime opcua_getTime() {
 			* HUNDRED_NANOSEC_PER_SEC + tv.tv_usec * HUNDRED_NANOSEC_PER_USEC;
 			* HUNDRED_NANOSEC_PER_SEC + tv.tv_usec * HUNDRED_NANOSEC_PER_USEC;
 	return dateTime;
 	return dateTime;
 }
 }
+
+

+ 2 - 2
src/opcua_time.h

@@ -7,9 +7,9 @@
 
 
 #ifndef OPCUA_TIME_H_
 #ifndef OPCUA_TIME_H_
 #define OPCUA_TIME_H_
 #define OPCUA_TIME_H_
+#include <time.h>
 
 
-
+UA_DateTime opcua_time_now();
 
 
 #endif /* OPCUA_TIME_H_ */
 #endif /* OPCUA_TIME_H_ */
 
 
-UA_DateTime opcua_getTime();

+ 29 - 2
tests/check_stack.c

@@ -33,6 +33,29 @@ START_TEST(test_getPacketType_validParameter)
 }
 }
 END_TEST
 END_TEST
 
 
+
+START_TEST(decodeByte_test)
+{
+	AD_RawMessage rawMessage;
+	Int32 position = 0;
+	//EncodeByte
+		char *mem = malloc(sizeof(Byte));
+		UInt16 Ui16Val;
+
+		rawMessage.message = mem;
+		rawMessage.length = 1;
+		mem[0] = 0x08;
+
+		position = 0;
+
+		decoder_decodeBuiltInDatatype(rawMessage.message, BYTE, &position, &Ui16Val);
+
+		ck_assert_int_eq(Ui16Val, 0x08);
+		ck_assert_int_eq(position, 1);
+		free(mem);
+}
+END_TEST
+
 START_TEST(encodeByte_test)
 START_TEST(encodeByte_test)
 {
 {
 	AD_RawMessage rawMessage;
 	AD_RawMessage rawMessage;
@@ -461,8 +484,10 @@ START_TEST(diagnosticInfo_calcSize_test)
 	diagnosticInfo.AdditionalInfo.Data = "OPCUA";
 	diagnosticInfo.AdditionalInfo.Data = "OPCUA";
 	diagnosticInfo.AdditionalInfo.Length = 5;
 	diagnosticInfo.AdditionalInfo.Length = 5;
 
 
-	ck_assert_int_eq(diagnosticInfo_calcSize(&diagnosticInfo),26);
-	ck_assert_int_eq(diagnosticInfo_calcSize(&the_empty_UA_DiagnosticInfo),1);
+	valcalc = diagnosticInfo_calcSize(&diagnosticInfo);
+	valreal = 26;
+	ck_assert_int_eq(valcalc,valreal);
+
 }
 }
 END_TEST
 END_TEST
 
 
@@ -1039,3 +1064,5 @@ int main (void)
 	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
 
 
 }
 }
+
+