From d71ec29fcffc58927fe46c086c81458bc70496b3 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Thu, 27 Feb 2014 09:29:58 +0400 Subject: [PATCH] DataTypeDescriptor got name_ --- libuavcan/include/uavcan/data_type.hpp | 42 +++++++++++++------ .../uavcan/internal/transport/dispatcher.hpp | 2 +- .../internal/transport/transfer_listener.hpp | 2 +- .../internal/transport/transfer_sender.hpp | 2 +- libuavcan/src/data_type.cpp | 21 +++++++++- libuavcan/src/transport/dispatcher.cpp | 14 +++---- libuavcan/src/transport/transfer_sender.cpp | 7 ++-- libuavcan/test/data_type.cpp | 11 +++++ .../test/transport/transfer_listener.cpp | 10 ++--- .../test/transport/transfer_test_helpers.cpp | 4 +- .../test/transport/transfer_test_helpers.hpp | 12 +++--- 11 files changed, 87 insertions(+), 40 deletions(-) diff --git a/libuavcan/include/uavcan/data_type.hpp b/libuavcan/include/uavcan/data_type.hpp index 347124c776..2c74644cf5 100644 --- a/libuavcan/include/uavcan/data_type.hpp +++ b/libuavcan/include/uavcan/data_type.hpp @@ -87,33 +87,49 @@ public: }; -struct DataTypeDescriptor +class DataTypeDescriptor { + DataTypeKind kind_; + uint16_t id_; + DataTypeSignature signature_; + const char* name_; + +public: enum { MaxDataTypeID = Frame::MaxDataTypeID }; - DataTypeKind kind; - uint16_t id; - DataTypeSignature signature; - DataTypeDescriptor() - : kind(DataTypeKind(0)) - , id(0) - , signature(DataTypeSignature::zero()) + : kind_(DataTypeKind(0)) + , id_(0) + , signature_(DataTypeSignature::zero()) + , name_("") { } - DataTypeDescriptor(DataTypeKind kind, uint16_t id, const DataTypeSignature& signature) - : kind(kind) - , id(id) - , signature(signature) + DataTypeDescriptor(DataTypeKind kind, uint16_t id, const DataTypeSignature& signature, const char* name) + : kind_(kind) + , id_(id) + , signature_(signature) + , name_(name) { assert(id <= MaxDataTypeID); assert(kind < NumDataTypeKinds); + assert(name); } + DataTypeKind getKind() const { return kind_; } + uint16_t getID() const { return id_; } + const DataTypeSignature& getSignature() const { return signature_; } + const char* getName() const { return name_; } + + std::string toString() const; + bool operator!=(const DataTypeDescriptor& rhs) const { return !operator==(rhs); } bool operator==(const DataTypeDescriptor& rhs) const { - return (kind == rhs.kind) && (id == rhs.id) && (signature == rhs.signature); + return + (kind_ == rhs.kind_) && + (id_ == rhs.id_) && + (signature_ == rhs.signature_) && + !std::strcmp(name_, rhs.name_); } }; diff --git a/libuavcan/include/uavcan/internal/transport/dispatcher.hpp b/libuavcan/include/uavcan/internal/transport/dispatcher.hpp index 9192038091..8a4432fa0c 100644 --- a/libuavcan/include/uavcan/internal/transport/dispatcher.hpp +++ b/libuavcan/include/uavcan/internal/transport/dispatcher.hpp @@ -32,7 +32,7 @@ class Dispatcher : Noncopyable bool operator()(const TransferListenerBase* listener) const { assert(listener); - return id_ > listener->getDataTypeDescriptor().id; + return id_ > listener->getDataTypeDescriptor().getID(); } }; diff --git a/libuavcan/include/uavcan/internal/transport/transfer_listener.hpp b/libuavcan/include/uavcan/internal/transport/transfer_listener.hpp index adb5bd66c0..b40348e68c 100644 --- a/libuavcan/include/uavcan/internal/transport/transfer_listener.hpp +++ b/libuavcan/include/uavcan/internal/transport/transfer_listener.hpp @@ -95,7 +95,7 @@ class TransferListenerBase : public LinkedListNode protected: TransferListenerBase(const DataTypeDescriptor& data_type) : data_type_(data_type) - , crc_base_(data_type.signature.toTransferCRC()) + , crc_base_(data_type.getSignature().toTransferCRC()) { } virtual ~TransferListenerBase() { } diff --git a/libuavcan/include/uavcan/internal/transport/transfer_sender.hpp b/libuavcan/include/uavcan/internal/transport/transfer_sender.hpp index 3c5cffd8df..81deab6ba6 100644 --- a/libuavcan/include/uavcan/internal/transport/transfer_sender.hpp +++ b/libuavcan/include/uavcan/internal/transport/transfer_sender.hpp @@ -31,7 +31,7 @@ public: : max_transfer_interval_(max_transfer_interval) , data_type_(data_type) , qos_(qos) - , crc_base_(data_type.signature.toTransferCRC()) + , crc_base_(data_type.getSignature().toTransferCRC()) , dispatcher_(dispatcher) { } diff --git a/libuavcan/src/data_type.cpp b/libuavcan/src/data_type.cpp index 83aa2cc68e..4182cf7189 100644 --- a/libuavcan/src/data_type.cpp +++ b/libuavcan/src/data_type.cpp @@ -2,7 +2,8 @@ * Copyright (C) 2014 Pavel Kirienko */ -#include +#include +#include #include #include @@ -34,4 +35,22 @@ TransferCRC DataTypeSignature::toTransferCRC() const return tcrc; } +/* + * DataTypeDescriptor + */ +std::string DataTypeDescriptor::toString() const +{ + char kindch = '?'; + switch (kind_) + { + case DataTypeKindMessage: kindch = 'm'; break; + case DataTypeKindService: kindch = 's'; break; + default: assert(0); + } + + std::ostringstream os; + os << name_ << ":" << id_ << kindch << ":" << std::hex << std::setfill('0') << std::setw(16) << signature_.get(); + return os.str(); +} + } diff --git a/libuavcan/src/transport/dispatcher.cpp b/libuavcan/src/transport/dispatcher.cpp index 397bd18acd..6dbb719a06 100644 --- a/libuavcan/src/transport/dispatcher.cpp +++ b/libuavcan/src/transport/dispatcher.cpp @@ -18,13 +18,13 @@ bool Dispatcher::ListenerRegister::add(TransferListenerBase* listener, Mode mode TransferListenerBase* p = list_.get(); while (p) { - if (p->getDataTypeDescriptor().id == listener->getDataTypeDescriptor().id) + if (p->getDataTypeDescriptor().getID() == listener->getDataTypeDescriptor().getID()) return false; p = p->getNextListNode(); } } // Objective is to arrange entries by Data Type ID in ascending order from root. - list_.insertBefore(listener, DataTypeIDInsertionComparator(listener->getDataTypeDescriptor().id)); + list_.insertBefore(listener, DataTypeIDInsertionComparator(listener->getDataTypeDescriptor().getID())); return true; } @@ -48,9 +48,9 @@ void Dispatcher::ListenerRegister::handleFrame(const RxFrame& frame) TransferListenerBase* p = list_.get(); while (p) { - if (p->getDataTypeDescriptor().id == frame.getDataTypeID()) + if (p->getDataTypeDescriptor().getID() == frame.getDataTypeID()) p->handleFrame(frame); - else if (p->getDataTypeDescriptor().id < frame.getDataTypeID()) // Listeners are ordered by data type id! + else if (p->getDataTypeDescriptor().getID() < frame.getDataTypeID()) // Listeners are ordered by data type id! break; p = p->getNextListNode(); } @@ -145,7 +145,7 @@ void Dispatcher::cleanup(uint64_t ts_monotonic) bool Dispatcher::registerMessageListener(TransferListenerBase* listener) { - if (listener->getDataTypeDescriptor().kind != DataTypeKindMessage) + if (listener->getDataTypeDescriptor().getKind() != DataTypeKindMessage) { assert(0); return false; @@ -155,7 +155,7 @@ bool Dispatcher::registerMessageListener(TransferListenerBase* listener) bool Dispatcher::registerServiceRequestListener(TransferListenerBase* listener) { - if (listener->getDataTypeDescriptor().kind != DataTypeKindService) + if (listener->getDataTypeDescriptor().getKind() != DataTypeKindService) { assert(0); return false; @@ -165,7 +165,7 @@ bool Dispatcher::registerServiceRequestListener(TransferListenerBase* listener) bool Dispatcher::registerServiceResponseListener(TransferListenerBase* listener) { - if (listener->getDataTypeDescriptor().kind != DataTypeKindService) + if (listener->getDataTypeDescriptor().getKind() != DataTypeKindService) { assert(0); return false; diff --git a/libuavcan/src/transport/transfer_sender.cpp b/libuavcan/src/transport/transfer_sender.cpp index 8329a59071..79592c17bb 100644 --- a/libuavcan/src/transport/transfer_sender.cpp +++ b/libuavcan/src/transport/transfer_sender.cpp @@ -14,7 +14,7 @@ int TransferSender::send(const uint8_t* payload, int payload_len, uint64_t monot uint64_t monotonic_blocking_deadline, TransferType transfer_type, NodeID dst_node_id, TransferID tid) { - Frame frame(data_type_.id, transfer_type, dispatcher_.getSelfNodeID(), dst_node_id, 0, tid); + Frame frame(data_type_.getID(), transfer_type, dispatcher_.getSelfNodeID(), dst_node_id, 0, tid); if (frame.getMaxPayloadLen() >= payload_len) // Single Frame Transfer { @@ -87,7 +87,7 @@ int TransferSender::send(const uint8_t* payload, int payload_len, uint64_t monot int TransferSender::send(const uint8_t* payload, int payload_len, uint64_t monotonic_tx_deadline, uint64_t monotonic_blocking_deadline, TransferType transfer_type, NodeID dst_node_id) { - const OutgoingTransferRegistryKey otr_key(data_type_.id, transfer_type, dst_node_id); + const OutgoingTransferRegistryKey otr_key(data_type_.getID(), transfer_type, dst_node_id); assert(monotonic_tx_deadline > 0); const uint64_t otr_deadline = monotonic_tx_deadline + max_transfer_interval_; @@ -95,7 +95,8 @@ int TransferSender::send(const uint8_t* payload, int payload_len, uint64_t monot TransferID* const tid = dispatcher_.getOutgoingTransferRegistry().accessOrCreate(otr_key, otr_deadline); if (tid == NULL) { - UAVCAN_TRACE("TransferSender", "OTR access failure, dtid=%i tt=%i", int(data_type_.id), int(transfer_type)); + UAVCAN_TRACE("TransferSender", "OTR access failure, dtd=%s tt=%i", + data_type_.toString().c_str(), int(transfer_type)); return -1; } diff --git a/libuavcan/test/data_type.cpp b/libuavcan/test/data_type.cpp index 3fffe9349c..52b870b435 100644 --- a/libuavcan/test/data_type.cpp +++ b/libuavcan/test/data_type.cpp @@ -91,3 +91,14 @@ TEST(DataTypeSignature, Correctness) ASSERT_FALSE(signature != DataTypeSignature(signature.get())); ASSERT_TRUE(signature != DataTypeSignature::zero()); } + + +TEST(DataTypeDescriptor, ToString) +{ + uavcan::DataTypeDescriptor desc; + ASSERT_EQ(":0s:0000000000000000", desc.toString()); + + desc = uavcan::DataTypeDescriptor(uavcan::DataTypeKindMessage, 123, + uavcan::DataTypeSignature(0xdeadbeef1234), "Bar"); + ASSERT_EQ("Bar:123m:0000deadbeef1234", desc.toString()); +} diff --git a/libuavcan/test/transport/transfer_listener.cpp b/libuavcan/test/transport/transfer_listener.cpp index 766d531a5f..a07618628e 100644 --- a/libuavcan/test/transport/transfer_listener.cpp +++ b/libuavcan/test/transport/transfer_listener.cpp @@ -30,7 +30,7 @@ public: TEST(TransferListener, BasicMFT) { - const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789)); + const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); static const int NUM_POOL_BLOCKS = 12; // This number is just enough to pass the test uavcan::PoolAllocator pool; @@ -85,7 +85,7 @@ TEST(TransferListener, BasicMFT) TEST(TransferListener, CrcFailure) { - const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789)); + const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); uavcan::PoolManager<1> poolmgr; // No dynamic memory TestSubscriber<256, 2, 2> subscriber(type, poolmgr); // Static buffer only, 2 entries @@ -128,7 +128,7 @@ TEST(TransferListener, CrcFailure) TEST(TransferListener, BasicSFT) { - const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789)); + const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); uavcan::PoolManager<1> poolmgr; // No dynamic memory. At all. TestSubscriber<0, 0, 5> subscriber(type, poolmgr); // Max buf size is 0, i.e. SFT-only @@ -163,7 +163,7 @@ TEST(TransferListener, BasicSFT) TEST(TransferListener, Cleanup) { - const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789)); + const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); uavcan::PoolManager<1> poolmgr; // No dynamic memory TestSubscriber<256, 1, 2> subscriber(type, poolmgr); // Static buffer only, 1 entry @@ -217,7 +217,7 @@ TEST(TransferListener, Cleanup) TEST(TransferListener, MaximumTransferLength) { - const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789)); + const uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "A"); uavcan::PoolManager<1> poolmgr; TestSubscriber subscriber(type, poolmgr); diff --git a/libuavcan/test/transport/transfer_test_helpers.cpp b/libuavcan/test/transport/transfer_test_helpers.cpp index cba9dddff2..d40dc524ff 100644 --- a/libuavcan/test/transport/transfer_test_helpers.cpp +++ b/libuavcan/test/transport/transfer_test_helpers.cpp @@ -32,7 +32,7 @@ TEST(TransferTestHelpers, Transfer) TEST(TransferTestHelpers, MFTSerialization) { - uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789)); + uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "Foo"); static const std::string DATA = "To go wrong in one's own way is better than to go right in someone else's."; const Transfer transfer(1, 100000, uavcan::TransferTypeMessageUnicast, 2, 42, 127, DATA, type); @@ -61,7 +61,7 @@ TEST(TransferTestHelpers, MFTSerialization) TEST(TransferTestHelpers, SFTSerialization) { - uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789)); + uavcan::DataTypeDescriptor type(uavcan::DataTypeKindMessage, 123, uavcan::DataTypeSignature(123456789), "Foo"); { const Transfer transfer(1, 100000, uavcan::TransferTypeMessageBroadcast, 7, 42, 0, "Nvrfrget", type); diff --git a/libuavcan/test/transport/transfer_test_helpers.hpp b/libuavcan/test/transport/transfer_test_helpers.hpp index 2e4232e6ab..04b1db5c0d 100644 --- a/libuavcan/test/transport/transfer_test_helpers.hpp +++ b/libuavcan/test/transport/transfer_test_helpers.hpp @@ -85,7 +85,7 @@ struct Transfer << " tid=" << int(transfer_id.get()) << " snid=" << int(src_node_id.get()) << " dnid=" << int(dst_node_id.get()) - << " dtid=" << int(data_type.id) + << " dtid=" << int(data_type.getID()) << "\n\t'" << payload << "'"; return os.str(); } @@ -165,7 +165,7 @@ std::vector serializeTransfer(const Transfer& transfer) std::vector raw_payload; if (need_crc) { - uavcan::TransferCRC payload_crc = transfer.data_type.signature.toTransferCRC(); + uavcan::TransferCRC payload_crc = transfer.data_type.getSignature().toTransferCRC(); payload_crc.add(reinterpret_cast(transfer.payload.c_str()), transfer.payload.length()); // Little endian raw_payload.push_back(payload_crc.get() & 0xFF); @@ -184,8 +184,8 @@ std::vector serializeTransfer(const Transfer& transfer) const int bytes_left = raw_payload.size() - offset; EXPECT_TRUE(bytes_left >= 0); - uavcan::Frame frm(transfer.data_type.id, transfer.transfer_type, transfer.src_node_id, transfer.dst_node_id, - frame_index, transfer.transfer_id); + uavcan::Frame frm(transfer.data_type.getID(), transfer.transfer_type, transfer.src_node_id, + transfer.dst_node_id, frame_index, transfer.transfer_id); const int spres = frm.setPayload(&*(raw_payload.begin() + offset), bytes_left); if (spres < 0) { @@ -210,10 +210,10 @@ std::vector serializeTransfer(const Transfer& transfer) return output; } -uavcan::DataTypeDescriptor makeDataType(uavcan::DataTypeKind kind, uint16_t id) +uavcan::DataTypeDescriptor makeDataType(uavcan::DataTypeKind kind, uint16_t id, const char* name = "") { const uavcan::DataTypeSignature signature((uint64_t(kind) << 16) | (id << 8) | (id & 0xFF)); - return uavcan::DataTypeDescriptor(kind, id, signature); + return uavcan::DataTypeDescriptor(kind, id, signature, name); } }