// H-soubor k souboru tcp.c
#ifndef _TCP_IP_H
#define _TCP_IP_H

#include "stdint.h"
#include "misc.h"

// definice konstant
#define TCP_BUFFER_SIZE			1500
#define TCP_MAX_DATA_SIZE		1400
#define MY_TTL					128		// zivotnost paketu -  paket muze projit maximalne timto poctem smerovacu

// Definice indexu v poli pro pocitani timeoutu
#define TCP_TIMEOUTID_HANDSHAKE		0
#define TCP_TIMEOUTID_CONNECTION	1
#define TCP_TIMEOUTID_ACK			2
#define TCP_TIMEOUTID_FINWAIT2		3

#define TCP_TIMEOUT_COUNT			4				// Pocet timeoutu ktere bude system kontrolovat

#define TCP_SEND_TRY_COUNT			3				// Pocet pokusu odeslat paket po vcasnem neobdrzeni ACK

// Definice konstant pro potreby check sumu
#define IP_PROTO_ICMP_V 	1
#define IP_PROTO_TCP_V 		6


// Definice 'len' - poctu byte pres ktere se pocita checksum
#define TCP_Checksum_len_NoOpt_NoData		20
#define TCP_Checksum_len_Opt_NoData			20+4	// 20... hlavicka bez options, 4... options
#define TCP_Checksum_len_NoOpt_Data			20		// + delka dat

// Definice delek hlavicek
#define TCP_Header_lenNoOption	20			// Delka hlavicky TCP paketu v bytech je 20 bytu (minimum, bez Options casti)
#define TCP_Header_lenOption	24			// Delka hlavicky TCP paketu v bytech je 20+4=24 bytu (s Options casti)
#define TCP_Header_lenNoOption2	(20/4)<<4	// Delka hlavicky TCP paketu v jednotce pocet 32 bitovych slov je 20 bytu (minimum, bez Options casti)
#define TCP_Header_lenOption2	(24/4)<<4	// Delka hlavicky TCP paketu v jednotce pocet 32 bitovych slov je 20+4=24 bytu (s Options casti)

// Definice offsetu polozek hlavicky v TCP paketu
#define OFFSET_TCP_Header			0x22	// offset v bytech
#define OFFSET_TCP_SourcePort		OFFSET_TCP_Header + 0x00
#define OFFSET_TCP_DestPort			OFFSET_TCP_Header + 2
#define OFFSET_TCP_SEQ				OFFSET_TCP_Header + 4	// celkem 32 bit = 4 byte
#define OFFSET_TCP_ACK				OFFSET_TCP_Header + 8	// celken 32 bit = 4 byte
#define OFFSET_TCP_DataOffset		OFFSET_TCP_Header + 12	// Maska 00001111 = 0x0F
#define OFFSET_TCP_Flags			OFFSET_TCP_Header + 13
#define OFFSET_TCP_WindowSize		OFFSET_TCP_Header + 14	// celkem 16 bit = 2 byte
#define OFFSET_TCP_CheckSum			OFFSET_TCP_Header + 16	// celkem 16 bit = 2 byte
#define OFFSET_TCP_UrgentPointer	OFFSET_TCP_Header + 18	// celkem 16 bit = 2 byte
#define OFFSET_TCP_Options			OFFSET_TCP_Header + 20
#define OFFSET_TCP_Options_Len		OFFSET_TCP_Header + 21
#define OFFSET_TCP_Options_Data		OFFSET_TCP_Header + 22
#define OFFSET_TCP_Data				OFFSET_TCP_Header + 20

#define TCP_NoOP			0x01	

// TCP Flags defined in RFC
#define TCP_FIN     0x01		// Oznacuje konec prenosu
#define TCP_SYN     0x02		// Priznak synchronizace
#define TCP_RST     0x04		// Priznak resetu
#define TCP_PSH     0x08		// Priznak PUSH
#define TCP_ACK     0x10		// Priznak ACK
#define TCP_URG     0x20		// priznak URGENT

// Definice stavu TCP stavoveho automatu
#define TCP_STATE_CLOSED			0			// Spojeni uzavreno
#define TCP_STATE_LISTEN			1			// Spojeni nasloucha
#define TCP_STATE_ESTABLISHED		2			// Spojeni navazano - lze vymenovat uzitecna data			
#define TCP_STATE_CLOSE_WAIT		3			// Odeslan pozadavek na ukonceni spojeni a cekani na jeho potvrzeni
#define TCP_STATE_LAST_ACK			4			// Odeslano posledni potvrzeni a uzavreni spojeni
#define TCP_STATE_SYN_RECEIVED		5			// Obdrzena zadost o spojeni (synchronizaci)
#define TCP_STATE_SYN_SEND			6			// OZaslana zadost o spojeni (synchronizaci)
#define TCP_STATE_FIN_WAIT_1		7			// Cekani serveru na potvrzeni konce spojeni aplikaci (napriklad HTTP serverem)
#define TCP_STATE_FIN_WAIT_2		8			// Cekani klienta na potvrzeni konce spojeni od serveru
#define TCP_STATE_TIME_WAIT			9			// Cekani na obdrzeni potvrzeni (ACK) od protistrany ze prijala odeslana data vporadku)
#define TCP_DATA_ARIVED				10			// Prichozi paket obsahuje uzitecna data

// definice struktur pro ukladani dat v RAM
/*	Struktura TCP hlavikcy:
		- 16b ... zdrojovy port
		- 16b ... cilovy port
		- 32b ... sequence number (SEQ)
		- 32b ... acknowledgement number ACK
		- 4b .... data offset
		- 3b .... reserved
		- 9b .... priznaky
		   |- 1b ... NS - nenastaven (rezervovano)
		   |- 1b ... CWR
		   |- 1b ... ECE
		   |- 1b ... URG - v urgent pointer poli platna hodnota
		   |- 1b ... ACK - v ACK je platna hodnota ke kontrole
		   |- 1b ... PSH - Push funkce do datoveho bufferu v prijimaci prijemce paketu
		   |- 1b ... RST - resetovani spojeni
		   |- 1b ... SYN - Synchronizace SEQ cisla - muze ho mit nastaven vzdy pouze prvni paket
			- 1b ... FIN - jiz zadna data se nebudou vysilat
		- 16b ... velikost okna - urcuje kolik bytu ma soucasne prijmout prijemce
		- 16b ... Checksum - 16-bit CRC hlavicky a dat
		- 16b ... Urgent pointer zpracovava se pouze pokud je nastaven priznak URG
		- 0-320b ... Options. Pocet bytu musi byt delitelny 32, delku urcuje parametr data offset. 
					 Je take doplnen takovym mnozstvim '0', aby celkovy pocet bitu paketu byl delitelny 32bity

*/

// definice prototypu
void TCP_Init(void);
void TCP_ResetRemoteClient(void);
void TCP_SaveRequestSEQ(uint8_t *RX_buffer);
uint8_t TCP_ProcessRx(uint8_t *RX_buffer, uint8_t *TX_buffer, uint16_t Rx_BufferLen);
uint8_t TCP_ReSendPacket(void);
uint8_t TCP_AddDataStringFromFLASH(const uint8_t *buffer, uint8_t *RX_buffer, uint8_t *TX_buffer);
uint8_t TCP_AddDataString(uint8_t *buffer, uint8_t *RX_buffer, uint8_t *TX_buffer);
uint8_t TCP_AddDataChar(uint8_t znak, uint8_t *RX_buffer, uint8_t *TX_buffer, uint8_t Konec);
void TCP_TxTCPPaket(uint8_t *RX_buffer, uint8_t *TX_buffer, uint16_t TCPDataLen, uint8_t PosledniPaket);
void TCP_TimeoutProcess(void);
void TCP_Set_TCP_Header(uint8_t *buffer, uint16_t SourcePort, uint16_t DestPort, uint32_t SEQ_num, 
						uint32_t ACK_num, uint8_t Flags, uint8_t OptionsByte, uint16_t len);
void TCP_Send_TCP_syn_ack(uint8_t *RX_buffer, uint8_t *TX_buffer);
void TCP_Send_TCP_ack(uint8_t *RX_buffer, uint8_t *TX_buffer, uint8_t IncrementAck);
void TCP_Send_TCP_fin_ack(uint8_t *RX_buffer, uint8_t *TX_buffer);
uint8_t TCP_Check_TCP_WWWPort(uint8_t *buffer, uint16_t WWWPort);
uint8_t TCP_CheckRemoteClient(uint8_t *RX_buffer);

#endif

/* Konec souboru */
