client_find_servers.c 8.5 KB

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