ua_transportLayer.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include <memory.h> // memset, memcpy
  2. #include "ua_stack.h"
  3. #include "ua_connection.h"
  4. #include "ua_transportLayer.h"
  5. #include "ua_secureLayer.h" // SL_process
  6. UA_Int32 TL_Connection_init(UA_TL_connection* c, UA_TL_data* tld)
  7. {
  8. c->connectionHandle = -1;
  9. c->connectionState = connectionState_CLOSED;
  10. c->readerThread = -1;
  11. c->UA_TL_writer = UA_NULL;
  12. memcpy(&(c->localConf),&(tld->tld->localConf),sizeof(TL_buffer));
  13. memset(&(c->remoteConf),0,sizeof(TL_buffer));
  14. UA_String_copy(&(tld->endpointUrl), &(c->localEndpointUrl));
  15. return UA_SUCCESS;
  16. }
  17. UA_Int32 TL_check(UA_TL_connection* connection, UA_ByteString* msg, int checkLocal)
  18. {
  19. UA_Int32 retval = UA_SUCCESS;
  20. UA_Int32 position = 4;
  21. UA_Int32 messageLength;
  22. DBG_VERBOSE(printf("TL_check - entered \n"));
  23. UA_Int32_decodeBinary(msg,&position,&messageLength);
  24. DBG_VERBOSE(printf("TL_check - messageLength = %d \n",messageLength));
  25. if (messageLength == -1 || messageLength != msg->length ||
  26. ( ( checkLocal == UA_TL_CHECK_LOCAL) && messageLength > (UA_Int32) connection->localConf.maxMessageSize) ||
  27. ( ( checkLocal == UA_TL_CHECK_REMOTE) && messageLength > (UA_Int32) connection->remoteConf.maxMessageSize))
  28. {
  29. DBG_ERR(printf("TL_check - length error \n"));
  30. retval = UA_ERR_INCONSISTENT;
  31. }
  32. return retval;
  33. }
  34. #define Cmp3Byte(data,pos,a,b,c) (*((Int32*) ((data)+(pos))) & 0xFFFFFF) == (Int32)(((Byte)(a))|((Byte)(b))<<8|((Byte)(c))<<16)
  35. UA_Int32 UA_TL_handleHello(UA_TL_connection* connection, UA_ByteString* msg, UA_Int32* pos) {
  36. UA_Int32 retval = UA_SUCCESS;
  37. UA_Int32 tmpPos = 0;
  38. UA_ByteString tmpMessage;
  39. UA_OPCUATcpHelloMessage helloMessage;
  40. UA_OPCUATcpAcknowledgeMessage ackMessage;
  41. UA_OPCUATcpMessageHeader ackHeader;
  42. if (connection->connectionState == connectionState_CLOSED) {
  43. DBG_VERBOSE(printf("TL_process - extracting header information \n"));
  44. UA_OPCUATcpHelloMessage_decodeBinary(msg,pos,&helloMessage);
  45. // memorize buffer info and change mode to established
  46. connection->remoteConf.protocolVersion = helloMessage.protocolVersion;
  47. connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize;
  48. connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize;
  49. connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize;
  50. connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount;
  51. UA_String_copy(&(helloMessage.endpointUrl), &(connection->remoteEndpointUrl));
  52. connection->connectionState = connectionState_ESTABLISHED;
  53. // clean up
  54. UA_OPCUATcpHelloMessage_deleteMembers(&helloMessage);
  55. DBG_VERBOSE(printf("TL_process - protocolVersion = %d \n",connection->remoteConf.protocolVersion));
  56. DBG_VERBOSE(printf("TL_process - recvBufferSize = %d \n",connection->remoteConf.recvBufferSize));
  57. DBG_VERBOSE(printf("TL_process - sendBufferSize = %d \n",connection->remoteConf.sendBufferSize));
  58. DBG_VERBOSE(printf("TL_process - maxMessageSize = %d \n",connection->remoteConf.maxMessageSize));
  59. DBG_VERBOSE(printf("TL_process - maxChunkCount = %d \n",connection->remoteConf.maxChunkCount));
  60. // build acknowledge response
  61. ackMessage.protocolVersion = connection->localConf.protocolVersion;
  62. ackMessage.receiveBufferSize = connection->localConf.recvBufferSize;
  63. ackMessage.sendBufferSize = connection->localConf.sendBufferSize;
  64. ackMessage.maxMessageSize = connection->localConf.maxMessageSize;
  65. ackMessage.maxChunkCount = connection->localConf.maxChunkCount;
  66. ackHeader.messageType = UA_MESSAGETYPE_ACK;
  67. ackHeader.isFinal = 'F';
  68. // encode header and message to buffer
  69. ackHeader.messageSize = UA_OPCUATcpAcknowledgeMessage_calcSize(&ackMessage)
  70. + UA_OPCUATcpMessageHeader_calcSize(&ackHeader);
  71. UA_ByteString_newMembers(&tmpMessage, ackHeader.messageSize);
  72. UA_OPCUATcpMessageHeader_encodeBinary(&ackHeader,&tmpPos,&tmpMessage);
  73. UA_OPCUATcpAcknowledgeMessage_encodeBinary(&ackMessage,&tmpPos,&tmpMessage);
  74. DBG_VERBOSE(printf("TL_process - Size messageToSend = %d, pos=%d\n",ackHeader.messageSize, tmpPos));
  75. TL_send(connection, &tmpMessage);
  76. UA_ByteString_deleteMembers(&tmpMessage);
  77. }
  78. else
  79. {
  80. DBG_ERR(printf("TL_process - wrong connection state \n"));
  81. retval = UA_ERROR_MULTIPLE_HEL;
  82. }
  83. return retval;
  84. }
  85. UA_Int32 UA_TL_handleOpen(UA_TL_connection* connection, UA_ByteString* msg, UA_Int32* pos) {
  86. UA_Int32 retval = UA_SUCCESS;
  87. if (connection->connectionState == connectionState_ESTABLISHED) {
  88. // create new secure channel and associate with this TL connection
  89. retval |= UA_SL_Channel_new(connection,msg,pos);
  90. } else {
  91. retval = UA_ERR_INVALID_VALUE;
  92. }
  93. return retval;
  94. }
  95. UA_Int32 UA_TL_handleMsg(UA_TL_connection* connection, UA_ByteString* msg, UA_Int32* pos) {
  96. UA_Int32 retval = UA_SUCCESS;
  97. UA_SL_Channel* slc = connection->secureChannel;
  98. retval |= UA_SL_process(slc,msg,pos);
  99. return retval;
  100. }
  101. UA_Int32 UA_TL_handleClo(UA_TL_connection* connection, UA_ByteString* msg, UA_Int32* pos) {
  102. UA_Int32 retval = UA_SUCCESS;
  103. UA_SL_Channel* slc = connection->secureChannel;
  104. retval |= UA_SL_process(slc,msg,pos);
  105. connection->connectionState = connectionState_CLOSE;
  106. return retval;
  107. }
  108. UA_Int32 TL_process(UA_TL_connection* connection, UA_ByteString* msg)
  109. {
  110. UA_Int32 retval = UA_SUCCESS;
  111. UA_Int32 pos = 0;
  112. UA_OPCUATcpMessageHeader tcpMessageHeader;
  113. DBG_VERBOSE(printf("TL_process - entered \n"));
  114. if ((retval = UA_OPCUATcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader)) == UA_SUCCESS) {
  115. printf("TL_process - messageType=%.*s\n",3,msg->data);
  116. switch(tcpMessageHeader.messageType) {
  117. case UA_MESSAGETYPE_HEL:
  118. retval = UA_TL_handleHello(connection, msg, &pos);
  119. break;
  120. case UA_MESSAGETYPE_OPN:
  121. retval = UA_TL_handleOpen(connection, msg, &pos);
  122. break;
  123. case UA_MESSAGETYPE_MSG:
  124. retval = UA_TL_handleMsg(connection, msg, &pos);
  125. break;
  126. case UA_MESSAGETYPE_CLO:
  127. retval = UA_TL_handleClo(connection, msg, &pos);
  128. break;
  129. default: // dispatch processing to secureLayer
  130. retval = UA_ERR_INVALID_VALUE;
  131. break;
  132. }
  133. }
  134. if (retval != UA_SUCCESS) {
  135. // FIXME: compose real error message
  136. UA_ByteString errorMsg;
  137. UA_ByteString_newMembers(&errorMsg,10);
  138. TL_send(connection,&errorMsg);
  139. UA_ByteString_deleteMembers(&errorMsg);
  140. }
  141. UA_OPCUATcpMessageHeader_deleteMembers(&tcpMessageHeader);
  142. return retval;
  143. }
  144. /** respond to client request */
  145. UA_Int32 TL_send(UA_TL_connection* connection, UA_ByteString* msg)
  146. {
  147. UA_Int32 retval = UA_SUCCESS;
  148. DBG_VERBOSE(printf("TL_send - entered \n"));
  149. if (TL_check(connection,msg,UA_TL_CHECK_REMOTE) == UA_SUCCESS) {
  150. connection->UA_TL_writer(connection,msg);
  151. }
  152. else
  153. {
  154. DBG_ERR(printf("TL_send - ERROR: packet size greater than remote buffer size"));
  155. retval = UA_ERROR;
  156. }
  157. return retval;
  158. }