TransferBufferManager: using TransferBufferManagerKey instead of plain Node ID, this allows to distinguish transfers of different type from the same Node ID, which is necessary for message broadcasting/unicasting

This commit is contained in:
Pavel Kirienko 2014-02-11 12:21:25 +04:00
parent 149ac87a54
commit 78ff31f9ad
6 changed files with 150 additions and 90 deletions

View File

@ -30,24 +30,63 @@ public:
/**
* Internal for TransferBufferManager
*/
class TransferBufferManagerEntry : public TransferBufferBase, Noncopyable
class TransferBufferManagerKey
{
uint8_t node_id_;
uint8_t transfer_type_;
public:
TransferBufferManagerKey()
: node_id_(NODE_ID_INVALID)
, transfer_type_(TransferType(0))
{
assert(isEmpty());
}
TransferBufferManagerKey(uint8_t node_id, TransferType ttype)
: node_id_(node_id)
, transfer_type_(ttype)
{
assert(node_id <= NODE_ID_MAX && node_id != NODE_ID_INVALID);
assert(!isEmpty());
}
bool operator==(const TransferBufferManagerKey& rhs) const
{
return node_id_ == rhs.node_id_ && transfer_type_ == rhs.transfer_type_;
}
bool isEmpty() const { return node_id_ == NODE_ID_INVALID; }
uint8_t getNodeID() const { return node_id_; }
TransferType getTransferType() const { return TransferType(transfer_type_); }
std::string toString() const;
};
/**
* Internal for TransferBufferManager
*/
class TransferBufferManagerEntry : public TransferBufferBase, Noncopyable
{
TransferBufferManagerKey key_;
protected:
virtual void resetImpl() = 0;
public:
TransferBufferManagerEntry(uint8_t node_id = NODE_ID_INVALID)
: node_id_(node_id)
TransferBufferManagerEntry() { }
TransferBufferManagerEntry(const TransferBufferManagerKey& key)
: key_(key)
{ }
uint8_t getNodeID() const { return node_id_; }
bool isEmpty() const { return node_id_ == NODE_ID_INVALID; }
const TransferBufferManagerKey& getKey() const { return key_; }
bool isEmpty() const { return key_.isEmpty(); }
void reset(uint8_t node_id = NODE_ID_INVALID)
void reset(const TransferBufferManagerKey& key = TransferBufferManagerKey())
{
node_id_ = node_id;
key_ = key;
resetImpl();
}
};
@ -169,7 +208,7 @@ public:
}
// Resetting self and moving all data from the source
reset(tbme->getNodeID());
reset(tbme->getKey());
const int res = tbme->read(0, data_, SIZE);
if (res < 0)
{
@ -198,9 +237,9 @@ class ITransferBufferManager
{
public:
virtual ~ITransferBufferManager() { }
virtual TransferBufferBase* access(uint8_t node_id) = 0;
virtual TransferBufferBase* create(uint8_t node_id) = 0;
virtual void remove(uint8_t node_id) = 0;
virtual TransferBufferBase* access(const TransferBufferManagerKey& key) = 0;
virtual TransferBufferBase* create(const TransferBufferManagerKey& key) = 0;
virtual void remove(const TransferBufferManagerKey& key) = 0;
};
/**
@ -215,24 +254,23 @@ class TransferBufferManager : public ITransferBufferManager, Noncopyable
LinkedListRoot<DynamicTransferBuffer> dynamic_buffers_;
IAllocator* const allocator_;
StaticBufferType* findFirstStatic(uint8_t node_id)
StaticBufferType* findFirstStatic(const TransferBufferManagerKey& key)
{
assert((node_id == NODE_ID_INVALID) || (node_id <= NODE_ID_MAX));
for (unsigned int i = 0; i < NUM_STATIC_BUFS; i++)
{
if (static_buffers_[i].getNodeID() == node_id)
if (static_buffers_[i].getKey() == key)
return static_buffers_ + i;
}
return NULL;
}
DynamicTransferBuffer* findFirstDynamic(uint8_t node_id)
DynamicTransferBuffer* findFirstDynamic(const TransferBufferManagerKey& key)
{
DynamicTransferBuffer* dyn = dynamic_buffers_.get();
while (dyn)
{
assert(!dyn->isEmpty());
if (dyn->getNodeID() == node_id)
if (dyn->getKey() == key)
return dyn;
dyn = dyn->getNextListNode();
}
@ -243,7 +281,7 @@ class TransferBufferManager : public ITransferBufferManager, Noncopyable
{
while (!dynamic_buffers_.isEmpty())
{
StaticBufferType* const sb = findFirstStatic(NODE_ID_INVALID);
StaticBufferType* const sb = findFirstStatic(TransferBufferManagerKey());
if (sb == NULL)
break;
DynamicTransferBuffer* dyn = dynamic_buffers_.get();
@ -252,7 +290,8 @@ class TransferBufferManager : public ITransferBufferManager, Noncopyable
if (sb->migrateFrom(dyn))
{
assert(!dyn->isEmpty());
UAVCAN_TRACE("TransferBufferManager", "Storage optimization: Migrated NID %i", int(dyn->getNodeID()));
UAVCAN_TRACE("TransferBufferManager", "Storage optimization: Migrated %s",
dyn->getKey().toString().c_str());
dynamic_buffers_.remove(dyn);
DynamicTransferBuffer::destroy(dyn, allocator_);
}
@ -262,8 +301,8 @@ class TransferBufferManager : public ITransferBufferManager, Noncopyable
* than STATIC_BUF_SIZE). This means that there is probably something wrong with the network. Logic
* that uses this class should explicitly ensure the proper maximum data size.
*/
UAVCAN_TRACE("TransferBufferManager", "Storage optimization: MIGRATION FAILURE NID %i BUFSIZE %u",
int(dyn->getNodeID()), STATIC_BUF_SIZE);
UAVCAN_TRACE("TransferBufferManager", "Storage optimization: MIGRATION FAILURE %s BUFSIZE %u",
dyn->getKey().toString().c_str(), STATIC_BUF_SIZE);
sb->reset();
break; // Probably we should try to migrate the rest?
}
@ -300,29 +339,29 @@ public:
return res;
}
TransferBufferBase* access(uint8_t node_id)
TransferBufferBase* access(const TransferBufferManagerKey& key)
{
if (node_id > NODE_ID_MAX || node_id == NODE_ID_INVALID)
if (key.isEmpty())
{
assert(0);
return NULL;
}
TransferBufferManagerEntry* tbme = findFirstStatic(node_id);
TransferBufferManagerEntry* tbme = findFirstStatic(key);
if (tbme)
return tbme;
return findFirstDynamic(node_id);
return findFirstDynamic(key);
}
TransferBufferBase* create(uint8_t node_id)
TransferBufferBase* create(const TransferBufferManagerKey& key)
{
if (node_id > NODE_ID_MAX || node_id == NODE_ID_INVALID)
if (key.isEmpty())
{
assert(0);
return NULL;
}
remove(node_id);
remove(key);
TransferBufferManagerEntry* tbme = findFirstStatic(NODE_ID_INVALID);
TransferBufferManagerEntry* tbme = findFirstStatic(TransferBufferManagerKey());
if (tbme == NULL)
{
DynamicTransferBuffer* dyn = DynamicTransferBuffer::instantiate(allocator_);
@ -335,16 +374,16 @@ public:
if (tbme)
{
assert(tbme->isEmpty());
tbme->reset(node_id);
tbme->reset(key);
}
return tbme;
}
void remove(uint8_t node_id)
void remove(const TransferBufferManagerKey& key)
{
assert((node_id <= NODE_ID_MAX) && (node_id != NODE_ID_INVALID));
assert(!key.isEmpty());
TransferBufferManagerEntry* const tbme = findFirstStatic(node_id);
TransferBufferManagerEntry* const tbme = findFirstStatic(key);
if (tbme)
{
tbme->reset();
@ -352,7 +391,7 @@ public:
return;
}
DynamicTransferBuffer* dyn = findFirstDynamic(node_id);
DynamicTransferBuffer* dyn = findFirstDynamic(key);
if (dyn)
{
dynamic_buffers_.remove(dyn);

View File

@ -27,8 +27,8 @@ private:
uint64_t this_transfer_timestamp_;
uint64_t transfer_interval_;
ITransferBufferManager* bufmgr_;
TransferBufferManagerKey bufmgr_key_;
TransferID tid_;
uint8_t node_id_;
uint8_t iface_index_;
uint8_t next_frame_index_;
@ -52,24 +52,21 @@ public:
, this_transfer_timestamp_(0)
, transfer_interval_(DEFAULT_TRANSFER_INTERVAL)
, bufmgr_(NULL)
, node_id_(NODE_ID_INVALID)
, iface_index_(IFACE_INDEX_NOTSET)
, next_frame_index_(0)
{ }
TransferReceiver(ITransferBufferManager* bufmgr, uint8_t node_id)
TransferReceiver(ITransferBufferManager* bufmgr, const TransferBufferManagerKey& bufmgr_key)
: prev_transfer_timestamp_(0)
, this_transfer_timestamp_(0)
, transfer_interval_(DEFAULT_TRANSFER_INTERVAL)
, bufmgr_(bufmgr)
, node_id_(node_id)
, bufmgr_key_(bufmgr_key)
, iface_index_(IFACE_INDEX_NOTSET)
, next_frame_index_(0)
{
assert(bufmgr);
assert(node_id <= NODE_ID_MAX);
assert(node_id != NODE_ID_INVALID);
assert(node_id != NODE_ID_BROADCAST);
assert(bufmgr_key.getNodeID() != NODE_ID_BROADCAST);
}
~TransferReceiver() { cleanup(); }
@ -82,7 +79,7 @@ public:
transfer_interval_ = rhs.transfer_interval_;
bufmgr_ = rhs.bufmgr_;
tid_ = rhs.tid_;
node_id_ = rhs.node_id_;
bufmgr_key_ = rhs.bufmgr_key_;
iface_index_ = rhs.iface_index_;
next_frame_index_ = rhs.next_frame_index_;
return *this;

View File

@ -4,10 +4,22 @@
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <uavcan/internal/transport/transfer_buffer.hpp>
namespace uavcan
{
/*
* TransferBufferManagerKey
*/
std::string TransferBufferManagerKey::toString() const
{
char buf[24];
std::snprintf(buf, sizeof(buf), "nid:%i tt:%i", int(node_id_), int(transfer_type_));
return std::string(buf);
}
/*
* DynamicTransferBuffer::Block
*/

View File

@ -18,8 +18,8 @@ const uint64_t TransferReceiver::MAX_TRANSFER_INTERVAL;
void TransferReceiver::cleanup()
{
if (bufmgr_ != NULL && node_id_ != NODE_ID_INVALID)
bufmgr_->remove(node_id_);
if (bufmgr_ != NULL && !bufmgr_key_.isEmpty())
bufmgr_->remove(bufmgr_key_);
}
TransferReceiver::TidRelation TransferReceiver::getTidRelation(const RxFrame& frame) const
@ -99,15 +99,15 @@ TransferReceiver::ResultCode TransferReceiver::receive(const RxFrame& frame)
if ((frame.frame_index == 0) && frame.last_frame) // Single-frame transfer
{
bufmgr_->remove(node_id_);
bufmgr_->remove(bufmgr_key_);
updateTransferTimings();
prepareForNextTransfer();
return RESULT_SINGLE_FRAME;
}
TransferBufferBase* buf = bufmgr_->access(node_id_);
TransferBufferBase* buf = bufmgr_->access(bufmgr_key_);
if (buf == NULL)
buf = bufmgr_->create(node_id_);
buf = bufmgr_->create(bufmgr_key_);
if (buf == NULL)
{
UAVCAN_TRACE("TransferReceiver", "Failed to access the buffer, %s", frame.toString().c_str());
@ -119,7 +119,7 @@ TransferReceiver::ResultCode TransferReceiver::receive(const RxFrame& frame)
if (res != frame.payload_len)
{
UAVCAN_TRACE("TransferReceiver", "Buffer write failure [%i], %s", res, frame.toString().c_str());
bufmgr_->remove(node_id_);
bufmgr_->remove(bufmgr_key_);
prepareForNextTransfer();
return RESULT_NOT_COMPLETE;
}
@ -146,7 +146,8 @@ bool TransferReceiver::isTimedOut(uint64_t timestamp) const
TransferReceiver::ResultCode TransferReceiver::addFrame(const RxFrame& frame)
{
assert(bufmgr_);
assert(node_id_ == frame.source_node_id);
assert(bufmgr_key_.getNodeID() == frame.source_node_id);
assert(bufmgr_key_.getTransferType() == frame.transfer_type);
if ((frame.timestamp == 0) ||
(frame.timestamp < prev_transfer_timestamp_) ||
@ -174,7 +175,7 @@ TransferReceiver::ResultCode TransferReceiver::addFrame(const RxFrame& frame)
"Restart [not_inited=%i, iface_timeout=%i, recv_timeout=%i, same_iface=%i, first_frame=%i, tid_rel=%i], %s",
int(not_initialized), int(iface_timed_out), int(receiver_timed_out), int(same_iface), int(first_fame),
int(tid_rel), frame.toString().c_str());
bufmgr_->remove(node_id_);
bufmgr_->remove(bufmgr_key_);
iface_index_ = frame.iface_index;
tid_ = frame.transfer_id;
next_frame_index_ = 0;

View File

@ -232,6 +232,7 @@ static int fillTestData(const std::string& data, uavcan::TransferBufferBase* tbb
TEST(TransferBufferManager, Basic)
{
using uavcan::TransferBufferManager;
using uavcan::TransferBufferManagerKey;
using uavcan::TransferBufferBase;
static const int POOL_BLOCKS = 8;
@ -243,25 +244,34 @@ TEST(TransferBufferManager, Basic)
std::auto_ptr<TransferBufferManagerType> mgr(new TransferBufferManagerType(&poolmgr));
// Empty
ASSERT_FALSE(mgr->access(0));
ASSERT_FALSE(mgr->access(uavcan::NODE_ID_MAX));
ASSERT_FALSE(mgr->access(TransferBufferManagerKey(0, uavcan::TRANSFER_TYPE_MESSAGE_UNICAST)));
ASSERT_FALSE(mgr->access(TransferBufferManagerKey(uavcan::NODE_ID_MAX, uavcan::TRANSFER_TYPE_MESSAGE_UNICAST)));
TransferBufferBase* tbb = NULL;
const TransferBufferManagerKey keys[5] =
{
TransferBufferManagerKey(0, uavcan::TRANSFER_TYPE_MESSAGE_UNICAST),
TransferBufferManagerKey(1, uavcan::TRANSFER_TYPE_MESSAGE_BROADCAST),
TransferBufferManagerKey(2, uavcan::TRANSFER_TYPE_SERVICE_REQUEST),
TransferBufferManagerKey(127, uavcan::TRANSFER_TYPE_SERVICE_RESPONSE),
TransferBufferManagerKey(64, uavcan::TRANSFER_TYPE_MESSAGE_BROADCAST)
};
// Static 0
ASSERT_TRUE((tbb = mgr->create(0)));
ASSERT_TRUE((tbb = mgr->create(keys[0])));
ASSERT_EQ(MGR_STATIC_BUFFER_SIZE, fillTestData(MGR_TEST_DATA[0], tbb));
ASSERT_EQ(1, mgr->getNumStaticBuffers());
// Static 1
ASSERT_TRUE((tbb = mgr->create(1)));
ASSERT_TRUE((tbb = mgr->create(keys[1])));
ASSERT_EQ(MGR_STATIC_BUFFER_SIZE, fillTestData(MGR_TEST_DATA[1], tbb));
ASSERT_EQ(2, mgr->getNumStaticBuffers());
ASSERT_EQ(0, mgr->getNumDynamicBuffers());
ASSERT_EQ(0, pool.getNumUsedBlocks());
// Dynamic 0
ASSERT_TRUE((tbb = mgr->create(2)));
ASSERT_TRUE((tbb = mgr->create(keys[2])));
ASSERT_EQ(1, pool.getNumUsedBlocks()); // Empty dynamic buffer occupies one block
ASSERT_EQ(MGR_TEST_DATA[2].length(), fillTestData(MGR_TEST_DATA[2], tbb));
ASSERT_EQ(2, mgr->getNumStaticBuffers());
@ -271,7 +281,7 @@ TEST(TransferBufferManager, Basic)
std::cout << "TransferBufferManager - Basic: Pool usage: " << pool.getNumUsedBlocks() << std::endl;
// Dynamic 2
ASSERT_TRUE((tbb = mgr->create(127)));
ASSERT_TRUE((tbb = mgr->create(keys[3])));
ASSERT_EQ(0, pool.getNumFreeBlocks()); // The test assumes that the memory must be exhausted now
ASSERT_EQ(0, fillTestData(MGR_TEST_DATA[3], tbb));
@ -279,46 +289,46 @@ TEST(TransferBufferManager, Basic)
ASSERT_EQ(2, mgr->getNumDynamicBuffers());
// Dynamic 3 - will fail due to OOM
ASSERT_FALSE((tbb = mgr->create(64)));
ASSERT_FALSE((tbb = mgr->create(keys[4])));
ASSERT_EQ(2, mgr->getNumStaticBuffers());
ASSERT_EQ(2, mgr->getNumDynamicBuffers());
// Making sure all buffers contain proper data
ASSERT_TRUE((tbb = mgr->access(0)));
ASSERT_TRUE((tbb = mgr->access(keys[0])));
ASSERT_TRUE(matchAgainst(MGR_TEST_DATA[0], *tbb));
ASSERT_TRUE((tbb = mgr->access(1)));
ASSERT_TRUE((tbb = mgr->access(keys[1])));
ASSERT_TRUE(matchAgainst(MGR_TEST_DATA[1], *tbb));
ASSERT_TRUE((tbb = mgr->access(2)));
ASSERT_TRUE((tbb = mgr->access(keys[2])));
ASSERT_TRUE(matchAgainst(MGR_TEST_DATA[2], *tbb));
ASSERT_TRUE((tbb = mgr->access(127)));
ASSERT_TRUE((tbb = mgr->access(keys[3])));
ASSERT_TRUE(matchAgainst(MGR_TEST_DATA[3], *tbb));
// Freeing one static buffer; one dynamic must migrate
mgr->remove(1);
ASSERT_FALSE(mgr->access(1));
mgr->remove(keys[1]);
ASSERT_FALSE(mgr->access(keys[1]));
ASSERT_EQ(2, mgr->getNumStaticBuffers());
ASSERT_EQ(1, mgr->getNumDynamicBuffers()); // One migrated to the static
ASSERT_LT(0, pool.getNumFreeBlocks());
// Removing NodeID 0; migration should fail due to oversized data
mgr->remove(0);
ASSERT_FALSE(mgr->access(0));
mgr->remove(keys[0]);
ASSERT_FALSE(mgr->access(keys[0]));
ASSERT_EQ(1, mgr->getNumStaticBuffers());
ASSERT_EQ(1, mgr->getNumDynamicBuffers()); // Migration failed
// At this time we have the following NodeID: 2, 127
ASSERT_TRUE((tbb = mgr->access(2)));
ASSERT_TRUE((tbb = mgr->access(keys[2])));
ASSERT_TRUE(matchAgainst(MGR_TEST_DATA[2], *tbb));
ASSERT_TRUE((tbb = mgr->access(127)));
ASSERT_TRUE((tbb = mgr->access(keys[3])));
ASSERT_TRUE(matchAgainst(MGR_TEST_DATA[3], *tbb));
// These were deleted: 0, 1
ASSERT_FALSE(mgr->access(1));
ASSERT_FALSE(mgr->access(0));
ASSERT_FALSE(mgr->access(keys[1]));
ASSERT_FALSE(mgr->access(keys[0]));
// Deleting the object; all memory must be freed
ASSERT_NE(0, pool.getNumUsedBlocks());

View File

@ -11,16 +11,15 @@
struct RxFrameGenerator
{
static const uint8_t DEFAULT_NODE_ID = 42;
static const uavcan::TransferBufferManagerKey DEFAULT_KEY;
uint16_t data_type_id;
uavcan::TransferType ttype;
uint8_t source_node_id;
uavcan::TransferBufferManagerKey bufmgr_key;
RxFrameGenerator(uint16_t data_type_id, uavcan::TransferType ttype, uint8_t source_node_id = DEFAULT_NODE_ID)
RxFrameGenerator(uint16_t data_type_id, uavcan::TransferType ttype,
const uavcan::TransferBufferManagerKey& bufmgr_key = DEFAULT_KEY)
: data_type_id(data_type_id)
, ttype(ttype)
, source_node_id(source_node_id)
, bufmgr_key(bufmgr_key)
{ }
uavcan::RxFrame operator()(int iface_index, const std::string& data, uint8_t frame_index, bool last,
@ -42,14 +41,16 @@ struct RxFrameGenerator
frm.last_frame = last;
std::copy(data.begin(), data.end(), frm.payload);
frm.payload_len = data.length();
frm.source_node_id = source_node_id;
frm.source_node_id = bufmgr_key.getNodeID();
frm.transfer_id = uavcan::TransferID(transfer_id);
frm.transfer_type = ttype;
frm.transfer_type = bufmgr_key.getTransferType();
return frm;
}
};
const uavcan::TransferBufferManagerKey RxFrameGenerator::DEFAULT_KEY(42, uavcan::TRANSFER_TYPE_MESSAGE_UNICAST);
template <unsigned int BUFSIZE>
struct Context
@ -62,7 +63,7 @@ struct Context
: bufmgr(&poolmgr)
{
assert(poolmgr.allocate(1) == NULL);
receiver = uavcan::TransferReceiver(&bufmgr, RxFrameGenerator::DEFAULT_NODE_ID);
receiver = uavcan::TransferReceiver(&bufmgr, RxFrameGenerator::DEFAULT_KEY);
}
~Context()
@ -125,7 +126,7 @@ TEST(TransferReceiver, Basic)
CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "12345678", 0, false, 0, 100)));
CHECK_COMPLETE(rcv.addFrame(gen(0, "foo", 1, true, 0, 200)));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), "12345678foo"));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "12345678foo"));
ASSERT_EQ(TransferReceiver::DEFAULT_TRANSFER_INTERVAL, rcv.getInterval()); // Not initialized yet
ASSERT_EQ(100, rcv.getLastTransferTimestamp());
@ -142,7 +143,7 @@ TEST(TransferReceiver, Basic)
CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "", 31,true, 1, 1300))); // Unexpected FI
CHECK_COMPLETE( rcv.addFrame(gen(0, "", 2, true, 1, 1300)));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), "12345678abcdefgh"));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "12345678abcdefgh"));
ASSERT_GT(TransferReceiver::DEFAULT_TRANSFER_INTERVAL, rcv.getInterval());
ASSERT_LT(TransferReceiver::MIN_TRANSFER_INTERVAL, rcv.getInterval());
ASSERT_EQ(1000, rcv.getLastTransferTimestamp());
@ -157,7 +158,7 @@ TEST(TransferReceiver, Basic)
CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwe", 0, true, 2, 2100))); // Wrong iface
CHECK_SINGLE_FRAME(rcv.addFrame(gen(0, "qwe", 0, true, 2, 2200)));
ASSERT_FALSE(bufmgr.access(RxFrameGenerator::DEFAULT_NODE_ID)); // Buffer must be removed
ASSERT_FALSE(bufmgr.access(gen.bufmgr_key)); // Buffer must be removed
ASSERT_GT(TransferReceiver::DEFAULT_TRANSFER_INTERVAL, rcv.getInterval());
ASSERT_EQ(2200, rcv.getLastTransferTimestamp());
@ -203,14 +204,14 @@ TEST(TransferReceiver, Basic)
ASSERT_LT(TransferReceiver::DEFAULT_TRANSFER_INTERVAL, rcv.getInterval());
ASSERT_LE(TransferReceiver::MIN_TRANSFER_INTERVAL, rcv.getInterval());
ASSERT_GE(TransferReceiver::MAX_TRANSFER_INTERVAL, rcv.getInterval());
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), "12345678qwe"));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "12345678qwe"));
/*
* Buffer cleanup
*/
ASSERT_TRUE(bufmgr.access(gen.source_node_id));
ASSERT_TRUE(bufmgr.access(gen.bufmgr_key));
context.receiver = TransferReceiver();
ASSERT_FALSE(bufmgr.access(gen.source_node_id));
ASSERT_FALSE(bufmgr.access(gen.bufmgr_key));
}
@ -231,7 +232,7 @@ TEST(TransferReceiver, OutOfBufferSpace_32bytes)
CHECK_COMPLETE( rcv.addFrame(gen(1, "", 4, true, 10, 100000400))); // 32
ASSERT_EQ(100000000, rcv.getLastTransferTimestamp());
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), "12345678123456781234567812345678"));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "12345678123456781234567812345678"));
/*
* Transfer longer than available buffer space
@ -243,7 +244,7 @@ TEST(TransferReceiver, OutOfBufferSpace_32bytes)
CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "12345678", 4, true, 11, 100001300))); // 40 // EOT, ignored - lost sync
ASSERT_EQ(100000000, rcv.getLastTransferTimestamp());
ASSERT_FALSE(bufmgr.access(gen.source_node_id)); // Buffer should be removed
ASSERT_FALSE(bufmgr.access(gen.bufmgr_key)); // Buffer should be removed
}
@ -262,7 +263,7 @@ TEST(TransferReceiver, UnterminatedTransfer)
}
CHECK_COMPLETE(rcv.addFrame(gen(1, "12345678", uavcan::Frame::FRAME_INDEX_MAX, true, 0, 1100)));
ASSERT_EQ(1000, rcv.getLastTransferTimestamp());
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), content));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), content));
}
@ -281,7 +282,7 @@ TEST(TransferReceiver, OutOfOrderFrames)
CHECK_COMPLETE( rcv.addFrame(gen(1, "abcd", 2, true, 10, 100000400)));
ASSERT_EQ(100000000, rcv.getLastTransferTimestamp());
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), "12345678qwertyuiabcd"));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "12345678qwertyuiabcd"));
}
@ -302,7 +303,7 @@ TEST(TransferReceiver, IntervalMeasurement)
CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "qwertyui", 1, false, tid.get(), timestamp)));
CHECK_COMPLETE( rcv.addFrame(gen(1, "abcd", 2, true, tid.get(), timestamp)));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), "12345678qwertyuiabcd"));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "12345678qwertyuiabcd"));
ASSERT_EQ(timestamp, rcv.getLastTransferTimestamp());
timestamp += INTERVAL;
@ -334,7 +335,7 @@ TEST(TransferReceiver, Restart)
CHECK_NOT_COMPLETE(rcv.addFrame(gen(1, "12345678", 1, false, 0, 13000300))); // Continue 3 sec later, iface timeout
CHECK_COMPLETE( rcv.addFrame(gen(1, "12345678", 2, true, 0, 13000400))); // OK nevertheless
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), "123456781234567812345678"));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "123456781234567812345678"));
/*
* Begins OK, gets an iface timeout, switches to another iface
@ -348,5 +349,5 @@ TEST(TransferReceiver, Restart)
CHECK_NOT_COMPLETE(rcv.addFrame(gen(0, "12345678", 1, false, 2, 16000900))); // Continuing
CHECK_COMPLETE( rcv.addFrame(gen(0, "12345678", 2, true, 2, 16000910))); // Done
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.source_node_id), "123456781234567812345678"));
ASSERT_TRUE(matchBufferContent(bufmgr.access(gen.bufmgr_key), "123456781234567812345678"));
}