5 #ifndef UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_ALLOCATION_REQUEST_MANAGER_HPP_INCLUDED 6 #define UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_ALLOCATION_REQUEST_MANAGER_HPP_INCLUDED 16 #include <uavcan/protocol/dynamic_node_id/Allocation.hpp> 20 namespace dynamic_node_id_server
63 enum { InvalidStage = 0 };
69 const uint8_t max_bytes_per_request = Allocation::MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST;
71 if ((msg.unique_id.size() != max_bytes_per_request) &&
72 (msg.unique_id.size() != (msg.unique_id.capacity() - max_bytes_per_request * 2U)) &&
73 (msg.unique_id.size() != msg.unique_id.capacity()))
77 if (msg.first_part_of_unique_id)
81 if (msg.unique_id.size() == Allocation::MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST)
85 if (msg.unique_id.size() < Allocation::MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST)
94 if (current_unique_id_.empty())
98 if (current_unique_id_.size() >= (Allocation::MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST * 2))
102 if (current_unique_id_.size() >= Allocation::MAX_LENGTH_OF_UNIQUE_ID_IN_REQUEST)
112 msg.unique_id = current_unique_id_;
113 UAVCAN_ASSERT(msg.unique_id.size() < msg.unique_id.capacity());
115 UAVCAN_TRACE(
"AllocationRequestManager",
"Intermediate response with %u bytes of unique ID",
116 unsigned(msg.unique_id.size()));
120 const int res = allocation_pub_.
broadcast(msg);
143 UAVCAN_TRACE(
"AllocationRequestManager",
"Stage timeout, reset");
144 current_unique_id_.clear();
151 const uint8_t request_stage = detectRequestStage(msg);
152 if (request_stage == InvalidStage)
158 const uint8_t expected_stage = getExpectedStage();
159 if (expected_stage == InvalidStage)
165 if (request_stage != expected_stage)
171 const uint8_t max_expected_bytes =
172 static_cast<uint8_t>(current_unique_id_.capacity() - current_unique_id_.size());
174 if (msg.unique_id.size() > max_expected_bytes)
183 for (
uint8_t i = 0; i < msg.unique_id.size(); i++)
185 current_unique_id_.push_back(msg.unique_id[i]);
194 if (current_unique_id_.size() == current_unique_id_.capacity())
196 UAVCAN_TRACE(
"AllocationRequestManager",
"Allocation request received; preferred node ID: %d",
200 copy(current_unique_id_.begin(), current_unique_id_.end(), unique_id.begin());
201 current_unique_id_.clear();
205 for (
uint8_t i = 0; i < 8; i++)
207 event_agrument |=
static_cast<uint64_t>(unique_id[i]) << (56U - i * 8U);
218 publishFollowupAllocationResponse();
223 current_unique_id_.clear();
238 , allocation_sub_(node)
239 , allocation_pub_(node)
244 int res = allocation_pub_.
init(priority);
265 msg.unique_id.resize(msg.unique_id.capacity());
266 copy(unique_id.begin(), unique_id.end(), msg.unique_id.begin());
268 msg.node_id = allocated_node_id.
get();
286 #endif // Include guard
IAllocationRequestHandler & handler_
NodeID getSrcNodeID() const
virtual bool canPublishFollowupAllocationResponse() const =0
uint8_t getExpectedStage() const
void handleAllocation(const ReceivedDataStructure< Allocation > &msg)
AllocationRequestManager(INode &node, IEventTracer &tracer, IAllocationRequestHandler &handler)
MonotonicTime last_activity_timestamp_
const MonotonicDuration stage_timeout_
virtual void handleAllocationRequest(const UniqueID &unique_id, NodeID preferred_node_id)=0
virtual void onEvent(TraceCode event_code, int64_t event_argument)=0
void setTxTimeout(MonotonicDuration tx_timeout)
TraceAllocationBadRequest
#define UAVCAN_TRACE(...)
void allowAnonymousTransfers()
TraceAllocationRequestAccepted
Subscriber< Allocation, AllocationCallback > allocation_sub_
static uint8_t detectRequestStage(const Allocation &msg)
UAVCAN_EXPORT OutputIt copy(InputIt first, InputIt last, OutputIt result)
TraceAllocationUnexpectedStage
TraceAllocationExchangeComplete
protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id UniqueID
virtual void registerInternalFailure(const char *msg)=0
void publishFollowupAllocationResponse()
int init(const TransferPriority priority)
bool isAnonymousTransfer() const
MonotonicTime getMonotonicTimestamp() const
virtual ~IAllocationRequestHandler()
int start(const Callback &callback)
int broadcastAllocationResponse(const UniqueID &unique_id, NodeID allocated_node_id)
MonotonicTime last_message_timestamp_
MonotonicTime getTimeOfLastAllocationActivity() const
TraceAllocationFollowupTimeout
Allocation::FieldTypes::unique_id current_unique_id_
static MonotonicDuration fromMSec(int64_t ms)
Publisher< Allocation > allocation_pub_
TraceAllocationFollowupDenied
void trace(TraceCode code, int64_t argument)
MonotonicTime getMonotonicTime() const
int broadcast(const DataType &message)
TraceAllocationFollowupResponse