opcua_transportLayer.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * opcua_transportLayer.c
  3. *
  4. * Created on: Dec 19, 2013
  5. * Author: opcua
  6. */
  7. #include "opcua_transportLayer.h"
  8. UA_Int32 TL_initConnectionObject(UA_connection *connection)
  9. {
  10. connection->newDataToRead = 0;
  11. connection->readData.data = UA_NULL;
  12. connection->readData.length = 0;
  13. connection->transportLayer.connectionState = connectionState_CLOSED;
  14. connection->transportLayer.localConf.maxChunkCount = 1;
  15. connection->transportLayer.localConf.maxMessageSize = 16384;
  16. connection->transportLayer.localConf.sendBufferSize = 8192;
  17. connection->transportLayer.localConf.recvBufferSize = 8192;
  18. return UA_NO_ERROR;
  19. }
  20. UA_Int32 TL_check(UA_connection *connection)
  21. {
  22. UA_Int32 position = 4;
  23. UA_UInt32 messageLength = 0;
  24. printf("TL_check - entered \n");
  25. UA_ByteString_printf("received data:",&(connection->readData));
  26. UA_UInt32_decode(connection->readData.data,&position,&messageLength);
  27. printf("TL_check - messageLength = %d \n",messageLength);
  28. if (messageLength == connection->readData.length &&
  29. messageLength < (connection->transportLayer.localConf.maxMessageSize))
  30. {
  31. printf("TL_check - no error \n");
  32. return UA_NO_ERROR;
  33. }
  34. printf("TL_check - length error \n");
  35. return UA_ERROR;
  36. }
  37. UA_Int32 TL_receive(UA_connection *connection, UA_ByteString *packet)
  38. {
  39. UA_UInt32 length = 0;
  40. UA_Int32 pos = 0;
  41. struct TL_header tmpHeader;
  42. printf("TL_receive - entered \n");
  43. packet->data = NULL;
  44. packet->length = 0;
  45. if(TL_check(connection) == UA_NO_ERROR)
  46. {
  47. printf("TL_receive - no error \n");
  48. printf("TL_receive - connection->readData.length %d \n",connection->readData.length);
  49. UA_Int32 packetType = TL_getPacketType(&(connection->readData),&pos);
  50. //is final chunk or not
  51. //TODO process chunks
  52. pos += sizeof(UA_Byte);
  53. //save the message size if needed
  54. pos += sizeof(UA_UInt32);
  55. printf("TL_receive - packetType = %d \n",packetType);
  56. switch(packetType)
  57. {
  58. case packetType_MSG:
  59. case packetType_OPN:
  60. case packetType_CLO:
  61. {
  62. packet->data = connection->readData.data;
  63. packet->length = connection->readData.length;
  64. printf("TL_receive - received MSG or OPN or CLO message\n");
  65. break;
  66. }
  67. case packetType_HEL:
  68. case packetType_ACK:
  69. {
  70. printf("TL_receive - received HEL or ACK message\n");
  71. TL_process(connection, packetType, &pos);
  72. break;
  73. }
  74. case packetType_ERR:
  75. {
  76. printf("TL_receive - received ERR message\n");
  77. //TODO ERROR HANDLING
  78. return UA_ERROR_RCV_ERROR;
  79. break;
  80. }
  81. }
  82. }
  83. else
  84. {
  85. //length error: send error message to communication partner
  86. //TL_send()
  87. }
  88. return UA_NO_ERROR;
  89. }
  90. #define Cmp3Byte(data,pos,a,b,c) (*((Int32*) ((data)+(pos))) & 0xFFFFFF) == (Int32)(((Byte)(a))|((Byte)(b))<<8|((Byte)(c))<<16)
  91. UA_Int32 TL_getPacketType(UA_ByteString *packet, UA_Int32 *pos)
  92. {
  93. UA_Int32 retVal = -1;
  94. // printf("TL_getPacketType - entered \n");
  95. // printf("TL_getPacketType - pos = %d \n",*pos);
  96. if(packet->data[*pos] == 'H' &&
  97. packet->data[*pos+1] == 'E' &&
  98. packet->data[*pos+2] == 'L')
  99. {
  100. *pos += 3 * sizeof(UA_Byte);
  101. retVal = packetType_HEL;
  102. }
  103. else if(packet->data[*pos] == 'A' &&
  104. packet->data[*pos+1] == 'C' &&
  105. packet->data[*pos+2] == 'K')
  106. {
  107. *pos += 3 * sizeof(UA_Byte);
  108. retVal = packetType_ACK;
  109. }
  110. else if(packet->data[*pos] == 'E' &&
  111. packet->data[*pos+1] == 'R' &&
  112. packet->data[*pos+2] == 'R')
  113. {
  114. *pos += 3 * sizeof(UA_Byte);
  115. retVal = packetType_ERR;
  116. }
  117. else if(packet->data[*pos] == 'O' &&
  118. packet->data[*pos+1] == 'P' &&
  119. packet->data[*pos+2] == 'N')
  120. {
  121. *pos += 3 * sizeof(UA_Byte);
  122. retVal = packetType_OPN;
  123. }
  124. else if(packet->data[*pos] == 'C' &&
  125. packet->data[*pos+1] == 'L' &&
  126. packet->data[*pos+2] == 'O')
  127. {
  128. *pos += 3 * sizeof(UA_Byte);
  129. retVal = packetType_CLO;
  130. }
  131. else if(packet->data[*pos] == 'M' &&
  132. packet->data[*pos+1] == 'S' &&
  133. packet->data[*pos+2] == 'G')
  134. {
  135. *pos += 3 * sizeof(UA_Byte);
  136. retVal = packetType_MSG;
  137. }
  138. //TODO retVal == -1 -- ERROR no valid message received
  139. return retVal;
  140. }
  141. UA_Int32 TL_process(UA_connection *connection,UA_Int32 packetType, UA_Int32 *pos)
  142. {
  143. UA_Int32 tmpPos = 0;
  144. UA_ByteString tmpMessage;
  145. UA_Byte reserved;
  146. UA_UInt32 messageSize;
  147. printf("TL_process - entered \n");
  148. struct TL_header tmpHeader;
  149. switch(packetType)
  150. {
  151. case packetType_HEL :
  152. if(connection->transportLayer.connectionState == connectionState_CLOSED)
  153. {
  154. printf("TL_process - extracting header information \n");
  155. printf("TL_process - pos = %d \n",*pos);
  156. /* extract information from received header */
  157. UA_UInt32_decode(connection->readData.data,pos,(&(connection->transportLayer.remoteConf.protocolVersion)));
  158. printf("TL_process - protocolVersion = %d \n",connection->transportLayer.remoteConf.protocolVersion);
  159. UA_UInt32_decode(connection->readData.data,pos,(&(connection->transportLayer.remoteConf.recvBufferSize)));
  160. printf("TL_process - recvBufferSize = %d \n",connection->transportLayer.remoteConf.recvBufferSize);
  161. UA_UInt32_decode(connection->readData.data,pos,(&(connection->transportLayer.remoteConf.sendBufferSize)));
  162. printf("TL_process - sendBufferSize = %d \n",connection->transportLayer.remoteConf.sendBufferSize);
  163. UA_UInt32_decode(connection->readData.data,pos,(&(connection->transportLayer.remoteConf.maxMessageSize)));
  164. printf("TL_process - maxMessageSize = %d \n",connection->transportLayer.remoteConf.maxMessageSize);
  165. UA_UInt32_decode(connection->readData.data,pos,(&(connection->transportLayer.remoteConf.maxChunkCount)));
  166. printf("TL_process - maxChunkCount = %d \n",connection->transportLayer.remoteConf.maxChunkCount);
  167. UA_String_decode(connection->readData.data,pos,(&(connection->transportLayer.endpointURL)));
  168. /* send back acknowledge */
  169. UA_alloc((void**)&(tmpMessage.data),SIZE_OF_ACKNOWLEDGE_MESSAGE);
  170. if(tmpMessage.data == UA_NULL)
  171. {
  172. printf("TL_process - memory allocation failed \n");
  173. }
  174. tmpMessage.length = SIZE_OF_ACKNOWLEDGE_MESSAGE;
  175. printf("TL_process - allocated memory \n");
  176. /* ------------------------ Header ------------------------ */
  177. // MessageType
  178. tmpMessage.data[0] = 'A';
  179. tmpMessage.data[1] = 'C';
  180. tmpMessage.data[2] = 'K';
  181. tmpPos += 3;
  182. // Chunk
  183. reserved = 'F';
  184. UA_Byte_encode(&reserved, &tmpPos, tmpMessage.data);
  185. // MessageSize
  186. messageSize = SIZE_OF_ACKNOWLEDGE_MESSAGE;
  187. UA_UInt32_encode(&messageSize,&tmpPos, tmpMessage.data);
  188. printf("TL_process - Size messageToSend = %d \n",messageSize);
  189. /* ------------------------ Body ------------------------ */
  190. // protocol version
  191. UA_UInt32_encode(&(connection->transportLayer.localConf.protocolVersion),
  192. &tmpPos, tmpMessage.data);
  193. printf("TL_process - localConf.protocolVersion = %d \n",connection->transportLayer.localConf.protocolVersion);
  194. //receive buffer size
  195. UA_UInt32_encode(&(connection->transportLayer.localConf.recvBufferSize),
  196. &tmpPos, tmpMessage.data);
  197. printf("TL_process - localConf.recvBufferSize = %d \n", connection->transportLayer.localConf.recvBufferSize);
  198. //send buffer size
  199. UA_UInt32_encode(&(connection->transportLayer.localConf.sendBufferSize),
  200. &tmpPos, tmpMessage.data);
  201. printf("TL_process - localConf.sendBufferSize = %d \n", connection->transportLayer.localConf.sendBufferSize);
  202. //maximum message size
  203. UA_UInt32_encode(&(connection->transportLayer.localConf.maxMessageSize),
  204. &tmpPos, tmpMessage.data);
  205. printf("TL_process - localConf.maxMessageSize = %d \n", connection->transportLayer.localConf.maxMessageSize);
  206. //maximum chunk count
  207. UA_UInt32_encode(&(connection->transportLayer.localConf.maxChunkCount),
  208. &tmpPos, tmpMessage.data);
  209. printf("TL_process - localConf.maxChunkCount = %d \n", connection->transportLayer.localConf.maxChunkCount);
  210. TL_send(connection, &tmpMessage);
  211. }
  212. else
  213. {
  214. printf("TL_process - wrong connection state \n");
  215. return UA_ERROR_MULTIPLY_HEL;
  216. }
  217. break;
  218. default:
  219. return UA_ERROR;
  220. }
  221. return UA_SUCCESS;
  222. }
  223. /*
  224. * respond to client request
  225. */
  226. UA_Int32 TL_send(UA_connection *connection, UA_ByteString *packet)
  227. {
  228. printf("TL_send - entered \n");
  229. connection->newDataToWrite = 1;
  230. if(packet->length < connection->transportLayer.remoteConf.maxMessageSize)
  231. {
  232. connection->writeData.data = packet->data;
  233. connection->writeData.length = packet->length;
  234. printf("TL_send - packet length = %d \n", packet->length);
  235. }
  236. else
  237. {
  238. printf("TL_send - ERROR: packet size greater than remote buffer size");
  239. //server error
  240. }
  241. return UA_SUCCESS;
  242. }