/* * Copyright (C) 2014 Pavel Kirienko */ #pragma once #include #include #include #include #include #include #include #include #include namespace uavcan { class UAVCAN_EXPORT NodeStatusProvider : private TimerBase { typedef MethodBinder GlobalDiscoveryRequestCallback; typedef MethodBinder GetNodeInfoCallback; const MonotonicTime creation_timestamp_; Publisher node_status_pub_; Subscriber gdr_sub_; ServiceServer gni_srv_; protocol::GetNodeInfo::Response node_info_; INode& getNode() { return node_status_pub_.getNode(); } bool isNodeInfoInitialized() const; int publish(); void publishWithErrorHandling(); virtual void handleTimerEvent(const TimerEvent&); void handleGlobalDiscoveryRequest(const protocol::GlobalDiscoveryRequest&); void handleGetNodeInfoRequest(const protocol::GetNodeInfo::Request&, protocol::GetNodeInfo::Response& rsp); public: explicit NodeStatusProvider(INode& node) : TimerBase(node) , creation_timestamp_(node.getMonotonicTime()) , node_status_pub_(node) , gdr_sub_(node) , gni_srv_(node) { assert(!creation_timestamp_.isZero()); node_info_.uavcan_version.major = UAVCAN_VERSION_MAJOR; node_info_.uavcan_version.minor = UAVCAN_VERSION_MINOR; node_info_.uavcan_version.build = UAVCAN_VERSION_BUILD; node_info_.status.status_code = protocol::NodeStatus::STATUS_INITIALIZING; // NodeStatus TX timeout equals its publication period minus some arbitrary time gap: node_status_pub_.setTxTimeout(MonotonicDuration::fromMSec(protocol::NodeStatus::PUBLICATION_PERIOD_MS - 10)); } int startAndPublish(); int forcePublish() { return publish(); } uint8_t getStatusCode() const { return node_info_.status.status_code; } void setStatusCode(uint8_t code); void setStatusOk() { setStatusCode(protocol::NodeStatus::STATUS_OK); } void setStatusInitializing() { setStatusCode(protocol::NodeStatus::STATUS_INITIALIZING); } void setStatusWarning() { setStatusCode(protocol::NodeStatus::STATUS_WARNING); } void setStatusCritical() { setStatusCode(protocol::NodeStatus::STATUS_CRITICAL); } void setStatusOffline() { setStatusCode(protocol::NodeStatus::STATUS_OFFLINE); } const typename protocol::GetNodeInfo::Response::FieldTypes::name& getName() const { return node_info_.name; } void setName(const char* name); const protocol::SoftwareVersion& getSoftwareVersion() const { return node_info_.software_version; } const protocol::HardwareVersion& getHardwareVersion() const { return node_info_.hardware_version; } void setSoftwareVersion(const protocol::SoftwareVersion& version); void setHardwareVersion(const protocol::HardwareVersion& version); }; }