/* * Copyright (C) 2014 Pavel Kirienko */ #pragma once #include #include #include #include #include #include namespace uavcan { struct UAVCAN_EXPORT NetworkCompatibilityCheckResult { NodeID conflicting_node; uint8_t num_failed_nodes; NetworkCompatibilityCheckResult() : num_failed_nodes(0) { } bool isOk() const { return !conflicting_node.isValid(); } }; /** * This class does not issue GlobalDiscoveryRequest, assuming that it was done already by the caller. * Instantiated object can execute() only once. Objects of this class are intended for stack allocation. */ class UAVCAN_EXPORT NetworkCompatibilityChecker : Noncopyable { typedef BitSet NodeIDMask; typedef MethodBinder&)> NodeStatusCallback; typedef MethodBinder&)> CATSResponseCallback; Subscriber ns_sub_; ServiceClient cats_cln_; NodeIDMask nid_mask_present_; NodeIDMask nid_mask_checked_; NetworkCompatibilityCheckResult result_; DataTypeKind checking_dtkind_; bool last_cats_request_ok_; INode& getNode() { return ns_sub_.getNode(); } const INode& getNode() const { return ns_sub_.getNode(); } MonotonicDuration getNetworkDiscoveryDelay() const; NodeID findNextUncheckedNode(); int waitForCATSResponse(); void handleNodeStatus(const ReceivedDataStructure& msg); void handleCATSResponse(ServiceCallResult& resp); int checkOneNodeOneDataTypeKind(NodeID nid, DataTypeKind kind); int checkOneNode(NodeID nid); int checkNodes(); public: explicit NetworkCompatibilityChecker(INode& node) : ns_sub_(node) , cats_cln_(node) , checking_dtkind_(DataTypeKindService) , last_cats_request_ok_(false) { } int execute(); const NetworkCompatibilityCheckResult& getResult() const { return result_; } static int publishGlobalDiscoveryRequest(INode& node); }; }