Quellcode durchsuchen

created new source files for connection and secureChannel handling

FlorianPalm vor 11 Jahren
Ursprung
Commit
9b491bfd7b

+ 417 - 0
src/ua_stack_channel.c

@@ -0,0 +1,417 @@
+/*
+ * ua_stack_channel.c
+ *
+ *  Created on: 09.05.2014
+ *      Author: root
+ */
+
+#include "ua_stack_channel.h"
+
+
+typedef struct SL_Channel1 {
+	SL_channelState state;
+	UA_UInt32 channelId;
+	//TL_Connection* tlConnection;
+
+	UA_TL_Connection1 connection;
+	UA_UInt32 requestId;
+	UA_UInt32 lastRequestId;
+
+	UA_UInt32 sequenceNumber;
+	UA_UInt32 lastSequenceNumber;
+
+	UA_AsymmetricAlgorithmSecurityHeader remoteAsymAlgSettings;
+	UA_AsymmetricAlgorithmSecurityHeader localAsymAlgSettings;
+
+
+	UA_ChannelSecurityToken securityToken;
+
+	UA_MessageSecurityMode securityMode;
+	UA_ByteString remoteNonce;
+	UA_ByteString localNonce;
+	SL_ChannelSecurityTokenProvider tokenProvider;
+	SL_ChannelIdProvider channelIdProvider;
+}SL_Channel1;
+
+UA_Int32 SL_Channel_registerTokenProvider(SL_secureChannel channel, SL_ChannelSecurityTokenProvider provider)
+{
+	((SL_Channel1*)channel)->tokenProvider = provider;
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_Channel_getRemainingLifetime(SL_secureChannel channel, UA_Int32 *lifetime)
+{
+	if(channel)
+	{
+		*lifetime = UA_DateTime_difference_ms(((SL_Channel1*)channel)->securityToken.createdAt,UA_DateTime_now());
+	return UA_SUCCESS;
+	}
+	else
+	{
+		printf("SL_Channel_getRemainingLifetime - no valid channel object, null pointer");
+		return UA_ERROR;
+	}
+}
+
+UA_Int32 SL_Channel_getChannelId(SL_secureChannel channel, UA_UInt32 *channelId)
+{
+	if(channel)
+	{
+		*channelId = ((SL_Channel1*)channel)->channelId;
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+
+UA_Int32 SL_Channel_getTokenId(SL_secureChannel channel, UA_UInt32 *tokenId)
+{
+	if(channel)
+	{
+		*tokenId = ((SL_Channel1*)channel)->securityToken.tokenId;
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+
+UA_Int32 SL_Channel_getLocalAsymAlgSettings(SL_secureChannel channel, UA_AsymmetricAlgorithmSecurityHeader **asymAlgSettings)
+{
+	UA_Int32 retval = 0;
+
+	retval |= UA_alloc((void**)asymAlgSettings,UA_AsymmetricAlgorithmSecurityHeader_calcSize(UA_NULL));
+
+	retval |= UA_ByteString_copy(&(channel->localAsymAlgSettings.receiverCertificateThumbprint),
+			&(*asymAlgSettings)->receiverCertificateThumbprint);
+	retval |= UA_ByteString_copy(&(channel->localAsymAlgSettings.securityPolicyUri),
+				&(*asymAlgSettings)->securityPolicyUri);
+	retval |= UA_ByteString_copy(&(channel->localAsymAlgSettings.senderCertificate),
+					&(*asymAlgSettings)->senderCertificate);
+
+	return UA_SUCCESS;
+}
+UA_Int32 SL_Channel_getConnection(SL_secureChannel channel, UA_TL_Connection1 *connection)
+{
+	if(channel)
+	{
+		*connection = ((SL_Channel1*)channel)->connection;
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+UA_Int32 SL_Channel_getRequestId(SL_secureChannel channel, UA_UInt32 *requestId)
+{
+	if(channel)
+	{
+		*requestId = ((SL_Channel1*)channel)->requestId;
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+UA_Int32 SL_Channel_getSequenceNumber(SL_secureChannel channel, UA_UInt32 *sequenceNumber)
+{
+	if(channel)
+	{
+		*sequenceNumber = ((SL_Channel1*)channel)->sequenceNumber;
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+UA_Int32 SL_Channel_getState(SL_secureChannel channel,SL_channelState *channelState)
+{
+	if(channel)
+	{
+		*channelState = ((SL_Channel1*)channel)->state;
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+
+UA_Int32 SL_Channel_getRevisedLifetime(SL_secureChannel channel, UA_UInt32 *revisedLifetime)
+{
+	if(channel)
+	{
+		*revisedLifetime = ((SL_Channel1*)channel)->securityToken.revisedLifetime;
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+
+//setters
+UA_Int32 SL_Channel_setId(SL_secureChannel channel, UA_UInt32 id)
+{
+	((SL_Channel1*)channel)->channelId = id;
+	return UA_SUCCESS;
+}
+
+//private function
+UA_Int32 SL_Channel_setState(SL_secureChannel channel,SL_channelState channelState)
+{
+	((SL_Channel1*)channel)->state = channelState;
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_Channel_init(SL_secureChannel channel,
+		UA_ByteString *receiverCertificateThumbprint,
+		UA_ByteString *securityPolicyUri,
+		UA_ByteString *senderCertificate,
+		UA_MessageSecurityMode securityMode)
+{
+	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_ByteString_copy(receiverCertificateThumbprint,
+			&((SL_Channel1*)channel)->localAsymAlgSettings.receiverCertificateThumbprint);
+
+	retval |= UA_ByteString_copy(securityPolicyUri,
+			&((SL_Channel1*)channel)->localAsymAlgSettings.securityPolicyUri);
+
+	retval |= UA_ByteString_copy(senderCertificate,
+			&((SL_Channel1*)channel)->localAsymAlgSettings.senderCertificate);
+
+
+
+	((SL_Channel1*)channel)->state = UA_SL_CHANNEL_CLOSED;
+	return retval;
+}
+//TODO implement real nonce generator - DUMMY function
+UA_Int32 SL_Channel_generateNonce(UA_ByteString *nonce)
+{
+	UA_ByteString_new(&nonce);
+	UA_alloc((void**)&(nonce->data),1);
+	nonce->length = 1;
+	nonce->data[0] = 'a';
+	return UA_SUCCESS;
+}
+
+_Bool SL_Channel_equal(void* channel1, void* channel2)
+{
+	return (((SL_Channel1*)channel1)->channelId == ((SL_Channel1*)channel2)->channelId);
+}
+
+UA_Int32 SL_Channel_new(SL_secureChannel *channel,
+		SL_ChannelIdProvider channelIdProvider,
+		SL_ChannelSecurityTokenProvider tokenProvider,
+		UA_ByteString *receiverCertificateThumbprint,
+		UA_ByteString *securityPolicyUri,
+		UA_ByteString *senderCertificate,
+		UA_MessageSecurityMode securityMode)
+
+{
+	UA_Int32 retval = UA_SUCCESS;
+	retval |= UA_alloc((void**)channel,sizeof(SL_Channel1));
+	SL_Channel1 *thisChannel = (SL_Channel1*)(*channel);
+
+	thisChannel->channelIdProvider = channelIdProvider;
+	thisChannel->tokenProvider = tokenProvider;
+
+	retval |= UA_ByteString_copy(receiverCertificateThumbprint,
+			&thisChannel->localAsymAlgSettings.receiverCertificateThumbprint);
+
+	retval |= UA_ByteString_copy(securityPolicyUri,
+			&thisChannel->localAsymAlgSettings.securityPolicyUri);
+
+	retval |= UA_ByteString_copy(senderCertificate,
+			&thisChannel->localAsymAlgSettings.senderCertificate);
+
+
+
+	thisChannel->state = UA_SL_CHANNEL_CLOSED;
+
+
+	return UA_SUCCESS;
+}
+UA_Int32 SL_Channel_initByRequest(SL_secureChannel channel,
+		UA_TL_Connection1 connection,
+		const UA_ByteString* msg,
+		UA_Int32* pos)
+{
+
+	UA_SequenceHeader *sequenceHeader;
+
+	UA_SequenceHeader_new(&sequenceHeader);
+	UA_SequenceHeader_init(sequenceHeader);
+
+
+	((SL_Channel1*)channel)->channelIdProvider(&((SL_Channel1*)channel)->channelId);
+
+	((SL_Channel1*)channel)->connection = connection;
+
+//	channel->createdAt = UA_DateTime_now();
+
+//	channel->localAsymAlgSettings.receiverCertificateThumbprint
+
+
+	SL_Channel_generateNonce(&channel->localNonce);
+
+
+
+	*pos += 4; // skip the securechannelid
+	UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos,
+			&channel->remoteAsymAlgSettings);
+
+	UA_SequenceHeader_decodeBinary(msg, pos,
+			sequenceHeader);
+
+
+	//init last requestId and sequenceNumber
+
+	channel->lastRequestId = sequenceHeader->requestId;
+	channel->lastSequenceNumber = sequenceHeader->sequenceNumber;
+
+	channel->state = UA_SL_CHANNEL_CLOSED;
+
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_Channel_delete(SL_secureChannel channel)
+{
+	//TODO implement me!
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_Channel_deleteMembers(SL_secureChannel channel)
+{
+	//TODO implement me!
+	return UA_SUCCESS;
+}
+UA_Int32 SL_Channel_processTokenRequest(SL_secureChannel channel,UA_UInt32 requestedLifetime, UA_SecurityTokenRequestType requestType)
+{
+	if(((SL_Channel1*)channel)->tokenProvider)
+	{
+		return ((SL_Channel1*)channel)->tokenProvider(channel,requestedLifetime,requestType, &((SL_Channel1*)channel)->securityToken);
+	}
+		printf("SL_Channel_processTokenRequest - no Token provider registered");
+		return UA_ERROR;
+}
+UA_Int32 SL_Channel_renewToken(SL_secureChannel channel, UA_UInt32 tokenId,UA_DateTime revisedLifetime, UA_DateTime createdAt)
+{
+	((SL_Channel1*)channel)->securityToken.tokenId = tokenId;
+	((SL_Channel1*)channel)->securityToken.createdAt = createdAt;
+	((SL_Channel1*)channel)->securityToken.revisedLifetime = revisedLifetime;
+	return UA_SUCCESS;
+}
+
+
+UA_Int32 SL_Channel_checkSequenceNumber(SL_secureChannel channel, UA_UInt32 sequenceNumber)
+{
+	if(((SL_Channel1*)channel)->sequenceNumber == sequenceNumber){
+		return UA_SUCCESS;
+	}
+	printf("SL_Channel_checkSequenceNumber - ERROR, wrong SequenceNumber expected: %i, received: %i",
+			((SL_Channel1*)channel)->sequenceNumber,sequenceNumber);
+	return UA_ERROR;
+
+}
+
+UA_Int32 SL_Channel_processOpenRequest(SL_secureChannel channel,
+		const UA_OpenSecureChannelRequest* request, UA_OpenSecureChannelResponse* response)
+{
+	UA_UInt32 protocolVersion;
+	SL_Channel1 *thisChannel = (SL_Channel1*)channel;
+	UA_Int32 retval = UA_SUCCESS;
+
+	UA_TL_Connection_getProtocolVersion(thisChannel->connection, &protocolVersion);
+
+	if (request->clientProtocolVersion
+			!= protocolVersion)
+	{
+		printf("SL_Channel_processOpenRequest - error protocol version \n");
+		//TODO ERROR_Bad_ProtocolVersionUnsupported
+	}
+
+	switch (request->requestType)
+	{
+	case UA_SECURITYTOKEN_ISSUE:
+		if (thisChannel->state == UA_SL_CHANNEL_OPEN)
+		{
+			printf("SL_Channel_processOpenRequest - multiple security token request");
+			//TODO return ERROR
+			retval = UA_ERROR;
+			break;
+		}
+		printf(
+				"SL_Channel_processOpenRequest - creating new token for a new SecureChannel\n");
+
+
+		SL_Channel_processTokenRequest(channel,request->requestedLifetime, request->requestType);
+		//	SL_createNewToken(connection);
+		break;
+	case UA_SECURITYTOKEN_RENEW:
+		if (thisChannel->state == UA_SL_CHANNEL_CLOSED)
+		{
+			printf(
+					"SL_Channel_processOpenRequest - renew token request received, but no secureChannel was established before");
+			//TODO return ERROR
+			retval = UA_ERROR;
+			break;
+		}
+		else
+		{
+			//generate new SecurityToken
+			retval = SL_Channel_processTokenRequest(channel,request->requestedLifetime, request->requestType);
+			if (retval != UA_SUCCESS)
+			{
+				printf(
+						"SL_Channel_processOpenRequest - creating new token for an existing SecureChannel\n");
+			}
+			else
+			{
+				printf(
+						"SL_Channel_processOpenRequest - cannot create new token for an existing SecureChannel\n");
+			}
+
+			break;
+		}
+	}
+
+	switch (request->securityMode)
+	{
+	case UA_SECURITYMODE_INVALID:
+		thisChannel->remoteNonce.data = UA_NULL;
+		thisChannel->remoteNonce.length = -1;
+		printf("SL_Channel_processOpenRequest - client demands no security \n");
+		break;
+
+	case UA_SECURITYMODE_SIGN:
+		printf("SL_Channel_processOpenRequest - client demands signed \n");
+		//TODO check if senderCertificate and ReceiverCertificateThumbprint are present
+		break;
+
+	case UA_SECURITYMODE_SIGNANDENCRYPT:
+		printf("SL_Channel_processOpenRequest - client demands signed & encrypted \n");
+		//TODO check if senderCertificate and ReceiverCertificateThumbprint are present
+		break;
+	}
+
+	thisChannel->state = 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 = protocolVersion;
+	SL_Channel_getChannelId(channel,&response->securityToken.channelId);
+
+	SL_Channel_getTokenId(channel, &response->securityToken.tokenId);
+	SL_Channel_getRevisedLifetime(channel, &response->securityToken.revisedLifetime);
+
+	UA_ByteString_copy(&thisChannel->localNonce, &response->serverNonce);
+
+
+	return retval;
+}
+
+UA_Int32 SL_Channel_processCloseRequest(SL_secureChannel channel,
+		const UA_CloseSecureChannelRequest* request)
+{
+	SL_Channel_setState(channel,UA_SL_CHANNEL_CLOSED);
+	return UA_SUCCESS;
+}
+
+

+ 110 - 0
src/ua_stack_channel.h

@@ -0,0 +1,110 @@
+/*
+ * ua_stack_channel.h
+ *
+ *  Created on: 09.05.2014
+ *      Author: root
+ */
+
+#ifndef UA_STACK_CHANNEL_H_
+#define UA_STACK_CHANNEL_H_
+
+#include <stdio.h>
+#include <memory.h> // memcpy
+#include "opcua.h"
+#include "ua_transport_connection.h"
+
+typedef enum ChannelState {
+	UA_SL_CHANNEL_CLOSING,
+	UA_SL_CHANNEL_CLOSED,
+	UA_SL_CHANNEL_OPENING,
+	UA_SL_CHANNEL_OPEN
+}SL_channelState;
+//hide object behind typedef
+typedef struct SL_Channel1 *SL_secureChannel;
+typedef UA_Int32 (*SL_ChannelSecurityTokenProvider)(SL_secureChannel ,UA_Int32 , SecurityTokenRequestType, UA_ChannelSecurityToken*);
+typedef UA_Int32 (*SL_ChannelIdProvider)(UA_UInt32*);
+
+
+
+UA_Int32 SL_Channel_new(SL_secureChannel *channel,
+		SL_ChannelIdProvider channelIdProvider,
+		SL_ChannelSecurityTokenProvider tokenProvider,
+		UA_ByteString *receiverCertificateThumbprint,
+		UA_ByteString *securityPolicyUri,
+		UA_ByteString *senderCertificate,
+		UA_MessageSecurityMode securityMode);
+
+UA_Int32 SL_Channel_init(SL_secureChannel channel,
+		UA_ByteString *receiverCertificateThumbprint,
+		UA_ByteString *securityPolicyUri,
+		UA_ByteString *senderCertificate, UA_MessageSecurityMode securityMode);
+
+UA_Int32 SL_Channel_initByRequest(SL_secureChannel channel, UA_TL_Connection1 connection, const UA_ByteString* msg,
+		UA_Int32* pos);
+
+UA_Int32 SL_Channel_initMembers(SL_secureChannel channel,
+		UA_TL_Connection1 *connection,
+		UA_UInt32 connectionId,
+		UA_UInt32 sequenceNumber,
+		UA_UInt32 requestId,
+		UA_MessageSecurityMode securityMode,
+		UA_ByteString *remoteNonce,
+		UA_ByteString *localNonce,
+		UA_ByteString *receiverCertificateThumbprint,
+		UA_ByteString *securityPolicyUri,
+		UA_ByteString *senderCertificate);
+
+UA_Int32 SL_Channel_delete(SL_secureChannel channel);
+UA_Int32 SL_Channel_deleteMembers(SL_secureChannel channel);
+UA_Int32 SL_Channel_renewToken(SL_secureChannel channel, UA_UInt32 tokenId, UA_DateTime revisedLifetime, UA_DateTime createdAt);
+UA_Int32 SL_Channel_processOpenRequest(SL_secureChannel channel,
+		const UA_OpenSecureChannelRequest* request, UA_OpenSecureChannelResponse* response);
+UA_Int32 SL_Channel_processCloseRequest(SL_secureChannel channel,
+		const UA_CloseSecureChannelRequest* request);
+UA_Int32 SL_Channel_registerTokenProvider(SL_secureChannel channel,SL_ChannelSecurityTokenProvider provider);
+UA_Int32 SL_Channel_registerChannelIdProvider(SL_ChannelIdProvider provider);
+UA_Int32 SL_Channel_checkSequenceNumber(SL_secureChannel channel, UA_UInt32 sequenceNumber);
+_Bool SL_Channel_equal(void* channel1, void* channel2);
+//getters
+UA_Int32 SL_Channel_getChannelId(SL_secureChannel channel, UA_UInt32 *channelId);
+UA_Int32 SL_Channel_getTokenId(SL_secureChannel channel, UA_UInt32 *tokenlId);
+UA_Int32 SL_Channel_getSequenceNumber(SL_secureChannel channel, UA_UInt32 *sequenceNumber);
+UA_Int32 SL_Channel_getRequestId(SL_secureChannel channel, UA_UInt32 *requestId);
+UA_Int32 SL_Channel_getConnectionId(SL_secureChannel channel, UA_UInt32 *connectionId);
+UA_Int32 SL_Channel_getConnection(SL_secureChannel channel, UA_TL_Connection1 *connection);
+UA_Int32 SL_Channel_getState(SL_secureChannel channel, SL_channelState *channelState);
+UA_Int32 SL_Channel_getLocalAsymAlgSettings(SL_secureChannel channel, UA_AsymmetricAlgorithmSecurityHeader **asymAlgSettings);
+UA_Int32 SL_Channel_getRemainingLifetime(SL_secureChannel channel, UA_Int32 *lifetime);
+
+UA_Int32 SL_Channel_getRevisedLifetime(SL_secureChannel channel, UA_UInt32 *revisedLifetime);
+
+
+//setters
+UA_Int32 SL_Channel_setId(SL_secureChannel channel, UA_UInt32 id);
+
+
+
+/*
+typedef struct SL_ChannelManager {
+	UA_UInt32 maxChannelCount;
+	UA_Int32 lastChannelId;
+	UA_UInt32 currentChannelCount;
+	UA_DateTime maxChannelLifeTime;
+	UA_indexedList_List channels;
+	UA_MessageSecurityMode securityMode;
+	UA_String *endpointUrl;
+}SL_ChannelManager;
+
+UA_Int32 SL_ChannelManager_init(SL_ChannelManager *channelManager, UA_UInt32 maxChannelCount, UA_Int32 startChannelId);
+UA_Int32 SL_ChannelManager_addChannel(SL_secureChannel channel);
+UA_Int32 SL_ChannelManager_renewChannelToken(UA_Int32 channelId, UA_DateTime requestedLifeTime);
+UA_Int32 SL_ChannelManager_bindChannel(UA_Int32 channelId, UA_TL_Connection1 connection);
+UA_Int32 SL_ChannelManager_removeChannel(UA_Int32 channelId);
+UA_Int32 SL_ChannelManager_getChannel(UA_Int32 channelId, SL_secureChannel *channel);
+UA_Int32 SL_ChannelManager_updateChannels();
+
+*/
+
+
+
+#endif /* UA_STACK_CHANNEL_H_ */

+ 204 - 0
src/ua_stack_channel_manager.c

@@ -0,0 +1,204 @@
+/*
+ * ua_stack_channel_manager.c
+ *
+ *  Created on: 09.05.2014
+ *      Author: root
+ */
+
+
+#include "ua_stack_channel_manager.h"
+
+typedef struct SL_ChannelManager {
+	UA_UInt32 maxChannelCount;
+	UA_Int32 lastChannelId;
+	UA_UInt32 currentChannelCount;
+	UA_DateTime maxChannelLifeTime;
+	UA_list_List channels;
+	UA_MessageSecurityMode securityMode;
+	UA_String endpointUrl;
+	UA_DateTime channelLifeTime;
+	UA_UInt32 lastTokenId;
+}SL_ChannelManager;
+static SL_ChannelManager *channelManager;
+/*
+UA_Int32 SL_ChannelManager_newChannelByRequest(UA_Int32 connectionId, const UA_ByteString* msg,
+		UA_Int32* pos, SL_secureChannel *newChannel)
+{
+	UA_UInt32 channelId = 0;
+	SL_Channel_newChannelByRequest(connectionId, msg, pos, newChannel);
+
+	SL_ChannelManager_addChannel(newChannel, &channelId);
+	SL_Channel_setId(newChannel, channelId);
+	return UA_SUCCESS;
+}
+*/
+UA_Int32 SL_ChannelManager_init(UA_UInt32 maxChannelCount,UA_UInt32 tokenLifetime, UA_UInt32 startChannelId, UA_UInt32 startTokenId, UA_String *endpointUrl)
+{
+	UA_alloc((void**)&channelManager,sizeof(SL_ChannelManager));
+	UA_indexedList_init(&(channelManager->channels));
+	channelManager->lastChannelId = startChannelId;
+	channelManager->lastTokenId = startTokenId;
+	UA_String_copy(endpointUrl,&channelManager->endpointUrl);
+	channelManager->maxChannelLifeTime = tokenLifetime;
+	channelManager->maxChannelCount = maxChannelCount;
+
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_ChannelManager_addChannel(SL_secureChannel channel)
+{
+	if (channelManager->maxChannelCount < channelManager->currentChannelCount)
+	{
+//TODO lock access (mulitthreading)------------
+		UA_list_addPayloadToBack(&channelManager->channels,(void*)channel);
+		//set id in channel object which was added
+//TODO lock access------------
+	}
+	return UA_SUCCESS;
+}
+
+UA_Int32 generateNewTokenId()
+{
+	//TODO lock accesss
+	return channelManager->lastTokenId++;
+}
+
+UA_Int32 SL_ChannelManager_generateChannelId(UA_UInt32 *newChannelId)
+{
+	if(channelManager)
+	{
+		*newChannelId = channelManager->lastChannelId++;
+		return UA_SUCCESS;
+	}
+	return UA_ERROR;
+}
+
+UA_UInt32 SL_ChannelManager_generateNewTokenId()
+{
+	return channelManager->lastTokenId++;
+}
+
+UA_Int32 SL_ChannelManager_generateToken(SL_secureChannel channel, UA_Int32 requestedLifeTime,
+		SecurityTokenRequestType requestType,
+		UA_ChannelSecurityToken* newToken)
+{
+	UA_UInt32 tokenId;
+	if(channel){
+		SL_Channel_getTokenId(channel,&tokenId);
+		if(requestType==UA_SECURITYTOKEN_ISSUE)
+		{
+			SL_Channel_getChannelId(channel,&newToken->channelId);
+			newToken->createdAt = UA_DateTime_now();
+			newToken->revisedLifetime = requestedLifeTime > channelManager->maxChannelLifeTime ? channelManager->maxChannelLifeTime : requestedLifeTime;
+			newToken->tokenId = SL_ChannelManager_generateNewTokenId();
+			return UA_SUCCESS;
+		}
+		else if(requestType==UA_SECURITYTOKEN_RENEW)
+		{
+			SL_Channel_getChannelId(channel,&newToken->channelId);
+			newToken->createdAt = UA_DateTime_now();
+			newToken->revisedLifetime = requestedLifeTime > channelManager->maxChannelLifeTime ? channelManager->maxChannelLifeTime : requestedLifeTime;
+			return UA_SUCCESS;
+		}
+		else
+		{
+			return UA_ERROR;
+		}
+	}
+	return UA_ERROR;
+}
+
+UA_Int32 SL_ChannelManager_processOpenRequest(SL_secureChannel channel,
+		const UA_OpenSecureChannelRequest* request, UA_OpenSecureChannelResponse* response)
+{
+
+
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_ChannelManager_updateChannels()
+{
+	//TODO lock access
+	UA_Int32 channelLifetime;
+	UA_UInt32 channelId;
+	UA_list_Element* current = channelManager->channels.first;
+	while (current)
+	{
+		if (current->payload)
+		{
+			UA_indexedList_Element* elem =
+					(UA_indexedList_Element*) current->payload;
+			SL_secureChannel *channel = (SL_secureChannel*) elem->payload;
+			//remove channels with expired lifetime, close linked list
+			if (channel)
+			{
+
+				SL_Channel_getRemainingLifetime(*channel,&channelLifetime);
+				if(channelLifetime <= 0)
+				{
+					//removeChannel
+				}
+			}
+			else
+			{
+				SL_Channel_getChannelId(*channel, &channelId);
+				//not possible to remove channel
+				printf(
+						"UA_SL_ChannelManager_updateChannels - could not remove channel with id: %i \n",
+						channelId);
+				return UA_SUCCESS;
+			}
+		}
+	}
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_ChannelManager_removeChannel(UA_Int32 channelId)
+{
+	//TODO lock access
+	SL_secureChannel channel;
+	SL_ChannelManager_getChannel(channelId, &channel);
+	UA_list_Element *element =  UA_list_search(&channelManager->channels, SL_Channel_equal, channel);
+
+	if (element)
+	{
+		element->next->prev = element->prev;
+		element->prev->next = element->next;
+
+		SL_Channel_delete((SL_secureChannel)element->payload);
+		//TODO notify server application that secureChannel has been closed part 6 - §7.1.4
+	}
+	//channel not found
+	return UA_ERROR;
+}
+UA_Int32 SL_ChannelManager_getChannelLifeTime(UA_DateTime *lifeTime)
+{
+	*lifeTime = channelManager->channelLifeTime;
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_ChannelManager_getChannelsByConnectionId(UA_Int32 connectionId,
+		SL_secureChannel **channels, UA_Int32 *noOfChannels)
+{
+	return UA_SUCCESS;
+}
+
+UA_Int32 SL_ChannelManager_getChannel(UA_UInt32 channelId, SL_secureChannel *channel)
+{
+	UA_list_Element* current = channelManager->channels.first;
+	while (current)
+	{
+		if (current->payload)
+		{
+			UA_indexedList_Element* elem =
+					(UA_indexedList_Element*) current->payload;
+			*channel = (SL_secureChannel) elem->payload;
+
+			return UA_SUCCESS;
+
+		}
+	}
+	*channel = UA_NULL;
+	return UA_ERROR;
+}
+

+ 38 - 0
src/ua_stack_channel_manager.h

@@ -0,0 +1,38 @@
+/*
+ * ua_stack_channel_manager.h
+ *
+ *  Created on: 09.05.2014
+ *      Author: root
+ */
+
+#ifndef UA_STACK_CHANNEL_MANAGER_H_
+#define UA_STACK_CHANNEL_MANAGER_H_
+
+#include "ua_stack_channel.h"
+
+
+
+//hide internal data of channelManager
+typedef struct SL_ChannelManager *SL_secureChannelManager;
+
+
+UA_Int32 SL_ChannelManager_init(UA_UInt32 maxChannelCount,UA_UInt32 tokenLifetime, UA_UInt32 startChannelId, UA_UInt32 startTokenId, UA_String *endpointUrl);
+UA_Int32 SL_ChannelManager_addChannel(SL_secureChannel channel);
+//UA_Int32 SL_ChannelManager_renewChannelToken(UA_Int32 channelId, UA_DateTime requestedLifeTime);
+//UA_Int32 SL_ChannelManager_createChannelToken(SL_secureChannel channel);
+//UA_Int32 SL_ChannelManager_renewChannelToken(SL_secureChannel channel);
+
+//UA_Int32 SL_ChannelManager_bindChannel(UA_Int32 channelId, TL_Connection *connection);
+UA_Int32 SL_ChannelManager_removeChannel(UA_Int32 channelId);
+UA_Int32 SL_ChannelManager_getChannel(UA_UInt32 channelId, SL_secureChannel *channel);
+
+UA_Int32 SL_ChannelManager_updateChannels();
+
+UA_Int32 SL_ChannelManager_getChannelLifeTime(UA_DateTime *lifeTime);
+
+UA_Int32 SL_ChannelManager_generateToken(SL_secureChannel channel, UA_Int32 requestedLifeTime, SecurityTokenRequestType requestType, UA_ChannelSecurityToken* newToken);
+
+UA_Int32 SL_ChannelManager_generateChannelId(UA_UInt32 *newChannelId);
+
+
+#endif /* UA_STACK_CHANNEL_MANAGER_H_ */

+ 63 - 0
src/ua_transport_connection_manager.c

@@ -0,0 +1,63 @@
+/*
+ * ua_connection_manager.c
+ *
+ *  Created on: 11.05.2014
+ *      Author: open62541
+ */
+
+#include "ua_transport_connection_manager.h"
+#include "ua_indexedList.h"
+typedef struct UA_TL_ConnectionManager
+{
+	UA_indexedList_List connections;
+	UA_UInt32 maxConnectionCount;
+	UA_UInt32 currentConnectionCount;
+}UA_TL_ConnectionManager;
+
+
+static UA_TL_ConnectionManager *connectionManager = UA_NULL;
+
+
+UA_Int32 UA_TL_ConnectionManager_init(UA_UInt32 maxConnectionCount)
+{
+	UA_Int32 retval = UA_SUCCESS;
+	if(connectionManager)
+	{
+		//connectionManager already exists;
+	}
+	else
+	{
+		retval |= UA_alloc((void**)connectionManager,sizeof(UA_TL_ConnectionManager));
+		connectionManager->maxConnectionCount = maxConnectionCount;
+		connectionManager->currentConnectionCount = 0;
+		retval |= UA_indexedList_init(&connectionManager->connections);
+	}
+	return UA_SUCCESS;
+}
+UA_Int32 UA_TL_ConnectionManager_addConnection(UA_TL_Connection1 *connection)
+{
+	UA_UInt32 connectionId;
+	UA_TL_Connection_getId(*connection, &connectionId);
+	return UA_indexedList_addValue(&(connectionManager->connections), connectionId, connection);
+}
+
+
+UA_Int32 UA_TL_ConnectionManager_removeConnection(UA_TL_Connection1 connection)
+{
+	UA_UInt32 connectionId;
+	UA_TL_Connection_getId(connection, &connectionId);
+	UA_TL_Connection1 foundValue = UA_indexedList_findValue(&connectionManager->connections,connectionId);
+	if(foundValue)
+	{
+		//remove connection
+	}
+	return UA_SUCCESS;
+}
+
+
+UA_Int32 UA_TL_ConnectionManager_getConnectionById(UA_Int32 connectionId, UA_TL_Connection1 *connection)
+{
+	return UA_SUCCESS;
+}
+
+

+ 20 - 0
src/ua_transport_connection_manager.h

@@ -0,0 +1,20 @@
+/*
+ * ua_connection_manager.h
+ *
+ *  Created on: 11.05.2014
+ *      Author: open62541
+ */
+
+#ifndef UA_CONNECTION_MANAGER_H_
+#define UA_CONNECTION_MANAGER_H_
+
+#include "ua_transport_connection.h"
+
+
+
+UA_Int32 UA_TL_ConnectionManager_addConnection(UA_TL_Connection1 *connection);
+UA_Int32 UA_TL_ConnectionManager_removeConnection(UA_TL_Connection1 connection);
+//getter
+UA_Int32 UA_TL_ConnectionManager_getConnectionById(UA_Int32 connectionId, UA_TL_Connection1 *connection);
+
+#endif /* UA_CONNECTION_MANAGER_H_ */