reactor-c 1.0
C Runtime for Lingua Franca
Loading...
Searching...
No Matches
Federated

Functions for federated execution. More...

Files

file  clock-sync.h
 Utility functions for clock synchronization in federated Lingua Franca programs.
file  federate.h
 Data structures and functions for federated Lingua Franca programs.
file  net_common.h
 Common message types and definitions for federated Lingua Franca programs.
file  net_util.h
 Network utility functions for Lingua Franca programs.
file  socket_common.h
 Common socket operations and utilities for federated Lingua Franca programs.

Data Structures

struct  federate_instance_t
 Structure that a federate instance uses to keep track of its own state. More...
 Structure for federation metadata. More...
struct  lf_stat_ll
 Holds generic statistical data. More...
struct  rti_addr_info_t
 A helper struct for passing rti_addr information between lf_parse_rti_addr and extract_rti_addr_info. More...
struct  socket_stat_t
 Statistics and state for clock synchronization over a socket connection. More...
struct  staa_t
 Structure for STAA (safe to assume absent). More...

Macros

#define _LF_CLOCK_SYNC_ATTENUATION   10
 Runtime clock offset updates will be divided by this number.
#define _LF_CLOCK_SYNC_COLLECT_STATS   true
 By default, collect statistics on clock synchronization.
#define _LF_CLOCK_SYNC_EXCHANGES_PER_INTERVAL   10
 Number of required clock sync T4 messages per synchronization interval.
#define ADDRESS_QUERY_RETRY_INTERVAL   MSEC(250)
 Time that a federate waits before asking the RTI again for the port and IP address of a federate.
#define CLOCK_SYNC_GUARD_BAND   USEC(100)
 Define a guard band to filter clock synchronization messages based on discrepancies in the network delay.
#define CONNECT_RETRY_INTERVAL   MSEC(500)
 Time between a federate's attempts to connect to the RTI.
#define CONNECT_TIMEOUT   MINUTES(1)
 Bound on the number of retries to connect to the RTI.
#define DEFAULT_PORT   15045u
 Default port number for the RTI.
#define DELAY_BETWEEN_SOCKET_RETRIES   MSEC(100)
 The amount of time to wait after a failed socket read or write before trying again.
#define DELAY_START   SEC(1)
 Delay the start of all federates by this amount.
#define ENCODE_STOP_GRANTED(buffer, time, microstep)
 Encode a stop granted message.
#define ENCODE_STOP_REQUEST(buffer, time, microstep)
 Encode a stop request message.
#define ENCODE_STOP_REQUEST_REPLY(buffer, time, microstep)
 Encode a stop request reply message.
#define FED_COM_BUFFER_SIZE   256u
 Size of the buffer used for messages sent between federates.
#define FEDERATE_ID_IN_USE   2
 Code sent with a MSG_TYPE_REJECT message indicating that the federate ID is already in use.
#define FEDERATE_ID_OUT_OF_RANGE   3
 Code sent with a MSG_TYPE_REJECT message indicating that the federate ID is out of range.
#define FEDERATION_ID_DOES_NOT_MATCH   1
 Code sent with a MSG_TYPE_REJECT message indicating that the federation ID does not match.
#define HMAC_DOES_NOT_MATCH   6
 Code sent with a MSG_TYPE_REJECT message indicating that the HMAC authentication failed.
#define LF_CLOCK_SYNC   LF_CLOCK_SYNC_INIT
 Clock synchronization mode.
#define LF_CLOCK_SYNC_INIT   2
 Indicator for clock synchronization to be turned on at initialization.
#define LF_CLOCK_SYNC_OFF   1
 Indicator for clock synchronization to be turned off altogether.
#define LF_CLOCK_SYNC_ON   3
 Indicator for clock synchronization to be turned on at initialization and runtime.
#define MAX_NUM_PORT_ADDRESSES   16u
 Maximum number of port addresses that a federate will try to connect to the RTI on.
#define MSG_TYPE_ACK   255
 Byte identifying an acknowledgment of the previously received message.
#define MSG_TYPE_ADDRESS_ADVERTISEMENT   15
 Byte identifying a message advertising the port for the TCP connection server of a federate.
#define MSG_TYPE_ADDRESS_QUERY   13
 Byte identifying a address query message, sent by a federate to RTI to ask for another federate's address and port number.
#define MSG_TYPE_ADDRESS_QUERY_REPLY   14
 Byte identifying a address query message reply, sent by a RTI to a federate to reply with a remote federate's address and port number.
#define MSG_TYPE_CLOCK_SYNC_CODED_PROBE   22
 Coded probe message.
#define MSG_TYPE_CLOCK_SYNC_T1   19
 Physical clock synchronization messages according to PTP.
#define MSG_TYPE_CLOCK_SYNC_T3   20
 Prompt the master to send a T4.
#define MSG_TYPE_CLOCK_SYNC_T4   21
 Physical clock synchronization message according to PTP.
#define MSG_TYPE_DOWNSTREAM_NEXT_EVENT_TAG   26
 Byte identifying a downstream next event tag (DNET) message sent from the RTI in centralized coordination.
#define MSG_TYPE_FAILED   25
 Byte identifying that the federate or the RTI has failed.
#define MSG_TYPE_FAILED   25
 Byte identifying that the federate or the RTI has failed.
#define MSG_TYPE_FED_IDS   1
 Byte identifying a message from a federate to an RTI containing the federation ID and the federate ID.
#define MSG_TYPE_FED_NONCE   100
 Byte identifying a message from a federate to an RTI containing federate's 8-byte random nonce for HMAC-based authentication.
#define MSG_TYPE_FED_RESPONSE   102
 Byte identifying a message from federate to RTI as a response to the RTI_RESPONSE message.
#define MSG_TYPE_LATEST_TAG_CONFIRMED   9
 Byte identifying a latest tag confirmed (LTC) message sent by a federate to the RTI.
#define MSG_TYPE_MESSAGE   3
 Byte identifying a message to forward to another federate.
#define MSG_TYPE_NEIGHBOR_STRUCTURE   24
 A message that informs the RTI about connections between this federate and other federates where messages are routed through the RTI.
#define MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE   9
 The size of the header of a neighbor structure message.
#define MSG_TYPE_NEXT_EVENT_TAG   6
 Byte identifying a next event tag (NET) message sent from a federate in centralized coordination.
#define MSG_TYPE_P2P_MESSAGE   17
 Byte identifying a message to send directly to another federate.
#define MSG_TYPE_P2P_SENDING_FED_ID   16
 Byte identifying a first message that is sent by a federate directly to another federate after establishing a socket connection to send messages directly to the federate.
#define MSG_TYPE_P2P_TAGGED_MESSAGE   18
 Byte identifying a timestamped message to send directly to another federate.
#define MSG_TYPE_PORT_ABSENT   23
 A port absent message, informing the receiver that a given port will not have event for the current logical time.
#define MSG_TYPE_PROVISIONAL_TAG_ADVANCE_GRANT   8
 Byte identifying a provisional time advance grant (PTAG) sent by the RTI to a federate in centralized coordination.
#define MSG_TYPE_REJECT   0
 Byte identifying a rejection of the previously received message.
#define MSG_TYPE_RESIGN   4
 Byte identifying that the federate or the RTI is ending its execution.
#define MSG_TYPE_RTI_RESPONSE   101
 Byte identifying a message from RTI to federate as a response to the FED_NONCE message.
#define MSG_TYPE_STOP_GRANTED   12
 Byte sent by the RTI indicating that the stop request from some federate has been granted.
#define MSG_TYPE_STOP_GRANTED_LENGTH   (1 + sizeof(instant_t) + sizeof(microstep_t))
 The length of a stop granted message.
#define MSG_TYPE_STOP_REQUEST_LENGTH   (1 + sizeof(instant_t) + sizeof(microstep_t))
 The length of a stop request message.
#define MSG_TYPE_STOP_REQUEST_REPLY_LENGTH   (1 + sizeof(instant_t) + sizeof(microstep_t))
 The length of a stop request reply message.
#define MSG_TYPE_TAG_ADVANCE_GRANT   7
 Byte identifying a time advance grant (TAG) sent by the RTI to a federate in centralized coordination.
#define MSG_TYPE_TAGGED_MESSAGE   5
 Byte identifying a timestamped message to forward to another federate.
#define MSG_TYPE_TIMESTAMP   2
 Byte identifying a timestamp message, which is 64 bits long.
#define MSG_TYPE_TIMESTAMP_LENGTH   (1 + sizeof(int64_t))
 The length of a timestamp message.
#define MSG_TYPE_UDP_PORT   254
 Byte identifying an acknowledgment of the previously received MSG_TYPE_FED_IDS message.
#define NONCE_LENGTH   8
 The randomly created nonce size will be 8 bytes.
#define NUMBER_OF_FEDERATES   1
 The number of federates.
#define PORT_BIND_RETRY_INTERVAL   SEC(1)
 Time to wait before re-attempting to bind to a port.
#define PORT_BIND_RETRY_LIMIT   60
 Number of attempts to bind to a port before giving up.
#define RTI_NOT_EXECUTED_WITH_AUTH   7
 Code sent with a MSG_TYPE_REJECT message indicating that the RTI was not executed using the -a or –auth option.
#define SHA256_HMAC_LENGTH   32
 The HMAC tag uses the SHA256 hash algorithm, creating a 32 byte length hash tag.
#define TCP_TIMEOUT_TIME   SEC(10)
 The timeout time in ns for TCP operations.
#define UDP_TIMEOUT_TIME   SEC(1)
 The timeout time in ns for UDP operations.
#define UNEXPECTED_MESSAGE   4
 Code sent with a MSG_TYPE_REJECT message indicating that the incoming message is not expected.
#define WRONG_SERVER   5
 Code sent with a MSG_TYPE_REJECT message indicating that the connected to the wrong server.

Typedefs

typedef struct federate_instance_t federate_instance_t
 Structure that a federate instance uses to keep track of its own state.
typedef struct federation_metadata_t federation_metadata_t
 Structure for federation metadata.
typedef struct lf_stat_ll lf_stat_ll
 Holds generic statistical data.
typedef enum parse_rti_code_t parse_rti_code_t
 Code returned by lf_parse_rti_addr().
typedef struct rti_addr_info_t rti_addr_info_t
 A helper struct for passing rti_addr information between lf_parse_rti_addr and extract_rti_addr_info.
typedef struct socket_stat_t socket_stat_t
 Statistics and state for clock synchronization over a socket connection.
typedef enum socket_type_t socket_type_t
 Type of socket.
typedef struct staa_t staa_t
 Structure for STAA (safe to assume absent).

Enumerations

enum  parse_rti_code_t {
  SUCCESS , INVALID_PORT , INVALID_HOST , INVALID_USER ,
  FAILED_TO_PARSE
}
 Code returned by lf_parse_rti_addr(). More...
enum  socket_type_t { TCP , UDP }
 Type of socket. More...

Functions

int accept_socket (int socket, int rti_socket)
 Wait for an incoming connection request on the specified server socket.
void clock_sync_add_offset (instant_t *t)
 Add the current clock synchronization offset to a specified timestamp.
void clock_sync_set_constant_bias (interval_t offset)
 Set a fixed offset to the physical clock.
void clock_sync_subtract_offset (instant_t *t)
 Subtract the clock synchronization offset from a timestamp.
int connect_to_socket (int sock, const char *hostname, int port)
 Attempt to establish a TCP connection to the specified hostname and port.
int create_clock_sync_thread (lf_thread_t *thread_id)
 Create the thread responsible for handling clock synchronization with the RTI if (runtime) clock synchronization is on.
int create_real_time_tcp_socket_errexit ()
 Create an IPv4 TCP socket with Nagle's algorithm disabled.
int create_server (uint16_t port, int *final_socket, uint16_t *final_port, socket_type_t sock_type, bool increment_port_on_retry)
 Create a TCP server that listens for socket connections.
void encode_int32 (int32_t data, unsigned char *buffer)
 Write the specified data as a sequence of bytes starting at the specified address.
void encode_int64 (int64_t data, unsigned char *buffer)
 Write the specified data as a sequence of bytes starting at the specified address.
void encode_tag (unsigned char *buffer, tag_t tag)
 Encode tag information into buffer.
void encode_uint16 (uint16_t data, unsigned char *buffer)
 Write the specified data as a sequence of bytes starting at the specified address.
void encode_uint32 (uint32_t data, unsigned char *buffer)
 Write the specified data as a sequence of bytes starting at the specified address.
void extract_header (unsigned char *buffer, uint16_t *port_id, uint16_t *federate_id, size_t *length)
 Extract the core header information that all messages between federates share.
int32_t extract_int32 (unsigned char *bytes)
 This will swap the order of the bytes if this machine is big endian.
int64_t extract_int64 (unsigned char *bytes)
 This will swap the order of the bytes if this machine is big endian.
bool extract_match_group (const char *rti_addr, char *dest, regmatch_t group, size_t max_len, size_t min_len, const char *err_msg)
 Extract one match group from the rti_addr regex .
bool extract_match_groups (const char *rti_addr, char **rti_addr_strs, bool **rti_addr_flags, regmatch_t *group_array, int *gids, size_t *max_lens, size_t *min_lens, const char **err_msgs)
 Extract match groups from the rti_addr regex.
void extract_rti_addr_info (const char *rti_addr, rti_addr_info_t *rti_addr_info)
 Extract the host, port and user from rti_addr.
tag_t extract_tag (unsigned char *buffer)
 Extract tag information from buffer.
void extract_timed_header (unsigned char *buffer, uint16_t *port_id, uint16_t *federate_id, size_t *length, tag_t *tag)
 Extract the timed header information for timed messages between federates.
uint16_t extract_uint16 (unsigned char *bytes)
 Extract an uint16_t from the specified byte sequence.
int handle_T1_clock_sync_message (unsigned char *buffer, int socket, instant_t t2)
 Handle a clock synchroninzation message T1 coming from the RTI.
void handle_T4_clock_sync_message (unsigned char *buffer, int socket, instant_t r4)
 Handle a clock synchronization message T4 coming from the RTI.
int host_is_big_endian (void)
 Return true (1) if the host is big endian.
void init_shutdown_mutex (void)
 Initialize shutdown mutex.
void lf_connect_to_federate (uint16_t remote_federate_id)
 Connect to the federate with the specified id.
void lf_connect_to_rti (const char *hostname, int port_number)
 Connect to the RTI at the specified host and port.
void lf_create_server (int specified_port)
 Create a server to listen to incoming P2P connections.
void lf_enqueue_port_absent_reactions (environment_t *env)
 Enqueue port absent reactions.
interval_t lf_get_fed_maxwait (void)
 Return the global maxwait for the current federate.
interval_t lf_get_sta (void)
 Return the global STA (safe to advance) offset for federated execution.
void * lf_handle_p2p_connections_from_federates (void *ignored)
 Thread to accept connections from other federates.
void lf_latest_tag_confirmed (tag_t tag_to_send)
 Send a latest tag confirmed (LTC) signal to the RTI.
parse_rti_code_t lf_parse_rti_addr (const char *rti_addr)
 Parse the address of the RTI and store them into the global federation_metadata struct.
void lf_reset_status_fields_on_input_port_triggers (void)
 Reset the status fields on network input ports to unknown or absent.
int lf_send_message (int message_type, unsigned short port, unsigned short federate, const char *next_destination_str, size_t length, unsigned char *message)
 Send a message to another federate.
void lf_send_neighbor_structure_to_RTI (int socket_TCP_RTI)
 Send information about connections to the RTI.
tag_t lf_send_next_event_tag (environment_t *env, tag_t tag, bool wait_for_reply)
 Send a next event tag (NET) signal.
void lf_send_port_absent_to_federate (environment_t *env, interval_t additional_delay, unsigned short port_ID, unsigned short fed_ID)
 Send a port absent message.
int lf_send_stop_request_to_rti (tag_t stop_tag)
 Send a MSG_TYPE_STOP_REQUEST message to the RTI.
int lf_send_tagged_message (environment_t *env, interval_t additional_delay, int message_type, unsigned short port, unsigned short federate, const char *next_destination_str, size_t length, unsigned char *message)
 Send a tagged message to the specified port of the specified federate.
void lf_set_fed_maxwait (interval_t offset)
 Set the global maxwait for the current federate.
void lf_set_federation_id (const char *fid)
 Set the federation_id of this federate.
void lf_set_sta (interval_t offset)
 Set the global STA (safe to advance) offset for federated execution.
void lf_spawn_staa_thread (void)
 Spawn a thread to iterate through STAA structs.
void lf_stall_advance_level_federation (environment_t *env, size_t level)
 Wait until inputs statuses are known up to and including the specified level.
void lf_stall_advance_level_federation_locked (size_t level)
 Version of lf_stall_advance_level_federation() that assumes the caller holds the mutex lock.
void lf_synchronize_with_other_federates (void)
 Synchronize the start with other federates via the RTI.
bool lf_update_max_level (tag_t tag, bool is_provisional)
 Update the max level allowed to advance (MLAA).
instant_t lf_wait_until_time (tag_t tag)
 Return the physical time that we should wait until before advancing to the specified tag.
bool match_regex (const char *str, char *regex)
 Check whether str matches regex.
ssize_t peek_from_socket (int socket, unsigned char *result)
 Without blocking, peek at the specified socket.
int read_from_socket (int socket, size_t num_bytes, unsigned char *buffer)
 Read the specified number of bytes from the specified socket into the specified buffer.
int read_from_socket_close_on_error (int *socket, size_t num_bytes, unsigned char *buffer)
 Read the specified number of bytes from the specified socket into the specified buffer.
void read_from_socket_fail_on_error (int *socket, size_t num_bytes, unsigned char *buffer, char *format,...)
 Read the specified number of bytes from the specified socket into the specified buffer and close the socket if an error occurs.
void reset_socket_stat (struct socket_stat_t *socket_stat)
 Reset statistics on the socket.
uint16_t setup_clock_synchronization_with_rti (void)
 Setup necessary functionalities to synchronize clock with the RTI.
int shutdown_socket (int *socket, bool read_before_closing)
 Shutdown and close the socket.
int32_t swap_bytes_if_big_endian_int32 (int32_t src)
 If this host is little endian, then reverse the order of the bytes of the argument.
int64_t swap_bytes_if_big_endian_int64 (int64_t src)
 If this host is little endian, then reverse the order of the bytes of the argument.
uint16_t swap_bytes_if_big_endian_uint16 (uint16_t src)
 If this host is little endian, then reverse the order of the bytes of the argument.
void synchronize_initial_physical_clock_with_rti (int *rti_socket_TCP)
 Synchronize the initial physical clock with the RTI.
void tracepoint_federate_from_federate (trace_event_t event_type, int fed_id, int partner_id, tag_t *tag)
 Trace federate receiving a message from another federate.
void tracepoint_federate_from_rti (trace_event_t event_type, int fed_id, tag_t *tag)
 Trace federate receiving a message from the RTI.
void tracepoint_federate_to_federate (trace_event_t event_type, int fed_id, int partner_id, tag_t *tag)
 Trace federate sending a message to another federate.
void tracepoint_federate_to_rti (trace_event_t event_type, int fed_id, tag_t *tag)
 Trace federate sending a message to the RTI.
bool validate_host (const char *host)
 Check whether host is valid.
bool validate_port (char *port)
 Check whether port is valid.
bool validate_user (const char *user)
 Check whether user is valid.
int write_to_socket (int socket, size_t num_bytes, unsigned char *buffer)
 Write the specified number of bytes to the specified socket from the specified buffer.
int write_to_socket_close_on_error (int *socket, size_t num_bytes, unsigned char *buffer)
 Write the specified number of bytes to the specified socket.
void write_to_socket_fail_on_error (int *socket, size_t num_bytes, unsigned char *buffer, lf_mutex_t *mutex, char *format,...)
 Write the specified number of bytes to the specified socket.

Variables

lf_mutex_t lf_outbound_socket_mutex
 Mutex lock held while performing outbound socket write and close operations.
lf_cond_t lf_port_status_changed
 Condition variable for blocking on unkonwn federate input ports.

Detailed Description

Functions for federated execution.

This group contains functions for federated execution. The message types and protocols are defined in net_common.h.

Macro Definition Documentation

◆ _LF_CLOCK_SYNC_ATTENUATION

#define _LF_CLOCK_SYNC_ATTENUATION   10

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Runtime clock offset updates will be divided by this number.

◆ _LF_CLOCK_SYNC_COLLECT_STATS

#define _LF_CLOCK_SYNC_COLLECT_STATS   true

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

By default, collect statistics on clock synchronization.

◆ _LF_CLOCK_SYNC_EXCHANGES_PER_INTERVAL

#define _LF_CLOCK_SYNC_EXCHANGES_PER_INTERVAL   10

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Number of required clock sync T4 messages per synchronization interval.

The offset to the clock will not be adjusted until this number of T4 clock synchronization messages have been received.

◆ ADDRESS_QUERY_RETRY_INTERVAL

#define ADDRESS_QUERY_RETRY_INTERVAL   MSEC(250)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Time that a federate waits before asking the RTI again for the port and IP address of a federate.

The federate repeatedly sends an MSG_TYPE_ADDRESS_QUERY message after the RTI responds that it does not know to previous such messages. This allows time for federates to start separately.

◆ CLOCK_SYNC_GUARD_BAND

#define CLOCK_SYNC_GUARD_BAND   USEC(100)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Define a guard band to filter clock synchronization messages based on discrepancies in the network delay.

See also
Coded probes in Geng, Yilong, et al. "Exploiting a natural network effect for scalable, fine-grained clock synchronization."

◆ CONNECT_RETRY_INTERVAL

#define CONNECT_RETRY_INTERVAL   MSEC(500)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Time between a federate's attempts to connect to the RTI.

◆ CONNECT_TIMEOUT

#define CONNECT_TIMEOUT   MINUTES(1)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Bound on the number of retries to connect to the RTI.

A federate will retry every CONNECT_RETRY_INTERVAL nanoseconds until CONNECTION_TIMEOUT expires.

◆ DEFAULT_PORT

#define DEFAULT_PORT   15045u

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Default port number for the RTI.

Unless a specific port has been specified by the LF program in the "at" for the RTI or on the command line, when the RTI starts up, it will attempt to open a socket server on this port.

◆ DELAY_BETWEEN_SOCKET_RETRIES

#define DELAY_BETWEEN_SOCKET_RETRIES   MSEC(100)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

The amount of time to wait after a failed socket read or write before trying again.

This defaults to 100 ms.

◆ DELAY_START

#define DELAY_START   SEC(1)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Delay the start of all federates by this amount.

This helps ensure that the federates do not start at the same time. Each federate has provided its current physical time to the RTI, and the RTI has picked the largest of these. It will add this quantity and declare that to be the start time.

Note
This could use the latency estimates that were acquired during initial clock synchronization.

◆ ENCODE_STOP_GRANTED

#define ENCODE_STOP_GRANTED ( buffer,
time,
microstep )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Value:
do { \
buffer[0] = MSG_TYPE_STOP_GRANTED; \
encode_int64(time, &(buffer[1])); \
encode_int32((int32_t)microstep, &(buffer[1 + sizeof(instant_t)])); \
} while (0)
int64_t instant_t
Time instant.
Definition tag.h:101
#define MSG_TYPE_STOP_GRANTED
Byte sent by the RTI indicating that the stop request from some federate has been granted.
Definition net_common.h:525

Encode a stop granted message.

Parameters
bufferThe buffer to encode the message into.
timeThe time at which the federates will stop.
microstepThe microstep at which the federates will stop.

◆ ENCODE_STOP_REQUEST

#define ENCODE_STOP_REQUEST ( buffer,
time,
microstep )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Value:
do { \
buffer[0] = MSG_TYPE_STOP_REQUEST; \
encode_int64(time, &(buffer[1])); \
encode_int32((int32_t)microstep, &(buffer[1 + sizeof(instant_t)])); \
} while (0)
#define MSG_TYPE_STOP_REQUEST
Byte identifying a stop request.
Definition net_common.h:462

Encode a stop request message.

Parameters
bufferThe buffer to encode the message into.
timeThe time at which the federates will stop.
microstepThe microstep at which the federates will stop.

◆ ENCODE_STOP_REQUEST_REPLY

#define ENCODE_STOP_REQUEST_REPLY ( buffer,
time,
microstep )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Value:
do { \
encode_int64(time, &(buffer[1])); \
encode_int32((int32_t)microstep, &(buffer[1 + sizeof(instant_t)])); \
} while (0)
#define MSG_TYPE_STOP_REQUEST_REPLY
Byte indicating a federate's reply to a MSG_TYPE_STOP_REQUEST that was sent by the RTI.
Definition net_common.h:493

Encode a stop request reply message.

Parameters
bufferThe buffer to encode the message into.
timeThe time at which the federates will stop.
microstepThe microstep at which the federates will stop.

◆ FED_COM_BUFFER_SIZE

#define FED_COM_BUFFER_SIZE   256u

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Size of the buffer used for messages sent between federates.

This is used by both the federates and the RTI, so message lengths should generally match.

◆ FEDERATE_ID_IN_USE

#define FEDERATE_ID_IN_USE   2

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Code sent with a MSG_TYPE_REJECT message indicating that the federate ID is already in use.

◆ FEDERATE_ID_OUT_OF_RANGE

#define FEDERATE_ID_OUT_OF_RANGE   3

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Code sent with a MSG_TYPE_REJECT message indicating that the federate ID is out of range.

◆ FEDERATION_ID_DOES_NOT_MATCH

#define FEDERATION_ID_DOES_NOT_MATCH   1

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Code sent with a MSG_TYPE_REJECT message indicating that the federation ID does not match.

◆ HMAC_DOES_NOT_MATCH

#define HMAC_DOES_NOT_MATCH   6

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Code sent with a MSG_TYPE_REJECT message indicating that the HMAC authentication failed.

◆ LF_CLOCK_SYNC

#define LF_CLOCK_SYNC   LF_CLOCK_SYNC_INIT

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Clock synchronization mode.

This is one of LF_CLOCK_SYNC_OFF, LF_CLOCK_SYNC_INIT, or LF_CLOCK_SYNC_ON. The default is LF_CLOCK_SYNC_INIT, which indicates that clock synchronization is performed only at initialization.

Note
This is a compile-time option.

◆ LF_CLOCK_SYNC_INIT

#define LF_CLOCK_SYNC_INIT   2

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Indicator for clock synchronization to be turned on at initialization.

◆ LF_CLOCK_SYNC_OFF

#define LF_CLOCK_SYNC_OFF   1

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Indicator for clock synchronization to be turned off altogether.

◆ LF_CLOCK_SYNC_ON

#define LF_CLOCK_SYNC_ON   3

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Indicator for clock synchronization to be turned on at initialization and runtime.

◆ MAX_NUM_PORT_ADDRESSES

#define MAX_NUM_PORT_ADDRESSES   16u

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Maximum number of port addresses that a federate will try to connect to the RTI on.

If you are using automatic ports begining at DEFAULT_PORT, this puts an upper bound on the number of RTIs that can be running on the same host.

◆ MSG_TYPE_ACK

#define MSG_TYPE_ACK   255

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying an acknowledgment of the previously received message.

This message carries no payload.

◆ MSG_TYPE_ADDRESS_ADVERTISEMENT

#define MSG_TYPE_ADDRESS_ADVERTISEMENT   15

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a message advertising the port for the TCP connection server of a federate.

This is utilized in decentralized coordination as well as for physical connections in centralized coordination. The next four bytes (or sizeof(int32_t)) will be the port number. The sending federate will not wait for a response from the RTI and assumes its request will be processed eventually by the RTI.

◆ MSG_TYPE_ADDRESS_QUERY

#define MSG_TYPE_ADDRESS_QUERY   13

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a address query message, sent by a federate to RTI to ask for another federate's address and port number.

The next two bytes are the other federate's ID.

◆ MSG_TYPE_ADDRESS_QUERY_REPLY

#define MSG_TYPE_ADDRESS_QUERY_REPLY   14

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a address query message reply, sent by a RTI to a federate to reply with a remote federate's address and port number.

The reply from the RTI will be a port number (an int32_t), which is -1 if the RTI does not know yet (it has not received MSG_TYPE_ADDRESS_ADVERTISEMENT from the other federate), followed by the IP address of the other federate (an IPV4 address, which has length INET_ADDRSTRLEN). The next four bytes (or sizeof(int32_t)) will be the port number. The next four bytes (or sizeof(in_addr), which is uint32_t) will be the ip address.

◆ MSG_TYPE_CLOCK_SYNC_CODED_PROBE

#define MSG_TYPE_CLOCK_SYNC_CODED_PROBE   22

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Coded probe message.

This messages is sent by the server (master) right after MSG_TYPE_CLOCK_SYNC_T4(t1) with a new physical clock snapshot t2. At the receiver, the previous MSG_TYPE_CLOCK_SYNC_T4 message and this message are assigned a receive timestamp r1 and r2. If |(r2 - r1) - (t2 - t1)| < GUARD_BAND, then the current clock sync cycle is considered pure and can be processed.

See also
Geng, Yilong, et al. "Exploiting a natural network effect for scalable, fine-grained clock synchronization."

◆ MSG_TYPE_CLOCK_SYNC_T1

#define MSG_TYPE_CLOCK_SYNC_T1   19

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Physical clock synchronization messages according to PTP.

The next 8 bytes will be a timestamp sent according to PTP.

◆ MSG_TYPE_CLOCK_SYNC_T3

#define MSG_TYPE_CLOCK_SYNC_T3   20

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Prompt the master to send a T4.

The next four bytes will be the sending federate's id.

◆ MSG_TYPE_CLOCK_SYNC_T4

#define MSG_TYPE_CLOCK_SYNC_T4   21

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Physical clock synchronization message according to PTP.

The next 8 bytes will be a timestamp sent according to PTP.

◆ MSG_TYPE_DOWNSTREAM_NEXT_EVENT_TAG

#define MSG_TYPE_DOWNSTREAM_NEXT_EVENT_TAG   26

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a downstream next event tag (DNET) message sent from the RTI in centralized coordination.

The next eight bytes will be the timestamp. The next four bytes will be the microstep. This signal from the RTI tells the destination federate that downstream federates do not need for it to send any next event tag (NET) signal with a tag g less than the specified tag. Thus, it should only send those signals if needs permission from the RTI to advance to g.

◆ MSG_TYPE_FAILED [1/2]

#define MSG_TYPE_FAILED   25

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying that the federate or the RTI has failed.

◆ MSG_TYPE_FAILED [2/2]

#define MSG_TYPE_FAILED   25

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Byte identifying that the federate or the RTI has failed.

◆ MSG_TYPE_FED_IDS

#define MSG_TYPE_FED_IDS   1

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a message from a federate to an RTI containing the federation ID and the federate ID.

The message contains, in this order:

  • One byte equal to MSG_TYPE_FED_IDS.
  • Two bytes (ushort) giving the federate ID.
  • One byte (uchar) giving the length N of the federation ID.
  • N bytes containing the federation ID. Each federate needs to have a unique ID between 0 and NUMBER_OF_FEDERATES-1. Each federate, when starting up, should send this message to the RTI. This is its first message to the RTI. The RTI will respond with either MSG_TYPE_REJECT, MSG_TYPE_ACK, or MSG_TYPE_UDP_PORT. If the federate is a C target LF program, the generated federate code does this by calling lf_synchronize_with_other_federates(), passing to it its federate ID.

◆ MSG_TYPE_FED_NONCE

#define MSG_TYPE_FED_NONCE   100

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a message from a federate to an RTI containing federate's 8-byte random nonce for HMAC-based authentication.

The federate sends this message to an incoming RTI when TCP connection is established between the RTI and the federate. The message contains, in this order:

  • One byte equal to MSG_TYPE_FED_NONCE.
  • Two bytes (ushort) giving the federate ID.
  • Eight bytes for federate's nonce.

◆ MSG_TYPE_FED_RESPONSE

#define MSG_TYPE_FED_RESPONSE   102

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a message from federate to RTI as a response to the RTI_RESPONSE message.

The federate sends this message to RTI for HMAC-based authentication. The message contains, in this order:

  • One byte equal to MSG_TYPE_FED_RESPONSE.
  • 32 bytes for HMAC tag based on SHA256. The HMAC tag is composed of the following order:
  • One byte equal to MSG_TYPE_FED_RESPONSE.
  • Eight bytes for received RTI's nonce.

◆ MSG_TYPE_LATEST_TAG_CONFIRMED

#define MSG_TYPE_LATEST_TAG_CONFIRMED   9

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a latest tag confirmed (LTC) message sent by a federate to the RTI.

The next eight bytes will be the timestep of the completed tag. The next four bytes will be the microsteps of the completed tag.

◆ MSG_TYPE_MESSAGE

#define MSG_TYPE_MESSAGE   3

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a message to forward to another federate.

The next two bytes will be the ID of the destination port. The next two bytes are the destination federate ID. The four bytes after that will be the length of the message. The remaining bytes are the message.

Note
This is currently not used. All messages are tagged, even on physical connections, because if "after" is used, the message may preserve the logical timestamp rather than using the physical time.

◆ MSG_TYPE_NEIGHBOR_STRUCTURE

#define MSG_TYPE_NEIGHBOR_STRUCTURE   24

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

A message that informs the RTI about connections between this federate and other federates where messages are routed through the RTI.

Currently, this only includes logical connections when the coordination is centralized. This information is needed for the RTI to perform the centralized coordination.

Note
Only information about the immediate neighbors is required. The RTI can transitively obtain the structure of the federation based on each federate's immediate neighbor information.

The next 4 bytes is the number of upstream federates. The next 4 bytes is the number of downstream federates.

Depending on the first four bytes, the next bytes are pairs of (fed ID (2 bytes), delay (8 bytes)) for this federate's connection to upstream federates (by direct connection). The delay is the minimum "after" delay of all connections from the upstream federate.

Depending on the second four bytes, the next bytes are fed IDs (2 bytes each), of this federate's downstream federates (by direct connection).

Note
The upstream and downstream connections are transmitted on the same message to prevent (at least to some degree) the scenario where the RTI has information about one, but not the other (which is a critical error).

◆ MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE

#define MSG_TYPE_NEIGHBOR_STRUCTURE_HEADER_SIZE   9

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

The size of the header of a neighbor structure message.

◆ MSG_TYPE_NEXT_EVENT_TAG

#define MSG_TYPE_NEXT_EVENT_TAG   6

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a next event tag (NET) message sent from a federate in centralized coordination.

The next eight bytes will be the timestamp. The next four bytes will be the microstep. This message from a federate tells the RTI the tag of the earliest event on that federate's event queue. In other words, absent any further inputs from other federates, this will be the least tag of the next set of reactions on that federate. tag of the next set of reactions on that federate. If the event queue is empty and a timeout time has been specified, then the timeout time will be sent. If there is no timeout time, then FOREVER will be sent. Note that if there are physical actions and the earliest event on the event queue has a tag that is ahead of physical time (or the queue is empty), the federate should try to regularly advance its tag (and thus send NET messages) to make sure downstream federates can make progress.

◆ MSG_TYPE_P2P_MESSAGE

#define MSG_TYPE_P2P_MESSAGE   17

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a message to send directly to another federate.

The next two bytes will be the ID of the destination port. The next two bytes are the destination federate ID. This is checked against the _lf_my_fed_id of the receiving federate to ensure the message was intended for The four bytes after will be the length of the message. The ramaining bytes are the message.

◆ MSG_TYPE_P2P_SENDING_FED_ID

#define MSG_TYPE_P2P_SENDING_FED_ID   16

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a first message that is sent by a federate directly to another federate after establishing a socket connection to send messages directly to the federate.

This first message contains two bytes identifying the sending federate (its ID), a byte giving the length of the federation ID, followed by the federation ID (a string). The response from the remote federate is expected to be MSG_TYPE_ACK, but if the remote federate does not expect this federate or federation to connect, it will respond instead with MSG_TYPE_REJECT.

◆ MSG_TYPE_P2P_TAGGED_MESSAGE

#define MSG_TYPE_P2P_TAGGED_MESSAGE   18

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a timestamped message to send directly to another federate.

This is a variant of

See also
MSG_TYPE_TAGGED_MESSAGE that is used in P2P connections between federates. Having a separate message type for P2P connections between federates will be useful in preventing crosstalk.

The next two bytes will be the ID of the destination port. The next two bytes are the destination federate ID. This is checked against the _lf_my_fed_id of the receiving federate to ensure the message was intended for the correct federate. The four bytes after will be the length of the message. The next eight bytes will be the timestamp. The next four bytes will be the microstep of the sender. The ramaining bytes are the message.

◆ MSG_TYPE_PORT_ABSENT

#define MSG_TYPE_PORT_ABSENT   23

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

A port absent message, informing the receiver that a given port will not have event for the current logical time.

The next 2 bytes is the port id. The next 2 bytes will be the federate id of the destination federate. This is needed for the centralized coordination so that the RTI knows where to forward the message. The next 8 bytes are the intended time of the absent message The next 4 bytes are the intended microstep of the absent message

◆ MSG_TYPE_PROVISIONAL_TAG_ADVANCE_GRANT

#define MSG_TYPE_PROVISIONAL_TAG_ADVANCE_GRANT   8

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a provisional time advance grant (PTAG) sent by the RTI to a federate in centralized coordination.

This message is a promise by the RTI to the federate that no later message sent to the federate will have a tag earlier than the tag carried by this PTAG message. The next eight bytes will be the timestamp. The next four bytes will be the microstep.

◆ MSG_TYPE_REJECT

#define MSG_TYPE_REJECT   0

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a rejection of the previously received message.

The reason for the rejection is included as an additional byte (uchar) (see below for encodings of rejection reasons).

◆ MSG_TYPE_RESIGN

#define MSG_TYPE_RESIGN   4

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying that the federate or the RTI is ending its execution.

◆ MSG_TYPE_RTI_RESPONSE

#define MSG_TYPE_RTI_RESPONSE   101

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a message from RTI to federate as a response to the FED_NONCE message.

The RTI sends this message to federate for HMAC-based authentication. The message contains, in this order:

  • One byte equal to MSG_TYPE_RTI_RESPONSE.
  • Eight bytes for RTI's nonce.
  • 32 bytes for HMAC tag based on SHA256. The HMAC tag is composed of the following order:
  • One byte equal to MSG_TYPE_RTI_RESPONSE.
  • Two bytes (ushort) giving the received federate ID.
  • Eight bytes for received federate's nonce.

◆ MSG_TYPE_STOP_GRANTED

#define MSG_TYPE_STOP_GRANTED   12

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte sent by the RTI indicating that the stop request from some federate has been granted.

The payload is the tag at which all federates have agreed that they can stop. The next 8 bytes will be the time at which the federates will stop. The next 4 bytes will be the microstep at which the federates will stop.

◆ MSG_TYPE_STOP_GRANTED_LENGTH

#define MSG_TYPE_STOP_GRANTED_LENGTH   (1 + sizeof(instant_t) + sizeof(microstep_t))

◆ MSG_TYPE_STOP_REQUEST_LENGTH

#define MSG_TYPE_STOP_REQUEST_LENGTH   (1 + sizeof(instant_t) + sizeof(microstep_t))

◆ MSG_TYPE_STOP_REQUEST_REPLY_LENGTH

#define MSG_TYPE_STOP_REQUEST_REPLY_LENGTH   (1 + sizeof(instant_t) + sizeof(microstep_t))

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

The length of a stop request reply message.

◆ MSG_TYPE_TAG_ADVANCE_GRANT

#define MSG_TYPE_TAG_ADVANCE_GRANT   7

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a time advance grant (TAG) sent by the RTI to a federate in centralized coordination.

This message is a promise by the RTI to the federate that no later message sent to the federate will have a tag earlier than or equal to the tag carried by this TAG message. The next eight bytes will be the timestamp. The next four bytes will be the microstep.

◆ MSG_TYPE_TAGGED_MESSAGE

#define MSG_TYPE_TAGGED_MESSAGE   5

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a timestamped message to forward to another federate.

The next two bytes will be the ID of the destination reactor port. The next two bytes are the destination federate ID. The four bytes after that will be the length of the message (as an unsigned 32-bit int). The next eight bytes will be the timestamp of the message. The next four bytes will be the microstep of the message. The remaining bytes are the message.

With centralized coordination, all such messages flow through the RTI. With decentralized coordination, tagged messages are sent peer-to-peer between federates and are marked with MSG_TYPE_P2P_TAGGED_MESSAGE.

◆ MSG_TYPE_TIMESTAMP

#define MSG_TYPE_TIMESTAMP   2

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying a timestamp message, which is 64 bits long.

Each federate sends its starting physical time as a message of this type, and the RTI broadcasts to all the federates the starting logical time as a message of this type.

◆ MSG_TYPE_TIMESTAMP_LENGTH

#define MSG_TYPE_TIMESTAMP_LENGTH   (1 + sizeof(int64_t))

◆ MSG_TYPE_UDP_PORT

#define MSG_TYPE_UDP_PORT   254

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Byte identifying an acknowledgment of the previously received MSG_TYPE_FED_IDS message.

This message is sent by the RTI to the federate with a payload indicating the UDP port to use for clock synchronization. The next four bytes will be the port number for the UDP server, or 0 or USHRT_MAX if there is no UDP server. 0 means that initial clock synchronization is enabled, whereas USHRT_MAX mean that no synchronization should be performed at all.

◆ NONCE_LENGTH

#define NONCE_LENGTH   8

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

The randomly created nonce size will be 8 bytes.

◆ NUMBER_OF_FEDERATES

#define NUMBER_OF_FEDERATES   1

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

The number of federates.

This defaults to 1.

◆ PORT_BIND_RETRY_INTERVAL

#define PORT_BIND_RETRY_INTERVAL   SEC(1)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Time to wait before re-attempting to bind to a port.

When a process closes, the network stack typically waits between 30 and 120 seconds before releasing the port. This is to allow for delayed packets so that a new process does not receive packets from a previous process. Here, we limit the retries to 60 seconds.

◆ PORT_BIND_RETRY_LIMIT

#define PORT_BIND_RETRY_LIMIT   60

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Number of attempts to bind to a port before giving up.

◆ RTI_NOT_EXECUTED_WITH_AUTH

#define RTI_NOT_EXECUTED_WITH_AUTH   7

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Code sent with a MSG_TYPE_REJECT message indicating that the RTI was not executed using the -a or –auth option.

◆ SHA256_HMAC_LENGTH

#define SHA256_HMAC_LENGTH   32

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

The HMAC tag uses the SHA256 hash algorithm, creating a 32 byte length hash tag.

◆ TCP_TIMEOUT_TIME

#define TCP_TIMEOUT_TIME   SEC(10)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

The timeout time in ns for TCP operations.

Default value is 10 secs.

◆ UDP_TIMEOUT_TIME

#define UDP_TIMEOUT_TIME   SEC(1)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

The timeout time in ns for UDP operations.

Default value is 1 sec.

◆ UNEXPECTED_MESSAGE

#define UNEXPECTED_MESSAGE   4

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Code sent with a MSG_TYPE_REJECT message indicating that the incoming message is not expected.

◆ WRONG_SERVER

#define WRONG_SERVER   5

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_common.h>

Code sent with a MSG_TYPE_REJECT message indicating that the connected to the wrong server.

Typedef Documentation

◆ federate_instance_t

typedef struct federate_instance_t federate_instance_t

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Structure that a federate instance uses to keep track of its own state.

◆ federation_metadata_t

typedef struct federation_metadata_t federation_metadata_t

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Structure for federation metadata.

◆ lf_stat_ll

typedef struct lf_stat_ll lf_stat_ll

◆ parse_rti_code_t

◆ rti_addr_info_t

typedef struct rti_addr_info_t rti_addr_info_t

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

A helper struct for passing rti_addr information between lf_parse_rti_addr and extract_rti_addr_info.

◆ socket_stat_t

typedef struct socket_stat_t socket_stat_t

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Statistics and state for clock synchronization over a socket connection.

This struct maintains the state and statistics needed for clock synchronization between a federate and the RTI using a variant of the Precision Time Protocol (PTP). The synchronization process involves four timestamps (T1-T4) to estimate network delays and clock offsets:

  1. T1: RTI's physical time when sending sync message
  2. T2: Federate's physical time when receiving T1
  3. T3: Federate's physical time when sending reply
  4. T4: RTI's physical time when receiving reply

The round trip delay is estimated as: (T4 - T1) - (T3 - T2) The clock offset can be estimated as: ((T2 - T1) + (T3 - T4)) / 2

◆ socket_type_t

◆ staa_t

typedef struct staa_t staa_t

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Structure for STAA (safe to assume absent).

Enumeration Type Documentation

◆ parse_rti_code_t

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Code returned by lf_parse_rti_addr().

Enumerator
SUCCESS 
INVALID_PORT 
INVALID_HOST 
INVALID_USER 
FAILED_TO_PARSE 

◆ socket_type_t

Function Documentation

◆ accept_socket()

int accept_socket ( int socket,
int rti_socket )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Wait for an incoming connection request on the specified server socket.

This blocks until a connection is successfully accepted. If an error occurs that is not temporary (e.g., EAGAIN or EWOULDBLOCK), it reports the error and exits. Temporary errors cause the function to retry accepting the connection.

If the rti_socket is not -1, this function checks whether the specified socket is still open. If it is not open, then this function returns -1. This is useful for federates to determine whether they are still connected to the federation and to stop waiting when they are not.

Parameters
socketThe server socket file descriptor that is listening for incoming connections.
rti_socketThe rti socket for the federate to check if it is still open.
Returns
The file descriptor for the newly accepted socket on success, or -1 on failure (with an appropriate error message printed).

◆ clock_sync_add_offset()

void clock_sync_add_offset ( instant_t * t)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Add the current clock synchronization offset to a specified timestamp.

Parameters
tPointer to the timestamp to which to add the offset.

◆ clock_sync_set_constant_bias()

void clock_sync_set_constant_bias ( interval_t offset)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Set a fixed offset to the physical clock.

After calling this, the value returned by lf_time_physical(void) and get_elpased_physical_time(void) will have this specified offset added to what it would have returned before the call.

◆ clock_sync_subtract_offset()

void clock_sync_subtract_offset ( instant_t * t)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Subtract the clock synchronization offset from a timestamp.

Parameters
tThe timestamp from which to subtract the current clock sync offset.

◆ connect_to_socket()

int connect_to_socket ( int sock,
const char * hostname,
int port )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Attempt to establish a TCP connection to the specified hostname and port.

Attempt to establish a TCP connection to the specified hostname and port. This function uses getaddrinfo to resolve the hostname and retries the connection periodically if it fails. If the specified port is 0, it iterates through a range of default ports starting from DEFAULT_PORT. The function will stop retrying if the CONNECT_TIMEOUT is reached.

Parameters
sockThe socket file descriptor that has already been created (using socket()).
hostnameThe hostname or IP address of the server to connect to.
portThe port number to connect to. If 0 is specified, a default port range will be used.
Returns
0 on success, -1 on failure, and errno is set to indicate the specific error.

◆ create_clock_sync_thread()

int create_clock_sync_thread ( lf_thread_t * thread_id)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Create the thread responsible for handling clock synchronization with the RTI if (runtime) clock synchronization is on.

Otherwise, do nothing and return 0.

Returns
On success, returns 0; On error, it returns an error number.

◆ create_real_time_tcp_socket_errexit()

int create_real_time_tcp_socket_errexit ( )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Create an IPv4 TCP socket with Nagle's algorithm disabled.

This uses TCP_NODELAY and Delayed ACKs disabled with TCP_QUICKACK. It exits application on any error.

Returns
The socket ID (a file descriptor).

◆ create_server()

int create_server ( uint16_t port,
int * final_socket,
uint16_t * final_port,
socket_type_t sock_type,
bool increment_port_on_retry )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Create a TCP server that listens for socket connections.

If the specified port number is greater than zero, this function will attempt to acquire that port. If the specified port number is zero, and the increment_port_on_retry is true, it will attempt to acquire DEFAULT_PORT. If it fails to acquire DEFAULT_PORT, then it will increment the port number from DEFAULT_PORT on each attempt until it has incremented MAX_NUM_PORT_ADDRESSES times, at which point it will cycle around and begin again with DEFAULT_PORT. If the port number is zero, and the increment_port_on_retry is false, it delegates to the operating system to provide an available port number. If acquiring the port fails, then this function will repeatedly attempt up to PORT_BIND_RETRY_LIMIT times with a delay of PORT_BIND_RETRY_INTERVAL in between each try.

Parameters
portThe port number to use or 0 to let the OS pick or 1 to start trying at DEFAULT_PORT.
final_socketPointer to the returned socket descriptor on which accepting connections will occur.
final_portPointer to the final port the server will use.
sock_typeType of the socket, TCP or UDP.
increment_port_on_retryBoolean to retry port increment.
Returns
0 for success, -1 for failure.

◆ encode_int32()

void encode_int32 ( int32_t data,
unsigned char * buffer )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Write the specified data as a sequence of bytes starting at the specified address.

This encodes the data in little-endian order (lowest order byte first). This works for int32_t.

Parameters
dataThe data to write.
bufferThe location to start writing.

◆ encode_int64()

void encode_int64 ( int64_t data,
unsigned char * buffer )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Write the specified data as a sequence of bytes starting at the specified address.

This encodes the data in little-endian order (lowest order byte first).

Parameters
dataThe data to write.
bufferThe location to start writing.

◆ encode_tag()

void encode_tag ( unsigned char * buffer,
tag_t tag )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Encode tag information into buffer.

Buffer must have been allocated externally.

Parameters
bufferThe buffer to encode into.
tagThe tag to encode into 'buffer'.

◆ encode_uint16()

void encode_uint16 ( uint16_t data,
unsigned char * buffer )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Write the specified data as a sequence of bytes starting at the specified address.

This encodes the data in little-endian order (lowest order byte first).

Parameters
dataThe data to write.
bufferThe location to start writing.

◆ encode_uint32()

void encode_uint32 ( uint32_t data,
unsigned char * buffer )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Write the specified data as a sequence of bytes starting at the specified address.

This encodes the data in little-endian order (lowest order byte first). This works for uint32_t.

Parameters
dataThe data to write.
bufferThe location to start writing.

◆ extract_header()

void extract_header ( unsigned char * buffer,
uint16_t * port_id,
uint16_t * federate_id,
size_t * length )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Extract the core header information that all messages between federates share.

The core header information is two bytes with the ID of the destination port, two bytes with the ID of the destination federate, and four bytes with the length of the message.

Note
Only present when federated execution is enabled.
Parameters
bufferThe buffer to read from.
port_idThe place to put the port ID.
federate_idThe place to put the federate ID.
lengthThe place to put the length.

◆ extract_int32()

int32_t extract_int32 ( unsigned char * bytes)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

This will swap the order of the bytes if this machine is big endian.

Parameters
bytesThe address of the start of the sequence of bytes.

◆ extract_int64()

int64_t extract_int64 ( unsigned char * bytes)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

This will swap the order of the bytes if this machine is big endian.

Parameters
bytesThe address of the start of the sequence of bytes.

◆ extract_match_group()

bool extract_match_group ( const char * rti_addr,
char * dest,
regmatch_t group,
size_t max_len,
size_t min_len,
const char * err_msg )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Extract one match group from the rti_addr regex .

Parameters
rti_addrThe rti_addr to extract from.
destThe destination to store the match group.
groupThe group to extract.
max_lenThe maximum length of the match group.
min_lenThe minimum length of the match group.
err_msgThe error message to return if there is an error.
Returns
true if SUCCESS, else false.

◆ extract_match_groups()

bool extract_match_groups ( const char * rti_addr,
char ** rti_addr_strs,
bool ** rti_addr_flags,
regmatch_t * group_array,
int * gids,
size_t * max_lens,
size_t * min_lens,
const char ** err_msgs )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Extract match groups from the rti_addr regex.

Parameters
rti_addrThe rti_addr to extract from.
rti_addr_strsThe array of rti_addr strings to store the match groups.
rti_addr_flagsThe array of rti_addr flags to store the match groups.
group_arrayThe array of regmatch_t to store the match groups.
gidsThe array of gids to store the match groups.
max_lensThe array of max_lens to store the match groups.
min_lensThe array of min_lens to store the match groups.
err_msgsThe array of error messages to store the match groups.
Returns
true if success, else false.

◆ extract_rti_addr_info()

void extract_rti_addr_info ( const char * rti_addr,
rti_addr_info_t * rti_addr_info )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Extract the host, port and user from rti_addr.

Parameters
rti_addrThe rti_addr to extract from.
rti_addr_infoThe rti_addr_info into which to store the extracted information.

◆ extract_tag()

tag_t extract_tag ( unsigned char * buffer)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Extract tag information from buffer.

The tag is transmitted as a 64-bit (8 byte) signed integer for time and a 32-bit (4 byte) unsigned integer for microstep.

Parameters
bufferThe buffer to read from.
Returns
The extracted tag.

◆ extract_timed_header()

void extract_timed_header ( unsigned char * buffer,
uint16_t * port_id,
uint16_t * federate_id,
size_t * length,
tag_t * tag )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Extract the timed header information for timed messages between federates.

This is two bytes with the ID of the destination port, two bytes with the ID of the destination federate, four bytes with the length of the message, eight bytes with a timestamp, and four bytes with a microstep.

Parameters
bufferThe buffer to read from.
port_idThe place to put the port ID.
federate_idThe place to put the federate ID.
lengthThe place to put the length.
tagThe place to put the tag.

◆ extract_uint16()

uint16_t extract_uint16 ( unsigned char * bytes)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Extract an uint16_t from the specified byte sequence.

This will swap the order of the bytes if this machine is big endian.

Parameters
bytesThe address of the start of the sequence of bytes.

◆ handle_T1_clock_sync_message()

int handle_T1_clock_sync_message ( unsigned char * buffer,
int socket,
instant_t t2 )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Handle a clock synchroninzation message T1 coming from the RTI.

T1 is the first message in a PTP exchange. This replies to the RTI with a T3 message. It also measures the time it takes between when the method is called and the reply has been sent.

Parameters
bufferThe buffer containing the message, including the message type.
socketThe socket (either _lf_rti_socket_TCP or _lf_rti_socket_UDP).
t2The physical time at which the T1 message was received.
Returns
0 if T3 reply is successfully sent, -1 otherwise.

◆ handle_T4_clock_sync_message()

void handle_T4_clock_sync_message ( unsigned char * buffer,
int socket,
instant_t r4 )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Handle a clock synchronization message T4 coming from the RTI.

If the socket is _lf_rti_socket_TCP, then assume we are in the initial clock synchronization phase and set the clock offset based on the estimated clock synchronization error. Otherwise, if the socket is _lf_rti_socket_UDP, then this looks also for a subsequent "coded probe" message on the socket. If the delay between the T4 and the coded probe message is not as expected, then reject this clock synchronization round. If it is not rejected, then make an adjustment to the clock offset based on the estimated error. This function does not acquire the socket_mutex lock. The caller should acquire it unless it is sure there is only one thread running.

Parameters
bufferThe buffer containing the message, including the message type.
socketThe socket (either _lf_rti_socket_TCP or _lf_rti_socket_UDP).
r4The physical time at which this T4 message was received.

◆ host_is_big_endian()

int host_is_big_endian ( void )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Return true (1) if the host is big endian.

Otherwise, return false.

◆ init_shutdown_mutex()

void init_shutdown_mutex ( void )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Initialize shutdown mutex.

This is used to synchronize the shutdown of the federate.

◆ lf_connect_to_federate()

void lf_connect_to_federate ( uint16_t remote_federate_id)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Connect to the federate with the specified id.

The established connection will then be used in functions such as lf_send_tagged_message() to send messages directly to the specified federate. This function first sends an MSG_TYPE_ADDRESS_QUERY message to the RTI to obtain the IP address and port number of the specified federate. It then attempts to establish a socket connection to the specified federate. If this fails, the program exits. If it succeeds, it sets element [id] of the _fed.sockets_for_outbound_p2p_connections global array to refer to the socket for communicating directly with the federate.

Parameters
remote_federate_idThe ID of the remote federate.

◆ lf_connect_to_rti()

void lf_connect_to_rti ( const char * hostname,
int port_number )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Connect to the RTI at the specified host and port.

This will return the socket descriptor for the connection. If port_number is 0, then start at DEFAULT_PORT and increment the port number on each attempt. If an attempt fails, wait CONNECT_RETRY_INTERVAL and try again. If it fails after CONNECT_TIMEOUT, the program exits. If it succeeds, it sets the _fed.socket_TCP_RTI global variable to refer to the socket for communicating with the RTI.

Parameters
hostnameA hostname, such as "localhost".
port_numberA port number or 0 to start with the default.

◆ lf_create_server()

void lf_create_server ( int specified_port)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Create a server to listen to incoming P2P connections.

Such connections are used for physical connections or any connection if using decentralized coordination. This function only handles the creation of the server socket. The bound port for the server socket is then sent to the RTI by sending an MSG_TYPE_ADDRESS_ADVERTISEMENT message (

See also
net_common.h). This function expects no response from the RTI.

If a port is specified by the user, that will be used. Otherwise, a random port will be assigned. If the bind fails, it will retry after PORT_BIND_RETRY_INTERVAL until it has tried PORT_BIND_RETRY_LIMIT times. Then it will fail.

Parameters
specified_portThe port specified by the user or 0 to use a random port.

◆ lf_enqueue_port_absent_reactions()

void lf_enqueue_port_absent_reactions ( environment_t * env)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Enqueue port absent reactions.

These reactions will send a MSG_TYPE_PORT_ABSENT message to downstream federates if a given network output port is not present.

Parameters
envThe environment of the federate

◆ lf_get_fed_maxwait()

interval_t lf_get_fed_maxwait ( void )

#include </Users/runner/work/reactor-c/reactor-c/include/core/reactor.h>

Return the global maxwait for the current federate.

◆ lf_get_sta()

interval_t lf_get_sta ( void )

#include </Users/runner/work/reactor-c/reactor-c/include/core/reactor.h>

Return the global STA (safe to advance) offset for federated execution.

◆ lf_handle_p2p_connections_from_federates()

void * lf_handle_p2p_connections_from_federates ( void * ignored)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Thread to accept connections from other federates.

This thread accepts connections from federates that send messages directly to this one (not through the RTI). This thread starts a thread for each accepted socket connection to read messages and, once it has opened all expected sockets, exits.

Parameters
ignoredNo argument needed for this thread.

◆ lf_latest_tag_confirmed()

void lf_latest_tag_confirmed ( tag_t tag_to_send)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Send a latest tag confirmed (LTC) signal to the RTI.

This avoids the send if an equal or later LTC has previously been sent.

This function assumes the caller holds the mutex lock on the top-level environment.

Parameters
tag_to_sendThe tag to send.

◆ lf_parse_rti_addr()

parse_rti_code_t lf_parse_rti_addr ( const char * rti_addr)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Parse the address of the RTI and store them into the global federation_metadata struct.

Returns
a parse_rti_code_t indicating the result of the parse.

◆ lf_reset_status_fields_on_input_port_triggers()

void lf_reset_status_fields_on_input_port_triggers ( void )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Reset the status fields on network input ports to unknown or absent.

This will reset to absent if the last_known_status_tag field of the port is greater than or equal to the current tag of the top-level environment. This should be overriden to present if an event gets scheduled. Otherwise, set the status to unknown.

Note
This function must be called at the beginning of each logical time.

◆ lf_send_message()

int lf_send_message ( int message_type,
unsigned short port,
unsigned short federate,
const char * next_destination_str,
size_t length,
unsigned char * message )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Send a message to another federate.

This function is used for physical connections between federates. If the socket connection to the remote federate or the RTI has been broken, then this returns -1 without sending. Otherwise, it returns 0.

This method assumes that the caller does not hold the lf_outbound_socket_mutex lock, which it acquires to perform the send.

Parameters
message_typeThe type of the message being sent (currently only MSG_TYPE_P2P_MESSAGE).
portThe ID of the destination port.
federateThe ID of the destination federate.
next_destination_strThe name of the next destination in string format (for reporting).
lengthThe message length.
messageThe message.
Returns
0 if the message has been sent, -1 otherwise.

◆ lf_send_neighbor_structure_to_RTI()

void lf_send_neighbor_structure_to_RTI ( int socket_TCP_RTI)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Send information about connections to the RTI.

This is a generated function that sends information about connections between this federate and other federates where messages are routed through the RTI. Currently, this only includes logical connections when the coordination is centralized. This information is needed for the RTI to perform the centralized coordination.

See also
MSG_TYPE_NEIGHBOR_STRUCTURE in net_common.h
Parameters
socket_TCP_RTIThe socket descriptor for the connection to the RTI.

◆ lf_send_next_event_tag()

tag_t lf_send_next_event_tag ( environment_t * env,
tag_t tag,
bool wait_for_reply )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Send a next event tag (NET) signal.

If this federate depends on upstream federates or sends data to downstream federates, then send to the RTI a NET, which will give the tag of the earliest event on the event queue, or, if the queue is empty, the timeout time, or, if there is no timeout, FOREVER.

If there are network outputs that depend on physical actions, then insert a dummy event to ensure this federate advances its tag so that downstream federates can make progress.

A NET is a promise saying that, absent network inputs, this federate will not produce an output message with tag earlier than the NET value.

If there are upstream federates, then after sending a NET, this will block until either the RTI grants the advance to the requested time or the wait for the response from the RTI is interrupted by a change in the event queue (e.g., a physical action triggered or a network message arrived). If there are no upstream federates, then it will not wait for a TAG (which won't be forthcoming anyway) and returns the earliest tag on the event queue.

If the federate has neither upstream nor downstream federates, then this returns the specified tag immediately without sending anything to the RTI.

If there is at least one physical action somewhere in the federate that can trigger an output to a downstream federate, then the NET is required to be less than the current physical time. If physical time is less than the earliest event in the event queue (or the event queue is empty), then this function will insert a dummy event with a tag equal to the current physical time (and a microstep of 0). This will enforce advancement of tag for this federate and causes a NET message to be sent repeatedly as physical time advances with the time interval between messages controlled by the target parameter coordination-options: {advance-message-interval timevalue}. It will stop creating dummy events if and when its event queue has an event with a timestamp less than physical time.

If wait_for_reply is false, then this function will simply send the specified tag and return that tag immediately. This is useful when a federate is shutting down and will not be sending any more messages at all.

In all cases, this returns either the specified tag or another tag when it is safe to advance logical time to the returned tag. The returned tag may be less than the specified tag if there are upstream federates and either the RTI responds with a lesser tag or the wait for a response from the RTI is interrupted by a change in the event queue.

This function is used in centralized coordination only.

This function assumes the caller holds the mutex lock.

Parameters
envThe environment of the federate
tagThe tag.
wait_for_replyIf true, wait for a reply.

◆ lf_send_port_absent_to_federate()

void lf_send_port_absent_to_federate ( environment_t * env,
interval_t additional_delay,
unsigned short port_ID,
unsigned short fed_ID )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Send a port absent message.

This informs the remote federate that it will not receive a message with tag less than the current tag of the specified environment delayed by the additional_delay.

Parameters
envThe environment from which to get the current tag.
additional_delayThe after delay of the connection or NEVER if none.
port_IDThe ID of the receiving port.
fed_IDThe fed ID of the receiving federate.

◆ lf_send_stop_request_to_rti()

int lf_send_stop_request_to_rti ( tag_t stop_tag)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Send a MSG_TYPE_STOP_REQUEST message to the RTI.

The payload is the specified tag plus one microstep. If this federate has previously received a stop request from the RTI, then do not send the message and return 1. Return -1 if the socket is disconnected. Otherwise, return 0.

Returns
0 if the message is sent.

◆ lf_send_tagged_message()

int lf_send_tagged_message ( environment_t * env,
interval_t additional_delay,
int message_type,
unsigned short port,
unsigned short federate,
const char * next_destination_str,
size_t length,
unsigned char * message )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Send a tagged message to the specified port of the specified federate.

The tag will be the current tag of the specified environment delayed by the specified additional_delay. If the delayed tag falls after the timeout time, then the message is not sent and -1 is returned. The caller can reuse or free the memory storing the message after this returns.

If the message fails to send (e.g. the socket connection is broken), then the response depends on the message_type. For MSG_TYPE_TAGGED_MESSAGE, the message is supposed to go via the RTI, and failure to communicate with the RTI is a critical failure. In this case, the program will exit with an error message. If the message type is MSG_TYPE_P2P_TAGGED_MESSAGE, then the failure is not critical. It may be due to the remote federate having exited, for example, because its safe-to-process offset led it to believe that there were no messages forthcoming. In this case, on failure to send the message, this function returns -11.

This method assumes that the caller does not hold the lf_outbound_socket_mutex lock, which it acquires to perform the send.

Parameters
envThe environment from which to get the current tag.
additional_delayThe after delay on the connection or NEVER is there is none.
message_typeThe type of the message being sent. Currently can be MSG_TYPE_TAGGED_MESSAGE for messages sent via the RTI or MSG_TYPE_P2P_TAGGED_MESSAGE for messages sent directly between federates.
portThe ID of the destination port.
federateThe ID of the destination federate.
next_destination_strThe next destination in string format (RTI or federate) (used for reporting errors).
lengthThe message length.
messageThe message.
Returns
0 if the message has been sent, 1 otherwise.

◆ lf_set_fed_maxwait()

void lf_set_fed_maxwait ( interval_t offset)

#include </Users/runner/work/reactor-c/reactor-c/include/core/reactor.h>

Set the global maxwait for the current federate.

Parameters
offsetA non-negative time value to be applied as the maxwait.

◆ lf_set_federation_id()

void lf_set_federation_id ( const char * fid)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Set the federation_id of this federate.

Parameters
fidThe federation ID.

◆ lf_set_sta()

void lf_set_sta ( interval_t offset)

#include </Users/runner/work/reactor-c/reactor-c/include/core/reactor.h>

Set the global STA (safe to advance) offset for federated execution.

Parameters
offsetA non-negative time value to be applied as the STA offset.

◆ lf_spawn_staa_thread()

void lf_spawn_staa_thread ( void )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Spawn a thread to iterate through STAA structs.

This will set their associated ports absent at an offset if the port is not present with a value by a certain physical time.

◆ lf_stall_advance_level_federation()

void lf_stall_advance_level_federation ( environment_t * env,
size_t level )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Wait until inputs statuses are known up to and including the specified level.

Specifically, wait until the specified level is less that the max level allowed to advance (MLAA). This function does nothing if the environment is not the top-level environment.

Parameters
envThe environment (which should always be the top-level environment).
levelThe level to which we would like to advance.

◆ lf_stall_advance_level_federation_locked()

void lf_stall_advance_level_federation_locked ( size_t level)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Version of lf_stall_advance_level_federation() that assumes the caller holds the mutex lock.

Parameters
levelThe level to which we would like to advance.

◆ lf_synchronize_with_other_federates()

void lf_synchronize_with_other_federates ( void )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Synchronize the start with other federates via the RTI.

This assumes that a connection to the RTI is already made and _lf_rti_socket_TCP is valid. It then sends the current logical time to the RTI and waits for the RTI to respond with a specified time. It starts a thread to listen for messages from the RTI.

◆ lf_update_max_level()

bool lf_update_max_level ( tag_t tag,
bool is_provisional )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Update the max level allowed to advance (MLAA).

If the specified tag is greater than the current_tag of the top-level environment (or equal and is_provisional is false), then set the MLAA to INT_MAX and return. This removes any barriers on execution at the current tag due to network inputs. Otherwise, set the MLAA to the minimum level over all (non-physical) network input ports where the status of the input port is not known at that current_tag.

This function assumes that the caller holds the mutex.

Parameters
tagThe latest TAG or PTAG received by this federate.
is_provisionalWhether the tag was provisional.
Returns
True if the MLAA changed.

◆ lf_wait_until_time()

instant_t lf_wait_until_time ( tag_t tag)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Return the physical time that we should wait until before advancing to the specified tag.

This function adds the STA offset (STP_offset parameter) to the time of the specified tag unless the tag is the starting tag (it is always safe to advance to the starting tag). It also avoids adding the STA offset if all network input ports are known at least up to one microstep earlier than the specified tag.

This function assumes that the caller holds the environment mutex.

Parameters
timeThe specified time.

◆ match_regex()

bool match_regex ( const char * str,
char * regex )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Check whether str matches regex.

Parameters
strThe string to check.
regexThe regex to check against.
Returns
true if there is a match, false otherwise.

◆ peek_from_socket()

ssize_t peek_from_socket ( int socket,
unsigned char * result )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Without blocking, peek at the specified socket.

If there is anything on the queue, put its first byte at the specified address and return 1. If there is nothing on the queue, return 0, and if an error occurs, return -1.

Parameters
socketThe socket ID.
resultPointer to where to put the first byte available on the socket.

◆ read_from_socket()

int read_from_socket ( int socket,
size_t num_bytes,
unsigned char * buffer )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Read the specified number of bytes from the specified socket into the specified buffer.

If an error occurs during this reading, return -1 and set errno to indicate the cause of the error. If the read succeeds in reading the specified number of bytes, return 0. If an EOF occurs before reading the specified number of bytes, return 1. This function repeats the read attempt until the specified number of bytes have been read, an EOF is read, or an error occurs. Specifically, errors EAGAIN, EWOULDBLOCK, and EINTR are not considered errors and instead trigger another attempt. A delay between attempts is given by DELAY_BETWEEN_SOCKET_RETRIES.

Parameters
socketThe socket ID.
num_bytesThe number of bytes to read.
bufferThe buffer into which to put the bytes.
Returns
0 for success, 1 for EOF, and -1 for an error.

◆ read_from_socket_close_on_error()

int read_from_socket_close_on_error ( int * socket,
size_t num_bytes,
unsigned char * buffer )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Read the specified number of bytes from the specified socket into the specified buffer.

This uses read_from_socket, but if a failure occurs, it closes the socket using shutdown_socket and returns -1. Otherwise, it returns 0.

Parameters
socketPointer to the socket ID.
num_bytesThe number of bytes to write.
bufferThe buffer from which to get the bytes.
Returns
0 for success, -1 for failure.

◆ read_from_socket_fail_on_error()

void read_from_socket_fail_on_error ( int * socket,
size_t num_bytes,
unsigned char * buffer,
char * format,
... )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Read the specified number of bytes from the specified socket into the specified buffer and close the socket if an error occurs.

If a disconnect or an EOF occurs during this reading, then if format is non-null, report an error and exit. If the mutex argument is non-NULL, release the mutex before exiting. If format is null, then report the error, but do not exit. This function takes a formatted string and additional optional arguments similar to printf(format, ...) that is appended to the error messages.

Parameters
socketThe socket ID.
num_bytesThe number of bytes to read.
bufferThe buffer into which to put the bytes.
formatA printf-style format string, followed by arguments to fill the string, or NULL to not exit with an error message.

◆ reset_socket_stat()

void reset_socket_stat ( struct socket_stat_t * socket_stat)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Reset statistics on the socket.

Parameters
socket_statThe socket_stat_t struct that keeps track of stats for a given connection

◆ setup_clock_synchronization_with_rti()

uint16_t setup_clock_synchronization_with_rti ( void )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Setup necessary functionalities to synchronize clock with the RTI.

Returns
port number to be sent to the RTI. If clock synchronization is off compeltely, USHRT_MAX is returned. If clock synchronization is set to initial, 0 is sent. If clock synchronization is set to on, a reserved UDP port number will be sent.

◆ shutdown_socket()

int shutdown_socket ( int * socket,
bool read_before_closing )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Shutdown and close the socket.

If read_before_closing is false, this calls shutdown with SHUT_RDWR, shutting down both directions. If this fails, then it calls close. If read_before_closing is true, this calls shutdown with SHUT_WR, only disallowing further writing. If this succeeds, then it calls read until an EOF is received and discards all received bytes, otherwise it calls close. In all cases, the socket ID pointed to by the socket argument is set to -1.

Parameters
socketPointer to the socket descriptor to shutdown and close.
read_before_closingIf true, read until EOF before closing the socket.
Returns
int 0 for success and -1 if either shutdown or close returns an error.

◆ swap_bytes_if_big_endian_int32()

int32_t swap_bytes_if_big_endian_int32 ( int32_t src)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

If this host is little endian, then reverse the order of the bytes of the argument.

Otherwise, return the argument unchanged. This can be used to convert the argument to network order (big endian) and then back again. Network transmissions, by convention, are big endian, meaning that the high-order byte is sent first. But many platforms, including my Mac, are little endian, meaning that the low-order byte is first in memory.

Parameters
srcThe argument to convert.

◆ swap_bytes_if_big_endian_int64()

int64_t swap_bytes_if_big_endian_int64 ( int64_t src)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

If this host is little endian, then reverse the order of the bytes of the argument.

Otherwise, return the argument unchanged. This can be used to convert the argument to network order (big endian) and then back again. Network transmissions, by convention, are big endian, meaning that the high-order byte is sent first. But many platforms, including my Mac, are little endian, meaning that the low-order byte is first in memory.

Parameters
srcThe argument to convert.

◆ swap_bytes_if_big_endian_uint16()

uint16_t swap_bytes_if_big_endian_uint16 ( uint16_t src)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

If this host is little endian, then reverse the order of the bytes of the argument.

Otherwise, return the argument unchanged. This can be used to convert the argument to network order (big endian) and then back again. Network transmissions, by convention, are big endian, meaning that the high-order byte is sent first. But many platforms, including my Mac, are little endian, meaning that the low-order byte is first in memory.

Parameters
srcThe argument to convert.

◆ synchronize_initial_physical_clock_with_rti()

void synchronize_initial_physical_clock_with_rti ( int * rti_socket_TCP)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/clock-sync.h>

Synchronize the initial physical clock with the RTI.

A call to this function is inserted into the startup sequence by the code generator if initial clock synchronization is required.

This is a blocking function that expects to read a MSG_TYPE_CLOCK_SYNC_T1 from the RTI TCP socket. It will then follow the PTP protocol to synchronize the local physical clock with the RTI. Failing to complete this protocol is treated as a catastrophic error that causes the federate to exit.

Parameters
rti_socket_TCPPointer to the RTI's socket

◆ tracepoint_federate_from_federate()

void tracepoint_federate_from_federate ( trace_event_t event_type,
int fed_id,
int partner_id,
tag_t * tag )

#include </Users/runner/work/reactor-c/reactor-c/include/core/tracepoint.h>

Trace federate receiving a message from another federate.

Parameters
event_typeThe type of event. Possible values are:
fed_idThe federate identifier.
partner_idThe partner federate identifier.
tagPointer to the tag that has been received, or NULL.

◆ tracepoint_federate_from_rti()

void tracepoint_federate_from_rti ( trace_event_t event_type,
int fed_id,
tag_t * tag )

#include </Users/runner/work/reactor-c/reactor-c/include/core/tracepoint.h>

Trace federate receiving a message from the RTI.

Parameters
event_typeThe type of event. Possible values are:
fed_idThe federate identifier.
tagPointer to the tag that has been received, or NULL.

◆ tracepoint_federate_to_federate()

void tracepoint_federate_to_federate ( trace_event_t event_type,
int fed_id,
int partner_id,
tag_t * tag )

#include </Users/runner/work/reactor-c/reactor-c/include/core/tracepoint.h>

Trace federate sending a message to another federate.

Parameters
event_typeThe type of event. Possible values are:
fed_idThe federate identifier.
partner_idThe partner federate identifier.
tagPointer to the tag that has been sent, or NULL.

◆ tracepoint_federate_to_rti()

void tracepoint_federate_to_rti ( trace_event_t event_type,
int fed_id,
tag_t * tag )

#include </Users/runner/work/reactor-c/reactor-c/include/core/tracepoint.h>

Trace federate sending a message to the RTI.

Parameters
event_typeThe type of event. Possible values are:
fed_idThe federate identifier.
tagPointer to the tag that has been sent, or NULL.

◆ validate_host()

bool validate_host ( const char * host)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Check whether host is valid.

Parameters
hostThe host to check.
Returns
true if valid, false otherwise.

◆ validate_port()

bool validate_port ( char * port)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Check whether port is valid.

Parameters
portThe port to check.
Returns
true if valid, false otherwise.

◆ validate_user()

bool validate_user ( const char * user)

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/net_util.h>

Check whether user is valid.

Parameters
userThe user to check.
Returns
true if valid, false otherwise.

◆ write_to_socket()

int write_to_socket ( int socket,
size_t num_bytes,
unsigned char * buffer )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Write the specified number of bytes to the specified socket from the specified buffer.

If an error occurs, return -1 and set errno to indicate the cause of the error. If the write succeeds, return 0. This function repeats the attempt until the specified number of bytes have been written or an error occurs. Specifically, errors EAGAIN, EWOULDBLOCK, and EINTR are not considered errors and instead trigger another attempt. A delay between attempts is given by DELAY_BETWEEN_SOCKET_RETRIES.

Parameters
socketThe socket ID.
num_bytesThe number of bytes to write.
bufferThe buffer from which to get the bytes.
Returns
0 for success, -1 for failure.

◆ write_to_socket_close_on_error()

int write_to_socket_close_on_error ( int * socket,
size_t num_bytes,
unsigned char * buffer )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Write the specified number of bytes to the specified socket.

This uses write_to_socket and closes the socket if an error occurs. If an error occurs, this will change the socket ID pointed to by the first argument to -1 and will return -1.

Parameters
socketPointer to the socket ID.
num_bytesThe number of bytes to write.
bufferThe buffer from which to get the bytes.
Returns
0 for success, -1 for failure.

◆ write_to_socket_fail_on_error()

void write_to_socket_fail_on_error ( int * socket,
size_t num_bytes,
unsigned char * buffer,
lf_mutex_t * mutex,
char * format,
... )

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/network/socket_common.h>

Write the specified number of bytes to the specified socket.

This uses write_to_socket_close_on_error and exits with an error code if an error occurs. If the mutex argument is non-NULL, release the mutex before exiting. If the format argument is non-null, then use it an any additional arguments to form the error message using printf conventions. Otherwise, print a generic error message.

Parameters
socketPointer to the socket ID.
num_bytesThe number of bytes to write.
bufferThe buffer from which to get the bytes.
mutexIf non-NULL, the mutex to unlock before exiting.
formatA format string for error messages, followed by any number of fields that will be used to fill the format string as in printf, or NULL to print a generic error message.

Variable Documentation

◆ lf_outbound_socket_mutex

lf_mutex_t lf_outbound_socket_mutex
extern

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Mutex lock held while performing outbound socket write and close operations.

◆ lf_port_status_changed

lf_cond_t lf_port_status_changed
extern

#include </Users/runner/work/reactor-c/reactor-c/include/core/federated/federate.h>

Condition variable for blocking on unkonwn federate input ports.