diff --git a/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp b/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp index 60e529b684..f3a399ead5 100644 --- a/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp +++ b/libuavcan/include/uavcan/transport/outgoing_transfer_registry.hpp @@ -41,6 +41,9 @@ public: assert(transfer_type != TransferTypeServiceResponse); } + DataTypeID getDataTypeID() const { return data_type_id_; } + TransferType getTransferType() const { return TransferType(transfer_type_); } + bool operator==(const OutgoingTransferRegistryKey& rhs) const { return @@ -66,6 +69,7 @@ class IOutgoingTransferRegistry public: virtual ~IOutgoingTransferRegistry() { } virtual TransferID* accessOrCreate(const OutgoingTransferRegistryKey& key, MonotonicTime new_deadline) = 0; + virtual bool exists(DataTypeID dtid, TransferType tt) const = 0; virtual void cleanup(MonotonicTime deadline) = 0; }; @@ -104,6 +108,23 @@ UAVCAN_PACKED_END } }; + class ExistenceCheckingPredicate + { + const DataTypeID dtid_; + const TransferType tt_; + + public: + ExistenceCheckingPredicate(DataTypeID dtid, TransferType tt) + : dtid_(dtid) + , tt_(tt) + { } + + bool operator()(const OutgoingTransferRegistryKey& key, const Value&) const + { + return dtid_ == key.getDataTypeID() && tt_ == key.getTransferType(); + } + }; + Map map_; public: @@ -126,6 +147,11 @@ public: return &p->tid; } + bool exists(DataTypeID dtid, TransferType tt) const + { + return NULL != map_.findFirstKey(ExistenceCheckingPredicate(dtid, tt)); + } + void cleanup(MonotonicTime ts) { map_.removeWhere(DeadlineExpiredPredicate(ts)); diff --git a/libuavcan/test/transport/outgoing_transfer_registry.cpp b/libuavcan/test/transport/outgoing_transfer_registry.cpp index 2945ee9cc1..2456df5030 100644 --- a/libuavcan/test/transport/outgoing_transfer_registry.cpp +++ b/libuavcan/test/transport/outgoing_transfer_registry.cpp @@ -20,9 +20,9 @@ TEST(OutgoingTransferRegistry, Basic) const OutgoingTransferRegistryKey keys[NUM_KEYS] = { OutgoingTransferRegistryKey(123, uavcan::TransferTypeMessageUnicast, 42), - OutgoingTransferRegistryKey(123, uavcan::TransferTypeMessageBroadcast, 0), - OutgoingTransferRegistryKey(123, uavcan::TransferTypeServiceRequest, 2), - OutgoingTransferRegistryKey(123, uavcan::TransferTypeMessageUnicast, 4), + OutgoingTransferRegistryKey(321, uavcan::TransferTypeMessageBroadcast, 0), + OutgoingTransferRegistryKey(213, uavcan::TransferTypeServiceRequest, 2), + OutgoingTransferRegistryKey(312, uavcan::TransferTypeMessageUnicast, 4), OutgoingTransferRegistryKey(456, uavcan::TransferTypeServiceRequest, 2) }; @@ -51,6 +51,20 @@ TEST(OutgoingTransferRegistry, Basic) ASSERT_FALSE(otr.accessOrCreate(keys[4], tsMono(1000000))); // Still OOM + /* + * Checking existence + * Exist: 0, 1, 2, 3 + * Does not exist: 4 + */ + ASSERT_TRUE(otr.exists(keys[1].getDataTypeID(), keys[1].getTransferType())); + ASSERT_TRUE(otr.exists(keys[0].getDataTypeID(), keys[0].getTransferType())); + ASSERT_TRUE(otr.exists(keys[3].getDataTypeID(), keys[3].getTransferType())); + ASSERT_TRUE(otr.exists(keys[2].getDataTypeID(), keys[2].getTransferType())); + + ASSERT_FALSE(otr.exists(keys[1].getDataTypeID(), keys[2].getTransferType())); // Invalid combination + ASSERT_FALSE(otr.exists(keys[0].getDataTypeID(), keys[1].getTransferType())); // Invalid combination + ASSERT_FALSE(otr.exists(keys[4].getDataTypeID(), keys[4].getTransferType())); // Plain missing + /* * Cleaning up */