From a9fdf44fa984343a4efbb8c19fc0b50efb19b108 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Wed, 14 Oct 2015 19:58:51 +0300 Subject: [PATCH] Transfer buffering system detemplatized; compiles but tests are failing --- .../uavcan/node/generic_subscriber.hpp | 49 ++-- .../include/uavcan/node/service_client.hpp | 17 +- .../include/uavcan/node/service_server.hpp | 6 +- libuavcan/include/uavcan/node/subscriber.hpp | 6 +- .../include/uavcan/transport/dispatcher.hpp | 28 +- .../uavcan/transport/transfer_buffer.hpp | 241 ++++++------------ .../uavcan/transport/transfer_listener.hpp | 92 ++----- libuavcan/src/node/uc_generic_subscriber.cpp | 6 +- .../uc_can_acceptance_filter_configurator.cpp | 4 +- libuavcan/src/transport/uc_dispatcher.cpp | 28 +- .../src/transport/uc_transfer_buffer.cpp | 212 +++++++-------- .../src/transport/uc_transfer_listener.cpp | 46 +++- libuavcan/test/transport/dispatcher.cpp | 28 +- .../test/transport/incoming_transfer.cpp | 2 +- libuavcan/test/transport/transfer_buffer.cpp | 23 +- .../test/transport/transfer_listener.cpp | 18 +- .../test/transport/transfer_receiver.cpp | 20 +- libuavcan/test/transport/transfer_sender.cpp | 6 +- .../test/transport/transfer_test_helpers.cpp | 2 +- .../test/transport/transfer_test_helpers.hpp | 11 +- 20 files changed, 335 insertions(+), 510 deletions(-) diff --git a/libuavcan/include/uavcan/node/generic_subscriber.hpp b/libuavcan/include/uavcan/node/generic_subscriber.hpp index eca19c829f..6a61e0b041 100644 --- a/libuavcan/include/uavcan/node/generic_subscriber.hpp +++ b/libuavcan/include/uavcan/node/generic_subscriber.hpp @@ -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 class TransferListenerTemplate = TransferListener - > -class UAVCAN_EXPORT TransferListenerInstantiationHelper -{ - enum { DataTypeMaxByteLen = BitLenToByteLen::Result }; - enum { NeedsBuffer = int(DataTypeMaxByteLen) > int(GuaranteedPayloadLenPerFrame) }; - enum { BufferSize = NeedsBuffer ? DataTypeMaxByteLen : 0 }; - -public: - typedef TransferListenerTemplate 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 { ReceivedDataStructureSpec() { } - ReceivedDataStructureSpec(const IncomingTransfer* arg_transfer) - : ReceivedDataStructure(arg_transfer) + ReceivedDataStructureSpec(const IncomingTransfer* arg_transfer) : + ReceivedDataStructure(arg_transfer) { } }; - explicit GenericSubscriber(INode& node) - : GenericSubscriberBase(node) + explicit GenericSubscriber(INode& node) : GenericSubscriberBase(node) { } virtual ~GenericSubscriber() { stop(); } @@ -247,8 +236,10 @@ int GenericSubscriber::checkInit() return -ErrUnknownDataType; } - forwarder_.template construct - (*this, *descr, node_.getAllocator()); + static const uint16_t MaxBufferSize = BitLenToByteLen::Result; + + forwarder_.template construct + (*this, *descr, MaxBufferSize, node_.getAllocator()); return 0; } @@ -286,7 +277,7 @@ void GenericSubscriber::handleIncomi template int GenericSubscriber:: -genericStart(bool (Dispatcher::*registration_method)(TransferListenerBase*)) +genericStart(bool (Dispatcher::*registration_method)(TransferListener*)) { const int res = checkInit(); if (res < 0) diff --git a/libuavcan/include/uavcan/node/service_client.hpp b/libuavcan/include/uavcan/node/service_client.hpp index a7cce0dd4e..d195dcc721 100644 --- a/libuavcan/include/uavcan/node/service_client.hpp +++ b/libuavcan/include/uavcan/node/service_client.hpp @@ -20,15 +20,6 @@ namespace uavcan { - -template -class UAVCAN_EXPORT ServiceResponseTransferListenerInstantiationHelper -{ -public: - typedef typename TransferListenerInstantiationHelper::Type Type; -}; - /** * This struct describes a pending service call. * Refer to @ref ServiceClient to learn more about service calls. @@ -225,8 +216,7 @@ template class UAVCAN_EXPORT ServiceClient : public GenericSubscriber::Type> + typename DataType_::Response, TransferListenerWithFilter> , public ServiceClientBase { public: @@ -239,8 +229,7 @@ public: private: typedef ServiceClient SelfType; typedef GenericPublisher PublisherType; - typedef typename ServiceResponseTransferListenerInstantiationHelper::Type TransferListenerType; - typedef GenericSubscriber SubscriberType; + typedef GenericSubscriber SubscriberType; typedef Multiset CallRegistry; @@ -537,7 +526,7 @@ int ServiceClient::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 diff --git a/libuavcan/include/uavcan/node/service_server.hpp b/libuavcan/include/uavcan/node/service_server.hpp index d362502800..5b40ad8836 100644 --- a/libuavcan/include/uavcan/node/service_server.hpp +++ b/libuavcan/include/uavcan/node/service_server.hpp @@ -88,8 +88,7 @@ template class UAVCAN_EXPORT ServiceServer - : public GenericSubscriber::Type> + : public GenericSubscriber { public: typedef DataType_ DataType; @@ -98,8 +97,7 @@ public: typedef Callback_ Callback; private: - typedef typename TransferListenerInstantiationHelper::Type TransferListenerType; - typedef GenericSubscriber SubscriberType; + typedef GenericSubscriber SubscriberType; typedef GenericPublisher PublisherType; PublisherType publisher_; diff --git a/libuavcan/include/uavcan/node/subscriber.hpp b/libuavcan/include/uavcan/node/subscriber.hpp index b82233dddd..1ee4c09888 100644 --- a/libuavcan/include/uavcan/node/subscriber.hpp +++ b/libuavcan/include/uavcan/node/subscriber.hpp @@ -43,15 +43,13 @@ template class UAVCAN_EXPORT Subscriber - : public GenericSubscriber::Type> + : public GenericSubscriber { public: typedef Callback_ Callback; private: - typedef typename TransferListenerInstantiationHelper::Type TransferListenerType; - typedef GenericSubscriber BaseType; + typedef GenericSubscriber BaseType; Callback callback_; diff --git a/libuavcan/include/uavcan/transport/dispatcher.hpp b/libuavcan/include/uavcan/transport/dispatcher.hpp index 99cee5b0a8..33ac1f2e5c 100644 --- a/libuavcan/include/uavcan/transport/dispatcher.hpp +++ b/libuavcan/include/uavcan/transport/dispatcher.hpp @@ -86,14 +86,14 @@ class UAVCAN_EXPORT Dispatcher : Noncopyable class ListenerRegistry { - LinkedListRoot list_; + LinkedListRoot 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& getList() const { return list_; } + const LinkedListRoot& 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& getListOfMessageListeners() const + const LinkedListRoot& getListOfMessageListeners() const { return lmsg_.getList(); } - const LinkedListRoot& getListOfServiceRequestListeners() const + const LinkedListRoot& getListOfServiceRequestListeners() const { return lsrv_req_.getList(); } - const LinkedListRoot& getListOfServiceResponseListeners() const + const LinkedListRoot& getListOfServiceResponseListeners() const { return lsrv_resp_.getList(); } diff --git a/libuavcan/include/uavcan/transport/transfer_buffer.hpp b/libuavcan/include/uavcan/transport/transfer_buffer.hpp index 7ea35145be..d4e05fac2f 100644 --- a/libuavcan/include/uavcan/transport/transfer_buffer.hpp +++ b/libuavcan/include/uavcan/transport/transfer_buffer.hpp @@ -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 +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 +class UAVCAN_EXPORT TransferBufferManagerEntry : public ITransferBuffer + , public LinkedListNode { struct Block : LinkedListNode { @@ -107,116 +120,58 @@ class UAVCAN_EXPORT DynamicTransferBufferManagerEntry LinkedListRoot 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::check(); - IsDynamicallyAllocatable::check(); + IsDynamicallyAllocatable::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 -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 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 -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 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 -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 diff --git a/libuavcan/include/uavcan/transport/transfer_listener.hpp b/libuavcan/include/uavcan/transport/transfer_listener.hpp index 181a2e36b1..b6d28d29f0 100644 --- a/libuavcan/include/uavcan/transport/transfer_listener.hpp +++ b/libuavcan/include/uavcan/transport/transfer_listener.hpp @@ -96,11 +96,11 @@ public: /** * Internal, refer to the transport dispatcher class. */ -class UAVCAN_EXPORT TransferListenerBase : public LinkedListNode, Noncopyable +class UAVCAN_EXPORT TransferListener : public LinkedListNode, Noncopyable { const DataTypeDescriptor& data_type_; - Map& receivers_; - ITransferBufferManager& bufmgr_; + TransferBufferManager bufmgr_; + Map 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& 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 -class UAVCAN_EXPORT TransferListener : public TransferListenerBase -{ - TransferBufferManager bufmgr_; - Map 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 -class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener +class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener { const ITransferAcceptanceFilter* filter_; virtual void handleFrame(const RxFrame& frame); public: - typedef TransferListener 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 -void TransferListenerWithFilter::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 diff --git a/libuavcan/src/node/uc_generic_subscriber.cpp b/libuavcan/src/node/uc_generic_subscriber.cpp index 4ec626cd10..f77cda77b9 100644 --- a/libuavcan/src/node/uc_generic_subscriber.cpp +++ b/libuavcan/src/node/uc_generic_subscriber.cpp @@ -7,8 +7,8 @@ namespace uavcan { -int GenericSubscriberBase::genericStart(TransferListenerBase* listener, - bool (Dispatcher::*registration_method)(TransferListenerBase*)) +int GenericSubscriberBase::genericStart(TransferListener* listener, + bool (Dispatcher::*registration_method)(TransferListener*)) { if (listener == NULL) { @@ -24,7 +24,7 @@ int GenericSubscriberBase::genericStart(TransferListenerBase* listener, return 0; } -void GenericSubscriberBase::stop(TransferListenerBase* listener) +void GenericSubscriberBase::stop(TransferListener* listener) { if (listener != NULL) { diff --git a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp index f82b6a57d0..820c0b22d2 100644 --- a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp +++ b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp @@ -38,8 +38,8 @@ int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration(AnonymousMessage return -ErrMemory; } - const TransferListenerBase* p = node_.getDispatcher().getListOfMessageListeners().get(); - while (p) + const TransferListener* p = node_.getDispatcher().getListOfMessageListeners().get(); + while (p != NULL) { CanFilterConfig cfg; cfg.id = static_cast(p->getDataTypeDescriptor().getID().get()) << 8; diff --git a/libuavcan/src/transport/uc_dispatcher.cpp b/libuavcan/src/transport/uc_dispatcher.cpp index 8e91437f81..0349862ca9 100644 --- a/libuavcan/src/transport/uc_dispatcher.cpp +++ b/libuavcan/src/transport/uc_dispatcher.cpp @@ -72,11 +72,11 @@ void LoopbackFrameListenerRegistry::invokeListeners(RxFrame& frame) /* * Dispatcher::ListenerRegister */ -bool Dispatcher::ListenerRegistry::add(TransferListenerBase* listener, Mode mode) +bool Dispatcher::ListenerRegistry::add(TransferListener* listener, Mode mode) { if (mode == UniqueListener) { - TransferListenerBase* p = list_.get(); + TransferListener* p = list_.get(); while (p) { if (p->getDataTypeDescriptor().getID() == listener->getDataTypeDescriptor().getID()) @@ -91,14 +91,14 @@ bool Dispatcher::ListenerRegistry::add(TransferListenerBase* listener, Mode mode return true; } -void Dispatcher::ListenerRegistry::remove(TransferListenerBase* listener) +void Dispatcher::ListenerRegistry::remove(TransferListener* listener) { list_.remove(listener); } bool Dispatcher::ListenerRegistry::exists(DataTypeID dtid) const { - TransferListenerBase* p = list_.get(); + TransferListener* p = list_.get(); while (p) { if (p->getDataTypeDescriptor().getID() == dtid) @@ -112,10 +112,10 @@ bool Dispatcher::ListenerRegistry::exists(DataTypeID dtid) const void Dispatcher::ListenerRegistry::cleanup(MonotonicTime ts) { - TransferListenerBase* p = list_.get(); + TransferListener* p = list_.get(); while (p) { - TransferListenerBase* const next = p->getNextListNode(); + TransferListener* const next = p->getNextListNode(); p->cleanup(ts); // p may be modified p = next; } @@ -123,10 +123,10 @@ void Dispatcher::ListenerRegistry::cleanup(MonotonicTime ts) void Dispatcher::ListenerRegistry::handleFrame(const RxFrame& frame) { - TransferListenerBase* p = list_.get(); + TransferListener* p = list_.get(); while (p) { - TransferListenerBase* const next = p->getNextListNode(); + TransferListener* const next = p->getNextListNode(); if (p->getDataTypeDescriptor().getID() == frame.getDataTypeID()) { p->handleFrame(frame); // p may be modified @@ -311,7 +311,7 @@ void Dispatcher::cleanup(MonotonicTime ts) lsrv_resp_.cleanup(ts); } -bool Dispatcher::registerMessageListener(TransferListenerBase* listener) +bool Dispatcher::registerMessageListener(TransferListener* listener) { if (listener->getDataTypeDescriptor().getKind() != DataTypeKindMessage) { @@ -321,7 +321,7 @@ bool Dispatcher::registerMessageListener(TransferListenerBase* listener) return lmsg_.add(listener, ListenerRegistry::ManyListeners); // Multiple subscribers are OK } -bool Dispatcher::registerServiceRequestListener(TransferListenerBase* listener) +bool Dispatcher::registerServiceRequestListener(TransferListener* listener) { if (listener->getDataTypeDescriptor().getKind() != DataTypeKindService) { @@ -331,7 +331,7 @@ bool Dispatcher::registerServiceRequestListener(TransferListenerBase* listener) return lsrv_req_.add(listener, ListenerRegistry::UniqueListener); // Only one server per data type } -bool Dispatcher::registerServiceResponseListener(TransferListenerBase* listener) +bool Dispatcher::registerServiceResponseListener(TransferListener* listener) { if (listener->getDataTypeDescriptor().getKind() != DataTypeKindService) { @@ -341,17 +341,17 @@ bool Dispatcher::registerServiceResponseListener(TransferListenerBase* listener) return lsrv_resp_.add(listener, ListenerRegistry::ManyListeners); // Multiple callers may call same srv } -void Dispatcher::unregisterMessageListener(TransferListenerBase* listener) +void Dispatcher::unregisterMessageListener(TransferListener* listener) { lmsg_.remove(listener); } -void Dispatcher::unregisterServiceRequestListener(TransferListenerBase* listener) +void Dispatcher::unregisterServiceRequestListener(TransferListener* listener) { lsrv_req_.remove(listener); } -void Dispatcher::unregisterServiceResponseListener(TransferListenerBase* listener) +void Dispatcher::unregisterServiceResponseListener(TransferListener* listener) { lsrv_resp_.remove(listener); } diff --git a/libuavcan/src/transport/uc_transfer_buffer.cpp b/libuavcan/src/transport/uc_transfer_buffer.cpp index f684d8ecd7..f30c9da675 100644 --- a/libuavcan/src/transport/uc_transfer_buffer.cpp +++ b/libuavcan/src/transport/uc_transfer_buffer.cpp @@ -8,6 +8,58 @@ namespace uavcan { +/* + * StaticTransferBufferImpl + */ +int StaticTransferBufferImpl::read(unsigned offset, uint8_t* data, unsigned len) const +{ + if (!data) + { + UAVCAN_ASSERT(0); + return -ErrInvalidParam; + } + if (offset >= max_write_pos_) + { + return 0; + } + if ((offset + len) > max_write_pos_) + { + len = max_write_pos_ - offset; + } + UAVCAN_ASSERT((offset + len) <= max_write_pos_); + (void)copy(data_ + offset, data_ + offset + len, data); + return int(len); +} + +int StaticTransferBufferImpl::write(unsigned offset, const uint8_t* data, unsigned len) +{ + if (!data) + { + UAVCAN_ASSERT(0); + return -ErrInvalidParam; + } + if (offset >= size_) + { + return 0; + } + if ((offset + len) > size_) + { + len = size_ - offset; + } + UAVCAN_ASSERT((offset + len) <= size_); + (void)copy(data, data + len, data_ + offset); + max_write_pos_ = max(uint16_t(offset + len), uint16_t(max_write_pos_)); + return int(len); +} + +void StaticTransferBufferImpl::reset() +{ + max_write_pos_ = 0; +#if UAVCAN_DEBUG + fill(data_, data_ + size_, uint8_t(0)); +#endif +} + /* * TransferBufferManagerKey */ @@ -23,8 +75,8 @@ std::string TransferBufferManagerKey::toString() const /* * DynamicTransferBuffer::Block */ -DynamicTransferBufferManagerEntry::Block* -DynamicTransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator) +TransferBufferManagerEntry::Block* +TransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator) { void* const praw = allocator.allocate(sizeof(Block)); if (praw == NULL) @@ -34,7 +86,7 @@ DynamicTransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator) return new (praw) Block; } -void DynamicTransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocator& allocator) +void TransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocator& allocator) { if (obj != NULL) { @@ -44,8 +96,8 @@ void DynamicTransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocat } } -void DynamicTransferBufferManagerEntry::Block::read(uint8_t*& outptr, unsigned target_offset, - unsigned& total_offset, unsigned& left_to_read) +void TransferBufferManagerEntry::Block::read(uint8_t*& outptr, unsigned target_offset, + unsigned& total_offset, unsigned& left_to_read) { UAVCAN_ASSERT(outptr); for (unsigned i = 0; (i < Block::Size) && (left_to_read > 0); i++, total_offset++) @@ -58,7 +110,7 @@ void DynamicTransferBufferManagerEntry::Block::read(uint8_t*& outptr, unsigned t } } -void DynamicTransferBufferManagerEntry::Block::write(const uint8_t*& inptr, unsigned target_offset, +void TransferBufferManagerEntry::Block::write(const uint8_t*& inptr, unsigned target_offset, unsigned& total_offset, unsigned& left_to_write) { UAVCAN_ASSERT(inptr); @@ -75,46 +127,28 @@ void DynamicTransferBufferManagerEntry::Block::write(const uint8_t*& inptr, unsi /* * DynamicTransferBuffer */ -DynamicTransferBufferManagerEntry* DynamicTransferBufferManagerEntry::instantiate(IPoolAllocator& allocator, +TransferBufferManagerEntry* TransferBufferManagerEntry::instantiate(IPoolAllocator& allocator, uint16_t max_size) { - void* const praw = allocator.allocate(sizeof(DynamicTransferBufferManagerEntry)); + void* const praw = allocator.allocate(sizeof(TransferBufferManagerEntry)); if (praw == NULL) { return NULL; } - return new (praw) DynamicTransferBufferManagerEntry(allocator, max_size); + return new (praw) TransferBufferManagerEntry(allocator, max_size); } -void DynamicTransferBufferManagerEntry::destroy(DynamicTransferBufferManagerEntry*& obj, IPoolAllocator& allocator) +void TransferBufferManagerEntry::destroy(TransferBufferManagerEntry*& obj, IPoolAllocator& allocator) { if (obj != NULL) { - obj->~DynamicTransferBufferManagerEntry(); + obj->~TransferBufferManagerEntry(); allocator.deallocate(obj); obj = NULL; } } -void DynamicTransferBufferManagerEntry::doReset() -{ - max_write_pos_ = 0; - Block* p = blocks_.get(); - while (p) - { - Block* const next = p->getNextListNode(); - blocks_.remove(p); - Block::destroy(p, allocator_); - p = next; - } -} - -void DynamicTransferBufferManagerEntry::resetImpl() -{ - doReset(); -} - -int DynamicTransferBufferManagerEntry::read(unsigned offset, uint8_t* data, unsigned len) const +int TransferBufferManagerEntry::read(unsigned offset, uint8_t* data, unsigned len) const { if (!data) { @@ -150,7 +184,7 @@ int DynamicTransferBufferManagerEntry::read(unsigned offset, uint8_t* data, unsi return int(len); } -int DynamicTransferBufferManagerEntry::write(unsigned offset, const uint8_t* data, unsigned len) +int TransferBufferManagerEntry::write(unsigned offset, const uint8_t* data, unsigned len) { if (!data) { @@ -221,82 +255,26 @@ int DynamicTransferBufferManagerEntry::write(unsigned offset, const uint8_t* dat return int(actually_written); } -/* - * StaticTransferBufferImpl - */ -int StaticTransferBufferImpl::read(unsigned offset, uint8_t* data, unsigned len) const -{ - if (!data) - { - UAVCAN_ASSERT(0); - return -ErrInvalidParam; - } - if (offset >= max_write_pos_) - { - return 0; - } - if ((offset + len) > max_write_pos_) - { - len = max_write_pos_ - offset; - } - UAVCAN_ASSERT((offset + len) <= max_write_pos_); - (void)copy(data_ + offset, data_ + offset + len, data); - return int(len); -} - -int StaticTransferBufferImpl::write(unsigned offset, const uint8_t* data, unsigned len) -{ - if (!data) - { - UAVCAN_ASSERT(0); - return -ErrInvalidParam; - } - if (offset >= size_) - { - return 0; - } - if ((offset + len) > size_) - { - len = size_ - offset; - } - UAVCAN_ASSERT((offset + len) <= size_); - (void)copy(data, data + len, data_ + offset); - max_write_pos_ = max(uint16_t(offset + len), uint16_t(max_write_pos_)); - return int(len); -} - -void StaticTransferBufferImpl::reset() +void TransferBufferManagerEntry::reset(const TransferBufferManagerKey& key) { + key_ = key; max_write_pos_ = 0; -#if UAVCAN_DEBUG - fill(data_, data_ + size_, uint8_t(0)); -#endif + Block* p = blocks_.get(); + while (p) + { + Block* const next = p->getNextListNode(); + blocks_.remove(p); + Block::destroy(p, allocator_); + p = next; + } } /* - * StaticTransferBufferManagerEntryImpl + * TransferBufferManager */ -void StaticTransferBufferManagerEntryImpl::resetImpl() +TransferBufferManagerEntry* TransferBufferManager::findFirst(const TransferBufferManagerKey& key) { - buf_.reset(); -} - -int StaticTransferBufferManagerEntryImpl::read(unsigned offset, uint8_t* data, unsigned len) const -{ - return buf_.read(offset, data, len); -} - -int StaticTransferBufferManagerEntryImpl::write(unsigned offset, const uint8_t* data, unsigned len) -{ - return buf_.write(offset, data, len); -} - -/* - * TransferBufferManagerImpl - */ -DynamicTransferBufferManagerEntry* TransferBufferManagerImpl::findFirstDynamic(const TransferBufferManagerKey& key) -{ - DynamicTransferBufferManagerEntry* dyn = dynamic_buffers_.get(); + TransferBufferManagerEntry* dyn = buffers_.get(); while (dyn) { UAVCAN_ASSERT(!dyn->isEmpty()); @@ -309,29 +287,29 @@ DynamicTransferBufferManagerEntry* TransferBufferManagerImpl::findFirstDynamic(c return NULL; } -TransferBufferManagerImpl::~TransferBufferManagerImpl() +TransferBufferManager::~TransferBufferManager() { - DynamicTransferBufferManagerEntry* dyn = dynamic_buffers_.get(); + TransferBufferManagerEntry* dyn = buffers_.get(); while (dyn) { - DynamicTransferBufferManagerEntry* const next = dyn->getNextListNode(); - dynamic_buffers_.remove(dyn); - DynamicTransferBufferManagerEntry::destroy(dyn, allocator_); + TransferBufferManagerEntry* const next = dyn->getNextListNode(); + buffers_.remove(dyn); + TransferBufferManagerEntry::destroy(dyn, allocator_); dyn = next; } } -ITransferBuffer* TransferBufferManagerImpl::access(const TransferBufferManagerKey& key) +ITransferBuffer* TransferBufferManager::access(const TransferBufferManagerKey& key) { if (key.isEmpty()) { UAVCAN_ASSERT(0); return NULL; } - return findFirstDynamic(key); + return findFirst(key); } -ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKey& key) +ITransferBuffer* TransferBufferManager::create(const TransferBufferManagerKey& key) { if (key.isEmpty()) { @@ -340,13 +318,13 @@ ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKe } remove(key); - DynamicTransferBufferManagerEntry* tbme = DynamicTransferBufferManagerEntry::instantiate(allocator_, max_buf_size_); + TransferBufferManagerEntry* tbme = TransferBufferManagerEntry::instantiate(allocator_, max_buf_size_); if (tbme == NULL) { return NULL; // Epic fail. } - dynamic_buffers_.insert(tbme); + buffers_.insert(tbme); UAVCAN_TRACE("TransferBufferManager", "Buffer created [num=%u], %s", getNumBuffers(), key.toString().c_str()); @@ -358,27 +336,27 @@ ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKe return tbme; } -void TransferBufferManagerImpl::remove(const TransferBufferManagerKey& key) +void TransferBufferManager::remove(const TransferBufferManagerKey& key) { UAVCAN_ASSERT(!key.isEmpty()); - DynamicTransferBufferManagerEntry* dyn = findFirstDynamic(key); + TransferBufferManagerEntry* dyn = findFirst(key); if (dyn != NULL) { UAVCAN_TRACE("TransferBufferManager", "Buffer deleted, %s", key.toString().c_str()); - dynamic_buffers_.remove(dyn); - DynamicTransferBufferManagerEntry::destroy(dyn, allocator_); + buffers_.remove(dyn); + TransferBufferManagerEntry::destroy(dyn, allocator_); } } -bool TransferBufferManagerImpl::isEmpty() const +bool TransferBufferManager::isEmpty() const { return getNumBuffers() == 0; } -unsigned TransferBufferManagerImpl::getNumBuffers() const +unsigned TransferBufferManager::getNumBuffers() const { - return dynamic_buffers_.getLength(); + return buffers_.getLength(); } } diff --git a/libuavcan/src/transport/uc_transfer_listener.cpp b/libuavcan/src/transport/uc_transfer_listener.cpp index 59ed97dc5c..064f5dae9b 100644 --- a/libuavcan/src/transport/uc_transfer_listener.cpp +++ b/libuavcan/src/transport/uc_transfer_listener.cpp @@ -80,10 +80,10 @@ int MultiFrameIncomingTransfer::read(unsigned offset, uint8_t* data, unsigned le } /* - * TransferListenerBase::TimedOutReceiverPredicate + * TransferListener::TimedOutReceiverPredicate */ -bool TransferListenerBase::TimedOutReceiverPredicate::operator()(const TransferBufferManagerKey& key, - const TransferReceiver& value) const +bool TransferListener::TimedOutReceiverPredicate::operator()(const TransferBufferManagerKey& key, + const TransferReceiver& value) const { if (value.isTimedOut(ts_)) { @@ -101,9 +101,9 @@ bool TransferListenerBase::TimedOutReceiverPredicate::operator()(const TransferB } /* - * TransferListenerBase + * TransferListener */ -bool TransferListenerBase::checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const +bool TransferListener::checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const { TransferCRC crc = crc_base_; unsigned offset = 0; @@ -113,7 +113,7 @@ bool TransferListenerBase::checkPayloadCrc(const uint16_t compare_with, const IT const int res = tbb.read(offset, buf, sizeof(buf)); if (res < 0) { - UAVCAN_TRACE("TransferListenerBase", "Failed to check CRC: Buffer read failure %i", res); + UAVCAN_TRACE("TransferListener", "Failed to check CRC: Buffer read failure %i", res); return false; } if (res == 0) @@ -125,14 +125,14 @@ bool TransferListenerBase::checkPayloadCrc(const uint16_t compare_with, const IT } if (crc.get() != compare_with) { - UAVCAN_TRACE("TransferListenerBase", "CRC mismatch, expected=0x%04x, got=0x%04x", + UAVCAN_TRACE("TransferListener", "CRC mismatch, expected=0x%04x, got=0x%04x", int(compare_with), int(crc.get())); return false; } return true; } -void TransferListenerBase::handleReception(TransferReceiver& receiver, const RxFrame& frame, +void TransferListener::handleReception(TransferReceiver& receiver, const RxFrame& frame, TransferBufferAccessor& tba) { switch (receiver.addFrame(frame, tba)) @@ -155,12 +155,12 @@ void TransferListenerBase::handleReception(TransferReceiver& receiver, const RxF const ITransferBuffer* tbb = tba.access(); if (tbb == NULL) { - UAVCAN_TRACE("TransferListenerBase", "Buffer access failure, last frame: %s", frame.toString().c_str()); + UAVCAN_TRACE("TransferListener", "Buffer access failure, last frame: %s", frame.toString().c_str()); break; } if (!checkPayloadCrc(receiver.getLastTransferCrc(), *tbb)) { - UAVCAN_TRACE("TransferListenerBase", "CRC error, last frame: %s", frame.toString().c_str()); + UAVCAN_TRACE("TransferListener", "CRC error, last frame: %s", frame.toString().c_str()); break; } MultiFrameIncomingTransfer it(receiver.getLastTransferTimestampMonotonic(), @@ -177,7 +177,7 @@ void TransferListenerBase::handleReception(TransferReceiver& receiver, const RxF } } -void TransferListenerBase::handleAnonymousTransferReception(const RxFrame& frame) +void TransferListener::handleAnonymousTransferReception(const RxFrame& frame) { if (allow_anonymous_transfers_) { @@ -187,13 +187,13 @@ void TransferListenerBase::handleAnonymousTransferReception(const RxFrame& frame } } -void TransferListenerBase::cleanup(MonotonicTime ts) +void TransferListener::cleanup(MonotonicTime ts) { receivers_.removeAllWhere(TimedOutReceiverPredicate(ts, bufmgr_)); UAVCAN_ASSERT(receivers_.isEmpty() ? bufmgr_.isEmpty() : 1); } -void TransferListenerBase::handleFrame(const RxFrame& frame) +void TransferListener::handleFrame(const RxFrame& frame) { if (frame.getSrcNodeID().isUnicast()) // Normal transfer { @@ -227,7 +227,25 @@ void TransferListenerBase::handleFrame(const RxFrame& frame) } else { - UAVCAN_TRACE("TransferListenerBase", "Invalid frame: %s", frame.toString().c_str()); // Invalid frame + UAVCAN_TRACE("TransferListener", "Invalid frame: %s", frame.toString().c_str()); // Invalid frame + } +} + +/* + * TransferListenerWithFilter + */ +void TransferListenerWithFilter::handleFrame(const RxFrame& frame) +{ + if (filter_ != NULL) + { + if (filter_->shouldAcceptFrame(frame)) + { + TransferListener::handleFrame(frame); + } + } + else + { + UAVCAN_ASSERT(0); } } diff --git a/libuavcan/test/transport/dispatcher.cpp b/libuavcan/test/transport/dispatcher.cpp index b33ace4931..65724864ae 100644 --- a/libuavcan/test/transport/dispatcher.cpp +++ b/libuavcan/test/transport/dispatcher.cpp @@ -86,17 +86,17 @@ TEST(Dispatcher, Reception) makeDataType(uavcan::DataTypeKindService, 1) }; - typedef TestListener<512> Subscriber; - typedef std::auto_ptr SubscriberPtr; - static const int NUM_SUBSCRIBERS = 6; - SubscriberPtr subscribers[NUM_SUBSCRIBERS] = + typedef std::auto_ptr TestListenerPtr; + static const int MaxBufSize = 512; + static const int NumSubscribers = 6; + TestListenerPtr subscribers[NumSubscribers] = { - SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[0], pool)), // msg - SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[0], pool)), // msg // Two similar - SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[1], pool)), // msg - SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[2], pool)), // srv - SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[3], pool)), // srv - SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[3], pool)) // srv // Repeat again + TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[0], MaxBufSize, pool)), // msg + TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[0], MaxBufSize, pool)), // msg // Two similar + TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[1], MaxBufSize, pool)), // msg + TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[2], MaxBufSize, pool)), // srv + TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[3], MaxBufSize, pool)), // srv + TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[3], MaxBufSize, pool)) // srv // Repeat again }; static const std::string DATA[6] = @@ -139,7 +139,7 @@ TEST(Dispatcher, Reception) /* * Registration */ - for (int i = 0; i < NUM_SUBSCRIBERS; i++) + for (int i = 0; i < NumSubscribers; i++) { ASSERT_FALSE(dispatcher.hasSubscriber(subscribers[i]->getDataTypeDescriptor().getID())); ASSERT_FALSE(dispatcher.hasPublisher(subscribers[i]->getDataTypeDescriptor().getID())); @@ -153,7 +153,7 @@ TEST(Dispatcher, Reception) ASSERT_TRUE(dispatcher.registerServiceResponseListener(subscribers[4].get())); ASSERT_TRUE(dispatcher.registerServiceResponseListener(subscribers[5].get())); - for (int i = 0; i < NUM_SUBSCRIBERS; i++) + for (int i = 0; i < NumSubscribers; i++) { ASSERT_FALSE(dispatcher.hasPublisher(subscribers[i]->getDataTypeDescriptor().getID())); } @@ -177,7 +177,7 @@ TEST(Dispatcher, Reception) ASSERT_EQ(1, dispatcher.getNumServiceRequestListeners()); ASSERT_EQ(2, dispatcher.getNumServiceResponseListeners()); - for (int i = 0; i < NUM_SUBSCRIBERS; i++) + for (int i = 0; i < NumSubscribers; i++) { ASSERT_TRUE(subscribers[i]->isEmpty()); } @@ -214,7 +214,7 @@ TEST(Dispatcher, Reception) ASSERT_TRUE(subscribers[5]->matchAndPop(transfers[3])); - for (int i = 0; i < NUM_SUBSCRIBERS; i++) + for (int i = 0; i < NumSubscribers; i++) { ASSERT_TRUE(subscribers[i]->isEmpty()); } diff --git a/libuavcan/test/transport/incoming_transfer.cpp b/libuavcan/test/transport/incoming_transfer.cpp index 735d0027b6..3e1f55bc58 100644 --- a/libuavcan/test/transport/incoming_transfer.cpp +++ b/libuavcan/test/transport/incoming_transfer.cpp @@ -73,7 +73,7 @@ TEST(MultiFrameIncomingTransfer, Basic) using uavcan::MultiFrameIncomingTransfer; uavcan::PoolAllocator poolmgr; - uavcan::TransferBufferManager<256> bufmgr(poolmgr); + uavcan::TransferBufferManager bufmgr(256, poolmgr); const RxFrame frame = makeFrame(); uavcan::TransferBufferManagerKey bufmgr_key(frame.getSrcNodeID(), frame.getTransferType()); diff --git a/libuavcan/test/transport/transfer_buffer.cpp b/libuavcan/test/transport/transfer_buffer.cpp index 27d798e6fc..e3baf42f64 100644 --- a/libuavcan/test/transport/transfer_buffer.cpp +++ b/libuavcan/test/transport/transfer_buffer.cpp @@ -83,8 +83,8 @@ static const int TEST_BUFFER_SIZE = 200; TEST(StaticTransferBuffer, Basic) { - using uavcan::StaticTransferBufferManagerEntry; - StaticTransferBufferManagerEntry buf; + using uavcan::StaticTransferBuffer; + StaticTransferBuffer buf; uint8_t local_buffer[TEST_BUFFER_SIZE * 2]; const uint8_t* const test_data_ptr = reinterpret_cast(TEST_DATA.c_str()); @@ -126,15 +126,15 @@ TEST(StaticTransferBuffer, Basic) } -TEST(DynamicTransferBufferManagerEntry, Basic) +TEST(TransferBufferManagerEntry, Basic) { - using uavcan::DynamicTransferBufferManagerEntry; + using uavcan::TransferBufferManagerEntry; static const int MAX_SIZE = TEST_BUFFER_SIZE; static const int POOL_BLOCKS = 8; uavcan::PoolAllocator pool; - DynamicTransferBufferManagerEntry buf(pool, MAX_SIZE); + TransferBufferManagerEntry buf(pool, MAX_SIZE); uint8_t local_buffer[TEST_BUFFER_SIZE * 2]; const uint8_t* const test_data_ptr = reinterpret_cast(TEST_DATA.c_str()); @@ -186,7 +186,7 @@ TEST(DynamicTransferBufferManagerEntry, Basic) // Destroying the object; memory should be released ASSERT_LT(0, pool.getNumUsedBlocks()); - buf.~DynamicTransferBufferManagerEntry(); + buf.~TransferBufferManagerEntry(); ASSERT_EQ(0, pool.getNumUsedBlocks()); } @@ -232,8 +232,7 @@ TEST(TransferBufferManager, Basic) static const int POOL_BLOCKS = 100; uavcan::PoolAllocator pool; - typedef TransferBufferManager TransferBufferManagerType; - std::auto_ptr mgr(new TransferBufferManagerType(pool)); + std::auto_ptr mgr(new TransferBufferManager(MGR_MAX_BUFFER_SIZE, pool)); // Empty ASSERT_FALSE(mgr->access(TransferBufferManagerKey(0, uavcan::TransferTypeMessageBroadcast))); @@ -313,11 +312,3 @@ TEST(TransferBufferManager, Basic) mgr.reset(); ASSERT_EQ(0, pool.getNumUsedBlocks()); } - - -TEST(TransferBufferManager, EmptySpecialization) -{ - uavcan::TransferBufferManager<0> mgr; - (void)mgr; - ASSERT_GE(sizeof(void*), sizeof(mgr)); -} diff --git a/libuavcan/test/transport/transfer_listener.cpp b/libuavcan/test/transport/transfer_listener.cpp index a4ea34b2b0..cf3806c7f0 100644 --- a/libuavcan/test/transport/transfer_listener.cpp +++ b/libuavcan/test/transport/transfer_listener.cpp @@ -9,11 +9,11 @@ class TransferListenerEmulator : public IncomingTransferEmulatorBase { - uavcan::TransferListenerBase& target_; + uavcan::TransferListener& target_; const uavcan::DataTypeDescriptor data_type_; public: - TransferListenerEmulator(uavcan::TransferListenerBase& target, const uavcan::DataTypeDescriptor& type, + TransferListenerEmulator(uavcan::TransferListener& target, const uavcan::DataTypeDescriptor& type, uavcan::NodeID dst_node_id = 127) : IncomingTransferEmulatorBase(dst_node_id) , target_(target) @@ -38,7 +38,7 @@ TEST(TransferListener, BasicMFT) uavcan::PoolAllocator pool; uavcan::TransferPerfCounter perf; - TestListener<256> subscriber(perf, type, pool); + TestListener subscriber(perf, type, 256, pool); /* * Test data @@ -96,7 +96,7 @@ TEST(TransferListener, CrcFailure) static const int NUM_POOL_BLOCKS = 100; uavcan::PoolAllocator poolmgr; uavcan::TransferPerfCounter perf; - TestListener<256> subscriber(perf, type, poolmgr); // Static buffer only, 2 entries + TestListener subscriber(perf, type, 256, poolmgr); // Static buffer only, 2 entries /* * Generating transfers with damaged payload (CRC is not valid) @@ -140,7 +140,7 @@ TEST(TransferListener, BasicSFT) static const int NUM_POOL_BLOCKS = 100; uavcan::PoolAllocator poolmgr; uavcan::TransferPerfCounter perf; - TestListener<0> subscriber(perf, type, poolmgr); // Max buf size is 0, i.e. SFT-only + TestListener subscriber(perf, type, 0, poolmgr); // Max buf size is 0, i.e. SFT-only TransferListenerEmulator emulator(subscriber, type); const Transfer transfers[] = @@ -176,7 +176,7 @@ TEST(TransferListener, Cleanup) static const int NUM_POOL_BLOCKS = 100; uavcan::PoolAllocator poolmgr; uavcan::TransferPerfCounter perf; - TestListener<256> subscriber(perf, type, poolmgr); // Static buffer only, 1 entry + TestListener subscriber(perf, type, 256, poolmgr); /* * Generating transfers @@ -208,7 +208,7 @@ TEST(TransferListener, Cleanup) /* * Cleanup with huge timestamp value will remove all entries */ - static_cast(subscriber).cleanup(tsMono(100000000)); + static_cast(subscriber).cleanup(tsMono(100000000)); /* * Sending the same transfers again - they will be accepted since registres were cleared @@ -232,7 +232,7 @@ TEST(TransferListener, AnonymousTransfers) static const int NUM_POOL_BLOCKS = 100; uavcan::PoolAllocator poolmgr; uavcan::TransferPerfCounter perf; - TestListener<0> subscriber(perf, type, poolmgr); + TestListener subscriber(perf, type, 0, poolmgr); TransferListenerEmulator emulator(subscriber, type); const Transfer transfers[] = @@ -264,5 +264,5 @@ TEST(TransferListener, Sizes) { using namespace uavcan; - std::cout << "sizeof(TransferListener<64>): " << sizeof(TransferListener<64>) << std::endl; + std::cout << "sizeof(TransferListener): " << sizeof(TransferListener) << std::endl; } diff --git a/libuavcan/test/transport/transfer_receiver.cpp b/libuavcan/test/transport/transfer_receiver.cpp index 878a41a70f..dd7e85d1d2 100644 --- a/libuavcan/test/transport/transfer_receiver.cpp +++ b/libuavcan/test/transport/transfer_receiver.cpp @@ -76,10 +76,10 @@ struct Context { uavcan::PoolAllocator pool; uavcan::TransferReceiver receiver; // Must be default constructible and copyable - uavcan::TransferBufferManager bufmgr; + uavcan::TransferBufferManager bufmgr; Context() : - bufmgr(pool) + bufmgr(BufSize, pool) { } ~Context() @@ -122,7 +122,7 @@ TEST(TransferReceiver, Basic) Context<32> context; RxFrameGenerator gen(789); uavcan::TransferReceiver& rcv = context.receiver; - uavcan::ITransferBufferManager& bufmgr = context.bufmgr; + uavcan::TransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); std::cout << "sizeof(TransferReceiver): " << sizeof(TransferReceiver) << std::endl; @@ -261,7 +261,7 @@ TEST(TransferReceiver, OutOfBufferSpace_32bytes) Context<32> context; RxFrameGenerator gen(789); uavcan::TransferReceiver& rcv = context.receiver; - uavcan::ITransferBufferManager& bufmgr = context.bufmgr; + uavcan::TransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); /* @@ -299,7 +299,7 @@ TEST(TransferReceiver, OutOfOrderFrames) Context<32> context; RxFrameGenerator gen(789); uavcan::TransferReceiver& rcv = context.receiver; - uavcan::ITransferBufferManager& bufmgr = context.bufmgr; + uavcan::TransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 7, 100000000), bk)); @@ -323,7 +323,7 @@ TEST(TransferReceiver, IntervalMeasurement) Context<32> context; RxFrameGenerator gen(789); uavcan::TransferReceiver& rcv = context.receiver; - uavcan::ITransferBufferManager& bufmgr = context.bufmgr; + uavcan::TransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); static const int INTERVAL = 1000; @@ -353,7 +353,7 @@ TEST(TransferReceiver, Restart) Context<32> context; RxFrameGenerator gen(789); uavcan::TransferReceiver& rcv = context.receiver; - uavcan::ITransferBufferManager& bufmgr = context.bufmgr; + uavcan::TransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); /* @@ -401,7 +401,7 @@ TEST(TransferReceiver, UtcTransferTimestamping) Context<32> context; RxFrameGenerator gen(789); uavcan::TransferReceiver& rcv = context.receiver; - uavcan::ITransferBufferManager& bufmgr = context.bufmgr; + uavcan::TransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); /* @@ -460,7 +460,7 @@ TEST(TransferReceiver, HeaderParsing) Context<32> context; RxFrameGenerator gen(123); uavcan::TransferReceiver& rcv = context.receiver; - uavcan::ITransferBufferManager& bufmgr = context.bufmgr; + uavcan::TransferBufferManager& bufmgr = context.bufmgr; /* * MFT, message broadcasting @@ -507,7 +507,7 @@ TEST(TransferReceiver, HeaderParsing) Context<32> context; RxFrameGenerator gen(123); uavcan::TransferReceiver& rcv = context.receiver; - uavcan::ITransferBufferManager& bufmgr = context.bufmgr; + uavcan::TransferBufferManager& bufmgr = context.bufmgr; static const uavcan::TransferType ADDRESSED_TRANSFER_TYPES[2] = { diff --git a/libuavcan/test/transport/transfer_sender.cpp b/libuavcan/test/transport/transfer_sender.cpp index ff5595e19a..a156b3039e 100644 --- a/libuavcan/test/transport/transfer_sender.cpp +++ b/libuavcan/test/transport/transfer_sender.cpp @@ -123,9 +123,9 @@ TEST(TransferSender, Basic) } } - TestListener<512> sub_msg(dispatcher_rx.getTransferPerfCounter(), TYPES[0], poolmgr); - TestListener<512> sub_srv_req(dispatcher_rx.getTransferPerfCounter(), TYPES[1], poolmgr); - TestListener<512> sub_srv_resp(dispatcher_rx.getTransferPerfCounter(), TYPES[1], poolmgr); + TestListener sub_msg(dispatcher_rx.getTransferPerfCounter(), TYPES[0], 512, poolmgr); + TestListener sub_srv_req(dispatcher_rx.getTransferPerfCounter(), TYPES[1], 512, poolmgr); + TestListener sub_srv_resp(dispatcher_rx.getTransferPerfCounter(), TYPES[1], 512, poolmgr); dispatcher_rx.registerMessageListener(&sub_msg); dispatcher_rx.registerServiceRequestListener(&sub_srv_req); diff --git a/libuavcan/test/transport/transfer_test_helpers.cpp b/libuavcan/test/transport/transfer_test_helpers.cpp index f7de3410f1..e3da982602 100644 --- a/libuavcan/test/transport/transfer_test_helpers.cpp +++ b/libuavcan/test/transport/transfer_test_helpers.cpp @@ -11,7 +11,7 @@ TEST(TransferTestHelpers, Transfer) { uavcan::PoolAllocator pool; - uavcan::TransferBufferManager<128> mgr(pool); + uavcan::TransferBufferManager mgr(128, pool); uavcan::TransferBufferAccessor tba(mgr, uavcan::TransferBufferManagerKey(0, uavcan::TransferTypeMessageBroadcast)); uavcan::RxFrame frame(uavcan::Frame(123, uavcan::TransferTypeMessageBroadcast, 1, 0, 0), diff --git a/libuavcan/test/transport/transfer_test_helpers.hpp b/libuavcan/test/transport/transfer_test_helpers.hpp index d1b4f76375..aa52154ea4 100644 --- a/libuavcan/test/transport/transfer_test_helpers.hpp +++ b/libuavcan/test/transport/transfer_test_helpers.hpp @@ -117,17 +117,16 @@ struct Transfer * In reality, uavcan::TransferListener should accept only specific transfer types * which are dispatched/filtered by uavcan::Dispatcher. */ -template -class TestListener : public uavcan::TransferListener +class TestListener : public uavcan::TransferListener { - typedef uavcan::TransferListener Base; + typedef uavcan::TransferListener Base; std::queue transfers_; public: TestListener(uavcan::TransferPerfCounter& perf, const uavcan::DataTypeDescriptor& data_type, - uavcan::IPoolAllocator& allocator) - : Base(perf, data_type, allocator) + uavcan::uint16_t max_buffer_size, uavcan::IPoolAllocator& allocator) + : Base(perf, data_type, max_buffer_size, allocator) { } void handleIncomingTransfer(uavcan::IncomingTransfer& transfer) @@ -166,7 +165,7 @@ public: return res; } - int getNumReceivedTransfers() const { return transfers_.size(); } + unsigned getNumReceivedTransfers() const { return static_cast(transfers_.size()); } bool isEmpty() const { return transfers_.empty(); } };