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