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

📄 tcp.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// TCP.C
//
// TCP General Functions
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "tcp.h"

// Private and Public Globals
UINT32   tcp_iss = 0x7F000000;  // Initial send sequence
UINT32   tcp_now = 0;           // current TCP time (in 500mS ticks)
TCPSTATS tcps;                  // Stats
TCPPROT  *ptTimeFirst = 0;      // Pointer to first time-out candidate
PSEUDO   tpseudo;               // Pseudo header for checksum

static void TcpTimeoutCheck();

//--------------------------------------------------------------------
// TcpMsg()
//
// Services Intialization and Resource Messages
//--------------------------------------------------------------------
void TcpMsg( uint Msg )
{
    static HANDLE hTimer;

    switch( Msg )
    {
    // System Initialization
    case MSG_EXEC_SYSTEM_INIT:
        // Initialize TCP Timer
        hTimer = TimerNew( &TcpMsg, 1, MSG_TCP_TIMER );
        // Initialize Stats
        mmZeroInit( &tcps, sizeof( TCPSTATS ) );
        // We Init ICMP/UDP/RAW stats here since they do not
        // require their own MSG routine
        mmZeroInit( _dwICMPIn, sizeof( UINT32 ) * (ICMP_MAXTYPE+1) );
        mmZeroInit( _dwICMPOut, sizeof( UINT32 ) * (ICMP_MAXTYPE+1) );
        mmZeroInit( &udps, sizeof( UDPSTATS ) );
        mmZeroInit( &raws, sizeof( RAWSTATS ) );
        break;

    // System Shutdown
    case MSG_EXEC_SYSTEM_SHUTDOWN:
        // Continue shutdown
        if( hTimer )
            TimerFree( hTimer );
        break;

    // Low Resoruces
    case MSG_EXEC_LOW_RESOURCES:
        break;

    // Half Second Timer
    case MSG_TCP_TIMER:
        TcpTimeoutCheck();
        break;
    }
}

//--------------------------------------------------------------------
// void TcpChecksum( TCPHDR *pbHdr )
//
// Checksums the TCP header
//--------------------------------------------------------------------
void TcpChecksum( TCPHDR *pTcpHdr )
{
    int     tmp1;
    UINT16  *pw;
    UINT32  dwTSum;

    // Get header size in bytes
    tmp1 = (int)HNC16(tpseudo.Length);

    // Checksum field is NULL in checksum calculations
    pTcpHdr->TCPChecksum = 0;

    // Checksum the header
    pw = (UINT16 *)pTcpHdr;
    dwTSum = 0;
    for( ; tmp1 > 1; tmp1 -= 2 )
        dwTSum += (UINT32)*pw++;
    if( tmp1 )
        dwTSum += (UINT32)(*pw & 0xFF);

    // Checksum the pseudo header
    pw = (UINT16 *)&tpseudo;
    for( tmp1=0; tmp1 < 6; tmp1++ )
        dwTSum += (UINT32)*pw++;

    dwTSum = (dwTSum&0xFFFF) + (dwTSum>>16);
    dwTSum = (dwTSum&0xFFFF) + (dwTSum>>16);
    dwTSum = ~dwTSum;

    // Note checksum is Net/Host byte order independent
    pTcpHdr->TCPChecksum = (UINT16)dwTSum;
}

//--------------------------------------------------------------------
// TCP Timeout Functions
//--------------------------------------------------------------------

//--------------------------------------------------------------------
// TcpTimeoutAdd
//
// Add TCP object to timeout canditate list
//--------------------------------------------------------------------
void TcpTimeoutAdd( TCPPROT *pt )
{
    // Easiest to always insert at head of list
    pt->pPrev = 0;
    pt->pNext = ptTimeFirst;
    if( ptTimeFirst )
        ptTimeFirst->pPrev = pt;
    ptTimeFirst = pt;
}

//--------------------------------------------------------------------
// TcpTimeoutRemove
//
// Remove TCP object from timeout canditate list
//--------------------------------------------------------------------
void TcpTimeoutRemove( TCPPROT *pt )
{
    // Patch preceeding entry
    if( !pt->pPrev )
        ptTimeFirst = pt->pNext;
    else
        pt->pPrev->pNext = pt->pNext;

    // Patch following entry
    if( pt->pNext )
       pt->pNext->pPrev = pt->pPrev;
}

//--------------------------------------------------------------------
// TcpTimeoutCheck
//
// Scan timeout list for TCP timeouts
//--------------------------------------------------------------------
static void TcpTimeoutCheck()
{
    TCPPROT *pt;
    TCPPROT **ppt;

    ppt = &ptTimeFirst;

    while( *ppt )
    {
        pt = *ppt;

        //
        // Check all timers. If pt goes away by calling the timeout
        // function, then move on to the next one.
        //
        if( pt->dwTicksRexmt && !--pt->dwTicksRexmt )
        {
            TcpTimeoutRexmt( pt );
            if( *ppt != pt )
                continue;
        }

        if( pt->dwTicksPersist && !--pt->dwTicksPersist )
        {
            TcpTimeoutPersist( pt );
            if( *ppt != pt )
                continue;
        }

        if( pt->dwTicksKeep && !--pt->dwTicksKeep )
        {
            TcpTimeoutKeep( pt );
            if( *ppt != pt )
                continue;
        }

        if( pt->dwTicksWait2 && !--pt->dwTicksWait2 )
        {
            TcpTimeoutWait2( pt );
            if( *ppt != pt )
                continue;
        }

        // Perform any delayed ACK
        if( pt->t_flags & TF_DELACK )
        {
            pt->t_flags &= ~TF_DELACK;
            pt->t_flags |= TF_ACKNOW;
            tcps.dwDelAck++;
            TcpOutput(pt);
	}
        else if( pt->t_flags & TF_NEEDOUTPUT )
            TcpOutput(pt);

        // Bump Idle time
        pt->t_tidle++;

        // Bump RTT counter if active
        if( pt->t_trtt )
            pt->t_trtt++;

        // Move on to next block
        ppt = &pt->pNext;
    }

    // Bump TCP start sequence
    tcp_iss += TCP_ISSINCR/2;

    // Bump TCP time
    tcp_now++;
}

⌨️ 快捷键说明

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