Transfer buffering system detemplatized; compiles but tests are failing

This commit is contained in:
Pavel Kirienko
2015-10-14 19:58:51 +03:00
parent 763e96b6ed
commit a9fdf44fa9
20 changed files with 335 additions and 510 deletions
@@ -100,9 +100,9 @@ protected:
~GenericSubscriberBase() { }
int genericStart(TransferListenerBase* listener, bool (Dispatcher::*registration_method)(TransferListenerBase*));
int genericStart(TransferListener* listener, bool (Dispatcher::*registration_method)(TransferListener*));
void stop(TransferListenerBase* listener);
void stop(TransferListener* listener);
public:
/**
@@ -115,22 +115,6 @@ public:
INode& getNode() const { return node_; }
};
/**
* This helper class does some compile-time magic on the transport layer machinery. For authorized personnel only.
*/
template <typename DataStruct_,
template<unsigned> class TransferListenerTemplate = TransferListener
>
class UAVCAN_EXPORT TransferListenerInstantiationHelper
{
enum { DataTypeMaxByteLen = BitLenToByteLen<DataStruct_::MaxBitLen>::Result };
enum { NeedsBuffer = int(DataTypeMaxByteLen) > int(GuaranteedPayloadLenPerFrame) };
enum { BufferSize = NeedsBuffer ? DataTypeMaxByteLen : 0 };
public:
typedef TransferListenerTemplate<BufferSize> Type;
};
/**
* Please note that the reference passed to the RX callback points to a stack-allocated object, which means
* that it gets invalidated shortly after the callback returns.
@@ -151,9 +135,15 @@ class UAVCAN_EXPORT GenericSubscriber : public GenericSubscriberBase
}
public:
TransferForwarder(SelfType& obj, const DataTypeDescriptor& data_type, IPoolAllocator& allocator)
: TransferListenerType(obj.node_.getDispatcher().getTransferPerfCounter(), data_type, allocator)
, obj_(obj)
TransferForwarder(SelfType& obj,
const DataTypeDescriptor& data_type,
uint16_t max_buffer_size,
IPoolAllocator& allocator) :
TransferListenerType(obj.node_.getDispatcher().getTransferPerfCounter(),
data_type,
max_buffer_size,
allocator),
obj_(obj)
{ }
};
@@ -163,20 +153,19 @@ class UAVCAN_EXPORT GenericSubscriber : public GenericSubscriberBase
void handleIncomingTransfer(IncomingTransfer& transfer);
int genericStart(bool (Dispatcher::*registration_method)(TransferListenerBase*));
int genericStart(bool (Dispatcher::*registration_method)(TransferListener*));
protected:
struct ReceivedDataStructureSpec : public ReceivedDataStructure<DataStruct>
{
ReceivedDataStructureSpec() { }
ReceivedDataStructureSpec(const IncomingTransfer* arg_transfer)
: ReceivedDataStructure<DataStruct>(arg_transfer)
ReceivedDataStructureSpec(const IncomingTransfer* arg_transfer) :
ReceivedDataStructure<DataStruct>(arg_transfer)
{ }
};
explicit GenericSubscriber(INode& node)
: GenericSubscriberBase(node)
explicit GenericSubscriber(INode& node) : GenericSubscriberBase(node)
{ }
virtual ~GenericSubscriber() { stop(); }
@@ -247,8 +236,10 @@ int GenericSubscriber<DataSpec, DataStruct, TransferListenerType>::checkInit()
return -ErrUnknownDataType;
}
forwarder_.template construct<SelfType&, const DataTypeDescriptor&, IPoolAllocator&>
(*this, *descr, node_.getAllocator());
static const uint16_t MaxBufferSize = BitLenToByteLen<DataStruct::MaxBitLen>::Result;
forwarder_.template construct<SelfType&, const DataTypeDescriptor&, uint16_t, IPoolAllocator&>
(*this, *descr, MaxBufferSize, node_.getAllocator());
return 0;
}
@@ -286,7 +277,7 @@ void GenericSubscriber<DataSpec, DataStruct, TransferListenerType>::handleIncomi
template <typename DataSpec, typename DataStruct, typename TransferListenerType>
int GenericSubscriber<DataSpec, DataStruct, TransferListenerType>::
genericStart(bool (Dispatcher::*registration_method)(TransferListenerBase*))
genericStart(bool (Dispatcher::*registration_method)(TransferListener*))
{
const int res = checkInit();
if (res < 0)
@@ -20,15 +20,6 @@
namespace uavcan
{
template <typename ServiceDataType>
class UAVCAN_EXPORT ServiceResponseTransferListenerInstantiationHelper
{
public:
typedef typename TransferListenerInstantiationHelper<typename ServiceDataType::Response,
TransferListenerWithFilter>::Type Type;
};
/**
* This struct describes a pending service call.
* Refer to @ref ServiceClient to learn more about service calls.
@@ -225,8 +216,7 @@ template <typename DataType_,
>
class UAVCAN_EXPORT ServiceClient
: public GenericSubscriber<DataType_,
typename DataType_::Response,
typename ServiceResponseTransferListenerInstantiationHelper<DataType_>::Type>
typename DataType_::Response, TransferListenerWithFilter>
, public ServiceClientBase
{
public:
@@ -239,8 +229,7 @@ public:
private:
typedef ServiceClient<DataType, Callback> SelfType;
typedef GenericPublisher<DataType, RequestType> PublisherType;
typedef typename ServiceResponseTransferListenerInstantiationHelper<DataType>::Type TransferListenerType;
typedef GenericSubscriber<DataType, ResponseType, TransferListenerType> SubscriberType;
typedef GenericSubscriber<DataType, ResponseType, TransferListenerWithFilter> SubscriberType;
typedef Multiset<CallState> CallRegistry;
@@ -537,7 +526,7 @@ int ServiceClient<DataType_, Callback_>::call(NodeID server_node_id, const Reque
* Configuring the listener so it will accept only the matching responses
* TODO move to init(), but this requires to somewhat refactor GenericSubscriber<> (remove TransferForwarder)
*/
TransferListenerType* const tl = SubscriberType::getTransferListener();
TransferListenerWithFilter* const tl = SubscriberType::getTransferListener();
if (tl == NULL)
{
UAVCAN_ASSERT(0); // Must have been created
@@ -88,8 +88,7 @@ template <typename DataType_,
#endif
>
class UAVCAN_EXPORT ServiceServer
: public GenericSubscriber<DataType_, typename DataType_::Request,
typename TransferListenerInstantiationHelper<typename DataType_::Request>::Type>
: public GenericSubscriber<DataType_, typename DataType_::Request, TransferListener>
{
public:
typedef DataType_ DataType;
@@ -98,8 +97,7 @@ public:
typedef Callback_ Callback;
private:
typedef typename TransferListenerInstantiationHelper<RequestType>::Type TransferListenerType;
typedef GenericSubscriber<DataType, RequestType, TransferListenerType> SubscriberType;
typedef GenericSubscriber<DataType, RequestType, TransferListener> SubscriberType;
typedef GenericPublisher<DataType, ResponseType> PublisherType;
PublisherType publisher_;
+2 -4
View File
@@ -43,15 +43,13 @@ template <typename DataType_,
#endif
>
class UAVCAN_EXPORT Subscriber
: public GenericSubscriber<DataType_, DataType_,
typename TransferListenerInstantiationHelper<DataType_>::Type>
: public GenericSubscriber<DataType_, DataType_, TransferListener>
{
public:
typedef Callback_ Callback;
private:
typedef typename TransferListenerInstantiationHelper<DataType_>::Type TransferListenerType;
typedef GenericSubscriber<DataType_, DataType_, TransferListenerType> BaseType;
typedef GenericSubscriber<DataType_, DataType_, TransferListener> BaseType;
Callback callback_;
@@ -86,14 +86,14 @@ class UAVCAN_EXPORT Dispatcher : Noncopyable
class ListenerRegistry
{
LinkedListRoot<TransferListenerBase> list_;
LinkedListRoot<TransferListener> list_;
class DataTypeIDInsertionComparator
{
const DataTypeID id_;
public:
explicit DataTypeIDInsertionComparator(DataTypeID id) : id_(id) { }
bool operator()(const TransferListenerBase* listener) const
bool operator()(const TransferListener* listener) const
{
UAVCAN_ASSERT(listener);
return id_ > listener->getDataTypeDescriptor().getID();
@@ -103,15 +103,15 @@ class UAVCAN_EXPORT Dispatcher : Noncopyable
public:
enum Mode { UniqueListener, ManyListeners };
bool add(TransferListenerBase* listener, Mode mode);
void remove(TransferListenerBase* listener);
bool add(TransferListener* listener, Mode mode);
void remove(TransferListener* listener);
bool exists(DataTypeID dtid) const;
void cleanup(MonotonicTime ts);
void handleFrame(const RxFrame& frame);
unsigned getNumEntries() const { return list_.getLength(); }
const LinkedListRoot<TransferListenerBase>& getList() const { return list_; }
const LinkedListRoot<TransferListener>& getList() const { return list_; }
};
ListenerRegistry lmsg_;
@@ -162,13 +162,13 @@ public:
void cleanup(MonotonicTime ts);
bool registerMessageListener(TransferListenerBase* listener);
bool registerServiceRequestListener(TransferListenerBase* listener);
bool registerServiceResponseListener(TransferListenerBase* listener);
bool registerMessageListener(TransferListener* listener);
bool registerServiceRequestListener(TransferListener* listener);
bool registerServiceResponseListener(TransferListener* listener);
void unregisterMessageListener(TransferListenerBase* listener);
void unregisterServiceRequestListener(TransferListenerBase* listener);
void unregisterServiceResponseListener(TransferListenerBase* listener);
void unregisterMessageListener(TransferListener* listener);
void unregisterServiceRequestListener(TransferListener* listener);
void unregisterServiceResponseListener(TransferListener* listener);
bool hasSubscriber(DataTypeID dtid) const;
bool hasPublisher(DataTypeID dtid) const;
@@ -185,15 +185,15 @@ public:
* removed from this list as soon as the corresponding service call is complete.
* @{
*/
const LinkedListRoot<TransferListenerBase>& getListOfMessageListeners() const
const LinkedListRoot<TransferListener>& getListOfMessageListeners() const
{
return lmsg_.getList();
}
const LinkedListRoot<TransferListenerBase>& getListOfServiceRequestListeners() const
const LinkedListRoot<TransferListener>& getListOfServiceRequestListeners() const
{
return lsrv_req_.getList();
}
const LinkedListRoot<TransferListenerBase>& getListOfServiceResponseListeners() const
const LinkedListRoot<TransferListener>& getListOfServiceResponseListeners() const
{
return lsrv_resp_.getList();
}
@@ -16,6 +16,47 @@
namespace uavcan
{
/**
* Standalone static buffer
*/
class StaticTransferBufferImpl : public ITransferBuffer
{
uint8_t* const data_;
const uint16_t size_;
uint16_t max_write_pos_;
public:
StaticTransferBufferImpl(uint8_t* buf, uint16_t buf_size) :
data_(buf),
size_(buf_size),
max_write_pos_(0)
{ }
virtual int read(unsigned offset, uint8_t* data, unsigned len) const;
virtual int write(unsigned offset, const uint8_t* data, unsigned len);
void reset();
uint16_t getSize() const { return size_; }
uint8_t* getRawPtr() { return data_; }
const uint8_t* getRawPtr() const { return data_; }
uint16_t getMaxWritePos() const { return max_write_pos_; }
void setMaxWritePos(uint16_t value) { max_write_pos_ = value; }
};
template <uint16_t Size>
class UAVCAN_EXPORT StaticTransferBuffer : public StaticTransferBufferImpl
{
uint8_t buffer_[Size];
public:
StaticTransferBuffer() : StaticTransferBufferImpl(buffer_, Size)
{
StaticAssert<(Size > 0)>::check();
}
};
/**
* Internal for TransferBufferManager
*/
@@ -53,41 +94,13 @@ public:
#endif
};
/**
* Internal for TransferBufferManager
*/
class UAVCAN_EXPORT TransferBufferManagerEntry : public ITransferBuffer, Noncopyable
{
TransferBufferManagerKey key_;
protected:
virtual void resetImpl() = 0;
public:
TransferBufferManagerEntry() { }
explicit TransferBufferManagerEntry(const TransferBufferManagerKey& key)
: key_(key)
{ }
const TransferBufferManagerKey& getKey() const { return key_; }
bool isEmpty() const { return key_.isEmpty(); }
void reset(const TransferBufferManagerKey& key = TransferBufferManagerKey())
{
key_ = key;
resetImpl();
}
};
/**
* Resizable gather/scatter storage.
* reset() call releases all memory blocks.
* Supports unordered write operations - from higher to lower offsets
*/
class UAVCAN_EXPORT DynamicTransferBufferManagerEntry
: public TransferBufferManagerEntry
, public LinkedListNode<DynamicTransferBufferManagerEntry>
class UAVCAN_EXPORT TransferBufferManagerEntry : public ITransferBuffer
, public LinkedListNode<TransferBufferManagerEntry>
{
struct Block : LinkedListNode<Block>
{
@@ -107,116 +120,58 @@ class UAVCAN_EXPORT DynamicTransferBufferManagerEntry
LinkedListRoot<Block> blocks_; // Blocks are ordered from lower to higher buffer offset
uint16_t max_write_pos_;
const uint16_t max_size_;
/// Reset functionality must be implemented in a non-virtual method to call it safely from the destructor.
void doReset();
virtual void resetImpl();
TransferBufferManagerKey key_;
public:
DynamicTransferBufferManagerEntry(IPoolAllocator& allocator, uint16_t max_size)
: allocator_(allocator)
, max_write_pos_(0)
, max_size_(max_size)
TransferBufferManagerEntry(IPoolAllocator& allocator, uint16_t max_size) :
allocator_(allocator),
max_write_pos_(0),
max_size_(max_size)
{
StaticAssert<(Block::Size > 8)>::check();
IsDynamicallyAllocatable<Block>::check();
IsDynamicallyAllocatable<DynamicTransferBufferManagerEntry>::check();
IsDynamicallyAllocatable<TransferBufferManagerEntry>::check();
}
virtual ~DynamicTransferBufferManagerEntry()
{
doReset();
}
virtual ~TransferBufferManagerEntry() { reset(); }
static DynamicTransferBufferManagerEntry* instantiate(IPoolAllocator& allocator, uint16_t max_size);
static void destroy(DynamicTransferBufferManagerEntry*& obj, IPoolAllocator& allocator);
virtual int read(unsigned offset, uint8_t* data, unsigned len) const;
virtual int write(unsigned offset, const uint8_t* data, unsigned len);
};
/**
* Standalone static buffer
*/
class StaticTransferBufferImpl : public ITransferBuffer
{
uint8_t* const data_;
const uint16_t size_;
uint16_t max_write_pos_;
public:
StaticTransferBufferImpl(uint8_t* buf, uint16_t buf_size)
: data_(buf)
, size_(buf_size)
, max_write_pos_(0)
{ }
static TransferBufferManagerEntry* instantiate(IPoolAllocator& allocator, uint16_t max_size);
static void destroy(TransferBufferManagerEntry*& obj, IPoolAllocator& allocator);
virtual int read(unsigned offset, uint8_t* data, unsigned len) const;
virtual int write(unsigned offset, const uint8_t* data, unsigned len);
void reset();
void reset(const TransferBufferManagerKey& key = TransferBufferManagerKey());
uint16_t getSize() const { return size_; }
uint8_t* getRawPtr() { return data_; }
const uint8_t* getRawPtr() const { return data_; }
uint16_t getMaxWritePos() const { return max_write_pos_; }
void setMaxWritePos(uint16_t value) { max_write_pos_ = value; }
};
template <uint16_t Size>
class UAVCAN_EXPORT StaticTransferBuffer : public StaticTransferBufferImpl
{
uint8_t buffer_[Size];
public:
StaticTransferBuffer()
: StaticTransferBufferImpl(buffer_, Size)
{
StaticAssert<(Size > 0)>::check();
}
const TransferBufferManagerKey& getKey() const { return key_; }
bool isEmpty() const { return key_.isEmpty(); }
};
/**
* Statically allocated storage for the buffer manager
* Buffer manager implementation.
*/
class StaticTransferBufferManagerEntryImpl : public TransferBufferManagerEntry
class TransferBufferManager : public Noncopyable
{
StaticTransferBufferImpl buf_;
LinkedListRoot<TransferBufferManagerEntry> buffers_;
IPoolAllocator& allocator_;
const uint16_t max_buf_size_;
virtual void resetImpl();
TransferBufferManagerEntry* findFirst(const TransferBufferManagerKey& key);
public:
StaticTransferBufferManagerEntryImpl(uint8_t* buf, uint16_t buf_size)
: buf_(buf, buf_size)
TransferBufferManager(uint16_t max_buf_size, IPoolAllocator& allocator) :
allocator_(allocator),
max_buf_size_(max_buf_size)
{ }
virtual int read(unsigned offset, uint8_t* data, unsigned len) const;
virtual int write(unsigned offset, const uint8_t* data, unsigned len);
};
~TransferBufferManager();
template <uint16_t Size>
class UAVCAN_EXPORT StaticTransferBufferManagerEntry : public StaticTransferBufferManagerEntryImpl
{
uint8_t buffer_[Size];
public:
StaticTransferBufferManagerEntry()
: StaticTransferBufferManagerEntryImpl(buffer_, Size)
{ }
};
ITransferBuffer* access(const TransferBufferManagerKey& key);
ITransferBuffer* create(const TransferBufferManagerKey& key);
void remove(const TransferBufferManagerKey& key);
bool isEmpty() const;
/**
* Manages different storage types (static/dynamic) for transfer reception logic.
*/
class UAVCAN_EXPORT ITransferBufferManager
{
public:
virtual ~ITransferBufferManager() { }
virtual ITransferBuffer* access(const TransferBufferManagerKey& key) = 0;
virtual ITransferBuffer* create(const TransferBufferManagerKey& key) = 0;
virtual void remove(const TransferBufferManagerKey& key) = 0;
virtual bool isEmpty() const = 0;
unsigned getNumBuffers() const;
};
/**
@@ -224,13 +179,13 @@ public:
*/
class UAVCAN_EXPORT TransferBufferAccessor
{
ITransferBufferManager& bufmgr_;
TransferBufferManager& bufmgr_;
const TransferBufferManagerKey key_;
public:
TransferBufferAccessor(ITransferBufferManager& bufmgr, TransferBufferManagerKey key)
: bufmgr_(bufmgr)
, key_(key)
TransferBufferAccessor(TransferBufferManager& bufmgr, TransferBufferManagerKey key) :
bufmgr_(bufmgr),
key_(key)
{
UAVCAN_ASSERT(!key.isEmpty());
}
@@ -239,54 +194,6 @@ public:
void remove() { bufmgr_.remove(key_); }
};
/**
* Buffer manager implementation.
*/
class TransferBufferManagerImpl : public ITransferBufferManager, Noncopyable
{
LinkedListRoot<DynamicTransferBufferManagerEntry> dynamic_buffers_;
IPoolAllocator& allocator_;
const uint16_t max_buf_size_;
DynamicTransferBufferManagerEntry* findFirstDynamic(const TransferBufferManagerKey& key);
public:
TransferBufferManagerImpl(uint16_t max_buf_size, IPoolAllocator& allocator)
: allocator_(allocator)
, max_buf_size_(max_buf_size)
{ }
virtual ~TransferBufferManagerImpl();
virtual ITransferBuffer* access(const TransferBufferManagerKey& key);
virtual ITransferBuffer* create(const TransferBufferManagerKey& key);
virtual void remove(const TransferBufferManagerKey& key);
virtual bool isEmpty() const;
unsigned getNumBuffers() const;
};
template <uint16_t MaxBufSize>
class UAVCAN_EXPORT TransferBufferManager : public TransferBufferManagerImpl
{
public:
explicit TransferBufferManager(IPoolAllocator& allocator) :
TransferBufferManagerImpl(MaxBufSize, allocator)
{ }
};
template <>
class UAVCAN_EXPORT TransferBufferManager<0> : public ITransferBufferManager
{
public:
TransferBufferManager() { }
TransferBufferManager(IPoolAllocator&) { }
virtual ITransferBuffer* access(const TransferBufferManagerKey&) { return NULL; }
virtual ITransferBuffer* create(const TransferBufferManagerKey&) { return NULL; }
virtual void remove(const TransferBufferManagerKey&) { }
virtual bool isEmpty() const { return true; }
};
}
#endif // UAVCAN_TRANSPORT_TRANSFER_BUFFER_HPP_INCLUDED
@@ -96,11 +96,11 @@ public:
/**
* Internal, refer to the transport dispatcher class.
*/
class UAVCAN_EXPORT TransferListenerBase : public LinkedListNode<TransferListenerBase>, Noncopyable
class UAVCAN_EXPORT TransferListener : public LinkedListNode<TransferListener>, Noncopyable
{
const DataTypeDescriptor& data_type_;
Map<TransferBufferManagerKey, TransferReceiver>& receivers_;
ITransferBufferManager& bufmgr_;
TransferBufferManager bufmgr_;
Map<TransferBufferManagerKey, TransferReceiver> receivers_;
TransferPerfCounter& perf_;
const TransferCRC crc_base_; ///< Pre-initialized with data type hash, thus constant
bool allow_anonymous_transfers_;
@@ -108,10 +108,10 @@ class UAVCAN_EXPORT TransferListenerBase : public LinkedListNode<TransferListene
class TimedOutReceiverPredicate
{
const MonotonicTime ts_;
ITransferBufferManager& parent_bufmgr_;
TransferBufferManager& parent_bufmgr_;
public:
TimedOutReceiverPredicate(MonotonicTime arg_ts, ITransferBufferManager& arg_bufmgr)
TimedOutReceiverPredicate(MonotonicTime arg_ts, TransferBufferManager& arg_bufmgr)
: ts_(arg_ts)
, parent_bufmgr_(arg_bufmgr)
{ }
@@ -122,25 +122,28 @@ class UAVCAN_EXPORT TransferListenerBase : public LinkedListNode<TransferListene
bool checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const;
protected:
TransferListenerBase(TransferPerfCounter& perf, const DataTypeDescriptor& data_type,
Map<TransferBufferManagerKey, TransferReceiver>& receivers,
ITransferBufferManager& bufmgr)
: data_type_(data_type)
, receivers_(receivers)
, bufmgr_(bufmgr)
, perf_(perf)
, crc_base_(data_type.getSignature().toTransferCRC())
, allow_anonymous_transfers_(false)
{ }
virtual ~TransferListenerBase() { }
void handleReception(TransferReceiver& receiver, const RxFrame& frame, TransferBufferAccessor& tba);
void handleAnonymousTransferReception(const RxFrame& frame);
virtual void handleIncomingTransfer(IncomingTransfer& transfer) = 0;
public:
TransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type,
uint16_t max_buffer_size, IPoolAllocator& allocator)
: data_type_(data_type)
, bufmgr_(max_buffer_size, allocator)
, receivers_(allocator)
, perf_(perf)
, crc_base_(data_type.getSignature().toTransferCRC())
, allow_anonymous_transfers_(false)
{ }
virtual ~TransferListener()
{
// Map must be cleared before bufmgr is destroyed
receivers_.clear();
}
const DataTypeDescriptor& getDataTypeDescriptor() const { return data_type_; }
/**
@@ -154,29 +157,6 @@ public:
virtual void handleFrame(const RxFrame& frame);
};
/**
* This class should be derived by transfer receivers (subscribers, servers).
*/
template <unsigned MaxBufSize>
class UAVCAN_EXPORT TransferListener : public TransferListenerBase
{
TransferBufferManager<MaxBufSize> bufmgr_;
Map<TransferBufferManagerKey, TransferReceiver> receivers_;
public:
TransferListener(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, IPoolAllocator& allocator)
: TransferListenerBase(perf, data_type, receivers_, bufmgr_)
, bufmgr_(allocator)
, receivers_(allocator)
{ }
virtual ~TransferListener()
{
// Map must be cleared before bufmgr is destroyed
receivers_.clear();
}
};
/**
* This class is used by transfer listener to decide if the frame should be accepted or ignored.
*/
@@ -194,19 +174,16 @@ public:
/**
* This class should be derived by callers.
*/
template <unsigned MaxBufSize>
class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener<MaxBufSize>
class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener
{
const ITransferAcceptanceFilter* filter_;
virtual void handleFrame(const RxFrame& frame);
public:
typedef TransferListener<MaxBufSize> BaseType;
TransferListenerWithFilter(TransferPerfCounter& perf, const DataTypeDescriptor& data_type,
IPoolAllocator& allocator)
: BaseType(perf, data_type, allocator)
uint16_t max_buffer_size, IPoolAllocator& allocator)
: TransferListener(perf, data_type, max_buffer_size, allocator)
, filter_(NULL)
{ }
@@ -216,27 +193,6 @@ public:
}
};
// ----------------------------------------------------------------------------
/*
* TransferListenerWithFilter<>
*/
template <unsigned MaxBufSize>
void TransferListenerWithFilter<MaxBufSize>::handleFrame(const RxFrame& frame)
{
if (filter_ != NULL)
{
if (filter_->shouldAcceptFrame(frame))
{
BaseType::handleFrame(frame);
}
}
else
{
UAVCAN_ASSERT(0);
}
}
}
#endif // UAVCAN_TRANSPORT_TRANSFER_LISTENER_HPP_INCLUDED