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

📄 sb.c

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

//--------------------------------------------------------------------
// SBNew()
//
// Creates a Socket Buffer
//--------------------------------------------------------------------
HANDLE SBNew( INT32 Max, INT32 Min, uint Mode )
{
    SB *pSB;

#ifdef _STRONG_CHECKING
    // Verify legal mode
    if( Mode!=SB_MODE_LINEAR && Mode!=SB_MODE_ATOMIC && Mode!=SB_MODE_HYBRID )
    {
        DbgPrintf(DBG_WARN,"SBNew: Illegal Mode");
        return(0);
    }
#endif

    // Allocate Object
    if( !(pSB = mmAlloc(sizeof(SB))) )
    {
        DbgPrintf(DBG_WARN,"SBNew: Object OOM");
        ExecLowResource();
        return(0);
    }

    // Zero-init Object
    mmZeroInit( pSB, sizeof(SB) );

    // Allocate external buffer if LINEAR
    if( Mode == SB_MODE_LINEAR && Max )
    {
        pSB->pData = mmBulkAlloc( Max );
        if( !pSB->pData )
        {
            DbgPrintf(DBG_WARN,"SBNew: Buffer OOM");
            mmFree( pSB );
            return(0);
        }
    }

    // Initialize type
    pSB->Type       = HTYPE_SB;
    pSB->Mode       = Mode;

    // Initialize the object
    pSB->Max        = Max;
    pSB->Min        = Min;

    return( (HANDLE)pSB );
}

//--------------------------------------------------------------------
// SBFree()
//
// Frees a SB
//--------------------------------------------------------------------
void SBFree( HANDLE h )
{
    SB    *pSB  = (SB *)h;

#ifdef _STRONG_CHECKING
    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBFree: HTYPE %04x",pSB->Type);
        return;
    }
#endif

    // Kill type for debug
    pSB->Type = 0;

    if( pSB->Mode == SB_MODE_LINEAR )
    {
        // Free the data buffer
        if( pSB->pData )
            mmBulkFree( pSB->pData );
    }
    else
    {
        // Free the Frags
        if( pSB->hFragFirst )
            FragFree( pSB->hFragFirst );
    }

    // Free the SB
    mmFree( pSB );
}

//--------------------------------------------------------------------
// SBFlush()
//
// Flush all data in SB and free associated buffer when fFree set
//--------------------------------------------------------------------
void SBFlush( HANDLE h, uint fFree )
{
    SB    *pSB  = (SB *)h;

#ifdef _STRONG_CHECKING
    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBFlush: HTYPE %04x",pSB->Type);
        return;
    }
#endif

    // Zap the total
    pSB->Total = 0;

    if( pSB->Mode == SB_MODE_LINEAR )
    {
        // Reset the object
        pSB->Head = pSB->Tail = 0;

        if( fFree && pSB->pData )
        {
            // Free Data Buffer
            mmBulkFree( pSB->pData );
            pSB->pData = 0;
        }
    }
    else
    {
        // Free all Frags
        if( pSB->hFragFirst )
            FragFree( pSB->hFragFirst );
        pSB->hFragFirst = 0;
    }
}

//--------------------------------------------------------------------
// SBRead()
//
// Read data from a SB
//--------------------------------------------------------------------
INT32 SBRead
(
    HANDLE  h,
    INT32   Size,
    INT32   Off,
    UINT8   *pbDst,
    IPN     *pIPFrom,
    uint    *pPortFrom,
    UINT8   flagPeek
)
{
    SB       *pSB  = (SB *)h;

#ifdef _STRONG_CHECKING
    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBRead: HTYPE %04x",pSB->Type);
        return( 0 );
    }
#endif

    if( pSB->Mode == SB_MODE_LINEAR )
    {
        //
        // Linear Case
        //

        INT32 Len;

        // Adjust size if too large
        if( (Size+Off) > pSB->Total )
            Size = pSB->Total - Off;

        if( Size <= 0 )
            return( Size );

        // Copy data when pointer supplied
        if( pbDst )
        {
            // First Copy
            Len = pSB->Max - (pSB->Tail+Off);
            if( Len >= 0 )
            {
                if( Len > Size )
                    Len = Size;
                if( Len )
                    mmCopy( pbDst, pSB->pData + pSB->Tail + Off, (uint)Len );

                // Copy the potential second block
                if( Size > Len )
                {
                    // Len is the number of bytes already copied
                    mmCopy( pbDst+Len, pSB->pData, (uint)(Size-Len) );
                }
            }
            else
            {
                // Here Len is the additional offset from the start
                Len = 0-Len;
                mmCopy( pbDst, pSB->pData+Len, (uint)Size );
            }
        }

        // Advance the tail pointer and adjust Total if not "peeking"
        if( !flagPeek )
        {
            pSB->Tail = (pSB->Tail+(Size+Off))%pSB->Max;
            pSB->Total -= (Size+Off);
        }

        return( Size );
    }
    else
    {
        //
        // Atomic Case
        //
        uint     ValidLen, Offset;
        HANDLE   hFrag;
        INT32    BytesCopied,ToCopy;
        UINT8    *pData;

        // Get the first frag
        hFrag = pSB->hFragFirst;

        // There must be a first frag
        if( !hFrag )
        {
            DbgPrintf(DBG_ERROR,"SBRead: Internal ATOMIC error");
            return(0);
        }

        // Copy in the "from" stuff
        if( pIPFrom )
            *pIPFrom = FragGetAux2( hFrag );
        if( pPortFrom )
            *pPortFrom = (uint)FragGetAux1( hFrag );

        BytesCopied = 0;

        for(;;)
        {
            // Get the buffer info
            pData = FragGetBufParams( hFrag, 0, &ValidLen, &Offset );

            // Get the most bytes we can copy this frag
            ToCopy = (INT32)ValidLen;

            // If we don't want the entire frag, trim it down
            if( (BytesCopied + ToCopy) > Size )
                ToCopy = Size - BytesCopied;

            // Copy the data from the frag
            if( ToCopy )
                mmCopy( pbDst + BytesCopied, pData + Offset, (uint)ToCopy );

            BytesCopied += ToCopy;

            // Handle ATOMIC mode
            if( pSB->Mode == SB_MODE_ATOMIC )
            {
                // If not "peeking", then fix the frag list and the totals
                if( !flagPeek )
                {
                    pSB->Total -= (INT32)ValidLen;
                    pSB->hFragFirst = FragGetNext( hFrag );
                    FragSetNext( hFrag, 0 );
                    FragFree( hFrag );
                }
                break;
            }

            //
            // Here we are in HYBRID mode
            //

            // If "peeking", just get next frag
            if( flagPeek )
                hFrag = FragGetNext( hFrag );
            else
            {
                // Fix the frag list and the totals
                pSB->Total -= ToCopy;

                if( ToCopy == (INT32)ValidLen )
                {
                    // We used the whole frag, remove it
                    pSB->hFragFirst = FragGetNext( hFrag );
                    FragSetNext( hFrag, 0 );
                    FragFree( hFrag );
                    hFrag = pSB->hFragFirst;
                }
                else
                {
                    // Some data left - patch frag
                    Offset += (uint)ToCopy;
                    ValidLen -= (uint)ToCopy;
                    FragSetBufParams( hFrag, ValidLen, Offset );
                    break;
                }
            }

            // Stop if we've copied the full request or out of frags
            if( BytesCopied == Size || !hFrag )
                break;
        }
        return( BytesCopied );
    }
}

//--------------------------------------------------------------------
// SBReadNC()
//
// Read data without copy from a SB
//--------------------------------------------------------------------
HANDLE SBReadNC( HANDLE h, IPN *pIPFrom, uint *pPortFrom )
{
    SB       *pSB  = (SB *)h;

#ifdef _STRONG_CHECKING
    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBReadNC: HTYPE %04x",pSB->Type);
        return( 0 );
    }
#endif

    if( pSB->Mode == SB_MODE_LINEAR )
        return(0);
    else
    {
        //
        // Atomic Case
        //
        uint     ValidLen, Offset;
        HANDLE   hFrag;

        // Get the first frag
        hFrag = pSB->hFragFirst;

        // There must be a first frag
        if( !hFrag )
        {
            DbgPrintf(DBG_ERROR,"SBReadNC: Internal ATOMIC error");
            return(0);
        }

        // Copy in the "from" stuff
        if( pIPFrom )
            *pIPFrom = FragGetAux2( hFrag );
        if( pPortFrom )
            *pPortFrom = (uint)FragGetAux1( hFrag );

        // Get the buffer info
        FragGetBufParams( hFrag, 0, &ValidLen, &Offset );

        // Remove the frag
        pSB->Total -= (INT32)ValidLen;
        pSB->hFragFirst = FragGetNext( hFrag );
        FragSetNext( hFrag, 0 );

        return( hFrag );
    }
}

//--------------------------------------------------------------------
// SBWrite()
//
// Write data (or attach frags) to a SB
//--------------------------------------------------------------------
INT32 SBWrite( HANDLE h, INT32 Size, void *pData, HANDLE hFrag )
{
    SB      *pSB = (SB *)h;

#ifdef _STRONG_CHECKING
    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBWrite: HTYPE %04x",pSB->Type);
        return( 0 );
    }
#endif

    if( pSB->Mode == SB_MODE_LINEAR )
    {
        //
        // Linear Case
        //
        INT32 Len;

        // Adjust size if too large
        Len = pSB->Max - pSB->Total;
        if( Size > Len )
            Size = Len;

        // Copy data
        if( !pSB->pData )
            Size = 0;
        else if( Size )
        {
            // First Copy
            Len = pSB->Max - pSB->Head;
            if( Len > Size )
                Len = Size;
            if( Len )
                mmCopy( pSB->pData + pSB->Head, (UINT8 *)pData, (uint)Len );

            // Potential Second Copy
            if( Size > Len )
                mmCopy( pSB->pData, ((UINT8 *)pData)+Len, (uint)(Size-Len) );

            // Advance head pointer and ajdust Total
            pSB->Head = (pSB->Head+Size)%pSB->Max;
            pSB->Total += Size;
        }

        // Free frag if provided
        if( hFrag )
            FragFree( hFrag );
    }
    else
    {
        //
        // Atomic Case
        //
        if( !hFrag )
        {
            DbgPrintf(DBG_ERROR,"SBWrite: No Frag");
            return( 0 );
        }

        // Normally the caller is charged with preparing the frag
        // for appending, but if a pointer is supplied, then
        // we do it here
        if( pData )
        {
            UINT8    *pDataOrg;
            uint     Offset;

            pDataOrg = FragGetBufParams( hFrag, 0, 0, 0 );
            Offset = (uint)(((UINT8 *)pData - pDataOrg));
            FragSetBufParams( hFrag, (uint)Size, Offset );
        }

        // Put this frag (chain) in the list
        if( !pSB->hFragFirst )
            pSB->hFragFirst = hFrag;
        else
            FragSetNext( pSB->hFragLast, hFrag );

        // Get the the new "last" frag
        do { pSB->hFragLast = hFrag; }
        while( hFrag = FragGetNext( pSB->hFragLast ) );

        // Adjust our count
        pSB->Total += Size;
    }

    return( Size );
}


//
// The following functions are direct structure references when
// _STRONG_CHECKING is not defined
//
#ifdef _STRONG_CHECKING

//--------------------------------------------------------------------
// SBGetTotal()
//
// Get the total bytes held in a SB
//--------------------------------------------------------------------
INT32 SBGetTotal( HANDLE h )
{
    SB    *pSB  = (SB *)h;

    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBGetTotal: HTYPE %04x",pSB->Type);
        return(0);
    }

    // Return Total
    return( pSB->Total );
}

//--------------------------------------------------------------------
// SBGetMax()
//
// Get the max bytes held in a SB
//--------------------------------------------------------------------
INT32 SBGetMax( HANDLE h )
{
    SB    *pSB  = (SB *)h;

    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBGetMax: HTYPE %04x",pSB->Type);
        return(0);
    }

    // Return Max
    return( pSB->Max );
}

//--------------------------------------------------------------------
// SBGetMin()
//
// Get the min byte threshold of a SB
//--------------------------------------------------------------------
INT32 SBGetMin( HANDLE h )
{
    SB    *pSB  = (SB *)h;

    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBGetMin: HTYPE %04x",pSB->Type);
        return(0);
    }

    // Return Min
    return( pSB->Min );
}

//--------------------------------------------------------------------
// SBSetMin()
//
// Set the min byte threshold of a SB
//--------------------------------------------------------------------
void SBSetMin( HANDLE h, UINT32 value )
{
    SB    *pSB  = (SB *)h;

    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBSetMin: HTYPE %04x",pSB->Type);
        return;
    }

    // Set Min
    pSB->Min = value;
}

//--------------------------------------------------------------------
// SBGetSpace()
//
// Get the space available in a SB
//--------------------------------------------------------------------
INT32 SBGetSpace( HANDLE h )
{
    SB    *pSB  = (SB *)h;

    if( pSB->Type != HTYPE_SB )
    {
        DbgPrintf(DBG_ERROR,"SBGetSpace: HTYPE %04x",pSB->Type);
        return(0);
    }

    // Return free space
    return( pSB->Max - pSB->Total );
}

#endif

⌨️ 快捷键说明

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