client_find_servers.c 8.5 KB

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