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; }
TransferReceiver::ResultCode TransferReceiver::addFrame(const RxFrame& frame, TransferBufferAccessor& tba) { if ((frame.getMonotonicTimestamp().isZero()) || (frame.getMonotonicTimestamp() < prev_transfer_ts_) || (frame.getMonotonicTimestamp() < this_transfer_ts_)) { return ResultNotComplete; } const bool not_initialized = !isInitialized(); const bool receiver_timed_out = isTimedOut(frame.getMonotonicTimestamp()); const bool same_iface = frame.getIfaceIndex() == iface_index_; const bool first_fame = frame.isFirst(); const TidRelation tid_rel = getTidRelation(frame); const bool iface_timed_out = (frame.getMonotonicTimestamp() - this_transfer_ts_).toUSec() > (int64_t(transfer_interval_usec_) * 2); // FSM, the hard way const bool need_restart = (not_initialized) || (receiver_timed_out) || (same_iface && first_fame && (tid_rel == TidFuture)) || (iface_timed_out && first_fame && (tid_rel == TidFuture)); if (need_restart) { const bool error = !not_initialized && !receiver_timed_out; if (error) { registerError(); } UAVCAN_TRACE("TransferReceiver", "Restart [not_inited=%i, iface_timeout=%i, recv_timeout=%i, same_iface=%i, first_frame=%i, tid_rel=%i], %s", int(not_initialized), int(iface_timed_out), int(receiver_timed_out), int(same_iface), int(first_fame), int(tid_rel), frame.toString().c_str()); tba.remove(); iface_index_ = frame.getIfaceIndex(); tid_ = frame.getTransferID(); next_frame_index_ = 0; buffer_write_pos_ = 0; this_transfer_crc_ = 0; if (!first_fame) { tid_.increment(); return ResultNotComplete; } } if (!validate(frame)) { return ResultNotComplete; } return receive(frame, tba); }