Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
If.hxx
Go to the documentation of this file.
1
35#ifndef _OPENLCB_IF_HXX_
36#define _OPENLCB_IF_HXX_
37
39#include <string>
40
42#include "executor/Executor.hxx"
43#include "executor/Service.hxx"
44#include "openlcb/Convert.hxx"
45#include "openlcb/Defs.hxx"
46#include "openlcb/Node.hxx"
47#include "utils/Buffer.hxx"
48#include "utils/Map.hxx"
49#include "utils/Queue.hxx"
50
51namespace openlcb
52{
53
54class Node;
55class StreamTransport;
56
61extern void send_event(Node* src_node, uint64_t event_id);
62
72{
74 : src({0, 0}), dst({0, 0}), flagsSrc(0), flagsDst(0) {}
75
76 void clear()
77 {
78 reset((Defs::MTI)0, 0, EMPTY_PAYLOAD);
79 }
80
81 void reset(Defs::MTI mti, NodeID src, NodeHandle dst, string payload)
82 {
83 this->mti = mti;
84 this->src = {src, 0};
85 this->dst = dst;
86 this->payload = std::move(payload);
87 this->dstNode = nullptr;
88 this->flagsSrc = 0;
89 this->flagsDst = 0;
90 }
91
92 void reset(Defs::MTI mti, NodeID src, string payload)
93 {
94 this->mti = mti;
95 this->src = {src, 0};
96 this->dst = {0, 0};
97 this->payload = std::move(payload);
98 this->dstNode = nullptr;
99 this->flagsSrc = 0;
100 this->flagsDst = 0;
101 }
102
113 string payload;
114
115 unsigned flagsSrc : 4;
116 unsigned flagsDst : 4;
117 unsigned get_flags_src() {
118 return flagsSrc;
119 }
120 unsigned get_flags_dst() {
121 return flagsDst;
122 }
123 void set_flag_src(unsigned flags) {
124 flagsSrc |= flags;
125 }
126 void clear_flag_src(unsigned flags) {
127 flagsSrc &= ~flags;
128 }
130 bool has_flag_src(unsigned flags) {
131 return ((flagsSrc & flags) == flags);
132 }
133 void set_flag_dst(unsigned flags) {
134 flagsDst |= flags;
135 }
136 void clear_flag_dst(unsigned flags) {
137 flagsDst &= ~flags;
138 }
140 bool has_flag_dst(unsigned flags) {
141 return ((flagsDst & flags) == flags);
142 }
143
144 typedef uint32_t id_type;
145 id_type id() const
146 {
147 return static_cast<uint32_t>(mti);
148 }
149
151 unsigned priority()
152 {
153 return Defs::mti_priority(mti);
154 }
155
170 enum SrcFlags {
171 // 1, 2, 4, 8: free
172 };
173};
174
178
184class If : public Service
185{
186public:
192 If(ExecutorBase *executor, int local_nodes_count);
193
195 virtual ~If()
196 {
197 }
198
201 {
203 if (txHook_)
204 {
205 txHook_();
206 }
207 return globalWriteFlow_;
208 }
219
222
225 {
226 return &dispatcher_;
227 }
228
235 virtual void add_owned_flow(Executable *e) = 0;
236
243 {
244 NodeID id = node->node_id();
245 HASSERT(localNodes_.find(id) == localNodes_.end());
246 localNodes_[id] = node;
247 }
248
255 virtual void delete_local_node(Node *node) = 0;
256
264 {
265 auto it = localNodes_.find(id);
266 if (it == localNodes_.end())
267 {
268 return nullptr;
269 }
270 return it->second;
271 }
272
280 {
281 return lookup_local_node(handle.id);
282 }
283
290 auto it = localNodes_.begin();
291 if (it == localNodes_.end()) return nullptr;
292 return it->second;
293 }
294
305 auto it = localNodes_.find(previous);
306 if (it == localNodes_.end())
307 {
308 return nullptr;
309 }
310 ++it;
311 if (it == localNodes_.end())
312 {
313 return nullptr;
314 }
315 return it->second;
316 }
317
320 virtual bool matching_node(NodeHandle expected,
321 NodeHandle actual) = 0;
322
323
327 virtual void canonicalize_handle(NodeHandle *h) {}
328
333
337 void set_tx_hook(std::function<void()> hook)
338 {
339 txHook_ = std::move(hook);
340 }
341
349
355 {
356 HASSERT(streamTransport_ == nullptr);
358 }
359
360protected:
361 void remove_local_node_from_map(Node *node)
362 {
363 auto it = localNodes_.find(node->node_id());
364 HASSERT(it != localNodes_.end());
365 localNodes_.erase(it);
366 }
367
372
373private:
376
378 std::function<void()> txHook_;
379
381
384
387
388 friend class VerifyNodeIdHandler;
389
391};
392
396
399 : public MessageStateFlowBase
400{
401public:
403 : MessageStateFlowBase(iface)
404 {
405 }
406
407 If *iface()
408 {
409 return static_cast<If *>(service());
410 }
411
414 {
415 return message()->data();
416 }
417};
418
426template <typename... Args> void send_message(Node *src_node, Defs::MTI mti, Args &&...args)
427{
429 mainBufferPool->alloc(&msg);
430 msg->data()->reset(mti, src_node->node_id(), std::forward<Args>(args)...);
431 if (msg->data()->dst == NodeHandle())
432 {
433 src_node->iface()->global_message_write_flow()->send(msg);
434 }
435 else
436 {
437 src_node->iface()->addressed_message_write_flow()->send(msg);
438 }
439}
440
441} // namespace openlcb
442
443#endif // _OPENLCB_IF_HXX_
DynamicPool * mainBufferPool
main buffer pool instance
Definition Buffer.cxx:37
Base class for all QMember types that hold data in an expandable format.
Definition Buffer.hxx:195
T * data()
get a pointer to the start of the data.
Definition Buffer.hxx:215
Type-specific implementations of the DispatchFlow methods.
An object that can be scheduled on an executor to run.
This class implements an execution of tasks pulled off an input queue.
Definition Executor.hxx:64
Abstract class for message recipients.
virtual void send(MessageType *message, unsigned priority=UINT_MAX)=0
Entry point to the flow.
Though the standard template library includes std::map, commonly implemented as a Red Black tree,...
Definition Map.hxx:63
Node information.
Definition Devtab.hxx:549
void alloc(Buffer< BufferType > **result, Executable *flow=NULL)
Get a free item out of the pool.
Definition Buffer.hxx:292
A list of queues.
Definition Queue.hxx:466
Collection of related state machines that pend on incoming messages.
ExecutorBase * executor()
State flow with a given typed input queue.
MessageType * message()
Abstract class representing an OpenLCB Interface.
Definition If.hxx:185
VNodeMap localNodes_
Local virtual nodes registered on this interface.
Definition If.hxx:383
virtual void canonicalize_handle(NodeHandle *h)
Canonicalizes the node handle: fills in id and/or alias from the maps the interface holds internally.
Definition If.hxx:327
virtual void delete_local_node(Node *node)=0
Removes a local node from this interface.
MessageHandler * global_message_write_flow()
Definition If.hxx:200
MessageDispatchFlow * dispatcher()
Definition If.hxx:224
Node * first_local_node()
Definition If.hxx:289
virtual ~If()
Destructor.
Definition If.hxx:195
void add_local_node(Node *node)
Registers a new local node on this interface.
Definition If.hxx:242
std::function< void()> txHook_
This function is pinged every time a message is transmitted.
Definition If.hxx:378
MessageHandler * addressedWriteFlow_
Allocator containing the addressed write flows.
Definition If.hxx:371
virtual Node * lookup_local_node_handle(NodeHandle handle)
Looks up a node ID in the local nodes' registry.
Definition If.hxx:279
MessageDispatchFlow dispatcher_
Flow responsible for routing incoming messages to handlers.
Definition If.hxx:375
Node * lookup_local_node(NodeID id)
Looks up a node ID in the local nodes' registry.
Definition If.hxx:263
void set_stream_transport(StreamTransport *s)
Adds the necessary object for this interface to support stream transport.
Definition If.hxx:354
StreamTransport * streamTransport_
Accessor for the objects and variables for supporting stream transport.
Definition If.hxx:386
virtual void add_owned_flow(Executable *e)=0
Transfers ownership of a module to the interface.
MessageHandler * globalWriteFlow_
Allocator containing the global write flows.
Definition If.hxx:369
DispatchFlow< Buffer< GenMessage >, 4 > MessageDispatchFlow
Type of the dispatcher of incoming NMRAnet messages.
Definition If.hxx:221
StreamTransport * stream_transport()
Definition If.hxx:345
void set_tx_hook(std::function< void()> hook)
Sets a transmit hook.
Definition If.hxx:337
Node * next_local_node(NodeID previous)
Iterator helper on the local nodes map.
Definition If.hxx:304
MessageHandler * addressed_message_write_flow()
Definition If.hxx:210
virtual NodeID get_default_node_id()=0
virtual bool matching_node(NodeHandle expected, NodeHandle actual)=0
Base class for incoming message handler flows.
Definition If.hxx:400
GenMessage * nmsg()
Returns the NMRAnet message we received.
Definition If.hxx:413
Base class for NMRAnet nodes conforming to the asynchronous interface.
Definition Node.hxx:52
Collects the objects needed to support streams on an OpenLCB interface.
This handler handles VerifyNodeId messages (both addressed and global) on the interface level.
Definition IfImpl.hxx:140
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Removes default copy-constructor and assignment added by C++.
Definition macros.h:171
string EMPTY_PAYLOAD
A global class / variable for empty or not-yet-initialized payloads.
Definition If.cxx:152
StateFlow< Buffer< GenMessage >, QList< 4 > > MessageStateFlowBase
Message handlers that are implemented as state flows should derive from this class.
Definition If.hxx:395
uint64_t NodeID
48-bit NMRAnet Node ID type
void send_event(Node *src_node, uint64_t event_id)
Helper function to send an event report to the bus.
Definition If.cxx:143
FlowInterface< Buffer< GenMessage > > MessageHandler
Interface class for all handlers that can be registered in the dispatcher to receive incoming NMRAnet...
Definition If.hxx:177
void send_message(Node *src_node, Defs::MTI mti, Args &&...args)
Sends an OpenLCB message to the bus.
Definition If.hxx:426
static unsigned int mti_priority(MTI mti)
Get the MTI priority (value 0 through 3).
MTI
Known Message type indicators.
This class is used in the dispatching of incoming or outgoing NMRAnet messages to the message handler...
Definition If.hxx:72
@ DSTFLAG_NOT_FIRST_MESSAGE
Signals to the stack that we need to set the continuation bits in the outgoing message to indicate th...
Definition If.hxx:163
@ WAIT_FOR_LOCAL_LOOPBACK
Specifies that the stack should wait for the local loopback processing before invoking the done notif...
Definition If.hxx:159
@ DSTFLAG_NOT_LAST_MESSAGE
Signals to the stack that we need to set the continuation bits in the outgoing message to indicate th...
Definition If.hxx:167
unsigned priority()
Returns the NMRAnet-defined priority band, in the range of 0..3.
Definition If.hxx:151
NodeHandle dst
Destination node.
Definition If.hxx:106
Node * dstNode
If the destination node is local, this value is non-NULL.
Definition If.hxx:110
bool has_flag_src(unsigned flags)
Returns true if src flags has all the specified flags set.
Definition If.hxx:130
NodeHandle src
Source node.
Definition If.hxx:104
Defs::MTI mti
OpenLCB MTI of the incoming message.
Definition If.hxx:108
string payload
Data content in the message body.
Definition If.hxx:113
bool has_flag_dst(unsigned flags)
Returns true if src flags has all the specified flags set.
Definition If.hxx:140
Container of both a NodeID and NodeAlias.
NodeID id
48-bit NMRAnet Node ID