From 613efa49b9ccf5f3e09c1e2263bbaef057b82b4b Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Fri, 14 Mar 2014 19:54:27 +0400 Subject: [PATCH] INode class. Publisher, Subscriber, ServiceServer, ServiceClient now accept INode in constructor instead of the bunch of independent params. Self NodeID now being configured via setNodeID() method instead of constructor param --- .../include/uavcan/node/abstract_node.hpp | 46 +++++++++++++ .../include/uavcan/node/generic_publisher.hpp | 19 +++--- .../uavcan/node/generic_subscriber.hpp | 23 ++++--- libuavcan/include/uavcan/node/publisher.hpp | 9 ++- libuavcan/include/uavcan/node/scheduler.hpp | 19 +++--- .../include/uavcan/node/service_client.hpp | 15 ++--- .../include/uavcan/node/service_server.hpp | 6 +- libuavcan/include/uavcan/node/subscriber.hpp | 4 +- libuavcan/include/uavcan/node/timer.hpp | 2 +- .../include/uavcan/transport/dispatcher.hpp | 9 ++- libuavcan/src/node/scheduler.cpp | 8 +-- libuavcan/src/node/timer.cpp | 4 +- libuavcan/src/transport/dispatcher.cpp | 14 +++- libuavcan/src/transport/transfer_sender.cpp | 2 +- libuavcan/test/node/publisher.cpp | 20 ++---- libuavcan/test/node/scheduler.cpp | 3 +- libuavcan/test/node/service_client.cpp | 50 ++++---------- libuavcan/test/node/service_server.cpp | 23 +++---- libuavcan/test/node/subscriber.cpp | 66 +++++++------------ libuavcan/test/node/test_node.hpp | 31 +++++++++ libuavcan/test/transport/dispatcher.cpp | 13 +++- libuavcan/test/transport/transfer_sender.cpp | 6 +- 22 files changed, 211 insertions(+), 181 deletions(-) create mode 100644 libuavcan/include/uavcan/node/abstract_node.hpp create mode 100644 libuavcan/test/node/test_node.hpp diff --git a/libuavcan/include/uavcan/node/abstract_node.hpp b/libuavcan/include/uavcan/node/abstract_node.hpp new file mode 100644 index 0000000000..5602b98513 --- /dev/null +++ b/libuavcan/include/uavcan/node/abstract_node.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#pragma once + +#include +#include + +namespace uavcan +{ + +class INode +{ +public: + virtual ~INode() { } + virtual IAllocator& getAllocator() = 0; + virtual Scheduler& getScheduler() = 0; + virtual const Scheduler& getScheduler() const = 0; + virtual IMarshalBufferProvider& getMarshalBufferProvider() = 0; + + Dispatcher& getDispatcher() { return getScheduler().getDispatcher(); } + const Dispatcher& getDispatcher() const { return getScheduler().getDispatcher(); } + + ISystemClock& getSystemClock() { return getScheduler().getSystemClock(); } + MonotonicTime getMonotonicTime() const { return getScheduler().getMonotonicTime(); } + UtcTime getUtcTime() const { return getScheduler().getUtcTime(); } + + NodeID getNodeID() const { return getScheduler().getDispatcher().getNodeID(); } + bool setNodeID(NodeID nid) + { + return getScheduler().getDispatcher().setNodeID(nid); + } + + int spin(MonotonicTime deadline) + { + return getScheduler().spin(deadline); + } + + int spin(MonotonicDuration duration) + { + return getScheduler().spin(getMonotonicTime() + duration); + } +}; + +} diff --git a/libuavcan/include/uavcan/node/generic_publisher.hpp b/libuavcan/include/uavcan/node/generic_publisher.hpp index 6f95d341e9..68bfbf6e04 100644 --- a/libuavcan/include/uavcan/node/generic_publisher.hpp +++ b/libuavcan/include/uavcan/node/generic_publisher.hpp @@ -4,9 +4,8 @@ #pragma once -#include +#include #include -#include #include #include #include @@ -30,8 +29,7 @@ class GenericPublisher const MonotonicDuration max_transfer_interval_; // TODO: memory usage can be reduced MonotonicDuration tx_timeout_; - Scheduler& scheduler_; - IMarshalBufferProvider& buffer_provider_; + INode& node_; LazyConstructor sender_; bool checkInit() @@ -50,15 +48,15 @@ class GenericPublisher return false; } sender_.template construct - (scheduler_.getDispatcher(), *descr, CanTxQueue::Qos(Qos), max_transfer_interval_); + (node_.getDispatcher(), *descr, CanTxQueue::Qos(Qos), max_transfer_interval_); return true; } - MonotonicTime getTxDeadline() const { return scheduler_.getMonotonicTimestamp() + tx_timeout_; } + MonotonicTime getTxDeadline() const { return node_.getMonotonicTime() + tx_timeout_; } IMarshalBuffer* getBuffer() { - return buffer_provider_.getBuffer(BitLenToByteLen::Result); + return node_.getMarshalBufferProvider().getBuffer(BitLenToByteLen::Result); } int genericPublish(const DataStruct& message, TransferType transfer_type, NodeID dst_node_id, @@ -94,12 +92,11 @@ class GenericPublisher } public: - GenericPublisher(Scheduler& scheduler, IMarshalBufferProvider& buffer_provider, MonotonicDuration tx_timeout, + GenericPublisher(INode& node, MonotonicDuration tx_timeout, MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval()) : max_transfer_interval_(max_transfer_interval) , tx_timeout_(tx_timeout) - , scheduler_(scheduler) - , buffer_provider_(buffer_provider) + , node_(node) { setTxTimeout(tx_timeout); #if UAVCAN_DEBUG @@ -132,7 +129,7 @@ public: tx_timeout_ = tx_timeout; } - Scheduler& getScheduler() const { return scheduler_; } + INode& getNode() const { return node_; } }; } diff --git a/libuavcan/include/uavcan/node/generic_subscriber.hpp b/libuavcan/include/uavcan/node/generic_subscriber.hpp index 08ad06ea13..33b57a893f 100644 --- a/libuavcan/include/uavcan/node/generic_subscriber.hpp +++ b/libuavcan/include/uavcan/node/generic_subscriber.hpp @@ -4,7 +4,7 @@ #pragma once -#include +#include #include #include #include @@ -107,8 +107,7 @@ class GenericSubscriber : Noncopyable using ReceivedDataStructure::setTransfer; }; - Scheduler& scheduler_; - IAllocator& allocator_; + INode& node_; LazyConstructor forwarder_; ReceivedDataStructureSpec message_; uint32_t failure_count_; @@ -128,7 +127,8 @@ class GenericSubscriber : Noncopyable UAVCAN_TRACE("GenericSubscriber", "Type [%s] is not registered", DataSpec::getDataTypeFullName()); return false; } - forwarder_.template construct(*this, *descr, allocator_); + forwarder_.template construct + (*this, *descr, node_.getAllocator()); return true; } @@ -170,7 +170,7 @@ class GenericSubscriber : Noncopyable return -1; } - if (!(scheduler_.getDispatcher().*registration_method)(forwarder_)) + if (!(node_.getDispatcher().*registration_method)(forwarder_)) { UAVCAN_TRACE("GenericSubscriber", "Failed to register transfer listener [%s]", DataSpec::getDataTypeFullName()); @@ -180,9 +180,8 @@ class GenericSubscriber : Noncopyable } protected: - GenericSubscriber(Scheduler& scheduler, IAllocator& allocator) - : scheduler_(scheduler) - , allocator_(allocator) + explicit GenericSubscriber(INode& node) + : node_(node) , failure_count_(0) { } @@ -209,9 +208,9 @@ protected: { if (forwarder_) { - scheduler_.getDispatcher().unregisterMessageListener(forwarder_); - scheduler_.getDispatcher().unregisterServiceRequestListener(forwarder_); - scheduler_.getDispatcher().unregisterServiceResponseListener(forwarder_); + node_.getDispatcher().unregisterMessageListener(forwarder_); + node_.getDispatcher().unregisterServiceRequestListener(forwarder_); + node_.getDispatcher().unregisterServiceResponseListener(forwarder_); } } @@ -222,7 +221,7 @@ protected: ReceivedDataStructure& getReceivedStructStorage() { return message_; } public: - Scheduler& getScheduler() const { return scheduler_; } + INode& getNode() const { return node_; } }; } diff --git a/libuavcan/include/uavcan/node/publisher.hpp b/libuavcan/include/uavcan/node/publisher.hpp index 09adf32902..9eae3be5cb 100644 --- a/libuavcan/include/uavcan/node/publisher.hpp +++ b/libuavcan/include/uavcan/node/publisher.hpp @@ -17,10 +17,9 @@ class Publisher : protected GenericPublisher public: typedef DataType_ DataType; - Publisher(Scheduler& scheduler, IMarshalBufferProvider& buffer_provider, - MonotonicDuration tx_timeout = getDefaultTxTimeout(), - MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval()) - : BaseType(scheduler, buffer_provider, tx_timeout, max_transfer_interval) + explicit Publisher(INode& node, MonotonicDuration tx_timeout = getDefaultTxTimeout(), + MonotonicDuration max_transfer_interval = TransferSender::getDefaultMaxTransferInterval()) + : BaseType(node, tx_timeout, max_transfer_interval) { #if UAVCAN_DEBUG assert(getTxTimeout() == tx_timeout); // Making sure default values are OK @@ -49,7 +48,7 @@ public: using BaseType::getMaxTxTimeout; using BaseType::getTxTimeout; using BaseType::setTxTimeout; - using BaseType::getScheduler; + using BaseType::getNode; }; } diff --git a/libuavcan/include/uavcan/node/scheduler.hpp b/libuavcan/include/uavcan/node/scheduler.hpp index 9e01005b55..0df72ea579 100644 --- a/libuavcan/include/uavcan/node/scheduler.hpp +++ b/libuavcan/include/uavcan/node/scheduler.hpp @@ -26,7 +26,7 @@ protected: virtual ~DeadlineHandler() { stop(); } public: - virtual void handleDeadline(MonotonicTime current_timestamp) = 0; + virtual void handleDeadline(MonotonicTime current) = 0; void startWithDeadline(MonotonicTime deadline); void startWithDelay(MonotonicDuration delay); @@ -50,7 +50,7 @@ public: bool doesExist(const DeadlineHandler* mdh) const; unsigned int getNumHandlers() const { return handlers_.getLength(); } - MonotonicTime pollAndGetMonotonicTimestamp(ISystemClock& sysclock); + MonotonicTime pollAndGetMonotonicTime(ISystemClock& sysclock); MonotonicTime getEarliestDeadline() const; }; @@ -75,9 +75,8 @@ class Scheduler : Noncopyable void pollCleanup(MonotonicTime mono_ts, uint32_t num_frames_processed_with_last_spin); public: - Scheduler(ICanDriver& can_driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr, - NodeID self_node_id) - : dispatcher_(can_driver, allocator, sysclock, otr, self_node_id) + Scheduler(ICanDriver& can_driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr) + : dispatcher_(can_driver, allocator, sysclock, otr) , prev_cleanup_ts_(sysclock.getMonotonic()) , deadline_resolution_(MonotonicDuration::fromMSec(DefaultDeadlineResolutionMs)) , cleanup_period_(MonotonicDuration::fromMSec(DefaultCleanupPeriodMs)) @@ -86,11 +85,13 @@ public: int spin(MonotonicTime deadline); DeadlineScheduler& getDeadlineScheduler() { return deadline_scheduler_; } - Dispatcher& getDispatcher() { return dispatcher_; } - ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); } - MonotonicTime getMonotonicTimestamp() const { return dispatcher_.getSystemClock().getMonotonic(); } - UtcTime getUtcTimestamp() const { return dispatcher_.getSystemClock().getUtc(); } + Dispatcher& getDispatcher() { return dispatcher_; } + const Dispatcher& getDispatcher() const { return dispatcher_; } + + ISystemClock& getSystemClock() { return dispatcher_.getSystemClock(); } + MonotonicTime getMonotonicTime() const { return dispatcher_.getSystemClock().getMonotonic(); } + UtcTime getUtcTime() const { return dispatcher_.getSystemClock().getUtc(); } MonotonicDuration getDeadlineResolution() const { return deadline_resolution_; } void setDeadlineResolution(MonotonicDuration res) diff --git a/libuavcan/include/uavcan/node/service_client.hpp b/libuavcan/include/uavcan/node/service_client.hpp index 54e6707080..a509d232ba 100644 --- a/libuavcan/include/uavcan/node/service_client.hpp +++ b/libuavcan/include/uavcan/node/service_client.hpp @@ -73,7 +73,6 @@ private: typedef GenericSubscriber SubscriberType; PublisherType publisher_; - IAllocator& allocator_; Callback callback_; MonotonicDuration request_timeout_; bool pending_; @@ -128,12 +127,10 @@ private: } public: - ServiceClient(Scheduler& scheduler, IAllocator& allocator, IMarshalBufferProvider& buffer_provider, - const Callback& callback = Callback()) - : SubscriberType(scheduler, allocator) - , DeadlineHandler(scheduler) - , publisher_(scheduler, buffer_provider, getDefaultRequestTimeout()) - , allocator_(allocator) + explicit ServiceClient(INode& node, const Callback& callback = Callback()) + : SubscriberType(node) + , DeadlineHandler(node.getScheduler()) + , publisher_(node, getDefaultRequestTimeout()) , callback_(callback) , request_timeout_(getDefaultRequestTimeout()) , pending_(false) @@ -177,8 +174,8 @@ public: */ const OutgoingTransferRegistryKey otr_key(descr->getID(), TransferTypeServiceRequest, server_node_id); const MonotonicTime otr_deadline = - SubscriberType::getScheduler().getMonotonicTimestamp() + TransferSender::getDefaultMaxTransferInterval(); - TransferID* const otr_tid = SubscriberType::getScheduler().getDispatcher().getOutgoingTransferRegistry() + SubscriberType::getNode().getMonotonicTime() + TransferSender::getDefaultMaxTransferInterval(); + TransferID* const otr_tid = SubscriberType::getNode().getDispatcher().getOutgoingTransferRegistry() .accessOrCreate(otr_key, otr_deadline); if (!otr_tid) { diff --git a/libuavcan/include/uavcan/node/service_server.hpp b/libuavcan/include/uavcan/node/service_server.hpp index b44ada6cd2..16e6cc0244 100644 --- a/libuavcan/include/uavcan/node/service_server.hpp +++ b/libuavcan/include/uavcan/node/service_server.hpp @@ -57,9 +57,9 @@ private: } public: - ServiceServer(Scheduler& scheduler, IAllocator& allocator, IMarshalBufferProvider& buffer_provider) - : SubscriberType(scheduler, allocator) - , publisher_(scheduler, buffer_provider, getDefaultTxTimeout()) + explicit ServiceServer(INode& node) + : SubscriberType(node) + , publisher_(node, getDefaultTxTimeout()) , callback_() , response_failure_count_(0) { diff --git a/libuavcan/include/uavcan/node/subscriber.hpp b/libuavcan/include/uavcan/node/subscriber.hpp index ce99b7be16..b09ac0021d 100644 --- a/libuavcan/include/uavcan/node/subscriber.hpp +++ b/libuavcan/include/uavcan/node/subscriber.hpp @@ -36,8 +36,8 @@ class Subscriber : public GenericSubscriber::check(); diff --git a/libuavcan/include/uavcan/node/timer.hpp b/libuavcan/include/uavcan/node/timer.hpp index cffc176773..52e257bd79 100644 --- a/libuavcan/include/uavcan/node/timer.hpp +++ b/libuavcan/include/uavcan/node/timer.hpp @@ -31,7 +31,7 @@ class Timer : private DeadlineHandler { MonotonicDuration period_; - void handleDeadline(MonotonicTime current_timestamp); + void handleDeadline(MonotonicTime current); public: using DeadlineHandler::stop; diff --git a/libuavcan/include/uavcan/transport/dispatcher.hpp b/libuavcan/include/uavcan/transport/dispatcher.hpp index ee0ad34eff..b2f4e4328a 100644 --- a/libuavcan/include/uavcan/transport/dispatcher.hpp +++ b/libuavcan/include/uavcan/transport/dispatcher.hpp @@ -51,17 +51,15 @@ class Dispatcher : Noncopyable ListenerRegister lsrv_req_; ListenerRegister lsrv_resp_; - const NodeID self_node_id_; + NodeID self_node_id_; void handleFrame(const CanRxFrame& can_frame); public: - Dispatcher(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr, - NodeID self_node_id) + Dispatcher(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr) : canio_(driver, allocator, sysclock) , sysclock_(sysclock) , outgoing_transfer_reg_(otr) - , self_node_id_(self_node_id) { } int spin(MonotonicTime deadline); @@ -87,7 +85,8 @@ public: IOutgoingTransferRegistry& getOutgoingTransferRegistry() { return outgoing_transfer_reg_; } - NodeID getSelfNodeID() const { return self_node_id_; } + NodeID getNodeID() const { return self_node_id_; } + bool setNodeID(NodeID nid); const ISystemClock& getSystemClock() const { return sysclock_; } ISystemClock& getSystemClock() { return sysclock_; } diff --git a/libuavcan/src/node/scheduler.cpp b/libuavcan/src/node/scheduler.cpp index fcf83fe27e..6937ac1641 100644 --- a/libuavcan/src/node/scheduler.cpp +++ b/libuavcan/src/node/scheduler.cpp @@ -21,7 +21,7 @@ void DeadlineHandler::startWithDeadline(MonotonicTime deadline) void DeadlineHandler::startWithDelay(MonotonicDuration delay) { - startWithDeadline(scheduler_.getMonotonicTimestamp() + delay); + startWithDeadline(scheduler_.getMonotonicTime() + delay); } void DeadlineHandler::stop() @@ -80,7 +80,7 @@ bool DeadlineScheduler::doesExist(const DeadlineHandler* mdh) const return false; } -MonotonicTime DeadlineScheduler::pollAndGetMonotonicTimestamp(ISystemClock& sysclock) +MonotonicTime DeadlineScheduler::pollAndGetMonotonicTime(ISystemClock& sysclock) { while (true) { @@ -117,7 +117,7 @@ MonotonicTime DeadlineScheduler::getEarliestDeadline() const MonotonicTime Scheduler::computeDispatcherSpinDeadline(MonotonicTime spin_deadline) const { const MonotonicTime earliest = std::min(deadline_scheduler_.getEarliestDeadline(), spin_deadline); - const MonotonicTime ts = getMonotonicTimestamp(); + const MonotonicTime ts = getMonotonicTime(); if (earliest > ts) { if (ts - earliest > deadline_resolution_) @@ -148,7 +148,7 @@ int Scheduler::spin(MonotonicTime deadline) if (retval < 0) break; - const MonotonicTime ts = deadline_scheduler_.pollAndGetMonotonicTimestamp(getSystemClock()); + const MonotonicTime ts = deadline_scheduler_.pollAndGetMonotonicTime(getSystemClock()); pollCleanup(ts, retval); if (ts >= deadline) break; diff --git a/libuavcan/src/node/timer.cpp b/libuavcan/src/node/timer.cpp index db92fe2d1f..93eb0fa822 100644 --- a/libuavcan/src/node/timer.cpp +++ b/libuavcan/src/node/timer.cpp @@ -8,7 +8,7 @@ namespace uavcan { -void Timer::handleDeadline(MonotonicTime current_timestamp) +void Timer::handleDeadline(MonotonicTime current) { assert(!isRunning()); @@ -18,7 +18,7 @@ void Timer::handleDeadline(MonotonicTime current_timestamp) startWithDeadline(scheduled_time + period_); // Application can re-register the timer with different params, it's OK - handleTimerEvent(TimerEvent(scheduled_time, current_timestamp)); + handleTimerEvent(TimerEvent(scheduled_time, current)); } void Timer::startOneShotWithDeadline(MonotonicTime deadline) diff --git a/libuavcan/src/transport/dispatcher.cpp b/libuavcan/src/transport/dispatcher.cpp index ae573ded34..9851dc8fb9 100644 --- a/libuavcan/src/transport/dispatcher.cpp +++ b/libuavcan/src/transport/dispatcher.cpp @@ -69,7 +69,7 @@ void Dispatcher::handleFrame(const CanRxFrame& can_frame) } if ((frame.getDstNodeID() != NodeID::Broadcast) && - (frame.getDstNodeID() != getSelfNodeID())) + (frame.getDstNodeID() != getNodeID())) { return; } @@ -117,7 +117,7 @@ int Dispatcher::spin(MonotonicTime deadline) int Dispatcher::send(const Frame& frame, MonotonicTime tx_deadline, MonotonicTime blocking_deadline, CanTxQueue::Qos qos) { - if (frame.getSrcNodeID() != getSelfNodeID()) + if (frame.getSrcNodeID() != getNodeID()) { assert(0); return -1; @@ -188,4 +188,14 @@ void Dispatcher::unregisterServiceResponseListener(TransferListenerBase* listene lsrv_resp_.remove(listener); } +bool Dispatcher::setNodeID(NodeID nid) +{ + if (nid.isUnicast() && !self_node_id_.isValid()) + { + self_node_id_ = nid; + return true; + } + return false; +} + } diff --git a/libuavcan/src/transport/transfer_sender.cpp b/libuavcan/src/transport/transfer_sender.cpp index f12e7707fa..056de741d0 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, MonotonicTime MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id, TransferID tid) { - Frame frame(data_type_.getID(), transfer_type, dispatcher_.getSelfNodeID(), dst_node_id, 0, tid); + Frame frame(data_type_.getID(), transfer_type, dispatcher_.getNodeID(), dst_node_id, 0, tid); if (frame.getMaxPayloadLen() >= payload_len) // Single Frame Transfer { diff --git a/libuavcan/test/node/publisher.cpp b/libuavcan/test/node/publisher.cpp index b2e028afd8..9710e9fc0a 100644 --- a/libuavcan/test/node/publisher.cpp +++ b/libuavcan/test/node/publisher.cpp @@ -7,24 +7,16 @@ #include #include "../clock.hpp" #include "../transport/can/can.hpp" +#include "test_node.hpp" TEST(Publisher, Basic) { - uavcan::PoolAllocator pool; - uavcan::PoolManager<1> poolmgr; - poolmgr.addPool(&pool); - SystemClockMock clock_mock(100); CanDriverMock can_driver(2, clock_mock); + TestNode node(can_driver, clock_mock, 1); - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - - uavcan::Scheduler sch(can_driver, poolmgr, clock_mock, out_trans_reg, uavcan::NodeID(1)); - - uavcan::MarshalBufferProvider<> buffer_provider; - - uavcan::Publisher publisher(sch, buffer_provider); + uavcan::Publisher publisher(node); std::cout << "sizeof(uavcan::Publisher): " << @@ -61,7 +53,7 @@ TEST(Publisher, Basic) // uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id, // uint_fast8_t frame_index, TransferID transfer_id, bool last_frame = false uavcan::Frame expected_frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast, - sch.getDispatcher().getSelfNodeID(), uavcan::NodeID::Broadcast, 0, 0, true); + node.getNodeID(), uavcan::NodeID::Broadcast, 0, 0, true); expected_frame.setPayload(expected_transfer_payload, 7); uavcan::CanFrame expected_can_frame; @@ -76,7 +68,7 @@ TEST(Publisher, Basic) ASSERT_LT(0, publisher.broadcast(msg)); expected_frame = uavcan::Frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast, - sch.getDispatcher().getSelfNodeID(), uavcan::NodeID::Broadcast, 0, 1, true); + node.getNodeID(), uavcan::NodeID::Broadcast, 0, 1, true); expected_frame.setPayload(expected_transfer_payload, 7); ASSERT_TRUE(expected_frame.compile(expected_can_frame)); @@ -97,7 +89,7 @@ TEST(Publisher, Basic) // uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id, // uint_fast8_t frame_index, TransferID transfer_id, bool last_frame = false uavcan::Frame expected_frame(uavcan::mavlink::Message::DefaultDataTypeID, uavcan::TransferTypeMessageUnicast, - sch.getDispatcher().getSelfNodeID(), uavcan::NodeID(0x44), 0, 0, true); + node.getNodeID(), uavcan::NodeID(0x44), 0, 0, true); expected_frame.setPayload(expected_transfer_payload, 7); uavcan::CanFrame expected_can_frame; diff --git a/libuavcan/test/node/scheduler.cpp b/libuavcan/test/node/scheduler.cpp index 4c7005d37c..2e3ce8482c 100644 --- a/libuavcan/test/node/scheduler.cpp +++ b/libuavcan/test/node/scheduler.cpp @@ -33,7 +33,8 @@ TEST(Scheduler, Timers) uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1)); + uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg); + sch.getDispatcher().setNodeID(1); /* * Registration diff --git a/libuavcan/test/node/service_client.cpp b/libuavcan/test/node/service_client.cpp index 27423f1bff..954f975dfa 100644 --- a/libuavcan/test/node/service_client.cpp +++ b/libuavcan/test/node/service_client.cpp @@ -12,6 +12,7 @@ #include #include "../clock.hpp" #include "../transport/can/can.hpp" +#include "test_node.hpp" template @@ -53,29 +54,6 @@ static void stringServiceServerCallback(const uavcan::ReceivedDataStructure pool; - uavcan::PoolManager<1> poolmgr; - SystemClockDriver clock_driver; - uavcan::MarshalBufferProvider<> buffer_provider; - uavcan::OutgoingTransferRegistry<8> otr; - uavcan::Scheduler scheduler; - - MakeshiftNode(uavcan::ICanDriver& can_driver, uavcan::NodeID self_node_id) - : otr(poolmgr) - , scheduler(can_driver, poolmgr, clock_driver, otr, self_node_id) - { - poolmgr.addPool(&pool); - } - - void spin(uavcan::MonotonicDuration duration) - { - scheduler.spin(clock_driver.getMonotonic() + duration); - } -}; - - struct PairableCanDriver : public uavcan::ICanDriver, public uavcan::ICanIface { uavcan::ISystemClock& clock; @@ -144,18 +122,16 @@ struct PairableCanDriver : public uavcan::ICanDriver, public uavcan::ICanIface TEST(ServiceClient, Basic) { SystemClockDriver clock; - PairableCanDriver can_a(clock), can_b(clock); can_a.linkTogether(&can_b); - - MakeshiftNode node_a(can_a, 1), node_b(can_b, 2); + TestNode node_a(can_a, clock, 1), node_b(can_b, clock, 2); // Type registration uavcan::GlobalDataTypeRegistry::instance().reset(); uavcan::DefaultDataTypeRegistrator _registrator; // Server - uavcan::ServiceServer server(node_a.scheduler, node_a.poolmgr, node_a.buffer_provider); + uavcan::ServiceServer server(node_a); ASSERT_EQ(1, server.start(stringServiceServerCallback)); { @@ -165,17 +141,17 @@ TEST(ServiceClient, Basic) typename ServiceCallResultHandler::Binder > ClientType; ServiceCallResultHandler handler; - ClientType client1(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider); - ClientType client2(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider); - ClientType client3(node_b.scheduler, node_b.poolmgr, node_b.buffer_provider); + ClientType client1(node_b); + ClientType client2(node_b); + ClientType client3(node_b); client1.setCallback(handler.bind()); client2.setCallback(client1.getCallback()); client3.setCallback(client1.getCallback()); client3.setRequestTimeout(uavcan::MonotonicDuration::fromMSec(100)); - ASSERT_EQ(1, node_a.scheduler.getDispatcher().getNumServiceRequestListeners()); - ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // NOT listening! + ASSERT_EQ(1, node_a.getDispatcher().getNumServiceRequestListeners()); + ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners()); // NOT listening! root_ns_a::StringService::Request request; request.string_request = "Hello world"; @@ -184,7 +160,7 @@ TEST(ServiceClient, Basic) ASSERT_LT(0, client2.call(1, request)); // OK ASSERT_LT(0, client3.call(99, request)); // Will timeout! - ASSERT_EQ(3, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Listening now! + ASSERT_EQ(3, node_b.getDispatcher().getNumServiceResponseListeners()); // Listening now! ASSERT_TRUE(client1.isPending()); ASSERT_TRUE(client2.isPending()); @@ -193,7 +169,7 @@ TEST(ServiceClient, Basic) node_a.spin(uavcan::MonotonicDuration::fromMSec(10)); node_b.spin(uavcan::MonotonicDuration::fromMSec(10)); - ASSERT_EQ(1, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Third is still listening! + ASSERT_EQ(1, node_b.getDispatcher().getNumServiceResponseListeners()); // Third is still listening! ASSERT_FALSE(client1.isPending()); ASSERT_FALSE(client2.isPending()); @@ -211,7 +187,7 @@ TEST(ServiceClient, Basic) ASSERT_FALSE(client2.isPending()); ASSERT_FALSE(client3.isPending()); - ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); // Third has timed out :( + ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners()); // Third has timed out :( // Validating ASSERT_TRUE(handler.match(ResultType::ErrorTimeout, 99, root_ns_a::StringService::Response())); @@ -219,11 +195,11 @@ TEST(ServiceClient, Basic) // Stray request ASSERT_LT(0, client3.call(99, request)); // Will timeout! ASSERT_TRUE(client3.isPending()); - ASSERT_EQ(1, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); + ASSERT_EQ(1, node_b.getDispatcher().getNumServiceResponseListeners()); } // All destroyed - nobody listening - ASSERT_EQ(0, node_b.scheduler.getDispatcher().getNumServiceResponseListeners()); + ASSERT_EQ(0, node_b.getDispatcher().getNumServiceResponseListeners()); } diff --git a/libuavcan/test/node/service_server.cpp b/libuavcan/test/node/service_server.cpp index 25811a375a..5875569643 100644 --- a/libuavcan/test/node/service_server.cpp +++ b/libuavcan/test/node/service_server.cpp @@ -8,6 +8,7 @@ #include #include "../clock.hpp" #include "../transport/can/can.hpp" +#include "test_node.hpp" struct ServerImpl @@ -36,30 +37,22 @@ struct ServerImpl TEST(ServiceServer, Basic) { - uavcan::PoolAllocator pool; - uavcan::PoolManager<1> poolmgr; - poolmgr.addPool(&pool); - // Manual type registration - we can't rely on the GDTR state uavcan::GlobalDataTypeRegistry::instance().reset(); uavcan::DefaultDataTypeRegistrator _registrator; SystemClockDriver clock_driver; CanDriverMock can_driver(1, clock_driver); - - uavcan::MarshalBufferProvider<> buffer_provider; - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - - uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1)); + TestNode node(can_driver, clock_driver, 1); ServerImpl impl("456"); { - uavcan::ServiceServer server(sch, poolmgr, buffer_provider); + uavcan::ServiceServer server(node); - ASSERT_EQ(0, sch.getDispatcher().getNumServiceRequestListeners()); + ASSERT_EQ(0, node.getDispatcher().getNumServiceRequestListeners()); server.start(impl.bind()); - ASSERT_EQ(1, sch.getDispatcher().getNumServiceRequestListeners()); + ASSERT_EQ(1, node.getDispatcher().getNumServiceRequestListeners()); /* * Request frames @@ -78,7 +71,7 @@ TEST(ServiceServer, Basic) can_driver.ifaces[0].pushRx(rx_frame); } - sch.spin(clock_driver.getMonotonic() + uavcan::MonotonicDuration::fromUSec(10000)); + node.spin(clock_driver.getMonotonic() + uavcan::MonotonicDuration::fromUSec(10000)); /* * Responses (MFT) @@ -113,7 +106,7 @@ TEST(ServiceServer, Basic) ASSERT_EQ(0, server.getRequestFailureCount()); ASSERT_EQ(0, server.getResponseFailureCount()); - ASSERT_EQ(1, sch.getDispatcher().getNumServiceRequestListeners()); + ASSERT_EQ(1, node.getDispatcher().getNumServiceRequestListeners()); } - ASSERT_EQ(0, sch.getDispatcher().getNumServiceRequestListeners()); + ASSERT_EQ(0, node.getDispatcher().getNumServiceRequestListeners()); } diff --git a/libuavcan/test/node/subscriber.cpp b/libuavcan/test/node/subscriber.cpp index 5ff4d0ad1c..1b215852f5 100644 --- a/libuavcan/test/node/subscriber.cpp +++ b/libuavcan/test/node/subscriber.cpp @@ -9,6 +9,7 @@ #include #include "../clock.hpp" #include "../transport/can/can.hpp" +#include "test_node.hpp" template @@ -59,27 +60,20 @@ struct SubscriptionListener TEST(Subscriber, Basic) { - uavcan::PoolAllocator pool; - uavcan::PoolManager<1> poolmgr; - poolmgr.addPool(&pool); - // Manual type registration - we can't rely on the GDTR state uavcan::GlobalDataTypeRegistry::instance().reset(); uavcan::DefaultDataTypeRegistrator _registrator; SystemClockDriver clock_driver; CanDriverMock can_driver(2, clock_driver); - - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - - uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1)); + TestNode node(can_driver, clock_driver, 1); typedef SubscriptionListener Listener; - uavcan::Subscriber sub_extended(sch, poolmgr); - uavcan::Subscriber sub_extended2(sch, poolmgr); // Not used - uavcan::Subscriber sub_simple(sch, poolmgr); - uavcan::Subscriber sub_simple2(sch, poolmgr); // Not used + uavcan::Subscriber sub_extended(node); + uavcan::Subscriber sub_extended2(node); // Not used + uavcan::Subscriber sub_simple(node); + uavcan::Subscriber sub_simple2(node); // Not used std::cout << "sizeof(uavcan::Subscriber): " << @@ -115,7 +109,7 @@ TEST(Subscriber, Basic) { uavcan::TransferType tt = (i & 1) ? uavcan::TransferTypeMessageUnicast : uavcan::TransferTypeMessageBroadcast; uavcan::NodeID dni = (tt == uavcan::TransferTypeMessageBroadcast) ? - uavcan::NodeID::Broadcast : sch.getDispatcher().getSelfNodeID(); + uavcan::NodeID::Broadcast : node.getDispatcher().getNodeID(); // uint_fast16_t data_type_id, TransferType transfer_type, NodeID src_node_id, NodeID dst_node_id, // uint_fast8_t frame_index, TransferID transfer_id, bool last_frame uavcan::Frame frame(uavcan::mavlink::Message::DefaultDataTypeID, tt, uavcan::NodeID(i + 100), dni, 0, i, true); @@ -127,19 +121,19 @@ TEST(Subscriber, Basic) /* * Reception */ - ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); + ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners()); ASSERT_EQ(1, sub_extended.start(listener.bindExtended())); ASSERT_EQ(1, sub_extended2.start(listener.bindExtended())); ASSERT_EQ(1, sub_simple.start(listener.bindSimple())); ASSERT_EQ(1, sub_simple2.start(listener.bindSimple())); - ASSERT_EQ(4, sch.getDispatcher().getNumMessageListeners()); + ASSERT_EQ(4, node.getDispatcher().getNumMessageListeners()); sub_extended2.stop(); // These are not used - making sure they aren't receiving anything sub_simple2.stop(); - ASSERT_EQ(2, sch.getDispatcher().getNumMessageListeners()); + ASSERT_EQ(2, node.getDispatcher().getNumMessageListeners()); for (unsigned int i = 0; i < rx_frames.size(); i++) { @@ -147,7 +141,7 @@ TEST(Subscriber, Basic) can_driver.ifaces[1].pushRx(rx_frames[i]); } - ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000))); + ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000))); /* * Validation @@ -175,14 +169,14 @@ TEST(Subscriber, Basic) /* * Unregistration */ - ASSERT_EQ(2, sch.getDispatcher().getNumMessageListeners()); + ASSERT_EQ(2, node.getDispatcher().getNumMessageListeners()); sub_extended.stop(); sub_extended2.stop(); sub_simple.stop(); sub_simple2.stop(); - ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); + ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners()); } @@ -194,26 +188,19 @@ static void panickingSink(const uavcan::ReceivedDataStructure pool; - uavcan::PoolManager<1> poolmgr; - poolmgr.addPool(&pool); - // Manual type registration - we can't rely on the GDTR state uavcan::GlobalDataTypeRegistry::instance().reset(); uavcan::DefaultDataTypeRegistrator _registrator; SystemClockDriver clock_driver; CanDriverMock can_driver(2, clock_driver); - - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - - uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1)); + TestNode node(can_driver, clock_driver, 1); { - uavcan::Subscriber sub(sch, poolmgr); - ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); + uavcan::Subscriber sub(node); + ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners()); sub.start(panickingSink); - ASSERT_EQ(1, sch.getDispatcher().getNumMessageListeners()); + ASSERT_EQ(1, node.getDispatcher().getNumMessageListeners()); ASSERT_EQ(0, sub.getFailureCount()); @@ -229,36 +216,29 @@ TEST(Subscriber, FailureCount) can_driver.ifaces[1].pushRx(rx_frame); } - ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000))); + ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000))); ASSERT_EQ(4, sub.getFailureCount()); - ASSERT_EQ(1, sch.getDispatcher().getNumMessageListeners()); // Still there + ASSERT_EQ(1, node.getDispatcher().getNumMessageListeners()); // Still there } - ASSERT_EQ(0, sch.getDispatcher().getNumMessageListeners()); // Removed + ASSERT_EQ(0, node.getDispatcher().getNumMessageListeners()); // Removed } TEST(Subscriber, SingleFrameTransfer) { - uavcan::PoolAllocator pool; - uavcan::PoolManager<1> poolmgr; - poolmgr.addPool(&pool); - // Manual type registration - we can't rely on the GDTR state uavcan::GlobalDataTypeRegistry::instance().reset(); uavcan::DefaultDataTypeRegistrator _registrator; SystemClockDriver clock_driver; CanDriverMock can_driver(2, clock_driver); - - uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - - uavcan::Scheduler sch(can_driver, poolmgr, clock_driver, out_trans_reg, uavcan::NodeID(1)); + TestNode node(can_driver, clock_driver, 1); typedef SubscriptionListener Listener; - uavcan::Subscriber sub(sch, poolmgr); + uavcan::Subscriber sub(node); std::cout << "sizeof(uavcan::Subscriber): " << @@ -280,7 +260,7 @@ TEST(Subscriber, SingleFrameTransfer) can_driver.ifaces[1].pushRx(rx_frame); } - ASSERT_LE(0, sch.spin(clock_driver.getMonotonic() + durMono(10000))); + ASSERT_LE(0, node.spin(clock_driver.getMonotonic() + durMono(10000))); ASSERT_EQ(0, sub.getFailureCount()); diff --git a/libuavcan/test/node/test_node.hpp b/libuavcan/test/node/test_node.hpp new file mode 100644 index 0000000000..2ebbc9bcc0 --- /dev/null +++ b/libuavcan/test/node/test_node.hpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Pavel Kirienko + */ + +#pragma once + +#include +#include + +struct TestNode : public uavcan::INode +{ + uavcan::PoolAllocator pool; + uavcan::PoolManager<1> poolmgr; + uavcan::MarshalBufferProvider<> buffer_provider; + uavcan::OutgoingTransferRegistry<8> otr; + uavcan::Scheduler scheduler; + + TestNode(uavcan::ICanDriver& can_driver, uavcan::ISystemClock& clock_driver, uavcan::NodeID self_node_id) + : otr(poolmgr) + , scheduler(can_driver, poolmgr, clock_driver, otr) + { + poolmgr.addPool(&pool); + setNodeID(self_node_id); + } + + uavcan::PoolManager<1>& getAllocator() { return poolmgr; } + uavcan::Scheduler& getScheduler() { return scheduler; } + const uavcan::Scheduler& getScheduler() const { return scheduler; } + uavcan::IMarshalBufferProvider& getMarshalBufferProvider() { return buffer_provider; } +}; + diff --git a/libuavcan/test/transport/dispatcher.cpp b/libuavcan/test/transport/dispatcher.cpp index 93d2847c36..700111e360 100644 --- a/libuavcan/test/transport/dispatcher.cpp +++ b/libuavcan/test/transport/dispatcher.cpp @@ -43,7 +43,10 @@ TEST(Dispatcher, Reception) uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg, SELF_NODE_ID); + uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg); + ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once + ASSERT_FALSE(dispatcher.setNodeID(SELF_NODE_ID)); + ASSERT_EQ(SELF_NODE_ID, dispatcher.getNodeID()); DispatcherTransferEmulator emulator(driver, SELF_NODE_ID); @@ -192,7 +195,9 @@ TEST(Dispatcher, Transmission) uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg, SELF_NODE_ID); + uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg); + ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once + ASSERT_FALSE(dispatcher.setNodeID(SELF_NODE_ID)); /* * Transmission @@ -229,7 +234,9 @@ TEST(Dispatcher, Spin) uavcan::OutgoingTransferRegistry<8> out_trans_reg(poolmgr); - uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg, SELF_NODE_ID); + uavcan::Dispatcher dispatcher(driver, poolmgr, clockmock, out_trans_reg); + ASSERT_TRUE(dispatcher.setNodeID(SELF_NODE_ID)); // Can be set only once + ASSERT_FALSE(dispatcher.setNodeID(SELF_NODE_ID)); clockmock.monotonic_auto_advance = 100; diff --git a/libuavcan/test/transport/transfer_sender.cpp b/libuavcan/test/transport/transfer_sender.cpp index 17a673b3ce..e4ccf0a8d5 100644 --- a/libuavcan/test/transport/transfer_sender.cpp +++ b/libuavcan/test/transport/transfer_sender.cpp @@ -39,8 +39,10 @@ TEST(TransferSender, Basic) static const uavcan::NodeID TX_NODE_ID(64); static const uavcan::NodeID RX_NODE_ID(65); - uavcan::Dispatcher dispatcher_tx(driver, poolmgr, clockmock, out_trans_reg, TX_NODE_ID); - uavcan::Dispatcher dispatcher_rx(driver, poolmgr, clockmock, out_trans_reg, RX_NODE_ID); + uavcan::Dispatcher dispatcher_tx(driver, poolmgr, clockmock, out_trans_reg); + uavcan::Dispatcher dispatcher_rx(driver, poolmgr, clockmock, out_trans_reg); + ASSERT_TRUE(dispatcher_tx.setNodeID(TX_NODE_ID)); + ASSERT_TRUE(dispatcher_rx.setNodeID(RX_NODE_ID)); /* * Test environment