/** * Invokes storage IO. */ int setVotedFor(NodeID node_id) { if (!node_id.isValid()) { UAVCAN_ASSERT(0); return -ErrInvalidParam; } tracer_.onEvent(TraceRaftVotedForUpdate, node_id.get()); StorageMarshaller io(storage_); uint32_t tmp = node_id.get(); int res = io.setAndGetBack(getVotedForKey(), tmp); if (res < 0) { return res; } if (node_id.get() != tmp) { return -ErrFailure; } voted_for_ = node_id; return 0; }
void handleTimerEvent(const TimerEvent&) { if (get_node_info_client_.hasPendingCalls()) { return; } const NodeID node_id = pickNextNodeToQueryAndCleanupMap(); if (!node_id.isUnicast()) { trace(TraceDiscoveryTimerStop, 0); stop(); return; } if (!handler_.canDiscoverNewNodes()) { return; // Timer must continue to run in order to not stuck when it unlocks } trace(TraceDiscoveryGetNodeInfoRequest, node_id.get()); UAVCAN_TRACE("dynamic_node_id_server::NodeDiscoverer", "Requesting GetNodeInfo from node %d", int(node_id.get())); const int res = get_node_info_client_.call(node_id, protocol::GetNodeInfo::Request()); if (res < 0) { getNode().registerInternalFailure("NodeDiscoverer GetNodeInfo call"); } }
bool operator()(const NodeID node_id, const FirmwareFilePath&) { if (node_id.get() > owner.last_queried_node_id_ && !owner.begin_fw_update_client_.hasPendingCallToServer(node_id)) { output = min(output, node_id.get()); } return false; }
TEST(NodeID, SettingNamespaceUri_And_Index) { uint32_t id = 1; uint32_t ns = 2; NodeID node = NumericNodeID(id, ns); node.SetNamespaceURI("uri"); node.SetServerIndex(3); ASSERT_TRUE(node.HasNamespaceURI()); ASSERT_TRUE(node.HasServerIndex()); }
void initialize(int port) { myport = port; current.__set_ip(get_eth_ip()); current.__set_port(myport); current.__set_id(sha256_ip_port_hex(current.ip, current.port)); NodeID noSet; // the finger table nodes are noSet at the start ftable.assign(256,noSet); predecessor = current; successor = current; ftable[0] = current; }
void findSucc(NodeID& _return, const std::string& key) { NodeID pred; findPred(pred, key); if (pred.id == current.id) { _return = successor; _return.__set_count(pred.count); return; } shared_ptr<DHTNodeClient> client(connectClientAgency(pred.ip, pred.port)); client->getNodeSucc(_return); _return.__set_count(pred.count); }
NodeID calcNodeID (PublicKey const& pk) { ripesha_hasher h; h(pk.data(), pk.size()); auto const digest = static_cast< ripesha_hasher::result_type>(h); static_assert(NodeID::bytes == sizeof(ripesha_hasher::result_type), ""); NodeID result; std::memcpy(result.data(), digest.data(), digest.size()); return result; }
Frame(DataTypeID data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id, uint_fast8_t frame_index, TransferID transfer_id, bool last_frame = false) : transfer_priority_(getDefaultPriorityForTransferType(transfer_type)) , transfer_type_(transfer_type) , data_type_id_(data_type_id) , payload_len_(0) , src_node_id_(src_node_id) , dst_node_id_(dst_node_id) , frame_index_(frame_index) , transfer_id_(transfer_id) , last_frame_(last_frame) { UAVCAN_ASSERT((transfer_type == TransferTypeMessageBroadcast) == dst_node_id.isBroadcast()); UAVCAN_ASSERT(data_type_id.isValidForDataTypeKind(getDataTypeKindForTransferType(transfer_type))); UAVCAN_ASSERT(src_node_id.isUnicast() ? (src_node_id != dst_node_id) : true); UAVCAN_ASSERT(frame_index <= getMaxIndex()); }
/** * Unicast the message to the specified destination Node ID. * Returns negative error code. */ int unicast(const DataType& message, NodeID dst_node_id) { if (!dst_node_id.isUnicast()) { UAVCAN_ASSERT(0); return -ErrInvalidParam; } return BaseType::publish(message, TransferTypeMessageUnicast, dst_node_id); }
void NodeTable::doDiscovery() { m_timers.schedule(c_bucketRefresh.count(), [this](boost::system::error_code const& _ec) { if (_ec) // we can't use m_logger here, because captured this might be already destroyed clog(VerbosityDebug, "discov") << "Discovery timer was probably cancelled: " << _ec.value() << " " << _ec.message(); if (_ec.value() == boost::asio::error::operation_aborted || m_timers.isStopped()) return; LOG(m_logger) << "performing random discovery"; NodeID randNodeId; crypto::Nonce::get().ref().copyTo(randNodeId.ref().cropped(0, h256::size)); crypto::Nonce::get().ref().copyTo(randNodeId.ref().cropped(h256::size, h256::size)); doDiscover(randNodeId, 0, make_shared<set<shared_ptr<NodeEntry>>>()); }); }
NodeID RippleAddress::getNodeID () const { switch (nVersion) { case TOKEN_NONE: Throw<std::runtime_error> ("unset source - getNodeID"); case TOKEN_NODE_PUBLIC: { // Note, we are encoding the left. NodeID node; node.copyFrom(Hash160 (vchData)); return node; } default: Throw<std::runtime_error> ("bad source: " + std::to_string(nVersion)); } return {}; // Silence compiler warning. }
virtual void handleTimerEvent(const TimerEvent&) { if (pending_nodes_.isEmpty()) { TimerBase::stop(); UAVCAN_TRACE("FirmwareUpdateTrigger", "Timer stopped"); return; } const NodeID node_id = pickNextNodeID(); if (!node_id.isUnicast()) { return; } FirmwareFilePath* const path = pending_nodes_.access(node_id); if (path == UAVCAN_NULLPTR) { UAVCAN_ASSERT(0); // pickNextNodeID() returned a node ID that is not present in the map return; } protocol::file::BeginFirmwareUpdate::Request req; req.source_node_id = getNode().getNodeID().get(); if (!common_path_prefix_.empty()) { req.image_file_remote_path.path += common_path_prefix_.c_str(); req.image_file_remote_path.path.push_back(protocol::file::Path::SEPARATOR); } req.image_file_remote_path.path += path->c_str(); UAVCAN_TRACE("FirmwareUpdateTrigger", "Request to %d with path: %s", int(node_id.get()), req.image_file_remote_path.path.c_str()); const int call_res = begin_fw_update_client_.call(node_id, req); if (call_res < 0) { getNode().registerInternalFailure("FirmwareUpdateTrigger call"); } }
OutgoingTransferRegistryKey(DataTypeID data_type_id, TransferType transfer_type, NodeID destination_node_id) : data_type_id_(data_type_id) , transfer_type_(transfer_type) , destination_node_id_(destination_node_id) { UAVCAN_ASSERT((transfer_type == TransferTypeMessageBroadcast) == destination_node_id.isBroadcast()); /* * Service response transfers must use the same Transfer ID as matching service request transfer, * so this registry is not applicable for service response transfers at all. */ UAVCAN_ASSERT(transfer_type != TransferTypeServiceResponse); }
void findPred(NodeID& _return, const std::string& key) { string left = current.id; string middle = key; string right = successor.id; /* bool flag; flag = right > left ? (middle > left && middle <= right) : ((middle > left && middle > right) || (middle < left && middle <= right)); **/ if (keyCompare(current.id, key, successor.id)) { _return = current; _return.__set_count(0); return ; } for(int i = 255; i >= 0; i--) { if (ftable[i].id.empty()) continue; if (keyCompare(current.id, ftable[i].id, key)) { boost::shared_ptr<TSocket> socket(new TSocket(ftable[i].ip.c_str(), ftable[i].port)); boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); boost::shared_ptr<DHTNodeClient> client(new DHTNodeClient(protocol)); transport->open(); try { client->findPred(_return, key); } catch (...) { client = boost::shared_ptr<DHTNodeClient>(); transport->close(); } transport->close(); _return.__set_count(_return.count + 1); return ; } } assert(false); }
int broadcastAllocationResponse(const UniqueID& unique_id, NodeID allocated_node_id) { Allocation msg; msg.unique_id.resize(msg.unique_id.capacity()); copy(unique_id.begin(), unique_id.end(), msg.unique_id.begin()); msg.node_id = allocated_node_id.get(); trace(TraceAllocationResponse, msg.node_id); return allocation_pub_.broadcast(msg); }
bool needToQuery(NodeID node_id) { UAVCAN_ASSERT(node_id.isUnicast()); /* * Fast check */ if (committed_node_mask_[node_id.get()]) { return false; } /* * Slow check - may involve full log search */ const INodeDiscoveryHandler::NodeAwareness awareness = handler_.checkNodeAwareness(node_id); if (awareness == INodeDiscoveryHandler::NodeAwarenessUnknown) { return true; } else if (awareness == INodeDiscoveryHandler::NodeAwarenessKnownButNotCommitted) { removeNode(node_id); return false; } else if (awareness == INodeDiscoveryHandler::NodeAwarenessKnownAndCommitted) { trace(TraceDiscoveryCommitCacheUpdated, node_id.get()); committed_node_mask_[node_id.get()] = true; removeNode(node_id); return false; } else { UAVCAN_ASSERT(0); return false; } }
void finalizeNodeDiscovery(const UniqueID* unique_id_or_null, NodeID node_id) { trace(TraceDiscoveryNodeFinalized, node_id.get() | ((unique_id_or_null == NULL) ? 0U : 0x100U)); removeNode(node_id); /* * It is paramount to check if the server is still interested to receive this data. * Otherwise, if the node appeared in the log while we were waiting for response, we'd end up with * duplicate node ID in the log. */ if (needToQuery(node_id)) { handler_.handleNewNodeDiscovery(unique_id_or_null, node_id); } }
virtual void handleTimerEvent(const TimerEvent&) { bool at_least_one_request_needed = false; const NodeID next = pickNextNodeToQuery(at_least_one_request_needed); if (next.isUnicast()) { UAVCAN_ASSERT(at_least_one_request_needed); getEntry(next).updated_since_last_attempt = false; const int res = get_node_info_client_.call(next, protocol::GetNodeInfo::Request()); if (res < 0) { get_node_info_client_.getNode().registerInternalFailure("NodeInfoRetriever GetNodeInfo call"); } } else { if (!at_least_one_request_needed) { TimerBase::stop(); UAVCAN_TRACE("NodeInfoRetriever", "Timer stopped"); } } }
virtual void handleNodeInfoRetrieved(const NodeID node_id, const protocol::GetNodeInfo::Response& node_info) { FirmwareFilePath firmware_file_path; const bool update_needed = checker_.shouldRequestFirmwareUpdate(node_id, node_info, firmware_file_path); if (update_needed) { UAVCAN_TRACE("FirmwareUpdateTrigger", "Node ID %d requires update; file path: %s", int(node_id.get()), firmware_file_path.c_str()); trySetPendingNode(node_id, firmware_file_path); } else { UAVCAN_TRACE("FirmwareUpdateTrigger", "Node ID %d does not need update", int(node_id.get())); pending_nodes_.remove(node_id); } }
/* * Methods of INodeInfoListener */ virtual void handleNodeInfoUnavailable(NodeID node_id) { UAVCAN_TRACE("FirmwareUpdateTrigger", "Node ID %d could not provide GetNodeInfo response", int(node_id.get())); pending_nodes_.remove(node_id); // For extra paranoia }
bool isVotedForSet() const { return voted_for_.isUnicast(); }
/** * Initialization is performed as follows (every step may fail and return an error): * 1. Log is restored or initialized. * 2. Current term is restored. If there was no current term stored and the log is empty, it will be initialized * with zero. * 3. VotedFor value is restored. If there was no VotedFor value stored, the log is empty, and the current term is * zero, the value will be initialized with zero. */ int init() { /* * Reading log */ int res = log_.init(); if (res < 0) { UAVCAN_TRACE("dynamic_node_id_server::distributed::PersistentState", "Log init failed: %d", res); return res; } const Entry* const last_entry = log_.getEntryAtIndex(log_.getLastIndex()); if (last_entry == UAVCAN_NULLPTR) { UAVCAN_ASSERT(0); return -ErrLogic; } const bool log_is_empty = (log_.getLastIndex() == 0) && (last_entry->term == 0); StorageMarshaller io(storage_); /* * Reading currentTerm */ if (storage_.get(getCurrentTermKey()).empty() && log_is_empty) { // First initialization current_term_ = 0; res = io.setAndGetBack(getCurrentTermKey(), current_term_); if (res < 0) { UAVCAN_TRACE("dynamic_node_id_server::distributed::PersistentState", "Failed to init current term: %d", res); return res; } if (current_term_ != 0) { return -ErrFailure; } } else { // Restoring res = io.get(getCurrentTermKey(), current_term_); if (res < 0) { UAVCAN_TRACE("dynamic_node_id_server::distributed::PersistentState", "Failed to read current term: %d", res); return res; } } tracer_.onEvent(TraceRaftCurrentTermRestored, current_term_); if (current_term_ < last_entry->term) { UAVCAN_TRACE("dynamic_node_id_server::distributed::PersistentState", "Persistent storage is damaged: current term is less than term of the last log entry (%u < %u)", unsigned(current_term_), unsigned(last_entry->term)); return -ErrLogic; } /* * Reading votedFor */ if (storage_.get(getVotedForKey()).empty() && log_is_empty && (current_term_ == 0)) { // First initialization voted_for_ = NodeID(0); uint32_t stored_voted_for = 0; res = io.setAndGetBack(getVotedForKey(), stored_voted_for); if (res < 0) { UAVCAN_TRACE("dynamic_node_id_server::distributed::PersistentState", "Failed to init votedFor: %d", res); return res; } if (stored_voted_for != 0) { return -ErrFailure; } } else { // Restoring uint32_t stored_voted_for = 0; res = io.get(getVotedForKey(), stored_voted_for); if (res < 0) { UAVCAN_TRACE("dynamic_node_id_server::distributed::PersistentState", "Failed to read votedFor: %d", res); return res; } if (stored_voted_for > NodeID::Max) { return -ErrInvalidConfiguration; } voted_for_ = NodeID(uint8_t(stored_voted_for)); } tracer_.onEvent(TraceRaftVotedForRestored, voted_for_.get()); return 0; }
NodeHandle FileHandle::get_node_from_id(NodeID id) const { return NodeHandle(id.get_index(), get_shared_data()); }
void removeNode(const NodeID node_id) { node_map_.remove(node_id); trace(TraceDiscoveryNodeRemoved, node_id.get()); }
// Returns the Unique ID recorded in the given NodeState int getNodeID(const NodeState& state) { ROSE_ASSERT(puids); NodeID* id = (NodeID*)state.getFact(puids, 0); return id->getID(); }
NodeID::NodeID(const NodeID &n) { idArray = new char[129]; strncpy(idArray, n.toString().c_str(), 128); idArray[n.toString().size()] = '\0'; };
int DynamicNodeIDClient::start(const protocol::HardwareVersion& hardware_version, const NodeID preferred_node_id, const TransferPriority transfer_priority) { terminate(); // Allocation is not possible if node ID is already set if (dnida_pub_.getNode().getNodeID().isUnicast()) { return -ErrLogic; } // Unique ID initialization & validation copy(hardware_version.unique_id.begin(), hardware_version.unique_id.end(), unique_id_); bool unique_id_is_zero = true; for (uint8_t i = 0; i < sizeof(unique_id_); i++) { if (unique_id_[i] != 0) { unique_id_is_zero = false; break; } } if (unique_id_is_zero) { return -ErrInvalidParam; } if (!preferred_node_id.isValid()) // Only broadcast and unicast are allowed { return -ErrInvalidParam; } // Initializing the fields preferred_node_id_ = preferred_node_id; allocated_node_id_ = NodeID(); allocator_node_id_ = NodeID(); UAVCAN_ASSERT(preferred_node_id_.isValid()); UAVCAN_ASSERT(!allocated_node_id_.isValid()); UAVCAN_ASSERT(!allocator_node_id_.isValid()); // Initializing node objects - Rule A int res = dnida_pub_.init(); if (res < 0) { return res; } dnida_pub_.allowAnonymousTransfers(); dnida_pub_.setPriority(transfer_priority); res = dnida_sub_.start(AllocationCallback(this, &DynamicNodeIDClient::handleAllocation)); if (res < 0) { return res; } dnida_sub_.allowAnonymousTransfers(); startPeriodic(MonotonicDuration::fromMSec(protocol::dynamic_node_id::Allocation::DEFAULT_REQUEST_PERIOD_MS)); return 0; }
void changeNodeStatus(const NodeID node_id, const Entry new_entry_value) { Entry& entry = getEntry(node_id); if (entry.status != new_entry_value.status) { NodeStatusChangeEvent event; event.node_id = node_id; event.old_status = entry.status; event.status = new_entry_value.status; event.was_known = entry.time_since_last_update_ms100 >= 0; UAVCAN_TRACE("NodeStatusMonitor", "Node %i [%s] status change: [%s] --> [%s]", int(node_id.get()), (event.was_known ? "known" : "new"), event.old_status.toString().c_str(), event.status.toString().c_str()); handleNodeStatusChange(event); } entry = new_entry_value; }
//inline bool NodeID::operator <(const NodeID &nid)const bool NodeID::operator <(const NodeID &nid)const { return this->toString()<nid.toString(); }