Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
IfImpl.cxx
Go to the documentation of this file.
1
36#include "openlcb/IfImpl.hxx"
37
38namespace openlcb
39{
40
42{
43 if (nmsg()->dst.id)
44 {
46 if (nmsg()->dstNode)
47 {
48 return call_immediately(STATE(send_to_local_node));
49 }
50 }
51 return send_to_hardware();
52}
53
55{
56 unsigned prio = priority();
57 // We do not believe infinite priority and use the one from the MTI
58 // instead.
59 if (prio >= (1 << 16))
60 {
61 prio = message()->data()->priority();
62 }
64 return call_immediately(STATE(send_finished));
65}
66
68{
69 if (!message()->data()->has_flag_dst(
71 {
72 // We do not pass on the done notifiable with the loopbacked message.
73 message()->set_done(nullptr);
74 }
75 unsigned loopback_prio = message()->data()->priority();
76 async_if()->dispatcher()->send(transfer_message(), loopback_prio);
77 return release_and_exit();
78}
79
80#if 0
82
85void Node::ident_info_reply(NodeHandle dst)
86{
87 /* macro for condensing the size calculation code */
88#define ADD_STRING_SIZE(_str, _max) \
89 { \
90 if ((_str)) \
91 { \
92 size_t len = strlen((_str)); \
93 size += len > (_max) ? (_max) : len; \
94 } \
95 }
96
97 /* macro for condensing the string insertion code */
98#define INSERT_STRING(_str, _max) \
99 { \
100 if ((_str)) \
101 { \
102 size_t len = strlen((_str)); \
103 len = len > (_max) ? (_max) : len; \
104 memcpy(pos, (_str), len); \
105 pos[len] = '\0'; \
106 pos += len + 1; \
107 } \
108 else \
109 { \
110 pos[0] = '\0'; \
111 pos++; \
112 } \
113 }
114
115 /* we make this static so that it does not use up stack */
119 static char ident[8+40+40+20+20+62+63];
120 char *pos = ident;
121 size_t size = 8;
122
123 ADD_STRING_SIZE(MANUFACTURER, 40);
124 ADD_STRING_SIZE(model, 40);
125 ADD_STRING_SIZE(HARDWARE_REV, 20);
126 ADD_STRING_SIZE(SOFTWARE_REV, 20);
127 ADD_STRING_SIZE(userName, 62);
128 ADD_STRING_SIZE(userDescription, 63);
129
130 pos[0] = SIMPLE_NODE_IDENT_VERSION_A;
131 pos++;
132
133 INSERT_STRING(MANUFACTURER, 40);
134 INSERT_STRING(model, 40);
135 INSERT_STRING(HARDWARE_REV, 20);
136 INSERT_STRING(SOFTWARE_REV, 20);
137
138 pos[0] = SIMPLE_NODE_IDENT_VERSION_B;
139 pos++;
140
141 INSERT_STRING(userName, 62);
142 INSERT_STRING(userDescription, 63);
143
144 for (int index = 0; size; )
145 {
146 size_t segment_size = size > 6 ? 6 : size;
147 Buffer *buffer = buffer_alloc(6);
148 memcpy(buffer->start(), ident + index, segment_size);
149 buffer->advance(segment_size);
150 write(Defs::MTI_IDENT_INFO_REPLY, dst, buffer);
151 size -= segment_size;
152 index += segment_size;
153 }
154}
155
159void Node::protocol_support_reply(NodeHandle dst)
160{
164 uint64_t protocols = PROTOCOL_IDENTIFICATION |
165 DATAGRAM |
166 EVENT_EXCHANGE |
167 SIMPLE_NODE_INFORMATION |
168 MEMORY_CONFIGURATION |
169 CDI;
170
171 Buffer *buffer = buffer_alloc(6);
172 uint8_t *bytes = (uint8_t*)buffer->start();
173
174 bytes[0] = (protocols >> 40) & 0xff;
175 bytes[1] = (protocols >> 32) & 0xff;
176 bytes[2] = (protocols >> 24) & 0xff;
177 bytes[3] = (protocols >> 16) & 0xff;
178 bytes[4] = (protocols >> 8) & 0xff;
179 bytes[5] = (protocols >> 0) & 0xff;
180
181 buffer->advance(6);
182
183 write(Defs::MTI_PROTOCOL_SUPPORT_REPLY, dst, buffer);
184}
185
186#endif // if 0
187
188} // namespace openlcb
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
Definition StateFlow.hxx:61
Base class for all QMember types that hold data in an expandable format.
Definition Buffer.hxx:195
Return type for a state flow callback.
void send(MessageType *msg, unsigned priority=UINT_MAX) OVERRIDE
Sends a message to the state flow for processing.
MessageType * transfer_message()
Releases ownership of the current message.
MessageType * message()
MessageDispatchFlow * dispatcher()
Definition If.hxx:224
virtual Node * lookup_local_node_handle(NodeHandle handle)
Looks up a node ID in the local nodes' registry.
Definition If.hxx:279
virtual Action send_to_local_node()
This state is called when an addressed message's destination is a node that is local to this interfac...
Definition IfImpl.cxx:54
Action global_entry()
Global write flows should return to this state AFTER sending the message to the hardware.
Definition IfImpl.cxx:67
virtual Action send_finished()
Virtual method called after the send is completed, i.e., all the frames are generated and sent to the...
Definition IfImpl.hxx:71
GenMessage * nmsg()
Implementations shall call this function when they are done with sending the packet.
Definition IfImpl.hxx:88
Action addressed_entry()
Addressed write flows should call this state BEFORE sending to the hardware.
Definition IfImpl.cxx:41
virtual Action send_to_hardware()=0
This function will be called (on the main executor) to initiate sending this message to the hardware.
@ MTI_IDENT_INFO_REPLY
node identity reply
@ MTI_PROTOCOL_SUPPORT_REPLY
reply with supported protocols
@ WAIT_FOR_LOCAL_LOOPBACK
Specifies that the stack should wait for the local loopback processing before invoking the done notif...
Definition If.hxx:159
Node * dstNode
If the destination node is local, this value is non-NULL.
Definition If.hxx:110
Container of both a NodeID and NodeAlias.