70 unsigned needed = std::min(
request()->numAliases_,
71 (
unsigned)(config_bulk_alias_num_can_frames() + 3) / 4);
77 for (
unsigned i = 0; i < needed; ++i)
121 unsigned num_sent = 0;
124 (num_sent < (
unsigned)(config_bulk_alias_num_can_frames())) &&
132 if (it->hasConflict_)
176 it->hasConflict_ = 1;
283 return std::make_unique<BulkAliasAllocator>(can_if);
BufferPtr< T > get_buffer_deleter(Buffer< T > *b)
Helper function to create a BufferPtr of an appropriate type without having to explicitly specify the...
C++11 version of std::make_unique which is only available from c++14 or later.
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
A BarrierNotifiable allows to create a number of child Notifiable and wait for all of them to finish.
void notify() override
Implementation of the barrier semantics.
BarrierNotifiable * reset(Notifiable *done)
Resets the barrier. Returns &*this. Asserts that is_done().
BarrierNotifiable * new_child()
Call this for each child task.
bool abort_if_almost_done()
Checks if there is exactly one outstanding notification left in the barrier.
Base class for all QMember types that hold data in an expandable format.
Action return_ok()
Terminates the flow and returns the request buffer to the caller with an error code of OK (zero).
BulkAliasRequest * request()
FrameDispatchFlow * frame_dispatcher()
OutgoingFrameHandler * frame_write_flow()
void register_handler(HandlerType *handler, ID id, ID mask)
Adds a new handler to this dispatcher.
void unregister_handler_all(HandlerType *handler)
Removes all instances of a handler from this dispatcher.
virtual void send(MessageType *message, unsigned priority=UINT_MAX)=0
Entry point to the flow.
MessageType * alloc()
Synchronously allocates a message buffer from the pool of this flow.
An mostly std::set<> compatible class that stores the internal data in a sorted vector.
Return type for a state flow callback.
Use this timer class to deliver the timeout notification to a stateflow.
Service * service()
Return a pointer to the service I am bound to.
Action wait()
Wait for an asynchronous call.
Action wait_and_call(Callback c)
Wait for resource to become available before proceeding to next state.
Action sleep_and_call(::Timer *timer, long long timeout_nsec, Callback c)
Suspends execution of this control flow for a specified time.
Action call_immediately(Callback c)
Imediately call the next state upon return.
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.
Implementation of the BulkAliasAllocatorInterface to allocate many aliases at the same time.
SortedListSet< AliasLookupInfo, LookupCompare > pendingAliasesByKey_
Stores the aliases we are trying to allocate in the alias order.
uint16_t nextToStampTime_
Index into the pendingAliasesByTime_ vector where we need to stmap time.
BulkAliasAllocator(IfCan *iface)
Constructor.
void send_can_frame(NodeAlias src, uint16_t control_field, int sequence)
Sends a CAN control frame to the bus.
Action complete()
Called when all RID frames are sent out.
Action send_cid_frames()
Picks a bunch of random aliases, sends CID frames for them to the bus.
Action entry() override
Start of flow when a request arrives to allocate many aliases.
void handle_conflict(Buffer< CanMessageData > *message)
Callback from the stack for all incoming frames while we are operating.
long long startTime_
We measure time elapsed relative to this point.
std::vector< PendingAliasInfo > pendingAliasesByTime_
Stores the aliases we are trying to allocate in time order of picking them.
uint16_t nextToClaim_
Index into the pendingAliasesByTime_ vector where we need to send out the reserve frame.
BarrierNotifiable bn_
Helper object to determine when the CAN frames have flushed from the system.
StateFlowTimer timer_
Helper object for sleeping.
Action stamp_time()
Adds the timestamps when the CID requests were sent out.
IncomingFrameHandler::GenericHandler conflictHandler_
Listens to incoming CAN frames and handles alias conflicts.
Action wait_for_results()
Sends out the RID frames for any alias that the 200 msec has already elapsed, then waits a bit and tr...
static constexpr unsigned ALLOCATE_DELAY
How many count to wait before sending out the RID frames.
Implementation of the OpenLCB interface abstraction for the CAN-bus interface standard.
AliasAllocator * alias_allocator()
std::unique_ptr< BulkAliasAllocatorInterface > create_bulk_alias_allocator(IfCan *can_if)
Creates a bulk alias allocator.
uint16_t NodeAlias
Alias to a 48-bit NMRAnet Node ID type.
long long os_get_time_monotonic(void)
Get the monotonic time since the system started.
#define MSEC_TO_NSEC(_msec)
Convert a millisecond value to a nanosecond value.
We store this type in the sorted map lookup structure.
uint16_t alias_
The value of the alias.
AliasLookupInfo(NodeAlias alias)
Constructor.
uint16_t hasConflict_
1 if we have seen a conflict
Comparator function on AliasLookupInfo objects.
We store this type in the time-ordered aliases structure.
PendingAliasInfo(NodeAlias alias)
Constructor.
unsigned cidTime_
The time when the CID requests were sent.
unsigned alias_
The value of the alias.
Message type to request allocating many aliases for an interface.
static void control_init(struct can_frame &frame, NodeAlias src, uint16_t field, int sequence)
Initialize a control frame CAN ID and set DLC to 0.
@ RID_FRAME
Reserve ID Frame.
static NodeAlias get_src(uint32_t can_id)
Get the source field value of the CAN ID.