Transfer buffering system detemplatized; compiles but tests are failing

This commit is contained in:
Pavel Kirienko
2015-10-14 19:59:04 +03:00
parent 763e96b6ed
commit a9fdf44fa9
20 changed files with 335 additions and 510 deletions
@@ -100,9 +100,9 @@ protected:
~GenericSubscriberBase() { } ~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: public:
/** /**
@@ -115,22 +115,6 @@ public:
INode& getNode() const { return node_; } 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 * 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. * that it gets invalidated shortly after the callback returns.
@@ -151,9 +135,15 @@ class UAVCAN_EXPORT GenericSubscriber : public GenericSubscriberBase
} }
public: public:
TransferForwarder(SelfType& obj, const DataTypeDescriptor& data_type, IPoolAllocator& allocator) TransferForwarder(SelfType& obj,
: TransferListenerType(obj.node_.getDispatcher().getTransferPerfCounter(), data_type, allocator) const DataTypeDescriptor& data_type,
, obj_(obj) 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); void handleIncomingTransfer(IncomingTransfer& transfer);
int genericStart(bool (Dispatcher::*registration_method)(TransferListenerBase*)); int genericStart(bool (Dispatcher::*registration_method)(TransferListener*));
protected: protected:
struct ReceivedDataStructureSpec : public ReceivedDataStructure<DataStruct> struct ReceivedDataStructureSpec : public ReceivedDataStructure<DataStruct>
{ {
ReceivedDataStructureSpec() { } ReceivedDataStructureSpec() { }
ReceivedDataStructureSpec(const IncomingTransfer* arg_transfer) ReceivedDataStructureSpec(const IncomingTransfer* arg_transfer) :
: ReceivedDataStructure<DataStruct>(arg_transfer) ReceivedDataStructure<DataStruct>(arg_transfer)
{ } { }
}; };
explicit GenericSubscriber(INode& node) explicit GenericSubscriber(INode& node) : GenericSubscriberBase(node)
: GenericSubscriberBase(node)
{ } { }
virtual ~GenericSubscriber() { stop(); } virtual ~GenericSubscriber() { stop(); }
@@ -247,8 +236,10 @@ int GenericSubscriber<DataSpec, DataStruct, TransferListenerType>::checkInit()
return -ErrUnknownDataType; return -ErrUnknownDataType;
} }
forwarder_.template construct<SelfType&, const DataTypeDescriptor&, IPoolAllocator&> static const uint16_t MaxBufferSize = BitLenToByteLen<DataStruct::MaxBitLen>::Result;
(*this, *descr, node_.getAllocator());
forwarder_.template construct<SelfType&, const DataTypeDescriptor&, uint16_t, IPoolAllocator&>
(*this, *descr, MaxBufferSize, node_.getAllocator());
return 0; return 0;
} }
@@ -286,7 +277,7 @@ void GenericSubscriber<DataSpec, DataStruct, TransferListenerType>::handleIncomi
template <typename DataSpec, typename DataStruct, typename TransferListenerType> template <typename DataSpec, typename DataStruct, typename TransferListenerType>
int GenericSubscriber<DataSpec, DataStruct, TransferListenerType>:: int GenericSubscriber<DataSpec, DataStruct, TransferListenerType>::
genericStart(bool (Dispatcher::*registration_method)(TransferListenerBase*)) genericStart(bool (Dispatcher::*registration_method)(TransferListener*))
{ {
const int res = checkInit(); const int res = checkInit();
if (res < 0) if (res < 0)
@@ -20,15 +20,6 @@
namespace uavcan 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. * This struct describes a pending service call.
* Refer to @ref ServiceClient to learn more about service calls. * Refer to @ref ServiceClient to learn more about service calls.
@@ -225,8 +216,7 @@ template <typename DataType_,
> >
class UAVCAN_EXPORT ServiceClient class UAVCAN_EXPORT ServiceClient
: public GenericSubscriber<DataType_, : public GenericSubscriber<DataType_,
typename DataType_::Response, typename DataType_::Response, TransferListenerWithFilter>
typename ServiceResponseTransferListenerInstantiationHelper<DataType_>::Type>
, public ServiceClientBase , public ServiceClientBase
{ {
public: public:
@@ -239,8 +229,7 @@ public:
private: private:
typedef ServiceClient<DataType, Callback> SelfType; typedef ServiceClient<DataType, Callback> SelfType;
typedef GenericPublisher<DataType, RequestType> PublisherType; typedef GenericPublisher<DataType, RequestType> PublisherType;
typedef typename ServiceResponseTransferListenerInstantiationHelper<DataType>::Type TransferListenerType; typedef GenericSubscriber<DataType, ResponseType, TransferListenerWithFilter> SubscriberType;
typedef GenericSubscriber<DataType, ResponseType, TransferListenerType> SubscriberType;
typedef Multiset<CallState> CallRegistry; 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 * Configuring the listener so it will accept only the matching responses
* TODO move to init(), but this requires to somewhat refactor GenericSubscriber<> (remove TransferForwarder) * 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) if (tl == NULL)
{ {
UAVCAN_ASSERT(0); // Must have been created UAVCAN_ASSERT(0); // Must have been created
@@ -88,8 +88,7 @@ template <typename DataType_,
#endif #endif
> >
class UAVCAN_EXPORT ServiceServer class UAVCAN_EXPORT ServiceServer
: public GenericSubscriber<DataType_, typename DataType_::Request, : public GenericSubscriber<DataType_, typename DataType_::Request, TransferListener>
typename TransferListenerInstantiationHelper<typename DataType_::Request>::Type>
{ {
public: public:
typedef DataType_ DataType; typedef DataType_ DataType;
@@ -98,8 +97,7 @@ public:
typedef Callback_ Callback; typedef Callback_ Callback;
private: private:
typedef typename TransferListenerInstantiationHelper<RequestType>::Type TransferListenerType; typedef GenericSubscriber<DataType, RequestType, TransferListener> SubscriberType;
typedef GenericSubscriber<DataType, RequestType, TransferListenerType> SubscriberType;
typedef GenericPublisher<DataType, ResponseType> PublisherType; typedef GenericPublisher<DataType, ResponseType> PublisherType;
PublisherType publisher_; PublisherType publisher_;
+2 -4
View File
@@ -43,15 +43,13 @@ template <typename DataType_,
#endif #endif
> >
class UAVCAN_EXPORT Subscriber class UAVCAN_EXPORT Subscriber
: public GenericSubscriber<DataType_, DataType_, : public GenericSubscriber<DataType_, DataType_, TransferListener>
typename TransferListenerInstantiationHelper<DataType_>::Type>
{ {
public: public:
typedef Callback_ Callback; typedef Callback_ Callback;
private: private:
typedef typename TransferListenerInstantiationHelper<DataType_>::Type TransferListenerType; typedef GenericSubscriber<DataType_, DataType_, TransferListener> BaseType;
typedef GenericSubscriber<DataType_, DataType_, TransferListenerType> BaseType;
Callback callback_; Callback callback_;
@@ -86,14 +86,14 @@ class UAVCAN_EXPORT Dispatcher : Noncopyable
class ListenerRegistry class ListenerRegistry
{ {
LinkedListRoot<TransferListenerBase> list_; LinkedListRoot<TransferListener> list_;
class DataTypeIDInsertionComparator class DataTypeIDInsertionComparator
{ {
const DataTypeID id_; const DataTypeID id_;
public: public:
explicit DataTypeIDInsertionComparator(DataTypeID id) : id_(id) { } explicit DataTypeIDInsertionComparator(DataTypeID id) : id_(id) { }
bool operator()(const TransferListenerBase* listener) const bool operator()(const TransferListener* listener) const
{ {
UAVCAN_ASSERT(listener); UAVCAN_ASSERT(listener);
return id_ > listener->getDataTypeDescriptor().getID(); return id_ > listener->getDataTypeDescriptor().getID();
@@ -103,15 +103,15 @@ class UAVCAN_EXPORT Dispatcher : Noncopyable
public: public:
enum Mode { UniqueListener, ManyListeners }; enum Mode { UniqueListener, ManyListeners };
bool add(TransferListenerBase* listener, Mode mode); bool add(TransferListener* listener, Mode mode);
void remove(TransferListenerBase* listener); void remove(TransferListener* listener);
bool exists(DataTypeID dtid) const; bool exists(DataTypeID dtid) const;
void cleanup(MonotonicTime ts); void cleanup(MonotonicTime ts);
void handleFrame(const RxFrame& frame); void handleFrame(const RxFrame& frame);
unsigned getNumEntries() const { return list_.getLength(); } unsigned getNumEntries() const { return list_.getLength(); }
const LinkedListRoot<TransferListenerBase>& getList() const { return list_; } const LinkedListRoot<TransferListener>& getList() const { return list_; }
}; };
ListenerRegistry lmsg_; ListenerRegistry lmsg_;
@@ -162,13 +162,13 @@ public:
void cleanup(MonotonicTime ts); void cleanup(MonotonicTime ts);
bool registerMessageListener(TransferListenerBase* listener); bool registerMessageListener(TransferListener* listener);
bool registerServiceRequestListener(TransferListenerBase* listener); bool registerServiceRequestListener(TransferListener* listener);
bool registerServiceResponseListener(TransferListenerBase* listener); bool registerServiceResponseListener(TransferListener* listener);
void unregisterMessageListener(TransferListenerBase* listener); void unregisterMessageListener(TransferListener* listener);
void unregisterServiceRequestListener(TransferListenerBase* listener); void unregisterServiceRequestListener(TransferListener* listener);
void unregisterServiceResponseListener(TransferListenerBase* listener); void unregisterServiceResponseListener(TransferListener* listener);
bool hasSubscriber(DataTypeID dtid) const; bool hasSubscriber(DataTypeID dtid) const;
bool hasPublisher(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. * 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(); return lmsg_.getList();
} }
const LinkedListRoot<TransferListenerBase>& getListOfServiceRequestListeners() const const LinkedListRoot<TransferListener>& getListOfServiceRequestListeners() const
{ {
return lsrv_req_.getList(); return lsrv_req_.getList();
} }
const LinkedListRoot<TransferListenerBase>& getListOfServiceResponseListeners() const const LinkedListRoot<TransferListener>& getListOfServiceResponseListeners() const
{ {
return lsrv_resp_.getList(); return lsrv_resp_.getList();
} }
@@ -16,6 +16,47 @@
namespace uavcan 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 * Internal for TransferBufferManager
*/ */
@@ -53,41 +94,13 @@ public:
#endif #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. * Resizable gather/scatter storage.
* reset() call releases all memory blocks. * reset() call releases all memory blocks.
* Supports unordered write operations - from higher to lower offsets * Supports unordered write operations - from higher to lower offsets
*/ */
class UAVCAN_EXPORT DynamicTransferBufferManagerEntry class UAVCAN_EXPORT TransferBufferManagerEntry : public ITransferBuffer
: public TransferBufferManagerEntry , public LinkedListNode<TransferBufferManagerEntry>
, public LinkedListNode<DynamicTransferBufferManagerEntry>
{ {
struct Block : LinkedListNode<Block> struct Block : LinkedListNode<Block>
{ {
@@ -107,116 +120,58 @@ class UAVCAN_EXPORT DynamicTransferBufferManagerEntry
LinkedListRoot<Block> blocks_; // Blocks are ordered from lower to higher buffer offset LinkedListRoot<Block> blocks_; // Blocks are ordered from lower to higher buffer offset
uint16_t max_write_pos_; uint16_t max_write_pos_;
const uint16_t max_size_; const uint16_t max_size_;
TransferBufferManagerKey key_;
/// Reset functionality must be implemented in a non-virtual method to call it safely from the destructor.
void doReset();
virtual void resetImpl();
public: public:
DynamicTransferBufferManagerEntry(IPoolAllocator& allocator, uint16_t max_size) TransferBufferManagerEntry(IPoolAllocator& allocator, uint16_t max_size) :
: allocator_(allocator) allocator_(allocator),
, max_write_pos_(0) max_write_pos_(0),
, max_size_(max_size) max_size_(max_size)
{ {
StaticAssert<(Block::Size > 8)>::check(); StaticAssert<(Block::Size > 8)>::check();
IsDynamicallyAllocatable<Block>::check(); IsDynamicallyAllocatable<Block>::check();
IsDynamicallyAllocatable<DynamicTransferBufferManagerEntry>::check(); IsDynamicallyAllocatable<TransferBufferManagerEntry>::check();
} }
virtual ~DynamicTransferBufferManagerEntry() virtual ~TransferBufferManagerEntry() { reset(); }
{
doReset();
}
static DynamicTransferBufferManagerEntry* instantiate(IPoolAllocator& allocator, uint16_t max_size); static TransferBufferManagerEntry* instantiate(IPoolAllocator& allocator, uint16_t max_size);
static void destroy(DynamicTransferBufferManagerEntry*& obj, IPoolAllocator& allocator); 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);
};
/**
* 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 read(unsigned offset, uint8_t* data, unsigned len) const;
virtual int write(unsigned offset, const uint8_t* data, unsigned len); 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_; } const TransferBufferManagerKey& getKey() const { return key_; }
bool isEmpty() const { return key_.isEmpty(); }
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();
}
}; };
/** /**
* 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: public:
StaticTransferBufferManagerEntryImpl(uint8_t* buf, uint16_t buf_size) TransferBufferManager(uint16_t max_buf_size, IPoolAllocator& allocator) :
: buf_(buf, buf_size) allocator_(allocator),
max_buf_size_(max_buf_size)
{ } { }
virtual int read(unsigned offset, uint8_t* data, unsigned len) const; ~TransferBufferManager();
virtual int write(unsigned offset, const uint8_t* data, unsigned len);
};
template <uint16_t Size> ITransferBuffer* access(const TransferBufferManagerKey& key);
class UAVCAN_EXPORT StaticTransferBufferManagerEntry : public StaticTransferBufferManagerEntryImpl ITransferBuffer* create(const TransferBufferManagerKey& key);
{ void remove(const TransferBufferManagerKey& key);
uint8_t buffer_[Size]; bool isEmpty() const;
public:
StaticTransferBufferManagerEntry()
: StaticTransferBufferManagerEntryImpl(buffer_, Size)
{ }
};
/** unsigned getNumBuffers() 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;
}; };
/** /**
@@ -224,13 +179,13 @@ public:
*/ */
class UAVCAN_EXPORT TransferBufferAccessor class UAVCAN_EXPORT TransferBufferAccessor
{ {
ITransferBufferManager& bufmgr_; TransferBufferManager& bufmgr_;
const TransferBufferManagerKey key_; const TransferBufferManagerKey key_;
public: public:
TransferBufferAccessor(ITransferBufferManager& bufmgr, TransferBufferManagerKey key) TransferBufferAccessor(TransferBufferManager& bufmgr, TransferBufferManagerKey key) :
: bufmgr_(bufmgr) bufmgr_(bufmgr),
, key_(key) key_(key)
{ {
UAVCAN_ASSERT(!key.isEmpty()); UAVCAN_ASSERT(!key.isEmpty());
} }
@@ -239,54 +194,6 @@ public:
void remove() { bufmgr_.remove(key_); } 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 #endif // UAVCAN_TRANSPORT_TRANSFER_BUFFER_HPP_INCLUDED
@@ -96,11 +96,11 @@ public:
/** /**
* Internal, refer to the transport dispatcher class. * 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_; const DataTypeDescriptor& data_type_;
Map<TransferBufferManagerKey, TransferReceiver>& receivers_; TransferBufferManager bufmgr_;
ITransferBufferManager& bufmgr_; Map<TransferBufferManagerKey, TransferReceiver> receivers_;
TransferPerfCounter& perf_; TransferPerfCounter& perf_;
const TransferCRC crc_base_; ///< Pre-initialized with data type hash, thus constant const TransferCRC crc_base_; ///< Pre-initialized with data type hash, thus constant
bool allow_anonymous_transfers_; bool allow_anonymous_transfers_;
@@ -108,10 +108,10 @@ class UAVCAN_EXPORT TransferListenerBase : public LinkedListNode<TransferListene
class TimedOutReceiverPredicate class TimedOutReceiverPredicate
{ {
const MonotonicTime ts_; const MonotonicTime ts_;
ITransferBufferManager& parent_bufmgr_; TransferBufferManager& parent_bufmgr_;
public: public:
TimedOutReceiverPredicate(MonotonicTime arg_ts, ITransferBufferManager& arg_bufmgr) TimedOutReceiverPredicate(MonotonicTime arg_ts, TransferBufferManager& arg_bufmgr)
: ts_(arg_ts) : ts_(arg_ts)
, parent_bufmgr_(arg_bufmgr) , 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; bool checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const;
protected: 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 handleReception(TransferReceiver& receiver, const RxFrame& frame, TransferBufferAccessor& tba);
void handleAnonymousTransferReception(const RxFrame& frame); void handleAnonymousTransferReception(const RxFrame& frame);
virtual void handleIncomingTransfer(IncomingTransfer& transfer) = 0; virtual void handleIncomingTransfer(IncomingTransfer& transfer) = 0;
public: 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_; } const DataTypeDescriptor& getDataTypeDescriptor() const { return data_type_; }
/** /**
@@ -154,29 +157,6 @@ public:
virtual void handleFrame(const RxFrame& frame); 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. * 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. * This class should be derived by callers.
*/ */
template <unsigned MaxBufSize> class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener
class UAVCAN_EXPORT TransferListenerWithFilter : public TransferListener<MaxBufSize>
{ {
const ITransferAcceptanceFilter* filter_; const ITransferAcceptanceFilter* filter_;
virtual void handleFrame(const RxFrame& frame); virtual void handleFrame(const RxFrame& frame);
public: public:
typedef TransferListener<MaxBufSize> BaseType;
TransferListenerWithFilter(TransferPerfCounter& perf, const DataTypeDescriptor& data_type, TransferListenerWithFilter(TransferPerfCounter& perf, const DataTypeDescriptor& data_type,
IPoolAllocator& allocator) uint16_t max_buffer_size, IPoolAllocator& allocator)
: BaseType(perf, data_type, allocator) : TransferListener(perf, data_type, max_buffer_size, allocator)
, filter_(NULL) , 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 #endif // UAVCAN_TRANSPORT_TRANSFER_LISTENER_HPP_INCLUDED
+3 -3
View File
@@ -7,8 +7,8 @@
namespace uavcan namespace uavcan
{ {
int GenericSubscriberBase::genericStart(TransferListenerBase* listener, int GenericSubscriberBase::genericStart(TransferListener* listener,
bool (Dispatcher::*registration_method)(TransferListenerBase*)) bool (Dispatcher::*registration_method)(TransferListener*))
{ {
if (listener == NULL) if (listener == NULL)
{ {
@@ -24,7 +24,7 @@ int GenericSubscriberBase::genericStart(TransferListenerBase* listener,
return 0; return 0;
} }
void GenericSubscriberBase::stop(TransferListenerBase* listener) void GenericSubscriberBase::stop(TransferListener* listener)
{ {
if (listener != NULL) if (listener != NULL)
{ {
@@ -38,8 +38,8 @@ int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration(AnonymousMessage
return -ErrMemory; return -ErrMemory;
} }
const TransferListenerBase* p = node_.getDispatcher().getListOfMessageListeners().get(); const TransferListener* p = node_.getDispatcher().getListOfMessageListeners().get();
while (p) while (p != NULL)
{ {
CanFilterConfig cfg; CanFilterConfig cfg;
cfg.id = static_cast<uint32_t>(p->getDataTypeDescriptor().getID().get()) << 8; cfg.id = static_cast<uint32_t>(p->getDataTypeDescriptor().getID().get()) << 8;
+14 -14
View File
@@ -72,11 +72,11 @@ void LoopbackFrameListenerRegistry::invokeListeners(RxFrame& frame)
/* /*
* Dispatcher::ListenerRegister * Dispatcher::ListenerRegister
*/ */
bool Dispatcher::ListenerRegistry::add(TransferListenerBase* listener, Mode mode) bool Dispatcher::ListenerRegistry::add(TransferListener* listener, Mode mode)
{ {
if (mode == UniqueListener) if (mode == UniqueListener)
{ {
TransferListenerBase* p = list_.get(); TransferListener* p = list_.get();
while (p) while (p)
{ {
if (p->getDataTypeDescriptor().getID() == listener->getDataTypeDescriptor().getID()) if (p->getDataTypeDescriptor().getID() == listener->getDataTypeDescriptor().getID())
@@ -91,14 +91,14 @@ bool Dispatcher::ListenerRegistry::add(TransferListenerBase* listener, Mode mode
return true; return true;
} }
void Dispatcher::ListenerRegistry::remove(TransferListenerBase* listener) void Dispatcher::ListenerRegistry::remove(TransferListener* listener)
{ {
list_.remove(listener); list_.remove(listener);
} }
bool Dispatcher::ListenerRegistry::exists(DataTypeID dtid) const bool Dispatcher::ListenerRegistry::exists(DataTypeID dtid) const
{ {
TransferListenerBase* p = list_.get(); TransferListener* p = list_.get();
while (p) while (p)
{ {
if (p->getDataTypeDescriptor().getID() == dtid) if (p->getDataTypeDescriptor().getID() == dtid)
@@ -112,10 +112,10 @@ bool Dispatcher::ListenerRegistry::exists(DataTypeID dtid) const
void Dispatcher::ListenerRegistry::cleanup(MonotonicTime ts) void Dispatcher::ListenerRegistry::cleanup(MonotonicTime ts)
{ {
TransferListenerBase* p = list_.get(); TransferListener* p = list_.get();
while (p) while (p)
{ {
TransferListenerBase* const next = p->getNextListNode(); TransferListener* const next = p->getNextListNode();
p->cleanup(ts); // p may be modified p->cleanup(ts); // p may be modified
p = next; p = next;
} }
@@ -123,10 +123,10 @@ void Dispatcher::ListenerRegistry::cleanup(MonotonicTime ts)
void Dispatcher::ListenerRegistry::handleFrame(const RxFrame& frame) void Dispatcher::ListenerRegistry::handleFrame(const RxFrame& frame)
{ {
TransferListenerBase* p = list_.get(); TransferListener* p = list_.get();
while (p) while (p)
{ {
TransferListenerBase* const next = p->getNextListNode(); TransferListener* const next = p->getNextListNode();
if (p->getDataTypeDescriptor().getID() == frame.getDataTypeID()) if (p->getDataTypeDescriptor().getID() == frame.getDataTypeID())
{ {
p->handleFrame(frame); // p may be modified p->handleFrame(frame); // p may be modified
@@ -311,7 +311,7 @@ void Dispatcher::cleanup(MonotonicTime ts)
lsrv_resp_.cleanup(ts); lsrv_resp_.cleanup(ts);
} }
bool Dispatcher::registerMessageListener(TransferListenerBase* listener) bool Dispatcher::registerMessageListener(TransferListener* listener)
{ {
if (listener->getDataTypeDescriptor().getKind() != DataTypeKindMessage) if (listener->getDataTypeDescriptor().getKind() != DataTypeKindMessage)
{ {
@@ -321,7 +321,7 @@ bool Dispatcher::registerMessageListener(TransferListenerBase* listener)
return lmsg_.add(listener, ListenerRegistry::ManyListeners); // Multiple subscribers are OK 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) 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 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) 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 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); lmsg_.remove(listener);
} }
void Dispatcher::unregisterServiceRequestListener(TransferListenerBase* listener) void Dispatcher::unregisterServiceRequestListener(TransferListener* listener)
{ {
lsrv_req_.remove(listener); lsrv_req_.remove(listener);
} }
void Dispatcher::unregisterServiceResponseListener(TransferListenerBase* listener) void Dispatcher::unregisterServiceResponseListener(TransferListener* listener)
{ {
lsrv_resp_.remove(listener); lsrv_resp_.remove(listener);
} }
+95 -117
View File
@@ -8,6 +8,58 @@
namespace uavcan 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 * TransferBufferManagerKey
*/ */
@@ -23,8 +75,8 @@ std::string TransferBufferManagerKey::toString() const
/* /*
* DynamicTransferBuffer::Block * DynamicTransferBuffer::Block
*/ */
DynamicTransferBufferManagerEntry::Block* TransferBufferManagerEntry::Block*
DynamicTransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator) TransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator)
{ {
void* const praw = allocator.allocate(sizeof(Block)); void* const praw = allocator.allocate(sizeof(Block));
if (praw == NULL) if (praw == NULL)
@@ -34,7 +86,7 @@ DynamicTransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator)
return new (praw) Block; return new (praw) Block;
} }
void DynamicTransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocator& allocator) void TransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocator& allocator)
{ {
if (obj != NULL) if (obj != NULL)
{ {
@@ -44,8 +96,8 @@ void DynamicTransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocat
} }
} }
void DynamicTransferBufferManagerEntry::Block::read(uint8_t*& outptr, unsigned target_offset, void TransferBufferManagerEntry::Block::read(uint8_t*& outptr, unsigned target_offset,
unsigned& total_offset, unsigned& left_to_read) unsigned& total_offset, unsigned& left_to_read)
{ {
UAVCAN_ASSERT(outptr); UAVCAN_ASSERT(outptr);
for (unsigned i = 0; (i < Block::Size) && (left_to_read > 0); i++, total_offset++) 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) unsigned& total_offset, unsigned& left_to_write)
{ {
UAVCAN_ASSERT(inptr); UAVCAN_ASSERT(inptr);
@@ -75,46 +127,28 @@ void DynamicTransferBufferManagerEntry::Block::write(const uint8_t*& inptr, unsi
/* /*
* DynamicTransferBuffer * DynamicTransferBuffer
*/ */
DynamicTransferBufferManagerEntry* DynamicTransferBufferManagerEntry::instantiate(IPoolAllocator& allocator, TransferBufferManagerEntry* TransferBufferManagerEntry::instantiate(IPoolAllocator& allocator,
uint16_t max_size) uint16_t max_size)
{ {
void* const praw = allocator.allocate(sizeof(DynamicTransferBufferManagerEntry)); void* const praw = allocator.allocate(sizeof(TransferBufferManagerEntry));
if (praw == NULL) if (praw == NULL)
{ {
return 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) if (obj != NULL)
{ {
obj->~DynamicTransferBufferManagerEntry(); obj->~TransferBufferManagerEntry();
allocator.deallocate(obj); allocator.deallocate(obj);
obj = NULL; obj = NULL;
} }
} }
void DynamicTransferBufferManagerEntry::doReset() int TransferBufferManagerEntry::read(unsigned offset, uint8_t* data, unsigned len) const
{
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
{ {
if (!data) if (!data)
{ {
@@ -150,7 +184,7 @@ int DynamicTransferBufferManagerEntry::read(unsigned offset, uint8_t* data, unsi
return int(len); 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) if (!data)
{ {
@@ -221,82 +255,26 @@ int DynamicTransferBufferManagerEntry::write(unsigned offset, const uint8_t* dat
return int(actually_written); return int(actually_written);
} }
/* void TransferBufferManagerEntry::reset(const TransferBufferManagerKey& key)
* 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()
{ {
key_ = key;
max_write_pos_ = 0; max_write_pos_ = 0;
#if UAVCAN_DEBUG Block* p = blocks_.get();
fill(data_, data_ + size_, uint8_t(0)); while (p)
#endif {
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(); TransferBufferManagerEntry* dyn = buffers_.get();
}
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();
while (dyn) while (dyn)
{ {
UAVCAN_ASSERT(!dyn->isEmpty()); UAVCAN_ASSERT(!dyn->isEmpty());
@@ -309,29 +287,29 @@ DynamicTransferBufferManagerEntry* TransferBufferManagerImpl::findFirstDynamic(c
return NULL; return NULL;
} }
TransferBufferManagerImpl::~TransferBufferManagerImpl() TransferBufferManager::~TransferBufferManager()
{ {
DynamicTransferBufferManagerEntry* dyn = dynamic_buffers_.get(); TransferBufferManagerEntry* dyn = buffers_.get();
while (dyn) while (dyn)
{ {
DynamicTransferBufferManagerEntry* const next = dyn->getNextListNode(); TransferBufferManagerEntry* const next = dyn->getNextListNode();
dynamic_buffers_.remove(dyn); buffers_.remove(dyn);
DynamicTransferBufferManagerEntry::destroy(dyn, allocator_); TransferBufferManagerEntry::destroy(dyn, allocator_);
dyn = next; dyn = next;
} }
} }
ITransferBuffer* TransferBufferManagerImpl::access(const TransferBufferManagerKey& key) ITransferBuffer* TransferBufferManager::access(const TransferBufferManagerKey& key)
{ {
if (key.isEmpty()) if (key.isEmpty())
{ {
UAVCAN_ASSERT(0); UAVCAN_ASSERT(0);
return NULL; return NULL;
} }
return findFirstDynamic(key); return findFirst(key);
} }
ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKey& key) ITransferBuffer* TransferBufferManager::create(const TransferBufferManagerKey& key)
{ {
if (key.isEmpty()) if (key.isEmpty())
{ {
@@ -340,13 +318,13 @@ ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKe
} }
remove(key); remove(key);
DynamicTransferBufferManagerEntry* tbme = DynamicTransferBufferManagerEntry::instantiate(allocator_, max_buf_size_); TransferBufferManagerEntry* tbme = TransferBufferManagerEntry::instantiate(allocator_, max_buf_size_);
if (tbme == NULL) if (tbme == NULL)
{ {
return NULL; // Epic fail. return NULL; // Epic fail.
} }
dynamic_buffers_.insert(tbme); buffers_.insert(tbme);
UAVCAN_TRACE("TransferBufferManager", "Buffer created [num=%u], %s", getNumBuffers(), key.toString().c_str()); UAVCAN_TRACE("TransferBufferManager", "Buffer created [num=%u], %s", getNumBuffers(), key.toString().c_str());
@@ -358,27 +336,27 @@ ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKe
return tbme; return tbme;
} }
void TransferBufferManagerImpl::remove(const TransferBufferManagerKey& key) void TransferBufferManager::remove(const TransferBufferManagerKey& key)
{ {
UAVCAN_ASSERT(!key.isEmpty()); UAVCAN_ASSERT(!key.isEmpty());
DynamicTransferBufferManagerEntry* dyn = findFirstDynamic(key); TransferBufferManagerEntry* dyn = findFirst(key);
if (dyn != NULL) if (dyn != NULL)
{ {
UAVCAN_TRACE("TransferBufferManager", "Buffer deleted, %s", key.toString().c_str()); UAVCAN_TRACE("TransferBufferManager", "Buffer deleted, %s", key.toString().c_str());
dynamic_buffers_.remove(dyn); buffers_.remove(dyn);
DynamicTransferBufferManagerEntry::destroy(dyn, allocator_); TransferBufferManagerEntry::destroy(dyn, allocator_);
} }
} }
bool TransferBufferManagerImpl::isEmpty() const bool TransferBufferManager::isEmpty() const
{ {
return getNumBuffers() == 0; return getNumBuffers() == 0;
} }
unsigned TransferBufferManagerImpl::getNumBuffers() const unsigned TransferBufferManager::getNumBuffers() const
{ {
return dynamic_buffers_.getLength(); return buffers_.getLength();
} }
} }
@@ -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, bool TransferListener::TimedOutReceiverPredicate::operator()(const TransferBufferManagerKey& key,
const TransferReceiver& value) const const TransferReceiver& value) const
{ {
if (value.isTimedOut(ts_)) 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_; TransferCRC crc = crc_base_;
unsigned offset = 0; 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)); const int res = tbb.read(offset, buf, sizeof(buf));
if (res < 0) 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; return false;
} }
if (res == 0) if (res == 0)
@@ -125,14 +125,14 @@ bool TransferListenerBase::checkPayloadCrc(const uint16_t compare_with, const IT
} }
if (crc.get() != compare_with) 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())); int(compare_with), int(crc.get()));
return false; return false;
} }
return true; return true;
} }
void TransferListenerBase::handleReception(TransferReceiver& receiver, const RxFrame& frame, void TransferListener::handleReception(TransferReceiver& receiver, const RxFrame& frame,
TransferBufferAccessor& tba) TransferBufferAccessor& tba)
{ {
switch (receiver.addFrame(frame, tba)) switch (receiver.addFrame(frame, tba))
@@ -155,12 +155,12 @@ void TransferListenerBase::handleReception(TransferReceiver& receiver, const RxF
const ITransferBuffer* tbb = tba.access(); const ITransferBuffer* tbb = tba.access();
if (tbb == NULL) 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; break;
} }
if (!checkPayloadCrc(receiver.getLastTransferCrc(), *tbb)) 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; break;
} }
MultiFrameIncomingTransfer it(receiver.getLastTransferTimestampMonotonic(), 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_) 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_)); receivers_.removeAllWhere(TimedOutReceiverPredicate(ts, bufmgr_));
UAVCAN_ASSERT(receivers_.isEmpty() ? bufmgr_.isEmpty() : 1); 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 if (frame.getSrcNodeID().isUnicast()) // Normal transfer
{ {
@@ -227,7 +227,25 @@ void TransferListenerBase::handleFrame(const RxFrame& frame)
} }
else 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);
} }
} }
+14 -14
View File
@@ -86,17 +86,17 @@ TEST(Dispatcher, Reception)
makeDataType(uavcan::DataTypeKindService, 1) makeDataType(uavcan::DataTypeKindService, 1)
}; };
typedef TestListener<512> Subscriber; typedef std::auto_ptr<TestListener> TestListenerPtr;
typedef std::auto_ptr<Subscriber> SubscriberPtr; static const int MaxBufSize = 512;
static const int NUM_SUBSCRIBERS = 6; static const int NumSubscribers = 6;
SubscriberPtr subscribers[NUM_SUBSCRIBERS] = TestListenerPtr subscribers[NumSubscribers] =
{ {
SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[0], pool)), // msg TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[0], MaxBufSize, pool)), // msg
SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[0], pool)), // msg // Two similar TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[0], MaxBufSize, pool)), // msg // Two similar
SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[1], pool)), // msg TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[1], MaxBufSize, pool)), // msg
SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[2], pool)), // srv TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[2], MaxBufSize, pool)), // srv
SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[3], pool)), // srv TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[3], MaxBufSize, pool)), // srv
SubscriberPtr(new Subscriber(dispatcher.getTransferPerfCounter(), TYPES[3], pool)) // srv // Repeat again TestListenerPtr(new TestListener(dispatcher.getTransferPerfCounter(), TYPES[3], MaxBufSize, pool)) // srv // Repeat again
}; };
static const std::string DATA[6] = static const std::string DATA[6] =
@@ -139,7 +139,7 @@ TEST(Dispatcher, Reception)
/* /*
* Registration * 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.hasSubscriber(subscribers[i]->getDataTypeDescriptor().getID()));
ASSERT_FALSE(dispatcher.hasPublisher(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[4].get()));
ASSERT_TRUE(dispatcher.registerServiceResponseListener(subscribers[5].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())); ASSERT_FALSE(dispatcher.hasPublisher(subscribers[i]->getDataTypeDescriptor().getID()));
} }
@@ -177,7 +177,7 @@ TEST(Dispatcher, Reception)
ASSERT_EQ(1, dispatcher.getNumServiceRequestListeners()); ASSERT_EQ(1, dispatcher.getNumServiceRequestListeners());
ASSERT_EQ(2, dispatcher.getNumServiceResponseListeners()); 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()); ASSERT_TRUE(subscribers[i]->isEmpty());
} }
@@ -214,7 +214,7 @@ TEST(Dispatcher, Reception)
ASSERT_TRUE(subscribers[5]->matchAndPop(transfers[3])); 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()); ASSERT_TRUE(subscribers[i]->isEmpty());
} }
@@ -73,7 +73,7 @@ TEST(MultiFrameIncomingTransfer, Basic)
using uavcan::MultiFrameIncomingTransfer; using uavcan::MultiFrameIncomingTransfer;
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 100, uavcan::MemPoolBlockSize> poolmgr; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 100, uavcan::MemPoolBlockSize> poolmgr;
uavcan::TransferBufferManager<256> bufmgr(poolmgr); uavcan::TransferBufferManager bufmgr(256, poolmgr);
const RxFrame frame = makeFrame(); const RxFrame frame = makeFrame();
uavcan::TransferBufferManagerKey bufmgr_key(frame.getSrcNodeID(), frame.getTransferType()); uavcan::TransferBufferManagerKey bufmgr_key(frame.getSrcNodeID(), frame.getTransferType());
+7 -16
View File
@@ -83,8 +83,8 @@ static const int TEST_BUFFER_SIZE = 200;
TEST(StaticTransferBuffer, Basic) TEST(StaticTransferBuffer, Basic)
{ {
using uavcan::StaticTransferBufferManagerEntry; using uavcan::StaticTransferBuffer;
StaticTransferBufferManagerEntry<TEST_BUFFER_SIZE> buf; StaticTransferBuffer<TEST_BUFFER_SIZE> buf;
uint8_t local_buffer[TEST_BUFFER_SIZE * 2]; uint8_t local_buffer[TEST_BUFFER_SIZE * 2];
const uint8_t* const test_data_ptr = reinterpret_cast<const uint8_t*>(TEST_DATA.c_str()); const uint8_t* const test_data_ptr = reinterpret_cast<const uint8_t*>(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 MAX_SIZE = TEST_BUFFER_SIZE;
static const int POOL_BLOCKS = 8; static const int POOL_BLOCKS = 8;
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * POOL_BLOCKS, uavcan::MemPoolBlockSize> pool; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * POOL_BLOCKS, uavcan::MemPoolBlockSize> pool;
DynamicTransferBufferManagerEntry buf(pool, MAX_SIZE); TransferBufferManagerEntry buf(pool, MAX_SIZE);
uint8_t local_buffer[TEST_BUFFER_SIZE * 2]; uint8_t local_buffer[TEST_BUFFER_SIZE * 2];
const uint8_t* const test_data_ptr = reinterpret_cast<const uint8_t*>(TEST_DATA.c_str()); const uint8_t* const test_data_ptr = reinterpret_cast<const uint8_t*>(TEST_DATA.c_str());
@@ -186,7 +186,7 @@ TEST(DynamicTransferBufferManagerEntry, Basic)
// Destroying the object; memory should be released // Destroying the object; memory should be released
ASSERT_LT(0, pool.getNumUsedBlocks()); ASSERT_LT(0, pool.getNumUsedBlocks());
buf.~DynamicTransferBufferManagerEntry(); buf.~TransferBufferManagerEntry();
ASSERT_EQ(0, pool.getNumUsedBlocks()); ASSERT_EQ(0, pool.getNumUsedBlocks());
} }
@@ -232,8 +232,7 @@ TEST(TransferBufferManager, Basic)
static const int POOL_BLOCKS = 100; static const int POOL_BLOCKS = 100;
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * POOL_BLOCKS, uavcan::MemPoolBlockSize> pool; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * POOL_BLOCKS, uavcan::MemPoolBlockSize> pool;
typedef TransferBufferManager<MGR_MAX_BUFFER_SIZE> TransferBufferManagerType; std::auto_ptr<TransferBufferManager> mgr(new TransferBufferManager(MGR_MAX_BUFFER_SIZE, pool));
std::auto_ptr<TransferBufferManagerType> mgr(new TransferBufferManagerType(pool));
// Empty // Empty
ASSERT_FALSE(mgr->access(TransferBufferManagerKey(0, uavcan::TransferTypeMessageBroadcast))); ASSERT_FALSE(mgr->access(TransferBufferManagerKey(0, uavcan::TransferTypeMessageBroadcast)));
@@ -313,11 +312,3 @@ TEST(TransferBufferManager, Basic)
mgr.reset(); mgr.reset();
ASSERT_EQ(0, pool.getNumUsedBlocks()); ASSERT_EQ(0, pool.getNumUsedBlocks());
} }
TEST(TransferBufferManager, EmptySpecialization)
{
uavcan::TransferBufferManager<0> mgr;
(void)mgr;
ASSERT_GE(sizeof(void*), sizeof(mgr));
}
@@ -9,11 +9,11 @@
class TransferListenerEmulator : public IncomingTransferEmulatorBase class TransferListenerEmulator : public IncomingTransferEmulatorBase
{ {
uavcan::TransferListenerBase& target_; uavcan::TransferListener& target_;
const uavcan::DataTypeDescriptor data_type_; const uavcan::DataTypeDescriptor data_type_;
public: public:
TransferListenerEmulator(uavcan::TransferListenerBase& target, const uavcan::DataTypeDescriptor& type, TransferListenerEmulator(uavcan::TransferListener& target, const uavcan::DataTypeDescriptor& type,
uavcan::NodeID dst_node_id = 127) uavcan::NodeID dst_node_id = 127)
: IncomingTransferEmulatorBase(dst_node_id) : IncomingTransferEmulatorBase(dst_node_id)
, target_(target) , target_(target)
@@ -38,7 +38,7 @@ TEST(TransferListener, BasicMFT)
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> pool; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> pool;
uavcan::TransferPerfCounter perf; uavcan::TransferPerfCounter perf;
TestListener<256> subscriber(perf, type, pool); TestListener subscriber(perf, type, 256, pool);
/* /*
* Test data * Test data
@@ -96,7 +96,7 @@ TEST(TransferListener, CrcFailure)
static const int NUM_POOL_BLOCKS = 100; static const int NUM_POOL_BLOCKS = 100;
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr;
uavcan::TransferPerfCounter perf; 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) * Generating transfers with damaged payload (CRC is not valid)
@@ -140,7 +140,7 @@ TEST(TransferListener, BasicSFT)
static const int NUM_POOL_BLOCKS = 100; static const int NUM_POOL_BLOCKS = 100;
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr;
uavcan::TransferPerfCounter perf; 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); TransferListenerEmulator emulator(subscriber, type);
const Transfer transfers[] = const Transfer transfers[] =
@@ -176,7 +176,7 @@ TEST(TransferListener, Cleanup)
static const int NUM_POOL_BLOCKS = 100; static const int NUM_POOL_BLOCKS = 100;
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr;
uavcan::TransferPerfCounter perf; uavcan::TransferPerfCounter perf;
TestListener<256> subscriber(perf, type, poolmgr); // Static buffer only, 1 entry TestListener subscriber(perf, type, 256, poolmgr);
/* /*
* Generating transfers * Generating transfers
@@ -208,7 +208,7 @@ TEST(TransferListener, Cleanup)
/* /*
* Cleanup with huge timestamp value will remove all entries * Cleanup with huge timestamp value will remove all entries
*/ */
static_cast<uavcan::TransferListenerBase&>(subscriber).cleanup(tsMono(100000000)); static_cast<uavcan::TransferListener&>(subscriber).cleanup(tsMono(100000000));
/* /*
* Sending the same transfers again - they will be accepted since registres were cleared * 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; static const int NUM_POOL_BLOCKS = 100;
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * NUM_POOL_BLOCKS, uavcan::MemPoolBlockSize> poolmgr;
uavcan::TransferPerfCounter perf; uavcan::TransferPerfCounter perf;
TestListener<0> subscriber(perf, type, poolmgr); TestListener subscriber(perf, type, 0, poolmgr);
TransferListenerEmulator emulator(subscriber, type); TransferListenerEmulator emulator(subscriber, type);
const Transfer transfers[] = const Transfer transfers[] =
@@ -264,5 +264,5 @@ TEST(TransferListener, Sizes)
{ {
using namespace uavcan; using namespace uavcan;
std::cout << "sizeof(TransferListener<64>): " << sizeof(TransferListener<64>) << std::endl; std::cout << "sizeof(TransferListener): " << sizeof(TransferListener) << std::endl;
} }
+10 -10
View File
@@ -76,10 +76,10 @@ struct Context
{ {
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 100, uavcan::MemPoolBlockSize> pool; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 100, uavcan::MemPoolBlockSize> pool;
uavcan::TransferReceiver receiver; // Must be default constructible and copyable uavcan::TransferReceiver receiver; // Must be default constructible and copyable
uavcan::TransferBufferManager<BufSize> bufmgr; uavcan::TransferBufferManager bufmgr;
Context() : Context() :
bufmgr(pool) bufmgr(BufSize, pool)
{ } { }
~Context() ~Context()
@@ -122,7 +122,7 @@ TEST(TransferReceiver, Basic)
Context<32> context; Context<32> context;
RxFrameGenerator gen(789); RxFrameGenerator gen(789);
uavcan::TransferReceiver& rcv = context.receiver; uavcan::TransferReceiver& rcv = context.receiver;
uavcan::ITransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferManager& bufmgr = context.bufmgr;
uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY);
std::cout << "sizeof(TransferReceiver): " << sizeof(TransferReceiver) << std::endl; std::cout << "sizeof(TransferReceiver): " << sizeof(TransferReceiver) << std::endl;
@@ -261,7 +261,7 @@ TEST(TransferReceiver, OutOfBufferSpace_32bytes)
Context<32> context; Context<32> context;
RxFrameGenerator gen(789); RxFrameGenerator gen(789);
uavcan::TransferReceiver& rcv = context.receiver; uavcan::TransferReceiver& rcv = context.receiver;
uavcan::ITransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferManager& bufmgr = context.bufmgr;
uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY);
/* /*
@@ -299,7 +299,7 @@ TEST(TransferReceiver, OutOfOrderFrames)
Context<32> context; Context<32> context;
RxFrameGenerator gen(789); RxFrameGenerator gen(789);
uavcan::TransferReceiver& rcv = context.receiver; uavcan::TransferReceiver& rcv = context.receiver;
uavcan::ITransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferManager& bufmgr = context.bufmgr;
uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY);
CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 7, 100000000), bk)); CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "1234567", SET100, 7, 100000000), bk));
@@ -323,7 +323,7 @@ TEST(TransferReceiver, IntervalMeasurement)
Context<32> context; Context<32> context;
RxFrameGenerator gen(789); RxFrameGenerator gen(789);
uavcan::TransferReceiver& rcv = context.receiver; uavcan::TransferReceiver& rcv = context.receiver;
uavcan::ITransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferManager& bufmgr = context.bufmgr;
uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY);
static const int INTERVAL = 1000; static const int INTERVAL = 1000;
@@ -353,7 +353,7 @@ TEST(TransferReceiver, Restart)
Context<32> context; Context<32> context;
RxFrameGenerator gen(789); RxFrameGenerator gen(789);
uavcan::TransferReceiver& rcv = context.receiver; uavcan::TransferReceiver& rcv = context.receiver;
uavcan::ITransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferManager& bufmgr = context.bufmgr;
uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY);
/* /*
@@ -401,7 +401,7 @@ TEST(TransferReceiver, UtcTransferTimestamping)
Context<32> context; Context<32> context;
RxFrameGenerator gen(789); RxFrameGenerator gen(789);
uavcan::TransferReceiver& rcv = context.receiver; uavcan::TransferReceiver& rcv = context.receiver;
uavcan::ITransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferManager& bufmgr = context.bufmgr;
uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY); uavcan::TransferBufferAccessor bk(context.bufmgr, RxFrameGenerator::DEFAULT_KEY);
/* /*
@@ -460,7 +460,7 @@ TEST(TransferReceiver, HeaderParsing)
Context<32> context; Context<32> context;
RxFrameGenerator gen(123); RxFrameGenerator gen(123);
uavcan::TransferReceiver& rcv = context.receiver; uavcan::TransferReceiver& rcv = context.receiver;
uavcan::ITransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferManager& bufmgr = context.bufmgr;
/* /*
* MFT, message broadcasting * MFT, message broadcasting
@@ -507,7 +507,7 @@ TEST(TransferReceiver, HeaderParsing)
Context<32> context; Context<32> context;
RxFrameGenerator gen(123); RxFrameGenerator gen(123);
uavcan::TransferReceiver& rcv = context.receiver; uavcan::TransferReceiver& rcv = context.receiver;
uavcan::ITransferBufferManager& bufmgr = context.bufmgr; uavcan::TransferBufferManager& bufmgr = context.bufmgr;
static const uavcan::TransferType ADDRESSED_TRANSFER_TYPES[2] = static const uavcan::TransferType ADDRESSED_TRANSFER_TYPES[2] =
{ {
+3 -3
View File
@@ -123,9 +123,9 @@ TEST(TransferSender, Basic)
} }
} }
TestListener<512> sub_msg(dispatcher_rx.getTransferPerfCounter(), TYPES[0], poolmgr); TestListener sub_msg(dispatcher_rx.getTransferPerfCounter(), TYPES[0], 512, poolmgr);
TestListener<512> sub_srv_req(dispatcher_rx.getTransferPerfCounter(), TYPES[1], poolmgr); TestListener sub_srv_req(dispatcher_rx.getTransferPerfCounter(), TYPES[1], 512, poolmgr);
TestListener<512> sub_srv_resp(dispatcher_rx.getTransferPerfCounter(), TYPES[1], poolmgr); TestListener sub_srv_resp(dispatcher_rx.getTransferPerfCounter(), TYPES[1], 512, poolmgr);
dispatcher_rx.registerMessageListener(&sub_msg); dispatcher_rx.registerMessageListener(&sub_msg);
dispatcher_rx.registerServiceRequestListener(&sub_srv_req); dispatcher_rx.registerServiceRequestListener(&sub_srv_req);
@@ -11,7 +11,7 @@ TEST(TransferTestHelpers, Transfer)
{ {
uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool; uavcan::PoolAllocator<uavcan::MemPoolBlockSize * 8, uavcan::MemPoolBlockSize> pool;
uavcan::TransferBufferManager<128> mgr(pool); uavcan::TransferBufferManager mgr(128, pool);
uavcan::TransferBufferAccessor tba(mgr, uavcan::TransferBufferManagerKey(0, uavcan::TransferTypeMessageBroadcast)); uavcan::TransferBufferAccessor tba(mgr, uavcan::TransferBufferManagerKey(0, uavcan::TransferTypeMessageBroadcast));
uavcan::RxFrame frame(uavcan::Frame(123, uavcan::TransferTypeMessageBroadcast, 1, 0, 0), uavcan::RxFrame frame(uavcan::Frame(123, uavcan::TransferTypeMessageBroadcast, 1, 0, 0),
@@ -117,17 +117,16 @@ struct Transfer
* In reality, uavcan::TransferListener should accept only specific transfer types * In reality, uavcan::TransferListener should accept only specific transfer types
* which are dispatched/filtered by uavcan::Dispatcher. * which are dispatched/filtered by uavcan::Dispatcher.
*/ */
template <unsigned MAX_BUF_SIZE> class TestListener : public uavcan::TransferListener
class TestListener : public uavcan::TransferListener<MAX_BUF_SIZE>
{ {
typedef uavcan::TransferListener<MAX_BUF_SIZE> Base; typedef uavcan::TransferListener Base;
std::queue<Transfer> transfers_; std::queue<Transfer> transfers_;
public: public:
TestListener(uavcan::TransferPerfCounter& perf, const uavcan::DataTypeDescriptor& data_type, TestListener(uavcan::TransferPerfCounter& perf, const uavcan::DataTypeDescriptor& data_type,
uavcan::IPoolAllocator& allocator) uavcan::uint16_t max_buffer_size, uavcan::IPoolAllocator& allocator)
: Base(perf, data_type, allocator) : Base(perf, data_type, max_buffer_size, allocator)
{ } { }
void handleIncomingTransfer(uavcan::IncomingTransfer& transfer) void handleIncomingTransfer(uavcan::IncomingTransfer& transfer)
@@ -166,7 +165,7 @@ public:
return res; return res;
} }
int getNumReceivedTransfers() const { return transfers_.size(); } unsigned getNumReceivedTransfers() const { return static_cast<unsigned>(transfers_.size()); }
bool isEmpty() const { return transfers_.empty(); } bool isEmpty() const { return transfers_.empty(); }
}; };