Projects/3BIT/winter-semester/ISA/include/state_machine.h
2026-04-14 19:28:46 +02:00

921 lines
28 KiB
C

/*
* ==================================================================================
* State Machine Header - Protocol State Management
*
* ISA Project
* Author: Roman Necas (xnecasr00)
* Date: 13. October 2025
*
* PURPOSE:
* This header defines the state machine layer for the ICMP covert channel file
* transfer protocol. It implements separate state machines for client and server
* modes, providing structured protocol flow control, timeout handling, and error
* recovery.
*
* RESPONSIBILITIES:
* - Client state machine: Manages file transmission states (START → DATA → END)
* - Server state machine: Manages file reception states (LISTENING → RECEIVING → CLOSING)
* - State transition validation: Ensures only valid state changes occur
* - Timeout detection: Detects idle sessions and triggers retransmissions
* - Retry logic with exponential backoff: Prevents network flooding
* - Error recovery: Handles recoverable errors vs fatal errors
* - Statistics tracking: Monitors state duration, retry counts, etc.
*
* STATE MACHINE PATTERN:
* Both client and server use event-driven state machines:
* - Current state: Represents current protocol phase
* - Events: Triggers for state transitions (packet received, timeout, error)
* - Transitions: Valid state changes defined by protocol
* - Actions: Side effects when entering/exiting states
*
* CLIENT STATE MACHINE:
* Manages the file sending protocol:
* IDLE → START_SENT → DATA_TRANSFER ⇄ DATA_WAIT_ACK → END_SENT → COMPLETED
* Any state can transition to ERROR or ABORT on failure
*
* SERVER STATE MACHINE:
* Manages the file receiving protocol:
* LISTENING → SESSION_INIT → RECEIVING_DATA ⇄ DATA_ACK_SENT → SESSION_CLOSING → COMPLETED
* Any state can transition to ERROR or TIMEOUT on failure
*
* TIMEOUT HANDLING:
* - Client timeouts trigger retransmissions with exponential backoff
* - Server timeouts indicate client failure or network partition
* - Timeout values increase: 2s → 4s → 8s → 16s → 30s (capped)
* ==================================================================================
*/
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
#include <time.h>
#include <stdint.h>
/*
* ==================================================================================
* CLIENT STATES
* ==================================================================================
*/
/*
* client_state_t - Client-side protocol states
*
* These states represent the phases of file transmission from client to server.
* The client progresses through these states sequentially, with possible loops
* between DATA_TRANSFER and DATA_WAIT_ACK for each chunk.
*
* STATE DIAGRAM:
*
* IDLE
* ↓
* START_SENT ──────┐
* ↓ │ (timeout/retry)
* DATA_TRANSFER │
* ↓ │
* DATA_WAIT_ACK ───┘
* ↓ (ACK received)
* [Loop back to DATA_TRANSFER if more chunks]
* ↓ (all chunks sent)
* END_SENT ────────┐
* ↓ │ (timeout/retry)
* COMPLETED │
* ↓
* ERROR/ABORT (from any state on failure)
*/
typedef enum {
/*
* CLIENT_IDLE - Initial state before transfer begins
*
* Entry: When client_sm_init() is called
* Exit: When file is opened and ready to send
* Next: CLIENT_START_SENT
*
* Activities in this state:
* - Open file for reading
* - Generate session ID
* - Prepare metadata (filename, file size, IV, salt)
*/
CLIENT_IDLE,
/*
* CLIENT_START_SENT - START packet sent, waiting for ACK
*
* Entry: After sending START packet with file metadata
* Exit: When START-ACK received or timeout/max retries
* Next: CLIENT_DATA_TRANSFER (success), CLIENT_ERROR (failure)
*
* Activities in this state:
* - Wait for START-ACK from server
* - Retry sending START on timeout (with exponential backoff)
* - Check retry count against MAX_RETRIES
*
* Timeout behavior: Retry up to MAX_RETRIES times before failing
*/
CLIENT_START_SENT,
/*
* CLIENT_DATA_TRANSFER - Sending DATA packet
*
* Entry: After START-ACK received, or after previous DATA-ACK
* Exit: After DATA packet sent
* Next: CLIENT_DATA_WAIT_ACK
*
* Activities in this state:
* - Read next chunk from file
* - Encrypt chunk
* - Create DATA packet with IFTP header
* - Send DATA packet
* - Increment sequence number
*/
CLIENT_DATA_TRANSFER,
/*
* CLIENT_DATA_WAIT_ACK - Waiting for ACK after DATA packet
*
* Entry: After DATA packet sent
* Exit: When DATA-ACK received, NACK received, or timeout
* Next: CLIENT_DATA_TRANSFER (more chunks), CLIENT_END_SENT (all sent),
* CLIENT_DATA_WAIT_ACK (retry on timeout)
*
* Activities in this state:
* - Wait for ACK matching current sequence number
* - Retry sending DATA on timeout (with exponential backoff)
* - Check retry count against MAX_RETRIES
* - Check if more chunks remain to send
*
* Timeout behavior: Retry same DATA packet up to MAX_RETRIES times
* NACK handling: Resend DATA immediately (counts as retry)
*/
CLIENT_DATA_WAIT_ACK,
/*
* CLIENT_END_SENT - END packet sent, waiting for final ACK
*
* Entry: After all DATA packets acknowledged
* Exit: When END-ACK received or timeout/max retries
* Next: CLIENT_COMPLETED (success), CLIENT_ERROR (failure)
*
* Activities in this state:
* - Wait for END-ACK from server
* - Retry sending END on timeout
* - Check retry count against MAX_RETRIES
*
* Timeout behavior: Retry up to MAX_RETRIES times before failing
*/
CLIENT_END_SENT,
/*
* CLIENT_COMPLETED - Transfer completed successfully
*
* Entry: After END-ACK received
* Exit: None (terminal state)
* Next: None
*
* Activities in this state:
* - Close file
* - Print transfer statistics
* - Clean up resources
*
* This is a terminal success state.
*/
CLIENT_COMPLETED,
/*
* CLIENT_ERROR - Transfer failed due to error
*
* Entry: From any state on unrecoverable error
* Exit: None (terminal state)
* Next: None
*
* Causes:
* - Max retries exceeded (MAX_RETRIES = 5)
* - File I/O error (disk read failure)
* - Network error (cannot send packets)
* - Protocol error (invalid packet from server)
*
* This is a terminal failure state.
*/
CLIENT_ERROR,
/*
* CLIENT_ABORT - Transfer aborted by user
*
* Entry: From any state on user interrupt (SIGINT)
* Exit: None (terminal state)
* Next: None
*
* Causes:
* - User presses Ctrl+C
* - User sends SIGTERM
* - Application shutdown requested
*
* This is a terminal state, resources should be cleaned up gracefully.
*/
CLIENT_ABORT
} client_state_t;
/*
* ==================================================================================
* SERVER STATES
* ==================================================================================
*/
/*
* server_state_t - Server-side protocol states
*
* These states represent the phases of file reception from client.
* The server remains in LISTENING until a START packet arrives, then
* progresses through reception states.
*
* STATE DIAGRAM:
*
* LISTENING
* ↓ (START received)
* SESSION_INIT
* ↓ (START-ACK sent)
* RECEIVING_DATA
* ↓ (DATA received)
* DATA_ACK_SENT
* ↓ (more DATA expected)
* RECEIVING_DATA ──┐
* ↓ │ (loop for each DATA packet)
* DATA_ACK_SENT ───┘
* ↓ (END received)
* SESSION_CLOSING
* ↓ (END-ACK sent)
* COMPLETED
*
* ERROR/TIMEOUT (from any state on failure)
*/
typedef enum {
/*
* SERVER_LISTENING - Waiting for START packet from any client
*
* Entry: When server_sm_init() is called, or after previous session completes
* Exit: When valid START packet received
* Next: SERVER_SESSION_INIT
*
* Activities in this state:
* - Poll for incoming ICMP packets (non-blocking)
* - Validate packet magic number (0xDEADBEEF)
* - Check packet type (must be START)
* - Extract metadata from START packet
*
* Timeout: No timeout in this state (server waits indefinitely)
*/
SERVER_LISTENING,
/*
* SERVER_SESSION_INIT - New session initialized, sending START-ACK
*
* Entry: After valid START packet received
* Exit: After START-ACK sent
* Next: SERVER_RECEIVING_DATA
*
* Activities in this state:
* - Create new server session structure
* - Extract metadata (filename, file_size, IV, salt)
* - Open output file (basename only for security)
* - Initialize crypto engine for decryption
* - Send START-ACK to client
* - Set expected_seq to 0 for first DATA packet
*
* Error handling: Transition to SERVER_ERROR if file cannot be created
*/
SERVER_SESSION_INIT,
/*
* SERVER_RECEIVING_DATA - Waiting for DATA packet
*
* Entry: After START-ACK sent, or after previous DATA-ACK sent
* Exit: When valid DATA packet received or timeout
* Next: SERVER_DATA_ACK_SENT (DATA received), SERVER_TIMEOUT (timeout)
*
* Activities in this state:
* - Wait for DATA packet with expected sequence number
* - Validate sequence number (must match expected_seq)
* - Validate CRC32 checksum
* - Decrypt data chunk
* - Write chunk to file
*
* Timeout: If no packet received within idle_timeout (default 30s),
* transition to SERVER_TIMEOUT
*/
SERVER_RECEIVING_DATA,
/*
* SERVER_DATA_ACK_SENT - ACK sent for received DATA packet
*
* Entry: After valid DATA packet received and written
* Exit: Immediately after ACK sent
* Next: SERVER_RECEIVING_DATA (more DATA expected),
* SERVER_SESSION_CLOSING (END packet received)
*
* Activities in this state:
* - Send DATA-ACK with acknowledged sequence number
* - Increment expected_seq for next DATA packet
* - Update transfer statistics
*
* This is a transient state - transitions immediately to RECEIVING_DATA
*/
SERVER_DATA_ACK_SENT,
/*
* SERVER_SESSION_CLOSING - END packet received, sending final ACK
*
* Entry: After valid END packet received
* Exit: After END-ACK sent
* Next: SERVER_COMPLETED
*
* Activities in this state:
* - Verify all expected data received (bytes_written == file_size)
* - Finalize file (close handle)
* - Send END-ACK to client
* - Clean up session resources
*/
SERVER_SESSION_CLOSING,
/*
* SERVER_COMPLETED - Session completed successfully
*
* Entry: After END-ACK sent
* Exit: None (terminal state for this session)
* Next: SERVER_LISTENING (for next session)
*
* Activities in this state:
* - Print transfer statistics
* - Clean up crypto resources
* - Reset to LISTENING for next client
*
* This is a terminal success state for the current session.
* Server can return to LISTENING to handle next client.
*/
SERVER_COMPLETED,
/*
* SERVER_ERROR - Session failed due to error
*
* Entry: From any state on unrecoverable error
* Exit: None (terminal state for this session)
* Next: SERVER_LISTENING (after cleanup)
*
* Causes:
* - File write error (disk full, permissions)
* - Decryption failure (wrong key, corrupted data)
* - Protocol violation (invalid packet, wrong session ID)
* - Checksum mismatch (data corruption)
*
* This is a terminal failure state. Server should clean up and return
* to LISTENING for next client.
*/
SERVER_ERROR,
/*
* SERVER_TIMEOUT - Session timed out waiting for client
*
* Entry: From RECEIVING_DATA when idle_timeout exceeded
* Exit: None (terminal state for this session)
* Next: SERVER_LISTENING (after cleanup)
*
* Causes:
* - Client crashed or network disconnected
* - Client waiting for ACK that was lost
* - Network partition
*
* Server should clean up incomplete file and return to LISTENING.
*/
SERVER_TIMEOUT
} server_state_t;
/*
* ==================================================================================
* PROTOCOL EVENTS
* ==================================================================================
*/
/*
* protocol_event_t - Events that trigger state machine transitions
*
* These events are generated by the protocol engine based on network activity,
* timeouts, file I/O results, and user actions.
*/
typedef enum {
/*
* EVENT_TIMEOUT - Timeout occurred waiting for response
*
* Client: Triggers retry of last packet sent (START, DATA, or END)
* Server: Triggers transition to SERVER_TIMEOUT if in RECEIVING_DATA
*
* Event data: NULL
*/
EVENT_TIMEOUT,
/*
* EVENT_PACKET_RECEIVED - Valid packet received from peer
*
* Client: START-ACK, DATA-ACK, or END-ACK received
* Server: START, DATA, or END packet received
*
* Event data: Pointer to received packet (iftp_header_t*)
*/
EVENT_PACKET_RECEIVED,
/*
* EVENT_PACKET_SENT - Packet successfully sent to peer
*
* Client: START, DATA, or END packet sent
* Server: ACK packet sent
*
* Event data: Pointer to sent packet (iftp_header_t*)
*/
EVENT_PACKET_SENT,
/*
* EVENT_ACK_RECEIVED - ACK packet received matching expected sequence
*
* Client: Triggers transition from WAIT_ACK to next state
* Server: Not used
*
* Event data: Pointer to ACK packet (iftp_header_t*)
*/
EVENT_ACK_RECEIVED,
/*
* EVENT_ERROR - Unrecoverable error occurred
*
* Triggers transition to ERROR state from any state.
*
* Event data: Pointer to error code (error_code_t*)
*/
EVENT_ERROR,
/*
* EVENT_FILE_EOF - End of file reached during read
*
* Client: All chunks sent, transition to END_SENT
* Server: Not used
*
* Event data: NULL
*/
EVENT_FILE_EOF,
/*
* EVENT_USER_ABORT - User requested abort (Ctrl+C, SIGTERM)
*
* Triggers transition to ABORT state from any state.
*
* Event data: NULL
*/
EVENT_USER_ABORT,
/*
* EVENT_RETRY_EXCEEDED - Maximum retry count exceeded
*
* Triggers transition to ERROR state when retries exhausted.
*
* Event data: NULL
*/
EVENT_RETRY_EXCEEDED
} protocol_event_t;
/*
* ==================================================================================
* CLIENT STATE MACHINE STRUCTURE
* ==================================================================================
*/
/*
* client_state_machine_t - Client state tracking and control
*
* This structure maintains all state for the client-side protocol engine.
* It tracks the current protocol phase, retry logic, sequence numbers, and
* timing information.
*
* LIFECYCLE:
* 1. Initialized by client_sm_init()
* 2. Transitions managed by client_sm_transition()
* 3. Timeouts checked by client_sm_check_timeout()
* 4. Events handled by client_sm_handle_event()
* 5. Reset by client_sm_reset() if retry needed
*/
typedef struct {
/*
* current_state - Current protocol state
*
* One of the client_state_t enum values.
* Modified by client_sm_transition() only.
*/
client_state_t current_state;
/*
* previous_state - Previous state before current
*
* Used for error recovery and debugging.
* Can transition back to previous_state if error is recoverable.
*/
client_state_t previous_state;
/*
* current_seq - Current sequence number for packets
*
* Incremented after each DATA packet sent.
* Used in IFTP header seq_num field.
* Range: 0 to UINT32_MAX (wraps around)
*
* Sequence number lifecycle:
* - START packet: seq_num = 0
* - DATA packet 1: seq_num = 1
* - DATA packet 2: seq_num = 2
* - ...
* - END packet: seq_num = (last DATA seq_num + 1)
*/
uint32_t current_seq;
/*
* ack_expected - Expected sequence number in ACK response
*
* When waiting for ACK, this holds the sequence number we expect
* to see in the ACK packet. Must match current_seq.
*/
uint32_t ack_expected;
/*
* retry_count - Number of retries attempted for current packet
*
* Incremented each time a timeout occurs and packet is resent.
* Reset to 0 when ACK received.
* Compared against MAX_RETRIES (5) to detect failure.
*
* If retry_count >= MAX_RETRIES:
* - Generate EVENT_RETRY_EXCEEDED
* - Transition to CLIENT_ERROR
*/
uint32_t retry_count;
/*
* state_entry_time - When current state was entered (Unix timestamp)
*
* Set by client_sm_transition() using time(NULL).
* Used to calculate:
* - Time spent in current state: time(NULL) - state_entry_time
* - State duration statistics
*/
time_t state_entry_time;
/*
* last_activity - Last time any network activity occurred
*
* Updated when:
* - Packet sent
* - Packet received
*
* Used to detect idle sessions and calculate overall session duration.
*/
time_t last_activity;
/*
* timeout_seconds - Timeout duration for current state
*
* How long to wait before considering state timed out.
* Compared against: time(NULL) - state_entry_time
*
* Exponential backoff:
* - Retry 0: 2 seconds (INITIAL_TIMEOUT)
* - Retry 1: 4 seconds
* - Retry 2: 8 seconds
* - Retry 3: 16 seconds
* - Retry 4: 30 seconds (MAX_TIMEOUT)
* - Retry 5: Fail (MAX_RETRIES exceeded)
*
* Formula: timeout = min(INITIAL_TIMEOUT * (2 ^ retry_count), MAX_TIMEOUT)
*/
int timeout_seconds;
/*
* session_id - Unique session identifier (16-bit)
*
* Generated by client_sm_init() using utils_generate_session_id()
* (cryptographically secure random number).
*
* Used in all IFTP packets to distinguish this transfer from others.
* Server uses this to track which session a packet belongs to.
*/
uint16_t session_id;
} client_state_machine_t;
/*
* ==================================================================================
* SERVER STATE MACHINE STRUCTURE
* ==================================================================================
*/
/*
* server_state_machine_t - Server state tracking and control
*
* This structure maintains all state for the server-side protocol engine.
* It tracks the current reception phase, expected sequence numbers, and
* session timeout information.
*
* LIFECYCLE:
* 1. Initialized by server_sm_init()
* 2. Transitions managed by server_sm_transition()
* 3. Timeouts checked by server_sm_check_timeout()
* 4. Events handled by server_sm_handle_event()
* 5. Reset by server_sm_reset() after session completes
*/
typedef struct {
/*
* current_state - Current protocol state
*
* One of the server_state_t enum values.
* Modified by server_sm_transition() only.
*/
server_state_t current_state;
/*
* previous_state - Previous state before current
*
* Used for debugging and state transition validation.
*/
server_state_t previous_state;
/*
* expected_seq - Expected sequence number in next DATA packet
*
* Initialized to 0 when START packet received.
* Incremented after each valid DATA packet.
*
* Used to:
* - Validate received DATA packet has correct seq_num
* - Detect duplicate packets (seq_num < expected_seq)
* - Detect skipped packets (seq_num > expected_seq)
*/
uint32_t expected_seq;
/*
* last_ack_sent - Sequence number of last ACK sent
*
* Used to detect:
* - Duplicate ACKs (can happen if client didn't receive ACK)
* - ACK retransmission needed
*/
uint32_t last_ack_sent;
/*
* state_entry_time - When current state was entered
*
* Set by server_sm_transition() using time(NULL).
* Used to calculate time spent in current state.
*/
time_t state_entry_time;
/*
* last_activity - Last time packet received from client
*
* Updated when valid packet received from client.
* Used to detect client failure:
* If (time(NULL) - last_activity) > idle_timeout:
* Transition to SERVER_TIMEOUT
*/
time_t last_activity;
/*
* idle_timeout - Maximum idle time before timeout (seconds)
*
* Default: SESSION_TIMEOUT (30 seconds)
*
* If no packet received from client within this time, assume:
* - Client crashed
* - Network partition
* - All retries exhausted on client side
*
* Server transitions to SERVER_TIMEOUT and cleans up session.
*/
int idle_timeout;
/*
* session_id - Session identifier from client
*
* Extracted from START packet.
* Used to validate that DATA/END packets belong to this session.
*
* Packets with different session_id are ignored or trigger
* new session creation (if in LISTENING state).
*/
uint16_t session_id;
} server_state_machine_t;
/*
* ==================================================================================
* CORE STATE MACHINE FUNCTIONS
* ==================================================================================
*/
/*
* client_sm_init - Initialize client state machine
*
* Sets up initial state for new file transfer session:
* - current_state = CLIENT_IDLE
* - current_seq = 0
* - retry_count = 0
* - timeout_seconds = INITIAL_TIMEOUT (2)
* - Generates session_id using utils_generate_session_id()
*
* @param sm: State machine structure to initialize
* @param session_id: Session ID to use (0 = generate new ID)
*/
void client_sm_init(client_state_machine_t *sm, uint16_t session_id);
/*
* server_sm_init - Initialize server state machine
*
* Sets up initial state for server listening mode:
* - current_state = SERVER_LISTENING
* - expected_seq = 0
* - idle_timeout = SESSION_TIMEOUT (30)
*
* @param sm: State machine structure to initialize
*/
void server_sm_init(server_state_machine_t *sm);
/*
* client_sm_transition - Transition client to new state
*
* Validates transition is legal, updates state, and records timing information.
*
* @param sm: Client state machine
* @param new_state: Desired next state
* @param reason: Human-readable transition reason (for debugging)
* @return: 0 on success, -1 if transition invalid
*/
int client_sm_transition(client_state_machine_t *sm, client_state_t new_state, const char *reason);
/*
* server_sm_transition - Transition server to new state
*
* Validates transition is legal, updates state, and records timing information.
*
* @param sm: Server state machine
* @param new_state: Desired next state
* @param reason: Human-readable transition reason (for debugging)
* @return: 0 on success, -1 if transition invalid
*/
int server_sm_transition(server_state_machine_t *sm, server_state_t new_state, const char *reason);
/*
* client_sm_check_timeout - Check if client state has timed out
*
* Compares (current_time - state_entry_time) against timeout_seconds.
*
* @param sm: Client state machine
* @return: 1 if timed out, 0 if not timed out
*/
int client_sm_check_timeout(client_state_machine_t *sm);
/*
* server_sm_check_timeout - Check if server session has timed out
*
* Compares (current_time - last_activity) against idle_timeout.
*
* @param sm: Server state machine
* @return: 1 if timed out, 0 if not timed out
*/
int server_sm_check_timeout(server_state_machine_t *sm);
/*
* client_sm_handle_event - Process event and transition accordingly
*
* Event-driven state machine update:
* - Validates event is valid for current state
* - Performs appropriate transition
* - Updates sequence numbers, retry counts
*
* @param sm: Client state machine
* @param event: Event that occurred
* @param event_data: Event-specific data (packet, error code, etc.)
* @return: 0 on success, -1 on error
*/
int client_sm_handle_event(client_state_machine_t *sm, protocol_event_t event, void *event_data);
/*
* server_sm_handle_event - Process event and transition accordingly
*
* @param sm: Server state machine
* @param event: Event that occurred
* @param event_data: Event-specific data
* @return: 0 on success, -1 on error
*/
int server_sm_handle_event(server_state_machine_t *sm, protocol_event_t event, void *event_data);
/*
* ==================================================================================
* UTILITY FUNCTIONS
* ==================================================================================
*/
/*
* client_state_name - Get human-readable name for client state
* @return: String name like "CLIENT_IDLE", "CLIENT_DATA_TRANSFER", etc.
*/
const char *client_state_name(client_state_t state);
/*
* server_state_name - Get human-readable name for server state
* @return: String name like "SERVER_LISTENING", "SERVER_RECEIVING_DATA", etc.
*/
const char *server_state_name(server_state_t state);
/*
* event_name - Get human-readable name for protocol event
* @return: String name like "EVENT_TIMEOUT", "EVENT_ACK_RECEIVED", etc.
*/
const char *event_name(protocol_event_t event);
/*
* ==================================================================================
* ENHANCED STATE MACHINE FUNCTIONS
* ==================================================================================
*/
/*
* client_sm_is_valid_transition - Check if state transition is valid
*
* Validates state machine invariants. Prevents illegal transitions like:
* - CLIENT_IDLE → CLIENT_END_SENT (skipping DATA phase)
* - CLIENT_COMPLETED → CLIENT_DATA_TRANSFER (no restart from completed)
*
* @return: 1 if transition valid, 0 if invalid
*/
int client_sm_is_valid_transition(client_state_t current, client_state_t next);
/*
* server_sm_is_valid_transition - Check if state transition is valid
* @return: 1 if transition valid, 0 if invalid
*/
int server_sm_is_valid_transition(server_state_t current, server_state_t next);
/*
* client_sm_can_recover - Check if error is recoverable
*
* Determines if client can retry after error:
* - retry_count < MAX_RETRIES: recoverable
* - retry_count >= MAX_RETRIES: not recoverable
*
* @return: 1 if can recover, 0 if cannot
*/
int client_sm_can_recover(const client_state_machine_t *sm);
/*
* server_sm_can_recover - Check if server error is recoverable
* @return: 1 if can recover, 0 if cannot
*/
int server_sm_can_recover(const server_state_machine_t *sm);
/*
* client_sm_reset - Reset state machine for retry
*
* Resets to IDLE state while preserving session_id.
* Used for retry after recoverable error.
*/
void client_sm_reset(client_state_machine_t *sm);
/*
* server_sm_reset - Reset state machine to LISTENING
*
* Used after session completion or error to prepare for next client.
*/
void server_sm_reset(server_state_machine_t *sm);
/*
* client_sm_handle_timeout_with_backoff - Handle timeout with exponential backoff
*
* Increments retry_count and calculates new timeout:
* timeout = min(INITIAL_TIMEOUT * (2 ^ retry_count), MAX_TIMEOUT)
*
* @return: 0 if retry possible, -1 if max retries exceeded
*/
int client_sm_handle_timeout_with_backoff(client_state_machine_t *sm);
/*
* client_sm_get_statistics - Get state machine statistics
*
* Formats statistics string with:
* - Current state and time in state
* - Retry count
* - Sequence number
* - Session ID
*
* @param sm: Client state machine
* @param buffer: Output buffer for statistics string
* @param buffer_size: Size of output buffer
* @return: Number of bytes written, or -1 on error
*/
int client_sm_get_statistics(const client_state_machine_t *sm, char *buffer, size_t buffer_size);
/*
* server_sm_get_statistics - Get state machine statistics
* @return: Number of bytes written, or -1 on error
*/
int server_sm_get_statistics(const server_state_machine_t *sm, char *buffer, size_t buffer_size);
#endif /* STATE_MACHINE_H */