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

Datagram protocol handler for reliable 0-72 byte addressed transfers. More...

Go to the source code of this file.

Data Structures

struct  interface_protocol_datagram_handler_t
 Callback interface for the datagram handler. lock/unlock are REQUIRED; all memory-operation pointers are optional (NULL = rejected). More...
 

Typedefs

typedef void(* memory_handler_t) (openlcb_statemachine_info_t *statemachine_info)
 Function pointer type shared by all per-address-space memory handlers.
 

Functions

void ProtocolDatagramHandler_initialize (const interface_protocol_datagram_handler_t *interface_protocol_datagram_handler)
 Stores the callback interface. Call once at startup before any datagram processing.
 
void ProtocolDatagramHandler_load_datagram_received_ok_message (openlcb_statemachine_info_t *statemachine_info, uint16_t reply_pending_time_in_seconds)
 Builds a Datagram Received OK message (MTI 0x0A28).
 
void ProtocolDatagramHandler_load_datagram_rejected_message (openlcb_statemachine_info_t *statemachine_info, uint16_t return_code)
 Builds a Datagram Rejected message (MTI 0x0A48).
 
void ProtocolDatagramHandler_datagram (openlcb_statemachine_info_t *statemachine_info)
 Processes an incoming datagram. Dispatches to the appropriate handler based on the command byte (payload[0]).
 
void ProtocolDatagramHandler_datagram_received_ok (openlcb_statemachine_info_t *statemachine_info)
 Handles an incoming Datagram Received OK reply. Clears the resend flag and frees the stored datagram awaiting acknowledgement.
 
void ProtocolDatagramHandler_datagram_rejected (openlcb_statemachine_info_t *statemachine_info)
 Handles an incoming Datagram Rejected reply. Sets the resend flag for temporary errors; clears retry state for permanent errors.
 
void ProtocolDatagramHandler_clear_resend_datagram_message (openlcb_node_t *openlcb_node)
 Frees any stored datagram and clears the resend flag for the node.
 
void ProtocolDatagramHandler_100ms_timer_tick (uint8_t current_tick)
 Periodic timer tick for datagram timeout tracking.
 
void ProtocolDatagramHandler_check_timeouts (uint8_t current_tick)
 Scans for timed-out or max-retried pending datagrams and frees them.
 

Detailed Description

Datagram protocol handler for reliable 0-72 byte addressed transfers.

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.

Routes incoming datagrams to per-address-space callbacks for read, write, write-under-mask, and stream variants. NULL optional callbacks cause automatic rejection with SUBCOMMAND_UNKNOWN. Handles Datagram Received OK, Datagram Rejected, and retry logic with timeout tracking.

Author
Jim Kueneman
Date
4 Mar 2026

Typedef Documentation

◆ memory_handler_t

typedef void(* memory_handler_t) (openlcb_statemachine_info_t *statemachine_info)

Function pointer type shared by all per-address-space memory handlers.

Function Documentation

◆ ProtocolDatagramHandler_initialize()

void ProtocolDatagramHandler_initialize ( const interface_protocol_datagram_handler_t * interface_protocol_datagram_handler)
extern

Stores the callback interface. Call once at startup before any datagram processing.

Parameters
interface_protocol_datagram_handlerPointer to interface_protocol_datagram_handler_t (must remain valid for application lifetime).

Stores the callback interface. Call once at startup before any datagram processing.

Algorithm:

  1. Cast away const and store the pointer in module-level static
* @param interface_protocol_datagram_handler  Populated callback table.
* 
Warning
Structure must remain valid for application lifetime.

◆ ProtocolDatagramHandler_load_datagram_received_ok_message()

void ProtocolDatagramHandler_load_datagram_received_ok_message ( openlcb_statemachine_info_t * statemachine_info,
uint16_t reply_pending_time_in_seconds )
extern

Builds a Datagram Received OK message (MTI 0x0A28).

The Reply Pending bit (0x80) is always set. A reply datagram (read data, write OK/fail, etc.) will always follow.

Parameters
statemachine_infoPointer to openlcb_statemachine_info_t context.
reply_pending_time_in_secondsSeconds until reply (rounded up to 2^N); 0 for no specific timeout.

Builds a Datagram Received OK message (MTI 0x0A28).

Algorithm:

  1. Convert reply_pending_time_in_seconds to a 4-bit power-of-2 exponent (1 = 2 s, 2 = 4 s, … 15 = 32768 s)
  2. Build MTI_DATAGRAM_OK_REPLY addressed back to the sender
  3. If reply_pending, store DATAGRAM_OK_REPLY_PENDING | exponent in payload[0]
  4. Mark outgoing message valid
* @param statemachine_info               Current context.
* @param reply_pending                   true if a reply datagram will follow.
* @param reply_pending_time_in_seconds   Seconds until reply (rounded up to 2^N).
*                                        Ignored when reply_pending is false.
* 

◆ ProtocolDatagramHandler_load_datagram_rejected_message()

void ProtocolDatagramHandler_load_datagram_rejected_message ( openlcb_statemachine_info_t * statemachine_info,
uint16_t return_code )
extern

Builds a Datagram Rejected message (MTI 0x0A48).

Parameters
statemachine_infoPointer to openlcb_statemachine_info_t context.
return_codeOpenLCB error code (0x1xxx permanent, 0x2xxx temporary).

Builds a Datagram Rejected message (MTI 0x0A48).

Algorithm:

  1. Build MTI_DATAGRAM_REJECTED_REPLY addressed back to the sender
  2. Copy 16-bit return_code into payload[0..1]
  3. Mark outgoing message valid
* @param statemachine_info  Current context.
* @param return_code        OpenLCB error code (0x1xxx permanent, 0x2xxx temporary).
* 

◆ ProtocolDatagramHandler_datagram()

void ProtocolDatagramHandler_datagram ( openlcb_statemachine_info_t * statemachine_info)
extern

Processes an incoming datagram. Dispatches to the appropriate handler based on the command byte (payload[0]).

Parameters
statemachine_infoPointer to openlcb_statemachine_info_t context with the received datagram.

Processes an incoming datagram. Dispatches to the appropriate handler based on the command byte (payload[0]).

Algorithm:

  1. If payload[0] == CONFIG_MEM_CONFIGURATION (0x20), delegate to _handle_datagram_memory_configuration_command()
  2. Otherwise reject with COMMAND_UNKNOWN
* @param statemachine_info  Context with the received datagram.
* 

◆ ProtocolDatagramHandler_datagram_received_ok()

void ProtocolDatagramHandler_datagram_received_ok ( openlcb_statemachine_info_t * statemachine_info)
extern

Handles an incoming Datagram Received OK reply. Clears the resend flag and frees the stored datagram awaiting acknowledgement.

Parameters
statemachine_infoPointer to openlcb_statemachine_info_t context with the received reply.

Handles an incoming Datagram Received OK reply. Clears the resend flag and frees the stored datagram awaiting acknowledgement.

Algorithm:

  1. Clear resend flag and free the stored datagram buffer
  2. Set outgoing_msg_info.valid = false (nothing to send)
* @param statemachine_info  Context with the received OK reply.
* 

◆ ProtocolDatagramHandler_datagram_rejected()

void ProtocolDatagramHandler_datagram_rejected ( openlcb_statemachine_info_t * statemachine_info)
extern

Handles an incoming Datagram Rejected reply. Sets the resend flag for temporary errors; clears retry state for permanent errors.

Parameters
statemachine_infoPointer to openlcb_statemachine_info_t context with the received rejection.

Handles an incoming Datagram Rejected reply. Sets the resend flag for temporary errors; clears retry state for permanent errors.

Algorithm:

  1. Extract error code from payload word 0
  2. If ERROR_TEMPORARY bit set and a stored datagram exists: a. Read retry count from timer.datagram.retry_count b. Increment retry count c. If retries < DATAGRAM_MAX_RETRIES, store new retry count and fresh tick snapshot, set resend_datagram flag d. If retries >= DATAGRAM_MAX_RETRIES, abandon (clear and free)
  3. If permanent error, clear resend flag and free stored buffer
  4. Set outgoing_msg_info.valid = false
* @param statemachine_info  Context with the received rejection.
* 

◆ ProtocolDatagramHandler_clear_resend_datagram_message()

void ProtocolDatagramHandler_clear_resend_datagram_message ( openlcb_node_t * openlcb_node)
extern

Frees any stored datagram and clears the resend flag for the node.

Parameters
openlcb_nodePointer to openlcb_node_t target node.

Frees any stored datagram and clears the resend flag for the node.

Algorithm:

  1. If last_received_datagram exists, lock/free/unlock it and NULL the pointer
  2. Clear resend_datagram flag
* @param openlcb_node  Target node.
* 
Note
Safe to call when no datagram is stored.

◆ ProtocolDatagramHandler_100ms_timer_tick()

void ProtocolDatagramHandler_100ms_timer_tick ( uint8_t current_tick)
extern

Periodic timer tick for datagram timeout tracking.

Called from the main loop with the current global tick. Currently a placeholder — Item 2 will add timeout handling.

Parameters
current_tickCurrent value of the global 100ms tick counter.

Called from the main loop with the current global tick. Currently a placeholder — timeout scanning is done by ProtocolDatagramHandler_check_timeouts().

* @param current_tick  Current value of the global 100ms tick counter.
* 

◆ ProtocolDatagramHandler_check_timeouts()

void ProtocolDatagramHandler_check_timeouts ( uint8_t current_tick)
extern

Scans for timed-out or max-retried pending datagrams and frees them.

Must be called from the main processing loop, not from an interrupt. Acquires the shared resource lock internally.

Parameters
current_tickCurrent value of the global 100ms tick, passed from the main loop.

Must be called from the main processing loop, not from an interrupt. Acquires the shared resource lock internally.

* @param current_tick  Current value of the global 100ms tick, passed from the main loop.
* 

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