📄 tcp2.c
字号:
#define THIS_IS_TCP
#include <string.h>
#include <usart.h>
#include <p18f452.h>
#include "Tcp.h"
#include "emNETRTOS.H"
/*
* Max TCP data length is MAC_TX_BUFFER_SIZE - sizeof(TCP_HEADER) -
* sizeof(IP_HEADER) - sizeof(ETHER_HEADER)
*/
#define MAX_TCP_DATA_LEN (MAC_TX_BUFFER_SIZE - 54)
/*
* TCP Timeout value to begin with.
*/
#define TCP_START_TIMEOUT_VAL ((TICK)TICK_SECOND * (TICK)60)
/*
* TCP Flags as defined by rfc793
*/
//extern BYTE NICCurrentTxBuffer;
typedef unsigned long TICK;
/*
* TCP Header def. as per rfc 793.
*/
typedef struct _TCP_HEADER
{
WORD SourcePort;
WORD DestPort;
DWORD SeqNumber;
DWORD AckNumber;
struct
{
unsigned int Reserved3 : 4;
unsigned int Val : 4;
} DataOffset;
union
{
struct
{
unsigned int flagFIN : 1;
unsigned int flagSYN : 1;
unsigned int flagRST : 1;
unsigned int flagPSH : 1;
unsigned int flagACK : 1;
unsigned int flagURG : 1;
unsigned int Reserved2 : 2;
} bits;
BYTE byte;
} Flags;
WORD Window;
WORD Checksum;
WORD UrgentPointer;
} TCP_HEADER;
/*
* TCP Options as defined by rfc 793
*/
#define TCP_OPTIONS_END_OF_LIST (0x00)
#define TCP_OPTIONS_NO_OP (0x01)
#define TCP_OPTIONS_MAX_SEG_SIZE (0x02)
typedef struct _TCP_OPTIONS
{
BYTE Kind;
BYTE Length;
WORD_VAL MaxSegSize;
} TCP_OPTIONS;
#define SwapPseudoTCPHeader(h) (h.TCPLength = swaps(h.TCPLength))
/*
* Pseudo header as defined by rfc 793.
*/
typedef struct _PSEUDO_HEADER
{
IP_ADDR SourceAddress;
IP_ADDR DestAddress;
BYTE Zero;
BYTE Protocol;
WORD TCPLength;
} PSEUDO_HEADER;
/*
* These are all sockets supported by this TCP.
*/
SOCKET_INFO TCB[MAX_SOCKETS];
/*
* Local temp port numbers.
*/
static WORD _NextPort;
/*
* Starting segment sequence number for each new connection.
*/
static DWORD ISS;
static void HandleTCPSeg(TCP_SOCKET s,
NODE_INFO *remote,
TCP_HEADER *h,
WORD len);
static void TransmitTCP(NODE_INFO *remote,
TCP_PORT localPort,
TCP_PORT remotePort,
DWORD seq,
DWORD ack,
BYTE flags,
BUFFER buffer,
WORD len);
static TCP_SOCKET FindMatchingSocket(TCP_HEADER *h,
NODE_INFO *remote);
static void SwapTCPHeader(TCP_HEADER* header);
static WORD CalcTCPChecksum(WORD len);
#define LOCAL_PORT_START_NUMBER (1024)
#define LOCAL_PORT_END_NUMBER (5000)
void SocketInit(void)
{
TCP_SOCKET s;
SOCKET_INFO* ps;
for ( s = 0; s < MAX_SOCKETS; s++ )
{
ps = &TCB[s];
ps->smState=TCP_CLOSED;
}
}
/*********************************************************************
* Function: void TCPInit(void)
*
* PreCondition: None
*
* Input: None
*
* Output: TCP is initialized.
*
* Side Effects: None
*
* Overview: Initialize all socket info.
*
* Note: This function is called only one during lifetime
* of the application.
********************************************************************/
void TCPInit(void)
{
TCP_SOCKET s;
SOCKET_INFO* ps;
// Initialize all sockets.
for ( s = 0; s < MAX_SOCKETS; s++ )
{
ps = &TCB[s];
ps->smState = TCP_CLOSED;
ps->Flags.bServer = FALSE;
ps->Flags.bIsPutReady = TRUE;
ps->Flags.bFirstRead = TRUE;
ps->Flags.bIsTxInProgress = FALSE;
ps->Flags.bIsGetReady = FALSE;
ps->TxBuffer = INVALID_BUFFER;
// ps->TimeOut= TCP_START_TIMEOUT_VAL;
}
_NextPort = LOCAL_PORT_START_NUMBER;
ISS = 0;
}
void TCPInitsocket(TCP_SOCKET s)
{
if((s>=0)&&(s<=4))
{
SOCKET_INFO* ps;
ps = &TCB[s];
ps->smState = TCP_CLOSED;
ps->Flags.bServer = FALSE;
ps->Flags.bIsPutReady = TRUE;
ps->Flags.bFirstRead = TRUE;
ps->Flags.bIsTxInProgress = FALSE;
ps->Flags.bIsGetReady = FALSE;
ps->TxBuffer = INVALID_BUFFER;
}
}
/*********************************************************************
* Function: TCP_SOCKET TCPListen(TCP_PORT port)
*
* PreCondition: TCPInit() is already called.
*
* Input: port - A TCP port to be opened.
*
* Output: Given port is opened and returned on success
* INVALID_SOCKET if no more sockets left.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
TCP_SOCKET TCPListen(TCP_PORT port)
{
TCP_SOCKET s;
SOCKET_INFO* ps;
for ( s = 0; s < MAX_SOCKETS; s++ )
{
ps = &TCB[s];
if ( ps->smState == TCP_CLOSED )
{
/*
* We have a CLOSED socket.
* Initialize it with LISTENing state info.
*/
ps->smState = TCP_LISTEN;
ps->localPort = port;
ps->remotePort = 0;
/*
* There is no remote node IP address info yet.
*/
ps->remote.IPAddr.Val = 0x00;
/*
* If a socket is listened on, it is a SERVER.
*/
ps->Flags.bServer = TRUE;
ps->Flags.bIsGetReady = FALSE;
ps->TxBuffer = INVALID_BUFFER;
ps->Flags.bIsPutReady = TRUE;
return s;
}
}
return INVALID_SOCKET;
}
/*********************************************************************
* Function: TCP_SOCKET TCPConnect(NODE_INFO* remote,
* TCP_PORT remotePort)
*
* PreCondition: TCPInit() is already called.
*
* Input: remote - Remote node address info
* remotePort - remote port to be connected.
*
* Output: A new socket is created, connection request is
* sent and socket handle is returned.
*
* Side Effects: None
*
* Overview: None
*
* Note: By default this function is not included in
* source. You must define STACK_CLIENT_MODE to
* be able to use this function.
********************************************************************/
TCP_SOCKET TCPConnect(NODE_INFO *remote, TCP_PORT remotePort,TCP_SOCKET s)
{
//TCP_SOCKET s;
SOCKET_INFO* ps;
BOOL lbFound;
//lbFound = FALSE;
/*
* Find an available socket
*/
/*for ( s = 0; s < MAX_SOCKETS; s++ )
{
ps = &TCB[s];
if ( ps->smState == TCP_CLOSED )
{
lbFound = TRUE;
break;
}
}*/
/*
* If there is no socket available, return error.
*/
//if ( lbFound == FALSE )
// return INVALID_SOCKET;
ps = &TCB[s];
/*
* Each new socket that is opened by this node, gets
* next sequential port number.
*/
ps->localPort = ++_NextPort;
if ( _NextPort > LOCAL_PORT_END_NUMBER )
_NextPort = LOCAL_PORT_START_NUMBER;
/*
* This is a client socket.
*/
ps->Flags.bServer = FALSE;
/*
* This is the port, we are trying to connect to.
*/
ps->remotePort = remotePort;
/*
* Each new socket that is opened by this node, will
* start with next segment seqeuence number.
*/
ps->SND_SEQ = ++ISS;
ps->SND_ACK = 0;
memcpy((BYTE*)&ps->remote, (const void*)remote, sizeof(ps->remote));
/*
* Send SYN message.
*/
//putrsUSART("sendtcp\n");
SendTCP(&ps->remote,
ps->localPort,
ps->remotePort,
ps->SND_SEQ,
ps->SND_ACK,
SYN);
ps->smState = TCP_SYN_SENT;
ps->SND_SEQ++;
return s;
}
TCP_SOCKET TCPConnect1(NODE_INFO *remote, TCP_PORT remotePort,TCP_SOCKET s,TCP_PORT localPort)
{
SOCKET_INFO* ps;
BOOL lbFound;
ps = &TCB[s];
ps->localPort =localPort;
ps->Flags.bServer = FALSE;
ps->remotePort = remotePort;
ps->SND_SEQ = ++ISS;
ps->SND_ACK = 0;
memcpy((BYTE*)&ps->remote, (const void*)remote, sizeof(ps->remote));
SendTCP(&ps->remote,
ps->localPort,
ps->remotePort,
ps->SND_SEQ,
ps->SND_ACK,
SYN);
//putrsUSART("TCPSYN\n");
ps->smState = TCP_SYN_SENT;
ps->SND_SEQ++;
return s;
}
/*********************************************************************
* Function: BOOL TCPIsConnected(TCP_SOCKET s)
*
* PreCondition: TCPInit() is already called.
*
* Input: s - Socket to be checked for connection.
*
* Output: TRUE if given socket is connected
* FALSE if given socket is not connected.
*
* Side Effects: None
*
* Overview: None
*
* Note: A socket is said to be connected if it is not
* in LISTEN and CLOSED mode. Socket may be in
* SYN_RCVD or FIN_WAIT_1 and may contain socket
* data.
********************************************************************/
BOOL TCPIsConnected(TCP_SOCKET s)
{
return ( TCB[s].smState == TCP_EST );
}
WORD TCPIsClosed(TCP_SOCKET s)
{ SOCKET_INFO* ps;
ps = &TCB[s];
/*if(s==0)
{
if(TCPIsConnected(s))
putrsUSART("tcp0hasestabl\n");
if( ps->smState==TCP_CLOSED)
{ putrsUSART("tcp0hasclosed\n");
return 1;
}
else
return 0;
}
else if(s==1)
{
if(TCPIsConnected(s))
putrsUSART("tcp1hasestabl\n");
if( ps->smState==TCP_CLOSED)
{ putrsUSART("tcp1hasclosed\n");
return 1;
}
else
return 0;
}*/
if( ps->smState==TCP_CLOSED)
{ //putrsUSART("tcphasclosed\n");
return 1;
}
else
return 0;
}
/*********************************************************************
* Function: void TCPDisconnect(TCP_SOCKET s)
*
* PreCondition: TCPInit() is already called AND
* TCPIsPutReady(s) == TRUE
*
* Input: s - Socket to be disconnected.
*
* Output: A disconnect request is sent for given socket.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
void TCPDisconnect(TCP_SOCKET s)
{
SOCKET_INFO *ps;
ps = &TCB[s];
/*
* If socket is not connected, may be it is already closed
* or in process of closing. Since user has called this
* explicitly, close it forcefully.
*/
if ( ps->smState != TCP_EST )
{
CloseSocket(ps);
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -