示例#1
0
    void handleGetNodeInfoResponse(const ServiceCallResult<protocol::GetNodeInfo>& result)
    {
        if (result.isSuccessful())
        {
            UAVCAN_TRACE("dynamic_node_id_server::NodeDiscoverer", "GetNodeInfo response from %d",
                         int(result.getCallID().server_node_id.get()));
            finalizeNodeDiscovery(&result.getResponse().hardware_version.unique_id, result.getCallID().server_node_id);
        }
        else
        {
            trace(TraceDiscoveryGetNodeInfoFailure, result.getCallID().server_node_id.get());

            NodeData* const data = node_map_.access(result.getCallID().server_node_id);
            if (data == NULL)
            {
                return;         // Probably it is a known node now
            }

            UAVCAN_TRACE("dynamic_node_id_server::NodeDiscoverer",
                         "GetNodeInfo request to %d has timed out, %d attempts",
                         int(result.getCallID().server_node_id.get()), int(data->num_get_node_info_attempts));
            data->num_get_node_info_attempts++;
            if (data->num_get_node_info_attempts >= MaxAttemptsToGetNodeInfo)
            {
                finalizeNodeDiscovery(NULL, result.getCallID().server_node_id);
                // Warning: data pointer is invalidated now
            }
        }
    }
    void handleBeginFirmwareUpdateResponse(const ServiceCallResult<protocol::file::BeginFirmwareUpdate>& result)
    {
        if (!result.isSuccessful())
        {
            UAVCAN_TRACE("FirmwareUpdateTrigger", "Request to %d has timed out, will retry",
                         int(result.getCallID().server_node_id.get()));
            return;
        }

        FirmwareFilePath* const old_path = pending_nodes_.access(result.getCallID().server_node_id);
        if (old_path == UAVCAN_NULLPTR)
        {
            // The entry has been removed, assuming that it's not needed anymore
            return;
        }

        const bool confirmed =
            result.getResponse().error == protocol::file::BeginFirmwareUpdate::Response::ERROR_OK ||
            result.getResponse().error == protocol::file::BeginFirmwareUpdate::Response::ERROR_IN_PROGRESS;

        if (confirmed)
        {
            UAVCAN_TRACE("FirmwareUpdateTrigger", "Node %d confirmed the update request",
                         int(result.getCallID().server_node_id.get()));
            pending_nodes_.remove(result.getCallID().server_node_id);
            checker_.handleFirmwareUpdateConfirmation(result.getCallID().server_node_id, result.getResponse());
        }
        else
        {
            UAVCAN_ASSERT(old_path != UAVCAN_NULLPTR);
            UAVCAN_ASSERT(TimerBase::isRunning());
            // We won't have to call trySetPendingNode(), because we'll directly update the old path via the pointer

            const bool update_needed =
                checker_.shouldRetryFirmwareUpdate(result.getCallID().server_node_id, result.getResponse(), *old_path);

            if (!update_needed)
            {
                UAVCAN_TRACE("FirmwareUpdateTrigger", "Node %d does not need retry",
                             int(result.getCallID().server_node_id.get()));
                pending_nodes_.remove(result.getCallID().server_node_id);
            }
        }
    }
    void handleGetNodeInfoResponse(const ServiceCallResult<protocol::GetNodeInfo>& result)
    {
        Entry& entry = getEntry(result.getCallID().server_node_id);

        if (result.isSuccessful())
        {
            /*
             * Updating the uptime here allows to properly handle a corner case where the service response arrives
             * after the device has restarted and published its new NodeStatus (although it's unlikely to happen).
             */
            entry.uptime_sec = result.getResponse().status.uptime_sec;
            entry.request_needed = false;
            listeners_.forEach(NodeInfoRetrievedHandlerCaller(result.getCallID().server_node_id,
                                                              result.getResponse()));
        }
        else
        {
            if (num_attempts_ != UnlimitedRequestAttempts)
            {
                entry.num_attempts_made++;
                if (entry.num_attempts_made >= num_attempts_)
                {
                    entry.request_needed = false;
                    listeners_.forEach(GenericHandlerCaller<NodeID>(&INodeInfoListener::handleNodeInfoUnavailable,
                                                                    result.getCallID().server_node_id));
                }
            }
        }
    }