Go to the documentation of this file.
5 #ifndef UAVCAN_PROTOCOL_NODE_INFO_RETRIEVER_HPP_INCLUDED
6 #define UAVCAN_PROTOCOL_NODE_INFO_RETRIEVER_HPP_INCLUDED
14 #include <uavcan/protocol/GetNodeInfo.hpp>
30 virtual void handleNodeInfoRetrieved(
NodeID node_id,
const protocol::GetNodeInfo::Response& node_info) = 0;
36 virtual void handleNodeInfoUnavailable(
NodeID node_id) = 0;
95 enum { MaxNumRequestAttempts = 254 };
96 enum { UnlimitedRequestAttempts = 0 };
112 , num_attempts_made(0)
113 , request_needed(false)
114 , updated_since_last_attempt(false)
128 : node_id(arg_node_id)
129 , node_info(arg_node_info)
140 template <
typename Event>
154 (key->*method)(event);
159 enum { DefaultNumRequestAttempts = 16 };
160 enum { DefaultTimerIntervalMSec = 40 };
187 return entries_[node_id.
get() - 1];
195 UAVCAN_TRACE(
"NodeInfoRetriever",
"Timer started, interval %s sec", request_interval_.
toString().c_str());
201 out_at_least_one_request_needed =
false;
203 for (
unsigned iter_cnt_ = 0; iter_cnt_ < (
sizeof(entries_) /
sizeof(entries_[0])); iter_cnt_++)
208 last_picked_node_ = 1;
213 const Entry& entry = getEntry(last_picked_node_);
217 out_at_least_one_request_needed =
true;
222 UAVCAN_TRACE(
"NodeInfoRetriever",
"Next node to query: %d",
int(last_picked_node_));
223 return NodeID(last_picked_node_);
233 bool at_least_one_request_needed =
false;
234 const NodeID next = pickNextNodeToQuery(at_least_one_request_needed);
239 getEntry(next).updated_since_last_attempt =
false;
240 const int res = get_node_info_client_.
call(next, protocol::GetNodeInfo::Request());
243 get_node_info_client_.
getNode().registerInternalFailure(
"NodeInfoRetriever GetNodeInfo call");
248 if (!at_least_one_request_needed)
258 const bool was_offline = !
event.was_known ||
259 (
event.old_status.mode == protocol::NodeStatus::MODE_OFFLINE);
261 const bool offline_now =
event.status.mode == protocol::NodeStatus::MODE_OFFLINE;
263 if (was_offline || offline_now)
270 UAVCAN_TRACE(
"NodeInfoRetriever",
"Offline status change: node ID %d, request needed: %d",
275 startTimerIfNotRunning();
292 startTimerIfNotRunning();
318 if (num_attempts_ != UnlimitedRequestAttempts)
335 , listeners_(
node.getAllocator())
336 , get_node_info_client_(
node)
338 , last_picked_node_(1)
339 , num_attempts_(DefaultNumRequestAttempts)
355 res = get_node_info_client_.
init(priority);
375 for (
unsigned i = 0; i < (
sizeof(entries_) /
sizeof(entries_[0])); i++)
377 entries_[i] =
Entry();
390 removeListener(listener);
395 return -ErrInvalidParam;
425 num_attempts_ =
min(
static_cast<uint8_t>(MaxNumRequestAttempts), num);
437 request_interval_ = interval;
458 return static_cast<uint8_t>(num);
464 #endif // Include guard
ServiceClient< protocol::GetNodeInfo, GetNodeInfoResponseCallback > get_node_info_client_
MonotonicDuration request_interval_
virtual void handleNodeStatusMessage(const ReceivedDataStructure< protocol::NodeStatus > &msg)
void removeListener(INodeInfoListener *listener)
NodeID pickNextNodeToQuery(bool &out_at_least_one_request_needed) const
uint8_t getNumRequestAttempts() const
int start(const TransferPriority priority=TransferPriority::OneHigherThanLowest)
bool request_needed
Always false for unknown nodes.
bool updated_since_last_attempt
Always false for unknown nodes.
ServiceCallID getCallID() const
void setNumRequestAttempts(const uint8_t num)
const protocol::GetNodeInfo::Response & node_info
const Entry & getEntry(NodeID node_id) const
virtual void handleNodeStatusChange(const NodeStatusMonitor::NodeStatusChangeEvent &event)
#define UAVCAN_TRACE(...)
struct UAVCAN_EXPORT StaticAssert
MonotonicDuration getRequestInterval() const
void startPeriodic(MonotonicDuration period)
bool operator()(INodeInfoListener *key)
virtual void handleNodeStatusMessage(const ReceivedDataStructure< protocol::NodeStatus > &msg)
virtual ~INodeInfoListener()
virtual void handleTimerEvent(const TimerEvent &)
void removeAll(const T &ref)
static const TransferPriority OneHigherThanLowest
bool isRetrievingInProgress() const
GenericHandlerCaller(void(INodeInfoListener::*arg_method)(Event), Event arg_event)
virtual void handleNodeStatusChange(const NodeStatusChangeEvent &event)
bool operator()(INodeInfoListener *key)
virtual void handleNodeInfoRetrieved(NodeID node_id, const protocol::GetNodeInfo::Response &node_info)=0
const UAVCAN_EXPORT T & min(const T &a, const T &b)
Multiset< INodeInfoListener * > listeners_
const ResponseFieldType & getResponse() const
bool isSuccessful() const
NodeInfoRetriever(INode &node)
bool hasPendingCallToServer(NodeID server_node_id) const
void toString(char buf[StringBufSize]) const
Prints time in seconds with microsecond resolution.
unsigned getNumPendingCalls() const
uint8_t getNumPendingRequests() const
void forEach(Operator oper)
void setRequestInterval(const MonotonicDuration interval)
virtual void handleNodeInfoUnavailable(NodeID node_id)=0
uint8_t num_attempts_made
void setCallback(const Callback &cb)
UAVCAN_EXPORT void handleFatalError(const char *msg)
int addListener(INodeInfoListener *listener)
void handleGetNodeInfoResponse(const ServiceCallResult< protocol::GetNodeInfo > &result)
uint8_t last_picked_node_
Entry & getEntry(NodeID node_id)
NodeInfoRetrievedHandlerCaller(NodeID arg_node_id, const protocol::GetNodeInfo::Response &arg_node_info)
NodeID getSrcNodeID() const
int call(NodeID server_node_id, const RequestType &request)
unsigned getNumListeners() const
void startTimerIfNotRunning()