mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-19 03:03:34 +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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user