ua_services_discovery.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/.*/
  4. #include "ua_server_internal.h"
  5. #include "ua_services.h"
  6. #include "ua_util.h"
  7. void Service_FindServers(UA_Server *server, UA_Session *session,
  8. const UA_FindServersRequest *request, UA_FindServersResponse *response) {
  9. UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing FindServersRequest");
  10. /* copy ApplicationDescription from the config */
  11. UA_ApplicationDescription *descr = UA_malloc(sizeof(UA_ApplicationDescription));
  12. if(!descr) {
  13. response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
  14. return;
  15. }
  16. response->responseHeader.serviceResult =
  17. UA_ApplicationDescription_copy(&server->config.applicationDescription, descr);
  18. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  19. UA_free(descr);
  20. return;
  21. }
  22. /* add the discoveryUrls from the networklayers */
  23. UA_String *disc = UA_realloc(descr->discoveryUrls, sizeof(UA_String) *
  24. (descr->discoveryUrlsSize + server->config.networkLayersSize));
  25. if(!disc) {
  26. response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
  27. UA_ApplicationDescription_delete(descr);
  28. return;
  29. }
  30. size_t existing = descr->discoveryUrlsSize;
  31. descr->discoveryUrls = disc;
  32. descr->discoveryUrlsSize += server->config.networkLayersSize;
  33. // TODO: Add nl only if discoveryUrl not already present
  34. for(size_t i = 0; i < server->config.networkLayersSize; ++i) {
  35. UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
  36. UA_String_copy(&nl->discoveryUrl, &descr->discoveryUrls[existing + i]);
  37. }
  38. response->servers = descr;
  39. response->serversSize = 1;
  40. }
  41. void Service_GetEndpoints(UA_Server *server, UA_Session *session, const UA_GetEndpointsRequest *request,
  42. UA_GetEndpointsResponse *response) {
  43. /* If the client expects to see a specific endpointurl, mirror it back. If
  44. not, clone the endpoints with the discovery url of all networklayers. */
  45. const UA_String *endpointUrl = &request->endpointUrl;
  46. if(endpointUrl->length > 0) {
  47. UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing GetEndpointsRequest with endpointUrl " \
  48. UA_PRINTF_STRING_FORMAT, UA_PRINTF_STRING_DATA(*endpointUrl));
  49. } else {
  50. UA_LOG_DEBUG_SESSION(server->config.logger, session, "Processing GetEndpointsRequest with an empty endpointUrl");
  51. }
  52. /* test if the supported binary profile shall be returned */
  53. #ifdef NO_ALLOCA
  54. UA_Boolean relevant_endpoints[server->endpointDescriptionsSize];
  55. #else
  56. UA_Boolean *relevant_endpoints = UA_alloca(sizeof(UA_Boolean) * server->endpointDescriptionsSize);
  57. #endif
  58. memset(relevant_endpoints, 0, sizeof(UA_Boolean) * server->endpointDescriptionsSize);
  59. size_t relevant_count = 0;
  60. if(request->profileUrisSize == 0) {
  61. for(size_t j = 0; j < server->endpointDescriptionsSize; ++j)
  62. relevant_endpoints[j] = true;
  63. relevant_count = server->endpointDescriptionsSize;
  64. } else {
  65. for(size_t j = 0; j < server->endpointDescriptionsSize; ++j) {
  66. for(size_t i = 0; i < request->profileUrisSize; ++i) {
  67. if(!UA_String_equal(&request->profileUris[i], &server->endpointDescriptions[j].transportProfileUri))
  68. continue;
  69. relevant_endpoints[j] = true;
  70. ++relevant_count;
  71. break;
  72. }
  73. }
  74. }
  75. if(relevant_count == 0) {
  76. response->endpointsSize = 0;
  77. return;
  78. }
  79. /* Clone the endpoint for each networklayer? */
  80. size_t clone_times = 1;
  81. UA_Boolean nl_endpointurl = false;
  82. if(endpointUrl->length == 0) {
  83. clone_times = server->config.networkLayersSize;
  84. nl_endpointurl = true;
  85. }
  86. response->endpoints = UA_Array_new(relevant_count * clone_times, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
  87. if(!response->endpoints) {
  88. response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY;
  89. return;
  90. }
  91. response->endpointsSize = relevant_count * clone_times;
  92. size_t k = 0;
  93. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  94. for(size_t i = 0; i < clone_times; ++i) {
  95. if(nl_endpointurl)
  96. endpointUrl = &server->config.networkLayers[i].discoveryUrl;
  97. for(size_t j = 0; j < server->endpointDescriptionsSize; ++j) {
  98. if(!relevant_endpoints[j])
  99. continue;
  100. retval |= UA_EndpointDescription_copy(&server->endpointDescriptions[j], &response->endpoints[k]);
  101. retval |= UA_String_copy(endpointUrl, &response->endpoints[k].endpointUrl);
  102. ++k;
  103. }
  104. }
  105. if(retval != UA_STATUSCODE_GOOD) {
  106. response->responseHeader.serviceResult = retval;
  107. UA_Array_delete(response->endpoints, response->endpointsSize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
  108. response->endpoints = NULL;
  109. response->endpointsSize = 0;
  110. return;
  111. }
  112. }