Node ID selection logic extracted into a class

This commit is contained in:
Pavel Kirienko
2015-05-09 16:16:43 +03:00
parent 696d97880d
commit 0f10d85f7e
2 changed files with 75 additions and 31 deletions
@@ -12,6 +12,7 @@
#include <uavcan/protocol/dynamic_node_id_server/distributed/event.hpp>
#include <uavcan/protocol/dynamic_node_id_server/distributed/raft_core.hpp>
#include <uavcan/protocol/dynamic_node_id_server/allocation_request_manager.hpp>
#include <uavcan/protocol/dynamic_node_id_server/node_id_selector.hpp>
namespace uavcan
{
@@ -69,39 +70,10 @@ class Server : private IAllocationRequestHandler
return raft_core_.traverseLogFromEndUntil(NodeIDLogPredicate(node_id));
}
NodeID findFreeNodeID(const NodeID preferred_node_id) const
{
uint8_t candidate = preferred_node_id.isUnicast() ? preferred_node_id.get() : NodeID::Max;
// Up
while (candidate <= NodeID::Max)
{
if (!isNodeIDTaken(candidate))
{
return candidate;
}
candidate++;
}
candidate = preferred_node_id.isUnicast() ? preferred_node_id.get() : NodeID::Max;
candidate--; // This has been tested already
// Down
while (candidate > 0)
{
if (!isNodeIDTaken(candidate))
{
return candidate;
}
candidate--;
}
return NodeID();
}
void allocateNewNode(const UniqueID& unique_id, const NodeID preferred_node_id)
{
const NodeID allocated_node_id = findFreeNodeID(preferred_node_id);
const NodeID allocated_node_id =
NodeIDSelector<Server>(this, &Server::isNodeIDTaken).findFreeNodeID(preferred_node_id);
if (!allocated_node_id.isUnicast())
{
UAVCAN_TRACE("DynamicNodeIDServer", "Request ignored - no free node ID left");
@@ -0,0 +1,72 @@
/*
* Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
*/
#ifndef UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_NODE_ID_SELECTOR_HPP_INCLUDED
#define UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_NODE_ID_SELECTOR_HPP_INCLUDED
#include <uavcan/build_config.hpp>
#include <cassert>
namespace uavcan
{
namespace dynamic_node_id_server
{
/**
* Node ID allocation logic
*/
template <typename Owner>
class NodeIDSelector
{
typedef bool (Owner::*IsNodeIDTakenMethod)(const NodeID node_id) const;
const Owner* const owner_;
const IsNodeIDTakenMethod is_node_id_taken_;
public:
NodeIDSelector(const Owner* owner, IsNodeIDTakenMethod is_node_id_taken)
: owner_(owner)
, is_node_id_taken_(is_node_id_taken)
{
UAVCAN_ASSERT(owner_ != NULL);
UAVCAN_ASSERT(is_node_id_taken_ != NULL);
}
/**
* Reutrns a default-constructed (invalid) node ID if a free one could not be found.
*/
NodeID findFreeNodeID(const NodeID preferred_node_id) const
{
uint8_t candidate = preferred_node_id.isUnicast() ? preferred_node_id.get() : NodeID::Max;
// Up
while (candidate <= NodeID::Max)
{
if (!(owner_->*is_node_id_taken_)(candidate))
{
return candidate;
}
candidate++;
}
candidate = preferred_node_id.isUnicast() ? preferred_node_id.get() : NodeID::Max;
candidate--; // This has been tested already
// Down
while (candidate > 0)
{
if (!(owner_->*is_node_id_taken_)(candidate))
{
return candidate;
}
candidate--;
}
return NodeID();
}
};
}
}
#endif // Include guard