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

📄 tcp2.c

📁 This code is used to TCP/IP connection It is developed by PIC18F452 and all this code is successfull
💻 C
📖 第 1 页 / 共 4 页
字号:
                CloseSocket(ps);
            else
                flags = ACK;
            break;
        }

        if ( flags > 0x00 )
        {
            if ( flags != ACK )
                seq = ps->SND_SEQ++;
            else
                seq = ps->SND_SEQ;

            SendTCP(&ps->remote,
                    ps->localPort,
                    ps->remotePort,
                    seq,
                    ps->SND_ACK,
                    flags);
        }
    }
#else
    return;
#endif
}*/
void TCPtickout(void)
{
   TCP_SOCKET s;
   SOCKET_INFO* ps;
   DWORD seq;
   BYTE flags;
   emInt8 id;
   flags = 0x00;
   for(s=0;s < MAX_SOCKETS; s++)
  {
   ps = &TCB[s];

   if ( ps->Flags.bIsGetReady || ps->Flags.bIsTxInProgress )
     continue;

   if ( (ps->smState == TCP_CLOSED) ||
        (ps->smState == TCP_LISTEN &&
         ps->Flags.bServer == TRUE) )
     continue;
   

   id=(s+1);
   if((id!=1)&&(id!=2))
     continue;
   if(emCheckHardTimer(id))
     {
        ps->RetryCount++;
        
        switch(ps->smState)
         {
           case TCP_SYN_SENT: 
             if ( ps->RetryCount < MAX_RETRY_COUNTS )
               {
                  flags = SYN ;
               }
             else
                  CloseSocket(ps);
             break;
           
           case TCP_SYN_RCVD:
             if ( ps->RetryCount < MAX_RETRY_COUNTS )
               {
                  flags = SYN | ACK;
               }
             else
                  CloseSocket(ps);
             break;     

         /*  case TCP_EST:
             if ( ps->RetryCount <= MAX_RETRY_COUNTS )
               {
                   if ( ps->TxBuffer != INVALID_BUFFER )
                     {
                         MACSetTxBuffer(ps->TxBuffer, 0);
                         MACFlush();
                     }
                   /*else if(ps->RxCount == 0)
                     {
                         flags = 0x00;
                         ps->RetryCount=0;//有疑问???
                     }*/
                 /*  else
                         flags = ACK;
               }
             else
               {
                   if ( ps->TxBuffer != INVALID_BUFFER )
                         MACDiscardTx(ps->TxBuffer);
                   ps->TxBuffer = INVALID_BUFFER;
                   flags = FIN | ACK;
                   ps->smState = TCP_FIN_WAIT_1;
               }
             break;   */           
           case TCP_FIN_WAIT_1:
           case TCP_LAST_ACK:
             if ( ps->RetryCount > MAX_RETRY_COUNTS )
                   CloseSocket(ps);
             else
                   flags = FIN;
             break;
 
           case TCP_CLOSING:
           case TCP_TIMED_WAIT:
             if ( ps->RetryCount > MAX_RETRY_COUNTS )
                   CloseSocket(ps);
             else
                   flags = ACK;
             break;


         }

       if ( flags > 0x00 )
        {
            if ( flags != ACK )
                seq = ps->SND_SEQ++;
            else
                seq = ps->SND_SEQ;

            SendTCP(&ps->remote,
                    ps->localPort,
                    ps->remotePort,
                    seq,
                    ps->SND_ACK,
                    flags);
        }

     }
    }
}



/*********************************************************************
 * Function:        BOOL TCPProcess(NODE_INFO* remote,
 *                                  WORD len)
 *
 * PreCondition:    TCPInit() is already called     AND
 *                  TCP segment is ready in MAC buffer
 *
 * Input:           remote      - Remote node info
 *                  len         - Total length of TCP semgent.
 *
 * Output:          TRUE if this function has completed its task
 *                  FALSE otherwise
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
BOOL TCPProcess(NODE_INFO *remote, WORD len)
{
    TCP_HEADER      TCPHeader;
    PSEUDO_HEADER   pseudoHeader;
    TCP_SOCKET      socket;
    WORD_VAL        checksum;
    BYTE            optionsSize;
    char        i;
    BYTE        *c;

    // Retrieve TCP header.
    MACGetArray((BYTE*)&TCPHeader, sizeof(TCPHeader));
    c=(BYTE*)&TCPHeader;
    for(i=0;i<20;i++)
     { 
        while(!TXSTAbits.TRMT);
        putcUSART(*(c++));
     }
   
    SwapTCPHeader(&TCPHeader);

    // Calculate IP pseudoheader checksum.
    pseudoHeader.SourceAddress      = remote->IPAddr;
    pseudoHeader.DestAddress.v[0]   = MY_IP_BYTE1;
    pseudoHeader.DestAddress.v[1]   = MY_IP_BYTE2;
    pseudoHeader.DestAddress.v[2]   = MY_IP_BYTE3;
    pseudoHeader.DestAddress.v[3]   = MY_IP_BYTE4;
    pseudoHeader.Zero               = 0x0;
    pseudoHeader.Protocol           = IP_PROT_TCP;
    pseudoHeader.TCPLength          = len;

    SwapPseudoTCPHeader(pseudoHeader);


    checksum.Val = ~CalcIPChecksum((BYTE*)&pseudoHeader,
                                    sizeof(pseudoHeader));


    // Set TCP packet checksum = pseudo header checksum in MAC RAM.
    IPSetRxBuffer(16);
    MACPut(checksum.v[0]);
    MACPut(checksum.v[1]);
    IPSetRxBuffer(0);

    // Now calculate TCP packet checksum in NIC RAM - including
    // pesudo header.
    checksum.Val = CalcTCPChecksum(len);

    if ( checksum.Val != TCPHeader.Checksum )
    {
        MACDiscardRx();
        return FALSE;
    }

    // Skip over options and retrieve all data bytes.
    optionsSize = (BYTE)((TCPHeader.DataOffset.Val << 2)-
                            sizeof(TCPHeader));
    len = len - optionsSize - sizeof(TCPHeader);

    // Position packet read pointer to start of data area.
    IPSetRxBuffer((TCPHeader.DataOffset.Val << 2));

    // Find matching socket.
    socket = FindMatchingSocket(&TCPHeader, remote);
    if ( socket < INVALID_SOCKET )
    {
        HandleTCPSeg(socket, remote, &TCPHeader, len);
        return TRUE;
    }
    else
    {
        /*
         * If this is an unknown socket, discard it and
         * send RESET to remote node.
         */
        MACDiscardRx();

		//putrsUSART("NO FIND\n");

        if ( socket == UNKNOWN_SOCKET )
        {

            TCPHeader.AckNumber += len;
            if ( TCPHeader.Flags.bits.flagSYN ||
                 TCPHeader.Flags.bits.flagFIN )
                TCPHeader.AckNumber++;

            SendTCP(remote,
                    TCPHeader.DestPort,
                    TCPHeader.SourcePort,
                    TCPHeader.AckNumber,
                    TCPHeader.SeqNumber,
                    RST);
            //putrsUSART("SENTRST\n");
         }
          
        return FALSE;
    }

    
}


/*********************************************************************
 * Function:        static void TransmitTCP(NODE_INFO* remote
 *                                          TCP_PORT localPort,
 *                                          TCP_PORT remotePort,
 *                                          DWORD seq,
 *                                          DWORD ack,
 *                                          BYTE flags,
 *                                          BUFFER buffer,
 *                                          WORD len)
 *
 * PreCondition:    TCPInit() is already called     AND
 *                  TCPIsPutReady() == TRUE
 *
 * Input:           remote      - Remote node info
 *                  localPort   - Source port number
 *                  remotePort  - Destination port number
 *                  seq         - Segment sequence number
 *                  ack         - Segment acknowledge number
 *                  flags       - Segment flags
 *                  buffer      - Buffer to which this segment
 *                                is to be transmitted
 *                  len         - Total data length for this segment.
 *
 * Output:          A TCP segment is assembled and put to transmit.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
static void TransmitTCP(NODE_INFO *remote,
                        TCP_PORT localPort,
                        TCP_PORT remotePort,
                        DWORD tseq,
                        DWORD tack,
                        BYTE flags,
                        BUFFER buffer,
                        WORD len)
{
    WORD_VAL        checkSum;
    TCP_HEADER      header;
    TCP_OPTIONS     options;
    PSEUDO_HEADER   pseudoHeader;

    /*
     * When using SLIP (USART), packet transmission takes some time
     * and hence before sending another packet, we must make sure
     * that, last packet is transmitted.
     * When using ethernet controller, transmission occurs very fast
     * and by the time next packet is transmitted, previous is
     * transmitted and we do not need to check for last packet.
     */
    while( !IPIsTxReady() );

    header.SourcePort           = localPort;
    header.DestPort             = remotePort;
    header.SeqNumber            = tseq;
    header.AckNumber            = tack;
    header.Flags.bits.Reserved2 = 0;
    header.DataOffset.Reserved3 = 0;
    header.Flags.byte           = flags;
    // Receive window = MAC Free buffer size - TCP header (20) - IP header (20)
    //                  - ETHERNET header (14 if using NIC) .
    header.Window               = MACGetFreeRxSize();
#if !defined(STACK_USE_SLIP)
    /*
     * Limit one segment at a time from remote host.
     * This limit increases overall throughput as remote host does not
     * flood us with packets and later retry with significant delay.
     */
    if ( header.Window >= MAC_RX_BUFFER_SIZE )
        header.Window = MAC_RX_BUFFER_SIZE;

    else if ( header.Window > 54 )
    {
        header.Window -= 54;
    }
    else
        header.Window = 0;
#else
    if ( header.Window > 40 )
    {
        header.Window -= 40;
    }
    else
        header.Window = 0;
#endif

    header.Checksum             = 0;
    header.UrgentPointer        = 0;

    SwapTCPHeader(&header);

    len += sizeof(header);

    if ( flags & SYN )
    {
        len += sizeof(options);
        options.Kind = TCP_OPTIONS_MAX_SEG_SIZE;
        options.Length = 0x04;

        // Load MSS in already swapped order.
        options.MaxSegSize.v[0]  = (MAC_RX_BUFFER_SIZE >> 8); // 0x05;
        options.MaxSegSize.v[1]  = (MAC_RX_BUFFER_SIZE & 0xff); // 0xb4;

        header.DataOffset.Val   = (sizeof(header) + sizeof(options)) >> 2;
    }
    else
        header.DataOffset.Val   = sizeof(header) >> 2;


    // Calculate IP pseudoheader checksum.
    pseudoHeader.SourceAddress.v[0] = MY_IP_BYTE1;
    pseudoHeader.SourceAddress.v[1] = MY_IP_BYTE2;
    pseudoHeader.SourceAddress.v[2] = MY_IP_BYTE3;
    pseudoHeader.SourceAddress.v[3] = MY_IP_BYTE4;
    pseudoHeader.DestAddress    = remote->IPAddr;
    pseudoHeader.Zero           = 0x0;
    pseudoHeader.Protocol       = IP_PROT_TCP;
    pseudoHeader.TCPLength      = len;

    SwapPseudoTCPHeader(pseudoHeader);

    header.Checksum = ~CalcIPChecksum((BYTE*)&pseudoHeader,
                        sizeof(pseudoHeader));
    checkSum.Val = header.Checksum;

    if ( buffer == INVALID_BUFFER )
        buffer = MACGetTxBuffer();

    IPSetTxBuffer(buffer, 0);

    // Write IP header.
    IPPutHeader(remote, IP_PROT_TCP, len);
    IPPutArray((BYTE*)&header, sizeof(header));

    if ( flags & SYN )
        IPPutArray((BYTE*)&options, sizeof(options));

    IPSetTxBuffer(buffer, 0);

    checkSum.Val = CalcTCPChecksum(len);

    // Update the checksum.
    IPSetTxBuffer(buffer, 16);
    MACPut(checkSum.v[1]);
    MACPut(checkSum.v[0]);
    MACSetTxBuffer(buffer, 0);
    MACFlush();
}



/*********************************************************************
 * Function:        static WORD CalcTCPChecksum(WORD len)
 *
 * PreCondition:    TCPInit() is already called     AND
 *                  MAC buffer pointer set to starting of buffer
 *
 * Input:           len     - Total number of bytes to calculate
 *                          checksum for.
 *
 * Output:          16-bit checksum as defined by rfc 793.
 *
 * Side Effects:    None
 *
 * Overview:        This function performs checksum calculation in
 *                  MAC buffer itself.
 *
 * Note:            None
 ********************************************************************/
static WORD CalcTCPChecksum(WORD len)
{
    BOOL lbMSB;
    WORD_VAL checkSum;
    BYTE Checkbyte;

    lbMSB = TRUE;
    checkSum.Val = 0;

    while( len-- )
    {
        Checkbyte = MACGet();

        if ( !lbMSB )
        {
            if ( (checkSum.v[0] = Checkbyte+checkSum.v[0]) < Checkbyte)
            {
                if ( ++checkSum.v[1] == 0 )
                    checkSum.v[0]++;
            }
        }
        else
        {
            if ( (checkSum.v[1] = Checkbyte+checkSum.v[1]) < Checkbyte)
            {
                if ( ++checkSum.v[0] == 0 )
                    checkSum.v[1]++;
            }
        }

        lbMSB = !lbMSB;
    }

    checkSum.v[1] = ~checkSum.v[1];
    checkSum.v[0] = ~checkSum.v[0];
    return checkSum.Val;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -