client_find_servers.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
  2. * See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
  3. /**
  4. * This client requests all the available servers from the discovery server (see server_discovery.c)
  5. * and then calls GetEndpoints on the returned list of servers.
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "open62541.h"
  10. UA_Logger logger = UA_Log_Stdout;
  11. static UA_StatusCode
  12. FindServers(const char* discoveryServerUrl, size_t* registeredServerSize,
  13. UA_ApplicationDescription** registeredServers) {
  14. UA_Client *client = UA_Client_new(UA_ClientConfig_standard);
  15. UA_StatusCode retval = UA_Client_connect(client, discoveryServerUrl);
  16. if(retval != UA_STATUSCODE_GOOD) {
  17. UA_Client_delete(client);
  18. return retval;
  19. }
  20. UA_FindServersRequest request;
  21. UA_FindServersRequest_init(&request);
  22. /* If you want to find specific servers, you can also include the server
  23. * URIs in the request: */
  24. //request.serverUrisSize = 1;
  25. //request.serverUris = UA_malloc(sizeof(UA_String));
  26. //request.serverUris[0] = UA_String_fromChars("open62541.example.server_register");
  27. //request.localeIdsSize = 1;
  28. //request.localeIds = UA_malloc(sizeof(UA_String));
  29. //request.localeIds[0] = UA_String_fromChars("en");
  30. // now send the request
  31. UA_FindServersResponse response;
  32. UA_FindServersResponse_init(&response);
  33. __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_FINDSERVERSREQUEST],
  34. &response, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]);
  35. //UA_Array_delete(request.serverUris, request.serverUrisSize, &UA_TYPES[UA_TYPES_STRING]);
  36. //UA_Array_delete(request.localeIds, request.localeIdsSize, &UA_TYPES[UA_TYPES_STRING]);
  37. if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  38. UA_LOG_ERROR(logger, UA_LOGCATEGORY_CLIENT,
  39. "FindServers failed with statuscode 0x%08x", response.responseHeader.serviceResult);
  40. UA_FindServersResponse_deleteMembers(&response);
  41. UA_Client_disconnect(client);
  42. UA_Client_delete(client);
  43. return response.responseHeader.serviceResult;
  44. }
  45. *registeredServerSize = response.serversSize;
  46. *registeredServers = (UA_ApplicationDescription*)UA_Array_new(response.serversSize,
  47. &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
  48. for(size_t i=0;i<response.serversSize;i++)
  49. UA_ApplicationDescription_copy(&response.servers[i], &(*registeredServers)[i]);
  50. UA_FindServersResponse_deleteMembers(&response);
  51. UA_Client_disconnect(client);
  52. UA_Client_delete(client);
  53. return (int) UA_STATUSCODE_GOOD;
  54. }
  55. static UA_StatusCode
  56. GetEndpoints(UA_Client *client, const UA_String* endpointUrl, size_t* endpointDescriptionsSize,
  57. UA_EndpointDescription** endpointDescriptions) {
  58. UA_GetEndpointsRequest request;
  59. UA_GetEndpointsRequest_init(&request);
  60. //request.requestHeader.authenticationToken = client->authenticationToken;
  61. request.requestHeader.timestamp = UA_DateTime_now();
  62. request.requestHeader.timeoutHint = 10000;
  63. request.endpointUrl = *endpointUrl; // assume the endpointurl outlives the service call
  64. UA_GetEndpointsResponse response;
  65. UA_GetEndpointsResponse_init(&response);
  66. __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST],
  67. &response, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]);
  68. if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  69. UA_LOG_ERROR(logger, UA_LOGCATEGORY_CLIENT,
  70. "GetEndpointRequest failed with statuscode 0x%08x",
  71. response.responseHeader.serviceResult);
  72. UA_GetEndpointsResponse_deleteMembers(&response);
  73. return response.responseHeader.serviceResult;
  74. }
  75. *endpointDescriptionsSize = response.endpointsSize;
  76. *endpointDescriptions = (UA_EndpointDescription*)UA_Array_new(response.endpointsSize,
  77. &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
  78. for(size_t i=0;i<response.endpointsSize;i++) {
  79. UA_EndpointDescription_init(&(*endpointDescriptions)[i]);
  80. UA_EndpointDescription_copy(&response.endpoints[i], &(*endpointDescriptions)[i]);
  81. }
  82. UA_GetEndpointsResponse_deleteMembers(&response);
  83. return UA_STATUSCODE_GOOD;
  84. }
  85. int main(void) {
  86. UA_ApplicationDescription* applicationDescriptionArray = NULL;
  87. size_t applicationDescriptionArraySize = 0;
  88. UA_StatusCode retval = FindServers("opc.tcp://localhost:4840",
  89. &applicationDescriptionArraySize,
  90. &applicationDescriptionArray);
  91. if(retval != UA_STATUSCODE_GOOD) {
  92. UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Could not call FindServers service. "
  93. "Is the discovery server started? StatusCode %s", UA_StatusCode_name(retval));
  94. return (int)retval;
  95. }
  96. // output all the returned/registered servers
  97. for (size_t i=0; i<applicationDescriptionArraySize; i++) {
  98. UA_ApplicationDescription *description = &applicationDescriptionArray[i];
  99. printf("Server[%lu]: %.*s", (unsigned long)i, (int)description->applicationUri.length,
  100. description->applicationUri.data);
  101. printf("\n\tName: %.*s", (int)description->applicationName.text.length,
  102. description->applicationName.text.data);
  103. printf("\n\tProduct URI: %.*s", (int)description->productUri.length,
  104. description->productUri.data);
  105. printf("\n\tType: ");
  106. switch(description->applicationType) {
  107. case UA_APPLICATIONTYPE_SERVER:
  108. printf("Server");
  109. break;
  110. case UA_APPLICATIONTYPE_CLIENT:
  111. printf("Client");
  112. break;
  113. case UA_APPLICATIONTYPE_CLIENTANDSERVER:
  114. printf("Client and Server");
  115. break;
  116. case UA_APPLICATIONTYPE_DISCOVERYSERVER:
  117. printf("Discovery Server");
  118. break;
  119. default:
  120. printf("Unknown");
  121. }
  122. printf("\n\tDiscovery URLs:");
  123. for (size_t j=0; j<description->discoveryUrlsSize; j++) {
  124. printf("\n\t\t[%lu]: %.*s", (unsigned long)j,
  125. (int)description->discoveryUrls[j].length,
  126. description->discoveryUrls[j].data);
  127. }
  128. printf("\n\n");
  129. }
  130. /*
  131. * Now that we have the list of available servers, call get endpoints on all of them
  132. */
  133. printf("-------- Server Endpoints --------\n");
  134. for (size_t i=0; i<applicationDescriptionArraySize; i++) {
  135. UA_ApplicationDescription *description = &applicationDescriptionArray[i];
  136. if (description->discoveryUrlsSize == 0) {
  137. UA_LOG_INFO(logger, UA_LOGCATEGORY_CLIENT,
  138. "[GetEndpoints] Server %.*s did not provide any discovery urls. Skipping.",
  139. description->applicationUri);
  140. continue;
  141. }
  142. printf("\nEndpoints for Server[%lu]: %.*s", (unsigned long)i,
  143. (int)description->applicationUri.length, description->applicationUri.data);
  144. UA_Client *client = UA_Client_new(UA_ClientConfig_standard);
  145. char* discoveryUrl = (char*)malloc(sizeof(char)*description->discoveryUrls[0].length+1);
  146. memcpy( discoveryUrl, description->discoveryUrls[0].data, description->discoveryUrls[0].length );
  147. discoveryUrl[description->discoveryUrls[0].length] = '\0';
  148. retval = UA_Client_connect(client, discoveryUrl);
  149. free(discoveryUrl);
  150. if(retval != UA_STATUSCODE_GOOD) {
  151. UA_Client_delete(client);
  152. return (int)retval;
  153. }
  154. UA_EndpointDescription* endpointArray = NULL;
  155. size_t endpointArraySize = 0;
  156. retval = GetEndpoints(client, &description->discoveryUrls[0], &endpointArraySize, &endpointArray);
  157. if(retval != UA_STATUSCODE_GOOD) {
  158. UA_Client_disconnect(client);
  159. UA_Client_delete(client);
  160. break;
  161. }
  162. for(size_t j = 0; j < endpointArraySize; j++) {
  163. UA_EndpointDescription* endpoint = &endpointArray[j];
  164. printf("\n\tEndpoint[%lu]:",(unsigned long)j);
  165. printf("\n\t\tEndpoint URL: %.*s", (int)endpoint->endpointUrl.length, endpoint->endpointUrl.data);
  166. printf("\n\t\tTransport profile URI: %.*s", (int)endpoint->transportProfileUri.length,
  167. endpoint->transportProfileUri.data);
  168. }
  169. UA_Array_delete(endpointArray, endpointArraySize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
  170. UA_Client_disconnect(client);
  171. UA_Client_delete(client);
  172. }
  173. printf("\n");
  174. UA_Array_delete(applicationDescriptionArray, applicationDescriptionArraySize,
  175. &UA_TYPES[UA_TYPES_APPLICATIONDESCRIPTION]);
  176. return (int)UA_STATUSCODE_GOOD;
  177. }