opcuaClient.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /*
  2. C ECHO client example using sockets
  3. */
  4. #include <stdio.h> //printf
  5. #include <string.h> //strlen
  6. #include <sys/socket.h> //socket
  7. #include <arpa/inet.h> //inet_addr
  8. #include <unistd.h> // for close
  9. #include <stdlib.h> // pulls in declaration of malloc, free
  10. #include "ua_transport_generated.h"
  11. #include "ua_namespace_0.h"
  12. UA_Int32 sendHello(UA_Int32 sock, UA_String *endpointURL) {
  13. UA_ByteString *message;
  14. UA_ByteString_new(&message);
  15. UA_ByteString_newMembers(message, 1000);
  16. UA_UInt32 offset = 0;
  17. UA_String endpointUrl;
  18. UA_String_copy(endpointURL, &endpointUrl);
  19. UA_TcpMessageHeader messageHeader;
  20. UA_TcpHelloMessage hello;
  21. messageHeader.isFinal = 'F';
  22. messageHeader.messageType = UA_MESSAGETYPE_HEL;
  23. hello.endpointUrl = endpointUrl;
  24. hello.maxChunkCount = 1;
  25. hello.maxMessageSize = 16777216;
  26. hello.protocolVersion = 0;
  27. hello.receiveBufferSize = 65536;
  28. hello.sendBufferSize = 65536;
  29. messageHeader.messageSize = UA_TcpHelloMessage_calcSizeBinary(
  30. (UA_TcpHelloMessage const*) &hello)
  31. + UA_TcpMessageHeader_calcSizeBinary(
  32. (UA_TcpMessageHeader const*) &messageHeader);
  33. UA_TcpMessageHeader_encodeBinary(
  34. (UA_TcpMessageHeader const*) &messageHeader, message, &offset);
  35. UA_TcpHelloMessage_encodeBinary((UA_TcpHelloMessage const*) &hello, message,
  36. &offset);
  37. UA_Int32 sendret = send(sock, message->data, offset, 0);
  38. UA_ByteString_delete(message);
  39. free(endpointUrl.data);
  40. if (sendret < 0) {
  41. return 1;
  42. }
  43. return 0;
  44. }
  45. int sendOpenSecureChannel(UA_Int32 sock) {
  46. UA_ByteString *message;
  47. UA_ByteString_new(&message);
  48. UA_ByteString_newMembers(message, 1000);
  49. UA_UInt32 offset = 0;
  50. UA_TcpMessageHeader msghdr;
  51. msghdr.isFinal = 'F';
  52. msghdr.messageType = UA_MESSAGETYPE_OPN;
  53. msghdr.messageSize = 135;
  54. UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
  55. UA_UInt32 secureChannelId = 0;
  56. UA_UInt32_encodeBinary(&secureChannelId, message, &offset);
  57. UA_String securityPolicy;
  58. UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None",
  59. &securityPolicy);
  60. UA_String_encodeBinary(&securityPolicy, message, &offset);
  61. UA_String senderCert;
  62. senderCert.data = UA_NULL;
  63. senderCert.length = -1;
  64. UA_String_encodeBinary(&senderCert, message, &offset);
  65. UA_String receiverCertThumb;
  66. receiverCertThumb.data = UA_NULL;
  67. receiverCertThumb.length = -1;
  68. UA_String_encodeBinary(&receiverCertThumb, message, &offset);
  69. UA_UInt32 sequenceNumber = 51;
  70. UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
  71. UA_UInt32 requestId = 1;
  72. UA_UInt32_encodeBinary(&requestId, message, &offset);
  73. UA_NodeId type;
  74. type.identifier.numeric = 446;
  75. type.identifierType = UA_NODEIDTYPE_NUMERIC;
  76. type.namespaceIndex = 0;
  77. UA_NodeId_encodeBinary(&type, message, &offset);
  78. UA_OpenSecureChannelRequest opnSecRq;
  79. UA_OpenSecureChannelRequest_init(&opnSecRq);
  80. opnSecRq.requestHeader.timestamp = UA_DateTime_now();
  81. UA_ByteString_newMembers(&opnSecRq.clientNonce, 1);
  82. opnSecRq.clientNonce.data[0] = 0;
  83. opnSecRq.clientProtocolVersion = 0;
  84. opnSecRq.requestedLifetime = 30000;
  85. opnSecRq.securityMode = UA_SECURITYMODE_NONE;
  86. opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE;
  87. opnSecRq.requestHeader.authenticationToken.identifier.numeric = 10;
  88. opnSecRq.requestHeader.authenticationToken.identifierType =
  89. UA_NODEIDTYPE_NUMERIC;
  90. opnSecRq.requestHeader.authenticationToken.namespaceIndex = 10;
  91. UA_OpenSecureChannelRequest_encodeBinary(&opnSecRq, message, &offset);
  92. UA_Int32 sendret = send(sock, message->data, offset, 0);
  93. UA_ByteString_delete(message);
  94. free(securityPolicy.data);
  95. if (sendret < 0) {
  96. printf("send opensecurechannel failed");
  97. return 1;
  98. }
  99. return 0;
  100. }
  101. UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId,
  102. UA_UInt32 tokenId, UA_UInt32 sequenceNumber, UA_UInt32 requestId,
  103. UA_String *endpointUrl) {
  104. UA_ByteString *message;
  105. UA_ByteString_new(&message);
  106. UA_ByteString_newMembers(message, 65536);
  107. UA_UInt32 tmpChannelId = channelId;
  108. UA_UInt32 offset = 0;
  109. UA_TcpMessageHeader msghdr;
  110. msghdr.isFinal = 'F';
  111. msghdr.messageType = UA_MESSAGETYPE_MSG;
  112. msghdr.messageSize = 164;
  113. UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
  114. UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
  115. UA_UInt32_encodeBinary(&tokenId, message, &offset);
  116. UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
  117. UA_UInt32_encodeBinary(&requestId, message, &offset);
  118. UA_NodeId type;
  119. type.identifier.numeric = 461;
  120. type.identifierType = UA_NODEIDTYPE_NUMERIC;
  121. type.namespaceIndex = 0;
  122. UA_NodeId_encodeBinary(&type, message, &offset);
  123. UA_CreateSessionRequest rq;
  124. UA_RequestHeader_init(&rq.requestHeader);
  125. rq.requestHeader.requestHandle = 1;
  126. rq.requestHeader.timestamp = UA_DateTime_now();
  127. rq.requestHeader.timeoutHint = 10000;
  128. rq.requestHeader.auditEntryId.length = -1;
  129. rq.requestHeader.authenticationToken.identifier.numeric = 10;
  130. rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
  131. rq.requestHeader.authenticationToken.namespaceIndex = 10;
  132. UA_String_copy(endpointUrl, &rq.endpointUrl);
  133. rq.clientDescription.applicationName.locale.length = -1;
  134. rq.clientDescription.applicationName.text.length = -1;
  135. rq.clientDescription.applicationUri.length = -1;
  136. rq.clientDescription.discoveryProfileUri.length = -1;
  137. rq.clientDescription.discoveryUrls = UA_NULL;
  138. rq.clientDescription.discoveryUrlsSize = -1;
  139. rq.clientDescription.gatewayServerUri.length = -1;
  140. rq.clientDescription.productUri.length = -1;
  141. UA_String_copycstring("mysession", &rq.sessionName);
  142. UA_String_copycstring("abcd", &rq.clientCertificate);
  143. UA_ByteString_newMembers(&rq.clientNonce, 1);
  144. rq.clientNonce.data[0] = 0;
  145. rq.requestedSessionTimeout = 1200000;
  146. rq.maxResponseMessageSize = UA_INT32_MAX;
  147. UA_CreateSessionRequest_encodeBinary(&rq, message, &offset);
  148. UA_Int32 sendret = send(sock, message->data, offset, 0);
  149. UA_ByteString_delete(message);
  150. free(rq.sessionName.data);
  151. free(rq.clientCertificate.data);
  152. if (sendret < 0) {
  153. printf("send opensecurechannel failed");
  154. return 1;
  155. }
  156. return 0;
  157. }
  158. UA_Int32 sendActivateSession(UA_Int32 sock, UA_UInt32 channelId,
  159. UA_UInt32 tokenId, UA_UInt32 sequenceNumber, UA_UInt32 requestId) {
  160. UA_ByteString *message;
  161. UA_ByteString_new(&message);
  162. UA_ByteString_newMembers(message, 65536);
  163. UA_UInt32 tmpChannelId = channelId;
  164. UA_UInt32 offset = 0;
  165. UA_TcpMessageHeader msghdr;
  166. msghdr.isFinal = 'F';
  167. msghdr.messageType = UA_MESSAGETYPE_MSG;
  168. msghdr.messageSize = 86;
  169. UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
  170. UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
  171. UA_UInt32_encodeBinary(&tokenId, message, &offset);
  172. UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
  173. UA_UInt32_encodeBinary(&requestId, message, &offset);
  174. UA_NodeId type;
  175. type.identifier.numeric = 467;
  176. type.identifierType = UA_NODEIDTYPE_NUMERIC;
  177. type.namespaceIndex = 0;
  178. UA_NodeId_encodeBinary(&type, message, &offset);
  179. UA_ActivateSessionRequest rq;
  180. UA_ActivateSessionRequest_init(&rq);
  181. rq.requestHeader.requestHandle = 2;
  182. rq.requestHeader.authenticationToken.identifier.numeric = 10;
  183. rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
  184. rq.requestHeader.authenticationToken.namespaceIndex = 10;
  185. UA_ActivateSessionRequest_encodeBinary(&rq, message, &offset);
  186. UA_Int32 sendret = send(sock, message->data, offset, 0);
  187. UA_ByteString_delete(message);
  188. if (sendret < 0) {
  189. printf("send opensecurechannel failed");
  190. return 1;
  191. }
  192. return 0;
  193. }
  194. UA_Int32 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
  195. UA_UInt32 sequenceNumber, UA_UInt32 requestId) {
  196. UA_ByteString *message;
  197. UA_ByteString_new(&message);
  198. UA_ByteString_newMembers(message, 65536);
  199. UA_UInt32 tmpChannelId = channelId;
  200. UA_UInt32 offset = 0;
  201. UA_TcpMessageHeader msghdr;
  202. msghdr.isFinal = 'F';
  203. msghdr.messageType = UA_MESSAGETYPE_MSG;
  204. msghdr.messageSize = 91;
  205. UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
  206. UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
  207. UA_UInt32_encodeBinary(&tokenId, message, &offset);
  208. UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
  209. UA_UInt32_encodeBinary(&requestId, message, &offset);
  210. UA_NodeId type;
  211. type.identifier.numeric = 631;
  212. type.identifierType = UA_NODEIDTYPE_NUMERIC;
  213. type.namespaceIndex = 0;
  214. UA_NodeId_encodeBinary(&type, message, &offset);
  215. UA_ReadRequest rq;
  216. UA_ReadRequest_init(&rq);
  217. rq.maxAge = 0;
  218. UA_Array_new((void **) &rq.nodesToRead, 1, &UA_[UA_READVALUEID]);
  219. rq.nodesToReadSize = 1;
  220. UA_ReadValueId_init(&(rq.nodesToRead[0]));
  221. rq.nodesToRead[0].attributeId = 13; //UA_ATTRIBUTEID_VALUE
  222. UA_NodeId_init(&(rq.nodesToRead[0].nodeId));
  223. rq.nodesToRead[0].nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
  224. rq.nodesToRead[0].nodeId.identifier.numeric = 2255;
  225. UA_QualifiedName_init(&(rq.nodesToRead[0].dataEncoding));
  226. rq.requestHeader.timeoutHint = 10000;
  227. rq.requestHeader.timestamp = UA_DateTime_now();
  228. rq.timestampsToReturn = 0x03;
  229. UA_ReadRequest_encodeBinary(&rq, message, &offset);
  230. UA_Int32 sendret = send(sock, message->data, offset, 0);
  231. UA_ByteString_delete(message);
  232. rq.requestHeader.authenticationToken.identifier.numeric = 10;
  233. rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
  234. rq.requestHeader.authenticationToken.namespaceIndex = 10;
  235. rq.requestHeader.requestHandle = 3;
  236. if (sendret < 0) {
  237. printf("send opensecurechannel failed");
  238. return 1;
  239. }
  240. return 0;
  241. }
  242. int main(int argc, char *argv[]) {
  243. int sock;
  244. struct sockaddr_in server;
  245. UA_ByteString *reply;
  246. UA_ByteString_new(&reply);
  247. UA_ByteString_newMembers(reply, 65536);
  248. //Create socket
  249. sock = socket(AF_INET, SOCK_STREAM, 0);
  250. if (sock == -1) {
  251. printf("Could not create socket");
  252. }
  253. server.sin_addr.s_addr = inet_addr("134.130.125.98");
  254. server.sin_family = AF_INET;
  255. server.sin_port = htons(16664);
  256. //Connect to remote server
  257. if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
  258. perror("connect failed. Error");
  259. return 1;
  260. }
  261. UA_String *endpointUrl;
  262. UA_String_new(&endpointUrl);
  263. UA_String_copycstring("opc.tcp://134.130.125.48:16663", endpointUrl);
  264. sendHello(sock, endpointUrl);
  265. int received = recv(sock, reply->data, reply->length, 0);
  266. sendOpenSecureChannel(sock);
  267. received = recv(sock, reply->data, reply->length, 0);
  268. UA_UInt32 recvOffset = 0;
  269. UA_TcpMessageHeader msghdr;
  270. UA_TcpMessageHeader_decodeBinary(reply, &recvOffset, &msghdr);
  271. UA_UInt32 secureChannelId;
  272. UA_UInt32_decodeBinary(reply, &recvOffset, &secureChannelId);
  273. sendCreateSession(sock, secureChannelId, 1, 52, 2, endpointUrl);
  274. received = recv(sock, reply->data, reply->length, 0);
  275. sendActivateSession(sock, secureChannelId, 1, 53, 3);
  276. received = recv(sock, reply->data, reply->length, 0);
  277. UA_DateTime tic, toc;
  278. for (UA_Int32 i = 0; i < 100; i++) {
  279. tic = UA_DateTime_now();
  280. sendReadRequest(sock, secureChannelId, 1+i, 54+i, 4+i);
  281. toc = UA_DateTime_now() - tic;
  282. received = recv(sock, reply->data, 2000, 0);
  283. UA_Int64 diff = ((UA_Int64) toc );
  284. printf("read req took: %llu \n", diff);
  285. }
  286. /*
  287. UA_TcpMessageHeader reqTcpHeader;
  288. UA_UInt32 reqSecureChannelId = 0;
  289. UA_UInt32 reqTokenId = 0;
  290. UA_SequenceHeader reqSequenceHeader;
  291. UA_NodeId reqRequestType;
  292. UA_ReadRequest req;
  293. UA_RequestHeader reqHeader;
  294. UA_NodeId reqHeaderAuthToken;
  295. UA_ExtensionObject reqHeaderAdditionalHeader;
  296. UA_NodeId_init(&reqRequestType);
  297. reqRequestType.identifierType = UA_NODEIDTYPE_NUMERIC;
  298. reqRequestType.identifier.numeric = 631; //read request
  299. UA_ReadRequest_init(&req);
  300. req.requestHeader = reqHeader;
  301. UA_RequestHeader_init(&(req.requestHeader));
  302. req.requestHeader.authenticationToken = reqHeaderAuthToken;
  303. UA_NodeId_init(&(req.requestHeader.authenticationToken));
  304. req.requestHeader.additionalHeader = reqHeaderAdditionalHeader;
  305. UA_ExtensionObject_init(&(req.requestHeader.additionalHeader));
  306. UA_Array_new((void **)&req.nodesToRead, 1, &UA_.types[UA_READVALUEID]);
  307. req.nodesToReadSize = 1;
  308. UA_ReadValueId_init(&(req.nodesToRead[0]));
  309. req.nodesToRead[0].attributeId = 13; //UA_ATTRIBUTEID_VALUE
  310. UA_NodeId_init(&(req.nodesToRead[0].nodeId));
  311. req.nodesToRead[0].nodeId.identifierType = UA_NODEIDTYPE_NUMERIC;
  312. req.nodesToRead[0].nodeId.identifier.numeric = 2255;
  313. UA_QualifiedName_init(&(req.nodesToRead[0].dataEncoding));
  314. messageEncodedLength = UA_TcpMessageHeader_calcSizeBinary(&reqTcpHeader) +
  315. UA_UInt32_calcSizeBinary(&reqSecureChannelId)+
  316. UA_UInt32_calcSizeBinary(&reqTokenId)+
  317. UA_SequenceHeader_calcSizeBinary(&reqSequenceHeader)+
  318. UA_NodeId_calcSizeBinary(&reqRequestType) +
  319. UA_ReadRequest_calcSizeBinary(&req);
  320. UA_TcpMessageHeader_init(&reqTcpHeader);
  321. reqTcpHeader.messageType = UA_MESSAGETYPE_MSG;
  322. reqTcpHeader.messageSize = messageEncodedLength;
  323. reqTcpHeader.isFinal = 'F';
  324. UA_TcpMessageHeader_encodeBinary(&reqTcpHeader, &message, &messagepos);
  325. UA_UInt32_encodeBinary(&reqSecureChannelId, &message, &messagepos);
  326. UA_UInt32_encodeBinary(&reqTokenId, &message, &messagepos);
  327. UA_SequenceHeader_encodeBinary(&reqSequenceHeader, &message, &messagepos);
  328. UA_NodeId_encodeBinary(&reqRequestType, &message, &messagepos);
  329. UA_ReadRequest_encodeBinary(&req, &message, &messagepos);
  330. */
  331. //Send some data
  332. //Receive a reply from the server
  333. if (received < 0) {
  334. puts("recv failed");
  335. return 1;
  336. }
  337. for (int i = 0; i < received; i++) {
  338. //show only printable ascii
  339. if (reply->data[i] >= 32 && reply->data[i] <= 126)
  340. printf("%c", reply->data[i]);
  341. }
  342. printf("\n");
  343. close(sock);
  344. return 0;
  345. }