opcuaClient.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  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_TcpMessageHeader messageHeader;
  18. UA_TcpHelloMessage hello;
  19. messageHeader.isFinal = 'F';
  20. messageHeader.messageType = UA_MESSAGETYPE_HEL;
  21. UA_String_copy(endpointURL, &hello.endpointUrl);
  22. hello.maxChunkCount = 1;
  23. hello.maxMessageSize = 16777216;
  24. hello.protocolVersion = 0;
  25. hello.receiveBufferSize = 65536;
  26. hello.sendBufferSize = 65536;
  27. messageHeader.messageSize = UA_TcpHelloMessage_calcSizeBinary(
  28. (UA_TcpHelloMessage const*) &hello)
  29. + UA_TcpMessageHeader_calcSizeBinary(
  30. (UA_TcpMessageHeader const*) &messageHeader);
  31. UA_TcpMessageHeader_encodeBinary(
  32. (UA_TcpMessageHeader const*) &messageHeader, message, &offset);
  33. UA_TcpHelloMessage_encodeBinary((UA_TcpHelloMessage const*) &hello, message,
  34. &offset);
  35. UA_Int32 sendret = send(sock, message->data, offset, 0);
  36. UA_ByteString_delete(message);
  37. free(hello.endpointUrl.data);
  38. if (sendret < 0) {
  39. return 1;
  40. }
  41. return 0;
  42. }
  43. int sendOpenSecureChannel(UA_Int32 sock) {
  44. UA_ByteString *message;
  45. UA_ByteString_new(&message);
  46. UA_ByteString_newMembers(message, 1000);
  47. UA_UInt32 offset = 0;
  48. UA_TcpMessageHeader msghdr;
  49. msghdr.isFinal = 'F';
  50. msghdr.messageType = UA_MESSAGETYPE_OPN;
  51. msghdr.messageSize = 135;
  52. UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
  53. UA_UInt32 secureChannelId = 0;
  54. UA_UInt32_encodeBinary(&secureChannelId, message, &offset);
  55. UA_String securityPolicy;
  56. UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None",
  57. &securityPolicy);
  58. UA_String_encodeBinary(&securityPolicy, message, &offset);
  59. UA_String senderCert;
  60. senderCert.data = UA_NULL;
  61. senderCert.length = -1;
  62. UA_String_encodeBinary(&senderCert, message, &offset);
  63. UA_String receiverCertThumb;
  64. receiverCertThumb.data = UA_NULL;
  65. receiverCertThumb.length = -1;
  66. UA_String_encodeBinary(&receiverCertThumb, message, &offset);
  67. UA_UInt32 sequenceNumber = 51;
  68. UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
  69. UA_UInt32 requestId = 1;
  70. UA_UInt32_encodeBinary(&requestId, message, &offset);
  71. UA_NodeId type;
  72. type.identifier.numeric = 446;
  73. type.identifierType = UA_NODEIDTYPE_NUMERIC;
  74. type.namespaceIndex = 0;
  75. UA_NodeId_encodeBinary(&type, message, &offset);
  76. UA_OpenSecureChannelRequest opnSecRq;
  77. UA_OpenSecureChannelRequest_init(&opnSecRq);
  78. opnSecRq.requestHeader.timestamp = UA_DateTime_now();
  79. UA_ByteString_newMembers(&opnSecRq.clientNonce, 1);
  80. opnSecRq.clientNonce.data[0] = 0;
  81. opnSecRq.clientProtocolVersion = 0;
  82. opnSecRq.requestedLifetime = 30000;
  83. opnSecRq.securityMode = UA_SECURITYMODE_NONE;
  84. opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE;
  85. opnSecRq.requestHeader.authenticationToken.identifier.numeric = 10;
  86. opnSecRq.requestHeader.authenticationToken.identifierType =
  87. UA_NODEIDTYPE_NUMERIC;
  88. opnSecRq.requestHeader.authenticationToken.namespaceIndex = 10;
  89. UA_OpenSecureChannelRequest_encodeBinary(&opnSecRq, message, &offset);
  90. UA_Int32 sendret = send(sock, message->data, offset, 0);
  91. UA_ByteString_delete(message);
  92. free(securityPolicy.data);
  93. if (sendret < 0) {
  94. printf("send opensecurechannel failed");
  95. return 1;
  96. }
  97. return 0;
  98. }
  99. UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId,
  100. UA_UInt32 tokenId, UA_UInt32 sequenceNumber, UA_UInt32 requestId,
  101. UA_String *endpointUrl) {
  102. UA_ByteString *message;
  103. UA_ByteString_new(&message);
  104. UA_ByteString_newMembers(message, 65536);
  105. UA_UInt32 tmpChannelId = channelId;
  106. UA_UInt32 offset = 0;
  107. UA_TcpMessageHeader msghdr;
  108. msghdr.isFinal = 'F';
  109. msghdr.messageType = UA_MESSAGETYPE_MSG;
  110. UA_NodeId type;
  111. type.identifier.numeric = 461;
  112. type.identifierType = UA_NODEIDTYPE_NUMERIC;
  113. type.namespaceIndex = 0;
  114. UA_CreateSessionRequest rq;
  115. UA_RequestHeader_init(&rq.requestHeader);
  116. rq.requestHeader.requestHandle = 1;
  117. rq.requestHeader.timestamp = UA_DateTime_now();
  118. rq.requestHeader.timeoutHint = 10000;
  119. rq.requestHeader.auditEntryId.length = -1;
  120. rq.requestHeader.authenticationToken.identifier.numeric = 10;
  121. rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
  122. rq.requestHeader.authenticationToken.namespaceIndex = 10;
  123. UA_String_copy(endpointUrl, &rq.endpointUrl);
  124. rq.clientDescription.applicationName.locale.length = 0;
  125. rq.clientDescription.applicationName.text.length = 0;
  126. rq.serverUri.length = 0;
  127. rq.serverUri.data = UA_NULL;
  128. rq.clientDescription.applicationUri.length = 0;
  129. rq.clientDescription.discoveryProfileUri.length = 0;
  130. rq.clientDescription.discoveryUrls = UA_NULL;
  131. rq.clientDescription.discoveryUrlsSize = 0;
  132. rq.clientDescription.gatewayServerUri.length = 0;
  133. rq.clientDescription.productUri.length = 0;
  134. UA_String_copycstring("mysession", &rq.sessionName);
  135. UA_String_copycstring("abcd", &rq.clientCertificate);
  136. UA_ByteString_newMembers(&rq.clientNonce, 1);
  137. rq.clientNonce.data[0] = 0;
  138. rq.requestedSessionTimeout = 1200000;
  139. rq.maxResponseMessageSize = UA_INT32_MAX;
  140. msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) + UA_CreateSessionRequest_calcSizeBinary(&rq);
  141. UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
  142. UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
  143. UA_UInt32_encodeBinary(&tokenId, message, &offset);
  144. UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
  145. UA_UInt32_encodeBinary(&requestId, message, &offset);
  146. UA_NodeId_encodeBinary(&type, message, &offset);
  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, UA_NodeId authenticationToken) {
  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_NodeId type;
  170. type.identifier.numeric = 467;
  171. type.identifierType = UA_NODEIDTYPE_NUMERIC;
  172. type.namespaceIndex = 0;
  173. UA_ActivateSessionRequest rq;
  174. UA_ActivateSessionRequest_init(&rq);
  175. rq.requestHeader.requestHandle = 2;
  176. rq.requestHeader.authenticationToken = authenticationToken;
  177. rq.requestHeader.timestamp = UA_DateTime_now();
  178. rq.requestHeader.timeoutHint = 10000;
  179. msghdr.messageSize = 16 +UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) + UA_ActivateSessionRequest_calcSizeBinary(&rq);
  180. UA_TcpMessageHeader_encodeBinary(&msghdr, message, &offset);
  181. UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
  182. UA_UInt32_encodeBinary(&tokenId, message, &offset);
  183. UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
  184. UA_UInt32_encodeBinary(&requestId, message, &offset);
  185. UA_NodeId_encodeBinary(&type, message, &offset);
  186. UA_ActivateSessionRequest_encodeBinary(&rq, message, &offset);
  187. UA_Int32 sendret = send(sock, message->data, offset, 0);
  188. UA_ByteString_delete(message);
  189. if (sendret < 0) {
  190. printf("send opensecurechannel failed");
  191. return 1;
  192. }
  193. return 0;
  194. }
  195. UA_Int64 sendReadRequest(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId,
  196. UA_UInt32 sequenceNumber, UA_UInt32 requestId,UA_NodeId authenticationToken, UA_Int32 nodeIds_size,UA_NodeId* nodeIds) {
  197. UA_ByteString *message;
  198. UA_ByteString_new(&message);
  199. UA_ByteString_newMembers(message, 65536);
  200. UA_UInt32 tmpChannelId = channelId;
  201. UA_UInt32 offset = 0;
  202. UA_TcpMessageHeader msghdr;
  203. msghdr.isFinal = 'F';
  204. msghdr.messageType = UA_MESSAGETYPE_MSG;
  205. UA_NodeId type;
  206. type.identifier.numeric = 631;
  207. type.identifierType = UA_NODEIDTYPE_NUMERIC;
  208. type.namespaceIndex = 0;
  209. UA_ReadRequest rq;
  210. UA_ReadRequest_init(&rq);
  211. rq.maxAge = 0;
  212. UA_Array_new((void **) &rq.nodesToRead, nodeIds_size, &UA_[UA_READVALUEID]);
  213. rq.nodesToReadSize = nodeIds_size;
  214. for(UA_Int32 i=0;i<nodeIds_size;i++)
  215. {
  216. UA_ReadValueId_init(&(rq.nodesToRead[i]));
  217. rq.nodesToRead[i].attributeId = 6; //WriteMask
  218. UA_NodeId_init(&(rq.nodesToRead[i].nodeId));
  219. rq.nodesToRead[i].nodeId = nodeIds[i];
  220. UA_QualifiedName_init(&(rq.nodesToRead[0].dataEncoding));
  221. }
  222. rq.requestHeader.timeoutHint = 10000;
  223. rq.requestHeader.timestamp = UA_DateTime_now();
  224. rq.requestHeader.authenticationToken = authenticationToken;
  225. rq.timestampsToReturn = 0x03;
  226. rq.requestHeader.requestHandle = 1 + requestId;
  227. msghdr.messageSize = 16 +UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) + UA_ReadRequest_calcSizeBinary(&rq);
  228. UA_TcpMessageHeader_encodeBinary(&msghdr,message,&offset);
  229. UA_UInt32_encodeBinary(&tmpChannelId, message, &offset);
  230. UA_UInt32_encodeBinary(&tokenId, message, &offset);
  231. UA_UInt32_encodeBinary(&sequenceNumber, message, &offset);
  232. UA_UInt32_encodeBinary(&requestId, message, &offset);
  233. UA_NodeId_encodeBinary(&type,message,&offset);
  234. UA_ReadRequest_encodeBinary(&rq, message, &offset);
  235. UA_DateTime tic = UA_DateTime_now();
  236. UA_Int32 sendret = send(sock, message->data, offset, 0);
  237. UA_Array_delete(rq.nodesToRead,nodeIds_size,&UA_[UA_READVALUEID]);
  238. UA_ByteString_delete(message);
  239. if (sendret < 0) {
  240. printf("send readrequest failed");
  241. return 1;
  242. }
  243. return tic;
  244. }
  245. int main(int argc, char *argv[]) {
  246. int sock;
  247. struct sockaddr_in server;
  248. UA_ByteString *reply;
  249. UA_ByteString_new(&reply);
  250. UA_ByteString_newMembers(reply, 65536);
  251. //start parameters
  252. if(argc < 7)
  253. {
  254. printf("1st parameter: number of nodes to read \n");
  255. printf("2nd parameter: number of read-tries \n");
  256. printf("3rd parameter: name of the file to save measurement data \n");
  257. printf("4th parameter: 1 = read same node, 0 = read different nodes \n");
  258. printf("5th parameter: ip adress \n");
  259. printf("6th parameter: port \n");
  260. return 0;
  261. }
  262. UA_UInt32 nodesToReadSize;
  263. UA_UInt32 tries;
  264. UA_Boolean alwaysSameNode;
  265. if(argv[1] == UA_NULL){
  266. nodesToReadSize = 1;
  267. }else{
  268. nodesToReadSize = atoi(argv[1]);
  269. }
  270. if(argv[2] == UA_NULL){
  271. tries= 2;
  272. }else{
  273. tries = (UA_UInt32) atoi(argv[2]);
  274. }
  275. if(atoi(argv[4]) != 0)
  276. {
  277. alwaysSameNode = UA_TRUE;
  278. }
  279. else
  280. {
  281. alwaysSameNode = UA_FALSE;
  282. }
  283. /*UA_Int32 pid;
  284. if((pid = fork()) < 0) {
  285. printf("no fork possible");
  286. return 0;
  287. }
  288. else*/{
  289. //Create socket
  290. sock = socket(AF_INET, SOCK_STREAM, 0);
  291. if (sock == -1) {
  292. printf("Could not create socket");
  293. }
  294. server.sin_addr.s_addr = inet_addr(argv[5]);
  295. server.sin_family = AF_INET;
  296. server.sin_port = htons(atoi(argv[6]));
  297. //Connect to remote server
  298. if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
  299. perror("connect failed. Error");
  300. return 1;
  301. }
  302. UA_String *endpointUrl;
  303. UA_String_new(&endpointUrl);
  304. UA_String_copycstring("opc.tcp://blabla.com:1234", endpointUrl);
  305. sendHello(sock, endpointUrl);
  306. int received = recv(sock, reply->data, reply->length, 0);
  307. sendOpenSecureChannel(sock);
  308. received = recv(sock, reply->data, reply->length, 0);
  309. UA_UInt32 recvOffset = 0;
  310. UA_TcpMessageHeader msghdr;
  311. UA_TcpMessageHeader_decodeBinary(reply, &recvOffset, &msghdr);
  312. UA_UInt32 secureChannelId;
  313. UA_AsymmetricAlgorithmSecurityHeader asymHeader;
  314. UA_SequenceHeader seqHeader;
  315. UA_NodeId rspType;
  316. UA_OpenSecureChannelResponse openSecChannelRsp;
  317. UA_UInt32_decodeBinary(reply, &recvOffset, &secureChannelId);
  318. UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(reply,&recvOffset,&asymHeader);
  319. UA_SequenceHeader_decodeBinary(reply,&recvOffset,&seqHeader);
  320. UA_NodeId_decodeBinary(reply,&recvOffset,&rspType);
  321. UA_OpenSecureChannelResponse_decodeBinary(reply,&recvOffset,&openSecChannelRsp);
  322. sendCreateSession(sock, secureChannelId, openSecChannelRsp.securityToken.tokenId, 52, 2, endpointUrl);
  323. received = recv(sock, reply->data, reply->length, 0);
  324. UA_NodeId messageType;
  325. recvOffset = 24;
  326. UA_NodeId_decodeBinary(reply,&recvOffset,&messageType);
  327. UA_CreateSessionResponse createSessionResponse;
  328. UA_CreateSessionResponse_decodeBinary(reply,&recvOffset,&createSessionResponse);
  329. sendActivateSession(sock, secureChannelId, openSecChannelRsp.securityToken.tokenId, 53, 3,createSessionResponse.authenticationToken);
  330. received = recv(sock, reply->data, reply->length, 0);
  331. UA_NodeId *nodesToRead;
  332. UA_Array_new((void**)&nodesToRead,nodesToReadSize,&UA_[UA_NODEID]);
  333. for(UA_UInt32 i = 0; i<nodesToReadSize; i++){
  334. UA_NodeId_new((UA_NodeId**)&nodesToRead[i]);
  335. if(alwaysSameNode){
  336. nodesToRead[i].identifier.numeric = 2253; //ask always the same node
  337. }
  338. else{
  339. nodesToRead[i].identifier.numeric = 19000 +i;
  340. }
  341. nodesToRead[i].identifierType = UA_NODEIDTYPE_NUMERIC;
  342. nodesToRead[i].namespaceIndex = 0;
  343. }
  344. UA_DateTime tic, toc;
  345. UA_Double *timeDiffs;
  346. UA_Array_new((void**)&timeDiffs,tries,&UA_[UA_DOUBLE]);
  347. UA_Double sum = 0;
  348. for (UA_UInt32 i = 0; i < tries; i++) {
  349. tic = sendReadRequest(sock, secureChannelId, openSecChannelRsp.securityToken.tokenId, 54+i, 4+i,createSessionResponse.authenticationToken,nodesToReadSize,nodesToRead);
  350. received = recv(sock, reply->data, 2000, 0);
  351. toc = UA_DateTime_now() - tic;
  352. timeDiffs[i] = (UA_Double)toc/(UA_Double)10e3;
  353. sum = sum + timeDiffs[i];
  354. //printf("read request took: %16.10f ms \n",timeDiffs[i]);
  355. }
  356. UA_Double mean = sum / tries;
  357. printf("mean time for handling request: %16.10f ms \n",mean);
  358. if(received>0)//dummy
  359. {
  360. printf("%i",received);
  361. }
  362. //save to file
  363. char data[100];
  364. const char flag = 'a';
  365. FILE* fHandle = fopen(argv[3],&flag);
  366. //header
  367. UA_Int32 bytesToWrite = sprintf(data,"measurement %s in ms, nodesToRead %d \n",argv[3],nodesToReadSize);
  368. fwrite(data,1,bytesToWrite,fHandle);
  369. for(UA_UInt32 i=0;i<tries;i++){
  370. bytesToWrite = sprintf(data,"%16.10f \n",timeDiffs[i]);
  371. fwrite(data,1,bytesToWrite,fHandle);
  372. }
  373. fclose(fHandle);
  374. UA_String_delete(endpointUrl);
  375. UA_Array_delete(nodesToRead,nodesToReadSize,&UA_[UA_NODEID]);
  376. close(sock);
  377. return 0;
  378. }
  379. }