From 06fa00c81790162b7679141b7bc3e0485ec81294 Mon Sep 17 00:00:00 2001 From: Francesco Pham Date: Fri, 2 Sep 2022 14:55:55 +0200 Subject: [PATCH] linux/communication: move resource directory object into EddieEndpoint - move resource directory object into EddieEndpoint, including methods that use the resource directory (ip/port getters, discover_rd, publish/unpublish) - access the resource directory using only coap requests even if the resource directory is local, without having to use direct method calls when the rd is in the same node. - remove remove_endpoint and add_endpoint from ResourceDirectory because not necessary anymore - move endpoints_to_string_list_filtered and rd_resources_to_string_list_filtered into private in ResourceDirectory - adapt tests, eddie-endpoint, VirtualizationReceiver to the new changes Signed-off-by: Francesco Pham --- common/include/EddieEndpoint.h | 20 ++ linux/communication/include/CoapServer.h | 72 ++----- .../communication/include/ResourceDirectory.h | 56 ++--- linux/communication/src/CoapServer.cpp | 199 ++---------------- linux/communication/src/EddieEndpoint.cpp | 168 ++++++++++++--- linux/communication/src/ResourceDirectory.cpp | 16 -- linux/examples/eddie_endpoint.cpp | 24 ++- linux/tests/communication_tests.cpp | 20 +- .../src/VirtualizationReceiver.cpp | 3 +- 9 files changed, 235 insertions(+), 343 deletions(-) diff --git a/common/include/EddieEndpoint.h b/common/include/EddieEndpoint.h index 0fd671f..7c488b7 100644 --- a/common/include/EddieEndpoint.h +++ b/common/include/EddieEndpoint.h @@ -18,6 +18,11 @@ private: CoapServer *server = nullptr; std::string resource_directory_ip; + std::string resource_directory_port; + + std::string ep; // endpoint name + std::string d; // sector name + std::string rd_endpoint; // rd endpoint string public: @@ -67,6 +72,10 @@ public: */ int start_server(bool blocking = false); + /** + * Stop the server thread + * @return 0 on success + */ int stop_server(); /** @@ -74,6 +83,17 @@ public: * @return 0 on success, -1 on error */ int publish_resources(); + + /** + * Ask the RD node to remove all the resources registered by this endpoint + * @return 0 non success, negative integer on failure + */ + int unpublish_resources(); + + /** + * Initialize a resource directory in the current node + */ + void init_resource_dir_local(); }; #endif \ No newline at end of file diff --git a/linux/communication/include/CoapServer.h b/linux/communication/include/CoapServer.h index 9bca529..5dc37bd 100644 --- a/linux/communication/include/CoapServer.h +++ b/linux/communication/include/CoapServer.h @@ -31,13 +31,6 @@ private: CoapClient *client; std::string my_ip; std::string my_port; - std::string ep; // endpoint name - std::string d; // sector name - - std::string resource_dir_ip; - std::string resource_dir_port; - std::string rd_endpoint; // rd endpoint string - ResourceDirectory *resource_directory = nullptr; std::thread server_thread; @@ -57,9 +50,8 @@ public: * CoapServer constructor * @param host The server's IP address. This IP address will used as base url in the resource directory registration * @param port Port number of the server as a string - * @param is_resource_dir True to initialize a resource directory in this node. */ - explicit CoapServer(const char *host, const char *port, int is_resource_dir); + explicit CoapServer(const char *host, const char *port); /** * The CoapServer destructor unpublishes the resources previously registered in the resource directory, @@ -73,35 +65,6 @@ public: */ CoapClient *get_client(); - /** - * Check if the current node is hosting the resource directory - * @return True if this node is a resource directory - */ - [[nodiscard]] bool is_rd() const; - - /** - * The IP address of the remote resource directory previously discovered using discover_rd - * @return IP address of the resource directory, empty string if no resource directory was discovered - */ - std::string get_rd_ip(); - - /** - * The port number of the remote resource directory previously discovered using discover_rd - * @return Port number of the resource directory, empty string if no resource directory was discovered - */ - std::string get_rd_port(); - - /** - * Initialize a resource directory in the current node - */ - void init_resource_dir_local(); - - /** - * Discover a resource directory in the network by sending a multicast CoAP request and listening for response. - * @return 0 on success, -1 if no resource directory was found or an error occurred sending the request. - */ - int discover_rd(); - /** * Add a resource into the server. A resource consists of a path, attributes and REST methods. * Adding the resource allows the server to serve it and call the appropriate REST handler @@ -111,26 +74,6 @@ public: */ int add_resource(EddieResource *resource); - /** - * Register the resources, previously added, in the resource directory - * @param lt Lifetime, length of time in seconds that the published resources are to be valid in the resource directory - * @return 0 on success, -1 on error - */ - int publish_resources(int lt = 90000); - - /** - * Ask the RD node to remove all the resources registered by this endpoint - * @return 0 non success, negative integer on failure. - */ - int unpublish_resources(); - - /** - * Retrieve the resources from the resource directory locally initialized in this node - * @param filters Filters to apply to the available resources. - * @return The list of resources, each resource is encoded in link format - */ - std::list rd_resources_to_string_list_filtered(const std::map &filters); - /** * Run the server loop spinning the CoAP I/O processing function. This loop runs until set_quit(true) is called * @return 0 on success, negative integer on failure. @@ -148,6 +91,19 @@ public: * @return 0 on success, negative integer on failure. */ int stop_server(); + + /** + * @brief Get the resources added into the server in link format + * + * @return resources as a link format string + */ + static std::string get_resources_in_linkformat(); + + [[nodiscard]] const std::string &get_my_ip() const; + + [[nodiscard]] const std::string &get_my_port() const; + + [[nodiscard]] coap_context_t *getContext() const; }; #endif //EDDIE_COAPSERVER_H diff --git a/linux/communication/include/ResourceDirectory.h b/linux/communication/include/ResourceDirectory.h index e4f1e6d..b5fd463 100644 --- a/linux/communication/include/ResourceDirectory.h +++ b/linux/communication/include/ResourceDirectory.h @@ -56,30 +56,6 @@ private: const std::unordered_map ¶ms, const std::string &data); - int init_server_context(); - - [[nodiscard]] bool get_quit() const { - return quit; - } - - void set_quit(bool val) { - quit = val; - } - -public: - - /** - * @brief Construct and initialize a new Resource Directory - * - * @param server_context A preinitialized server context. If not specified, a new context will be created. - */ - explicit ResourceDirectory(const std::string& ip, coap_context_t *server_context = nullptr); - - /** - * Stop resource directory and releases resources - */ - ~ResourceDirectory(); - /** * Get the list of endpoints potentially filtered by attributes * @param filters The endpoints that match the attributes listed in this map will be returned. @@ -98,25 +74,29 @@ public: static std::list rd_resources_to_string_list_filtered(std::map filters); + int init_server_context(); + + [[nodiscard]] bool get_quit() const { + return quit; + } + + void set_quit(bool val) { + quit = val; + } + +public: + /** - * Remove an endpoint and its associated registered resources - * @param rd_endpoint endpoint location path identifier - * @param ep endpoint name - * @param d endpoint sector - * @return 0 on success + * @brief Construct and initialize a new Resource Directory + * + * @param server_context A preinitialized server context. If not specified, a new context will be created. */ - static int remove_endpoint(const std::string& rd_endpoint, const std::string& ep, const std::string& d); + explicit ResourceDirectory(const std::string& ip, coap_context_t *server_context = nullptr); /** - * Add an endpoint with some parameters and data containing the resources to be registered - * @param ep_d_key key made of endpoint name + @ + endpoint sector - * @param params endpoint attributes - * @param data list of resources to be registered in link format - * @return 0 on success, -1 otherwise + * Stop resource directory and releases resources */ - int add_endpoint(const std::string& ep_d_key, - const std::unordered_map ¶ms, - const std::string &data); + ~ResourceDirectory(); /** * Run the resource directory I/O loop until the resource directory is destroyed diff --git a/linux/communication/src/CoapServer.cpp b/linux/communication/src/CoapServer.cpp index fac6bfc..3e6bb9a 100644 --- a/linux/communication/src/CoapServer.cpp +++ b/linux/communication/src/CoapServer.cpp @@ -7,13 +7,11 @@ #include "CoapServer.h" #include "common.h" -#include "ResourceDirectory.h" #include #include #include #include -#include #include #include #include @@ -22,8 +20,7 @@ class CoapClient; ThreadSafeMap *CoapServer::resources = new ThreadSafeMap(); -std::string -resource_list_to_string(const std::list &resources) { +static std::string resource_list_to_string(const std::list &resources) { size_t buf_size = 1000; auto *buf = static_cast(malloc(buf_size * sizeof(unsigned char))); size_t len = buf_size; @@ -92,36 +89,21 @@ void CoapServer::resource_handler(coap_resource_t *resource, coap_session_t *ses coap_pdu_set_code(response, static_cast(response_message.status_code)); } -CoapServer::CoapServer(const char *host, const char *port, int is_resource_dir) { +CoapServer::CoapServer(const char *host, const char *port) { my_ip = host; my_port = port; LOG_DBG("Initializing CoapServer"); init_server("::", port); this->client = new CoapClient(); - if (is_resource_dir) init_resource_dir_local(); - - auto now = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count(); - - std::ostringstream oss; - oss << now; - - ep = oss.str(); - d = ep; - LOG_DBG("Initialized CoapServer"); } CoapServer::~CoapServer() { - unpublish_resources(); stop_server(); - delete this->resource_directory; - resources->delete_all(); delete resources; delete client; - coap_free_context(this->context); } @@ -137,18 +119,6 @@ CoapClient *CoapServer::get_client() { return client; } -bool CoapServer::is_rd() const { - return this->resource_directory != nullptr; -} - -std::string CoapServer::get_rd_ip() { - return this->resource_dir_ip; -} - -std::string CoapServer::get_rd_port() { - return this->resource_dir_port; -} - int CoapServer::init_server(const char *host, const char *port) { coap_address_t dst; @@ -221,154 +191,6 @@ int CoapServer::add_resource(EddieResource *resource) { return 0; } -int CoapServer::discover_rd() { - LOG_DBG("Discovering resource directory"); - - request_t request { - COAP_IP6_MULTICAST_SITE_LOCAL, - "5683", - GET, - ".well-known/core", - "rt=core.rd", - nullptr, - 0, - false, - 40 - }; - - message_t response = get_client()->send_message_and_wait_response(request); - - std::vector parsed = parse_link_format(response.data); - - if (parsed.empty()) return -1; - - std::string rd_uri = "coap://" + response.src_ip; - coap_uri_t parsed_rd_uri; - int r = coap_split_uri(reinterpret_cast(rd_uri.c_str()), - rd_uri.length(), - &parsed_rd_uri); - - if (r < 0) { - LOG_ERR("Error parsing src address"); - return -1; - } - - this->resource_dir_ip = std::string(reinterpret_cast(parsed_rd_uri.host.s), parsed_rd_uri.host.length); - this->resource_dir_port = std::to_string(parsed_rd_uri.port); - - LOG_DBG("Found resource directory: ip=%s port=%s", this->resource_dir_ip.c_str(), this->resource_dir_port.c_str()); - - return 0; -} - -int CoapServer::publish_resources(int lt) { - auto res_list = resources->get_all(); - - std::string data = resource_list_to_string(res_list); - std::string base_address; - if (is_ipv6_address(my_ip)) - base_address = "coap://[" + my_ip + "]:" + my_port; - else if (is_ipv4_address(my_ip)) - base_address = "coap://" + my_ip + ":" + my_port; - else { - LOG_ERR("Invalid ip address"); - } - - if (data.empty() && !res_list.empty()) { - LOG_DBG("[CoapServer::publish_resources]: unable to create string representation of resource"); - return -1; - } - - if (is_rd() && this->resource_directory) { - std::string ep_d_key = this->ep + "@" + this->d; - - std::unordered_map params = {{"base", base_address}, - {"ep", this->ep}, - {"d", this->d}, - {"lt", std::to_string(lt)}}; - - if (!base_address.empty()) params["base"] = base_address; - - if (this->resource_directory->add_endpoint(ep_d_key, params, data) != 0) { - LOG_ERR("failed to add endpoint to local resource directory"); - return -1; - } - } - else if (!resource_dir_ip.empty()) { - std::string query = "ep=" + ep + "&d=" + d + "<=" + std::to_string(lt); - if (!base_address.empty()) query += + "&base=" + base_address; - - request_t request { - resource_dir_ip.c_str(), - resource_dir_port.c_str(), - POST, - "rd", - query.c_str(), - reinterpret_cast(data.c_str()), - data.length(), - true, - 40 - }; - - message_t response = get_client()->send_message_and_wait_response(request); - if (!response.location_path.empty()) { - this->rd_endpoint = "rd/" + response.location_path; - } - else { - LOG_ERR("Location path option not found in response"); - return -1; - } - } - else { - LOG_ERR("Resource directory is neither local nor remote"); - return -1; - } - - return 0; -} - -int CoapServer::unpublish_resources() { - if (this->resource_directory) { - ResourceDirectory::remove_endpoint(rd_endpoint, ep, d); - return 0; - } - - if (rd_endpoint.empty()) { - LOG_ERR("rd_endpoint is empty, nothing to unpublish"); - return -1; - } - - request_t request { - resource_dir_ip.c_str(), - resource_dir_port.c_str(), - DELETE, - this->rd_endpoint.c_str(), - nullptr, - nullptr, - 0, - true, - 40 - }; - message_t response = get_client()->send_message_and_wait_response(request); - if (response.status_code != DELETED) return -1; - - return 0; -} - -void CoapServer::init_resource_dir_local() { - LOG_DBG("Initializing local resource directory"); - if (this->resource_directory) { - LOG_ERR("local resource directory already initialized"); - return; - } - this->resource_directory = new ResourceDirectory(my_ip, this->context); -} - -std::list CoapServer::rd_resources_to_string_list_filtered(const std::map &filters) { - if (!this->resource_directory) return {}; - return ResourceDirectory::rd_resources_to_string_list_filtered(filters); -} - int CoapServer::run() { while (!this->get_quit()) { coap_io_process(this->context, 250); @@ -390,3 +212,20 @@ int CoapServer::stop_server() { server_thread.join(); return 0; } + +const std::string &CoapServer::get_my_ip() const { + return my_ip; +} + +const std::string &CoapServer::get_my_port() const { + return my_port; +} + +std::string CoapServer::get_resources_in_linkformat() { + auto res_list = resources->get_all(); + return resource_list_to_string(res_list); +} + +coap_context_t *CoapServer::getContext() const { + return context; +} diff --git a/linux/communication/src/EddieEndpoint.cpp b/linux/communication/src/EddieEndpoint.cpp index edf6bca..cb963e8 100644 --- a/linux/communication/src/EddieEndpoint.cpp +++ b/linux/communication/src/EddieEndpoint.cpp @@ -6,8 +6,11 @@ */ #include "EddieEndpoint.h" +#define DEFAULT_LT 90000 #define NOW std::chrono::system_clock::now() +static ResourceDirectory *resource_directory = nullptr; + CoapClient* EddieEndpoint::get_client(){ return this->server ? this->server->get_client() : nullptr; } @@ -18,55 +21,76 @@ CoapServer* EddieEndpoint::get_server() { EddieEndpoint::EddieEndpoint(const std::string& port, const std::string& ip) { server = new CoapServer(ip.empty() ? get_local_node_ip().c_str() : ip.c_str(), - port.c_str(), - 0); + port.c_str()); + + auto now = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + std::ostringstream oss; + oss << now; + ep = oss.str(); + d = ep; } EddieEndpoint::~EddieEndpoint() { + unpublish_resources(); + delete resource_directory; + stop_server(); delete server; - coap_cleanup(); } int EddieEndpoint::discover_rd() { - int r = get_server()->discover_rd(); - if (r != 0) get_server()->init_resource_dir_local(); - return 0; -} + LOG_DBG("Discovering resource directory"); -std::vector EddieEndpoint::get_resources_from_rd() { - if (get_server() == nullptr) { - coap_log(LOG_EMERG, "[CoapNode::discover]: server is null\n"); - exit(EXIT_FAILURE); - } + request_t request { + COAP_IP6_MULTICAST_SITE_LOCAL, + "5683", + GET, + ".well-known/core", + "rt=core.rd", + nullptr, + 0, + false, + 40 + }; - std::map empty; + message_t response = get_client()->send_message_and_wait_response(request); - // this node is rd, get the info directly - if (get_server()->is_rd()) { - auto list = get_server()->rd_resources_to_string_list_filtered(empty); - std::string to_return; + std::vector parsed = parse_link_format(response.data); - for (const auto &res: list) { - to_return += res + ","; - } + if (parsed.empty()) return -1; - if (to_return.back() == ',') to_return.pop_back(); + std::string rd_uri = "coap://" + response.src_ip; + coap_uri_t parsed_rd_uri; + int r = coap_split_uri(reinterpret_cast(rd_uri.c_str()), + rd_uri.length(), + &parsed_rd_uri); - return parse_link_format(to_return); + if (r < 0) { + LOG_ERR("Error parsing src address"); + return -1; } - std::string rd_ip = get_server()->get_rd_ip(); - std::string rd_port = get_server()->get_rd_port(); + resource_directory_ip = + std::string(reinterpret_cast(parsed_rd_uri.host.s), parsed_rd_uri.host.length); + resource_directory_port = + std::to_string(parsed_rd_uri.port); + + LOG_DBG("Found resource directory: ip=%s port=%s", + this->resource_directory_ip.c_str(), this->resource_directory_port.c_str()); - if (rd_ip.empty() || rd_port.empty()) { - LOG_ERR("Could not found resource directory"); + return 0; +} + +std::vector EddieEndpoint::get_resources_from_rd() { + if (resource_directory_ip.empty() || resource_directory_port.empty()) { + LOG_ERR("unknown resource directory address, please discover it first or initialize one"); return {}; } request_t request{ - rd_ip.c_str(), - rd_port.c_str(), + resource_directory_ip.c_str(), + resource_directory_port.c_str(), GET, "rd-lookup/res", nullptr, @@ -81,8 +105,6 @@ std::vector EddieEndpoint::get_resources_from_rd() { LOG_ERR("Error getting resources from rd: status_code=%d, content=%s", response.status_code, response.data.c_str()); return {}; } - - LOG_DBG("Discovered resources: %s", response.data.c_str()); return parse_link_format(response.data); } @@ -106,5 +128,87 @@ int EddieEndpoint::stop_server() { int EddieEndpoint::publish_resources() { LOG_DBG("Publishing resources"); - return get_server()->publish_resources(); -} \ No newline at end of file + + if (resource_directory_ip.empty() || resource_directory_port.empty()) { + LOG_ERR("unknown resource directory address, please discover it first or initialize one"); + return -1; + } + + std::string base_address; + std::string my_ip = get_server()->get_my_ip(); + std::string my_port = get_server()->get_my_port(); + if (is_ipv6_address(my_ip)) + base_address = "coap://[" + my_ip + "]:" + my_port; + else if (is_ipv4_address(my_ip)) + base_address = "coap://" + my_ip + ":" + my_port; + else { + LOG_ERR("Invalid ip address"); + } + + std::string data = CoapServer::get_resources_in_linkformat(); + + if (data.empty()) { + LOG_DBG("[CoapServer::publish_resources]: unable to get resources in link format"); + return -1; + } + + std::string query = "ep=" + ep + "&d=" + d + "<=" + std::to_string(DEFAULT_LT); + if (!base_address.empty()) query += + "&base=" + base_address; + + request_t request { + resource_directory_ip.c_str(), + resource_directory_port.c_str(), + POST, + "rd", + query.c_str(), + reinterpret_cast(data.c_str()), + data.length(), + true, + 40 + }; + + message_t response = get_client()->send_message_and_wait_response(request); + if (!response.location_path.empty()) { + this->rd_endpoint = "rd/" + response.location_path; + } + else { + LOG_ERR("Location path option not found in response"); + return -1; + } + + return 0; +} + +int EddieEndpoint::unpublish_resources() { + if (rd_endpoint.empty()) { + LOG_ERR("rd_endpoint is empty, nothing to unpublish"); + return -1; + } + + request_t request { + resource_directory_ip.c_str(), + resource_directory_port.c_str(), + DELETE, + this->rd_endpoint.c_str(), + nullptr, + nullptr, + 0, + true, + 40 + }; + message_t response = get_client()->send_message_and_wait_response(request); + if (response.status_code != DELETED) return -1; + + return 0; +} + +void EddieEndpoint::init_resource_dir_local() { + LOG_DBG("Initializing local resource directory"); + if (resource_directory) { + LOG_ERR("local resource directory already initialized"); + return; + } + resource_directory = new ResourceDirectory(get_server()->get_my_ip(), get_server()->getContext()); + resource_directory_ip = "::1"; + resource_directory_port = get_server()->get_my_port(); +} diff --git a/linux/communication/src/ResourceDirectory.cpp b/linux/communication/src/ResourceDirectory.cpp index e95302a..d2857c9 100644 --- a/linux/communication/src/ResourceDirectory.cpp +++ b/linux/communication/src/ResourceDirectory.cpp @@ -748,19 +748,3 @@ int ResourceDirectory::run() { return 0; } - -int ResourceDirectory::add_endpoint( - const std::string& ep_d_key, - const std::unordered_map ¶ms, - const std::string &data -) { - std::string ep_name = ResourceDirectory::add_endpoint_to_rd(ep_d_key, this->context, params, data); - return ep_name.empty() ? -1 : 0; -} - -int ResourceDirectory::remove_endpoint(const std::string& rd_endpoint, const std::string& ep, const std::string& d) { - rd_endpoints->erase(rd_endpoint); - rd_endpoints_by_ep_d->erase(ep + "@" + d); - - return 0; -} \ No newline at end of file diff --git a/linux/examples/eddie_endpoint.cpp b/linux/examples/eddie_endpoint.cpp index cdd8551..9c00062 100644 --- a/linux/examples/eddie_endpoint.cpp +++ b/linux/examples/eddie_endpoint.cpp @@ -8,6 +8,16 @@ #include "eddie.h" #include "argparse.hpp" +#include +#include +#include + +volatile sig_atomic_t stop; + +void inthand(int signum) { + stop = 1; +} + class EddieLamp : public EddieResource { private: const char * const core_path[2] = { "linux-lamp", nullptr }; @@ -75,6 +85,7 @@ public: int main(int argc, char *argv[]) { + signal(SIGINT, inthand); argparse::ArgumentParser program("eddie-endpoint"); program.add_argument("--ip", "-a") @@ -107,8 +118,8 @@ int main(int argc, char *argv[]) coap_set_log_level(LOG_DEBUG); EddieEndpoint node = EddieEndpoint(std::to_string(port_number), ip); - - node.discover_rd(); + if (node.discover_rd()) node.init_resource_dir_local(); + node.start_server(); if (program["--exampleres"] == true) { EddieLamp lamp_resource; @@ -118,9 +129,12 @@ int main(int argc, char *argv[]) node.publish_resources(); } - node.get_resources_from_rd(); - node.start_server(true); - node.stop_server(); + std::vector discovered_resources = node.get_resources_from_rd(); + for (const Link& link: discovered_resources) { + LOG_DBG("Discovered resource: host=%s, port=%s, path=%s", link.host.c_str(), link.port.c_str(), link.path.c_str()); + } + + while (!stop) std::this_thread::sleep_for(std::chrono::seconds(1)); return 0; } diff --git a/linux/tests/communication_tests.cpp b/linux/tests/communication_tests.cpp index 8c97e62..5c5b51a 100644 --- a/linux/tests/communication_tests.cpp +++ b/linux/tests/communication_tests.cpp @@ -102,25 +102,19 @@ TEST(Communication, Client_Requests_And_Response) { EXPECT_EQ(response.data, ";ct=40;rt=\"core.rd-lookup-ep\""); } -TEST(Communication, Server_Init_No_Rd) { +TEST(Communication, Server_Init) { /* Resource dir disabled */ - CoapServer server = CoapServer("0.0.0.0", "5683", 0); + CoapServer server = CoapServer("0.0.0.0", "5683"); } -TEST(Communication, Server_Init_With_Rd) { - /* Resource dir enabled */ - CoapServer server = CoapServer("0.0.0.0", "5683", 1); -} - -TEST(Communication, Server_Resource) { - CoapServer server = CoapServer("0.0.0.0", "5683", 1); - - EddieLamp lamp_resource; - EXPECT_EQ(server.add_resource(&lamp_resource), 0); +TEST(Communication, Endpoint_Init) { + EddieEndpoint endpoint("5684"); } -TEST(Communication, Endpoint_Init) { +TEST(Communication, Add_Resource) { EddieEndpoint endpoint("5684"); + EddieLamp lamp_resource; + EXPECT_EQ(endpoint.add_resource(&lamp_resource), 0); } TEST(Communication, Rd_Discovery) { diff --git a/linux/virtualization/src/VirtualizationReceiver.cpp b/linux/virtualization/src/VirtualizationReceiver.cpp index 6b3a508..007cc59 100644 --- a/linux/virtualization/src/VirtualizationReceiver.cpp +++ b/linux/virtualization/src/VirtualizationReceiver.cpp @@ -200,7 +200,8 @@ void VirtualizationReceiver::on_name_lost(GDBusConnection *connection, const gch VirtualizationReceiver::VirtualizationReceiver(const std::string& ip, const std::string& port) { eddie_endpoint = new EddieEndpoint(port, ip); - eddie_endpoint->discover_rd(); + if (eddie_endpoint->discover_rd()) + eddie_endpoint->init_resource_dir_local(); } void VirtualizationReceiver::update_resources() { -- GitLab