ua_transport_binary.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include <memory.h>
  2. #include "ua_transport_binary.h"
  3. #include "ua_transport.h"
  4. #include "ua_transport_binary_secure.h"
  5. #include "ua_transport_connection.h"
  6. static UA_Int32 TL_handleHello1(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_UInt32* pos){
  7. UA_Int32 retval = UA_SUCCESS;
  8. UA_UInt32 tmpPos = 0;
  9. UA_Int32 connectionState;
  10. UA_OPCUATcpHelloMessage helloMessage;
  11. UA_TL_Connection_getState(connection, &connectionState);
  12. if (connectionState == CONNECTIONSTATE_CLOSED){
  13. DBG_VERBOSE(printf("TL_handleHello - extracting header information \n"));
  14. UA_OPCUATcpHelloMessage_decodeBinary(msg,pos,&helloMessage);
  15. UA_TL_Connection_configByHello(connection, &helloMessage);
  16. DBG_VERBOSE(printf("TL_handleHello - protocolVersion = %d \n",connection->remoteConf.protocolVersion));
  17. DBG_VERBOSE(printf("TL_handleHello - recvBufferSize = %d \n",connection->remoteConf.recvBufferSize));
  18. DBG_VERBOSE(printf("TL_handleHello - sendBufferSize = %d \n",connection->remoteConf.sendBufferSize));
  19. DBG_VERBOSE(printf("TL_handleHello - maxMessageSize = %d \n",connection->remoteConf.maxMessageSize));
  20. DBG_VERBOSE(printf("TL_handleHello - maxChunkCount = %d \n",connection->remoteConf.maxChunkCount));
  21. // build acknowledge response
  22. UA_OPCUATcpAcknowledgeMessage ackMessage;
  23. TL_Buffer localConfig;
  24. UA_TL_Connection_getLocalConfiguration(connection, &localConfig);
  25. ackMessage.protocolVersion = localConfig.protocolVersion;
  26. ackMessage.receiveBufferSize = localConfig.recvBufferSize;
  27. ackMessage.sendBufferSize = localConfig.sendBufferSize;
  28. ackMessage.maxMessageSize = localConfig.maxMessageSize;
  29. ackMessage.maxChunkCount = localConfig.maxChunkCount;
  30. UA_OPCUATcpMessageHeader ackHeader;
  31. ackHeader.messageType = UA_MESSAGETYPE_ACK;
  32. ackHeader.isFinal = 'F';
  33. // encode header and message to buffer
  34. tmpPos = 0;
  35. ackHeader.messageSize = UA_OPCUATcpAcknowledgeMessage_calcSizeBinary(&ackMessage) + UA_OPCUATcpMessageHeader_calcSizeBinary(&ackHeader);
  36. UA_ByteString *ack_msg;
  37. UA_alloc((void **)&ack_msg, sizeof(UA_ByteString));
  38. UA_ByteString_newMembers(ack_msg, ackHeader.messageSize);
  39. UA_OPCUATcpMessageHeader_encodeBinary(&ackHeader,ack_msg,&tmpPos);
  40. UA_OPCUATcpAcknowledgeMessage_encodeBinary(&ackMessage, ack_msg,&tmpPos);
  41. DBG_VERBOSE(printf("TL_handleHello - Size messageToSend = %d, pos=%d\n",ackHeader.messageSize, tmpPos));
  42. DBG_VERBOSE(UA_ByteString_printx("_handleHello - ack=", ack_msg));
  43. TL_Send(connection, (const UA_ByteString **) &ack_msg, 1);
  44. DBG_VERBOSE(printf("TL_handleHello - finished writing\n"));
  45. UA_ByteString_delete(ack_msg);
  46. } else {
  47. DBG_ERR(printf("TL_handleHello - wrong connection state \n"));
  48. retval = UA_ERROR_MULTIPLE_HEL;
  49. }
  50. return retval;
  51. }
  52. /*
  53. static UA_Int32 TL_handleHello(TL_Connection* connection, const UA_ByteString* msg, UA_Int32* pos) {
  54. UA_Int32 retval = UA_SUCCESS;
  55. UA_Int32 tmpPos = 0;
  56. UA_OPCUATcpHelloMessage helloMessage;
  57. if (connection->connectionState == CONNECTIONSTATE_CLOSED) {
  58. DBG_VERBOSE(printf("TL_handleHello - extracting header information \n"));
  59. UA_OPCUATcpHelloMessage_decodeBinary(msg,pos,&helloMessage);
  60. // memorize buffer info and change mode to established
  61. connection->remoteConf.protocolVersion = helloMessage.protocolVersion;
  62. connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize;
  63. connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize;
  64. connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize;
  65. connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount;
  66. UA_String_copy(&(helloMessage.endpointUrl), &(connection->remoteEndpointUrl));
  67. UA_OPCUATcpHelloMessage_deleteMembers(&helloMessage);
  68. DBG_VERBOSE(printf("TL_handleHello - protocolVersion = %d \n",connection->remoteConf.protocolVersion));
  69. DBG_VERBOSE(printf("TL_handleHello - recvBufferSize = %d \n",connection->remoteConf.recvBufferSize));
  70. DBG_VERBOSE(printf("TL_handleHello - sendBufferSize = %d \n",connection->remoteConf.sendBufferSize));
  71. DBG_VERBOSE(printf("TL_handleHello - maxMessageSize = %d \n",connection->remoteConf.maxMessageSize));
  72. DBG_VERBOSE(printf("TL_handleHello - maxChunkCount = %d \n",connection->remoteConf.maxChunkCount));
  73. connection->connectionState = CONNECTIONSTATE_ESTABLISHED;
  74. // build acknowledge response
  75. UA_OPCUATcpAcknowledgeMessage ackMessage;
  76. ackMessage.protocolVersion = connection->localConf.protocolVersion;
  77. ackMessage.receiveBufferSize = connection->localConf.recvBufferSize;
  78. ackMessage.sendBufferSize = connection->localConf.sendBufferSize;
  79. ackMessage.maxMessageSize = connection->localConf.maxMessageSize;
  80. ackMessage.maxChunkCount = connection->localConf.maxChunkCount;
  81. UA_OPCUATcpMessageHeader ackHeader;
  82. ackHeader.messageType = UA_MESSAGETYPE_ACK;
  83. ackHeader.isFinal = 'F';
  84. // encode header and message to buffer
  85. tmpPos = 0;
  86. ackHeader.messageSize = UA_OPCUATcpAcknowledgeMessage_calcSize(&ackMessage) + UA_OPCUATcpMessageHeader_calcSize(&ackHeader);
  87. UA_ByteString *ack_msg;
  88. UA_alloc((void **)&ack_msg, sizeof(UA_ByteString));
  89. UA_ByteString_newMembers(ack_msg, ackHeader.messageSize);
  90. UA_OPCUATcpMessageHeader_encodeBinary(&ackHeader,&tmpPos,ack_msg);
  91. UA_OPCUATcpAcknowledgeMessage_encodeBinary(&ackMessage,&tmpPos,ack_msg);
  92. DBG_VERBOSE(printf("TL_handleHello - Size messageToSend = %d, pos=%d\n",ackHeader.messageSize, tmpPos));
  93. DBG_VERBOSE(UA_ByteString_printx("_handleHello - ack=", ack_msg));
  94. TL_Send(connection, (const UA_ByteString **) &ack_msg, 1);
  95. DBG_VERBOSE(printf("TL_handleHello - finished writing\n"));
  96. UA_ByteString_delete(ack_msg);
  97. } else {
  98. DBG_ERR(printf("TL_handleHello - wrong connection state \n"));
  99. retval = UA_ERROR_MULTIPLE_HEL;
  100. }
  101. return retval;
  102. }
  103. */
  104. static UA_Int32 TL_securitySettingsMockup_get(UA_ByteString *receiverCertificateThumbprint,UA_ByteString *securityPolicyUri, UA_ByteString *senderCertificate)
  105. {
  106. receiverCertificateThumbprint->data = UA_NULL;
  107. receiverCertificateThumbprint->length = 0;
  108. UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None",(UA_String*)securityPolicyUri);
  109. senderCertificate->data = UA_NULL;
  110. senderCertificate->length = 0;
  111. return UA_SUCCESS;
  112. }
  113. static UA_Int32 TL_handleOpen(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_UInt32* pos) {
  114. UA_Int32 retval = UA_SUCCESS;
  115. UA_Int32 state;
  116. SL_secureChannel *channel;
  117. UA_ByteString receiverCertificateThumbprint;
  118. UA_ByteString securityPolicyUri;
  119. UA_ByteString senderCertificate;
  120. /*TODO place this into a initialization routine, get this from the "stack"-object*/
  121. retval |= TL_securitySettingsMockup_get(&receiverCertificateThumbprint, &securityPolicyUri, &senderCertificate);
  122. retval |= UA_TL_Connection_getState(connection,&state);
  123. if (state == CONNECTIONSTATE_ESTABLISHED) {
  124. retval |= SL_Channel_new(&channel,
  125. SL_ChannelManager_generateChannelId,
  126. SL_ChannelManager_generateToken,
  127. &receiverCertificateThumbprint,
  128. &securityPolicyUri,
  129. &senderCertificate,
  130. UA_SECURITYMODE_INVALID);
  131. if(SL_Channel_initByRequest(*channel,connection, msg, pos) == UA_SUCCESS){
  132. retval |= SL_ProcessOpenChannel(*channel, msg, pos);
  133. retval |= SL_ChannelManager_addChannel(channel);
  134. return retval;
  135. }else{
  136. printf("TL_handleOpen - ERROR: could not create new secureChannel");
  137. }
  138. }
  139. else{
  140. printf("TL_handleOpen - ERROR: wrong ConnectionState");
  141. }
  142. return UA_ERR_INVALID_VALUE;
  143. }
  144. static UA_Int32 TL_handleMsg(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_UInt32* pos) {
  145. UA_Int32 state;
  146. UA_TL_Connection_getState(connection,&state);
  147. if (state == CONNECTIONSTATE_ESTABLISHED) {
  148. return SL_Process(msg, pos);
  149. }
  150. return UA_ERR_INVALID_VALUE;
  151. }
  152. static UA_Int32 TL_handleClo(UA_TL_Connection1 connection, const UA_ByteString* msg, UA_UInt32* pos) {
  153. UA_Int32 retval = UA_SUCCESS;
  154. UA_SecureConversationMessageHeader *header;
  155. retval |= UA_SecureConversationMessageHeader_new(&header);
  156. retval |= UA_SecureConversationMessageHeader_decodeBinary(msg,pos,header);
  157. retval |= SL_ChannelManager_removeChannel(header->secureChannelId);
  158. retval |= UA_SecureConversationMessageHeader_delete(header);
  159. //TODO remove that
  160. UA_TL_Connection_close(connection);
  161. return retval;
  162. }
  163. UA_Int32 TL_Process(UA_TL_Connection1 connection, const UA_ByteString* msg) {
  164. UA_Int32 retval = UA_SUCCESS;
  165. UA_UInt32 pos = 0;
  166. UA_OPCUATcpMessageHeader tcpMessageHeader;
  167. DBG_VERBOSE(printf("TL_Process - entered \n"));
  168. if ((retval = UA_OPCUATcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader)) == UA_SUCCESS) {
  169. printf("TL_Process - messageType=%.*s\n",3,msg->data);
  170. switch(tcpMessageHeader.messageType) {
  171. case UA_MESSAGETYPE_HEL:
  172. retval = TL_handleHello1(connection, msg, &pos);
  173. //retval = TL_handleHello(connection, msg, &pos);
  174. break;
  175. case UA_MESSAGETYPE_OPN:
  176. retval = TL_handleOpen(connection, msg, &pos);
  177. break;
  178. case UA_MESSAGETYPE_MSG:
  179. retval = TL_handleMsg(connection, msg, &pos);
  180. break;
  181. case UA_MESSAGETYPE_CLO:
  182. retval = TL_handleClo(connection, msg, &pos);
  183. break;
  184. default: // dispatch processing to secureLayer
  185. retval = UA_ERR_INVALID_VALUE;
  186. break;
  187. }
  188. }
  189. /* if (retval != UA_SUCCESS) { */
  190. /* // FIXME: compose real error message */
  191. /* UA_ByteString errorMsg; */
  192. /* UA_ByteString *errorMsg_ptr = &errorMsg; */
  193. /* UA_ByteString_newMembers(&errorMsg,10); */
  194. /* TL_Send(connection,(const UA_ByteString **)&errorMsg_ptr, 1); */
  195. /* UA_ByteString_deleteMembers(&errorMsg); */
  196. /* } */
  197. UA_OPCUATcpMessageHeader_deleteMembers(&tcpMessageHeader);
  198. return retval;
  199. }
  200. /** respond to client request */
  201. UA_Int32 TL_Send(UA_TL_Connection1 connection, const UA_ByteString** gather_buf, UA_UInt32 gather_len) {
  202. UA_Int32 retval = UA_SUCCESS;
  203. DBG_VERBOSE(printf("TL_send - entered \n"));
  204. // if (TL_check(connection,msg,TL_CHECK_REMOTE) == UA_SUCCESS) {
  205. retval = UA_TL_Connection_callWriter(connection, gather_buf, gather_len);
  206. DBG_VERBOSE(printf("TL_send - exited \n"));
  207. //}
  208. /* else */
  209. /* { */
  210. /* DBG_ERR(printf("TL_send - ERROR: packet size greater than remote buffer size")); */
  211. /* retval = UA_ERROR; */
  212. /* } */
  213. return retval;
  214. }