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

Central MTI-based message dispatcher. More...

Go to the source code of this file.

Data Structures

struct  interface_openlcb_main_statemachine_t
 Dependency-injection interface for the main state machine. Required pointers must be non-NULL; optional ones may be NULL (causes automatic Interaction Rejected). Internal pointers are exposed for unit testing. More...
 

Functions

void OpenLcbMainStatemachine_initialize (const interface_openlcb_main_statemachine_t *interface_openlcb_main_statemachine)
 Stores the callback interface and prepares internal state.
 
void OpenLcbMainStatemachine_run (void)
 Runs one non-blocking step of protocol processing.
 
void OpenLcbMainStatemachine_load_interaction_rejected (openlcb_statemachine_info_t *statemachine_info)
 Builds an Interaction Rejected response for the current incoming message. Internal use.
 
bool OpenLcbMainStatemachine_handle_outgoing_openlcb_message (void)
 Tries to send the pending message. Returns true if one was pending.
 
bool OpenLcbMainStatemachine_handle_try_reenumerate (void)
 Re-enters the state processor if the enumerate flag is set.
 
bool OpenLcbMainStatemachine_handle_try_pop_next_incoming_openlcb_message (void)
 Pops the next message from the FIFO (thread-safe). Returns true if popped.
 
bool OpenLcbMainStatemachine_handle_try_enumerate_first_node (void)
 Starts node enumeration from the first node. Returns true if processed.
 
bool OpenLcbMainStatemachine_handle_try_enumerate_next_node (void)
 Advances to the next node; frees message at end. Returns true if processed.
 
void OpenLcbMainStatemachine_process_main_statemachine (openlcb_statemachine_info_t *statemachine_info)
 MTI dispatcher. Routes incoming message to the correct handler.
 
bool OpenLcbMainStatemachine_does_node_process_msg (openlcb_statemachine_info_t *statemachine_info)
 Address filter. Returns true if the node should process this message.
 
openlcb_statemachine_info_tOpenLcbMainStatemachine_get_statemachine_info (void)
 Returns pointer to internal static state machine info. For unit testing only — do not modify.
 

Detailed Description

Central MTI-based message dispatcher.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Pops messages from the FIFO, enumerates all nodes, and routes to the correct protocol handler via function pointers. NULL optional handlers trigger Interaction Rejected automatically. Required handlers include message network, protocol support, and resource locking; optional handlers cover SNIP, events, trains, datagrams, and streams.

Author
Jim Kueneman
Date
4 Mar 2026

Function Documentation

◆ OpenLcbMainStatemachine_initialize()

void OpenLcbMainStatemachine_initialize ( const interface_openlcb_main_statemachine_t * interface_openlcb_main_statemachine)
extern

Stores the callback interface and prepares internal state.

Call once at startup after buffer/FIFO initialization and before OpenLcbMainStatemachine_run().

Parameters
interface_openlcb_main_statemachinePointer to interface_openlcb_main_statemachine_t. Must remain valid for application lifetime.

Stores the callback interface and prepares internal state.

Algorithm:

  1. Store interface pointer
  2. Link outgoing message buffer pointers, set payload type to STREAM
  3. Clear message and payload, mark buffer as allocated
  4. Set incoming message to NULL, clear enumerate flag, set node to NULL
* @param interface_openlcb_main_statemachine Pointer to populated interface structure
* 

◆ OpenLcbMainStatemachine_run()

void OpenLcbMainStatemachine_run ( void )
extern

Runs one non-blocking step of protocol processing.

Priority order: send pending → re-enumerate → pop FIFO → enumerate nodes. Call as fast as possible from your main loop.

Runs one non-blocking step of protocol processing.

Algorithm:

  1. Send pending outgoing message (highest priority), return if busy
  2. Handle multi-message re-enumeration, return if active
  3. Pop next incoming message from FIFO, return if attempted
  4. Enumerate first node for the message, return if acted
  5. Enumerate next node, return if acted

◆ OpenLcbMainStatemachine_load_interaction_rejected()

void OpenLcbMainStatemachine_load_interaction_rejected ( openlcb_statemachine_info_t * statemachine_info)
extern

Builds an Interaction Rejected response for the current incoming message. Internal use.

Parameters
statemachine_infoPointer to openlcb_statemachine_info_t context.

Builds an Interaction Rejected response for the current incoming message. Internal use.

Algorithm:

  1. Validate all required pointers (return early if NULL)
  2. Load OIR message with error code and triggering MTI in payload
  3. Set valid flag for transmission
* @param statemachine_info Pointer to state machine context
* 

◆ OpenLcbMainStatemachine_handle_outgoing_openlcb_message()

bool OpenLcbMainStatemachine_handle_outgoing_openlcb_message ( void )
extern

Tries to send the pending message. Returns true if one was pending.

Tries to send the pending message. Returns true if one was pending.

Algorithm:

  1. If outgoing valid flag is set, call send_openlcb_msg callback
  2. On success clear the valid flag
  3. Return true if a message was pending, false if idle
Returns
true if message pending (caller should retry), false if nothing to send

◆ OpenLcbMainStatemachine_handle_try_reenumerate()

bool OpenLcbMainStatemachine_handle_try_reenumerate ( void )
extern

Re-enters the state processor if the enumerate flag is set.

Re-enters the state processor if the enumerate flag is set.

Algorithm:

  1. If enumerate flag is set, call process_main_statemachine again
  2. Return true while flag remains set, false when enumeration is complete
Returns
true if re-enumeration active, false if complete

◆ OpenLcbMainStatemachine_handle_try_pop_next_incoming_openlcb_message()

bool OpenLcbMainStatemachine_handle_try_pop_next_incoming_openlcb_message ( void )
extern

Pops the next message from the FIFO (thread-safe). Returns true if popped.

Pops the next message from the FIFO (thread-safe). Returns true if popped.

Algorithm:

  1. If already holding a message, return false
  2. Lock shared resources, pop from FIFO, unlock
  3. Return true if pop attempted (even if queue was empty), false if busy
Returns
true if pop attempted, false if still processing previous message

◆ OpenLcbMainStatemachine_handle_try_enumerate_first_node()

bool OpenLcbMainStatemachine_handle_try_enumerate_first_node ( void )
extern

Starts node enumeration from the first node. Returns true if processed.

Starts node enumeration from the first node. Returns true if processed.

Algorithm:

  1. If node pointer already set, return false (already enumerating)
  2. Reset train search match flag for new enumeration
  3. Get first node; if NULL free the message and return true
  4. If node is in RUNSTATE_RUN, dispatch message via process_main_statemachine
  5. Return true
Returns
true if enumeration step taken, false if no action needed

◆ OpenLcbMainStatemachine_handle_try_enumerate_next_node()

bool OpenLcbMainStatemachine_handle_try_enumerate_next_node ( void )
extern

Advances to the next node; frees message at end. Returns true if processed.

Advances to the next node; frees message at end. Returns true if processed.

Algorithm:

  1. If no current node, return false
  2. Get next node; if NULL free the message and return true
  3. If node is in RUNSTATE_RUN, dispatch message via process_main_statemachine
  4. Return true
Returns
true if enumeration active, false if no current node

◆ OpenLcbMainStatemachine_process_main_statemachine()

void OpenLcbMainStatemachine_process_main_statemachine ( openlcb_statemachine_info_t * statemachine_info)
extern

MTI dispatcher. Routes incoming message to the correct handler.

Parameters
statemachine_infoPointer to openlcb_statemachine_info_t context.

MTI dispatcher. Routes incoming message to the correct handler.

Algorithm:

  1. Return early if NULL or does_node_process_msg() is false
  2. Switch on MTI (40 message types: SNIP, Message Network, PIP, Event Transport, Train, Datagram, Stream)
  3. For optional handlers that are NULL: send Interaction Rejected on request MTIs, silently ignore reply/indication MTIs
  4. Default: reject unknown addressed MTIs, ignore unknown global MTIs
* @param statemachine_info Pointer to state machine context with message and node information
* 

◆ OpenLcbMainStatemachine_does_node_process_msg()

bool OpenLcbMainStatemachine_does_node_process_msg ( openlcb_statemachine_info_t * statemachine_info)
extern

Address filter. Returns true if the node should process this message.

Parameters
statemachine_infoPointer to openlcb_statemachine_info_t context.

Address filter. Returns true if the node should process this message.

Algorithm:

  1. Return false if node is NULL or not initialized
  2. Accept global (unaddressed) messages
  3. Accept addressed messages whose dest alias/ID matches this node
  4. Special case: always accept MTI_VERIFY_NODE_ID_GLOBAL
* @param statemachine_info Pointer to state machine context
* 
Returns
true if node should process message, false otherwise

◆ OpenLcbMainStatemachine_get_statemachine_info()

openlcb_statemachine_info_t * OpenLcbMainStatemachine_get_statemachine_info ( void )
extern

Returns pointer to internal static state machine info. For unit testing only — do not modify.

Returns pointer to internal static state machine info. For unit testing only — do not modify.


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