libuav original
Dependents: UAVCAN UAVCAN_Subscriber
transfer_listener.hpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #ifndef UAVCAN_TRANSPORT_TRANSFER_LISTENER_HPP_INCLUDED 00006 #define UAVCAN_TRANSPORT_TRANSFER_LISTENER_HPP_INCLUDED 00007 00008 #include <cassert> 00009 #include <uavcan/error.hpp> 00010 #include <uavcan/std.hpp> 00011 #include <uavcan/transport/transfer_receiver.hpp> 00012 #include <uavcan/transport/perf_counter.hpp> 00013 #include <uavcan/util/linked_list.hpp> 00014 #include <uavcan/util/map.hpp> 00015 #include <uavcan/debug.hpp> 00016 #include <uavcan/transport/crc.hpp> 00017 #include <uavcan/data_type.hpp> 00018 00019 namespace uavcan 00020 { 00021 /** 00022 * Container for received transfer. 00023 */ 00024 class UAVCAN_EXPORT IncomingTransfer : public ITransferBuffer 00025 { 00026 MonotonicTime ts_mono_; 00027 UtcTime ts_utc_; 00028 TransferPriority transfer_priority_; 00029 TransferType transfer_type_; 00030 TransferID transfer_id_; 00031 NodeID src_node_id_; 00032 uint8_t iface_index_; 00033 00034 /// That's a no-op, asserts in debug builds 00035 virtual int write(unsigned offset, const uint8_t* data, unsigned len); 00036 00037 protected: 00038 IncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, TransferPriority transfer_priority, 00039 TransferType transfer_type, TransferID transfer_id, NodeID source_node_id, 00040 uint8_t iface_index) 00041 : ts_mono_(ts_mono) 00042 , ts_utc_(ts_utc) 00043 , transfer_priority_(transfer_priority) 00044 , transfer_type_(transfer_type) 00045 , transfer_id_(transfer_id) 00046 , src_node_id_(source_node_id) 00047 , iface_index_(iface_index) 00048 { } 00049 00050 public: 00051 /** 00052 * Dispose the payload buffer. Further calls to read() will not be possible. 00053 */ 00054 virtual void release() { } 00055 00056 /** 00057 * Whether this is a anonymous transfer 00058 */ 00059 virtual bool isAnonymousTransfer() const { return false; } 00060 00061 MonotonicTime getMonotonicTimestamp() const { return ts_mono_; } 00062 UtcTime getUtcTimestamp() const { return ts_utc_; } 00063 TransferPriority getPriority() const { return transfer_priority_; } 00064 TransferType getTransferType() const { return transfer_type_; } 00065 TransferID getTransferID() const { return transfer_id_; } 00066 NodeID getSrcNodeID() const { return src_node_id_; } 00067 uint8_t getIfaceIndex() const { return iface_index_; } 00068 }; 00069 00070 /** 00071 * Internal. 00072 */ 00073 class UAVCAN_EXPORT SingleFrameIncomingTransfer : public IncomingTransfer 00074 { 00075 const uint8_t* const payload_; 00076 const uint8_t payload_len_; 00077 public: 00078 explicit SingleFrameIncomingTransfer(const RxFrame& frm); 00079 virtual int read(unsigned offset, uint8_t* data, unsigned len) const; 00080 virtual bool isAnonymousTransfer() const; 00081 }; 00082 00083 /** 00084 * Internal. 00085 */ 00086 class UAVCAN_EXPORT MultiFrameIncomingTransfer : public IncomingTransfer, Noncopyable 00087 { 00088 TransferBufferAccessor& buf_acc_; 00089 public: 00090 MultiFrameIncomingTransfer(MonotonicTime ts_mono, UtcTime ts_utc, const RxFrame& last_frame, 00091 TransferBufferAccessor& tba); 00092 virtual int read(unsigned offset, uint8_t* data, unsigned len) const; 00093 virtual void release() { buf_acc_.remove(); } 00094 }; 00095 00096 /** 00097 * Internal, refer to the transport dispatcher class. 00098 */ 00099 class UAVCAN_EXPORT TransferListener : public LinkedListNode<TransferListener> 00100 { 00101 const DataTypeDescriptor& data_type_; 00102 TransferBufferManager bufmgr_; 00103 Map<TransferBufferManagerKey, TransferReceiver> receivers_; 00104 TransferPerfCounter& perf_; 00105 const TransferCRC crc_base_; ///< Pre-initialized with data type hash, thus constant 00106 bool allow_anonymous_transfers_; 00107 00108 class TimedOutReceiverPredicate 00109 { 00110 const MonotonicTime ts_; 00111 TransferBufferManager& parent_bufmgr_; 00112 00113 public: 00114 TimedOutReceiverPredicate(MonotonicTime arg_ts, TransferBufferManager& arg_bufmgr) 00115 : ts_(arg_ts) 00116 , parent_bufmgr_(arg_bufmgr) 00117 { } 00118 00119 bool operator()(const TransferBufferManagerKey& key, const TransferReceiver& value) const; 00120 }; 00121 00122 bool checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const; 00123 00124 protected: 00125 void handleReception(TransferReceiver& receiver, const RxFrame& frame, TransferBufferAccessor& tba); 00126 void handleAnonymousTransferReception(const RxFrame& frame); 00127 00128 virtual void handleIncomingTransfer(IncomingTransfer& transfer) = 0; 00129 00130 public: 00131 TransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, 00132 uint16_t max_buffer_size, IPoolAllocator& allocator) 00133 : data_type_(data_type) 00134 , bufmgr_(max_buffer_size, allocator) 00135 , receivers_(allocator) 00136 , perf_(perf) 00137 , crc_base_(data_type.getSignature().toTransferCRC()) 00138 , allow_anonymous_transfers_(false) 00139 { } 00140 00141 virtual ~TransferListener(); 00142 00143 const DataTypeDescriptor& getDataTypeDescriptor() const { return data_type_; } 00144 00145 /** 00146 * By default, anonymous transfers will be ignored. 00147 * This option allows to enable reception of anonymous transfers. 00148 */ 00149 void allowAnonymousTransfers() { allow_anonymous_transfers_ = true; } 00150 00151 void cleanup(MonotonicTime ts); 00152 00153 virtual void handleFrame(const RxFrame& frame); 00154 }; 00155 00156 /** 00157 * This class is used by transfer listener to decide if the frame should be accepted or ignored. 00158 */ 00159 class ITransferAcceptanceFilter 00160 { 00161 public: 00162 /** 00163 * If it returns false, the frame will be ignored, otherwise accepted. 00164 */ 00165 virtual bool shouldAcceptFrame(const RxFrame& frame) const = 0; 00166 00167 virtual ~ITransferAcceptanceFilter() { } 00168 }; 00169 00170 /** 00171 * This class should be derived by callers. 00172 */ 00173 class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener 00174 { 00175 const ITransferAcceptanceFilter* filter_; 00176 00177 virtual void handleFrame(const RxFrame& frame); 00178 00179 public: 00180 TransferListenerWithFilter(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, 00181 uint16_t max_buffer_size, IPoolAllocator& allocator) 00182 : TransferListener(perf, data_type, max_buffer_size, allocator) 00183 , filter_(UAVCAN_NULLPTR) 00184 { } 00185 00186 void installAcceptanceFilter(const ITransferAcceptanceFilter* acceptance_filter) 00187 { 00188 filter_ = acceptance_filter; 00189 } 00190 }; 00191 00192 } 00193 00194 #endif // UAVCAN_TRANSPORT_TRANSFER_LISTENER_HPP_INCLUDED
Generated on Tue Jul 12 2022 17:17:35 by
1.7.2