NetworkCompatibilityChecker will not be executed at each Node<>::start(), there's special method for that - Node<>::checkNetworkCompatibility()

This commit is contained in:
Pavel Kirienko
2014-04-12 22:10:26 +04:00
parent dd5908dad8
commit e476a957a8
6 changed files with 60 additions and 46 deletions
+28 -24
View File
@@ -51,8 +51,6 @@ class UAVCAN_EXPORT Node : public INode
bool started_; bool started_;
int initNetwork(NetworkCompatibilityCheckResult& node_init_result);
protected: protected:
virtual void registerInternalFailure(const char* msg) virtual void registerInternalFailure(const char* msg)
{ {
@@ -99,7 +97,9 @@ public:
bool isStarted() const { return started_; } bool isStarted() const { return started_; }
int start(NetworkCompatibilityCheckResult& node_init_result); int start();
int checkNetworkCompatibility(NetworkCompatibilityCheckResult& result);
/* /*
* Initialization methods * Initialization methods
@@ -173,25 +173,7 @@ public:
template <std::size_t MemPoolSize_, unsigned OutgoingTransferRegistryStaticEntries, template <std::size_t MemPoolSize_, unsigned OutgoingTransferRegistryStaticEntries,
unsigned OutgoingTransferMaxPayloadLen> unsigned OutgoingTransferMaxPayloadLen>
int Node<MemPoolSize_, OutgoingTransferRegistryStaticEntries, OutgoingTransferMaxPayloadLen>:: int Node<MemPoolSize_, OutgoingTransferRegistryStaticEntries, OutgoingTransferMaxPayloadLen>::start()
initNetwork(NetworkCompatibilityCheckResult& node_init_result)
{
int res = NetworkCompatibilityChecker::publishGlobalDiscoveryRequest(*this);
if (res < 0)
{
return res;
}
NetworkCompatibilityChecker initializer(*this);
StaticAssert<(sizeof(initializer) < 1200)>::check();
res = initializer.execute();
node_init_result = initializer.getResult();
return res;
}
template <std::size_t MemPoolSize_, unsigned OutgoingTransferRegistryStaticEntries,
unsigned OutgoingTransferMaxPayloadLen>
int Node<MemPoolSize_, OutgoingTransferRegistryStaticEntries, OutgoingTransferMaxPayloadLen>::
start(NetworkCompatibilityCheckResult& node_init_result)
{ {
if (started_) if (started_)
{ {
@@ -225,12 +207,34 @@ start(NetworkCompatibilityCheckResult& node_init_result)
{ {
goto fail; goto fail;
} }
res = initNetwork(node_init_result); started_ = res >= 0;
started_ = (res >= 0) && node_init_result.isOk();
return res; return res;
fail: fail:
assert(res < 0); assert(res < 0);
return res; return res;
} }
template <std::size_t MemPoolSize_, unsigned OutgoingTransferRegistryStaticEntries,
unsigned OutgoingTransferMaxPayloadLen>
int Node<MemPoolSize_, OutgoingTransferRegistryStaticEntries, OutgoingTransferMaxPayloadLen>::
checkNetworkCompatibility(NetworkCompatibilityCheckResult& result)
{
if (!started_)
{
return -ErrNotInited;
}
int res = NetworkCompatibilityChecker::publishGlobalDiscoveryRequest(*this);
if (res < 0)
{
return res;
}
NetworkCompatibilityChecker checker(*this);
StaticAssert<(sizeof(checker) < 2048)>::check();
res = checker.execute();
result = checker.getResult();
return res;
}
} }
+6 -2
View File
@@ -59,7 +59,9 @@ TEST(Node, Basic)
* Init the second node - network is empty * Init the second node - network is empty
*/ */
uavcan::NetworkCompatibilityCheckResult result; uavcan::NetworkCompatibilityCheckResult result;
ASSERT_LE(0, node2.start(result)); ASSERT_LE(0, node2.start());
ASSERT_LE(0, node2.checkNetworkCompatibility(result));
ASSERT_TRUE(result.isOk());
ASSERT_FALSE(node_status_monitor.findNodeWithWorstStatus().isValid()); ASSERT_FALSE(node_status_monitor.findNodeWithWorstStatus().isValid());
@@ -68,7 +70,9 @@ TEST(Node, Basic)
*/ */
ASSERT_FALSE(node1.isStarted()); ASSERT_FALSE(node1.isStarted());
ASSERT_EQ(-uavcan::ErrNotInited, node1.spin(uavcan::MonotonicDuration::fromMSec(20))); ASSERT_EQ(-uavcan::ErrNotInited, node1.spin(uavcan::MonotonicDuration::fromMSec(20)));
ASSERT_LE(0, node1.start(result)); ASSERT_LE(0, node1.start());
ASSERT_LE(0, node1.checkNetworkCompatibility(result));
ASSERT_TRUE(result.isOk());
ASSERT_TRUE(node1.isStarted()); ASSERT_TRUE(node1.isStarted());
ASSERT_EQ(1, node_status_monitor.findNodeWithWorstStatus().get()); ASSERT_EQ(1, node_status_monitor.findNodeWithWorstStatus().get());
+9 -3
View File
@@ -21,17 +21,23 @@ static uavcan_linux::NodePtr initNode(const std::vector<std::string>& ifaces, ua
node->getLogger().setLevel(uavcan::protocol::debug::LogLevel::DEBUG); node->getLogger().setLevel(uavcan::protocol::debug::LogLevel::DEBUG);
/* /*
* Starting the node. This may take a few seconds. * Starting the node.
*/ */
std::cout << "Starting the node..." << std::endl; std::cout << "Starting the node..." << std::endl;
uavcan::NetworkCompatibilityCheckResult init_result; const int start_res = node->start();
const int start_res = node->start(init_result);
std::cout << "Start returned: " << start_res << std::endl; std::cout << "Start returned: " << start_res << std::endl;
ENFORCE(0 == start_res); ENFORCE(0 == start_res);
/*
* Checking if our node conflicts with other nodes. This may take a few seconds.
*/
uavcan::NetworkCompatibilityCheckResult init_result;
ENFORCE(0 == node->checkNetworkCompatibility(init_result));
if (!init_result.isOk()) if (!init_result.isOk())
{ {
throw std::runtime_error("Network conflict with node " + std::to_string(init_result.conflicting_node.get())); throw std::runtime_error("Network conflict with node " + std::to_string(init_result.conflicting_node.get()));
} }
std::cout << "Node started successfully" << std::endl; std::cout << "Node started successfully" << std::endl;
/* /*
@@ -108,15 +108,7 @@ static uavcan_linux::NodePtr initNode(const std::vector<std::string>& ifaces, ua
auto node = uavcan_linux::makeNode(ifaces); auto node = uavcan_linux::makeNode(ifaces);
node->setNodeID(nid); node->setNodeID(nid);
node->setName(name.c_str()); node->setName(name.c_str());
ENFORCE(0 == node->start()); // This node doesn't check its network compatibility
uavcan::NetworkCompatibilityCheckResult init_result;
const int start_res = node->start(init_result);
ENFORCE(0 == start_res);
if (!init_result.isOk())
{
throw std::runtime_error("Network conflict with node " + std::to_string(init_result.conflicting_node.get()));
}
node->setStatusOk(); node->setStatusOk();
return node; return node;
} }
@@ -17,9 +17,10 @@ static uavcan_linux::NodePtr initNode(const std::vector<std::string>& ifaces, ua
node->setNodeID(nid); node->setNodeID(nid);
node->setName(name.c_str()); node->setName(name.c_str());
ENFORCE(0 == node->start());
uavcan::NetworkCompatibilityCheckResult init_result; uavcan::NetworkCompatibilityCheckResult init_result;
const int start_res = node->start(init_result); ENFORCE(0 == node->checkNetworkCompatibility(init_result));
ENFORCE(0 == start_res);
if (!init_result.isOk()) if (!init_result.isOk())
{ {
throw std::runtime_error("Network conflict with node " + std::to_string(init_result.conflicting_node.get())); throw std::runtime_error("Network conflict with node " + std::to_string(init_result.conflicting_node.get()));
@@ -81,16 +81,23 @@ public:
*/ */
while (true) while (true)
{ {
uavcan::NodeInitializationResult init_result; // Calling start() multiple times is OK - only the first successfull call will be effective
const int uavcan_start_res = node.start(init_result); int res = node.start();
if (uavcan_start_res < 0) uavcan::NetworkCompatibilityCheckResult ncc_result;
if (res >= 0)
{ {
lowsyslog("Node initialization failure: %i, will try agin soon\n", uavcan_start_res); lowsyslog("Checking network compatibility...\n");
res = node.checkNetworkCompatibility(ncc_result);
} }
else if (!init_result.isOk())
if (res < 0)
{ {
lowsyslog("Network conflict with %u, will try again soon\n", init_result.conflicting_node.get()); lowsyslog("Node initialization failure: %i, will try agin soon\n", res);
}
else if (!ncc_result.isOk())
{
lowsyslog("Network conflict with %u, will try again soon\n", ncc_result.conflicting_node.get());
} }
else else
{ {