You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
4.6 KiB
164 lines
4.6 KiB
// etcp.h - Extended Transmission Control Protocol |
|
#ifndef ETCP_H |
|
#define ETCP_H |
|
|
|
#include <stdint.h> |
|
#include <stddef.h> |
|
#include "ll_queue.h" |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
// Forward declarations |
|
typedef struct epkt epkt_t; |
|
|
|
// Callback type for sending packets via UDP |
|
typedef void (*etcp_tx_callback_t)(epkt_t* epkt, uint8_t* pkt, uint16_t len, void* arg); |
|
|
|
// Main ETCP structure |
|
struct epkt { |
|
// Queues |
|
ll_queue_t* tx_queue; // Queue of data to send |
|
ll_queue_t* output_queue; // Output queue (reassembled data) |
|
|
|
// Received packets sorted linked list |
|
struct rx_packet* rx_list; |
|
|
|
// Sent packets (for retransmission) |
|
struct sent_packet* sent_list; |
|
|
|
// Metrics |
|
uint16_t rtt_last; // Last RTT (timebase 0.1us) |
|
uint16_t rtt_avg_10; // Average RTT last 10 packets |
|
uint16_t rtt_avg_100; // Average RTT last 100 packets |
|
uint16_t jitter; // Jitter (averaged) |
|
uint16_t bandwidth; // Current bandwidth (bytes per timebase) |
|
uint32_t bytes_sent_total; // Total bytes sent |
|
uint16_t last_sent_timestamp; // Timestamp of last sent packet |
|
uint32_t bytes_allowed; // Calculated bytes allowed to send |
|
|
|
// State |
|
uint16_t next_tx_id; // Next ID for transmission |
|
uint16_t last_rx_id; // Last received ID (for ACK) |
|
uint16_t last_delivered_id; // Last delivered to output_queue ID |
|
|
|
// Timers |
|
void* next_tx_timer; // Timer for next transmission |
|
void* retransmit_timer; // Timer for retransmissions |
|
|
|
// Callback |
|
etcp_tx_callback_t tx_callback; |
|
void* tx_callback_arg; |
|
|
|
// RTT history for averaging |
|
uint16_t rtt_history[100]; |
|
uint8_t rtt_history_idx; |
|
uint8_t rtt_history_count; |
|
|
|
// Pending ACKs |
|
uint16_t pending_ack_ids[32]; |
|
uint16_t pending_ack_timestamps[32]; |
|
uint8_t pending_ack_count; |
|
|
|
// Pending retransmission requests |
|
uint16_t pending_retransmit_ids[32]; |
|
uint8_t pending_retransmit_count; |
|
|
|
// Window management |
|
uint32_t unacked_bytes; // Number of bytes sent but not yet acknowledged |
|
uint32_t window_size; // Current window size in bytes (calculated) |
|
uint16_t last_acked_id; // Last acknowledged packet ID |
|
uint16_t last_rx_ack_id; // Latest received ACK ID from receiver |
|
uint16_t retrans_timer_period; // Current retransmission timer period (timebase) |
|
uint16_t next_retrans_time; // Time of next retransmission check |
|
uint8_t window_blocked; // Flag: transmission blocked by window limit |
|
}; |
|
|
|
// API Functions |
|
|
|
/** |
|
* @brief Initialize new ETCP instance |
|
* @return Pointer to new instance or NULL on error |
|
*/ |
|
epkt_t* etcp_init(void); |
|
|
|
/** |
|
* @brief Free ETCP instance and all associated resources |
|
* @param epkt Instance to free |
|
*/ |
|
void etcp_free(epkt_t* epkt); |
|
|
|
/** |
|
* @brief Set callback for sending packets via UDP |
|
* @param epkt ETCP instance |
|
* @param cb Callback function |
|
* @param arg User argument passed to callback |
|
*/ |
|
void etcp_set_callback(epkt_t* epkt, etcp_tx_callback_t cb, void* arg); |
|
|
|
/** |
|
* @brief Process received UDP packet |
|
* @param epkt ETCP instance |
|
* @param pkt Packet data |
|
* @param len Packet length |
|
* @return 0 on success, -1 on error |
|
*/ |
|
int etcp_rx_input(epkt_t* epkt, uint8_t* pkt, uint16_t len); |
|
|
|
/** |
|
* @brief Get total number of packets waiting in transmission queues |
|
* @param epkt ETCP instance |
|
* @return Number of packets |
|
*/ |
|
int etcp_tx_queue_size(epkt_t* epkt); |
|
|
|
/** |
|
* @brief Put data into transmission queue |
|
* @param epkt ETCP instance |
|
* @param data Data to send |
|
* @param len Data length |
|
* @return 0 on success, -1 on error |
|
*/ |
|
int etcp_tx_put(epkt_t* epkt, uint8_t* data, uint16_t len); |
|
|
|
/** |
|
* @brief Get output queue for reading received data |
|
* @param epkt ETCP instance |
|
* @return Pointer to output queue (ll_queue_t*) |
|
*/ |
|
ll_queue_t* etcp_get_output_queue(epkt_t* epkt); |
|
|
|
/** |
|
* @brief Set bandwidth limit |
|
* @param epkt ETCP instance |
|
* @param bandwidth Bytes per timebase (0.1us) |
|
*/ |
|
void etcp_set_bandwidth(epkt_t* epkt, uint16_t bandwidth); |
|
|
|
/** |
|
* @brief Update window size based on current RTT and bandwidth |
|
* @param epkt ETCP instance |
|
* Window size = RTT * bandwidth * 2 (bytes in flight) |
|
*/ |
|
void etcp_update_window(epkt_t* epkt); |
|
|
|
/** |
|
* @brief Get current RTT |
|
* @param epkt ETCP instance |
|
* @return RTT in timebase units |
|
*/ |
|
uint16_t etcp_get_rtt(epkt_t* epkt); |
|
|
|
/** |
|
* @brief Get current jitter |
|
* @param epkt ETCP instance |
|
* @return Jitter in timebase units |
|
*/ |
|
uint16_t etcp_get_jitter(epkt_t* epkt); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#endif // ETCP_H
|
|
|