bool TransferReceiver::writePayload(const RxFrame& frame, ITransferBuffer& buf) { const uint8_t* const payload = frame.getPayloadPtr(); const unsigned payload_len = frame.getPayloadLen(); if (frame.isFirst()) // First frame contains CRC, we need to extract it now { if (frame.getPayloadLen() < TransferCRC::NumBytes) { return false; // Must have been validated earlier though. I think I'm paranoid. } this_transfer_crc_ = static_cast<uint16_t>(payload[0] & 0xFF); this_transfer_crc_ |= static_cast<uint16_t>(static_cast<uint16_t>(payload[1] & 0xFF) << 8); // Little endian. const unsigned effective_payload_len = payload_len - TransferCRC::NumBytes; const int res = buf.write(buffer_write_pos_, payload + TransferCRC::NumBytes, effective_payload_len); const bool success = res == static_cast<int>(effective_payload_len); if (success) { buffer_write_pos_ = static_cast<uint16_t>(buffer_write_pos_ + effective_payload_len); } return success; } else { const int res = buf.write(buffer_write_pos_, payload, payload_len); const bool success = res == static_cast<int>(payload_len); if (success) { buffer_write_pos_ = static_cast<uint16_t>(buffer_write_pos_ + payload_len); } return success; } }
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; }
/* * SingleFrameIncomingTransfer */ SingleFrameIncomingTransfer::SingleFrameIncomingTransfer(const RxFrame& frm) : IncomingTransfer(frm.getMonotonicTimestamp(), frm.getUtcTimestamp(), frm.getPriority(), frm.getTransferType(), frm.getTransferID(), frm.getSrcNodeID(), frm.getIfaceIndex()) , payload_(frm.getPayloadPtr()) , payload_len_(uint8_t(frm.getPayloadLen())) { UAVCAN_ASSERT(frm.isValid()); }
TEST(SingleFrameIncomingTransfer, Basic) { using uavcan::RxFrame; using uavcan::SingleFrameIncomingTransfer; const RxFrame frame = makeFrame(); SingleFrameIncomingTransfer it(frame); ASSERT_TRUE(match(it, frame, frame.getPayloadPtr(), frame.getPayloadLen())); }