mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-30 11:24:07 +08:00
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:
parent
149ac87a54
commit
78ff31f9ad
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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"));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user