bool TransferReceiver::validate(const RxFrame& frame) const { if (iface_index_ != frame.getIfaceIndex()) { return false; } if (frame.isFirst() && !frame.isLast() && (frame.getPayloadLen() < TransferCRC::NumBytes)) { UAVCAN_TRACE("TransferReceiver", "CRC expected, %s", frame.toString().c_str()); registerError(); return false; } if ((frame.getIndex() == Frame::MaxIndex) && !frame.isLast()) { UAVCAN_TRACE("TransferReceiver", "Unterminated transfer, %s", frame.toString().c_str()); registerError(); return false; } if (frame.getIndex() != next_frame_index_) { UAVCAN_TRACE("TransferReceiver", "Unexpected frame index (not %i), %s", int(next_frame_index_), frame.toString().c_str()); registerError(); return false; } if (getTidRelation(frame) != TidSame) { UAVCAN_TRACE("TransferReceiver", "Unexpected TID (current %i), %s", tid_.get(), frame.toString().c_str()); registerError(); return false; } return true; }
TransferReceiver::ResultCode TransferReceiver::receive(const RxFrame& frame, TransferBufferAccessor& tba) { // Transfer timestamps are derived from the first frame if (frame.isFirst()) { this_transfer_ts_ = frame.getMonotonicTimestamp(); first_frame_ts_ = frame.getUtcTimestamp(); } if (frame.isFirst() && frame.isLast()) { tba.remove(); updateTransferTimings(); prepareForNextTransfer(); this_transfer_crc_ = 0; // SFT has no CRC return ResultSingleFrame; } // Payload write ITransferBuffer* buf = tba.access(); if (buf == NULL) { buf = tba.create(); } if (buf == NULL) { UAVCAN_TRACE("TransferReceiver", "Failed to access the buffer, %s", frame.toString().c_str()); prepareForNextTransfer(); registerError(); return ResultNotComplete; } if (!writePayload(frame, *buf)) { UAVCAN_TRACE("TransferReceiver", "Payload write failed, %s", frame.toString().c_str()); tba.remove(); prepareForNextTransfer(); registerError(); return ResultNotComplete; } next_frame_index_++; if (frame.isLast()) { updateTransferTimings(); prepareForNextTransfer(); return ResultComplete; } return ResultNotComplete; }
/* * MultiFrameIncomingTransfer */ MultiFrameIncomingTransfer::MultiFrameIncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, const RxFrame& last_frame, TransferBufferAccessor& tba) : IncomingTransfer(ts_mono, ts_utc, last_frame.getPriority(), last_frame.getTransferType(), last_frame.getTransferID(), last_frame.getSrcNodeID(), last_frame.getIfaceIndex()) , buf_acc_(tba) { UAVCAN_ASSERT(last_frame.isValid()); UAVCAN_ASSERT(last_frame.isLast()); }
/* * GlobalTimeSyncMaster */ void GlobalTimeSyncMaster::handleLoopbackFrame(const RxFrame& frame) { const uint8_t iface = frame.getIfaceIndex(); if (initialized_ && iface < MaxCanIfaces) { if (frame.getDataTypeID() == dtid_ && frame.getTransferType() == TransferTypeMessageBroadcast && frame.isLast() && frame.isFirst() && frame.getSrcNodeID() == node_.getNodeID()) { iface_masters_[iface]->setTxTimestamp(frame.getUtcTimestamp()); } } else { UAVCAN_ASSERT(0); } }
void TransferListenerBase::handleFrame(const RxFrame& frame) { if (frame.getSrcNodeID().isUnicast()) // Normal transfer { const TransferBufferManagerKey key(frame.getSrcNodeID(), frame.getTransferType()); TransferReceiver* recv = receivers_.access(key); if (recv == NULL) { if (!frame.isFirst()) { return; } TransferReceiver new_recv; recv = receivers_.insert(key, new_recv); if (recv == NULL) { UAVCAN_TRACE("TransferListener", "Receiver registration failed; frame %s", frame.toString().c_str()); return; } } TransferBufferAccessor tba(bufmgr_, key); handleReception(*recv, frame, tba); } else if (frame.getSrcNodeID().isBroadcast() && frame.isFirst() && frame.isLast() && frame.getDstNodeID().isBroadcast()) // Anonymous transfer { handleAnonymousTransferReception(frame); } else { UAVCAN_TRACE("TransferListenerBase", "Invalid frame: %s", frame.toString().c_str()); // Invalid frame } }