ua_server_binary.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. #include "ua_server.h"
  2. #include "ua_services.h"
  3. #include "ua_statuscodes.h"
  4. static void processHello(UA_Connection *connection, const UA_ByteString *msg,
  5. UA_UInt32 *pos) {
  6. UA_UInt32 tmpPos = 0;
  7. UA_OPCUATcpHelloMessage helloMessage;
  8. if(connection->state != UA_CONNECTION_OPENING) {
  9. // multiple HEL are not allowed
  10. connection->close(connection->callbackHandle);
  11. return;
  12. }
  13. UA_OPCUATcpHelloMessage_decodeBinary(msg, pos, &helloMessage);
  14. connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount;
  15. connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize;
  16. connection->remoteConf.protocolVersion = helloMessage.protocolVersion;
  17. connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize;
  18. connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize;
  19. connection->state = UA_CONNECTION_ESTABLISHED;
  20. // build acknowledge response
  21. UA_OPCUATcpMessageHeader ackHeader;
  22. ackHeader.messageType = UA_MESSAGETYPE_ACK;
  23. ackHeader.isFinal = 'F';
  24. UA_OPCUATcpAcknowledgeMessage ackMessage;
  25. ackMessage.protocolVersion = connection->localConf.protocolVersion;
  26. ackMessage.receiveBufferSize = connection->localConf.recvBufferSize;
  27. ackMessage.sendBufferSize = connection->localConf.sendBufferSize;
  28. ackMessage.maxMessageSize = connection->localConf.maxMessageSize;
  29. ackMessage.maxChunkCount = connection->localConf.maxChunkCount;
  30. ackHeader.messageSize = UA_OPCUATcpAcknowledgeMessage_calcSizeBinary(&ackMessage) +
  31. UA_OPCUATcpMessageHeader_calcSizeBinary(&ackHeader);
  32. UA_ByteString *ack_msg;
  33. UA_alloc((void **)&ack_msg, sizeof(UA_ByteString));
  34. UA_ByteString_newMembers(ack_msg, ackHeader.messageSize);
  35. tmpPos = 0;
  36. UA_OPCUATcpMessageHeader_encodeBinary(&ackHeader, ack_msg, &tmpPos);
  37. UA_OPCUATcpAcknowledgeMessage_encodeBinary(&ackMessage, ack_msg, &tmpPos);
  38. UA_ByteStringArray answer_buf = { .stringsSize = 1, .strings = ack_msg };
  39. connection->write(connection->callbackHandle, &answer_buf);
  40. UA_ByteString_delete(ack_msg);
  41. }
  42. static void processOpen(UA_Connection *connection, UA_Server *server,
  43. const UA_ByteString *msg, UA_UInt32 *pos) {
  44. UA_UInt32 secureChannelId;
  45. if(connection->state != UA_CONNECTION_ESTABLISHED) {
  46. if(connection->state == UA_CONNECTION_OPENING)
  47. connection->close(connection->callbackHandle);
  48. return;
  49. }
  50. UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
  51. // needs asym encoding for returning
  52. // call the service!!!!
  53. /* if(connection->channel != UA_NULL) { */
  54. /* //create new channel */
  55. /* SL_Channel *newChannel; */
  56. /* retval |= SL_ChannelManager_generateChannel(cm, ) */
  57. /* retval |= SL_ProcessOpenChannel(newChannel, server, msg, pos); */
  58. /* retval |= SL_Channel_bind(newChannel, connection); */
  59. /* return retval; */
  60. /* } */
  61. /* // channel already exists, renew token? */
  62. /* retval |= SL_ProcessOpenChannel(channel, server, msg, pos); */
  63. /* return retval; */
  64. }
  65. static void init_response_header(UA_RequestHeader const *p, UA_ResponseHeader *r) {
  66. r->requestHandle = p->requestHandle;
  67. r->serviceResult = UA_STATUSCODE_GOOD;
  68. r->stringTableSize = 0;
  69. r->timestamp = UA_DateTime_now();
  70. }
  71. #define CHECK_PROCESS(CODE, CLEANUP) \
  72. do { \
  73. if(CODE != UA_SUCCESS) { \
  74. CLEANUP; \
  75. goto clean_up; \
  76. } } while(0)
  77. #define INVOKE_SERVICE(TYPE) do { \
  78. UA_##TYPE##Request p; \
  79. UA_##TYPE##Response r; \
  80. UA_Session *session = UA_NULL; \
  81. CHECK_PROCESS(UA_##TYPE##Request_decodeBinary(msg, pos, &p),; ); \
  82. UA_##TYPE##Response_init(&r); \
  83. init_response_header(&p.requestHeader, &r.responseHeader); \
  84. UA_SessionManager_getSessionByToken(server->sessionManager, &p.requestHeader.authenticationToken, \
  85. &session); \
  86. DBG_VERBOSE(printf("Invoke Service: %s\n", # TYPE)); \
  87. Service_##TYPE(server, session, &p, &r); \
  88. DBG_VERBOSE(printf("Finished Service: %s\n", # TYPE)); \
  89. UA_ByteString_newMembers(&responseBuf.strings[1], UA_##TYPE##Response_calcSizeBinary(&r)); \
  90. UA_##TYPE##Response_encodeBinary(&r, &responseBuf.strings[1], &sendOffset); \
  91. UA_##TYPE##Request_deleteMembers(&p); \
  92. UA_##TYPE##Response_deleteMembers(&r); \
  93. responseType = requestType.nodeId.identifier.numeric + 3; \
  94. } while(0)
  95. static void processMessage(UA_Connection *connection, UA_Server *server,
  96. const UA_ByteString *msg, UA_UInt32 *pos) {
  97. // 1) Read in the securechannel
  98. UA_UInt32 secureChannelId;
  99. UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
  100. UA_SecureChannel *channel;
  101. UA_SecureChannelManager_get(server->secureChannelManager, secureChannelId, &channel);
  102. // 2) Read the security header
  103. UA_UInt32 tokenId;
  104. UA_UInt32_decodeBinary(msg, pos, &tokenId);
  105. UA_SequenceHeader sequenceHeader;
  106. CHECK_PROCESS(UA_SequenceHeader_decodeBinary(msg, pos, &sequenceHeader),; );
  107. //UA_SecureChannel_checkSequenceNumber(channel,sequenceHeader.sequenceNumber);
  108. //UA_SecureChannel_checkRequestId(channel,sequenceHeader.requestId);
  109. // 3) Read the nodeid of the request
  110. UA_ExpandedNodeId requestType;
  111. CHECK_PROCESS(UA_ExpandedNodeId_decodeBinary(msg, pos, &requestType),; );
  112. if(requestType.nodeId.identifierType != UA_NODEIDTYPE_NUMERIC)
  113. goto close_connection;
  114. // 4) process the request
  115. UA_ByteStringArray responseBuf;
  116. UA_ByteStringArray_init(&responseBuf, 2);
  117. UA_UInt32 responseType;
  118. //subtract 2 for binary encoding
  119. UA_UInt32 sendOffset = 0;
  120. switch(requestType.nodeId.identifier.numeric - 2) {
  121. case UA_GETENDPOINTSREQUEST_NS0:
  122. {
  123. UA_GetEndpointsRequest p;
  124. UA_GetEndpointsResponse r;
  125. CHECK_PROCESS(UA_GetEndpointsRequest_decodeBinary(msg, pos, &p),; );
  126. UA_GetEndpointsResponse_init(&r);
  127. init_response_header(&p.requestHeader, &r.responseHeader);
  128. Service_GetEndpoints(server, &p, &r);
  129. UA_ByteString_newMembers(&responseBuf.strings[1],
  130. UA_GetEndpointsResponse_calcSizeBinary(&r));
  131. UA_GetEndpointsResponse_encodeBinary(&r, &responseBuf.strings[1], &sendOffset);
  132. UA_GetEndpointsRequest_deleteMembers(&p);
  133. UA_GetEndpointsResponse_deleteMembers(&r);
  134. responseType = requestType.nodeId.identifier.numeric + 3;
  135. break;
  136. }
  137. case UA_CREATESESSIONREQUEST_NS0:
  138. {
  139. UA_CreateSessionRequest p;
  140. UA_CreateSessionResponse r;
  141. CHECK_PROCESS(UA_CreateSessionRequest_decodeBinary(msg, pos, &p),; );
  142. UA_CreateSessionResponse_init(&r);
  143. init_response_header(&p.requestHeader, &r.responseHeader);
  144. Service_CreateSession(server, channel, &p, &r);
  145. UA_ByteString_newMembers(&responseBuf.strings[1],
  146. UA_CreateSessionResponse_calcSizeBinary(&r));
  147. UA_CreateSessionResponse_encodeBinary(&r, &responseBuf.strings[1], &sendOffset);
  148. UA_CreateSessionRequest_deleteMembers(&p);
  149. UA_CreateSessionResponse_deleteMembers(&r);
  150. responseType = requestType.nodeId.identifier.numeric + 3;
  151. break;
  152. }
  153. case UA_ACTIVATESESSIONREQUEST_NS0:
  154. INVOKE_SERVICE(ActivateSession);
  155. break;
  156. case UA_READREQUEST_NS0:
  157. INVOKE_SERVICE(Read);
  158. break;
  159. case UA_WRITEREQUEST_NS0:
  160. INVOKE_SERVICE(Write);
  161. break;
  162. case UA_BROWSEREQUEST_NS0:
  163. INVOKE_SERVICE(Browse);
  164. break;
  165. case UA_CREATESUBSCRIPTIONREQUEST_NS0:
  166. INVOKE_SERVICE(CreateSubscription);
  167. break;
  168. case UA_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_NS0:
  169. INVOKE_SERVICE(TranslateBrowsePathsToNodeIds);
  170. break;
  171. case UA_PUBLISHREQUEST_NS0:
  172. INVOKE_SERVICE(Publish);
  173. break;
  174. case UA_CREATEMONITOREDITEMSREQUEST_NS0:
  175. INVOKE_SERVICE(CreateMonitoredItems);
  176. break;
  177. case UA_SETPUBLISHINGMODEREQUEST_NS0:
  178. INVOKE_SERVICE(SetPublishingMode);
  179. break;
  180. default:
  181. {
  182. printf("SL_processMessage - unknown request, namespace=%d, request=%d\n",
  183. requestType.nodeId.namespaceIndex, requestType.nodeId.identifier.numeric);
  184. UA_RequestHeader p;
  185. UA_ResponseHeader r;
  186. CHECK_PROCESS(UA_RequestHeader_decodeBinary(msg, pos, &p),; );
  187. UA_ResponseHeader_init(&r);
  188. r.requestHandle = p.requestHandle;
  189. r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
  190. UA_ByteString_newMembers(&responseBuf.strings[1], UA_ResponseHeader_calcSizeBinary(&r));
  191. UA_ResponseHeader_encodeBinary(&r, &responseBuf.strings[1], &sendOffset);
  192. UA_RequestHeader_deleteMembers(&p);
  193. UA_ResponseHeader_deleteMembers(&r);
  194. responseType = UA_RESPONSEHEADER_NS0 + 2;
  195. }
  196. }
  197. // 5) Build the header
  198. #define SIZE_SECURECHANNEL_HEADER 12
  199. #define SIZE_SEQHEADER_HEADER 8
  200. UA_NodeId response_nodeid = { .namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC,
  201. .identifier.numeric = responseType }; // add 2 for binary encoding
  202. UA_ByteString_newMembers(&responseBuf.strings[0],
  203. 8 + 16 + // normal header + 4*32bit secure channel information
  204. UA_NodeId_calcSizeBinary(&response_nodeid));
  205. // sizePadding = 0;
  206. // sizeSignature = 0;
  207. UA_ByteString *header = &responseBuf.strings[0];
  208. // secure conversation message header
  209. header->data[0] = 'M';
  210. header->data[1] = 'S';
  211. header->data[2] = 'G';
  212. header->data[3] = 'F';
  213. UA_UInt32 rpos = 4;
  214. UA_Int32 packetSize = header->length + responseBuf.strings[0].length;
  215. UA_Int32_encodeBinary(&packetSize, header, &rpos);
  216. UA_UInt32_encodeBinary(&channel->securityToken.channelId, header, &rpos);
  217. // algorithm security header
  218. UA_UInt32_encodeBinary(&channel->securityToken.tokenId, header, &rpos);
  219. // encode sequence header
  220. UA_UInt32_encodeBinary(&channel->sequenceNumber, header, &rpos);
  221. UA_UInt32_encodeBinary(&channel->requestId, header, &rpos);
  222. // add payload type
  223. UA_NodeId_encodeBinary(&response_nodeid, header, &rpos);
  224. // sign data
  225. // encrypt data
  226. // 6) Send it over the wire.
  227. connection->write(connection->callbackHandle, &responseBuf);
  228. clean_up:
  229. UA_ExpandedNodeId_deleteMembers(&requestType);
  230. UA_ByteStringArray_deleteMembers(&responseBuf);
  231. return;
  232. close_connection:
  233. // make sure allocated data has been freed
  234. connection->state = UA_CONNECTION_CLOSING;
  235. connection->close(connection->callbackHandle);
  236. return;
  237. }
  238. static void processClose(UA_Connection *connection, UA_Server *server,
  239. const UA_ByteString *msg, UA_UInt32 *pos) {
  240. // just read in the sequenceheader
  241. }
  242. UA_Int32 UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection,
  243. const UA_ByteString *msg) {
  244. UA_Int32 retval = UA_SUCCESS;
  245. UA_UInt32 pos = 0;
  246. UA_OPCUATcpMessageHeader tcpMessageHeader;
  247. do {
  248. retval = UA_OPCUATcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader);
  249. if(retval == UA_SUCCESS) {
  250. // none of the process-functions returns an error its all contained inside.
  251. switch(tcpMessageHeader.messageType) {
  252. case UA_MESSAGETYPE_HEL:
  253. processHello(connection, msg, &pos);
  254. break;
  255. case UA_MESSAGETYPE_OPN:
  256. processOpen(connection, server, msg, &pos);
  257. break;
  258. case UA_MESSAGETYPE_MSG:
  259. // if this fails, the connection is closed (no break on the case)
  260. if(connection->state == UA_CONNECTION_ESTABLISHED &&
  261. connection->channel != UA_NULL) {
  262. processMessage(connection, server, msg, &pos);
  263. break;
  264. }
  265. case UA_MESSAGETYPE_CLO:
  266. connection->state = UA_CONNECTION_CLOSING;
  267. processClose(connection, server, msg, &pos);
  268. connection->close(connection->callbackHandle);
  269. break;
  270. }
  271. } else {
  272. printf("TL_Process - ERROR: decoding of header failed \n");
  273. connection->state = UA_CONNECTION_CLOSING;
  274. processClose(connection, server, msg, &pos);
  275. connection->close(connection->callbackHandle);
  276. }
  277. UA_OPCUATcpMessageHeader_deleteMembers(&tcpMessageHeader);
  278. } while(msg->length > (UA_Int32)pos);
  279. return retval;
  280. }