mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-07-02 15:30:34 +08:00
Transfer buffering system detemplatized; compiles but tests are failing
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user