Loopback frame listener API implemented; TransferSender supports iface masks and CanIOFlags. All of that is necessary to implement network-wide time synchronization.

This commit is contained in:
Pavel Kirienko
2014-03-21 17:30:25 +04:00
parent 9d35c616ef
commit 54921a3738
7 changed files with 250 additions and 12 deletions
@@ -14,6 +14,44 @@
namespace uavcan
{
class Dispatcher;
class LoopbackFrameListenerBase : public LinkedListNode<LoopbackFrameListenerBase>, Noncopyable
{
Dispatcher& dispatcher_;
protected:
LoopbackFrameListenerBase(Dispatcher& dispatcher)
: dispatcher_(dispatcher)
{ }
virtual ~LoopbackFrameListenerBase() { stopListening(); }
void startListening();
void stopListening();
bool isListening() const;
Dispatcher& getDispatcher() { return dispatcher_; }
public:
virtual void handleLoopbackFrame(const RxFrame& frame) = 0;
};
class LoopbackFrameListenerRegistry : Noncopyable
{
LinkedListRoot<LoopbackFrameListenerBase> listeners_;
public:
void add(LoopbackFrameListenerBase* listener);
void remove(LoopbackFrameListenerBase* listener);
bool doesExist(const LoopbackFrameListenerBase* listener) const;
unsigned int getNumListeners() const { return listeners_.getLength(); }
void invokeListeners(RxFrame& frame);
};
class Dispatcher : Noncopyable
{
CanIOManager canio_;
@@ -52,9 +90,12 @@ class Dispatcher : Noncopyable
ListenerRegister lsrv_req_;
ListenerRegister lsrv_resp_;
LoopbackFrameListenerRegistry loopback_listeners_;
NodeID self_node_id_;
void handleFrame(const CanRxFrame& can_frame);
void handleLoopbackFrame(const CanRxFrame& can_frame);
public:
Dispatcher(ICanDriver& driver, IAllocator& allocator, ISystemClock& sysclock, IOutgoingTransferRegistry& otr)
@@ -69,7 +110,7 @@ public:
* Refer to CanIOManager::send() for the parameter description
*/
int send(const Frame& frame, MonotonicTime tx_deadline, MonotonicTime blocking_deadline, CanTxQueue::Qos qos,
CanIOFlags flags);
CanIOFlags flags, uint8_t iface_mask);
void cleanup(MonotonicTime ts);
@@ -91,6 +132,8 @@ public:
IOutgoingTransferRegistry& getOutgoingTransferRegistry() { return outgoing_transfer_reg_; }
LoopbackFrameListenerRegistry& getLoopbackFrameListenerRegistry() { return loopback_listeners_; }
NodeID getNodeID() const { return self_node_id_; }
bool setNodeID(NodeID nid);
@@ -21,10 +21,13 @@ class TransferSender
const CanTxQueue::Qos qos_;
const TransferCRC crc_base_;
CanIOFlags flags_;
uint8_t iface_mask_;
Dispatcher& dispatcher_;
public:
enum { AllIfacesMask = 0xFF };
static MonotonicDuration getDefaultMaxTransferInterval()
{
return MonotonicDuration::fromMSec(60 * 1000);
@@ -37,12 +40,20 @@ public:
, qos_(qos)
, crc_base_(data_type.getSignature().toTransferCRC())
, flags_(CanIOFlags(0))
, iface_mask_(AllIfacesMask)
, dispatcher_(dispatcher)
{ }
CanIOFlags getCanIOFlags() const { return flags_; }
void setCanIOFlags(CanIOFlags flags) { flags_ = flags; }
uint8_t getIfaceMask() const { return iface_mask_; }
void setIfaceMask(uint8_t iface_mask)
{
assert(iface_mask);
iface_mask_ = iface_mask;
}
/**
* Send with explicit Transfer ID.
* Should be used only for service responses, where response TID should match request TID.