Quellcode durchsuchen

added structures for connection and secure channel handling

opcua vor 11 Jahren
Ursprung
Commit
7a7c859bde

+ 50 - 25
examples/src/networklayer.c

@@ -28,7 +28,7 @@ NL_Description NL_Description_TcpBinary  = {
 _Bool NL_ConnectionComparer(void *p1, void* p2) {
 	NL_Connection* c1 = (NL_Connection*) p1;
 	NL_Connection* c2 = (NL_Connection*) p2;
-	return (c1->connection.connectionHandle == c2->connection.connectionHandle);
+	return (c1->connectionHandle == c2->connectionHandle);
 }
 int NL_TCP_SetNonBlocking(int sock) {
 	int opts = fcntl(sock,F_GETFL);
@@ -45,20 +45,26 @@ int NL_TCP_SetNonBlocking(int sock) {
 }
 
 void NL_Connection_printf(void* payload) {
+  UA_UInt32 id;
   NL_Connection* c = (NL_Connection*) payload;
-  printf("ListElement connectionHandle = %d\n",c->connection.connectionHandle);
+  UA_TL_Connection_getId(c->connection,&id);
+  printf("ListElement connectionHandle = %d\n",id);
 }
 void NL_addHandleToSet(UA_Int32 handle, NL_data* nl) {
 	FD_SET(handle, &(nl->readerHandles));
 	nl->maxReaderHandle = (handle > nl->maxReaderHandle) ? handle : nl->maxReaderHandle;
 }
 void NL_setFdSet(void* payload) {
+  UA_UInt32 id;
   NL_Connection* c = (NL_Connection*) payload;
-  NL_addHandleToSet(c->connection.connectionHandle, c->networkLayer);
+  UA_TL_Connection_getId(c->connection,&id);
+  NL_addHandleToSet(id, c->networkLayer);
 }
 void NL_checkFdSet(void* payload) {
+	  UA_UInt32 id;
   NL_Connection* c = (NL_Connection*) payload;
-  if (FD_ISSET(c->connection.connectionHandle, &(c->networkLayer->readerHandles))) {
+  UA_TL_Connection_getId(c->connection,&id);
+  if (FD_ISSET(id, &(c->networkLayer->readerHandles))) {
 	  c->reader((void*)c);
   }
 }
@@ -108,31 +114,40 @@ UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), v
 void* NL_TCP_reader(NL_Connection *c) {
 
 	UA_ByteString readBuffer;
-	UA_alloc((void**)&(readBuffer.data),c->connection.localConf.recvBufferSize);
 
-	if (c->connection.connectionState != CONNECTIONSTATE_CLOSE) {
+	TL_Buffer localBuffers;
+	UA_UInt32 connectionId;
+	UA_TL_Connection_getLocalConfiguration(c->connection, &localBuffers);
+	UA_TL_Connection_getId(c->connection, &connectionId);
+	UA_alloc((void**)&(readBuffer.data),localBuffers.recvBufferSize);
+
+
+	if (c->state  != CONNECTIONSTATE_CLOSE) {
 		DBG_VERBOSE(printf("NL_TCP_reader - enter read\n"));
-		readBuffer.length = read(c->connection.connectionHandle, readBuffer.data, c->connection.localConf.recvBufferSize);
+		readBuffer.length = read(connectionId, readBuffer.data, localBuffers.recvBufferSize);
 		DBG_VERBOSE(printf("NL_TCP_reader - leave read\n"));
 
 		DBG_VERBOSE(printf("NL_TCP_reader - src={%*.s}, ",c->connection.remoteEndpointUrl.length,c->connection.remoteEndpointUrl.data));
 		DBG(UA_ByteString_printx("NL_TCP_reader - received=",&readBuffer));
 
 		if (readBuffer.length  > 0) {
-			TL_Process(&(c->connection),&readBuffer);
+
+			TL_Process((c->connection),&readBuffer);
 		} else {
-			c->connection.connectionState = CONNECTIONSTATE_CLOSE;
+//TODO close connection - what does close do?
+			c->state = CONNECTIONSTATE_CLOSE;
+			//c->connection.connectionState = CONNECTIONSTATE_CLOSE;
 			perror("ERROR reading from socket1");
 		}
 	}
 
-	if (c->connection.connectionState == CONNECTIONSTATE_CLOSE) {
+	if (c->state == CONNECTIONSTATE_CLOSE) {
 		DBG_VERBOSE(printf("NL_TCP_reader - enter shutdown\n"));
-		shutdown(c->connection.connectionHandle,2);
+		shutdown(connectionId,2);
 		DBG_VERBOSE(printf("NL_TCP_reader - enter close\n"));
-		close(c->connection.connectionHandle);
+		close(connectionId);
 		DBG_VERBOSE(printf("NL_TCP_reader - leave close\n"));
-		c->connection.connectionState = CONNECTIONSTATE_CLOSED;
+		c->state  = CONNECTIONSTATE_CLOSED;
 
 		UA_ByteString_deleteMembers(&readBuffer);
 
@@ -162,7 +177,7 @@ void* NL_TCP_readerThread(NL_Connection *c) {
 #endif
 
 /** write message provided in the gather buffers to a tcp transport layer connection */
-UA_Int32 NL_TCP_writer(struct TL_Connection_T const * c, UA_ByteString const * const * gather_buf, UA_UInt32 gather_len) {
+UA_Int32 NL_TCP_writer(UA_Int32 connectionHandle, UA_ByteString const * const * gather_buf, UA_UInt32 gather_len) {
 
 	struct iovec iov[gather_len];
 	UA_UInt32 total_len = 0;
@@ -188,7 +203,7 @@ UA_Int32 NL_TCP_writer(struct TL_Connection_T const * c, UA_ByteString const * c
 		int n=0;
 		do {
 			DBG_VERBOSE(printf("NL_TCP_writer - enter write with %d bytes to write\n",total_len));
-			n = sendmsg(c->connectionHandle, &message, 0);
+			n = sendmsg(connectionHandle, &message, 0);
 			DBG_VERBOSE(printf("NL_TCP_writer - leave write with n=%d,errno={%d,%s}\n",n,(n>0)?0:errno,(n>0)?"":strerror(errno)));
 		} while (n == -1L && errno == EINTR);
 		if (n >= 0) {
@@ -205,13 +220,23 @@ UA_Int32 NL_TCP_writer(struct TL_Connection_T const * c, UA_ByteString const * c
 
 void* NL_Connection_init(NL_Connection* c, NL_data* tld, UA_Int32 connectionHandle, NL_Reader reader, TL_Writer writer)
 {
+
+
+	UA_TL_Connection1 connection = UA_NULL;
+	//create new connection object
+	UA_TL_Connection_new(&connection, tld->tld->localConf,writer);
+	//add connection object to list, so stack is aware of its connections
+
+	UA_TL_ConnectionManager_addConnection(&connection);
+
 	// connection layer of UA stackwriteLock
-	c->connection.connectionHandle = connectionHandle;
-	c->connection.connectionState = CONNECTIONSTATE_CLOSED;
-	c->connection.writerCallback = writer;
-	memcpy(&(c->connection.localConf),&(tld->tld->localConf),sizeof(TL_Buffer));
-	memset(&(c->connection.remoteConf),0,sizeof(TL_Buffer));
-	UA_String_copy(&(tld->endpointUrl), &(c->connection.localEndpointUrl));
+
+	//c->connection.connectionHandle = connectionHandle;
+	//c->connection.connectionState = CONNECTIONSTATE_CLOSED;
+	//c->connection.writerCallback = writer;
+	//memcpy(&(c->connection.localConf),&(tld->tld->localConf),sizeof(TL_Buffer));
+	//memset(&(c->connection.remoteConf),0,sizeof(TL_Buffer));
+	//UA_String_copy(&(tld->endpointUrl), &(c->connection.localEndpointUrl));
 
 	// network layer
 	c->reader = reader;
@@ -227,7 +252,7 @@ void* NL_TCP_listen(NL_Connection* c) {
 	NL_data* tld = c->networkLayer;
 
 	DBG_VERBOSE(printf("NL_TCP_listen - enter listen\n"));
-	int retval = listen(c->connection.connectionHandle, tld->tld->maxConnections);
+	int retval = listen(c->connectionHandle, tld->tld->maxConnections);
 	DBG_VERBOSE(printf("NL_TCP_listen - leave listen, retval=%d\n",retval));
 
 	if (retval < 0) {
@@ -239,7 +264,7 @@ void* NL_TCP_listen(NL_Connection* c) {
 		struct sockaddr_in cli_addr;
 		socklen_t cli_len = sizeof(cli_addr);
 		DBG_VERBOSE(printf("NL_TCP_listen - enter accept\n"));
-		int newsockfd = accept(c->connection.connectionHandle, (struct sockaddr *) &cli_addr, &cli_len);
+		int newsockfd = accept(c->connectionHandle, (struct sockaddr *) &cli_addr, &cli_len);
 		DBG_VERBOSE(printf("NL_TCP_listen - leave accept\n"));
 		if (newsockfd < 0) {
 			DBG_ERR(printf("TL_TCP_listen - accept returns errno={%d,%s}\n",errno,strerror(errno)));
@@ -254,7 +279,7 @@ void* NL_TCP_listen(NL_Connection* c) {
 			pthread_create( &(cclient->readerThreadHandle), NULL, (void*(*)(void*)) NL_TCP_readerThread, (void*) cclient);
 #else
 			UA_list_addPayloadToBack(&(tld->connections),cclient);
-			NL_TCP_SetNonBlocking(cclient->connection.connectionHandle);
+			NL_TCP_SetNonBlocking(cclient->connectionHandle);
 #endif
 		}
 	} else {
@@ -317,7 +342,7 @@ UA_Int32 NL_TCP_init(NL_data* tld, UA_Int32 port) {
 		pthread_create( &(c->readerThreadHandle), NULL, (void*(*)(void*)) NL_TCP_listenThread, (void*) c);
 #else
 		UA_list_addPayloadToBack(&(tld->connections),c);
-		NL_TCP_SetNonBlocking(c->connection.connectionHandle);
+		NL_TCP_SetNonBlocking(c->connectionHandle);
 #endif
 	}
 	return retval;

+ 5 - 2
examples/src/networklayer.h

@@ -5,6 +5,7 @@
 #include "ua_transport.h"
 #include "ua_transport_binary.h"
 #include "ua_list.h"
+#include "ua_transport_connection_manager.h"
 
 #ifdef MULTITHREADING
 #include <pthread.h> // pthreadcreate, pthread_t
@@ -44,7 +45,9 @@ typedef struct T_NL_data {
 struct NL_Connection_T;
 typedef void* (*NL_Reader)(struct NL_Connection_T *c);
 typedef struct NL_Connection_T {
-	TL_Connection connection;
+	UA_TL_Connection1 connection;
+	UA_Int32 state;
+	UA_UInt32 connectionHandle;
 	NL_Reader reader;
 #ifdef MULTITHREADING
 	pthread_t readerThreadHandle;
@@ -54,6 +57,6 @@ typedef struct NL_Connection_T {
 
 NL_data* NL_init(NL_Description* tlDesc, UA_Int32 port);
 UA_Int32 NL_msgLoop(NL_data* nl, struct timeval* tv,UA_Int32 (*timeoutCallBack)(void*),void *arg);
-UA_Int32 NL_TCP_writer(struct TL_Connection_T const * c, UA_ByteString const * const * gather_buf, UA_UInt32 gather_len);
+UA_Int32 NL_TCP_writer(UA_Int32 connectionHandle, UA_ByteString const * const * gather_buf, UA_UInt32 gather_len);
 
 #endif /* NETWORKLAYER_H_ */

+ 26 - 14
examples/src/opcuaServerACPLT.c

@@ -6,6 +6,7 @@
 #include "ua_transport.h"
 #include "ua_transport_binary.h"
 #include "networklayer.h"
+#include "ua_stack_channel_manager.h"
 
 #ifdef LINUX
 
@@ -42,14 +43,22 @@ void server_run() {
 #ifdef DEBUG
 	tmpTestFunction();
 #endif
-	TL_Connection connection;
-	connection.connectionState = CONNECTIONSTATE_CLOSED;
-	connection.writerCallback = (TL_Writer) NL_TCP_writer;
-	connection.localConf.maxChunkCount = 1;
-	connection.localConf.maxMessageSize = BUFFER_SIZE;
-	connection.localConf.protocolVersion = 0;
-	connection.localConf.recvBufferSize = BUFFER_SIZE;
-	connection.localConf.recvBufferSize = BUFFER_SIZE;
+	UA_TL_Connection1 connection;// = UA_NULL;
+	TL_Buffer localBuffers;
+	UA_Int32 connectionState;
+	//connection.connectionState = CONNECTIONSTATE_CLOSED;
+	//connection.writerCallback = (TL_Writer) NL_TCP_writer;
+	localBuffers.maxChunkCount = 1;
+	localBuffers.maxMessageSize = BUFFER_SIZE;
+	localBuffers.protocolVersion = 0;
+	localBuffers.recvBufferSize = BUFFER_SIZE;
+	localBuffers.recvBufferSize = BUFFER_SIZE;
+
+	/*init secure Channel manager, which handles more than one channel */
+	SL_ChannelManager_init(2, 873);
+	UA_TL_Connection_new(&connection, localBuffers, (TL_Writer)NL_TCP_writer);
+
+
 
 	UA_ByteString slMessage = { -1, UA_NULL };
 
@@ -95,9 +104,10 @@ void server_run() {
 			perror("ERROR on accept");
 			exit(1);
 		}
-
-		printf("server_run - connection accepted: %i, state: %i\n", newsockfd, connection.connectionState);
-		connection.connectionHandle = newsockfd;
+		UA_TL_Connection_getState(connection, &connectionState);
+		printf("server_run - connection accepted: %i, state: %i\n", newsockfd, connectionState);
+		UA_TL_Connection_bind(connection, newsockfd);
+		//connection.connectionHandle = newsockfd;
 		do {
             memset(buffer, 0, BUFFER_SIZE);
 			n = read(newsockfd, buffer, BUFFER_SIZE);
@@ -105,15 +115,17 @@ void server_run() {
                 slMessage.data = (UA_Byte*) buffer;
 				slMessage.length = n;
 				UA_ByteString_printx("server_run - received=",&slMessage);
-				TL_Process(&connection, &slMessage);
+				TL_Process(connection, &slMessage);
 			} else if (n <= 0) {
 				perror("ERROR reading from socket1");
 				exit(1);
 			}
-		} while(connection.connectionState != CONNECTIONSTATE_CLOSE);
+			UA_TL_Connection_getState(connection,&connectionState);
+		} while(connectionState != CONNECTIONSTATE_CLOSE);
 		shutdown(newsockfd,2);
 		close(newsockfd);
-		connection.connectionState = CONNECTIONSTATE_CLOSED;
+		UA_TL_Connection_close(connection);
+
 	}
 	shutdown(sockfd,2);
 	close(sockfd);

+ 1 - 0
examples/src/opcuaServerMini.c

@@ -10,6 +10,7 @@
  * quite small and memory allocation capabilities is not needed
  * as long as features are consequently minimized.
  ****************************************************************/
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <memory.h>

+ 1 - 0
include/ua_basictypes.h

@@ -312,6 +312,7 @@ typedef struct T_UA_DateTimeStruct
 	UA_Int16 year;
 } UA_DateTimeStruct;
 UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime time);
+UA_Int32 UA_DateTime_difference_ms(UA_DateTime time1, UA_DateTime time2);
 UA_Int32 UA_DateTime_toString(UA_DateTime time, UA_String* timeString);
 
 

+ 5 - 1
src/Makefile.am

@@ -68,7 +68,11 @@ libopen62541_la_SOURCES = opcua.c\
 						ua_services_discovery.c\
 						ua_services_securechannel.c\
 						ua_services_view.c\
-						ua_application.c
+						ua_application.c\
+						ua_stack_channel.c\
+						ua_stack_channel_manager.c\
+						ua_transport_connection_manager.c\
+						ua_transport_connection.c
 
 #bin_PROGRAMS= $(top_builddir)/bin/open62541.out
 #__top_builddir__bin_libOpen62541_out_SOURCES = opcuaServer.c

+ 4 - 1
src/ua_basictypes.c

@@ -1287,7 +1287,10 @@ UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime time){
 
 	return dateTimeStruct;
 }
-
+UA_Int32 UA_DateTime_difference_ms(UA_DateTime time1, UA_DateTime time2)
+{
+	return (UA_Int32)(((time1 - time2) / 10000000) &0xFFFFFF);
+}
 UA_Int32 UA_DateTime_toString(UA_DateTime time, UA_String* timeString){
 	char *charBuf = (char*)(*timeString).data;
 

+ 8 - 8
src/ua_services.h

@@ -20,7 +20,7 @@
  * the configuration information required to establish a SecureChannel and a
  * Session.
  */
-UA_Int32 Service_GetEndpoints(SL_Channel *channel, const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response);
+UA_Int32 Service_GetEndpoints(const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response);
 // Service_RegisterServer
 /** @} */
 
@@ -39,12 +39,12 @@ UA_Int32 Service_GetEndpoints(SL_Channel *channel, const UA_GetEndpointsRequest*
  * to ensure Confidentiality and Integrity for Message exchange during a
  * Session.
  */
-UA_Int32 Service_OpenSecureChannel(SL_Channel *channel, const UA_OpenSecureChannelRequest* request, UA_OpenSecureChannelResponse* response);
+UA_Int32 Service_OpenSecureChannel(SL_secureChannel channel,const UA_OpenSecureChannelRequest* request, UA_OpenSecureChannelResponse* response);
 
 /**
  * @brief This Service is used to terminate a SecureChannel.
  */
-UA_Int32 Service_CloseSecureChannel(SL_Channel *channel, const UA_CloseSecureChannelRequest *request, UA_CloseSecureChannelResponse *response);
+UA_Int32 Service_CloseSecureChannel(const UA_CloseSecureChannelRequest *request, UA_CloseSecureChannelResponse *response);
 /** @} */
 
 /**
@@ -63,7 +63,7 @@ UA_Int32 Service_CloseSecureChannel(SL_Channel *channel, const UA_CloseSecureCha
  * logs and in the Server’s address space. The second is the authenticationToken
  * which is used to associate an incoming request with a Session.
  */
-UA_Int32 Service_CreateSession(SL_Channel *channel, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
+UA_Int32 Service_CreateSession(const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
 
 /**
  * @brief This Service is used by the Client to submit its SoftwareCertificates
@@ -72,12 +72,12 @@ UA_Int32 Service_CreateSession(SL_Channel *channel, const UA_CreateSessionReques
  * Client before it issues any other Service request after CreateSession.
  * Failure to do so shall cause the Server to close the Session.
  */
-UA_Int32 Service_ActivateSession(SL_Channel *channel, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
+UA_Int32 Service_ActivateSession(const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
 
 /**
  * @brief This Service is used to terminate a Session.
  */
-UA_Int32 Service_CloseSession(SL_Channel *channel, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
+UA_Int32 Service_CloseSession(const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
 // Service_Cancel
 /** @} */
 
@@ -110,7 +110,7 @@ UA_Int32 Service_CloseSession(SL_Channel *channel, const UA_CloseSessionRequest
  * The browse can be further limited by the use of a View. This Browse Service
  * also supports a primitive filtering capability.
  */ 
-UA_Int32 Service_Browse(SL_Channel *channel, const UA_BrowseRequest *request, UA_BrowseResponse *response);
+UA_Int32 Service_Browse(const UA_BrowseRequest *request, UA_BrowseResponse *response);
 // Service_BrowseNext
 // Service_TranslateBrowsePathsRoNodeIds
 // Service_RegisterNodes
@@ -152,7 +152,7 @@ UA_Int32 Service_Browse(SL_Channel *channel, const UA_BrowseRequest *request, UA
  * values as a composite, to read individual elements or to read ranges of
  * elements of the composite.
  */
-UA_Int32 Service_Read(SL_Channel *channel, const UA_ReadRequest *request, UA_ReadResponse *response);
+UA_Int32 Service_Read(const UA_ReadRequest *request, UA_ReadResponse *response);
 // Service_HistoryRead
 // Service_Write
 // Service_HistoryUpdate

+ 10 - 4
src/ua_services_attribute.c

@@ -171,16 +171,22 @@ static UA_DataValue * service_read_node(Application *app, const UA_ReadValueId *
 	return v;
 }
 
-UA_Int32 Service_Read(SL_Channel *channel, const UA_ReadRequest *request, UA_ReadResponse *response ) {
-	if(channel->session == UA_NULL || channel->session->application == UA_NULL) return UA_ERROR; // TODO: Return error message
+UA_Int32 Service_Read(const UA_ReadRequest *request, UA_ReadResponse *response ) {
 
-	int readsize = request->nodesToReadSize > 0 ? request->nodesToReadSize : 0;
+	//TODO use request->requestHeader.authenticationToken to get the correct session
+
+	//if(channel->session == UA_NULL || channel->session->application == UA_NULL) return UA_ERROR; // TODO: Return error message
+
+
+	UA_Int32 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++) {
 		DBG_VERBOSE(printf("service_read - attributeId=%d\n",request->nodesToRead[i]->attributeId));
 		DBG_VERBOSE(UA_NodeId_printf("service_read - nodeId=",&(request->nodesToRead[i]->nodeId)));
-		response->results[i] = service_read_node(channel->session->application, request->nodesToRead[i]);
+
+	//TODO provide the part of the adress space which is bound to session
+	//response->results[i] = service_read_node(channel->session->application, request->nodesToRead[i]);
 	}
 	response->diagnosticInfosSize = -1;
 	return UA_SUCCESS;

+ 5 - 2
src/ua_services_discovery.c

@@ -1,5 +1,5 @@
 #include "ua_services.h"
-UA_Int32 Service_GetEndpoints(SL_Channel *channel, const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response) {
+UA_Int32 Service_GetEndpoints(const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response) {
 	UA_String_printx("endpointUrl=", &request->endpointUrl);
 
 	response->endpointsSize = 1;
@@ -8,7 +8,10 @@ UA_Int32 Service_GetEndpoints(SL_Channel *channel, const UA_GetEndpointsRequest*
 	//Security issues:
 	//The policy should be 'http://opcfoundation.org/UA/SecurityPolicy#None'
 	//FIXME String or ByteString
-	UA_String_copy((UA_String*)&channel->localAsymAlgSettings.securityPolicyUri,&response->endpoints[0]->securityPolicyUri);
+//TODO get Channel by SessionManager / Session
+//UA_SessionManager_getSession(request->requestHeader->authenticationToken);
+//channel = UA_Session_getChannel(session);
+//UA_String_copy((UA_String*)&channel->localAsymAlgSettings.securityPolicyUri,&response->endpoints[0]->securityPolicyUri);
 	//FIXME hard-coded code
 	response->endpoints[0]->securityMode = UA_MESSAGESECURITYMODE_NONE;
 	UA_String_copycstring("http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary", &response->endpoints[0]->transportProfileUri);

+ 17 - 63
src/ua_services_securechannel.c

@@ -1,75 +1,29 @@
 #include "ua_services.h"
 #include "ua_transport_binary_secure.h"
 
-UA_Int32 Service_OpenSecureChannel(SL_Channel *channel, const UA_OpenSecureChannelRequest* request, UA_OpenSecureChannelResponse* response) {
-	
-	if (request->clientProtocolVersion != channel->tlConnection->remoteConf.protocolVersion) {
-		printf("SL_processMessage - error protocol version \n");
-		//TODO ERROR_Bad_ProtocolVersionUnsupported
-	}
 
-	UA_UInt32 retval = UA_SUCCESS;
-	switch (request->requestType) {
-	case UA_SECURITYTOKEN_ISSUE:
-		if (channel->connectionState == CONNECTIONSTATE_ESTABLISHED) {
-			printf("SL_processMessage - multiple security token request");
-			//TODO return ERROR
-			retval = UA_ERROR;
-			break;
-		}
-		printf("SL_processMessage - TODO: create new token for a new SecureChannel\n");
-		//	SL_createNewToken(connection);
-		break;
-	case UA_SECURITYTOKEN_RENEW:
-		if (channel->connectionState == CONNECTIONSTATE_CLOSED) {
-			printf("SL_processMessage - renew token request received, but no secureChannel was established before");
-			//TODO return ERROR
-			retval = UA_ERROR;
-			break;
-		}
-		printf("TODO: create new token for an existing SecureChannel\n");
-		break;
-	}
 
-	switch (request->securityMode) {
-	case UA_SECURITYMODE_INVALID:
-		channel->remoteNonce.data = UA_NULL;
-		channel->remoteNonce.length = -1;
-		printf("SL_processMessage - client demands no security \n");
-		break;
+UA_Int32 Service_OpenSecureChannel(SL_secureChannel channel,
+		const UA_OpenSecureChannelRequest* request,
+		UA_OpenSecureChannelResponse* response)
+{
+	UA_Int32 retval = UA_SUCCESS;
 
-	case UA_SECURITYMODE_SIGN:
-		printf("SL_processMessage - client demands signed \n");
-		//TODO check if senderCertificate and ReceiverCertificateThumbprint are present
-		break;
 
-	case UA_SECURITYMODE_SIGNANDENCRYPT:
-		printf("SL_processMessage - client demands signed & encrypted \n");
-		//TODO check if senderCertificate and ReceiverCertificateThumbprint are present
-		break;
-	}
+	SL_channelState channelState;
 
-	channel->connectionState = CONNECTIONSTATE_ESTABLISHED;
-
-	if (request->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
-		response->responseHeader.serviceDiagnostics.encodingMask = 0;
-	} else {
-		response->responseHeader.serviceDiagnostics.encodingMask = 0;
-	}
-
-	response->serverProtocolVersion = channel->tlConnection->localConf.protocolVersion;
-	response->securityToken.channelId = channel->securityToken.secureChannelId;
-	response->securityToken.tokenId = channel->securityToken.tokenId.tokenId;
-	response->securityToken.revisedLifetime = channel->securityToken.revisedLifetime;
-	UA_ByteString_copy(&channel->localNonce, &response->serverNonce);
+	//channel takes care of opening process
+	retval |= SL_Channel_processOpenRequest(channel, request,response);
+	retval |= SL_Channel_getState(channel, &channelState);
 	return retval;
 }
 
-UA_Int32 Service_CloseSecureChannel(SL_Channel *channel, const UA_CloseSecureChannelRequest *request, UA_CloseSecureChannelResponse *response) {
-	// 62451 Part 6 Chapter 7.1.4 - The server does not send a CloseSecureChannel response
-	channel->connectionState = CONNECTIONSTATE_CLOSE;
-	return UA_SUCCESS;
+UA_Int32 Service_CloseSecureChannel(const UA_CloseSecureChannelRequest *request,
+		UA_CloseSecureChannelResponse *response)
+{
+	UA_Int32 retval = UA_SUCCESS;
+
+// 62451 Part 6 Chapter 7.1.4 - The server does not send a CloseSecureChannel response
+
+	return retval;
 }

+ 5 - 5
src/ua_services_session.c

@@ -6,7 +6,7 @@ Session sessionMockup = {
 		&appMockup
 };
 
-UA_Int32 Service_CreateSession(SL_Channel *channel, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) {
+UA_Int32 Service_CreateSession(const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) {
 	UA_String_printf("CreateSession Service - endpointUrl=", &(request->endpointUrl));
 	// FIXME: create session
 
@@ -16,7 +16,7 @@ UA_Int32 Service_CreateSession(SL_Channel *channel, const UA_CreateSessionReques
 	return UA_SUCCESS;
 }
 
-UA_Int32 Service_ActivateSession(SL_Channel *channel, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response) {
+UA_Int32 Service_ActivateSession(const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response) {
 	// FIXME: activate session
 	UA_NodeId_printf("ActivateSession - authToken=", &(request->requestHeader.authenticationToken));
 	// 321 == AnonymousIdentityToken_Encoding_DefaultBinary
@@ -24,12 +24,12 @@ UA_Int32 Service_ActivateSession(SL_Channel *channel, const UA_ActivateSessionRe
 	UA_ByteString_printx_hex("ActivateSession - uIdToken.body=", &(request->userIdentityToken.body));
 
 	// FIXME: channel->session->application = <Application Ptr>
-	channel->session = &sessionMockup;
+	//FIXME channel->session = &sessionMockup;
 	return UA_SUCCESS;
 }
 
-UA_Int32 Service_CloseSession(SL_Channel *channel, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response) {
-	channel->session = UA_NULL;
+UA_Int32 Service_CloseSession(const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response) {
+	//FIXME channel->session = UA_NULL;
 	// FIXME: set response
 	return UA_SUCCESS;
 }

+ 1 - 1
src/ua_services_view.c

@@ -1,6 +1,6 @@
 #include "ua_services.h"
 
-UA_Int32 Service_Browse(SL_Channel *channel, const UA_BrowseRequest *request, UA_BrowseResponse *response) {
+UA_Int32 Service_Browse(const UA_BrowseRequest *request, UA_BrowseResponse *response) {
 	UA_Int32 retval = UA_SUCCESS;
 	DBG_VERBOSE(UA_NodeId_printf("BrowseService - view=",&(request->view.viewId)));
 	UA_Int32 i = 0;

+ 3 - 3
src/ua_transport.h

@@ -6,19 +6,19 @@
 
 static const UA_Int32 SL_HEADER_LENGTH = 0;
 
-enum ConnectionState {
+typedef enum UA_ConnectionState {
 	CONNECTIONSTATE_CLOSED,
 	CONNECTIONSTATE_OPENING,
 	CONNECTIONSTATE_ESTABLISHED,
 	CONNECTIONSTATE_CLOSE
-};
+}UA_ConnectionState;
 
 typedef struct Session_T {
 	UA_Int32 sessionId;
 	Application *application;
 } Session;
 
-typedef enum {
+typedef enum SecurityTokenRequestType{
 	UA_SECURITYTOKEN_ISSUE = 0,
 	UA_SECURITYTOKEN_RENEW = 1
 } SecurityTokenRequestType;

+ 99 - 23
src/ua_transport_binary.c

@@ -2,20 +2,67 @@
 #include "ua_transport_binary.h"
 #include "ua_transport.h"
 #include "ua_transport_binary_secure.h"
+#include "ua_transport_connection.h"
 
-static UA_Int32 TL_check(TL_Connection* connection, UA_ByteString* msg) {
-	if(msg->length > (UA_Int32) connection->localConf.maxMessageSize || msg->length > (UA_Int32) connection->remoteConf.maxMessageSize) {
-		DBG_ERR(printf("TL_check - length error \n"));
-		return UA_ERR_INCONSISTENT;
+
+static UA_Int32 TL_handleHello1(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_Int32* pos){
+	UA_Int32 retval = UA_SUCCESS;
+	UA_Int32 tmpPos = 0;
+	UA_Int32 connectionState;
+	UA_OPCUATcpHelloMessage helloMessage;
+	UA_TL_Connection_getState(connection, &connectionState);
+	if (connectionState == CONNECTIONSTATE_CLOSED){
+		DBG_VERBOSE(printf("TL_handleHello - extracting header information \n"));
+		UA_OPCUATcpHelloMessage_decodeBinary(msg,pos,&helloMessage);
+
+		UA_TL_Connection_configByHello(connection, &helloMessage);
+		DBG_VERBOSE(printf("TL_handleHello - protocolVersion = %d \n",connection->remoteConf.protocolVersion));
+		DBG_VERBOSE(printf("TL_handleHello - recvBufferSize = %d \n",connection->remoteConf.recvBufferSize));
+		DBG_VERBOSE(printf("TL_handleHello - sendBufferSize = %d \n",connection->remoteConf.sendBufferSize));
+		DBG_VERBOSE(printf("TL_handleHello - maxMessageSize = %d \n",connection->remoteConf.maxMessageSize));
+		DBG_VERBOSE(printf("TL_handleHello - maxChunkCount = %d \n",connection->remoteConf.maxChunkCount));
+
+		// build acknowledge response
+		UA_OPCUATcpAcknowledgeMessage ackMessage;
+		TL_Buffer localConfig;
+		UA_TL_Connection_getLocalConfiguration(connection, &localConfig);
+		ackMessage.protocolVersion = localConfig.protocolVersion;
+		ackMessage.receiveBufferSize = localConfig.recvBufferSize;
+		ackMessage.sendBufferSize = localConfig.sendBufferSize;
+		ackMessage.maxMessageSize = localConfig.maxMessageSize;
+		ackMessage.maxChunkCount = localConfig.maxChunkCount;
+
+		UA_OPCUATcpMessageHeader ackHeader;
+		ackHeader.messageType = UA_MESSAGETYPE_ACK;
+		ackHeader.isFinal = 'F';
+
+		// encode header and message to buffer
+		tmpPos = 0;
+		ackHeader.messageSize = UA_OPCUATcpAcknowledgeMessage_calcSize(&ackMessage) + UA_OPCUATcpMessageHeader_calcSize(&ackHeader);
+		UA_ByteString *ack_msg;
+		UA_alloc((void **)&ack_msg, sizeof(UA_ByteString));
+		UA_ByteString_newMembers(ack_msg, ackHeader.messageSize);
+		UA_OPCUATcpMessageHeader_encodeBinary(&ackHeader,&tmpPos,ack_msg);
+		UA_OPCUATcpAcknowledgeMessage_encodeBinary(&ackMessage,&tmpPos,ack_msg);
+
+		DBG_VERBOSE(printf("TL_handleHello - Size messageToSend = %d, pos=%d\n",ackHeader.messageSize, tmpPos));
+		DBG_VERBOSE(UA_ByteString_printx("_handleHello - ack=", ack_msg));
+		TL_Send(connection, (const UA_ByteString **) &ack_msg, 1);
+		DBG_VERBOSE(printf("TL_handleHello - finished writing\n"));
+		UA_ByteString_delete(ack_msg);
+	} else {
+		DBG_ERR(printf("TL_handleHello - wrong connection state \n"));
+		retval = UA_ERROR_MULTIPLE_HEL;
 	}
-	return UA_SUCCESS;
+	return retval;
 }
-
+/*
 static UA_Int32 TL_handleHello(TL_Connection* connection, const UA_ByteString* msg, UA_Int32* pos) {
 	UA_Int32 retval = UA_SUCCESS;
 	UA_Int32 tmpPos = 0;
 	UA_OPCUATcpHelloMessage helloMessage;
 
+
 	if (connection->connectionState == CONNECTIONSTATE_CLOSED) {
 		DBG_VERBOSE(printf("TL_handleHello - extracting header information \n"));
 		UA_OPCUATcpHelloMessage_decodeBinary(msg,pos,&helloMessage);
@@ -68,28 +115,52 @@ static UA_Int32 TL_handleHello(TL_Connection* connection, const UA_ByteString* m
 	}
 	return retval;
 }
-
-static UA_Int32 TL_handleOpen(TL_Connection* connection, const UA_ByteString* msg, UA_Int32* pos) {
-	if (connection->connectionState == CONNECTIONSTATE_ESTABLISHED) {
-		return SL_Channel_new(connection, msg, pos);
+*/
+static UA_Int32 TL_handleOpen(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_Int32* pos) {
+	UA_Int32 state;
+	UA_TL_Connection_getState(connection,&state);
+	SL_secureChannel channel = UA_NULL;
+	if (state == CONNECTIONSTATE_ESTABLISHED) {
+	//	return SL_Channel_new(connection, msg, pos);
+		//UA_TL_Connection_getId(connection,connectionId);
+
+		if(SL_Channel_newByRequest(connection, msg, pos, &channel) == UA_SUCCESS)
+		{
+
+			SL_Channel_registerTokenProvider(channel, SL_ChannelManager_generateToken);
+			SL_ProcessOpenChannel(channel, msg, pos);
+			SL_ChannelManager_addChannel(channel);
+		}else
+		{
+			printf("TL_handleOpen - ERROR: could not create new secureChannel");
+		}
 	}
+
 	return UA_ERR_INVALID_VALUE;
 }
 
-static UA_Int32 TL_handleMsg(TL_Connection* connection, const UA_ByteString* msg, UA_Int32* pos) {
-	SL_Channel* slc = connection->secureChannel;
-	return SL_Process(slc,msg,pos);
+static UA_Int32 TL_handleMsg(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_Int32* pos) {
+	UA_Int32 state;
+	UA_TL_Connection_getState(connection,&state);
+	if (state == CONNECTIONSTATE_ESTABLISHED) {
+		return SL_Process(msg,pos);
+	}
+	return UA_ERR_INVALID_VALUE;
 }
 
-static UA_Int32 TL_handleClo(TL_Connection* connection, const UA_ByteString* msg, UA_Int32* pos) {
-	SL_Channel* slc = connection->secureChannel;
-	connection->connectionState = CONNECTIONSTATE_CLOSE;
-    connection->secureChannel = UA_NULL;
-    slc->tlConnection = UA_NULL;
-	return UA_SUCCESS;
+static UA_Int32 TL_handleClo(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_Int32* pos) {
+	UA_Int32 retval = UA_SUCCESS;
+	UA_SecureConversationMessageHeader *header;
+	retval |= UA_SecureConversationMessageHeader_new(&header);
+	retval |= UA_SecureConversationMessageHeader_decodeBinary(msg,pos,header);
+
+	retval |= SL_ChannelManager_removeChannel(header->secureChannelId);
+
+	retval |= UA_SecureConversationMessageHeader_delete(header);
+	return retval;
 }
 
-UA_Int32 TL_Process(TL_Connection* connection, const UA_ByteString* msg) {
+UA_Int32 TL_Process(UA_TL_Connection1 connection, const UA_ByteString* msg) {
 	UA_Int32 retval = UA_SUCCESS;
 	UA_Int32 pos = 0;
 	UA_OPCUATcpMessageHeader tcpMessageHeader;
@@ -100,7 +171,9 @@ UA_Int32 TL_Process(TL_Connection* connection, const UA_ByteString* msg) {
 		printf("TL_Process - messageType=%.*s\n",3,msg->data);
 		switch(tcpMessageHeader.messageType) {
 		case UA_MESSAGETYPE_HEL:
-			retval = TL_handleHello(connection, msg, &pos);
+			retval = TL_handleHello1(connection, msg, &pos);
+			//retval = TL_handleHello(connection, msg, &pos);
+
 			break;
 		case UA_MESSAGETYPE_OPN:
 			retval = TL_handleOpen(connection, msg, &pos);
@@ -129,11 +202,14 @@ UA_Int32 TL_Process(TL_Connection* connection, const UA_ByteString* msg) {
 }
 
 /** respond to client request */
-UA_Int32 TL_Send(TL_Connection* connection, const UA_ByteString** gather_buf, UA_UInt32 gather_len) {
+UA_Int32 TL_Send(UA_TL_Connection1 connection, const UA_ByteString** gather_buf, UA_UInt32 gather_len) {
 	UA_Int32 retval = UA_SUCCESS;
+
+
 	DBG_VERBOSE(printf("TL_send - entered \n"));
 	//	if (TL_check(connection,msg,TL_CHECK_REMOTE) == UA_SUCCESS) {
-	retval = connection->writerCallback(connection, gather_buf, gather_len);
+
+	retval = UA_TL_Connection_callWriter(connection, gather_buf, gather_len);
 	DBG_VERBOSE(printf("TL_send - exited \n"));
 		//}
 	/* else */

+ 7 - 20
src/ua_transport_binary.h

@@ -4,28 +4,14 @@
 
 #include "opcua.h"
 #include "ua_transport_binary.h"
+#include "ua_transport_connection.h"
 
-//transport errors begin at 1000
-#define UA_ERROR_MULTIPLE_HEL 1000
-#define UA_ERROR_RCV_ERROR 1001
-
-//variables which belong to layer
-#define TL_SERVER_PROTOCOL_VERSION  0
-#define TL_SERVER_MAX_CHUNK_COUNT 1
-#define TL_SERVER_MAX_MESSAGE_SIZE  8192
-
-typedef struct {
-	UA_UInt32 protocolVersion;
-	UA_UInt32 sendBufferSize;
-	UA_UInt32 recvBufferSize;
-	UA_UInt32 maxMessageSize;
-	UA_UInt32 maxChunkCount;
-} TL_Buffer;
 
 /* Transport Layer Connection */
-struct TL_Connection_T; // forward declaration
-typedef UA_Int32 (*TL_Writer)(struct TL_Connection_T* connection, const UA_ByteString** gather_bufs, UA_Int32 gather_len); // send mutiple buffer concatenated into one msg (zero copy)
+//struct TL_Connection_T; // forward declaration
 
+//typedef UA_Int32 (*TL_Writer)(struct TL_Connection_T* connection, const UA_ByteString** gather_bufs, UA_Int32 gather_len); // send mutiple buffer concatenated into one msg (zero copy)
+/*
 typedef struct TL_Connection_T {
 	UA_Int32 connectionHandle;
 	UA_UInt32 connectionState;
@@ -36,8 +22,9 @@ typedef struct TL_Connection_T {
 	UA_String remoteEndpointUrl;
 	struct SL_Channel_T* secureChannel;
 } TL_Connection;
+*/
 
-UA_Int32 TL_Send(TL_Connection* connection, const UA_ByteString** gather_buf, UA_UInt32 gather_len);
-UA_Int32 TL_Process(TL_Connection *connection, const UA_ByteString *packet);
+UA_Int32 TL_Send(UA_TL_Connection1 connection, const UA_ByteString** gather_buf, UA_UInt32 gather_len);
+UA_Int32 TL_Process(UA_TL_Connection1 connection, const UA_ByteString* msg);
 
 #endif /* OPCUA_TRANSPORT_BINARY_H_ */

+ 198 - 97
src/ua_transport_binary_secure.c

@@ -10,40 +10,59 @@
 #define SIZE_SECURECHANNEL_HEADER 12
 #define SIZE_SEQHEADER_HEADER 8
 
-SL_Channel slc;
+static UA_Int32 SL_Send(SL_secureChannel channel,
+		const UA_ByteString * responseMessage, UA_Int32 type)
+{
+
+	//access function for SL_secureChannel
+	//SL_Channel_getId(secureChannel)
+	//SL_Channel_getSequenceNumber(secureChannel)
 
-static UA_Int32 SL_Send(SL_Channel* channel, const UA_ByteString * responseMessage, UA_Int32 type) {
 	UA_Int32 pos = 0;
 	UA_Int32 isAsym = (type == UA_OPENSECURECHANNELRESPONSE_NS0); // FIXME: this is a to dumb method to determine asymmetric algorithm setting
-
+	UA_UInt32 channelId;
+	UA_UInt32 sequenceNumber;
+	UA_UInt32 requestId;
+	UA_TL_Connection1 connection;
 	UA_NodeId resp_nodeid;
+	UA_AsymmetricAlgorithmSecurityHeader *asymAlgSettings = UA_NULL;
+
+	//UA_AsymmetricAlgorithmSecurityHeader_new((void**)(&asymAlgSettings));
+
 	resp_nodeid.encodingByte = UA_NODEIDTYPE_FOURBYTE;
 	resp_nodeid.namespace = 0;
-	resp_nodeid.identifier.numeric = type+2; // binary encoding
+	resp_nodeid.identifier.numeric = type + 2; // binary encoding
 
 	const UA_ByteString *response_gather[2]; // securechannel_header, seq_header, security_encryption_header, message_length (eventually + padding + size_signature);
-	UA_alloc((void **)&response_gather[0], sizeof(UA_ByteString));
-	if(isAsym) {
-		UA_ByteString_newMembers((UA_ByteString *)response_gather[0], SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER +
-								 UA_AsymmetricAlgorithmSecurityHeader_calcSize(&channel->localAsymAlgSettings) +
-								 UA_NodeId_calcSize(&resp_nodeid));
-	}
-	else {
-		UA_ByteString_newMembers((UA_ByteString *)response_gather[0], 8 + 16 + // normal header + 4*32bit secure channel information
-								 UA_NodeId_calcSize(&resp_nodeid));
-	}
-		
-	
+	UA_alloc((void ** )&response_gather[0], sizeof(UA_ByteString));
+	if (isAsym)
+	{
+
+		UA_ByteString_newMembers((UA_ByteString *) response_gather[0],
+				SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER
+						+ UA_AsymmetricAlgorithmSecurityHeader_calcSize(
+								asymAlgSettings)
+						+ UA_NodeId_calcSize(&resp_nodeid));
+	}
+	else
+	{
+		UA_ByteString_newMembers((UA_ByteString *) response_gather[0], 8 + 16 + // normal header + 4*32bit secure channel information
+				UA_NodeId_calcSize(&resp_nodeid));
+	}
+
 	// sizePadding = 0;
 	// sizeSignature = 0;
-    UA_ByteString *header = (UA_ByteString *)response_gather[0];
+	UA_ByteString *header = (UA_ByteString *) response_gather[0];
 
 	/*---encode Secure Conversation Message Header ---*/
-	if (isAsym) {
+	if (isAsym)
+	{
 		header->data[0] = 'O';
 		header->data[1] = 'P';
 		header->data[2] = 'N';
-	} else {
+	}
+	else
+	{
 		header->data[0] = 'M';
 		header->data[1] = 'S';
 		header->data[2] = 'G';
@@ -52,39 +71,58 @@ static UA_Int32 SL_Send(SL_Channel* channel, const UA_ByteString * responseMessa
 	header->data[pos] = 'F';
 	pos += 1;
 
-    UA_Int32 packetSize = response_gather[0]->length + responseMessage->length;
+	UA_Int32 packetSize = response_gather[0]->length + responseMessage->length;
 	UA_Int32_encodeBinary(&packetSize, &pos, header);
-	UA_UInt32_encodeBinary(&channel->securityToken.secureChannelId, &pos, header);
+
+	//use get accessor to read the channel Id
+	SL_Channel_getChannelId(channel, &channelId);
+
+	UA_UInt32_encodeBinary(&channelId, &pos, header);
 
 	/*---encode Algorithm Security Header ---*/
-	if (isAsym) {
-		UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(&channel->localAsymAlgSettings, &pos, header);
-	} else {
-		UA_SymmetricAlgorithmSecurityHeader_encodeBinary(&channel->securityToken.tokenId, &pos, header);
+	if (isAsym)
+	{
+
+		SL_Channel_getLocalAsymAlgSettings(channel, asymAlgSettings);
+		UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(asymAlgSettings, &pos,
+				header);
+	}
+	else
+	{
+
+		UA_UInt32 tokenId = 0;
+		SL_Channel_getTokenId(channel, &tokenId);
+
+		UA_UInt32_encodeBinary(&tokenId, &pos, header);
 	}
 
 	/*---encode Sequence Header ---*/
-	UA_UInt32_encodeBinary(&channel->sequenceHeader.sequenceNumber, &pos, header);
-	UA_UInt32_encodeBinary(&channel->sequenceHeader.requestId, &pos, header);
+	SL_Channel_getSequenceNumber(channel, &sequenceNumber);
+	UA_UInt32_encodeBinary(&sequenceNumber, &pos, header);
+	SL_Channel_getRequestId(channel, &requestId);
+	UA_UInt32_encodeBinary(&requestId, &pos, header);
 
 	/*---add payload type---*/
 	UA_NodeId_encodeBinary(&resp_nodeid, &pos, header);
-	
+
 	/*---add encoded Message ---*/
-    response_gather[1] = responseMessage; // is deleted in the calling function
+	response_gather[1] = responseMessage; // is deleted in the calling function
 
 	/* sign Data*/
 
 	/* encrypt Data*/
 
 	/* send Data */
-    TL_Send(channel->tlConnection, response_gather, 2);
+	SL_Channel_getConnection(channel, &connection);
+	TL_Send(connection, response_gather, 2);
 
-	UA_ByteString_delete((UA_ByteString *)response_gather[0]);
+	UA_ByteString_delete((UA_ByteString *) response_gather[0]);
 	return UA_SUCCESS;
 }
 
-static void init_response_header(UA_RequestHeader const * p, UA_ResponseHeader * r) {
+static void init_response_header(UA_RequestHeader const * p,
+		UA_ResponseHeader * r)
+{
 	memset((void*) r, 0, sizeof(UA_ResponseHeader));
 	r->requestHandle = p->requestHandle;
 	r->serviceResult = UA_STATUSCODE_GOOD;
@@ -99,7 +137,7 @@ static void init_response_header(UA_RequestHeader const * p, UA_ResponseHeader *
 	UA_##TYPE##Response_init(&r); \
 	init_response_header(&p.requestHeader, &r.responseHeader); \
 	DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
-	Service_##TYPE(channel, &p, &r); \
+	Service_##TYPE(&p, &r); \
 	DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
     *pos = 0; \
 	UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSize(&r)); \
@@ -108,51 +146,87 @@ static void init_response_header(UA_RequestHeader const * p, UA_ResponseHeader *
 	UA_##TYPE##Response_deleteMembers(&r); \
 
 /** this function manages all the generic stuff for the request-response game */
-UA_Int32 SL_handleRequest(SL_Channel *channel, const UA_ByteString* msg, UA_Int32 *pos) {
+//UA_Int32 SL_handleRequest(SL_Channel *channel, const UA_ByteString* msg,
+//		UA_Int32 *pos)
+
+UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
+		UA_Int32 *pos)
+{
 	UA_Int32 retval = UA_SUCCESS;
 
 	// Every Message starts with a NodeID which names the serviceRequestType
 	UA_NodeId serviceRequestType;
 	UA_NodeId_decodeBinary(msg, pos, &serviceRequestType);
-	UA_NodeId_printf("SL_processMessage - serviceRequestType=", &serviceRequestType);
+	UA_NodeId_printf("SL_processMessage - serviceRequestType=",
+			&serviceRequestType);
 
 	UA_ByteString response_msg;
-	int serviceid = serviceRequestType.identifier.numeric-2; // binary encoding has 2 added to the id
-    UA_Int32 responsetype;
-	if(serviceid == UA_GETENDPOINTSREQUEST_NS0) {
+	UA_Int32 serviceid = serviceRequestType.identifier.numeric - 2; // binary encoding has 2 added to the id
+	UA_Int32 responsetype;
+	if (serviceid == UA_GETENDPOINTSREQUEST_NS0)
+	{
 		INVOKE_SERVICE(GetEndpoints);
 		responsetype = UA_GETENDPOINTSRESPONSE_NS0;
 	}
-	else if(serviceid == UA_OPENSECURECHANNELREQUEST_NS0) {
-		INVOKE_SERVICE(OpenSecureChannel);
+	else if (serviceid == UA_OPENSECURECHANNELREQUEST_NS0)
+	{
+		//I see at the moment no other way to handle this
+		UA_OpenSecureChannelRequest p;
+		UA_OpenSecureChannelResponse r;
+		UA_OpenSecureChannelRequest_decodeBinary(msg, pos, &p);
+		UA_OpenSecureChannelResponse_init(&r);
+		init_response_header(&p.requestHeader, &r.responseHeader);
+		DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE));
+		Service_OpenSecureChannel(channel,&p, &r);
+		DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE));
+	    *pos = 0; \
+		UA_ByteString_newMembers(&response_msg, UA_OpenSecureChannelResponse_calcSize(&r));
+		UA_OpenSecureChannelResponse_encodeBinary(&r, pos, &response_msg);
+		UA_OpenSecureChannelRequest_deleteMembers(&p);
+		UA_OpenSecureChannelResponse_deleteMembers(&r);
+
+		//INVOKE_SERVICE(OpenSecureChannel);
 		responsetype = UA_OPENSECURECHANNELRESPONSE_NS0;
 	}
-	else if(serviceid == UA_CLOSESECURECHANNELREQUEST_NS0) {
+	else if (serviceid == UA_CLOSESECURECHANNELREQUEST_NS0)
+	{
 		INVOKE_SERVICE(CloseSecureChannel);
 		responsetype = UA_CLOSESECURECHANNELRESPONSE_NS0;
 	}
-	else if(serviceid == UA_CREATESESSIONREQUEST_NS0) {
+	else if (serviceid == UA_CREATESESSIONREQUEST_NS0)
+	{
+		//TODO prepare userdefined implementation
 		INVOKE_SERVICE(CreateSession);
 		responsetype = UA_CREATESESSIONRESPONSE_NS0;
 	}
-	else if(serviceid == UA_ACTIVATESESSIONREQUEST_NS0) {
+	else if (serviceid == UA_ACTIVATESESSIONREQUEST_NS0)
+	{
+		//TODO prepare userdefined implementation
 		INVOKE_SERVICE(ActivateSession);
 		responsetype = UA_ACTIVATESESSIONRESPONSE_NS0;
 	}
-	else if(serviceid == UA_CLOSESESSIONREQUEST_NS0) {
+	else if (serviceid == UA_CLOSESESSIONREQUEST_NS0)
+	{
+		//TODO prepare userdefined implementation
 		INVOKE_SERVICE(CloseSession);
 		responsetype = UA_CLOSESESSIONRESPONSE_NS0;
 	}
-	else if(serviceid == UA_READREQUEST_NS0) {
+	else if (serviceid == UA_READREQUEST_NS0)
+	{
+		//TODO prepare userdefined implementation
 		INVOKE_SERVICE(Read);
-	    responsetype = UA_READRESPONSE_NS0;
+		responsetype = UA_READRESPONSE_NS0;
 	}
-	else {
-		printf("SL_processMessage - unknown request, namespace=%d, request=%d\n", serviceRequestType.namespace,serviceRequestType.identifier.numeric);
+	else
+	{
+		printf(
+				"SL_processMessage - unknown request, namespace=%d, request=%d\n",
+				serviceRequestType.namespace,
+				serviceRequestType.identifier.numeric);
 		retval = UA_ERROR;
 		UA_RequestHeader p;
 		UA_ResponseHeader r;
-		UA_RequestHeader_decodeBinary(msg,pos,&p);
+		UA_RequestHeader_decodeBinary(msg, pos, &p);
 		UA_ResponseHeader_init(&r);
 		r.requestHandle = p.requestHandle;
 		r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
@@ -167,6 +241,12 @@ UA_Int32 SL_handleRequest(SL_Channel *channel, const UA_ByteString* msg, UA_Int3
 
 	return retval;
 }
+
+UA_Int32 SL_ProcessOpenChannel(SL_secureChannel channel, const UA_ByteString* msg,
+		UA_Int32 *pos)
+{
+	return SL_handleRequest(channel, msg, pos);
+}
 /**
  *
  * @param connection
@@ -174,65 +254,86 @@ UA_Int32 SL_handleRequest(SL_Channel *channel, const UA_ByteString* msg, UA_Int3
  * @param pos
  * @return
  */
-UA_Int32 SL_Channel_new(TL_Connection *connection, const UA_ByteString* msg, UA_Int32* pos) {
-	DBG_VERBOSE(printf("SL_Channel_new - entered\n"));
-	UA_Int32 retval = UA_SUCCESS;
-
-	/* Create New Channel*/
-	SL_Channel *channel = &slc; // FIXME: generate new secure channel
-	UA_AsymmetricAlgorithmSecurityHeader_init(&(channel->localAsymAlgSettings));
-	UA_ByteString_copy(&UA_ByteString_securityPoliceNone, &(channel->localAsymAlgSettings.securityPolicyUri));
-	UA_alloc((void**)&(channel->localNonce.data), sizeof(UA_Byte));
-	channel->localNonce.length = 1;
-	channel->connectionState = CONNECTIONSTATE_CLOSED; // the state of the channel will be opened in the service
-	channel->sequenceHeader.requestId = 0;
-	channel->sequenceHeader.sequenceNumber = 1;
-	UA_String_init(&(channel->secureChannelId));
-	channel->securityMode = UA_SECURITYMODE_INVALID;
-	channel->securityToken.secureChannelId = 25; //TODO set a valid start secureChannelId number
-	channel->securityToken.tokenId.tokenId = 1; //TODO set a valid start TokenId
-
-	connection->secureChannel = channel;
-	connection->secureChannel->tlConnection = connection;
-
-	/* Read the OPN message headers */
-	*pos += 4; // skip the securechannelid
-	UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos, &connection->secureChannel->remoteAsymAlgSettings);
-	UA_SequenceHeader_decodeBinary(msg, pos, &connection->secureChannel->sequenceHeader);
-	//TODO check that the sequence number is smaller than MaxUInt32 - 1024
-	//TODO check if a OpenSecureChannelRequest follows
-
-	retval |= SL_handleRequest(channel, msg, pos);
-	return retval;
-
-	// FIXME: reject
-}
-
+//UA_Int32 SL_Channel_new(TL_Connection *connection, const UA_ByteString* msg,
+//		UA_Int32* pos)
+//{
+//	DBG_VERBOSE(printf("SL_Channel_new - entered\n"));
+//	UA_Int32 retval = UA_SUCCESS;
+//
+//	/* Create New Channel*/
+//	SL_Channel *channel = &slc; // FIXME: generate new secure channel
+//	UA_AsymmetricAlgorithmSecurityHeader_init(&(channel->localAsymAlgSettings));
+//	UA_ByteString_copy(&UA_ByteString_securityPoliceNone,
+//			&(channel->localAsymAlgSettings.securityPolicyUri));
+//	UA_alloc((void** )&(channel->localNonce.data), sizeof(UA_Byte));
+//	channel->localNonce.length = 1;
+//	channel->connectionState = CONNECTIONSTATE_CLOSED; // the state of the channel will be opened in the service
+//	channel->sequenceHeader.requestId = 0;
+//	channel->sequenceHeader.sequenceNumber = 1;
+//	UA_String_init(&(channel->secureChannelId));
+//	channel->securityMode = UA_SECURITYMODE_INVALID;
+//	channel->securityToken.secureChannelId = 25; //TODO set a valid start secureChannelId number
+//	channel->securityToken.tokenId.tokenId = 1; //TODO set a valid start TokenId
+//	connection->secureChannel = channel;
+//	connection->secureChannel->tlConnection = connection;
+/* Read the OPN message headers */
+//	*pos += 4; // skip the securechannelid
+//	UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos,
+//			&connection->secureChannel->remoteAsymAlgSettings);
+//	UA_SequenceHeader_decodeBinary(msg, pos,
+//			&connection->secureChannel->sequenceHeader);
+//	//TODO check that the sequence number is smaller than MaxUInt32 - 1024
+//	//TODO check if a OpenSecureChannelRequest follows
+//	retval |= SL_handleRequest(channel, msg, pos);
+//	return retval;
+// FIXME: reject
+//}
 /**
  * process the rest of the header. TL already processed MessageType
  * (OPN,MSG,...), isFinal and MessageSize. SL_process cares for
  * secureChannelId, XASHeader and sequenceHeader
  * */
-UA_Int32 SL_Process(SL_Channel* connection, const UA_ByteString* msg, UA_Int32* pos) {
+UA_Int32 SL_Process(const UA_ByteString* msg,
+		UA_Int32* pos)
+{
 
 	DBG_VERBOSE(printf("SL_process - entered \n"));
 	UA_UInt32 secureChannelId;
+	UA_UInt32 foundChannelId;
+	SL_secureChannel channel;
+	UA_SequenceHeader sequenceHeader;
 
-	if (connection->connectionState == CONNECTIONSTATE_ESTABLISHED) {
-		UA_UInt32_decodeBinary(msg,pos,&secureChannelId);
 
-		//FIXME: we assume SAS, need to check if AAS or SAS
-		UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
-		// if (connection->securityMode == UA_MESSAGESECURITYMODE_NONE) {
-		UA_SymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos, &symAlgSecHeader);
+	UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
 
-		printf("SL_process - securityToken received=%d, expected=%d\n",secureChannelId,connection->securityToken.secureChannelId);
-		if (secureChannelId == connection->securityToken.secureChannelId) {
-			UA_SequenceHeader_decodeBinary(msg, pos, &(connection->sequenceHeader));
-			SL_handleRequest(&slc, msg, pos);
-		} else {
-			//TODO generate ERROR_Bad_SecureChannelUnkown
-		}
+	//FIXME: we assume SAS, need to check if AAS or SAS
+	UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
+	// if (connection->securityMode == UA_MESSAGESECURITYMODE_NONE) {
+	UA_SymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos,
+			&symAlgSecHeader);
+
+	if (SL_ChannelManager_getChannel(secureChannelId,
+			&channel) == UA_SUCCESS)
+	{
+
+		SL_Channel_getChannelId(channel, &foundChannelId);
+		printf("SL_process - received msg, with channel id: %i \n",
+				foundChannelId);
+
+		//sequence number processing
+		UA_SequenceHeader_decodeBinary(msg, pos,
+				&sequenceHeader);
+		SL_Channel_checkSequenceNumber(channel,sequenceHeader.sequenceNumber);
+
+		//request id processing
+
+
+		SL_handleRequest(channel, msg, pos);
 	}
+	else
+	{
+		//TODO generate ERROR_Bad_SecureChannelUnkown
+	}
+
 	return UA_SUCCESS;
 }

+ 30 - 5
src/ua_transport_binary_secure.h

@@ -3,7 +3,22 @@
 #include "opcua.h"
 #include "ua_transport.h"
 #include "ua_transport_binary.h"
-#include "ua_transport_binary_secure.h"
+#include "ua_stack_channel.h"
+#include "ua_stack_channel_manager.h"
+#define UA_ERROR_MULTIPLE_HEL 1001
+/*inputs for secure Channel which must be provided once
+endPointUrl
+securityPolicyUrl
+securityMode
+revisedLifetime
+*/
+
+/*inputs for secure Channel Manager which must be provided once
+ maxChannelCount
+
+ */
+
+
 
 typedef struct {
 	UA_UInt32 secureChannelId;
@@ -14,8 +29,8 @@ typedef struct {
 
 typedef struct SL_Channel_T {
 	UA_String secureChannelId;
-	TL_Connection* tlConnection;
-	Session *session; // equals UA_Null iff no session is active
+	UA_TL_Connection1 tlConnection;
+	Session *session; // equals UA_Null if no session is active
 	UA_AsymmetricAlgorithmSecurityHeader remoteAsymAlgSettings;
 	UA_AsymmetricAlgorithmSecurityHeader localAsymAlgSettings;
 	UA_SequenceHeader sequenceHeader;
@@ -26,7 +41,17 @@ typedef struct SL_Channel_T {
 	SL_ChannelSecurityToken securityToken;
 } SL_Channel;
 
-UA_Int32 SL_Process(SL_Channel* channel, const UA_ByteString* msg, UA_Int32* pos);
-UA_Int32 SL_Channel_new(TL_Connection *connection, const UA_ByteString* msg, UA_Int32* pos); // this function is called from the OpenSecureChannel service
 
+UA_Int32 SL_Process(const UA_ByteString* msg, UA_Int32* pos);
+
+/**
+ * @brief Wrapper function, to encapsulate handleRequest for openSecureChannel requests
+ * @param channel A secure Channel structure, which receives the information for the new created secure channel
+ * @param msg Message which holds the binary encoded request
+ * @param pos Position in the message at which the request begins
+ * @return Returns UA_SUCCESS if successful executed, UA_ERROR in any other case
+
+ */
+UA_Int32 SL_ProcessOpenChannel(SL_secureChannel channel, const UA_ByteString* msg,
+		UA_Int32 *pos);
 #endif /* OPCUA_TRANSPORT_BINARY_SECURE_H_ */

+ 1 - 1
tests/check_builtin.c

@@ -2019,7 +2019,7 @@ Suite *testSuite_builtin(void)
 	tcase_add_test(tc_copy, UA_Variant_copyShallWorkOn2DArrayExample);
 
 	tcase_add_test(tc_copy, UA_DiagnosticInfo_copyShallWorkOnExample);
-//	tcase_add_test(tc_copy, UA_ApplicationDescription_copyShallWorkOnExample);
+	tcase_add_test(tc_copy, UA_ApplicationDescription_copyShallWorkOnExample);
 	suite_add_tcase(s,tc_copy);
 	return s;
 }