SOLA
Loading...
Searching...
No Matches
fsm.h
1// Copyright The SOLA Contributors
2//
3// Licensed under the MIT License.
4// For details on the licensing terms, see the LICENSE file.
5// SPDX-License-Identifier: MIT
6
7#ifndef MINHTON_UTILS_FSM_H_
8#define MINHTON_UTILS_FSM_H_
9
10#include "fsmlite/fsm.h"
11#include "minhton/core/constants.h"
12#include "minhton/core/node_info.h"
13#include "minhton/message/types.h"
14
15namespace minhton {
16
18 minhton::MessageType msg_type{MessageType::kInit};
19 bool does_not_need_replacement = false;
20};
21
23 minhton::MessageType msg_type{MessageType::kInit};
24};
25
26struct Signal {
27 minhton::SignalType signal_type;
28 bool can_leave_position = false;
29 bool join_via_bootstrap = false;
30 std::string join_address;
31 uint16_t join_port = 0;
32 NodeInfo join_nodeinfo = NodeInfo();
33
34 static Signal joinNetworkViaNodeInfo(const NodeInfo &ni) {
35 return Signal{SignalType::kJoinNetwork, false, false, ni.getAddress(), ni.getPort(), ni};
36 }
37 static Signal joinNetworkViaAddress(std::string addr, uint16_t port) {
38 return Signal{SignalType::kJoinNetwork, false, false, addr, port};
39 }
40 static Signal joinNetworkViaBootstrap(std::string addr, uint16_t port) {
41 return Signal{SignalType::kJoinNetwork, false, true, addr, port};
42 }
43 static Signal joinNetworkViaBootstrap() {
44 return Signal{SignalType::kJoinNetwork, false, true, ""};
45 }
46 static Signal leaveNetwork() { return Signal{SignalType::kLeaveNetwork, false, false, ""}; }
47};
48
49struct Timeout {
50 minhton::TimeoutType timeout_type;
51 bool valid_bootstrap_response = false;
52};
53
54class FiniteStateMachine : public fsmlite::fsm<FiniteStateMachine> {
55 friend class fsm; // base class needs access to transition_table
56
57public:
58 using event = int;
59
60 explicit FiniteStateMachine(state_type init_state = kIdle) : fsm(init_state) {}
61
62 bool isActionValid() {
63 if (this->valid_action_) {
64 this->valid_action_ = false;
65 return true;
66 }
67 return false;
68 }
69
70 static std::string getStateString(FSMState state);
71
72private:
73 // actions
74 void validAction([[maybe_unused]] const Signal &event) { this->valid_action_ = true; }
75 void validAction([[maybe_unused]] const Timeout &event) { this->valid_action_ = true; }
76 void validAction([[maybe_unused]] const ReceiveMessage &event) { this->valid_action_ = true; }
77 void validAction([[maybe_unused]] const SendMessage &event) { this->valid_action_ = true; }
78
79 // guards
80 bool joinNetworkSignalUsingBootstrap(const Signal &event) const;
81 bool joinNetworkSignalUsingAddress(const Signal &event) const;
82 bool leaveNetworkSignalCanLeavePosition(const Signal &event) const;
83 bool leaveNetworkSignalCannotLeavePosition(const Signal &event) const;
84
85 bool bootstrapResponseTimeoutInvalid(const Timeout &event) const;
86 bool bootstrapResponseTimeoutValid(const Timeout &event) const;
87 bool joinResponseTimeout(const Timeout &event) const;
88 bool joinAcceptAckResponseTimeout(const Timeout &event) const;
89 bool replacementAckResponseTimeout(const Timeout &event) const;
90 bool replacementOfferResponseTimeout(const Timeout &event) const;
91 bool timeoutNonCriticalMsgInConnectedState(const Timeout &event) const;
92
93 bool recvJoinAcceptMessage(const ReceiveMessage &event) const;
94 bool recvJoinAcceptAckMessage(const ReceiveMessage &event) const;
95 bool recvReplacementAckMessage(const ReceiveMessage &event) const;
96 bool recvReplacementOfferMessage(const ReceiveMessage &event) const;
97 bool recvBootstrapDiscoverMessage(const ReceiveMessage &event) const;
98 bool recvBootstrapResponseMessage(const ReceiveMessage &event) const;
99 bool recvNonCriticalMsgInConnectedState(const ReceiveMessage &event) const;
100 bool recvFindReplacementAtNodeToReplace(const ReceiveMessage &event) const;
101 bool recvFindReplacementNack(const ReceiveMessage &event) const;
102 bool recvFindReplacement(const ReceiveMessage &event) const;
103 bool recvParentResponseAck(const ReceiveMessage &event) const;
104
105 bool sendJoinMessage(const SendMessage &event) const;
106 bool sendJoinAcceptMessage(const SendMessage &event) const;
107 bool sendJoinAcceptAckMessage(const SendMessage &event) const;
108 bool sendReplacementOfferMessage(const SendMessage &event) const;
109 bool sendReplacementOfferNackMessage(const SendMessage &event) const;
110 bool sendParentResponseMessage(const SendMessage &event) const;
111 bool sendReplacementAckMessage(const SendMessage &event) const;
112 bool sendBootstrapDiscoverMessage(const SendMessage &event) const;
113 bool sendBootstrapResponseMessage(const SendMessage &event) const;
114 bool sendNonCriticalMsgInConnectedState(const SendMessage &event) const;
115 bool sendLeaveRelatedMsgInIdleState(const SendMessage &event) const;
116 bool sendRemoveNeighborMessage(const SendMessage &event) const;
117 bool sendRemoveAndUpdateNeighbor(const SendMessage &event) const;
118 bool sendUpdateNeighborsMessage(const SendMessage &event) const;
119
120 bool valid_action_ = false;
121
122 using m = FiniteStateMachine;
123
124 using transition_table = table<
125 // Start-State - Event - Target-State - Action - Guard
126
127 // workflow transitions
128 mem_fn_row<kIdle, Signal, kWaitForBootstrapResponse, &m::validAction,
129 &m::joinNetworkSignalUsingBootstrap>,
130 mem_fn_row<kIdle, Signal, kWaitForJoinAccept, &m::validAction,
131 &m::joinNetworkSignalUsingAddress>,
132 mem_fn_row<kJoinFailed, Signal, kWaitForJoinAccept, &m::validAction,
133 &m::joinNetworkSignalUsingAddress>,
134 mem_fn_row<kWaitForBootstrapResponse, Timeout, kErrorState, &m::validAction,
135 &m::bootstrapResponseTimeoutInvalid>,
136 mem_fn_row<kWaitForBootstrapResponse, Timeout, kWaitForJoinAccept, &m::validAction,
137 &m::bootstrapResponseTimeoutValid>,
138 mem_fn_row<kWaitForJoinAccept, Timeout, kJoinFailed, &m::validAction,
139 &m::joinResponseTimeout>,
140 mem_fn_row<kWaitForJoinAccept, ReceiveMessage, kConnected, &m::validAction,
141 &m::recvJoinAcceptMessage>,
142 mem_fn_row<kConnected, SendMessage, kConnectedAcceptingChild, &m::validAction,
143 &m::sendJoinAcceptMessage>,
144 mem_fn_row<kConnectedAcceptingChild, ReceiveMessage, kConnected, &m::validAction,
145 &m::recvJoinAcceptAckMessage>,
146 mem_fn_row<kConnectedAcceptingChild, Timeout, kConnected, &m::validAction,
147 &m::joinAcceptAckResponseTimeout>,
148 mem_fn_row<kConnected, SendMessage, kConnectedWaitingParentResponse, &m::validAction,
149 &m::sendParentResponseMessage>,
150 mem_fn_row<kConnectedWaitingParentResponse, SendMessage, kConnectedWaitingParentResponse,
151 &m::validAction, &m::sendReplacementOfferNackMessage>,
152 mem_fn_row<kConnectedWaitingParentResponse, ReceiveMessage, kSignOffFromInlevelNeighbors,
153 &m::validAction, &m::recvParentResponseAck>,
154 mem_fn_row<kConnectedWaitingParentResponseDirectLeaveWoReplacement, ReceiveMessage,
155 kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, &m::validAction,
156 &m::recvParentResponseAck>,
157 mem_fn_row<kSignOffFromInlevelNeighbors, SendMessage, kConnectedReplacing, &m::validAction,
158 &m::sendReplacementOfferMessage>,
159 mem_fn_row<kSignOffFromInlevelNeighbors, SendMessage, kSignOffFromInlevelNeighbors,
160 &m::validAction, &m::sendRemoveNeighborMessage>,
161 mem_fn_row<kSignOffFromInlevelNeighbors, SendMessage, kSignOffFromInlevelNeighbors,
162 &m::validAction, &m::sendUpdateNeighborsMessage>,
163 mem_fn_row<kSignOffFromInlevelNeighbors, SendMessage, kSignOffFromInlevelNeighbors,
164 &m::validAction, &m::sendRemoveAndUpdateNeighbor>,
165 mem_fn_row<kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, SendMessage,
166 kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, &m::validAction,
167 &m::sendRemoveNeighborMessage>,
168 mem_fn_row<kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, SendMessage,
169 kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, &m::validAction,
170 &m::sendUpdateNeighborsMessage>,
171 mem_fn_row<kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, SendMessage,
172 kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, &m::validAction,
173 &m::sendRemoveAndUpdateNeighbor>,
174 mem_fn_row<kConnectedReplacing, ReceiveMessage, kConnected, &m::validAction,
175 &m::recvReplacementAckMessage>,
176 mem_fn_row<kConnectedReplacing, Timeout, kConnected, &m::validAction,
177 &m::replacementAckResponseTimeout>,
178 mem_fn_row<kConnected, Signal, kConnectedWaitingParentResponseDirectLeaveWoReplacement,
179 &m::validAction, &m::leaveNetworkSignalCanLeavePosition>,
180 mem_fn_row<kConnected, Signal, kWaitForReplacementOffer, &m::validAction,
181 &m::leaveNetworkSignalCannotLeavePosition>,
182 mem_fn_row<kWaitForReplacementOffer, Timeout, kConnected, &m::validAction,
183 &m::replacementOfferResponseTimeout>,
184 mem_fn_row<kWaitForReplacementOffer, ReceiveMessage, kIdle, &m::validAction,
185 &m::recvReplacementOfferMessage>,
186 mem_fn_row<kConnected, SendMessage, kConnected, &m::validAction,
187 &m::sendJoinAcceptAckMessage>,
188
189 // transitions needed for the workflow
190 mem_fn_row<kWaitForJoinAccept, SendMessage, kWaitForJoinAccept, &m::validAction,
191 &m::sendJoinMessage>,
192 mem_fn_row<kWaitForBootstrapResponse, SendMessage, kWaitForBootstrapResponse, &m::validAction,
193 &m::sendBootstrapDiscoverMessage>,
194 mem_fn_row<kWaitForBootstrapResponse, ReceiveMessage, kWaitForBootstrapResponse,
195 &m::validAction, &m::recvBootstrapResponseMessage>,
196 mem_fn_row<kIdle, SendMessage, kIdle, &m::validAction, &m::sendLeaveRelatedMsgInIdleState>,
197
198 // non-critical connected recv transitions
199 mem_fn_row<kConnected, ReceiveMessage, kConnected, &m::validAction,
200 &m::recvNonCriticalMsgInConnectedState>,
201 mem_fn_row<kConnectedAcceptingChild, ReceiveMessage, kConnectedAcceptingChild,
202 &m::validAction, &m::recvNonCriticalMsgInConnectedState>,
203 mem_fn_row<kConnectedReplacing, ReceiveMessage, kConnectedReplacing, &m::validAction,
204 &m::recvNonCriticalMsgInConnectedState>,
205 mem_fn_row<kWaitForReplacementOffer, ReceiveMessage,
206 kConnectedWaitingParentResponseDirectLeaveWoReplacement, &m::validAction,
207 &m::recvFindReplacementAtNodeToReplace>,
208 mem_fn_row<kWaitForReplacementOffer, ReceiveMessage, kWaitForReplacementOffer,
209 &m::validAction, &m::recvNonCriticalMsgInConnectedState>,
210 mem_fn_row<kConnectedWaitingParentResponse, ReceiveMessage, kConnectedWaitingParentResponse,
211 &m::validAction, &m::recvNonCriticalMsgInConnectedState>,
212 mem_fn_row<kSignOffFromInlevelNeighbors, ReceiveMessage, kSignOffFromInlevelNeighbors,
213 &m::validAction, &m::recvNonCriticalMsgInConnectedState>,
214 mem_fn_row<kConnectedWaitingParentResponseDirectLeaveWoReplacement, ReceiveMessage,
215 kConnectedWaitingParentResponseDirectLeaveWoReplacement, &m::validAction,
216 &m::recvNonCriticalMsgInConnectedState>,
217 mem_fn_row<kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, ReceiveMessage,
218 kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, &m::validAction,
219 &m::recvNonCriticalMsgInConnectedState>,
220 mem_fn_row<kWaitForReplacementOffer, ReceiveMessage, kConnected, &m::validAction,
221 &m::recvFindReplacementNack>,
222
223 // non-critical connected send transitions
224 mem_fn_row<kConnected, SendMessage, kConnected, &m::validAction,
225 &m::sendNonCriticalMsgInConnectedState>,
226 mem_fn_row<kConnectedAcceptingChild, SendMessage, kConnectedAcceptingChild, &m::validAction,
227 &m::sendNonCriticalMsgInConnectedState>,
228 mem_fn_row<kConnectedReplacing, SendMessage, kConnectedReplacing, &m::validAction,
229 &m::sendNonCriticalMsgInConnectedState>,
230 mem_fn_row<kWaitForReplacementOffer, SendMessage, kWaitForReplacementOffer, &m::validAction,
231 &m::sendNonCriticalMsgInConnectedState>,
232
233 // TODO: ONLY FOR FORWARDING. NOT INITIATE-SELF-DEPARTURE
234 mem_fn_row<kConnectedWaitingParentResponse, SendMessage, kConnectedWaitingParentResponse,
235 &m::validAction, &m::sendNonCriticalMsgInConnectedState>,
236 mem_fn_row<kSignOffFromInlevelNeighbors, SendMessage, kSignOffFromInlevelNeighbors,
237 &m::validAction, &m::sendNonCriticalMsgInConnectedState>,
238 mem_fn_row<kConnectedWaitingParentResponseDirectLeaveWoReplacement, SendMessage,
239 kConnectedWaitingParentResponseDirectLeaveWoReplacement, &m::validAction,
240 &m::sendNonCriticalMsgInConnectedState>,
241 mem_fn_row<kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, SendMessage,
242 kSignOffFromInlevelNeighborsDirectLeaveWoReplacement, &m::validAction,
243 &m::sendNonCriticalMsgInConnectedState>,
244
245 // non-critical connected timeout transitions
246 mem_fn_row<kConnected, Timeout, kConnected, &m::validAction,
247 &m::timeoutNonCriticalMsgInConnectedState>,
248 mem_fn_row<kConnectedAcceptingChild, Timeout, kConnectedAcceptingChild, &m::validAction,
249 &m::timeoutNonCriticalMsgInConnectedState>,
250 mem_fn_row<kConnectedReplacing, Timeout, kConnectedReplacing, &m::validAction,
251 &m::timeoutNonCriticalMsgInConnectedState>,
252 mem_fn_row<kWaitForReplacementOffer, Timeout, kWaitForReplacementOffer, &m::validAction,
253 &m::timeoutNonCriticalMsgInConnectedState>,
254
255 // bootstrap discover must be allowed to be received in any state
256 // but only answered in connected
257 mem_fn_row<kConnected, SendMessage, kConnected, &m::validAction,
258 &m::sendBootstrapResponseMessage>,
259
260 mem_fn_row<kIdle, ReceiveMessage, kIdle, &m::validAction, &m::recvBootstrapDiscoverMessage>,
261 mem_fn_row<kIdle, ReceiveMessage, kIdle, &m::validAction, &m::recvFindReplacement>,
262 mem_fn_row<kWaitForBootstrapResponse, ReceiveMessage, kWaitForBootstrapResponse,
263 &m::validAction, &m::recvBootstrapDiscoverMessage>,
264 mem_fn_row<kWaitForJoinAccept, ReceiveMessage, kWaitForJoinAccept, &m::validAction,
265 &m::recvBootstrapDiscoverMessage>,
266 mem_fn_row<kConnected, ReceiveMessage, kConnected, &m::validAction,
267 &m::recvBootstrapDiscoverMessage>,
268 mem_fn_row<kConnectedAcceptingChild, ReceiveMessage, kConnectedAcceptingChild,
269 &m::validAction, &m::recvBootstrapDiscoverMessage>,
270 mem_fn_row<kConnectedReplacing, ReceiveMessage, kConnectedReplacing, &m::validAction,
271 &m::recvBootstrapDiscoverMessage>,
272 mem_fn_row<kWaitForReplacementOffer, ReceiveMessage, kWaitForReplacementOffer,
273 &m::validAction, &m::recvBootstrapDiscoverMessage>,
274 mem_fn_row<kErrorState, ReceiveMessage, kErrorState, &m::validAction,
275 &m::recvBootstrapDiscoverMessage>,
276
277 // multicast is unreliable, therefore we could also receive
278 // unwanted bootstrap response messages in any state
279 mem_fn_row<kIdle, ReceiveMessage, kIdle, &m::validAction, &m::recvBootstrapResponseMessage>,
280 mem_fn_row<kWaitForBootstrapResponse, ReceiveMessage, kWaitForBootstrapResponse,
281 &m::validAction, &m::recvBootstrapResponseMessage>,
282 mem_fn_row<kWaitForJoinAccept, ReceiveMessage, kWaitForJoinAccept, &m::validAction,
283 &m::recvBootstrapResponseMessage>,
284 mem_fn_row<kConnected, ReceiveMessage, kConnected, &m::validAction,
285 &m::recvBootstrapResponseMessage>,
286 mem_fn_row<kConnectedAcceptingChild, ReceiveMessage, kConnectedAcceptingChild,
287 &m::validAction, &m::recvBootstrapResponseMessage>,
288 mem_fn_row<kConnectedReplacing, ReceiveMessage, kConnectedReplacing, &m::validAction,
289 &m::recvBootstrapResponseMessage>,
290 mem_fn_row<kWaitForReplacementOffer, ReceiveMessage, kWaitForReplacementOffer,
291 &m::validAction, &m::recvBootstrapResponseMessage>,
292 mem_fn_row<kErrorState, ReceiveMessage, kErrorState, &m::validAction,
293 &m::recvBootstrapResponseMessage>
294
295 >;
296};
297
298} // namespace minhton
299
300#endif
Definition fsm.h:54
Definition node_info.h:24
uint16_t getPort() const
Definition node_info.cpp:59
std::string getAddress() const
Definition node_info.cpp:61
Definition minhton_watchdog_ns3.cpp:24
MessageType
Definition types.h:17
Definition fsm.h:17
Definition fsm.h:22
Definition fsm.h:26
Definition fsm.h:49