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

// 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