5 #ifndef UAVCAN_PROTOCOL_NODE_STATUS_MONITOR_HPP_INCLUDED 6 #define UAVCAN_PROTOCOL_NODE_STATUS_MONITOR_HPP_INCLUDED 12 #include <uavcan/protocol/NodeStatus.hpp> 36 StaticAssert<protocol::NodeStatus::FieldTypes::health::BitLen == 2>::check();
37 StaticAssert<protocol::NodeStatus::FieldTypes::mode::BitLen == 3>::check();
38 StaticAssert<protocol::NodeStatus::FieldTypes::sub_mode::BitLen == 3>::check();
44 return ( this->health == rhs.
health 45 && this->mode == rhs.
mode 54 (void)
snprintf(buf,
sizeof(buf),
"health=%d mode=%d sub_mode=%d",
int(health),
int(mode),
int(sub_mode));
55 return std::string(buf);
73 enum { TimerPeriodMs100 = 2 };
90 time_since_last_update_ms100(-1)
102 return entries_[node_id.
get() - 1];
107 Entry& entry = getEntry(node_id);
112 event.old_status = entry.
status;
113 event.status = new_entry_value.
status;
116 UAVCAN_TRACE(
"NodeStatusMonitor",
"Node %i [%s] status change: [%s] --> [%s]",
int(node_id.
get()),
118 event.old_status.toString().c_str(),
event.status.toString().c_str());
120 handleNodeStatusChange(event);
122 entry = new_entry_value;
129 new_entry.
status.
health = msg.health & ((1 << protocol::NodeStatus::FieldTypes::health::BitLen) - 1);
130 new_entry.
status.
mode = msg.mode & ((1 << protocol::NodeStatus::FieldTypes::mode::BitLen) - 1);
131 new_entry.
status.
sub_mode = msg.sub_mode & ((1 << protocol::NodeStatus::FieldTypes::sub_mode::BitLen) - 1);
135 handleNodeStatusMessage(msg);
140 const int OfflineTimeoutMs100 = protocol::NodeStatus::OFFLINE_TIMEOUT_MS / 100;
144 Entry& entry = getEntry(i);
146 entry.
status.
mode != protocol::NodeStatus::MODE_OFFLINE)
153 Entry new_entry_value = entry;
155 new_entry_value.
status.
mode = protocol::NodeStatus::MODE_OFFLINE;
156 changeNodeStatus(i, new_entry_value);
214 Entry& entry = getEntry(node_id);
228 for (
unsigned i = 0; i < (
sizeof(entries_) /
sizeof(entries_[0])); i++)
230 entries_[i] =
Entry();
247 const Entry& entry = getEntry(node_id);
269 return getEntry(node_id).time_since_last_update_ms100 >= 0;
279 NodeID nid_with_worst_health;
280 uint8_t worst_health = protocol::NodeStatus::HEALTH_OK;
286 const Entry& entry = getEntry(nid);
287 if (entry.time_since_last_update_ms100 >= 0)
289 if (entry.status.health > worst_health || !nid_with_worst_health.
isValid())
291 nid_with_worst_health = nid;
292 worst_health = entry.status.health;
297 return nid_with_worst_health;
305 template <
typename Operator>
312 const Entry& entry = getEntry(nid);
313 if (entry.time_since_last_update_ms100 >= 0)
315 op(nid, entry.status);
323 #endif // UAVCAN_PROTOCOL_NODE_STATUS_MONITOR_HPP_INCLUDED
void changeNodeStatus(const NodeID node_id, const Entry new_entry_value)
virtual void handleNodeStatusChange(const NodeStatusChangeEvent &event)
MethodBinder< NodeStatusMonitor *, void(NodeStatusMonitor::*)(const TimerEvent &)> TimerCallback
NodeID getSrcNodeID() const
bool isNodeKnown(NodeID node_id) const
void startPeriodic(MonotonicDuration period)
virtual ~NodeStatusMonitor()
UAVCAN_EXPORT void handleFatalError(const char *msg)
virtual void handleNodeStatusMessage(const ReceivedDataStructure< protocol::NodeStatus > &msg)
void setCallback(const Callback &callback)
#define UAVCAN_TRACE(...)
NodeID findNodeWithWorstHealth() const
static std::string toString(long x)
TimerEventForwarder< TimerCallback > timer_
UAVCAN_EXPORT EnableIf<!IsSameType< R, Array< T, ArrayMode, MaxSize > >::Result, bool >::Type operator==(const R &rhs, const Array< T, ArrayMode, MaxSize > &lhs)
NodeStatus getNodeStatus(NodeID node_id) const
bool operator==(const NodeStatus rhs) const
int start(const Callback &callback)
Subscriber< protocol::NodeStatus, NodeStatusCallback > sub_
void handleNodeStatus(const ReceivedDataStructure< protocol::NodeStatus > &msg)
NodeStatusMonitor(INode &node)
void handleTimerEvent(const TimerEvent &)
Entry & getEntry(NodeID node_id) const
static MonotonicDuration fromMSec(int64_t ms)
void forgetNode(NodeID node_id)
bool operator!=(const NodeStatus rhs) const
void forEachNode(Operator op) const
int snprintf(char *out, std::size_t maxlen, const char *format,...)
int8_t time_since_last_update_ms100