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