diff --git a/libuavcan/include/uavcan/protocol/node_info_retriever.hpp b/libuavcan/include/uavcan/protocol/node_info_retriever.hpp index 017102fa40..00458efbea 100644 --- a/libuavcan/include/uavcan/protocol/node_info_retriever.hpp +++ b/libuavcan/include/uavcan/protocol/node_info_retriever.hpp @@ -365,6 +365,22 @@ public: return 0; } + /** + * This method forces the class to re-request uavcan.protocol.GetNodeInfo from all nodes as if they + * have just appeared in the network. + */ + void invalidateAll() + { + NodeStatusMonitor::forgetAllNodes(); + get_node_info_client_.cancelAllCalls(); + + for (unsigned i = 0; i < (sizeof(entries_) / sizeof(entries_[0])); i++) + { + entries_[i] = Entry(); + } + // It is not necessary to reset the last picked node index + } + /** * Adds one listener. Does nothing if such listener already exists. * May return -ErrMemory if there's no space to add the listener. diff --git a/libuavcan/include/uavcan/protocol/node_status_monitor.hpp b/libuavcan/include/uavcan/protocol/node_status_monitor.hpp index 86a1348b31..0e5c80aa68 100644 --- a/libuavcan/include/uavcan/protocol/node_status_monitor.hpp +++ b/libuavcan/include/uavcan/protocol/node_status_monitor.hpp @@ -195,6 +195,17 @@ public: } } + /** + * Make all nodes unknown. + */ + void forgetAllNodes() + { + for (unsigned i = 0; i < (sizeof(entries_) / sizeof(entries_[0])); i++) + { + entries_[i] = Entry(); + } + } + /** * Returns status of a given node. * Unknown nodes are considered offline. diff --git a/libuavcan/test/protocol/node_info_retriever.cpp b/libuavcan/test/protocol/node_info_retriever.cpp index 88fc4aace8..f5bbb25a7e 100644 --- a/libuavcan/test/protocol/node_info_retriever.cpp +++ b/libuavcan/test/protocol/node_info_retriever.cpp @@ -203,6 +203,26 @@ TEST(NodeInfoRetriever, Basic) EXPECT_EQ(13, listener.status_message_cnt); EXPECT_EQ(7, listener.status_change_cnt); // node 2 online/offline + 2 test nodes above online/offline + 1 EXPECT_EQ(3, listener.info_unavailable_cnt); + + /* + * Forcing the class to forget everything + */ + std::cout << "Invalidation" << std::endl; + + retr.invalidateAll(); + + ASSERT_FALSE(retr.isRetrievingInProgress()); + ASSERT_EQ(0, retr.getNumPendingRequests()); + + tid.increment(); + publishNodeStatus(nodes.can_a, uavcan::NodeID(10), 0, 60, tid); + publishNodeStatus(nodes.can_a, uavcan::NodeID(11), 0, 60, tid); + publishNodeStatus(nodes.can_a, uavcan::NodeID(12), 0, 60, tid); + + nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(200)); + + ASSERT_TRUE(retr.isRetrievingInProgress()); + ASSERT_EQ(3, retr.getNumPendingRequests()); }