#include #include "ua_transport_binary.h" #include "ua_transport.h" #include "ua_transport_binary_secure.h" 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; } return UA_SUCCESS; } UA_Int32 TL_handleHello(TL_connection* connection, UA_ByteString* msg, UA_Int32* pos) { UA_Int32 retval = UA_SUCCESS; UA_Int32 tmpPos = 0; UA_ByteString tmpMessage; UA_ByteString *tmpMessage_ptr = &tmpMessage; UA_OPCUATcpHelloMessage helloMessage; UA_OPCUATcpAcknowledgeMessage ackMessage; UA_OPCUATcpMessageHeader ackHeader; if (connection->connectionState == connectionState_CLOSED) { DBG_VERBOSE(printf("TL_process - extracting header information \n")); UA_OPCUATcpHelloMessage_decodeBinary(msg,pos,&helloMessage); // memorize buffer info and change mode to established connection->remoteConf.protocolVersion = helloMessage.protocolVersion; connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize; connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize; connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize; connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount; UA_String_copy(&(helloMessage.endpointUrl), &(connection->remoteEndpointUrl)); connection->connectionState = connectionState_ESTABLISHED; // clean up UA_OPCUATcpHelloMessage_deleteMembers(&helloMessage); DBG_VERBOSE(printf("TL_process - protocolVersion = %d \n",connection->remoteConf.protocolVersion)); DBG_VERBOSE(printf("TL_process - recvBufferSize = %d \n",connection->remoteConf.recvBufferSize)); DBG_VERBOSE(printf("TL_process - sendBufferSize = %d \n",connection->remoteConf.sendBufferSize)); DBG_VERBOSE(printf("TL_process - maxMessageSize = %d \n",connection->remoteConf.maxMessageSize)); DBG_VERBOSE(printf("TL_process - maxChunkCount = %d \n",connection->remoteConf.maxChunkCount)); // build acknowledge response ackMessage.protocolVersion = connection->localConf.protocolVersion; ackMessage.receiveBufferSize = connection->localConf.recvBufferSize; ackMessage.sendBufferSize = connection->localConf.sendBufferSize; ackMessage.maxMessageSize = connection->localConf.maxMessageSize; ackMessage.maxChunkCount = connection->localConf.maxChunkCount; ackHeader.messageType = UA_MESSAGETYPE_ACK; ackHeader.isFinal = 'F'; // encode header and message to buffer ackHeader.messageSize = UA_OPCUATcpAcknowledgeMessage_calcSize(&ackMessage) + UA_OPCUATcpMessageHeader_calcSize(&ackHeader); UA_ByteString_newMembers(&tmpMessage, ackHeader.messageSize); UA_OPCUATcpMessageHeader_encodeBinary(&ackHeader,&tmpPos,&tmpMessage); UA_OPCUATcpAcknowledgeMessage_encodeBinary(&ackMessage,&tmpPos,&tmpMessage); DBG_VERBOSE(printf("TL_process - Size messageToSend = %d, pos=%d\n",ackHeader.messageSize, tmpPos)); TL_send(connection, &tmpMessage_ptr, 1); UA_ByteString_deleteMembers(&tmpMessage); } else { DBG_ERR(printf("TL_process - wrong connection state \n")); retval = UA_ERROR_MULTIPLE_HEL; } return retval; } UA_Int32 TL_handleOpen(TL_connection* connection, UA_ByteString* msg, UA_Int32* pos) { if (connection->connectionState == connectionState_ESTABLISHED) { return SL_Channel_new(connection,msg,pos); // create new secure channel and associate with this TL connection } return UA_ERR_INVALID_VALUE; } UA_Int32 TL_handleMsg(TL_connection* connection, UA_ByteString* msg, UA_Int32* pos) { SL_Channel* slc = connection->secureChannel; return SL_process(slc,msg,pos); } UA_Int32 TL_handleClo(TL_connection* connection, UA_ByteString* msg, UA_Int32* pos) { SL_Channel* slc = connection->secureChannel; connection->connectionState = connectionState_CLOSE; return SL_process(slc,msg,pos); } UA_Int32 TL_process(TL_connection* connection, UA_ByteString* msg) { UA_Int32 retval = UA_SUCCESS; UA_Int32 pos = 0; UA_OPCUATcpMessageHeader tcpMessageHeader; DBG_VERBOSE(printf("TL_process - entered \n")); if ((retval = UA_OPCUATcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader)) == UA_SUCCESS) { printf("TL_process - messageType=%.*s\n",3,msg->data); switch(tcpMessageHeader.messageType) { case UA_MESSAGETYPE_HEL: retval = TL_handleHello(connection, msg, &pos); break; case UA_MESSAGETYPE_OPN: retval = TL_handleOpen(connection, msg, &pos); break; case UA_MESSAGETYPE_MSG: retval = TL_handleMsg(connection, msg, &pos); break; case UA_MESSAGETYPE_CLO: retval = TL_handleClo(connection, msg, &pos); break; default: // dispatch processing to secureLayer retval = UA_ERR_INVALID_VALUE; break; } } if (retval != UA_SUCCESS) { // FIXME: compose real error message UA_ByteString errorMsg; UA_ByteString *errorMsg_ptr = &errorMsg; UA_ByteString_newMembers(&errorMsg,10); TL_send(connection,&errorMsg_ptr, 1); UA_ByteString_deleteMembers(&errorMsg); } UA_OPCUATcpMessageHeader_deleteMembers(&tcpMessageHeader); return retval; } /** respond to client request */ UA_Int32 TL_send(TL_connection* connection, 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); //} /* else */ /* { */ /* DBG_ERR(printf("TL_send - ERROR: packet size greater than remote buffer size")); */ /* retval = UA_ERROR; */ /* } */ return retval; }