/*
LUFA Library
Copyright ( C ) Dean Camera , 2013.
dean [ at ] fourwalledcubicle [ dot ] com
www . lufa - lib . org
*/
/*
Copyright 2013 Dean Camera ( dean [ at ] fourwalledcubicle [ dot ] com )
Permission to use , copy , modify , distribute , and sell this
software and its documentation for any purpose is hereby granted
without fee , provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation , and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific , written prior permission .
The author disclaims all warranties with regard to this
software , including all implied warranties of merchantability
and fitness . In no event shall the author be liable for any
special , indirect or consequential damages or any damages
whatsoever resulting from loss of use , data or profits , whether
in an action of contract , negligence or other tortious action ,
arising out of or in connection with the use or performance of
this software .
*/
/** \file
*
* Header file for TCP . c .
*/
# ifndef _TCP_H_
# define _TCP_H_
/* Includes: */
# include <avr/io.h>
# include <stdbool.h>
# include "EthernetProtocols.h"
# include "Ethernet.h"
# include "ProtocolDecoders.h"
/* Macros: */
/** Maximum number of TCP ports which can be open at the one time. */
# define MAX_OPEN_TCP_PORTS 1
/** Maximum number of TCP connections which can be sustained at the one time. */
# define MAX_TCP_CONNECTIONS 3
/** TCP window size, giving the maximum number of bytes which can be buffered at the one time. */
# define TCP_WINDOW_SIZE 512
/** Port number for HTTP transmissions. */
# define TCP_PORT_HTTP SwapEndian_16(80)
/** Data direction indicator for a TCP application buffer, indicating data from host-to-device. */
# define TCP_PACKETDIR_IN false
/** Data direction indicator for a TCP application buffer, indicating data from device-to-host. */
# define TCP_PACKETDIR_OUT true
/** Congestion Window Reduced TCP flag mask. */
# define TCP_FLAG_CWR (1 << 7)
/** Explicit Congestion Notification TCP flag mask. */
# define TCP_FLAG_ECE (1 << 6)
/** Urgent TCP flag mask. */
# define TCP_FLAG_URG (1 << 5)
/** Data Acknowledge TCP flag mask. */
# define TCP_FLAG_ACK (1 << 4)
/** Data Push TCP flag mask. */
# define TCP_FLAG_PSH (1 << 3)
/** Reset TCP flag mask. */
# define TCP_FLAG_RST (1 << 2)
/** Synchronize TCP flag mask. */
# define TCP_FLAG_SYN (1 << 1)
/** Connection Finalize TCP flag mask. */
# define TCP_FLAG_FIN (1 << 0)
/** Application macro: Determines if the given application buffer contains a packet received from the host
*
* \ param [ in ] Buffer Application buffer to check
*
* \ return Boolean true if the buffer contains a packet from the host , false otherwise
*/
# define TCP_APP_HAS_RECEIVED_PACKET(Buffer) (Buffer->Ready && (Buffer->Direction == TCP_PACKETDIR_IN))
/** Application macro: Indicates if the application buffer is currently locked by the application for device-to-host transfers.
*
* \ param [ in ] Buffer Application buffer to check
*
* \ return Boolean true if the buffer has been captured by the application for device - to - host transmissions , false otherwise
*/
# define TCP_APP_HAVE_CAPTURED_BUFFER(Buffer) (!(Buffer->Ready) && Buffer->InUse && \
( Buffer - > Direction = = TCP_PACKETDIR_OUT ) )
/** Application macro: Indicates if the application can lock the buffer for multiple continued device-to-host transmissions.
*
* \ param [ in ] Buffer Application buffer to check
*
* \ return Boolean true if the buffer may be captured by the application for device - to - host transmissions , false otherwise
*/
# define TCP_APP_CAN_CAPTURE_BUFFER(Buffer) Buffer->InUse
/** Application macro: Captures the application buffer, locking it for device-to-host transmissions only. This should be
* performed when the application needs to transmit several packets worth of data in succession with no interruptions from the host .
*
* \ pre The application must check that the buffer can be locked first using TCP_APP_CAN_CAPTURE_BUFFER ( ) .
*
* \ param [ in ] Buffer Application buffer to lock
*/
# define TCP_APP_CAPTURE_BUFFER(Buffer) MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->InUse = true; }MACROE
/** Application macro: Releases a captured application buffer, allowing for host-to-device packets to be received.
*
* \ param [ in ] Buffer Application buffer to release
*/
# define TCP_APP_RELEASE_BUFFER(Buffer) MACROS{ Buffer->InUse = false; }MACROE
/** Application macro: Sends the contents of the given application buffer to the host.
*
* \ param [ in ] Buffer Application buffer to send
* \ param [ in ] Len Length of data contained in the buffer
*/
# define TCP_APP_SEND_BUFFER(Buffer, Len) MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->Length = Len; Buffer->Ready = true; }MACROE
/** Application macro: Clears the application buffer, ready for a packet to be written to it.
*
* \ param [ in ] Buffer Application buffer to clear
*/
# define TCP_APP_CLEAR_BUFFER(Buffer) MACROS{ Buffer->Ready = false; Buffer->Length = 0; }MACROE
/** Application macro: Closes an open connection to a host.
*
* \ param [ in ] Connection Open TCP connection to close
*/
# define TCP_APP_CLOSECONNECTION(Connection) MACROS{ Connection->State = TCP_Connection_Closing; }MACROE
/* Enums: */
/** Enum for possible TCP port states. */
enum TCP_PortStates_t
{
TCP_Port_Closed = 0 , /**< TCP port closed, no connections to a host may be made on this port. */
TCP_Port_Open = 1 , /**< TCP port open, connections to a host may be made on this port. */
} ;
/** Enum for possible TCP connection states. */
enum TCP_ConnectionStates_t
{
TCP_Connection_Listen = 0 , /**< Listening for a connection from a host */
TCP_Connection_SYNSent = 1 , /**< Unused */
TCP_Connection_SYNReceived = 2 , /**< SYN received, waiting for ACK */
TCP_Connection_Established = 3 , /**< Connection established in both directions */
TCP_Connection_FINWait1 = 4 , /**< Closing, waiting for ACK */
TCP_Connection_FINWait2 = 5 , /**< Closing, waiting for FIN ACK */
TCP_Connection_CloseWait = 6 , /**< Closing, waiting for ACK */
TCP_Connection_Closing = 7 , /**< Unused */
TCP_Connection_LastACK = 8 , /**< Unused */
TCP_Connection_TimeWait = 9 , /**< Unused */
TCP_Connection_Closed = 10 , /**< Connection closed in both directions */
} ;
/* Type Defines: */
/** Type define for a TCP connection buffer structure, including size, data and direction. */
typedef struct
{
uint16_t Length ; /**< Length of data in the TCP application buffer */
uint8_t Data [ TCP_WINDOW_SIZE ] ; /**< TCP application data buffer */
bool Direction ; /**< Buffer transmission direction, either TCP_PACKETDIR_IN or TCP_PACKETDIR_OUT */
bool Ready ; /**< If data from host, indicates buffer ready to be read, otherwise indicates
* buffer ready to be sent to the host
*/
bool InUse ; /**< Indicates if the buffer is locked to to the current direction, and cannot be changed */
} TCP_ConnectionBuffer_t ;
/** Type define for a TCP connection information structure. */
typedef struct
{
uint32_t SequenceNumberIn ; /**< Current TCP sequence number for host-to-device */
uint32_t SequenceNumberOut ; /**< Current TCP sequence number for device-to-host */
TCP_ConnectionBuffer_t Buffer ; /**< Connection application data buffer */
} TCP_ConnectionInfo_t ;
/** Type define for a complete TCP connection state. */
typedef struct
{
uint16_t Port ; /**< Connection port number on the device */
uint16_t RemotePort ; /**< Connection port number on the host */
IP_Address_t RemoteAddress ; /**< Connection protocol IP address of the host */
TCP_ConnectionInfo_t Info ; /**< Connection information, including application buffer */
uint8_t State ; /**< Current connection state, a value from the \ref TCP_ConnectionStates_t enum */
} TCP_ConnectionState_t ;
/** Type define for a TCP port state. */
typedef struct
{
uint16_t Port ; /**< TCP port number on the device */
uint8_t State ; /**< Current port state, a value from the \ref TCP_PortStates_t enum */
void ( * ApplicationHandler ) ( TCP_ConnectionState_t * ConnectionState ,
TCP_ConnectionBuffer_t * Buffer ) ; /**< Port application handler */
} TCP_PortState_t ;
/** Type define for a TCP packet header. */
typedef struct
{
uint16_t SourcePort ; /**< Source port of the TCP packet */
uint16_t DestinationPort ; /**< Destination port of the TCP packet */
uint32_t SequenceNumber ; /**< Data sequence number of the packet */
uint32_t AcknowledgmentNumber ; /**< Data acknowledgment number of the packet */
unsigned Reserved : 4 ; /**< Reserved, must be all 0 */
unsigned DataOffset : 4 ; /**< Offset of the data from the start of the header, in 4 byte chunks */
uint8_t Flags ; /**< TCP packet flags */
uint16_t WindowSize ; /**< Current data window size (bytes remaining in reception buffer) */
uint16_t Checksum ; /**< TCP checksum */
uint16_t UrgentPointer ; /**< Urgent data pointer */
} TCP_Header_t ;
/* Function Prototypes: */
void TCP_Init ( void ) ;
void TCP_Task ( void ) ;
bool TCP_SetPortState ( const uint16_t Port ,
const uint8_t State ,
void ( * Handler ) ( TCP_ConnectionState_t * , TCP_ConnectionBuffer_t * ) ) ;
uint8_t TCP_GetPortState ( const uint16_t Port ) ;
bool TCP_SetConnectionState ( const uint16_t Port ,
const IP_Address_t * RemoteAddress ,
const uint16_t RemotePort ,
const uint8_t State ) ;
uint8_t TCP_GetConnectionState ( const uint16_t Port ,
const IP_Address_t * RemoteAddress ,
const uint16_t RemotePort ) ;
TCP_ConnectionInfo_t * TCP_GetConnectionInfo ( const uint16_t Port ,
const IP_Address_t * RemoteAddress ,
const uint16_t RemotePort ) ;
int16_t TCP_ProcessTCPPacket ( void * IPHeaderInStart ,
void * TCPHeaderInStart ,
void * TCPHeaderOutStart ) ;
# if defined(INCLUDE_FROM_TCP_C)
static uint16_t TCP_Checksum16 ( void * TCPHeaderOutStart ,
const IP_Address_t * SourceAddress ,
const IP_Address_t * DestinationAddress ,
uint16_t TCPOutSize ) ;
# endif
# endif