/* * Copyright (C) 2014 Pavel Kirienko */ #pragma once #include #include #include #include #include #include namespace uavcan { struct UAVCAN_EXPORT NodeInitializationResult { NodeID conflicting_node; 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 NodeInitializer : Noncopyable { typedef std::bitset NodeIDMask; typedef MethodBinder&)> NodeStatusCallback; typedef MethodBinder&)> CATSResponseCallback; Subscriber ns_sub_; ServiceClient cats_cln_; NodeIDMask nid_mask_present_; NodeIDMask nid_mask_checked_; NodeInitializationResult 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: NodeInitializer(INode& node) : ns_sub_(node) , cats_cln_(node) , checking_dtkind_(DataTypeKindService) , last_cats_request_ok_(false) { } int execute(); const NodeInitializationResult& getResult() const { return result_; } static int publishGlobalDiscoveryRequest(INode& node); }; }