ua_client.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include "ua_client.h"
  2. #include "ua_types_encoding_binary.h"
  3. #include "ua_transport_generated.h"
  4. struct UA_Client {
  5. UA_ClientNetworkLayer networkLayer;
  6. void *connectionHandle;
  7. UA_String endpointUrl;
  8. UA_Connection connection;
  9. /* UA_UInt32 channelId; */
  10. /* UA_SequenceHeader sequenceHdr; */
  11. /* UA_NodeId authenticationToken; */
  12. /* UA_UInt32 tokenId; */
  13. /* UA_Connection *connection; */
  14. };
  15. UA_Client * UA_Client_new(void) {
  16. UA_Client *c = UA_malloc(sizeof(UA_Client));
  17. if(!c)
  18. return UA_NULL;
  19. UA_String_init(&c->endpointUrl);
  20. c->connection.state = UA_CONNECTION_OPENING;
  21. return c;
  22. }
  23. static UA_StatusCode HelAckHandshake(UA_Client *c);
  24. static UA_StatusCode SecureChannelHandshake(UA_Client *c);
  25. static UA_StatusCode SessionHandshake(UA_Client *c);
  26. static UA_StatusCode CloseSession(UA_Client *c);
  27. static UA_StatusCode CloseSecureChannel(UA_Client *c);
  28. UA_StatusCode UA_Client_connect(UA_Client *c, UA_ConnectionConfig conf, UA_ClientNetworkLayer networkLayer,
  29. char *endpointUrl) {
  30. UA_StatusCode retval = UA_String_copycstring(endpointUrl, &c->endpointUrl);
  31. if(retval != UA_STATUSCODE_GOOD)
  32. return UA_STATUSCODE_BADOUTOFMEMORY;
  33. c->networkLayer = networkLayer;
  34. c->connection.localConf = conf;
  35. retval = networkLayer.connect(c->endpointUrl, &c->connectionHandle);
  36. if(!retval != UA_STATUSCODE_GOOD)
  37. return retval;
  38. HelAckHandshake(c);
  39. // securechannel
  40. // session
  41. return UA_STATUSCODE_GOOD;
  42. }
  43. UA_StatusCode UA_EXPORT UA_Client_disconnect(UA_Client *c) {
  44. return UA_STATUSCODE_GOOD;
  45. }
  46. // The tcp connection is established. Now do the handshake
  47. static UA_StatusCode HelAckHandshake(UA_Client *c) {
  48. UA_TcpMessageHeader messageHeader;
  49. messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_HELF;
  50. UA_TcpHelloMessage hello;
  51. UA_String_copy(&c->endpointUrl, &hello.endpointUrl);
  52. UA_Connection *conn = &c->connection;
  53. hello.maxChunkCount = conn->localConf.maxChunkCount;
  54. hello.maxMessageSize = conn->localConf.maxMessageSize;
  55. hello.protocolVersion = conn->localConf.protocolVersion;
  56. hello.receiveBufferSize = conn->localConf.recvBufferSize;
  57. hello.sendBufferSize = conn->localConf.sendBufferSize;
  58. messageHeader.messageSize = UA_TcpHelloMessage_calcSizeBinary((UA_TcpHelloMessage const*) &hello) +
  59. UA_TcpMessageHeader_calcSizeBinary((UA_TcpMessageHeader const*) &messageHeader);
  60. UA_ByteString message;
  61. message.data = UA_alloca(messageHeader.messageSize);
  62. message.length = messageHeader.messageSize;
  63. size_t offset = 0;
  64. UA_TcpMessageHeader_encodeBinary(&messageHeader, &message, &offset);
  65. UA_TcpHelloMessage_encodeBinary(&hello, &message, &offset);
  66. UA_ByteStringArray buf = {.stringsSize = 1, .strings = &message};
  67. UA_StatusCode retval = c->networkLayer.send(c->connectionHandle, buf);
  68. if(retval)
  69. return retval;
  70. UA_Byte replybuf[1024];
  71. UA_ByteString reply = {.data = replybuf, .length = 1024};
  72. retval = c->networkLayer.awaitResponse(c->connectionHandle, &reply, 100);
  73. if (retval)
  74. return retval;
  75. offset = 0;
  76. UA_TcpAcknowledgeMessage ackMessage;
  77. retval = UA_TcpAcknowledgeMessage_decodeBinary(&reply, &offset, &ackMessage);
  78. if(retval != UA_STATUSCODE_GOOD) {
  79. UA_TcpAcknowledgeMessage_deleteMembers(&ackMessage);
  80. return retval;
  81. }
  82. conn->remoteConf.maxChunkCount = ackMessage.maxChunkCount;
  83. conn->remoteConf.maxMessageSize = ackMessage.maxMessageSize;
  84. conn->remoteConf.protocolVersion = ackMessage.protocolVersion;
  85. conn->remoteConf.recvBufferSize = ackMessage.receiveBufferSize;
  86. conn->remoteConf.sendBufferSize = ackMessage.sendBufferSize;
  87. conn->state = UA_CONNECTION_ESTABLISHED;
  88. return UA_STATUSCODE_GOOD;
  89. }
  90. static UA_StatusCode SecureChannelHandshake(UA_Client *c) {
  91. UA_SecureConversationMessageHeader msghdr;
  92. msghdr.messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_OPNF;
  93. msghdr.secureChannelId = 0;
  94. UA_AsymmetricAlgorithmSecurityHeader asymHeader;
  95. UA_AsymmetricAlgorithmSecurityHeader_init(&asymHeader);
  96. UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None", &asymHeader.securityPolicyUri);
  97. UA_SequenceHeader seqHeader;
  98. seqHeader.sequenceNumber = 51; // why is that???
  99. seqHeader.requestId = 1;
  100. UA_NodeId requestType = {.identifierType = UA_NODEIDTYPE_NUMERIC, .namespaceIndex = 0,
  101. .identifier.numeric = 446}; // id of opensecurechannelrequest
  102. UA_OpenSecureChannelRequest opnSecRq;
  103. UA_OpenSecureChannelRequest_init(&opnSecRq);
  104. opnSecRq.requestHeader.timestamp = UA_DateTime_now();
  105. UA_ByteString_newMembers(&opnSecRq.clientNonce, 1);
  106. opnSecRq.clientNonce.data[0] = 0;
  107. opnSecRq.clientProtocolVersion = 0;
  108. opnSecRq.requestedLifetime = 30000;
  109. opnSecRq.securityMode = UA_MESSAGESECURITYMODE_NONE;
  110. opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE;
  111. opnSecRq.requestHeader.authenticationToken.identifier.numeric = 10;
  112. opnSecRq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
  113. opnSecRq.requestHeader.authenticationToken.namespaceIndex = 10;
  114. msghdr.messageHeader.messageSize = UA_SecureConversationMessageHeader_calcSizeBinary(&msghdr) +
  115. UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(&asymHeader) +
  116. UA_SequenceHeader_calcSizeBinary(&seqHeader) +
  117. UA_NodeId_calcSizeBinary(&requestType) +
  118. UA_OpenSecureChannelRequest_calcSizeBinary(&opnSecRq);
  119. UA_ByteString message;
  120. UA_ByteString_newMembers(&message, msghdr.messageHeader.messageSize);
  121. size_t offset = 0;
  122. UA_SecureConversationMessageHeader_encodeBinary(&msghdr, &message, &offset);
  123. UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(&asymHeader, &message, &offset);
  124. UA_SequenceHeader_encodeBinary(&seqHeader, &message, &offset);
  125. UA_NodeId_encodeBinary(&requestType, &message, &offset);
  126. UA_OpenSecureChannelRequest_encodeBinary(&opnSecRq, &message, &offset);
  127. UA_OpenSecureChannelRequest_deleteMembers(&opnSecRq);
  128. UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&asymHeader);
  129. UA_ByteStringArray buf = {.stringsSize = 1, .strings = &message};
  130. UA_StatusCode retval = c->networkLayer.send(c->connectionHandle, buf);
  131. UA_ByteString_deleteMembers(&message);
  132. // parse the response
  133. UA_ByteString response;
  134. UA_ByteString_newMembers(&response, c->connection.localConf.recvBufferSize);
  135. retval = c->networkLayer.awaitResponse(c->connectionHandle, &response, 1000);
  136. /* UA_SecureConversationMessageHeader_init(&msghdr); */
  137. /* UA_AsymmetricAlgorithmSecurityHeader_init(&asymHeader); */
  138. /* UA_SequenceHeader_init(&seqHeader); */
  139. /* UA_OpenSecureChannelResponse opnSecRq; */
  140. /* UA_SecureConversationMessageHeader_calcSizeBinary(&respHeader) */
  141. /* + UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(&asymHeader) */
  142. /* + UA_SequenceHeader_calcSizeBinary(&seqHeader) */
  143. /* + UA_NodeId_calcSizeBinary(&responseType) */
  144. /* + UA_OpenSecureChannelResponse_calcSizeBinary(&p); */
  145. //UA_SecureConversationMessageHeader respHeader;
  146. //UA_NodeId responseType = UA_NODEIDS[UA_OPENSECURECHANNELRESPONSE];
  147. return retval;
  148. }