/* * 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()); }
/* * 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); } }
/* * Dispatcher */ void Dispatcher::handleFrame(const CanRxFrame& can_frame) { RxFrame frame; if (!frame.parse(can_frame)) { // This is not counted as a transport error UAVCAN_TRACE("Dispatcher", "Invalid CAN frame received: %s", can_frame.toString().c_str()); return; } if ((frame.getDstNodeID() != NodeID::Broadcast) && (frame.getDstNodeID() != getNodeID())) { return; } switch (frame.getTransferType()) { case TransferTypeMessageBroadcast: case TransferTypeMessageUnicast: { lmsg_.handleFrame(frame); break; } case TransferTypeServiceRequest: { lsrv_req_.handleFrame(frame); break; } case TransferTypeServiceResponse: { lsrv_resp_.handleFrame(frame); break; } default: { UAVCAN_ASSERT(0); break; } } }
TEST(MultiFrameIncomingTransfer, Basic) { using uavcan::RxFrame; using uavcan::MultiFrameIncomingTransfer; uavcan::PoolManager<1> poolmgr; // We don't need dynamic memory uavcan::TransferBufferManager<256, 1> bufmgr(poolmgr); const RxFrame frame = makeFrame(); uavcan::TransferBufferManagerKey bufmgr_key(frame.getSrcNodeID(), frame.getTransferType()); uavcan::TransferBufferAccessor tba(bufmgr, bufmgr_key); MultiFrameIncomingTransfer it(frame.getMonotonicTimestamp(), frame.getUtcTimestamp(), frame, tba); /* * Empty read must fail */ uint8_t data_byte = 0; ASSERT_GT(0, it.read(0, &data_byte, 1)); // Error - no such buffer /* * Filling the test data */ const std::string data = "123Hello world"; const uint8_t* const data_ptr = reinterpret_cast<const uint8_t*>(data.c_str()); ASSERT_FALSE(bufmgr.access(bufmgr_key)); ASSERT_TRUE(bufmgr.create(bufmgr_key)); ASSERT_EQ(data.length(), bufmgr.access(bufmgr_key)->write(0, data_ptr, data.length())); /* * Check */ ASSERT_TRUE(match(it, frame, data_ptr, data.length())); /* * Buffer release */ ASSERT_TRUE(bufmgr.access(bufmgr_key)); it.release(); ASSERT_FALSE(bufmgr.access(bufmgr_key)); }
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 } }