#define TCP_MAX_PORT	65535

#define TCP_SRTT_ALPHA	0.9

#define TCP_RTO_BETA	2
#define TCP_RTO_MIN		0.2
#define TCP_RTO_MAX		10

#define TCP_WINDOW_SIZE	8192

#define TCP_MSS			536 // Max Segment Size default

#define TCP_TIMEOUT		5000

#define TCP_STATE_CLOSED		0
#define TCP_STATE_LISTEN		1
#define TCP_STATE_SYN_SENT		2
#define TCP_STATE_SYN_RECEIVED	3
#define TCP_STATE_ESTABLISHED	4
#define TCP_STATE_FIN_WAIT1		5
#define TCP_STATE_FIN_WAIT2		6
#define TCP_STATE_CLOSE_WAIT	7
#define TCP_STATE_CLOSING		8
#define TCP_STATE_LAST_ACK		9
#define TCP_STATE_TIME_WAIT		10

// TCP header flags. Test with Bt(), e.g. Bt(&flags, TCPf_RST)
#define TCPf_FIN	0
#define TCPf_SYN	1
#define TCPf_RST	2
//#define TCPf_PSH	3 // most stacks don't implement PUSH.
#define TCPf_ACK	4
//#define TCPf_URG	5 // most stacks don't implement URGENT.

#define TCPF_FIN	(1 << TCPf_FIN)
#define TCPF_SYN	(1 << TCPf_SYN)
#define TCPF_RST	(1 << TCPf_RST)
//#define TCPF_PSH	(1 << TCPf_PSH) // most stacks don't implement PUSH.
#define TCPF_ACK	(1 << TCPf_ACK)
//#define TCPF_URG	(1 << TCPf_URG) // most stacks don't implement URGENT.


class CTCPAckQueue:CQueue
{
	F64 time_sent;
	U32 retries;
	U32 start_seq_num;
	U32 end_seq_num;

	U32 tcp_packet_size;	// Size of memory allocation of U8* tcp_packet.
	U8 *tcp_packet;			// Memory location of entire TCP Header + Data Payload.
};

// stores packet data of incoming connect() requests,
// local accept() will search queue for pending connections,
// and use this data to send out notification connection was accepted.
class CTCPAcceptQueue:CQueue
{
	U32 segment_seq_num;
	U32 ipv4_address;
	U16 port;
};

class CTCPSocket
{
	CSocket					*socket;
	U8						 state;
	U64						 timeout; // timeout for socket calls. Initialized 0: non-blocking.

	CSocketAddressStorage	 source_address;	// based on ->family, cast or assign to a var as IPV4/IPV6 CSocketAddress
	CSocketAddressStorage	 destination_address;

	CTCPAckQueue			*ack_queue; // Sent TCP packets awaiting an ACK collect here to be retransmitted. CQueue head.

	U64						 accept_queue_limit;
	CTCPAcceptQueue			*accept_queue;

	U32						 max_segment_size;

	U32						 first_unacked_seq; // SEQ number of first unacknowledged octet
	U32						 next_send_seq_num;
	U32						 next_recv_seq_num;
	F64						 srtt; // Smoothed Round-Trip Time
	F64						 connection_time;

	U32						 receive_window;// allowed # of unacknowledged incoming octets
	U32						 send_window;	// allowed # of unacknowledged outgoing octets

	I64						 write_position; // position in RX buffer to write incoming octets
	I64						 read_position;  // position in RX buffer Socket calls have read up to
	I64						 receive_buffer_size;
	U8						*receive_buffer;
};


class CTCPTreeQueue:CQueue
{
	CTCPSocket		*socket;
};

class CTCPTreeNode:CBST
{
	CTCPTreeQueue	*queue;
};

class CTCPRepEntry:CQueue
{
	CTCPTreeNode *node;
};


class CTCPHeader
{
	U16	source_port;
	U16	destination_port;
	U32 seq_num;
	U32	ack_num;
	U8	data_offset;
	U8	flags;
	U16	window_size;
	U16	checksum;
	U16	urgent_pointer;
};

class CTCPPseudoHeader
{
	U32 source_address;
	U32 destination_address;
	U8	zeros;
	U8	protocol;
	U16	tcp_length; // length of TCP headers & payload
};

class CTCPGlobals
{

	CTCPTreeNode	*bound_socket_tree;
	U16				 next_source_port;

} tcp_globals;

