Transfer buffering system detemplatized; compiles but tests are failing

This commit is contained in:
Pavel Kirienko
2015-10-14 19:58:51 +03:00
parent 763e96b6ed
commit a9fdf44fa9
20 changed files with 335 additions and 510 deletions
+3 -3
View File
@@ -7,8 +7,8 @@
namespace uavcan
{
int GenericSubscriberBase::genericStart(TransferListenerBase* listener,
bool (Dispatcher::*registration_method)(TransferListenerBase*))
int GenericSubscriberBase::genericStart(TransferListener* listener,
bool (Dispatcher::*registration_method)(TransferListener*))
{
if (listener == NULL)
{
@@ -24,7 +24,7 @@ int GenericSubscriberBase::genericStart(TransferListenerBase* listener,
return 0;
}
void GenericSubscriberBase::stop(TransferListenerBase* listener)
void GenericSubscriberBase::stop(TransferListener* listener)
{
if (listener != NULL)
{
@@ -38,8 +38,8 @@ int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration(AnonymousMessage
return -ErrMemory;
}
const TransferListenerBase* p = node_.getDispatcher().getListOfMessageListeners().get();
while (p)
const TransferListener* p = node_.getDispatcher().getListOfMessageListeners().get();
while (p != NULL)
{
CanFilterConfig cfg;
cfg.id = static_cast<uint32_t>(p->getDataTypeDescriptor().getID().get()) << 8;
+14 -14
View File
@@ -72,11 +72,11 @@ void LoopbackFrameListenerRegistry::invokeListeners(RxFrame& frame)
/*
* Dispatcher::ListenerRegister
*/
bool Dispatcher::ListenerRegistry::add(TransferListenerBase* listener, Mode mode)
bool Dispatcher::ListenerRegistry::add(TransferListener* listener, Mode mode)
{
if (mode == UniqueListener)
{
TransferListenerBase* p = list_.get();
TransferListener* p = list_.get();
while (p)
{
if (p->getDataTypeDescriptor().getID() == listener->getDataTypeDescriptor().getID())
@@ -91,14 +91,14 @@ bool Dispatcher::ListenerRegistry::add(TransferListenerBase* listener, Mode mode
return true;
}
void Dispatcher::ListenerRegistry::remove(TransferListenerBase* listener)
void Dispatcher::ListenerRegistry::remove(TransferListener* listener)
{
list_.remove(listener);
}
bool Dispatcher::ListenerRegistry::exists(DataTypeID dtid) const
{
TransferListenerBase* p = list_.get();
TransferListener* p = list_.get();
while (p)
{
if (p->getDataTypeDescriptor().getID() == dtid)
@@ -112,10 +112,10 @@ bool Dispatcher::ListenerRegistry::exists(DataTypeID dtid) const
void Dispatcher::ListenerRegistry::cleanup(MonotonicTime ts)
{
TransferListenerBase* p = list_.get();
TransferListener* p = list_.get();
while (p)
{
TransferListenerBase* const next = p->getNextListNode();
TransferListener* const next = p->getNextListNode();
p->cleanup(ts); // p may be modified
p = next;
}
@@ -123,10 +123,10 @@ void Dispatcher::ListenerRegistry::cleanup(MonotonicTime ts)
void Dispatcher::ListenerRegistry::handleFrame(const RxFrame& frame)
{
TransferListenerBase* p = list_.get();
TransferListener* p = list_.get();
while (p)
{
TransferListenerBase* const next = p->getNextListNode();
TransferListener* const next = p->getNextListNode();
if (p->getDataTypeDescriptor().getID() == frame.getDataTypeID())
{
p->handleFrame(frame); // p may be modified
@@ -311,7 +311,7 @@ void Dispatcher::cleanup(MonotonicTime ts)
lsrv_resp_.cleanup(ts);
}
bool Dispatcher::registerMessageListener(TransferListenerBase* listener)
bool Dispatcher::registerMessageListener(TransferListener* listener)
{
if (listener->getDataTypeDescriptor().getKind() != DataTypeKindMessage)
{
@@ -321,7 +321,7 @@ bool Dispatcher::registerMessageListener(TransferListenerBase* listener)
return lmsg_.add(listener, ListenerRegistry::ManyListeners); // Multiple subscribers are OK
}
bool Dispatcher::registerServiceRequestListener(TransferListenerBase* listener)
bool Dispatcher::registerServiceRequestListener(TransferListener* listener)
{
if (listener->getDataTypeDescriptor().getKind() != DataTypeKindService)
{
@@ -331,7 +331,7 @@ bool Dispatcher::registerServiceRequestListener(TransferListenerBase* listener)
return lsrv_req_.add(listener, ListenerRegistry::UniqueListener); // Only one server per data type
}
bool Dispatcher::registerServiceResponseListener(TransferListenerBase* listener)
bool Dispatcher::registerServiceResponseListener(TransferListener* listener)
{
if (listener->getDataTypeDescriptor().getKind() != DataTypeKindService)
{
@@ -341,17 +341,17 @@ bool Dispatcher::registerServiceResponseListener(TransferListenerBase* listener)
return lsrv_resp_.add(listener, ListenerRegistry::ManyListeners); // Multiple callers may call same srv
}
void Dispatcher::unregisterMessageListener(TransferListenerBase* listener)
void Dispatcher::unregisterMessageListener(TransferListener* listener)
{
lmsg_.remove(listener);
}
void Dispatcher::unregisterServiceRequestListener(TransferListenerBase* listener)
void Dispatcher::unregisterServiceRequestListener(TransferListener* listener)
{
lsrv_req_.remove(listener);
}
void Dispatcher::unregisterServiceResponseListener(TransferListenerBase* listener)
void Dispatcher::unregisterServiceResponseListener(TransferListener* listener)
{
lsrv_resp_.remove(listener);
}
+95 -117
View File
@@ -8,6 +8,58 @@
namespace uavcan
{
/*
* StaticTransferBufferImpl
*/
int StaticTransferBufferImpl::read(unsigned offset, uint8_t* data, unsigned len) const
{
if (!data)
{
UAVCAN_ASSERT(0);
return -ErrInvalidParam;
}
if (offset >= max_write_pos_)
{
return 0;
}
if ((offset + len) > max_write_pos_)
{
len = max_write_pos_ - offset;
}
UAVCAN_ASSERT((offset + len) <= max_write_pos_);
(void)copy(data_ + offset, data_ + offset + len, data);
return int(len);
}
int StaticTransferBufferImpl::write(unsigned offset, const uint8_t* data, unsigned len)
{
if (!data)
{
UAVCAN_ASSERT(0);
return -ErrInvalidParam;
}
if (offset >= size_)
{
return 0;
}
if ((offset + len) > size_)
{
len = size_ - offset;
}
UAVCAN_ASSERT((offset + len) <= size_);
(void)copy(data, data + len, data_ + offset);
max_write_pos_ = max(uint16_t(offset + len), uint16_t(max_write_pos_));
return int(len);
}
void StaticTransferBufferImpl::reset()
{
max_write_pos_ = 0;
#if UAVCAN_DEBUG
fill(data_, data_ + size_, uint8_t(0));
#endif
}
/*
* TransferBufferManagerKey
*/
@@ -23,8 +75,8 @@ std::string TransferBufferManagerKey::toString() const
/*
* DynamicTransferBuffer::Block
*/
DynamicTransferBufferManagerEntry::Block*
DynamicTransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator)
TransferBufferManagerEntry::Block*
TransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator)
{
void* const praw = allocator.allocate(sizeof(Block));
if (praw == NULL)
@@ -34,7 +86,7 @@ DynamicTransferBufferManagerEntry::Block::instantiate(IPoolAllocator& allocator)
return new (praw) Block;
}
void DynamicTransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocator& allocator)
void TransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocator& allocator)
{
if (obj != NULL)
{
@@ -44,8 +96,8 @@ void DynamicTransferBufferManagerEntry::Block::destroy(Block*& obj, IPoolAllocat
}
}
void DynamicTransferBufferManagerEntry::Block::read(uint8_t*& outptr, unsigned target_offset,
unsigned& total_offset, unsigned& left_to_read)
void TransferBufferManagerEntry::Block::read(uint8_t*& outptr, unsigned target_offset,
unsigned& total_offset, unsigned& left_to_read)
{
UAVCAN_ASSERT(outptr);
for (unsigned i = 0; (i < Block::Size) && (left_to_read > 0); i++, total_offset++)
@@ -58,7 +110,7 @@ void DynamicTransferBufferManagerEntry::Block::read(uint8_t*& outptr, unsigned t
}
}
void DynamicTransferBufferManagerEntry::Block::write(const uint8_t*& inptr, unsigned target_offset,
void TransferBufferManagerEntry::Block::write(const uint8_t*& inptr, unsigned target_offset,
unsigned& total_offset, unsigned& left_to_write)
{
UAVCAN_ASSERT(inptr);
@@ -75,46 +127,28 @@ void DynamicTransferBufferManagerEntry::Block::write(const uint8_t*& inptr, unsi
/*
* DynamicTransferBuffer
*/
DynamicTransferBufferManagerEntry* DynamicTransferBufferManagerEntry::instantiate(IPoolAllocator& allocator,
TransferBufferManagerEntry* TransferBufferManagerEntry::instantiate(IPoolAllocator& allocator,
uint16_t max_size)
{
void* const praw = allocator.allocate(sizeof(DynamicTransferBufferManagerEntry));
void* const praw = allocator.allocate(sizeof(TransferBufferManagerEntry));
if (praw == NULL)
{
return NULL;
}
return new (praw) DynamicTransferBufferManagerEntry(allocator, max_size);
return new (praw) TransferBufferManagerEntry(allocator, max_size);
}
void DynamicTransferBufferManagerEntry::destroy(DynamicTransferBufferManagerEntry*& obj, IPoolAllocator& allocator)
void TransferBufferManagerEntry::destroy(TransferBufferManagerEntry*& obj, IPoolAllocator& allocator)
{
if (obj != NULL)
{
obj->~DynamicTransferBufferManagerEntry();
obj->~TransferBufferManagerEntry();
allocator.deallocate(obj);
obj = NULL;
}
}
void DynamicTransferBufferManagerEntry::doReset()
{
max_write_pos_ = 0;
Block* p = blocks_.get();
while (p)
{
Block* const next = p->getNextListNode();
blocks_.remove(p);
Block::destroy(p, allocator_);
p = next;
}
}
void DynamicTransferBufferManagerEntry::resetImpl()
{
doReset();
}
int DynamicTransferBufferManagerEntry::read(unsigned offset, uint8_t* data, unsigned len) const
int TransferBufferManagerEntry::read(unsigned offset, uint8_t* data, unsigned len) const
{
if (!data)
{
@@ -150,7 +184,7 @@ int DynamicTransferBufferManagerEntry::read(unsigned offset, uint8_t* data, unsi
return int(len);
}
int DynamicTransferBufferManagerEntry::write(unsigned offset, const uint8_t* data, unsigned len)
int TransferBufferManagerEntry::write(unsigned offset, const uint8_t* data, unsigned len)
{
if (!data)
{
@@ -221,82 +255,26 @@ int DynamicTransferBufferManagerEntry::write(unsigned offset, const uint8_t* dat
return int(actually_written);
}
/*
* StaticTransferBufferImpl
*/
int StaticTransferBufferImpl::read(unsigned offset, uint8_t* data, unsigned len) const
{
if (!data)
{
UAVCAN_ASSERT(0);
return -ErrInvalidParam;
}
if (offset >= max_write_pos_)
{
return 0;
}
if ((offset + len) > max_write_pos_)
{
len = max_write_pos_ - offset;
}
UAVCAN_ASSERT((offset + len) <= max_write_pos_);
(void)copy(data_ + offset, data_ + offset + len, data);
return int(len);
}
int StaticTransferBufferImpl::write(unsigned offset, const uint8_t* data, unsigned len)
{
if (!data)
{
UAVCAN_ASSERT(0);
return -ErrInvalidParam;
}
if (offset >= size_)
{
return 0;
}
if ((offset + len) > size_)
{
len = size_ - offset;
}
UAVCAN_ASSERT((offset + len) <= size_);
(void)copy(data, data + len, data_ + offset);
max_write_pos_ = max(uint16_t(offset + len), uint16_t(max_write_pos_));
return int(len);
}
void StaticTransferBufferImpl::reset()
void TransferBufferManagerEntry::reset(const TransferBufferManagerKey& key)
{
key_ = key;
max_write_pos_ = 0;
#if UAVCAN_DEBUG
fill(data_, data_ + size_, uint8_t(0));
#endif
Block* p = blocks_.get();
while (p)
{
Block* const next = p->getNextListNode();
blocks_.remove(p);
Block::destroy(p, allocator_);
p = next;
}
}
/*
* StaticTransferBufferManagerEntryImpl
* TransferBufferManager
*/
void StaticTransferBufferManagerEntryImpl::resetImpl()
TransferBufferManagerEntry* TransferBufferManager::findFirst(const TransferBufferManagerKey& key)
{
buf_.reset();
}
int StaticTransferBufferManagerEntryImpl::read(unsigned offset, uint8_t* data, unsigned len) const
{
return buf_.read(offset, data, len);
}
int StaticTransferBufferManagerEntryImpl::write(unsigned offset, const uint8_t* data, unsigned len)
{
return buf_.write(offset, data, len);
}
/*
* TransferBufferManagerImpl
*/
DynamicTransferBufferManagerEntry* TransferBufferManagerImpl::findFirstDynamic(const TransferBufferManagerKey& key)
{
DynamicTransferBufferManagerEntry* dyn = dynamic_buffers_.get();
TransferBufferManagerEntry* dyn = buffers_.get();
while (dyn)
{
UAVCAN_ASSERT(!dyn->isEmpty());
@@ -309,29 +287,29 @@ DynamicTransferBufferManagerEntry* TransferBufferManagerImpl::findFirstDynamic(c
return NULL;
}
TransferBufferManagerImpl::~TransferBufferManagerImpl()
TransferBufferManager::~TransferBufferManager()
{
DynamicTransferBufferManagerEntry* dyn = dynamic_buffers_.get();
TransferBufferManagerEntry* dyn = buffers_.get();
while (dyn)
{
DynamicTransferBufferManagerEntry* const next = dyn->getNextListNode();
dynamic_buffers_.remove(dyn);
DynamicTransferBufferManagerEntry::destroy(dyn, allocator_);
TransferBufferManagerEntry* const next = dyn->getNextListNode();
buffers_.remove(dyn);
TransferBufferManagerEntry::destroy(dyn, allocator_);
dyn = next;
}
}
ITransferBuffer* TransferBufferManagerImpl::access(const TransferBufferManagerKey& key)
ITransferBuffer* TransferBufferManager::access(const TransferBufferManagerKey& key)
{
if (key.isEmpty())
{
UAVCAN_ASSERT(0);
return NULL;
}
return findFirstDynamic(key);
return findFirst(key);
}
ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKey& key)
ITransferBuffer* TransferBufferManager::create(const TransferBufferManagerKey& key)
{
if (key.isEmpty())
{
@@ -340,13 +318,13 @@ ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKe
}
remove(key);
DynamicTransferBufferManagerEntry* tbme = DynamicTransferBufferManagerEntry::instantiate(allocator_, max_buf_size_);
TransferBufferManagerEntry* tbme = TransferBufferManagerEntry::instantiate(allocator_, max_buf_size_);
if (tbme == NULL)
{
return NULL; // Epic fail.
}
dynamic_buffers_.insert(tbme);
buffers_.insert(tbme);
UAVCAN_TRACE("TransferBufferManager", "Buffer created [num=%u], %s", getNumBuffers(), key.toString().c_str());
@@ -358,27 +336,27 @@ ITransferBuffer* TransferBufferManagerImpl::create(const TransferBufferManagerKe
return tbme;
}
void TransferBufferManagerImpl::remove(const TransferBufferManagerKey& key)
void TransferBufferManager::remove(const TransferBufferManagerKey& key)
{
UAVCAN_ASSERT(!key.isEmpty());
DynamicTransferBufferManagerEntry* dyn = findFirstDynamic(key);
TransferBufferManagerEntry* dyn = findFirst(key);
if (dyn != NULL)
{
UAVCAN_TRACE("TransferBufferManager", "Buffer deleted, %s", key.toString().c_str());
dynamic_buffers_.remove(dyn);
DynamicTransferBufferManagerEntry::destroy(dyn, allocator_);
buffers_.remove(dyn);
TransferBufferManagerEntry::destroy(dyn, allocator_);
}
}
bool TransferBufferManagerImpl::isEmpty() const
bool TransferBufferManager::isEmpty() const
{
return getNumBuffers() == 0;
}
unsigned TransferBufferManagerImpl::getNumBuffers() const
unsigned TransferBufferManager::getNumBuffers() const
{
return dynamic_buffers_.getLength();
return buffers_.getLength();
}
}
@@ -80,10 +80,10 @@ int MultiFrameIncomingTransfer::read(unsigned offset, uint8_t* data, unsigned le
}
/*
* TransferListenerBase::TimedOutReceiverPredicate
* TransferListener::TimedOutReceiverPredicate
*/
bool TransferListenerBase::TimedOutReceiverPredicate::operator()(const TransferBufferManagerKey& key,
const TransferReceiver& value) const
bool TransferListener::TimedOutReceiverPredicate::operator()(const TransferBufferManagerKey& key,
const TransferReceiver& value) const
{
if (value.isTimedOut(ts_))
{
@@ -101,9 +101,9 @@ bool TransferListenerBase::TimedOutReceiverPredicate::operator()(const TransferB
}
/*
* TransferListenerBase
* TransferListener
*/
bool TransferListenerBase::checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const
bool TransferListener::checkPayloadCrc(const uint16_t compare_with, const ITransferBuffer& tbb) const
{
TransferCRC crc = crc_base_;
unsigned offset = 0;
@@ -113,7 +113,7 @@ bool TransferListenerBase::checkPayloadCrc(const uint16_t compare_with, const IT
const int res = tbb.read(offset, buf, sizeof(buf));
if (res < 0)
{
UAVCAN_TRACE("TransferListenerBase", "Failed to check CRC: Buffer read failure %i", res);
UAVCAN_TRACE("TransferListener", "Failed to check CRC: Buffer read failure %i", res);
return false;
}
if (res == 0)
@@ -125,14 +125,14 @@ bool TransferListenerBase::checkPayloadCrc(const uint16_t compare_with, const IT
}
if (crc.get() != compare_with)
{
UAVCAN_TRACE("TransferListenerBase", "CRC mismatch, expected=0x%04x, got=0x%04x",
UAVCAN_TRACE("TransferListener", "CRC mismatch, expected=0x%04x, got=0x%04x",
int(compare_with), int(crc.get()));
return false;
}
return true;
}
void TransferListenerBase::handleReception(TransferReceiver& receiver, const RxFrame& frame,
void TransferListener::handleReception(TransferReceiver& receiver, const RxFrame& frame,
TransferBufferAccessor& tba)
{
switch (receiver.addFrame(frame, tba))
@@ -155,12 +155,12 @@ void TransferListenerBase::handleReception(TransferReceiver& receiver, const RxF
const ITransferBuffer* tbb = tba.access();
if (tbb == NULL)
{
UAVCAN_TRACE("TransferListenerBase", "Buffer access failure, last frame: %s", frame.toString().c_str());
UAVCAN_TRACE("TransferListener", "Buffer access failure, last frame: %s", frame.toString().c_str());
break;
}
if (!checkPayloadCrc(receiver.getLastTransferCrc(), *tbb))
{
UAVCAN_TRACE("TransferListenerBase", "CRC error, last frame: %s", frame.toString().c_str());
UAVCAN_TRACE("TransferListener", "CRC error, last frame: %s", frame.toString().c_str());
break;
}
MultiFrameIncomingTransfer it(receiver.getLastTransferTimestampMonotonic(),
@@ -177,7 +177,7 @@ void TransferListenerBase::handleReception(TransferReceiver& receiver, const RxF
}
}
void TransferListenerBase::handleAnonymousTransferReception(const RxFrame& frame)
void TransferListener::handleAnonymousTransferReception(const RxFrame& frame)
{
if (allow_anonymous_transfers_)
{
@@ -187,13 +187,13 @@ void TransferListenerBase::handleAnonymousTransferReception(const RxFrame& frame
}
}
void TransferListenerBase::cleanup(MonotonicTime ts)
void TransferListener::cleanup(MonotonicTime ts)
{
receivers_.removeAllWhere(TimedOutReceiverPredicate(ts, bufmgr_));
UAVCAN_ASSERT(receivers_.isEmpty() ? bufmgr_.isEmpty() : 1);
}
void TransferListenerBase::handleFrame(const RxFrame& frame)
void TransferListener::handleFrame(const RxFrame& frame)
{
if (frame.getSrcNodeID().isUnicast()) // Normal transfer
{
@@ -227,7 +227,25 @@ void TransferListenerBase::handleFrame(const RxFrame& frame)
}
else
{
UAVCAN_TRACE("TransferListenerBase", "Invalid frame: %s", frame.toString().c_str()); // Invalid frame
UAVCAN_TRACE("TransferListener", "Invalid frame: %s", frame.toString().c_str()); // Invalid frame
}
}
/*
* TransferListenerWithFilter
*/
void TransferListenerWithFilter::handleFrame(const RxFrame& frame)
{
if (filter_ != NULL)
{
if (filter_->shouldAcceptFrame(frame))
{
TransferListener::handleFrame(frame);
}
}
else
{
UAVCAN_ASSERT(0);
}
}