Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
AliasAllocator.hxx
Go to the documentation of this file.
1
35#ifndef _OPENLCB_ALIASALLOCATOR_HXX_
36#define _OPENLCB_ALIASALLOCATOR_HXX_
37
38#include "openlcb/IfCan.hxx"
39#include "openlcb/Defs.hxx"
41
42namespace openlcb
43{
44
47extern size_t g_alias_test_conflicts;
48
51{
52 AliasInfo()
53 : alias(0)
54 , state(STATE_EMPTY)
55 , return_to_reallocation(1)
56 {
57 }
58
59 void reset()
60 {
61 alias = 0;
62 state = STATE_EMPTY;
63 return_to_reallocation = 1;
64 }
65
66 void do_not_reallocate()
67 {
68 return_to_reallocation = 0;
69 }
70
72 uint16_t alias : 12;
73 uint16_t state : 3;
74 uint16_t return_to_reallocation : 1;
75
76 enum State
77 {
78 STATE_EMPTY = 0,
79 STATE_CHECKING,
80 STATE_RESERVED,
81 STATE_ASSIGNED,
82 STATE_CONFLICT
83 };
84};
85
95class AliasAllocator : public StateFlow<Buffer<AliasInfo>, QList<1>>
96{
97public:
110
112 virtual ~AliasAllocator();
113
116 {
117 return if_id_;
118 }
119
123 void reinit_seed();
124
128
141 NodeAlias get_allocated_alias(NodeID destination_id, Executable *done);
142
145 unsigned num_reserved_aliases();
146
149
152 void return_alias(NodeID id, NodeAlias alias);
153
159 void add_allocated_alias(NodeAlias alias);
160
161#ifdef GTEST
164 void TEST_finish_pending_allocation();
165
169 void TEST_add_allocated_alias(NodeAlias alias);
170
172 void TEST_set_reserve_unused_alias_count(unsigned count)
173 {
174 reserveUnusedAliases_ = count;
175 }
176#endif
177
178private:
181 {
182 public:
183 ConflictHandler(AliasAllocator *parent) : parent_(parent)
184 {
185 }
186 void send(Buffer<CanMessageData> *message, unsigned priority) override;
187
188 private:
189 AliasAllocator *parent_;
190 } conflictHandler_;
191
192 friend class ConflictHandler;
193
194 AliasInfo *pending_alias()
195 {
196 return message()->data();
197 }
198
199 Action entry() override;
200 Action handle_allocate_for_cid_frame();
201 Action send_cid_frame();
202 Action wait_done();
203 Action send_rid_frame();
204
205 Action handle_alias_conflict();
206
208 void next_seed();
209
210 friend class AsyncAliasAllocatorTest;
211 friend class AsyncIfTest;
212
213 StateFlowTimer timer_;
214
217
220
224 {
225 return static_cast<IfCan *>(service());
226 }
227
231 unsigned conflict_detected_ : 1;
232
234 unsigned seed_ : 12;
235
239
242
244 // SleepData sleep_helper_;
245};
246
250{
251public:
252 AddAliasAllocator(NodeID if_id, IfCan *iface)
253 {
254 iface->set_alias_allocator(new AliasAllocator(if_id, iface));
255 }
256};
257
258} // namespace openlcb
259
260
261#endif // _OPENLCB_ALIASALLOCATOR_HXX_
A BarrierNotifiable allows to create a number of child Notifiable and wait for all of them to finish.
Base class for all QMember types that hold data in an expandable format.
Definition Buffer.hxx:195
An object that can be scheduled on an executor to run.
This class implements a linked list "queue" of buffers.
Definition Queue.hxx:98
State flow with a given typed input queue.
Base::Action Action
Allows using Action without having StateFlowBase:: prefix in front of it.
MessageType * message()
Create this object statically to add an alias allocator to an already statically allocated interface.
Listens to incoming CAN frames and handles alias conflicts.
void send(Buffer< CanMessageData > *message, unsigned priority) override
Entry point to the flow.
This state flow is responsible for reserving node ID aliases.
unsigned cid_frame_sequence_
Which CID frame are we trying to send out. Valid values: 7..4.
NodeID if_id_
48-bit nodeID that we will use for alias reservations.
void clear_reserved_aliases()
Removes all aliases that are reserved but not yet used.
unsigned conflict_detected_
Set to 1 if an incoming frame signals an alias conflict.
Q waitingClients_
Set of client flows that are waiting for allocating an alias.
unsigned reserveUnusedAliases_
How many unused aliases we should reserve.
void return_alias(NodeID id, NodeAlias alias)
Releases a given alias.
BarrierNotifiable n_
Notifiable used for tracking outgoing frames.
void add_allocated_alias(NodeAlias alias)
Call from an alternate alias allocator.
NodeAlias get_new_seed()
Returns a new alias to check from the random sequence.
IfCan * if_can()
Physical interface for sending packets and assigning handlers to received packets.
unsigned seed_
Seed for generating random-looking alias numbers.
void reinit_seed()
Resets the alias allocator to the state it was at construction.
Action entry() override
Entry into the StateFlow activity.
NodeAlias get_allocated_alias(NodeID destination_id, Executable *done)
Allocates an alias from the reserved but unused aliases list.
void next_seed()
Generates the next alias to check in the seed_ variable.
virtual ~AliasAllocator()
Destructor.
Test fixture base class with helper methods for exercising the asynchronous interface code.
Implementation of the OpenLCB interface abstraction for the CAN-bus interface standard.
Definition IfCan.hxx:65
void set_alias_allocator(AliasAllocator *a)
Sets the alias allocator for this If. Takes ownership of pointer.
Definition IfCan.cxx:751
size_t g_alias_test_conflicts
Counts the number of aliases that were given up because a conflict has arisen during the allocation.
uint64_t NodeID
48-bit NMRAnet Node ID type
uint16_t NodeAlias
Alias to a 48-bit NMRAnet Node ID type.
Information we know locally about an NMRAnet CAN alias.
uint16_t alias
The current alias.