diff --git a/libuavcan/include/uavcan/node/generic_publisher.hpp b/libuavcan/include/uavcan/node/generic_publisher.hpp index 68bfbf6e04..c08ed9814c 100644 --- a/libuavcan/include/uavcan/node/generic_publisher.hpp +++ b/libuavcan/include/uavcan/node/generic_publisher.hpp @@ -106,6 +106,11 @@ public: ~GenericPublisher() { } + int init() + { + return checkInit() ? 0 : -1; + } + int publish(const DataStruct& message, TransferType transfer_type, NodeID dst_node_id, MonotonicTime blocking_deadline = MonotonicTime()) { @@ -118,6 +123,12 @@ public: return genericPublish(message, transfer_type, dst_node_id, &tid, blocking_deadline); } + TransferSender* getTransferSender() + { + checkInit(); + return sender_.isConstructed() ? static_cast(sender_) : NULL; + } + static MonotonicDuration getMinTxTimeout() { return MonotonicDuration::fromUSec(200); } static MonotonicDuration getMaxTxTimeout() { return MonotonicDuration::fromMSec(60000); } diff --git a/libuavcan/include/uavcan/node/publisher.hpp b/libuavcan/include/uavcan/node/publisher.hpp index 9eae3be5cb..152936e525 100644 --- a/libuavcan/include/uavcan/node/publisher.hpp +++ b/libuavcan/include/uavcan/node/publisher.hpp @@ -44,6 +44,8 @@ public: static MonotonicDuration getDefaultTxTimeout() { return MonotonicDuration::fromMSec(5); } // 5 ms --> 200 Hz max + using BaseType::init; + using BaseType::getTransferSender; using BaseType::getMinTxTimeout; using BaseType::getMaxTxTimeout; using BaseType::getTxTimeout; diff --git a/libuavcan/include/uavcan/node/service_client.hpp b/libuavcan/include/uavcan/node/service_client.hpp index 6ffe1f6a04..e2c08c6f5a 100644 --- a/libuavcan/include/uavcan/node/service_client.hpp +++ b/libuavcan/include/uavcan/node/service_client.hpp @@ -143,6 +143,11 @@ public: virtual ~ServiceClient() { cancel(); } + int init() + { + return publisher_.init(); + } + int call(NodeID server_node_id, const RequestType& request) // TODO: Refactor, move into a non-template subclass! { /* diff --git a/libuavcan/include/uavcan/node/service_server.hpp b/libuavcan/include/uavcan/node/service_server.hpp index bfcffb0701..7dddb3727b 100644 --- a/libuavcan/include/uavcan/node/service_server.hpp +++ b/libuavcan/include/uavcan/node/service_server.hpp @@ -79,6 +79,12 @@ public: } callback_ = callback; + const int publisher_res = publisher_.init(); + if (publisher_res < 0) + { + UAVCAN_TRACE("ServiceServer", "Publisher initialization failure: %i", publisher_res); + return publisher_res; + } return SubscriberType::startAsServiceRequestListener(); } diff --git a/libuavcan/test/node/publisher.cpp b/libuavcan/test/node/publisher.cpp index 9710e9fc0a..faa8ab4833 100644 --- a/libuavcan/test/node/publisher.cpp +++ b/libuavcan/test/node/publisher.cpp @@ -105,4 +105,18 @@ TEST(Publisher, Basic) * Misc */ ASSERT_TRUE(uavcan::GlobalDataTypeRegistry::instance().isFrozen()); + ASSERT_TRUE(publisher.getTransferSender()); +} + + +TEST(Publisher, ImplicitInitialization) +{ + SystemClockMock clock_mock(100); + CanDriverMock can_driver(2, clock_mock); + TestNode node(can_driver, clock_mock, 1); + + uavcan::Publisher publisher(node); + + // Will be initialized ad-hoc + ASSERT_TRUE(publisher.getTransferSender()); }