ua_server_discovery.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. *
  5. * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
  6. * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
  7. */
  8. #include <open62541/client.h>
  9. #include "ua_server_internal.h"
  10. #ifdef UA_ENABLE_DISCOVERY
  11. UA_StatusCode
  12. register_server_with_discovery_server(UA_Server *server,
  13. void *pClient,
  14. const UA_Boolean isUnregister,
  15. const char* semaphoreFilePath) {
  16. UA_Client *client = (UA_Client *) pClient;
  17. /* Prepare the request. Do not cleanup the request after the service call,
  18. * as the members are stack-allocated or point into the server config. */
  19. UA_RegisterServer2Request request;
  20. UA_RegisterServer2Request_init(&request);
  21. request.requestHeader.timestamp = UA_DateTime_now();
  22. request.requestHeader.timeoutHint = 10000;
  23. request.server.isOnline = !isUnregister;
  24. request.server.serverUri = server->config.applicationDescription.applicationUri;
  25. request.server.productUri = server->config.applicationDescription.productUri;
  26. request.server.serverType = server->config.applicationDescription.applicationType;
  27. request.server.gatewayServerUri = server->config.applicationDescription.gatewayServerUri;
  28. if(semaphoreFilePath) {
  29. #ifdef UA_ENABLE_DISCOVERY_SEMAPHORE
  30. request.server.semaphoreFilePath =
  31. UA_STRING((char*)(uintptr_t)semaphoreFilePath); /* dirty cast */
  32. #else
  33. UA_LOG_WARNING(&server->config.logger, UA_LOGCATEGORY_CLIENT,
  34. "Ignoring semaphore file path. open62541 not compiled "
  35. "with UA_ENABLE_DISCOVERY_SEMAPHORE=ON");
  36. #endif
  37. }
  38. request.server.serverNames = &server->config.applicationDescription.applicationName;
  39. request.server.serverNamesSize = 1;
  40. /* Copy the discovery urls from the server config and the network layers*/
  41. size_t config_discurls = server->config.applicationDescription.discoveryUrlsSize;
  42. size_t nl_discurls = server->config.networkLayersSize;
  43. size_t total_discurls = config_discurls + nl_discurls;
  44. UA_STACKARRAY(UA_String, urlsBuf, total_discurls);
  45. request.server.discoveryUrls = urlsBuf;
  46. request.server.discoveryUrlsSize = total_discurls;
  47. for(size_t i = 0; i < config_discurls; ++i)
  48. request.server.discoveryUrls[i] = server->config.applicationDescription.discoveryUrls[i];
  49. /* TODO: Add nl only if discoveryUrl not already present */
  50. for(size_t i = 0; i < nl_discurls; ++i) {
  51. UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
  52. request.server.discoveryUrls[config_discurls + i] = nl->discoveryUrl;
  53. }
  54. #ifdef UA_ENABLE_DISCOVERY_MULTICAST
  55. request.discoveryConfigurationSize = 1;
  56. request.discoveryConfiguration = UA_ExtensionObject_new();
  57. UA_ExtensionObject_init(&request.discoveryConfiguration[0]);
  58. // Set to NODELETE so that we can just use a pointer to the mdns config
  59. request.discoveryConfiguration[0].encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
  60. request.discoveryConfiguration[0].content.decoded.type = &UA_TYPES[UA_TYPES_MDNSDISCOVERYCONFIGURATION];
  61. request.discoveryConfiguration[0].content.decoded.data = &server->config.discovery.mdns;
  62. #endif
  63. // First try with RegisterServer2, if that isn't implemented, use RegisterServer
  64. UA_RegisterServer2Response response;
  65. __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_REGISTERSERVER2REQUEST],
  66. &response, &UA_TYPES[UA_TYPES_REGISTERSERVER2RESPONSE]);
  67. UA_StatusCode serviceResult = response.responseHeader.serviceResult;
  68. UA_RegisterServer2Response_deleteMembers(&response);
  69. UA_Array_delete(request.discoveryConfiguration,
  70. request.discoveryConfigurationSize,
  71. &UA_TYPES[UA_TYPES_EXTENSIONOBJECT]);
  72. request.discoveryConfiguration = NULL;
  73. request.discoveryConfigurationSize = 0;
  74. if(serviceResult == UA_STATUSCODE_BADNOTIMPLEMENTED ||
  75. serviceResult == UA_STATUSCODE_BADSERVICEUNSUPPORTED) {
  76. /* Try RegisterServer */
  77. UA_RegisterServerRequest request_fallback;
  78. UA_RegisterServerRequest_init(&request_fallback);
  79. /* Copy from RegisterServer2 request */
  80. request_fallback.requestHeader = request.requestHeader;
  81. request_fallback.server = request.server;
  82. UA_RegisterServerResponse response_fallback;
  83. __UA_Client_Service(client, &request_fallback,
  84. &UA_TYPES[UA_TYPES_REGISTERSERVERREQUEST],
  85. &response_fallback,
  86. &UA_TYPES[UA_TYPES_REGISTERSERVERRESPONSE]);
  87. serviceResult = response_fallback.responseHeader.serviceResult;
  88. UA_RegisterServerResponse_deleteMembers(&response_fallback);
  89. }
  90. if(serviceResult != UA_STATUSCODE_GOOD) {
  91. UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_CLIENT,
  92. "RegisterServer/RegisterServer2 failed with statuscode %s",
  93. UA_StatusCode_name(serviceResult));
  94. }
  95. return serviceResult;
  96. }
  97. UA_StatusCode
  98. UA_Server_register_discovery(UA_Server *server, UA_Client *client,
  99. const char* semaphoreFilePath) {
  100. UA_LOCK(server->serviceMutex);
  101. UA_StatusCode retval = register_server_with_discovery_server(server, client,
  102. false, semaphoreFilePath);
  103. UA_UNLOCK(server->serviceMutex);
  104. return retval;
  105. }
  106. UA_StatusCode
  107. UA_Server_unregister_discovery(UA_Server *server, UA_Client *client) {
  108. UA_LOCK(server->serviceMutex);
  109. UA_StatusCode retval = register_server_with_discovery_server(server, client,
  110. true, NULL);
  111. UA_UNLOCK(server->serviceMutex);
  112. return retval;
  113. }
  114. #endif /* UA_ENABLE_DISCOVERY */