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

Application-level Broadcast Time Protocol module. More...

Go to the source code of this file.

Data Structures

struct  interface_openlcb_application_broadcast_time_t
 Application-provided callbacks for broadcast time events. More...
 

Macros

#define BROADCAST_TIME_MAX_CUSTOM_CLOCKS   4
 
#define BROADCAST_TIME_WELLKNOWN_CLOCK_COUNT   4
 
#define BROADCAST_TIME_TOTAL_CLOCK_COUNT   (BROADCAST_TIME_WELLKNOWN_CLOCK_COUNT + BROADCAST_TIME_MAX_CUSTOM_CLOCKS)
 

Functions

void OpenLcbApplicationBroadcastTime_initialize (const interface_openlcb_application_broadcast_time_t *interface)
 Initialises the broadcast time module and stores the callback interface.
 
broadcast_clock_state_tOpenLcbApplicationBroadcastTime_setup_consumer (openlcb_node_t *openlcb_node, event_id_t clock_id)
 Allocates a clock slot as a consumer and registers event ranges on the node.
 
broadcast_clock_state_tOpenLcbApplicationBroadcastTime_setup_producer (openlcb_node_t *openlcb_node, event_id_t clock_id)
 Allocates a clock slot as a producer and registers event ranges on the node.
 
broadcast_clock_state_tOpenLcbApplicationBroadcastTime_get_clock (event_id_t clock_id)
 Returns the state for a registered clock.
 
bool OpenLcbApplicationBroadcastTime_is_consumer (event_id_t clock_id)
 Returns whether the given clock is registered as a consumer.
 
bool OpenLcbApplicationBroadcastTime_is_producer (event_id_t clock_id)
 Returns whether the given clock is registered as a producer.
 
void OpenLcbApplicationBroadcastTime_start (event_id_t clock_id)
 Marks the given clock as running so the 100 ms tick will advance it.
 
void OpenLcbApplicationBroadcastTime_stop (event_id_t clock_id)
 Marks the given clock as stopped so the 100 ms tick will not advance it.
 
void OpenLcbApplicationBroadcastTime_100ms_time_tick (uint8_t current_tick)
 Advances all running consumer clocks based on elapsed ticks.
 
bool OpenLcbApplicationBroadcastTime_send_report_time (openlcb_node_t *openlcb_node, event_id_t clock_id, uint8_t hour, uint8_t minute)
 Sends a Report Time event (Producer Identified Set) for a producer clock.
 
bool OpenLcbApplicationBroadcastTime_send_report_date (openlcb_node_t *openlcb_node, event_id_t clock_id, uint8_t month, uint8_t day)
 Sends a Report Date event (Producer Identified Set) for a producer clock.
 
bool OpenLcbApplicationBroadcastTime_send_report_year (openlcb_node_t *openlcb_node, event_id_t clock_id, uint16_t year)
 Sends a Report Year event (Producer Identified Set) for a producer clock.
 
bool OpenLcbApplicationBroadcastTime_send_report_rate (openlcb_node_t *openlcb_node, event_id_t clock_id, int16_t rate)
 Sends a Report Rate event (Producer Identified Set) for a producer clock.
 
bool OpenLcbApplicationBroadcastTime_send_start (openlcb_node_t *openlcb_node, event_id_t clock_id)
 Sends a Start event for a producer clock.
 
bool OpenLcbApplicationBroadcastTime_send_stop (openlcb_node_t *openlcb_node, event_id_t clock_id)
 Sends a Stop event for a producer clock.
 
bool OpenLcbApplicationBroadcastTime_send_date_rollover (openlcb_node_t *openlcb_node, event_id_t clock_id)
 Sends a Date Rollover event for a producer clock.
 
bool OpenLcbApplicationBroadcastTime_send_query_reply (openlcb_node_t *openlcb_node, event_id_t clock_id, uint8_t next_hour, uint8_t next_minute)
 Sends the full query reply sequence for a producer clock.
 
bool OpenLcbApplicationBroadcastTime_send_query (openlcb_node_t *openlcb_node, event_id_t clock_id)
 Sends a Query event for a consumer clock.
 
bool OpenLcbApplicationBroadcastTime_send_set_time (openlcb_node_t *openlcb_node, event_id_t clock_id, uint8_t hour, uint8_t minute)
 Sends a Set Time command to a clock generator.
 
bool OpenLcbApplicationBroadcastTime_send_set_date (openlcb_node_t *openlcb_node, event_id_t clock_id, uint8_t month, uint8_t day)
 Sends a Set Date command to a clock generator.
 
bool OpenLcbApplicationBroadcastTime_send_set_year (openlcb_node_t *openlcb_node, event_id_t clock_id, uint16_t year)
 Sends a Set Year command to a clock generator.
 
bool OpenLcbApplicationBroadcastTime_send_set_rate (openlcb_node_t *openlcb_node, event_id_t clock_id, int16_t rate)
 Sends a Set Rate command to a clock generator.
 
bool OpenLcbApplicationBroadcastTime_send_command_start (openlcb_node_t *openlcb_node, event_id_t clock_id)
 Sends a Start command to a clock generator.
 
bool OpenLcbApplicationBroadcastTime_send_command_stop (openlcb_node_t *openlcb_node, event_id_t clock_id)
 Sends a Stop command to a clock generator.
 
void OpenLcbApplicationBroadcastTime_trigger_query_reply (event_id_t clock_id)
 Triggers an immediate query reply (6-message sync sequence) for a producer clock.
 
void OpenLcbApplicationBroadcastTime_trigger_sync_delay (event_id_t clock_id)
 Starts or resets the 3-second sync delay timer for a producer clock.
 

Detailed Description

Application-level Broadcast Time Protocol module.

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.

Provides a fixed-size array of clock slots and the API for the OpenLCB Broadcast Time Protocol. Supports up to BROADCAST_TIME_TOTAL_CLOCK_COUNT simultaneous clocks (four well-known plus BROADCAST_TIME_MAX_CUSTOM_CLOCKS user-defined clocks).

The protocol handler (protocol_broadcast_time_handler.c) updates clock state when time events are received from the network. This module is optional — applications that do not use broadcast time should not include it.

Author
Jim Kueneman
Date
28 Feb 2026

Macro Definition Documentation

◆ BROADCAST_TIME_MAX_CUSTOM_CLOCKS

#define BROADCAST_TIME_MAX_CUSTOM_CLOCKS   4

◆ BROADCAST_TIME_WELLKNOWN_CLOCK_COUNT

#define BROADCAST_TIME_WELLKNOWN_CLOCK_COUNT   4

◆ BROADCAST_TIME_TOTAL_CLOCK_COUNT

#define BROADCAST_TIME_TOTAL_CLOCK_COUNT   (BROADCAST_TIME_WELLKNOWN_CLOCK_COUNT + BROADCAST_TIME_MAX_CUSTOM_CLOCKS)

Function Documentation

◆ OpenLcbApplicationBroadcastTime_initialize()

void OpenLcbApplicationBroadcastTime_initialize ( const interface_openlcb_application_broadcast_time_t * interface)
extern

Initialises the broadcast time module and stores the callback interface.

Clears all clock slots to zero and stores the interface pointer. Must be called once before any other function in this module.

Parameters
interfacePointer to a interface_openlcb_application_broadcast_time_t with the desired callbacks (NULL callbacks are safe).
Warning
Must be called before any setup or send functions.

Algorithm:

  1. Zero all clock slots with memset.
  2. Store the interface pointer in the static _interface variable.
* @param interface  Pointer to a interface_openlcb_application_broadcast_time_t
*                   with the desired callbacks (NULL callbacks are safe).
* 
Warning
Must be called before any other function in this module.

◆ OpenLcbApplicationBroadcastTime_setup_consumer()

broadcast_clock_state_t * OpenLcbApplicationBroadcastTime_setup_consumer ( openlcb_node_t * openlcb_node,
event_id_t clock_id )
extern

Allocates a clock slot as a consumer and registers event ranges on the node.

Finds or allocates a clock slot for clock_id and marks it as a consumer. Registers the full 32 768-event consumer and producer ranges on the node so the node can receive Report events and send the Query event.

Parameters
openlcb_nodePointer to the openlcb_node_t that will consume this clock. May be NULL to allocate the slot without registering ranges.
clock_id64-bit event_id_t that identifies the clock.
Returns
Pointer to the clock's broadcast_clock_state_t, or NULL if the clock array is full.
Warning
Returns NULL if no free clock slots are available.

Algorithm:

  1. Call _find_or_allocate_clock() for clock_id.
  2. If NULL, return NULL.
  3. Set clock->is_consumer = 1.
  4. If openlcb_node is non-NULL, register consumer and producer ranges for both halves of the clock's 65536-event range.
  5. Return pointer to the clock state.
* @param openlcb_node  Pointer to the openlcb_node_t; may be NULL to skip range registration.
* @param clock_id      64-bit event_id_t identifying the clock.
* 
Returns
Pointer to the broadcast_clock_state_t, or NULL if no free slots.

◆ OpenLcbApplicationBroadcastTime_setup_producer()

broadcast_clock_state_t * OpenLcbApplicationBroadcastTime_setup_producer ( openlcb_node_t * openlcb_node,
event_id_t clock_id )
extern

Allocates a clock slot as a producer and registers event ranges on the node.

Finds or allocates a clock slot for clock_id and marks it as a producer. Registers the full 32 768-event producer and consumer ranges on the node so the node can send Report events and receive Set/Query commands.

Parameters
openlcb_nodePointer to the openlcb_node_t that will produce this clock. May be NULL to allocate the slot without registering ranges.
clock_id64-bit event_id_t that identifies the clock.
Returns
Pointer to the clock's broadcast_clock_state_t, or NULL if the clock array is full.
Warning
Returns NULL if no free clock slots are available.

Algorithm:

  1. Call _find_or_allocate_clock() for clock_id.
  2. If NULL, return NULL.
  3. Set clock->is_producer = 1.
  4. If openlcb_node is non-NULL, register producer and consumer ranges for both halves of the clock's 65536-event range.
  5. Return pointer to the clock state.
* @param openlcb_node  Pointer to the openlcb_node_t; may be NULL to skip range registration.
* @param clock_id      64-bit event_id_t identifying the clock.
* 
Returns
Pointer to the broadcast_clock_state_t, or NULL if no free slots.

◆ OpenLcbApplicationBroadcastTime_get_clock()

broadcast_clock_state_t * OpenLcbApplicationBroadcastTime_get_clock ( event_id_t clock_id)
extern

Returns the state for a registered clock.

Parameters
clock_id64-bit event_id_t that identifies the clock.
Returns
Pointer to the broadcast_clock_state_t, or NULL if not found.

Algorithm:

  1. Call _find_clock_by_id(); if found, return &clock->state.
  2. Otherwise return NULL.
* @param clock_id  64-bit event_id_t identifying the clock.
* 
Returns
Pointer to the broadcast_clock_state_t, or NULL if not found.

◆ OpenLcbApplicationBroadcastTime_is_consumer()

bool OpenLcbApplicationBroadcastTime_is_consumer ( event_id_t clock_id)
extern

Returns whether the given clock is registered as a consumer.

Parameters
clock_id64-bit event_id_t that identifies the clock.
Returns
true if registered as a consumer, false if not found or not a consumer.

Algorithm:

  1. Find the clock slot; if not found, return false.
  2. Return clock->is_consumer.
* @param clock_id  64-bit event_id_t identifying the clock.
* 
Returns
true if registered as a consumer, false otherwise.

◆ OpenLcbApplicationBroadcastTime_is_producer()

bool OpenLcbApplicationBroadcastTime_is_producer ( event_id_t clock_id)
extern

Returns whether the given clock is registered as a producer.

Parameters
clock_id64-bit event_id_t that identifies the clock.
Returns
true if registered as a producer, false if not found or not a producer.

Algorithm:

  1. Find the clock slot; if not found, return false.
  2. Return clock->is_producer.
* @param clock_id  64-bit event_id_t identifying the clock.
* 
Returns
true if registered as a producer, false otherwise.

◆ OpenLcbApplicationBroadcastTime_start()

void OpenLcbApplicationBroadcastTime_start ( event_id_t clock_id)
extern

Marks the given clock as running so the 100 ms tick will advance it.

Parameters
clock_id64-bit event_id_t that identifies the clock.

Marks the given clock as running so the 100 ms tick will advance it.

Algorithm:

  1. Find the clock slot for clock_id; if not found, return immediately.
  2. Set state.is_running = true.
* @param clock_id  64-bit event_id_t identifying the clock.
* 

◆ OpenLcbApplicationBroadcastTime_stop()

void OpenLcbApplicationBroadcastTime_stop ( event_id_t clock_id)
extern

Marks the given clock as stopped so the 100 ms tick will not advance it.

Parameters
clock_id64-bit event_id_t that identifies the clock.

Marks the given clock as stopped so the 100 ms tick will not advance it.

Algorithm:

  1. Find the clock slot for clock_id; if not found, return immediately.
  2. Set state.is_running = false.
* @param clock_id  64-bit event_id_t identifying the clock.
* 

◆ OpenLcbApplicationBroadcastTime_100ms_time_tick()

void OpenLcbApplicationBroadcastTime_100ms_time_tick ( uint8_t current_tick)
extern

Advances all running consumer clocks based on elapsed ticks.

Called from the main loop with the current global tick. Uses fixed-point accumulation to handle fractional rates without floating-point arithmetic. Fires the on_time_changed callback each time a fast-clock minute boundary is crossed.

Parameters
current_tickCurrent value of the global 100ms tick counter.
Note
Clocks with rate 0 or that are stopped are skipped.
Only consumer clocks are advanced; producer clocks manage their own time.

Advances all running consumer clocks based on elapsed ticks.

Algorithm:

  1. Compute ticks elapsed since last call via subtraction.
  2. Skip if no time has elapsed (deduplication).
  3. For each allocated, running consumer clock with a non-zero rate:
    • Compute abs_rate from the signed rate.
    • Add 100 * abs_rate * ticks_elapsed to state.ms_accumulator.
    • While accumulator >= BROADCAST_TIME_MS_PER_MINUTE_FIXED_POINT (240,000):
      • Subtract the threshold from the accumulator.
      • Call _advance_minute_forward() or _advance_minute_backward() depending on rate sign.
      • Fire the on_time_changed callback.
  4. For each allocated producer clock with a producer_node:
    • Compare previous_run_state with the node's current run_state.
    • On transition to RUNSTATE_RUN, auto-set query_reply_pending to trigger the Standard §6.1 startup sync sequence.
    • Update previous_run_state.

The threshold 240,000 equals 4 * 60 * 1000, which at rate=4 (1.0x) yields exactly one fast-minute per real minute. See the accumulator math comment above for details.

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

◆ OpenLcbApplicationBroadcastTime_send_report_time()

bool OpenLcbApplicationBroadcastTime_send_report_time ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
uint8_t hour,
uint8_t minute )
extern

Sends a Report Time event (Producer Identified Set) for a producer clock.

Builds a time event ID from the given hour and minute and sends it as a PC Event Report. No-op if the clock is not found or is not a producer.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
hourHour value to report (0–23).
minuteMinute value to report (0–59).
Returns
true if queued or clock not a producer, false if the transmit buffer is full.

Sends a Report Time event (Producer Identified Set) for a producer clock.

Algorithm:

  1. Find the clock; if not found or not a producer, return true (nothing to do).
  2. Build the time event ID and send it as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* @param hour          Hour value to report (0-23).
* @param minute        Minute value to report (0-59).
* 
Returns
true if queued or clock not applicable, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_report_date()

bool OpenLcbApplicationBroadcastTime_send_report_date ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
uint8_t month,
uint8_t day )
extern

Sends a Report Date event (Producer Identified Set) for a producer clock.

Builds a date event ID from the given month and day and sends it as a PC Event Report. No-op if the clock is not found or is not a producer.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
monthMonth value to report (1–12).
dayDay value to report (1–31).
Returns
true if queued or clock not a producer, false if the transmit buffer is full.

Sends a Report Date event (Producer Identified Set) for a producer clock.

Algorithm:

  1. Find the clock; if not found or not a producer, return true (nothing to do).
  2. Build the date event ID and send it as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* @param month         Month value to report (1-12).
* @param day           Day value to report (1-31).
* 
Returns
true if queued or clock not applicable, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_report_year()

bool OpenLcbApplicationBroadcastTime_send_report_year ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
uint16_t year )
extern

Sends a Report Year event (Producer Identified Set) for a producer clock.

Builds a year event ID and sends it as a PC Event Report. No-op if the clock is not found or is not a producer.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
yearYear value to report.
Returns
true if queued or clock not a producer, false if the transmit buffer is full.

Sends a Report Year event (Producer Identified Set) for a producer clock.

Algorithm:

  1. Find the clock; if not found or not a producer, return true (nothing to do).
  2. Build the year event ID and send it as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* @param year          Year value to report.
* 
Returns
true if queued or clock not applicable, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_report_rate()

bool OpenLcbApplicationBroadcastTime_send_report_rate ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
int16_t rate )
extern

Sends a Report Rate event (Producer Identified Set) for a producer clock.

Builds a rate event ID from the 12-bit fixed-point rate and sends it as a PC Event Report. No-op if the clock is not found or is not a producer.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
rate12-bit signed fixed-point rate (4 = 1.0x real-time).
Returns
true if queued or clock not a producer, false if the transmit buffer is full.

Sends a Report Rate event (Producer Identified Set) for a producer clock.

Algorithm:

  1. Find the clock; if not found or not a producer, return true (nothing to do).
  2. Build the rate event ID and send it as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* @param rate          12-bit signed fixed-point rate (4 = 1.0x real-time).
* 
Returns
true if queued or clock not applicable, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_start()

bool OpenLcbApplicationBroadcastTime_send_start ( openlcb_node_t * openlcb_node,
event_id_t clock_id )
extern

Sends a Start event for a producer clock.

Tells all consumers on the network that this clock is now running. No-op if the clock is not found or is not a producer.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
Returns
true if queued or clock not a producer, false if the transmit buffer is full.

Sends a Start event for a producer clock.

Algorithm:

  1. Find the clock; if not found or not a producer, return true (nothing to do).
  2. Build the Start command event ID and send it as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* 
Returns
true if queued or clock not applicable, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_stop()

bool OpenLcbApplicationBroadcastTime_send_stop ( openlcb_node_t * openlcb_node,
event_id_t clock_id )
extern

Sends a Stop event for a producer clock.

Tells all consumers on the network that this clock has stopped. No-op if the clock is not found or is not a producer.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
Returns
true if queued or clock not a producer, false if the transmit buffer is full.

Sends a Stop event for a producer clock.

Algorithm:

  1. Find the clock; if not found or not a producer, return true (nothing to do).
  2. Build the Stop command event ID and send it as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* 
Returns
true if queued or clock not applicable, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_date_rollover()

bool OpenLcbApplicationBroadcastTime_send_date_rollover ( openlcb_node_t * openlcb_node,
event_id_t clock_id )
extern

Sends a Date Rollover event for a producer clock.

Notifies consumers that the clock has crossed midnight and the date has changed. No-op if the clock is not found or is not a producer.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
Returns
true if queued or clock not a producer, false if the transmit buffer is full.

Sends a Date Rollover event for a producer clock.

Algorithm:

  1. Find the clock; if not found or not a producer, return true (nothing to do).
  2. Build the Date Rollover command event ID and send it as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* 
Returns
true if queued or clock not applicable, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_query_reply()

bool OpenLcbApplicationBroadcastTime_send_query_reply ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
uint8_t next_hour,
uint8_t next_minute )
extern

Sends the full query reply sequence for a producer clock.

The reply sequence (per the OpenLCB Broadcast Time Standard) consists of six messages: Start/Stop, Rate, Year, Date, current Time (all as Producer Identified Set), and the next-minute Time as a PC Event Report. Because the transmit buffer may fill during the sequence, this function uses a static state variable and must be called repeatedly until it returns true.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
next_hourHour of the next scheduled time event (0–23).
next_minuteMinute of the next scheduled time event (0–59).
Returns
true when all six messages have been queued, false if more calls are needed.
Note
State is stored per-clock in broadcast_clock_t.send_query_reply_state, allowing concurrent query replies for different clocks.

Looks up the clock by clock_id and delegates to the internal state machine. See _send_query_reply_for_clock for the full sequence.

* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* @param next_hour     Hour of the next scheduled time event (0-23).
* @param next_minute   Minute of the next scheduled time event (0-59).
* 
Returns
true when all six messages have been queued, false if more calls are needed.
Note
State is stored per-clock in broadcast_clock_t.send_query_reply_state, allowing concurrent query replies for different clocks.

◆ OpenLcbApplicationBroadcastTime_send_query()

bool OpenLcbApplicationBroadcastTime_send_query ( openlcb_node_t * openlcb_node,
event_id_t clock_id )
extern

Sends a Query event for a consumer clock.

Asks the clock generator to respond with its full current state (start/stop, rate, year, date, time). The generator replies with a six-message sequence. No-op if the clock is not found or is not a consumer.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the clock.
Returns
true if queued or clock not a consumer, false if the transmit buffer is full.

Sends a Query event for a consumer clock.

Algorithm:

  1. Find the clock; if not found or not a consumer, return true (nothing to do).
  2. Build the Query command event ID and send it as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the clock.
* 
Returns
true if queued or clock not applicable, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_set_time()

bool OpenLcbApplicationBroadcastTime_send_set_time ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
uint8_t hour,
uint8_t minute )
extern

Sends a Set Time command to a clock generator.

Asks the clock generator to change its current time to the given hour and minute. The generator will broadcast the updated time to all consumers.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the target clock.
hourDesired hour (0–23).
minuteDesired minute (0–59).
Returns
true if queued, false if the transmit buffer is full.

Algorithm:

  1. Build the time event ID with the set flag.
  2. Send as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the target clock.
* @param hour          Desired hour (0-23).
* @param minute        Desired minute (0-59).
* 
Returns
true if queued, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_set_date()

bool OpenLcbApplicationBroadcastTime_send_set_date ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
uint8_t month,
uint8_t day )
extern

Sends a Set Date command to a clock generator.

Asks the clock generator to change its current date to the given month and day. The generator will broadcast the updated date to all consumers.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the target clock.
monthDesired month (1–12).
dayDesired day (1–31).
Returns
true if queued, false if the transmit buffer is full.

Algorithm:

  1. Build the date event ID with the set flag.
  2. Send as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the target clock.
* @param month         Desired month (1-12).
* @param day           Desired day (1-31).
* 
Returns
true if queued, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_set_year()

bool OpenLcbApplicationBroadcastTime_send_set_year ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
uint16_t year )
extern

Sends a Set Year command to a clock generator.

Asks the clock generator to change its current year. The generator will broadcast the updated year to all consumers.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the target clock.
yearDesired year.
Returns
true if queued, false if the transmit buffer is full.

Algorithm:

  1. Build the year event ID with the set flag.
  2. Send as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the target clock.
* @param year          Desired year.
* 
Returns
true if queued, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_set_rate()

bool OpenLcbApplicationBroadcastTime_send_set_rate ( openlcb_node_t * openlcb_node,
event_id_t clock_id,
int16_t rate )
extern

Sends a Set Rate command to a clock generator.

Asks the clock generator to change its fast-clock rate. The rate is a 12-bit signed fixed-point value where 4 means 1.0x real-time and negative values run the clock backward.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the target clock.
rate12-bit signed fixed-point rate (4 = 1.0x real-time).
Returns
true if queued, false if the transmit buffer is full.

Algorithm:

  1. Build the rate event ID with the set flag.
  2. Send as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the target clock.
* @param rate          12-bit signed fixed-point rate (4 = 1.0x real-time).
* 
Returns
true if queued, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_command_start()

bool OpenLcbApplicationBroadcastTime_send_command_start ( openlcb_node_t * openlcb_node,
event_id_t clock_id )
extern

Sends a Start command to a clock generator.

Asks the clock generator to start running. The generator will broadcast a Start event to all consumers when it complies.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the target clock.
Returns
true if queued, false if the transmit buffer is full.

Algorithm:

  1. Build the Start command event ID.
  2. Send as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the target clock.
* 
Returns
true if queued, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_send_command_stop()

bool OpenLcbApplicationBroadcastTime_send_command_stop ( openlcb_node_t * openlcb_node,
event_id_t clock_id )
extern

Sends a Stop command to a clock generator.

Asks the clock generator to stop running. The generator will broadcast a Stop event to all consumers when it complies.

Parameters
openlcb_nodePointer to the sending openlcb_node_t.
clock_id64-bit event_id_t identifying the target clock.
Returns
true if queued, false if the transmit buffer is full.

Algorithm:

  1. Build the Stop command event ID.
  2. Send as a PC Event Report.
* @param openlcb_node  Pointer to the sending openlcb_node_t.
* @param clock_id      64-bit event_id_t identifying the target clock.
* 
Returns
true if queued, false if the transmit buffer is full.

◆ OpenLcbApplicationBroadcastTime_trigger_query_reply()

void OpenLcbApplicationBroadcastTime_trigger_query_reply ( event_id_t clock_id)
extern

Triggers an immediate query reply (6-message sync sequence) for a producer clock.

Sets the query_reply_pending flag and resets the state machine so the 100ms tick will drive the 6-message sequence (Start/Stop, Rate, Year, Date, Time as Producer Identified Set, then next-minute Time as PCER).

Parameters
clock_id64-bit event_id_t identifying the clock.

Triggers an immediate query reply (6-message sync sequence) for a producer clock.

Sets the query_reply_pending flag and resets the state machine so the 100ms tick will drive the 6-message sync sequence.

* @param clock_id  64-bit event_id_t identifying the clock.
* 

◆ OpenLcbApplicationBroadcastTime_trigger_sync_delay()

void OpenLcbApplicationBroadcastTime_trigger_sync_delay ( event_id_t clock_id)
extern

Starts or resets the 3-second sync delay timer for a producer clock.

After Set commands, the producer waits 3 seconds before sending a sync reply, allowing multiple Set commands to coalesce into one reply. Each call resets the timer. When the timer expires, the query reply state machine is triggered automatically.

Parameters
clock_id64-bit event_id_t identifying the clock.

Each call resets the timer to 30 ticks (3 seconds at 100ms). When the timer expires, the query reply state machine is triggered automatically, sending the 6-message sync sequence.

* @param clock_id  64-bit event_id_t identifying the clock.
* 

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