Browse Source

bugfix arrays of structured types

Leon Urbas 11 years ago
parent
commit
fffaf881aa

+ 2 - 0
include/opcua_basictypes.h

@@ -183,6 +183,7 @@ typedef struct T_UA_String
 UA_String;
 UA_TYPE_METHOD_PROTOTYPES (UA_String)
 UA_Int32 UA_String_copy(UA_String const * src, UA_String* dst);
+UA_Int32 UA_String_copycstring(char const * src, UA_String* dst);
 UA_Int32 UA_String_compare(UA_String *string1, UA_String *string2);
 void UA_String_printf(char* label, UA_String* string);
 void UA_String_printx(char* label, UA_String* string);
@@ -209,6 +210,7 @@ typedef struct T_UA_LocalizedText
 }
 UA_LocalizedText;
 UA_TYPE_METHOD_PROTOTYPES (UA_LocalizedText)
+UA_Int32 UA_LocalizedText_copycstring(char const * src, UA_LocalizedText* dst);
 void UA_ByteString_printf(char* label, UA_ByteString* string);
 void UA_ByteString_printx(char* label, UA_ByteString* string);
 void UA_ByteString_printx_hex(char* label, UA_ByteString* string);

+ 7 - 17
src/UA_connection.h

@@ -8,6 +8,7 @@
 #ifndef OPCUA_CONNECTIONHELPER_H_
 #define OPCUA_CONNECTIONHELPER_H_
 #include "opcua.h"
+#include "UA_stackInternalTypes.h"
 
 enum UA_MessageType
 {
@@ -29,7 +30,7 @@ enum connectionState
 typedef struct
 {
 	UA_UInt32 secureChannelId;
-	UA_UInt32 tokenId;
+	UA_SymmetricAlgorithmSecurityHeader tokenId;
 	UA_DateTime createdAt;
 	UA_Int32 revisedLifetime;
 }SL_ChannelSecurityToken;
@@ -51,33 +52,22 @@ struct TL_connection
 	TL_buffer localConf;
 	UA_String endpointURL;
 };
-typedef struct
-{
-	UA_ByteString SecurityPolicyUri;
-	UA_ByteString SenderCertificate;
-	UA_ByteString ReceiverCertificateThumbprint;
-
-}AsymmetricAlgSecuritySettings;
-
 
 
 struct SL_connection
 {
-	AsymmetricAlgSecuritySettings remoteAsymAlgSettings;
-	AsymmetricAlgSecuritySettings localAsymAlgSettings;
-/*
-	UA_ByteString SecurityPolicyUri;
-	UA_ByteString SenderCertificate;
-	UA_ByteString ReceiverCertificateThumbprint;
-*/
+	UA_AsymmetricAlgorithmSecurityHeader remoteAsymAlgSettings;
+	UA_AsymmetricAlgorithmSecurityHeader localAsymAlgSettings;
+
 	UA_UInt32 sequenceNumber;
 	UA_UInt32 requestType;
 	UA_String secureChannelId;
-	//UInt32 UInt32_secureChannelId;
+
 	UA_UInt32 securityMode;
 	UA_ByteString remoteNonce;
 	UA_ByteString localNonce;
 	UA_UInt32 connectionState;
+
 	SL_ChannelSecurityToken securityToken;
 	UA_UInt32 requestId; // request Id of the current request
 };

+ 11 - 30
src/UA_stackInternalTypes.c

@@ -37,7 +37,7 @@ UA_Int32 UA_MessageType_decode(UA_Byte const * src, UA_Int32* pos, UA_MessageTyp
 }
 UA_TYPE_METHOD_DELETE_FREE(UA_MessageType)
 UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_MessageType)
-UA_Int32 UA_MessageType_printf(char *label, UA_MessageType* p) {
+void UA_MessageType_printf(char *label, UA_MessageType* p) {
 	UA_Byte* b = (UA_Byte*) p;
 	printf("%s{%c%c%c}\n", label, b[2],b[1],b[0]);
 }
@@ -208,7 +208,6 @@ UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_calcSize(UA_AsymmetricAlgorithmSec
 	 + UA_ByteString_calcSize(&(ptr->securityPolicyUri))
 	 + UA_ByteString_calcSize(&(ptr->senderCertificate))
 	 + UA_ByteString_calcSize(&(ptr->receiverCertificateThumbprint))
-	 // + sizeof(UA_UInt32) // requestId
 	;
 }
 
@@ -217,7 +216,6 @@ UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_encode(UA_AsymmetricAlgorithmSecur
 	retval |= UA_ByteString_encode(&(src->securityPolicyUri),pos,dst);
 	retval |= UA_ByteString_encode(&(src->senderCertificate),pos,dst);
 	retval |= UA_ByteString_encode(&(src->receiverCertificateThumbprint),pos,dst);
-	// retval |= UA_UInt32_encode(&(src->requestId),pos,dst);
 	return retval;
 }
 
@@ -226,7 +224,6 @@ UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_decode(UA_Byte const * src, UA_Int
 	retval |= UA_ByteString_decode(src,pos,&(dst->securityPolicyUri));
 	retval |= UA_ByteString_decode(src,pos,&(dst->senderCertificate));
 	retval |= UA_ByteString_decode(src,pos,&(dst->receiverCertificateThumbprint));
-	// retval |= UA_UInt32_decode(src,pos,&(dst->requestId));
 	return retval;
 }
 
@@ -243,36 +240,20 @@ UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorit
 	retval |= UA_ByteString_deleteMembers(&(p->receiverCertificateThumbprint));
 	return retval;
 }
-
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_calcSize(UA_SymmetricAlgorithmSecurityHeader const * ptr) {
-	if(ptr==UA_NULL){return sizeof(UA_SymmetricAlgorithmSecurityHeader);}
-	return 0
-	 + sizeof(UA_UInt32) // tokenId
-	;
-}
-
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_encode(UA_SymmetricAlgorithmSecurityHeader const * src, UA_Int32* pos, UA_Byte* dst) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_encode(&(src->tokenId),pos,dst);
-	return retval;
-}
-
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_decode(UA_Byte const * src, UA_Int32* pos, UA_SymmetricAlgorithmSecurityHeader* dst) {
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_init(UA_AsymmetricAlgorithmSecurityHeader* p) {
 	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_UInt32_decode(src,pos,&(dst->tokenId));
+	if(p==UA_NULL) return UA_ERROR;
+	retval |= UA_ByteString_init(&(p->securityPolicyUri));
+	retval |= UA_ByteString_init(&(p->senderCertificate));
+	retval |= UA_ByteString_init(&(p->receiverCertificateThumbprint));
 	return retval;
 }
 
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_delete(UA_SymmetricAlgorithmSecurityHeader* p) {
-	UA_Int32 retval = UA_SUCCESS;
-	retval |= UA_SymmetricAlgorithmSecurityHeader_deleteMembers(p);
-	retval |= UA_free(p);
-	return retval;
-    }
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_deleteMembers(UA_SymmetricAlgorithmSecurityHeader* p) {
-	UA_Int32 retval = UA_SUCCESS;
-	return retval;
-}
+UA_TYPE_METHOD_DECODE_AS(UA_SymmetricAlgorithmSecurityHeader, UA_UInt32)
+UA_TYPE_METHOD_ENCODE_AS(UA_SymmetricAlgorithmSecurityHeader, UA_UInt32)
+UA_TYPE_METHOD_DELETE_AS(UA_SymmetricAlgorithmSecurityHeader, UA_UInt32)
+UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_SymmetricAlgorithmSecurityHeader, UA_UInt32)
+UA_TYPE_METHOD_CALCSIZE_AS(UA_SymmetricAlgorithmSecurityHeader, UA_UInt32)
 
 UA_Int32 UA_SequenceHeader_calcSize(UA_SequenceHeader const * ptr) {
 	if(ptr==UA_NULL){return sizeof(UA_SequenceHeader);}

+ 6 - 17
src/UA_stackInternalTypes.h

@@ -11,7 +11,6 @@
 
 #include "UA_config.h"
 #include "opcua.h"
-#include "UA_connection.h"
 
 
 static const UA_Int32 SL_HEADER_LENGTH = 0;
@@ -33,7 +32,7 @@ typedef enum
 typedef struct T_SL_Response
 {
 	UA_UInt32 serverProtocolVersion;
-	SL_ChannelSecurityToken securityToken;
+	UA_ChannelSecurityToken securityToken;
 	UA_String serverNonce;
 }UA_SL_Response;
 UA_TYPE_METHOD_PROTOTYPES(UA_SL_Response)
@@ -45,7 +44,7 @@ UA_Int32 UA_MessageType_encode(UA_MessageType const * src, UA_Int32* pos, UA_Byt
 UA_Int32 UA_MessageType_decode(UA_Byte const * src, UA_Int32* pos, UA_MessageType* dst);
 UA_Int32 UA_MessageType_delete(UA_MessageType* p);
 UA_Int32 UA_MessageType_deleteMembers(UA_MessageType* p);
-
+void UA_MessageType_printf(char *label, UA_MessageType* p);
 
 /*** UA_OPCUATcpMessageHeader ***/
 /* TCP Header */
@@ -109,24 +108,14 @@ typedef struct T_UA_AsymmetricAlgorithmSecurityHeader {
 	UA_ByteString securityPolicyUri;
 	UA_ByteString senderCertificate;
 	UA_ByteString receiverCertificateThumbprint;
-	// UA_UInt32 requestId;
 } UA_AsymmetricAlgorithmSecurityHeader;
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_calcSize(UA_AsymmetricAlgorithmSecurityHeader const * ptr);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_encode(UA_AsymmetricAlgorithmSecurityHeader const * src, UA_Int32* pos, UA_Byte* dst);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_decode(UA_Byte const * src, UA_Int32* pos, UA_AsymmetricAlgorithmSecurityHeader* dst);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_delete(UA_AsymmetricAlgorithmSecurityHeader* p);
-UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorithmSecurityHeader* p);
+UA_TYPE_METHOD_PROTOTYPES (UA_AsymmetricAlgorithmSecurityHeader)
+UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_init(UA_AsymmetricAlgorithmSecurityHeader* p);
 
 /*** UA_SymmetricAlgorithmSecurityHeader ***/
 /* Secure Layer Symmetric Algorithm Header */
-typedef struct T_UA_SymmetricAlgorithmSecurityHeader {
-	UA_UInt32 tokenId;
-} UA_SymmetricAlgorithmSecurityHeader;
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_calcSize(UA_SymmetricAlgorithmSecurityHeader const * ptr);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_encode(UA_SymmetricAlgorithmSecurityHeader const * src, UA_Int32* pos, UA_Byte* dst);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_decode(UA_Byte const * src, UA_Int32* pos, UA_SymmetricAlgorithmSecurityHeader* dst);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_delete(UA_SymmetricAlgorithmSecurityHeader* p);
-UA_Int32 UA_SymmetricAlgorithmSecurityHeader_deleteMembers(UA_SymmetricAlgorithmSecurityHeader* p);
+typedef UA_Int32 UA_SymmetricAlgorithmSecurityHeader;
+UA_TYPE_METHOD_PROTOTYPES(UA_SymmetricAlgorithmSecurityHeader)
 
 /*** UA_SequenceHeader ***/
 /* Secure Layer Sequence Header */

+ 24 - 2
src/opcua_basictypes.c

@@ -365,6 +365,19 @@ UA_Int32 UA_String_copy(UA_String const * src, UA_String* dst) {
 	}
 	return retval;
 }
+UA_Int32 UA_String_copycstring(char const * src, UA_String* dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	dst->length = strlen(src);
+	dst->data = UA_NULL;
+	if (dst->length > 0) {
+		retval |= UA_alloc((void**)&(dst->data), dst->length);
+		if (retval == UA_SUCCESS) {
+			retval |= UA_memcpy((void*)dst->data, src, dst->length);
+		}
+	}
+	return retval;
+}
+
 UA_String UA_String_null = { -1, UA_NULL };
 UA_Int32 UA_String_init(UA_String* p){
 	//FIXME: is UA_String_null now depricated?
@@ -392,11 +405,12 @@ UA_Int32 UA_String_compare(UA_String* string1, UA_String* string2) {
 	return retval;
 }
 void UA_String_printf(char* label, UA_String* string) {
-	printf("%s {Length=%d, Data=%s}\n", label, string->length,
-			(char*)string->data);
+	printf("%s {Length=%d, Data=%.*s}\n", label, string->length,
+			string->length, (char*)string->data);
 }
 void UA_String_printx(char* label, UA_String* string) {
 	int i;
+	if (string == UA_NULL) { printf("%s {NULL}\n", label); return; }
 	printf("%s {Length=%d, Data=", label, string->length);
 	if (string->length > 0) {
 		for (i = 0; i < string->length; i++) {
@@ -553,6 +567,14 @@ UA_Int32 UA_LocalizedText_init(UA_LocalizedText* p){
 	return UA_SUCCESS;
 }
 UA_TYPE_METHOD_NEW_DEFAULT(UA_LocalizedText)
+UA_Int32 UA_LocalizedText_copycstring(char const * src, UA_LocalizedText* dst) {
+	UA_Int32 retval = UA_SUCCESS;
+	if(dst==UA_NULL)return UA_ERROR;
+	dst->encodingMask = 0x03;
+	retval |= UA_String_copycstring("EN",&(dst->locale));
+	retval |= UA_String_copycstring(src,&(dst->text));
+	return retval;
+}
 
 /* Serialization of UA_NodeID is specified in 62541-6, §5.2.2.9 */
 UA_Int32 UA_NodeId_calcSize(UA_NodeId const *p) {

+ 137 - 132
src/opcua_secureLayer.c

@@ -8,6 +8,7 @@
 #include <memory.h> // memcpy
 #include "opcua_transportLayer.h"
 #include "opcua_secureLayer.h"
+#include "UA_stackInternalTypes.h"
 
 #define SIZE_SECURECHANNEL_HEADER 12
 #define SIZE_SEQHEADER_HEADER 8
@@ -18,12 +19,8 @@
  */
 UA_Int32 SL_initConnectionObject(UA_connection *connection)
 {
-
-	//TODO: fill with valid information
-	UA_ByteString_init(&(connection->secureLayer.localAsymAlgSettings.ReceiverCertificateThumbprint));
-	UA_ByteString_copy(&UA_ByteString_securityPoliceNone, &(connection->secureLayer.localAsymAlgSettings.SecurityPolicyUri));
-	UA_ByteString_init(&(connection->secureLayer.localAsymAlgSettings.SenderCertificate));
-	UA_ByteString_init(&(connection->secureLayer.remoteNonce));
+	UA_AsymmetricAlgorithmSecurityHeader_init(&(connection->secureLayer.localAsymAlgSettings));
+	UA_ByteString_copy(&UA_ByteString_securityPoliceNone, &(connection->secureLayer.localAsymAlgSettings.securityPolicyUri));
 
 	UA_alloc((void**)&(connection->secureLayer.localNonce.data),sizeof(UA_Byte));
 	connection->secureLayer.localNonce.length = 1;
@@ -51,67 +48,58 @@ UA_Int32 SL_send(UA_connection* connection, UA_ByteString const * responseMessag
 	UA_UInt32 sequenceNumber;
 	UA_UInt32 requestId;
 	UA_Int32 pos;
-	UA_Int32 sizeAsymAlgHeader;
 	UA_ByteString responsePacket;
 	UA_Int32 packetSize;
 	UA_Int32 sizePadding;
 	UA_Int32 sizeSignature;
 
+	// FIXME: this is a to dump method to determine asymmetric algorithm setting
+	UA_Int32 isAsym = (type == 449);
+
 
-	sizeAsymAlgHeader = 3 * sizeof(UA_UInt32) +
-			connection->secureLayer.localAsymAlgSettings.SecurityPolicyUri.length +
-			connection->secureLayer.localAsymAlgSettings.SenderCertificate.length +
-			connection->secureLayer.localAsymAlgSettings.ReceiverCertificateThumbprint.length;
 	pos = 0;
 	//sequence header
 	sequenceNumber = connection->secureLayer.sequenceNumber;
     requestId = connection->secureLayer.requestId;
 
+    sizePadding = 0;
+	sizeSignature = 0;
 
-	if(type == 449) //openSecureChannelResponse -> asymmetric algorithm
-	{
-		//TODO fill with valid sizes
-		sizePadding = 0;
-		sizeSignature = 0;
-
-		//TODO: size calculation need
-		packetSize = SIZE_SECURECHANNEL_HEADER +
+	packetSize = SIZE_SECURECHANNEL_HEADER +
 				SIZE_SEQHEADER_HEADER +
-				sizeAsymAlgHeader +
+				( isAsym ? UA_AsymmetricAlgorithmSecurityHeader_calcSize(&(connection->secureLayer.localAsymAlgSettings)) : UA_SymmetricAlgorithmSecurityHeader_calcSize(&(connection->secureLayer.securityToken.tokenId)) )+
 				responseMessage->length +
 				sizePadding +
-				sizeSignature +
-		// FIXME: Leon misses two bytes here
-				2;
+				sizeSignature;
 
-		//get memory for response
-		UA_alloc((void**)&(responsePacket.data),packetSize);
-
-		responsePacket.length = packetSize;
+	//get memory for response
+	UA_alloc((void**)&(responsePacket.data),packetSize);
+	responsePacket.length = packetSize;
 
-		/*---encode Secure Conversation Message Header ---*/
+	/*---encode Secure Conversation Message Header ---*/
+	if (isAsym) {
 		//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;
-		UA_Int32_encode(&packetSize,&pos,responsePacket.data);
-		UA_UInt32_encode(&(connection->secureLayer.securityToken.secureChannelId),&pos,responsePacket.data);
-
-		/*---encode Asymmetric Algorithm Header ---*/
-		UA_ByteString_encode(&(connection->secureLayer.localAsymAlgSettings.SecurityPolicyUri),
-						&pos,responsePacket.data);
-		UA_ByteString_encode(&(connection->secureLayer.localAsymAlgSettings.SenderCertificate),
-						&pos,responsePacket.data );
-		UA_ByteString_encode(&(connection->secureLayer.localAsymAlgSettings.ReceiverCertificateThumbprint),
-						&pos,responsePacket.data );
+	} else {
+		//encode MessageType - MSG message
+		responsePacket.data[0] = 'M';
+		responsePacket.data[1] = 'S';
+		responsePacket.data[2] = 'G';
+	}
+	pos += 3;
+	responsePacket.data[3] = 'F';
+	pos += 1;
+	UA_Int32_encode(&packetSize,&pos,responsePacket.data);
+	UA_UInt32_encode(&(connection->secureLayer.securityToken.secureChannelId),&pos,responsePacket.data);
+
+	/*---encode Algorithm Security Header ---*/
+	if (isAsym)	{
+		UA_AsymmetricAlgorithmSecurityHeader_encode(&(connection->secureLayer.localAsymAlgSettings),&pos,responsePacket.data);
+	} else {
+		UA_SymmetricAlgorithmSecurityHeader_encode(&(connection->secureLayer.securityToken.tokenId),&pos,responsePacket.data);
 	}
-
-
-
 
 	/*---encode Sequence Header ---*/
 	UA_UInt32_encode(&sequenceNumber,&pos,responsePacket.data);
@@ -122,13 +110,11 @@ UA_Int32 SL_send(UA_connection* connection, UA_ByteString const * responseMessag
 
 	/* sign Data*/
 
-	/* encrypt Data */
+	/* encrypt Data*/
 
 	/* send Data */
 	TL_send(connection,&responsePacket);
-	// do not delete here, memory still needed for actual writing  in top-level procedure
-	// UA_ByteString_deleteMembers(&responsePacket);
-
+	// responsePackage will be deleted by top-level procedure
 	return UA_NO_ERROR;
 }
 
@@ -278,16 +264,6 @@ UA_Int32 SL_openSecureChannel(UA_connection *connection,
 
 	return UA_SUCCESS;
 }
-/*
-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)
  */
@@ -386,7 +362,7 @@ UA_Int32 SL_processMessage(UA_connection *connection, UA_ByteString message) {
 		switch (securityMode) {
 		case UA_SECURITYMODE_INVALID:
 			connection->secureLayer.remoteNonce.data = NULL;
-			connection->secureLayer.remoteNonce.length = 0;
+			connection->secureLayer.remoteNonce.length = -1;
 			printf("SL_processMessage - client demands no security \n");
 			break;
 
@@ -419,10 +395,84 @@ UA_Int32 SL_processMessage(UA_connection *connection, UA_ByteString message) {
 		retval = SL_openSecureChannel(connection, &requestHeader, SC_Good);
 		UA_RequestHeader_deleteMembers(&requestHeader);
 	} else {
-		printf("SL_processMessage - unknown service request");
-		//TODO change error code
-		retval = UA_ERROR;
-
+		if (serviceRequestType.namespace == 0) {
+			// FIXME: quick hack
+			switch (serviceRequestType.identifier.numeric) {
+			case 428:
+				serviceRequestType.identifier.numeric = 426;
+				break;
+			}
+			UA_Int32 namespace_index = UA_toIndex(serviceRequestType.identifier.numeric);
+			if (namespace_index == -1) {
+				printf("SL_processMessage - unknown request, namespace=%d, request=%d\n", serviceRequestType.namespace, serviceRequestType.identifier.numeric);
+				retval = UA_ERROR;
+			} else {
+				void * obj;
+				UA_alloc(&obj,UA_[namespace_index].calcSize(UA_NULL));
+				UA_[namespace_index].decode(message.data,&pos,obj);
+
+				// FXIME: we need a more clever response/request architecture
+				if (serviceRequestType.identifier.numeric  == 426 ) {
+					UA_GetEndpointsRequest *p = (UA_GetEndpointsRequest*) obj;
+					UA_GetEndpointsResponse *r;
+					UA_NodeId responseType;
+
+					UA_String_printx("endpointUrl=",&(p->endpointUrl));
+					UA_GetEndpointsResponse_new(&r);
+					UA_ResponseHeader_new(&(r->responseHeader));
+					r->responseHeader->requestHandle = p->requestHeader->requestHandle;
+					r->responseHeader->serviceResult = SC_Good;
+					r->responseHeader->stringTableSize = 0;
+					r->responseHeader->timestamp = UA_DateTime_now();
+					UA_DiagnosticInfo_new(&(r->responseHeader->serviceDiagnostics));
+					UA_ExtensionObject_new(&(r->responseHeader->additionalHeader));
+
+					// TODO: Arrays need to be redesigned, this is crap
+					r->endpointsSize = 1;
+					UA_alloc((void**) &(r->endpoints), sizeof(void*));
+					UA_EndpointDescription *epd;
+					UA_EndpointDescription_new(&epd);
+					*(r->endpoints) = epd;
+
+					// FIXME: this memory gets lost
+					UA_String_copycstring("http://localhost:16664/",&(r->endpoints[0]->endpointUrl));
+					// FIXME: this memory gets lost
+					UA_ApplicationDescription_new(&(r->endpoints[0]->server));
+					// FIXME: This should be a feature of the application
+					UA_String_copycstring("open62541.com/applications/4711",&(r->endpoints[0]->server->applicationUri));
+					UA_String_copycstring("open62541.com/product/release",&(r->endpoints[0]->server->productUri));
+					// FIXME: This should be a feature of the application
+					UA_LocalizedText_copycstring("The open62541 application",&(r->endpoints[0]->server->applicationName));
+					// FIXME: This should be a feature of the application and an enum
+					r->endpoints[0]->server->applicationType = 0; // Server
+					// all the other strings are empty by initialization
+
+					// Now let's build the response
+					UA_ByteString response;
+					responseType.encodingByte = UA_NODEIDTYPE_FOURBYTE;
+					responseType.namespace = 0;
+					responseType.identifier.numeric = 431;
+
+					response.length = UA_NodeId_calcSize(&responseType) + UA_GetEndpointsResponse_calcSize(r);
+					UA_alloc((void**)&(response.data), response.length);
+					pos = 0;
+
+					UA_NodeId_encode(&responseType, &pos, response.data);
+					UA_GetEndpointsResponse_encode(r, &pos, response.data);
+
+					SL_send(connection, &response, 431);
+
+					UA_ByteString_deleteMembers(&response);
+					UA_GetEndpointsResponse_delete(r);
+					UA_GetEndpointsRequest_delete(p);
+
+					return UA_SUCCESS;
+				}
+			}
+		} else {
+			printf("SL_processMessage - unknown request, namespace=%d, request=%d\n", serviceRequestType.namespace, serviceRequestType.identifier.numeric);
+			retval = UA_ERROR;
+		}
 	}
 	return retval;
 }
@@ -454,6 +504,7 @@ void SL_receive(UA_connection *connection, UA_ByteString *serviceMessage) {
 		switch (secureConvHeader.tcpMessageHeader->messageType) {
 
 		case UA_MESSAGETYPE_OPN: /* openSecureChannel Message received */
+			printf("SL_receive - process OPN\n");
 			UA_AsymmetricAlgorithmSecurityHeader_decode(secureChannelPacket.data, &pos, &asymAlgSecHeader);
 			UA_ByteString_printf("SL_receive - AAS_Header.ReceiverThumbprint=",
 					&(asymAlgSecHeader.receiverCertificateThumbprint));
@@ -463,7 +514,7 @@ void SL_receive(UA_connection *connection, UA_ByteString *serviceMessage) {
 					&(asymAlgSecHeader.senderCertificate));
 			if (secureConvHeader.secureChannelId != 0) {
 				iTmp = UA_ByteString_compare(
-						&(connection->secureLayer.remoteAsymAlgSettings.SenderCertificate),
+						&(connection->secureLayer.remoteAsymAlgSettings.senderCertificate),
 						&(asymAlgSecHeader.senderCertificate));
 				if (iTmp != UA_EQUAL) {
 					printf("SL_receive - UA_ERROR_BadSecureChannelUnknown \n");
@@ -486,7 +537,6 @@ void SL_receive(UA_connection *connection, UA_ByteString *serviceMessage) {
 			connection->secureLayer.sequenceNumber =
 					sequenceHeader.sequenceNumber;
 
-			//SL_decrypt(&secureChannelPacket);
 			message.data = &secureChannelPacket.data[pos];
 			message.length = secureChannelPacket.length - pos;
 			UA_ByteString_printx("SL_receive - message=",&message);
@@ -497,21 +547,35 @@ void SL_receive(UA_connection *connection, UA_ByteString *serviceMessage) {
 
 			break;
 		case UA_MESSAGETYPE_MSG: /* secure Channel Message received */
-			UA_ByteString_printx("SL_receive - MSG, msg=", serviceMessage);
-			if (connection->secureLayer.connectionState
-					== connectionState_ESTABLISHED) {
-
+			printf("SL_receive - process MSG\n");
+// FIXME: check connection state
+//			if (connection->secureLayer.connectionState
+//					== connectionState_ESTABLISHED) {
 				if (secureConvHeader.secureChannelId
 						== connection->secureLayer.securityToken.secureChannelId) {
-
+					UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
+
+					//FIXME: we assume SAS, need to check if AAS or SAS
+					UA_SymmetricAlgorithmSecurityHeader_decode(secureChannelPacket.data, &pos, &symAlgSecHeader);
+
+					// decode sequenceHeader and remember
+					UA_SequenceHeader_decode(secureChannelPacket.data, &pos, &sequenceHeader);
+					printf("SL_receive - SequenceHeader.RequestId=%d\n",sequenceHeader.requestId);
+					printf("SL_receive - SequenceHeader.SequenceNr=%d\n",sequenceHeader.sequenceNumber);
+					connection->secureLayer.requestId = sequenceHeader.requestId;
+					connection->secureLayer.sequenceNumber = sequenceHeader.sequenceNumber;
+					// process message
+					message.data = &secureChannelPacket.data[pos];
+					message.length = secureChannelPacket.length - pos;
+					UA_ByteString_printx("SL_receive - message=",&message);
+					SL_processMessage(connection, message);
 				} else {
 					//TODO generate ERROR_Bad_SecureChannelUnkown
 				}
-			}
+//			} // check connection state
 
 			break;
 		case UA_MESSAGETYPE_CLO: /* closeSecureChannel Message received */
-			UA_ByteString_printx("SL_receive - CLO, msg=", serviceMessage);
 			if (SL_check(connection, secureChannelPacket) == UA_NO_ERROR) {
 
 			}
@@ -522,65 +586,6 @@ void SL_receive(UA_connection *connection, UA_ByteString *serviceMessage) {
 	} else {
 		printf("SL_receive - no data received \n");
 	}
-	/*
-	 Int32 readPosition = 0;
-
-	 //get the Secure Channel Message Header
-	 decodeSCMHeader(secureChannelPacket,
-	 &readPosition, &SCM_Header);
-
-	 //get the Secure Channel Asymmetric Algorithm Security Header
-	 decodeAASHeader(secureChannelPacket,
-	 &readPosition, &AAS_Header);
-
-	 //get the Sequence Header
-	 decodeSequenceHeader(secureChannelPacket,
-	 &readPosition, &SequenceHeader);
-
-	 //get Secure Channel Message
-	 //SL_secureChannel_Message_get(connection, secureChannelPacket,
-	 //			&readPosition,serviceMessage);
-
-	 if (secureChannelPacket->length > 0)
-	 {
-	 switch (SCM_Header.MessageType)
-	 {
-	 case packetType_MSG:
-	 if (connection->secureLayer.connectionState
-	 == connectionState_ESTABLISHED)
-	 {
-
-	 }
-	 else //receiving message, without secure channel
-	 {
-	 //TODO send back Error Message
-	 }
-	 break;
-	 case packetType_OPN:
-	 //Server Handling
-	 //		if (openSecureChannelHeader_check(connection, secureChannelPacket))
-	 //		{
-	 //check if the request is valid
-	 //	SL_openSecureChannelRequest_check(connection, secureChannelPacket);
-	 //		}
-	 //		else
-	 //		{
-	 //			//TODO send back Error Message
-	 //		}
-	 //Client Handling
-
-	 //TODO free memory for secureChannelPacket
-
-	 break;
-	 case packetType_CLO:
-
-
-	 //TODO free memory for secureChannelPacket
-	 break;
-	 }
-
-	 }
-	 */
 }
 
 

+ 1 - 1
src/opcua_transportLayer.c

@@ -83,7 +83,7 @@ UA_Int32 TL_receive(UA_connection *connection, UA_ByteString *packet)
 		case UA_MESSAGETYPE_HEL:
 		case UA_MESSAGETYPE_ACK:
 		{
-			printf("TL_receive - received HEL or ACK message\n");
+			puts("TL_receive - received HEL or ACK message");
 			TL_process(connection, tcpMessageHeader->messageType, &pos);
 			break;
 		}

+ 4 - 0
tool/generate_builtin.py

@@ -116,8 +116,12 @@ def createStructured(element):
             typename = stripTypename(child.get("TypeName"))
             if typename in structured_types:
                 valuemap[childname] = typename + "*"
+                if child.get("LengthField"):
+                    valuemap[childname] = typename + "**"
             elif typename in indefinite_types:
                 valuemap[childname] = typename + "*"
+                if child.get("LengthField"):
+                    valuemap[childname] = typename + "**"
             elif child.get("LengthField"):
                 valuemap[childname] = typename + "**"
             else:

+ 16 - 4
tool/generate_namespace.py

@@ -12,7 +12,7 @@ if len(sys.argv) != 3:
 
 # types that are to be excluded
 exclude_kind = set(["Object","ObjectType","Variable","Method","ReferenceType"])
-exclude_types = set(["Structure", "BaseDataType", "Number", 
+exclude_types = set(["Number", 
     "Integer", "UInteger", "Enumeration",
 	"Image", "ImageBMP", "ImageGIF", "ImageJPG", "ImagePNG",
 	"References", "BaseVariableType", "BaseDataVariableType", 
@@ -76,8 +76,14 @@ for row in rows1:
 
     if skipType(row[0]):
 	continue
-
-    name = "UA_" + row[0]
+	
+    if row[0] == "BaseDataType":
+    	name = "UA_Variant"
+    elif row[0] == "Structure":
+    	name = "UA_ExtensionObject" 
+    else:	
+	name = "UA_" + row[0]
+	
     print("\t"+name.upper()+"="+str(i)+",", file=fh)
     print('\tcase '+row[1]+': retval='+name.upper()+'; break; //'+row[2], file=fc)
     i = i+1
@@ -94,7 +100,13 @@ for row in rows2:
     if skipType(row[0]):
 	continue
 
-    name = "UA_" + row[0]
+    if row[0] == "BaseDataType":
+    	name = "UA_Variant"
+    elif row[0] == "Structure":
+    	name = "UA_ExtensionObject" 
+    else:	
+	name = "UA_" + row[0]
+
     print('#define '+name.upper()+'_NS0 (UA_['+name.upper()+'].Id)', file=fh)
 
     print("\t{" + row[1] + ", (UA_Int32(*)(void const*)) " + name + "_calcSize, (UA_Int32(*)(UA_Byte const*,UA_Int32*,void*)) " + name + "_decode, (UA_Int32(*)(void const*,UA_Int32*,UA_Byte*))" + name + "_encode},",end='\n',file=fc)