⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp2.c

📁 This code is used to TCP/IP connection It is developed by PIC18F452 and all this code is successfull
💻 C
📖 第 1 页 / 共 4 页
字号:

#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 + -