OpenLcbCLib 1.0 Alpha
OpenSource C Library to create OpenLcb/Lcc Nodes
Loading...
Searching...
No Matches
can_main_statemachine.h File Reference

Main CAN layer state machine — orchestrates alias management, login, and message dispatch. More...

Go to the source code of this file.

Data Structures

struct  interface_can_main_statemachine_t
 Dependency-injection interface for the CAN main state machine. More...
 

Functions

void CanMainStatemachine_initialize (const interface_can_main_statemachine_t *interface_can_main_statemachine)
 Registers the dependency-injection interface and prepares internal buffers.
 
void CanMainStateMachine_run (void)
 Executes one iteration of the main CAN state machine.
 
can_statemachine_info_tCanMainStateMachine_get_can_statemachine_info (void)
 Returns a pointer to the internal state machine context.
 
bool CanMainStatemachine_handle_duplicate_aliases (void)
 Scans the alias table, unregisters duplicates, and resets affected nodes.
 
bool CanMainStatemachine_handle_login_outgoing_can_message (void)
 Attempts to transmit the pending login frame (CID, RID, or AMD).
 
bool CanMainStatemachine_handle_outgoing_can_message (void)
 Pops one message from the outgoing CAN FIFO and attempts transmission.
 
bool CanMainStatemachine_handle_try_enumerate_first_node (void)
 Gets the first node and processes it through its appropriate state machine.
 
bool CanMainStatemachine_handle_try_enumerate_next_node (void)
 Continues enumeration and processes the next node.
 
bool CanMainStatemachine_handle_listener_verification (void)
 Probes one listener alias for staleness and queues an AME if due.
 

Detailed Description

Main CAN layer state machine — orchestrates alias management, login, and message dispatch.

Coordinates duplicate alias detection, outgoing message transmission, login sequencing, and round-robin node enumeration across all virtual nodes. Non-blocking: call CanMainStateMachine_run() as fast as possible in the main loop.

Author
Jim Kueneman
Date
8 Mar 2026

Function Documentation

◆ CanMainStatemachine_initialize()

void CanMainStatemachine_initialize ( const interface_can_main_statemachine_t * interface_can_main_statemachine)
extern

Registers the dependency-injection interface and prepares internal buffers.

Must be called once at startup, after CanBufferStore_initialize(), CanBufferFifo_initialize(), and CanLoginStateMachine_initialize(), and before CAN reception begins.

Parameters
interface_can_main_statemachinePointer to a fully populated interface_can_main_statemachine_t. Must remain valid for the lifetime of the application. All pointers must be non-NULL.
Warning
NOT thread-safe - call during single-threaded initialization only.
See also
CanMainStateMachine_run

Registers the dependency-injection interface and prepares internal buffers.

Stores the interface pointer, clears the static login frame buffer, links it to the state machine context, and zeroes all context flags.

* @param interface_can_main_statemachine Pointer to the populated dependency interface.
* 
Warning
Must be called once at startup after CanBufferStore_initialize().

◆ CanMainStateMachine_run()

void CanMainStateMachine_run ( void )
extern

Executes one iteration of the main CAN state machine.

Non-blocking. Processes one operation per call and returns immediately. Call as fast as possible in the main loop.

Warning
Must be called frequently to keep CAN traffic flowing.
NOT thread-safe - call from a single context only.
See also
CanMainStatemachine_initialize - must be called first

Executes one iteration of the main CAN state machine.

Calls each handler in priority order, returning after the first one that does work. Listener verification runs unconditionally before the priority chain. Priority: duplicate aliases -> outgoing CAN frame -> login frame -> enumerate first node -> enumerate next node.

◆ CanMainStateMachine_get_can_statemachine_info()

can_statemachine_info_t * CanMainStateMachine_get_can_statemachine_info ( void )
extern

Returns a pointer to the internal state machine context.

Intended for unit testing and debugging only.

Returns
Pointer to the internal can_statemachine_info_t (never NULL after initialize).
Warning
Do not modify the returned structure.
NOT thread-safe.

Returns a pointer to the internal state machine context.

◆ CanMainStatemachine_handle_duplicate_aliases()

bool CanMainStatemachine_handle_duplicate_aliases ( void )
extern

Scans the alias table, unregisters duplicates, and resets affected nodes.

Exposed for unit testing. Normally called via the interface pointer.

Returns
true if any duplicate aliases were found and resolved, false if none.
Warning
Locks shared resources during operation.
NOT thread-safe.

Scans the alias table, unregisters duplicates, and resets affected nodes.

Locks shared resources, reads the flag, calls _process_duplicate_aliases() if needed, then unlocks.

Returns
true if duplicates were found and processed, false if none.

◆ CanMainStatemachine_handle_login_outgoing_can_message()

bool CanMainStatemachine_handle_login_outgoing_can_message ( void )
extern

Attempts to transmit the pending login frame (CID, RID, or AMD).

Exposed for unit testing. Normally called via the interface pointer.

Returns
true if a login frame was pending (sent or not), false if nothing pending.
Warning
NOT thread-safe.

Attempts to transmit the pending login frame (CID, RID, or AMD).

Clears login_outgoing_can_msg_valid only after successful transmission. Returns true if a login frame was pending (sent or retried), false if none.

◆ CanMainStatemachine_handle_outgoing_can_message()

bool CanMainStatemachine_handle_outgoing_can_message ( void )
extern

Pops one message from the outgoing CAN FIFO and attempts transmission.

Exposed for unit testing. Normally called via the interface pointer. Frees the buffer only on successful transmission; retries on the next call otherwise.

Returns
true if a message was in the FIFO (sent or not), false if FIFO empty.
Warning
Locks shared resources during FIFO access.
NOT thread-safe.

Pops one message from the outgoing CAN FIFO and attempts transmission.

Algorithm:

  1. If no frame is held in the working slot, pop one from the FIFO (under lock).
  2. If a frame is held, try to send it; free it (under lock) only on success.
  3. Return true if a frame was pending (sent or not), false if FIFO was empty.
Returns
true if a frame was pending, false if the FIFO was empty.
Note
The frame is retried on the next call if the hardware buffer was busy.

◆ CanMainStatemachine_handle_try_enumerate_first_node()

bool CanMainStatemachine_handle_try_enumerate_first_node ( void )
extern

Gets the first node and processes it through its appropriate state machine.

Exposed for unit testing. Normally called via the interface pointer.

Returns
true if the first node was found (or no nodes exist), false if already enumerating.
Warning
NOT thread-safe.

Gets the first node and processes it through its appropriate state machine.

Returns false if enumeration is already active (node pointer non-NULL). Otherwise fetches the first node, runs its login state machine if still logging in, and returns true.

Returns
true if enumeration was started (or no nodes exist), false if already active.

◆ CanMainStatemachine_handle_try_enumerate_next_node()

bool CanMainStatemachine_handle_try_enumerate_next_node ( void )
extern

Continues enumeration and processes the next node.

Exposed for unit testing. Normally called via the interface pointer.

Returns
true if no more nodes remain (enumeration complete), false if more nodes exist.
Warning
NOT thread-safe.

Continues enumeration and processes the next node.

Fetches the next node and runs its login state machine if still logging in. Returns true when there are no more nodes (enumeration complete), false otherwise.

Returns
true when all nodes have been processed, false if more nodes remain.

◆ CanMainStatemachine_handle_listener_verification()

bool CanMainStatemachine_handle_listener_verification ( void )
extern

Probes one listener alias for staleness and queues an AME if due.

Exposed for unit testing. Normally called via the interface pointer.

Returns
true if a probe AME was queued, false if nothing to do.
Warning
Locks shared resources during CAN buffer allocation and FIFO push.
NOT thread-safe.

Algorithm:

  1. Call ListenerAliasTable_check_one_verification() with current tick
  2. If non-zero node_id returned: get first node's alias, allocate a CAN buffer (with lock/unlock), build targeted AME, push to CAN FIFO (with lock/unlock)
  3. Return true if an AME was queued, false otherwise
Returns
true if a probe AME was queued, false if nothing to do.

Copyright (c) 2026 Jim Kueneman all rights reserved. See the License