From 8891015321fae6aca4218e101109685837a9d2aa Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Mon, 8 Jun 2015 11:57:05 +0300 Subject: [PATCH] IRxFrameListener --- .../include/uavcan/transport/dispatcher.hpp | 26 +++++++++++++++++++ libuavcan/src/transport/uc_dispatcher.cpp | 10 +++++++ 2 files changed, 36 insertions(+) diff --git a/libuavcan/include/uavcan/transport/dispatcher.hpp b/libuavcan/include/uavcan/transport/dispatcher.hpp index 9a277e4f2a..bf615a1665 100644 --- a/libuavcan/include/uavcan/transport/dispatcher.hpp +++ b/libuavcan/include/uavcan/transport/dispatcher.hpp @@ -58,6 +58,20 @@ public: void invokeListeners(RxFrame& frame); }; +/** + * Implement this interface to receive notifications about all incoming CAN frames, including loopback. + */ +class UAVCAN_EXPORT IRxFrameListener +{ +public: + virtual ~IRxFrameListener() { } + + /** + * Make sure to filter out loopback frames if they are not wanted. + */ + virtual void handleRxFrame(const CanRxFrame& frame, CanIOFlags flags) = 0; +}; + /** * This class performs low-level CAN frame routing. */ @@ -103,6 +117,7 @@ class UAVCAN_EXPORT Dispatcher : Noncopyable ListenerRegistry lsrv_resp_; LoopbackFrameListenerRegistry loopback_listeners_; + IRxFrameListener* rx_listener_; NodeID self_node_id_; bool self_node_id_is_set_; @@ -110,11 +125,14 @@ class UAVCAN_EXPORT Dispatcher : Noncopyable void handleFrame(const CanRxFrame& can_frame); void handleLoopbackFrame(const CanRxFrame& can_frame); + void notifyRxFrameListener(const CanRxFrame& can_frame, CanIOFlags flags); + public: Dispatcher(ICanDriver& driver, IPoolAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr) : canio_(driver, allocator, sysclock) , sysclock_(sysclock) , outgoing_transfer_reg_(otr) + , rx_listener_(NULL) , self_node_id_(NodeID::Broadcast) // Default , self_node_id_is_set_(false) { } @@ -180,6 +198,14 @@ public: LoopbackFrameListenerRegistry& getLoopbackFrameListenerRegistry() { return loopback_listeners_; } + IRxFrameListener* getRxFrameListener() const { return rx_listener_; } + void removeRxFrameListener() { rx_listener_ = NULL; } + void installRxFrameListener(IRxFrameListener* listener) + { + UAVCAN_ASSERT(listener != NULL); + rx_listener_ = listener; + } + /** * Node ID can be set only once. * Non-unicast Node ID puts the node into passive mode. diff --git a/libuavcan/src/transport/uc_dispatcher.cpp b/libuavcan/src/transport/uc_dispatcher.cpp index eb41b83e52..1c124256fd 100644 --- a/libuavcan/src/transport/uc_dispatcher.cpp +++ b/libuavcan/src/transport/uc_dispatcher.cpp @@ -199,6 +199,14 @@ void Dispatcher::handleLoopbackFrame(const CanRxFrame& can_frame) loopback_listeners_.invokeListeners(frame); } +void Dispatcher::notifyRxFrameListener(const CanRxFrame& can_frame, CanIOFlags flags) +{ + if (rx_listener_ != NULL) + { + rx_listener_->handleRxFrame(can_frame, flags); + } +} + int Dispatcher::spin(MonotonicTime deadline) { int num_frames_processed = 0; @@ -222,6 +230,7 @@ int Dispatcher::spin(MonotonicTime deadline) num_frames_processed++; handleFrame(frame); } + notifyRxFrameListener(frame, flags); } } while (sysclock_.getMonotonic() < deadline); @@ -253,6 +262,7 @@ int Dispatcher::spinOnce() num_frames_processed++; handleFrame(frame); } + notifyRxFrameListener(frame, flags); } else {