예제 #1
0
    /**
     * 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;
    }
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;
}