opcua_transportLayer.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /*
  2. * opcua_transportLayer.c
  3. *
  4. * Created on: Dec 19, 2013
  5. * Author: opcua
  6. */
  7. #include "opcua_transportLayer.h"
  8. /*
  9. * send acknowledge to the client
  10. */
  11. void TL_sendACK(UA_connection *connection)
  12. {
  13. //get memory for message
  14. //
  15. //build message
  16. //connection->transportLayer.localConf.maxChunkCount;
  17. //call send function
  18. }
  19. /*
  20. * server answer to open message
  21. */
  22. void TL_open(UA_connection *connection, AD_RawMessage *rawMessage)
  23. {
  24. UA_connection tmpConnection;
  25. switch(connection->transportLayer.connectionState)
  26. {
  27. connectionState_CLOSED :
  28. {
  29. //process the connection values received by the client
  30. TL_processHELMessage(&tmpConnection,rawMessage);
  31. connection->transportLayer.localConf.protocolVersion = TL_SERVER_PROTOCOL_VERSION;
  32. connection->transportLayer.localConf.recvBufferSize =
  33. tmpConnection.transportLayer.localConf.recvBufferSize;
  34. connection->transportLayer.localConf.sendBufferSize =
  35. tmpConnection.transportLayer.localConf.sendBufferSize;
  36. connection->transportLayer.localConf.maxMessageSize = TL_SERVER_MAX_MESSAGE_SIZE;
  37. connection->transportLayer.localConf.maxChunkCount = TL_SERVER_MAX_CHUNK_COUNT;
  38. TL_sendACK(connection);
  39. connection->transportLayer.connectionState = connectionState_ESTABLISHED;
  40. break;
  41. }
  42. connectionState_OPENING :
  43. {
  44. // TL_sendACK(connection);
  45. // connection->transportLayer.connectionState = connectionState_ESTABLISHED;
  46. break;
  47. }
  48. connectionState_ESTABLISHED :
  49. {
  50. break;
  51. }
  52. }
  53. }
  54. Int32 TL_checkMessage(UA_connection *connection, AD_RawMessage *TL_messsage)
  55. {
  56. Int32 position = 4;
  57. TL_getPacketType(TL_messsage);
  58. Int32 messageLen = decodeUInt32(TL_messsage->message, &position);
  59. if (messageLen == TL_messsage->length &&
  60. messageLen < (connection->transportLayer.localConf.maxMessageSize))
  61. {
  62. return 1;
  63. }
  64. return 0;
  65. }
  66. void TL_receive(UA_connection *connection, AD_RawMessage *TL_message)
  67. {
  68. UInt32 bufferSize = connection->transportLayer.localConf.recvBufferSize = 8192;
  69. UInt32 length = 0;
  70. AD_RawMessage tmpRawMessage;
  71. struct TL_header tmpHeader;
  72. //allocate memory for the message
  73. //TODO filter double Hello Messages -> generate error message as response
  74. //TODO build a file which handles the memory allocation
  75. tmpRawMessage.message = (char *)malloc(bufferSize);
  76. if (tmpRawMessage.message != NULL)
  77. {
  78. //length = tcp_recv(connection, tmpRawMessage.message, bufferSize);
  79. }
  80. tmpRawMessage.length = length;
  81. if(tmpRawMessage.length > 0)
  82. {
  83. switch(TL_getPacketType(&tmpRawMessage))
  84. {
  85. packetType_MSG:
  86. packetType_OPN:
  87. packetType_CLO:
  88. //CHECK MESSAGE SIZE
  89. if (TL_checkMessage(connection,TL_message))
  90. {
  91. TL_message->length = tmpRawMessage.length;
  92. TL_message->message = tmpRawMessage.message;
  93. }
  94. else
  95. {
  96. // SEND BACK ERROR MESSAGE
  97. }
  98. break;
  99. packetType_HEL:
  100. TL_message->length = 0;
  101. TL_message->message = NULL;
  102. TL_open(connection, &tmpRawMessage);
  103. break;
  104. packetType_ACK:
  105. TL_message->length = 0;
  106. TL_message->message = NULL;
  107. break;
  108. packetType_ERR:
  109. TL_message->length = 0;
  110. TL_message->message = NULL;
  111. //TODO ERROR HANDLING
  112. break;
  113. //TODO ERROR HANDLING
  114. }
  115. //check in which state the connection is
  116. }
  117. }
  118. /*
  119. * get the message header
  120. */
  121. void TL_getMessageHeader(struct TL_header *header, AD_RawMessage *rawMessage)
  122. {
  123. int pos = 0;
  124. if(rawMessage->message[0] == 'H' &&
  125. rawMessage->message[1] == 'E' &&
  126. rawMessage->message[2] == 'L')
  127. {
  128. header->MessageType = TL_HEL;
  129. }
  130. else if(rawMessage->message[0] == 'A' &&
  131. rawMessage->message[1] == 'C' &&
  132. rawMessage->message[2] == 'K')
  133. {
  134. header->MessageType = TL_ACK;
  135. }
  136. else if(rawMessage->message[0] == 'E' &&
  137. rawMessage->message[1] == 'R' &&
  138. rawMessage->message[2] == 'R')
  139. {
  140. header->MessageType = TL_ERR;
  141. }
  142. else if(rawMessage->message[0] == 'O' &&
  143. rawMessage->message[1] == 'P' &&
  144. rawMessage->message[2] == 'N')
  145. {
  146. header->MessageType = TL_OPN;
  147. }
  148. else if(rawMessage->message[0] == 'C' &&
  149. rawMessage->message[1] == 'L' &&
  150. rawMessage->message[2] == 'O')
  151. {
  152. header->MessageType = TL_CLO;
  153. }
  154. else if(rawMessage->message[0] == 'M' &&
  155. rawMessage->message[1] == 'S' &&
  156. rawMessage->message[2] == 'G')
  157. {
  158. header->MessageType = TL_MSG;
  159. }
  160. else
  161. {
  162. //TODO ERROR no valid message received
  163. }
  164. pos = pos + TL_MESSAGE_TYPE_LEN;
  165. header->Reserved = decodeByte(rawMessage->message,&pos);
  166. pos = pos + TL_RESERVED_LEN;
  167. header->MessageSize = decodeUInt32(rawMessage->message,&pos);
  168. }
  169. Int32 TL_getPacketType(AD_RawMessage *rawMessage)
  170. {
  171. if(rawMessage->message[0] == 'H' &&
  172. rawMessage->message[1] == 'E' &&
  173. rawMessage->message[2] == 'L')
  174. {
  175. return packetType_HEL;
  176. }
  177. else if(rawMessage->message[0] == 'A' &&
  178. rawMessage->message[1] == 'C' &&
  179. rawMessage->message[2] == 'K')
  180. {
  181. return packetType_ACK;
  182. }
  183. else if(rawMessage->message[0] == 'E' &&
  184. rawMessage->message[1] == 'R' &&
  185. rawMessage->message[2] == 'R')
  186. {
  187. return packetType_ERR;
  188. }
  189. else if(rawMessage->message[0] == 'O' &&
  190. rawMessage->message[1] == 'P' &&
  191. rawMessage->message[2] == 'N')
  192. {
  193. return packetType_OPN;
  194. }
  195. else if(rawMessage->message[0] == 'C' &&
  196. rawMessage->message[1] == 'L' &&
  197. rawMessage->message[2] == 'O')
  198. {
  199. return packetType_CLO;
  200. }
  201. else if(rawMessage->message[0] == 'M' &&
  202. rawMessage->message[1] == 'S' &&
  203. rawMessage->message[2] == 'G')
  204. {
  205. return packetType_MSG;
  206. }
  207. else
  208. {
  209. return -1;//TODO ERROR no valid message received
  210. }
  211. }
  212. void TL_processHELMessage_test()
  213. {
  214. Byte data[] = {0x48,0x45,0x4c,0x46,0x56,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x88,0x13,0x00,0x00,0x36,0x00,0x00,0x00,0x6f,0x70,0x63,0x2e,0x74,0x63,0x70,0x3a,0x2f,0x2f,0x43,0x61,0x6e,0x6f,0x70,0x75,0x73,0x2e,0x70,0x6c,0x74,0x2e,0x72,0x77,0x74,0x68,0x2d,0x61,0x61,0x63,0x68,0x65,0x6e,0x2e,0x64,0x65,0x3a,0x31,0x36,0x36,0x36,0x34,0x2f,0x34,0x43,0x45,0x55,0x41,0x53,0x65,0x72,0x76,0x65,0x72};
  215. UA_connection con;
  216. AD_RawMessage rawMessage;
  217. rawMessage.message = data;
  218. rawMessage.length = 86;
  219. struct TL_messageBodyHEL HELmessage;
  220. struct TL_header header;
  221. printf("TL_getHELMessage_test");
  222. header.MessageSize = 86;
  223. header.MessageType = TL_HEL; // HEL message
  224. header.Reserved = 0x46; // F
  225. TL_processHELMessage(&con, &rawMessage);
  226. if(con.transportLayer.remoteConf.protocolVersion == 0 &&
  227. con.transportLayer.remoteConf.recvBufferSize == 65536 &&
  228. con.transportLayer.remoteConf.sendBufferSize == 65536 &&
  229. con.transportLayer.remoteConf.maxMessageSize == 16777216 &&
  230. con.transportLayer.remoteConf.maxChunkCount == 5000)
  231. {
  232. printf(" - passed \n");
  233. }
  234. else
  235. {
  236. printf(" - failed \n");
  237. }
  238. }
  239. /*
  240. * gets the TL_messageBody
  241. */
  242. void TL_processHELMessage(UA_connection *connection, AD_RawMessage *rawMessage)
  243. {
  244. UInt32 pos = TL_HEADER_LENGTH;
  245. struct TL_header tmpHeader;
  246. connection->transportLayer.remoteConf.protocolVersion =
  247. decodeUInt32(rawMessage->message,&pos);
  248. pos = pos + sizeof(UInt32);
  249. connection->transportLayer.remoteConf.recvBufferSize =
  250. decodeUInt32(rawMessage->message,&pos);
  251. pos = pos + sizeof(UInt32);
  252. connection->transportLayer.remoteConf.sendBufferSize =
  253. decodeUInt32(rawMessage->message,&pos);
  254. pos = pos + sizeof(UInt32);
  255. connection->transportLayer.remoteConf.maxMessageSize =
  256. decodeUInt32(rawMessage->message,&pos);
  257. pos = pos + sizeof(UInt32);
  258. connection->transportLayer.remoteConf.maxChunkCount =
  259. decodeUInt32(rawMessage->message,&pos);
  260. pos = pos + sizeof(UInt32);
  261. connection->transportLayer.endpointURL.Data = &(rawMessage->message[pos]);
  262. connection->transportLayer.endpointURL.Length = tmpHeader.MessageSize - pos;
  263. }
  264. /*
  265. * respond to client request
  266. */
  267. TL_send(AD_RawMessage *rawMessage)
  268. {
  269. //call tcp function or callback
  270. }