New dynamic node ID allocation client

This commit is contained in:
Pavel Kirienko
2015-04-26 07:42:26 +03:00
parent edf556a9f2
commit abea24eeec
5 changed files with 323 additions and 342 deletions
@@ -10,7 +10,7 @@
#include <uavcan/node/timer.hpp>
#include <uavcan/util/method_binder.hpp>
#include <uavcan/build_config.hpp>
#include <uavcan/protocol/DynamicNodeIDAllocation.hpp>
#include <uavcan/protocol/dynamic_node_id/Allocation.hpp>
#include <uavcan/protocol/HardwareVersion.hpp>
namespace uavcan
@@ -18,9 +18,8 @@ namespace uavcan
/**
* This class implements client-side logic of dynamic node ID allocation procedure.
*
* Once started, the object will be publishing dynamic node ID allocation requests at the maximum frequency allowed
* by the specification, until a Node ID is granted by the allocator. Note that if there are multiple responses,
* Node ID from the first response will be taken, and all subsequent responses will be ignored.
* Once started, the object will be publishing dynamic node ID allocation requests at the default frequency defined
* by the specification, until a Node ID is granted by the allocator.
*
* If the local node is equipped with redundant CAN interfaces, all of them will be used for publishing requests
* and listening for responses.
@@ -31,73 +30,60 @@ class DynamicNodeIDAllocationClient : private TimerBase
{
typedef MethodBinder<DynamicNodeIDAllocationClient*,
void (DynamicNodeIDAllocationClient::*)
(const ReceivedDataStructure<protocol::DynamicNodeIDAllocation>&)>
DynamicNodeIDAllocationCallback;
(const ReceivedDataStructure<protocol::dynamic_node_id::Allocation>&)>
AllocationCallback;
Publisher<protocol::DynamicNodeIDAllocation> dnida_pub_;
Subscriber<protocol::DynamicNodeIDAllocation, DynamicNodeIDAllocationCallback> dnida_sub_;
Publisher<protocol::dynamic_node_id::Allocation> dnida_pub_;
Subscriber<protocol::dynamic_node_id::Allocation, AllocationCallback> dnida_sub_;
uint64_t short_unique_id_;
uint8_t unique_id_[protocol::HardwareVersion::FieldTypes::unique_id::MaxSize];
NodeID preferred_node_id_;
NodeID allocated_node_id_;
NodeID allocator_node_id_;
void terminate();
virtual void handleTimerEvent(const TimerEvent&);
void handleDynamicNodeIDAllocation(const ReceivedDataStructure<protocol::DynamicNodeIDAllocation>& msg);
int startImpl();
void handleAllocation(const ReceivedDataStructure<protocol::dynamic_node_id::Allocation>& msg);
public:
DynamicNodeIDAllocationClient(INode& node)
: TimerBase(node)
, dnida_pub_(node)
, dnida_sub_(node)
, short_unique_id_(0)
{ }
/**
* Starts the client with a pre-computed short unique Node ID.
* @param short_unique_node_id The unique ID, only lower 57 bits of it will be used.
* @param preferred_node_id Node ID that the application would like to take; default is any.
* @return Zero on success
* Negative error code on failure
* -ErrLogic if the node is not in passive mode (i.e. allocation is meaningless)
* -ErrInvalidParam if the supplied short unique ID is invalid
* @param hardware_version Hardware version information, where unique_id must be set correctly.
* @param preferred_node_id Node ID that the application would like to take; set to broadcast (zero) if
* the application doesn't have any preference (this is default).
* @return Zero on success
* Negative error code on failure
* -ErrLogic if 1. the node is not in passive mode or 2. the client is already started
*/
int start(uint64_t short_unique_node_id, NodeID preferred_node_id = NodeID::Broadcast);
int start(const protocol::HardwareVersion& hardware_version, const NodeID preferred_node_id = NodeID::Broadcast);
/**
* This overload computes a short unique Node ID using data from uavcan.protocol.HardwareVersion structure.
* @param hardware_version Hardware version information, where unique_id must be set correctly.
* @param preferred_node_id Node ID that the application would like to take; default is any.
* @return Refer to the overload for details
* -ErrInvalidParam if short unique ID could not be computed
* Use this method to determine when allocation is complete.
*/
int start(const protocol::HardwareVersion& hardware_version, NodeID preferred_node_id = NodeID::Broadcast);
bool isAllocationComplete() const { return getAllocatedNodeID().isUnicast(); }
/**
* This method allows to retrieve the value that was allocated to the local node.
* If no value was allocated yet, the returned Node ID will be invalid (non-unicast).
* Tip: use getAllocatedNodeID().isUnicast() to check if allocation is complete.
* @return If allocation is complete, a valid unicast Node ID will be returned.
* If allocation is not complete yet, an invalid Node ID will be returned.
* This method allows to retrieve the node ID that was allocated to the local node.
* If no node ID was allocated yet, the returned node ID will be invalid (non-unicast).
* @return If allocation is complete, a valid unicast node ID will be returned.
* If allocation is not complete yet, a non-unicast node ID will be returned.
*/
NodeID getAllocatedNodeID() const { return allocated_node_id_; }
/**
* This method allows to retrieve node ID of the allocator that granted our Node ID.
* If no Node ID was allocated yet, the returned Node ID will be invalid (non-unicast).
* @return If allocation is complete, a valid unicast Node ID will be returned.
* If allocation is not complete yet, an invalid Node ID will be returned.
* If no node ID was allocated yet, the returned node ID will be invalid (non-unicast).
* @return If allocation is complete, a valid unicast node ID will be returned.
* If allocation is not complete yet, an non-unicast node ID will be returned.
*/
NodeID getAllocatorNodeID() const { return allocator_node_id_; }
/**
* This utility method simply returns the short node ID used in the allocation request messages.
* Returned value will be zero if the short unique node ID has not been initialized yet.
*/
uint64_t getShortUniqueNodeID() const { return short_unique_id_; }
};
}