BST_UINT32 BST_OS_StaticMemCtrlBlkFree( BST_MEM_CTRL_BLOCK *BST_MemCtrlBlock,
                               BST_MEM_HEAD_BLOCK *Block )
{
    BST_UINT32           ulLockLevel;

    if (( BST_NULL_PTR == BST_MemCtrlBlock )
        ||( BST_NULL_PTR == Block ))
    {
        return BST_MEM_ERROR;
    }

    ulLockLevel = BST_OS_SpinLock(&g_stBstMemSpinLock);

    if ( BST_NOT_USED == Block->ulMemUsedFlag )
    {
        BST_OS_SpinUnLock(&g_stBstMemSpinLock, ulLockLevel);

        BST_RLS_LOG("# Free Msg again.");

        return BST_MEM_ERROR;
    }

    Block->ulMemUsedFlag = BST_NOT_USED;
    Block->pstNext = BST_MemCtrlBlock->pstBlocks;
    BST_MemCtrlBlock->pstBlocks = Block;

    BST_MemCtrlBlock->lIdleBlockNumber++;

    BST_OS_MemStatusReport( BST_MemCtrlBlock->enType );

    BST_OS_SpinUnLock(&g_stBstMemSpinLock, ulLockLevel);

    return BST_MEM_OK;
}
BST_UINT32 BST_OS_RecvMail(
    BST_OS_MBX_T   *pstMbx,
    BST_VOID      **pMsg,
    BST_UINT32      ulExTime )
{
    BST_OS_MAIL_T                      *pstContent;
    BST_UINT32                          ulPendTime;
    BST_UINT32                          ulPastTime;
    BST_OS_LOCKCNT_T                    tThreadLockCnt;

    BST_ASSERT_NULL_RTN( pstMbx,        BST_ERR_INVALID_PTR );
    BST_ASSERT_NULL_RTN( pstMbx->hSem,  BST_ERR_INVALID_PTR );
    BST_ASSERT_NULL_RTN( pMsg,          BST_ERR_INVALID_PTR );

    *pMsg                               = BST_NULL_PTR;

    if( (BST_UINT32)BST_OS_SYS_FOREVER == ulExTime )
    {
        ulPendTime                      = (BST_UINT32)BST_OS_SYS_FOREVER;
    }
    else if( ulExTime < BST_OS_TICKS_MS )
    {
        ulPendTime                      = BST_OS_TICKS_MS;
    }
    else
    {
        ulPendTime                      = ulExTime;
    }

    ulPastTime = BST_OS_RecvSem( pstMbx->hSem, ulPendTime );

    if( BST_OS_SYS_TIMEOUT == ulPastTime )
    {
        return BST_OS_SYS_TIMEOUT;
    }

    tThreadLockCnt                      = (BST_OS_LOCKCNT_T)BST_OS_SpinLock( &g_MboxLock );

    pstContent                          = (BST_OS_MAIL_T *)lstGet( &pstMbx->hList );


    if ( BST_NULL_PTR == pstContent )
    {
       *pMsg                           = BST_NULL_PTR;
        BST_OS_SpinUnLock( &g_MboxLock, (BST_UINT32)tThreadLockCnt );
        return BST_OS_SYS_TIMEOUT;
    }
    *pMsg                               = pstContent->ulContent;

    BST_OS_FREE( pstContent );
    BST_OS_SpinUnLock( &g_MboxLock, (BST_UINT32)tThreadLockCnt );
    /*lint -e438*/
    return( ulPastTime );
    /*lint +e438*/
}
BST_VOID* BST_OS_StaticMemCtrlBlkMalloc( BST_MEM_CTRL_BLOCK *BST_MemCtrlBlock)
{
    BST_ULONG             ulLockLevel;
    BST_MEM_HEAD_BLOCK   *Block;
    BST_UINT_PTR         *pulTemp;
    BST_UINT_PTR          ulBlockAddr;
    BST_UINT32            ulCrcTag;

    if ( BST_NULL_PTR == BST_MemCtrlBlock )
    {
        return((BST_VOID*)BST_NULL_PTR);
    }

    ulLockLevel = BST_OS_SpinLock(&g_stBstMemSpinLock);

    if( 0 >= BST_MemCtrlBlock->lIdleBlockNumber )
    {
        BST_OS_SpinUnLock(&g_stBstMemSpinLock, ulLockLevel);

        return((BST_VOID*)BST_NULL_PTR);
    }
    else
    {
        BST_MemCtrlBlock->lIdleBlockNumber--;
        Block = BST_MemCtrlBlock->pstBlocks;
        Block->ulMemUsedFlag = BST_USED;
        BST_MemCtrlBlock->pstBlocks = Block->pstNext;
    }

    BST_OS_SpinUnLock(&g_stBstMemSpinLock, ulLockLevel);


    /* check memory */
    pulTemp = (BST_UINT_PTR*)(Block->ulMemAddress);

    ulBlockAddr = *pulTemp++;
    ulCrcTag = *pulTemp;

    if ( ((BST_UINT_PTR)Block != ulBlockAddr) || (BST_MEMORY_CRC != ulCrcTag) )
    {
        return((BST_VOID*)BST_NULL_PTR);
    }

    return (BST_VOID *)Block->ulMemAddress;
}
BST_VOID BST_SRV_CHNL_Clear(
    BST_SRV_CHNL_LINK_STRU     *pstChnlLink )
{
    BST_SRV_CHNL_SENT_STRU     *pSentItem;
    BST_SRV_CHNL_SENT_STRU     *pSentItem2;
    BST_SRV_CHNL_HEAD_STRU     *pstPktItem;
    BST_SRV_CHNL_HEAD_STRU     *pstPktItem2;
    BST_DRV_STRU               *pNetDrvHandle;
    BST_UINT8                   ucUnused;
    BST_UINT32                  ulSpinlockCnt;

    BST_ASSERT_NULL( pstChnlLink );
    pstChnlLink->ulIsPropSet    = BST_FALSE;
    for(;;)
    {
        pSentItem               = BST_SRV_Q_PeekHead(pstChnlLink->pSentList);
        if( BST_NULL_PTR == pSentItem )
        {
            break;
        }
        if( BST_DSPP_FLG_LVLTYPE_HS == pSentItem->usProcLevel )
        {
            ulSpinlockCnt       = BST_OS_SpinLock( &g_HighPriCntSpinLock );
            if ( g_ulHighPriCnt > 0 )
            {
                g_ulHighPriCnt--;
                if ( 0 == g_ulHighPriCnt )
                {
                    pNetDrvHandle= BST_DRV_NetGetDvcHandle();
                    ucUnused     = 0;
                    pNetDrvHandle->pfIoCtrl( BST_DRV_CMD_HPR_DATA_FINISH, (BST_VOID *)&ucUnused );
                }
            }
            BST_OS_SpinUnLock( &g_HighPriCntSpinLock , ulSpinlockCnt );
        }
        BST_DBG_LOG1("BST_SRV_CHNL_Clear,g_ulHighPriCnt--",g_ulHighPriCnt);
        BST_SRV_Q_RmvItem( (BST_SRV_CHNL_Q **)&pstChnlLink->pSentList,
                           (BST_SRV_CHNL_Q *)pSentItem,
                           (BST_SRV_CHNL_Q **)&pSentItem2 );
        BST_OS_FREE( pSentItem );
    }
    for(;;)
    {
        pstPktItem              = BST_SRV_Q_PeekHead(pstChnlLink->pUnsendList);
        if( BST_NULL_PTR == pstPktItem )
        {
            break;
        }
        BST_SRV_Q_RmvItem( (BST_SRV_CHNL_Q **)&pstChnlLink->pUnsendList,
                           (BST_SRV_CHNL_Q *)pstPktItem,
                           (BST_SRV_CHNL_Q **)&pstPktItem2 );
        BST_SRV_FreeIpBlock( pstPktItem );
    }

}
//lint -sem(lstAdd,custodial(2))
BST_ERR_ENUM_UINT8 BST_OS_SendMail( BST_OS_MBX_T *pstMbx, BST_VOID *pMsg )
{
    BST_OS_MAIL_T                      *pstContent;
    BST_OS_LOCKCNT_T                    tThreadLockCnt;

    BST_ASSERT_NULL_RTN( pstMbx, BST_ERR_INVALID_PTR );
    BST_ASSERT_NULL_RTN( pstMbx->hSem, BST_ERR_INVALID_PTR );

    pstContent                          = BST_OS_MALLOC( BST_OS_SIZEOF(BST_OS_MAIL_T) );
    BST_ASSERT_NULL_RTN( pstContent, BST_ERR_NO_MEMORY );

    tThreadLockCnt                      = (BST_OS_LOCKCNT_T)BST_OS_SpinLock( &g_MboxLock );
    pstContent->ulContent               = pMsg;

    lstAdd( &pstMbx->hList, ( NODE * )pstContent );
    BST_OS_SpinUnLock( &g_MboxLock,(BST_UINT32)tThreadLockCnt );
    BST_OS_SendSem( pstMbx->hSem );

    return( BST_NO_ERROR_MSG );
}
BST_ERR_ENUM_UINT8 BST_SRV_CHNL_Acked (
    BST_SRV_CHNL_LINK_STRU     *pstLinkItem,
    const BST_UINT32            ulMinNumber,
    const BST_UINT32            ulMaxNumber )
{
    BST_SRV_CHNL_SENT_STRU             *pSentItem;
    BST_SRV_CHNL_SENT_STRU             *pSentItem2;
    BST_SRV_CHNL_HEAD_STRU             *pstPktItem;
    BST_SRV_CHNL_HEAD_STRU             *pstPktItem2;
    BST_UINT32                          ulSpinlockCnt;
    BST_UINT32                          ulOrigCounter;
    BST_DRV_STRU                       *pNetDrvHandle;
    BST_ERR_ENUM_UINT8                  enRtnVal;

    BST_ASSERT_NULL_RTN( pstLinkItem, BST_ERR_INVALID_PTR );
    BST_ASSERT_NORM_RTN( ulMaxNumber < ulMinNumber, BST_ERR_ILLEGAL_PARAM );

    BST_DBG_LOG2( "BST_SRV_CHNL_Acked ulMinNumber, ulMaxNumber",
                  ulMinNumber, ulMaxNumber );
    /*查找已发送的数据包的*/
    pSentItem                           = BST_SRV_Q_PeekHead(pstLinkItem->pSentList);
    ulOrigCounter                       = g_ulHighPriCnt;
    pSentItem2                          = BST_NULL_PTR;
    pstPktItem2                         = BST_NULL_PTR;
    while( pSentItem != BST_NULL_PTR )
    {
        if ( ( pSentItem->ulAckNo > ulMinNumber )
           &&( pSentItem->ulAckNo <=ulMaxNumber ) )
        {
            if( BST_DSPP_FLG_LVLTYPE_HS == pSentItem->usProcLevel )
            {
                ulSpinlockCnt           = BST_OS_SpinLock( &g_HighPriCntSpinLock );
                if ( g_ulHighPriCnt > 0 )
                {
                    g_ulHighPriCnt--;
                }
                BST_OS_SpinUnLock( &g_HighPriCntSpinLock , ulSpinlockCnt );
            }
            BST_DBG_LOG1("BST_SRV_CHNL_Acked,g_ulHighPriCnt--",g_ulHighPriCnt);
            BST_SRV_Q_RmvItem( (BST_SRV_CHNL_Q **)&pstLinkItem->pSentList,
                               (BST_SRV_CHNL_Q *)pSentItem,
                               (BST_SRV_CHNL_Q **)&pSentItem2 );
            BST_OS_FREE( pSentItem );
        }
        else
        {
            pSentItem2                  = pSentItem->pNext;
        }
        pSentItem                       = pSentItem2;
    }

    pstPktItem                          = BST_SRV_Q_PeekHead(pstLinkItem->pUnsendList);
    while ( pstPktItem != BST_NULL_PTR )
    {
        if( BST_IP_SKT_PROP_NONE != pstPktItem->ucPropType )
        {
            if( ( ( pstPktItem->stProp.ulSeqNum + pstPktItem->ulUsed  ) > ulMinNumber )
              &&( ( pstPktItem->stProp.ulSeqNum + pstPktItem->ulUsed  ) <=ulMaxNumber ) )
            {
                BST_SRV_Q_RmvItem( (BST_SRV_CHNL_Q **)&pstLinkItem->pUnsendList,
                                   (BST_SRV_CHNL_Q *)pstPktItem,
                                   (BST_SRV_CHNL_Q **)&pstPktItem2 );
                BST_SRV_FreeIpBlock( pstPktItem );
            }
            else
            {
                pstPktItem2             = pstPktItem->pNext;
            }
        }
        else
        {
            pstPktItem2                 = pstPktItem->pNext;
        }
        pstPktItem                      = pstPktItem2;
    }
    enRtnVal                            = BST_NO_ERROR_MSG;
    if( BST_NULL_PTR != pstLinkItem->pUnsendList )
    {
        BST_OS_TimerStop( pstLinkItem->ulTimerId );
        BST_DBG_LOG( "BST_SRV_CHNL_Acked, Proc Unsent List" );
        enRtnVal                        = BST_SRV_CHNL_ProcInCB( pstLinkItem );
    }

    /**
     * 刚刚有值,现在无值,那么说明全部高优先数据发送完成
     */
    if( ( 0 != ulOrigCounter ) && ( 0 == g_ulHighPriCnt ) )
    {
        pNetDrvHandle   = BST_DRV_NetGetDvcHandle();
        enRtnVal        = 0;
        pNetDrvHandle->pfIoCtrl( BST_DRV_CMD_HPR_DATA_FINISH, (BST_VOID *)&enRtnVal );
        BST_DBG_LOG( "BST_SRV_CHNL_Acked, BST_DRV_CMD_HPR_DATA_FINISH" );
    }

    return enRtnVal;
}
BST_ERR_ENUM_UINT8 BST_SRV_CHNL_Send_Runing( 
    BST_SRV_CHNL_LINK_STRU     *pstChnlLink,
    BST_SRV_CHNL_HEAD_STRU     *pstPktItem )
{
    BST_SRV_CHNL_SENT_STRU     *pSentItem;
    BST_SRV_CHNL_HEAD_STRU     *pstUnsendItem;
    BST_SRV_CHNL_LINK_STRU     *pstLinkItem2;
    BST_IP_ERR_T                enIpErr;
    BST_DSPP_CAppUlVc          *pstDsppUl;
    BST_UINT32                  ulSpinlockCnt;
    BST_UINT16                  usFlags;

    BST_ASSERT_NULL_RTN( pstChnlLink, BST_ERR_INVALID_PTR );
    BST_ASSERT_NULL_RTN( pstPktItem, BST_ERR_INVALID_PTR );
    enIpErr                     = BST_IP_ERR_OK;
    if( BST_SRV_ChnlIsTail(pstPktItem) )
    {
        usFlags                 = BST_IP_SEND_FLAG_VOID;
    }
    else
    {
        usFlags                 = BST_IP_SEND_FLAG_MORE;
    }
    if( BST_IP_SKT_PROP_NONE != pstPktItem->ucPropType )
    {
        BST_SRV_CHNL_Set_LinkProp( pstChnlLink, pstPktItem );
        pstChnlLink->ulCurrentSeq
                                = pstPktItem->stProp.ulSeqNum;
    }

    BST_DBG_LOG4("BST_SRV_CHNL_Send_Runing Length, ProcLevel, PackAddr, Flag",
                    pstPktItem->ulUsed,
                    pstPktItem->usProcLevel,
                    pstPktItem->ucPktAddr,
                    usFlags );
    switch( pstPktItem->usProcLevel )
    {
        case BST_DSPP_FLG_LVLTYPE_NORMAL:
            enIpErr             = pstChnlLink->pcSocket->Write
                                  ( (const BST_UINT8 *)&pstPktItem->aucData[0],
                                    (BST_UINT16)pstPktItem->ulUsed, BST_IP_BSTT_DATA, usFlags );
        break;

        case BST_DSPP_FLG_LVLTYPE_HS:
            enIpErr             = pstChnlLink->pcSocket->Write
                                  ( (const BST_UINT8 *)&pstPktItem->aucData[0],
                                    (BST_UINT16)pstPktItem->ulUsed,
                                    BST_IP_HPRI_DATA,
                                    usFlags );
        break;

        case BST_DSPP_FLG_LVLTYPE_LP:
            enIpErr             = pstChnlLink->pcSocket->Write
                                  ( (const BST_UINT8 *)&pstPktItem->aucData[0],
                                    (BST_UINT16)pstPktItem->ulUsed,
                                    BST_IP_LPWR_DATA,
                                    usFlags );
        break;

        default:
            return BST_ERR_PAR_UNKNOW;
    }
    if( BST_IP_ERR_OK == enIpErr )
    {
        pSentItem               = ( BST_SRV_CHNL_SENT_STRU *)BST_OS_MALLOC(
                                  BST_OS_SIZEOF( BST_SRV_CHNL_SENT_STRU ) );
        if( BST_NULL_PTR == pSentItem )
        {
            return BST_ERR_NO_MEMORY;
        }
        pstChnlLink->ulCurrentSeq += pstPktItem->ulUsed;
        pSentItem->pNext        = BST_NULL_PTR;
        if ( BST_DSPP_FLG_LVLTYPE_HS == pstPktItem->usProcLevel )
        {
            ulSpinlockCnt       = BST_OS_SpinLock( &g_HighPriCntSpinLock );
            g_ulHighPriCnt++;
            BST_OS_SpinUnLock( &g_HighPriCntSpinLock , ulSpinlockCnt );
        }
        pSentItem->usProcLevel  = pstPktItem->usProcLevel;
        pSentItem->ulAckNo      = pstChnlLink->ulCurrentSeq;
        BST_SRV_Q_PushToTail( (BST_SRV_CHNL_Q **)&pstChnlLink->pSentList,
                              (BST_SRV_CHNL_Q *)pSentItem );
        BST_DBG_LOG3("tiger BST_SRV_FreeIpBlock1 g_ulHighPriCnt++, sent",pstPktItem, g_ulHighPriCnt, pstPktItem->ulUsed);
        BST_SRV_FreeIpBlock( pstPktItem );
    }
    else if( BST_IP_ERR_MEM == enIpErr )
    {
        /*申请空间存储未发送的数据,避免在处理完成时将数据释放*/
        pstUnsendItem           = BST_SRV_AlocIpBlock();
        if ( BST_NULL_PTR == pstUnsendItem )
        {
            return BST_ERR_NO_MEMORY;
        }
        BST_OS_MEMCPY( pstUnsendItem, pstPktItem, BST_OS_SIZEOF(BST_SRV_CHNL_HEAD_STRU));
        BST_SRV_CHNL_Send_Suspend( pstChnlLink, pstUnsendItem );
        pstChnlLink->enState    = BST_SRV_CHNL_STATE_SUSPEND;
        return BST_ERR_NO_MEMORY;
    }
    else
    {
        pstDsppUl               = BST_DSPP_CAppUlVc::GetInstance();
        if( pstChnlLink->ulAddrType == BST_DSPP_FLG_ADDTYPE_INET )
        {
            pstDsppUl->Report( BST_DSPP_FLG_CMD_CLOSE,
                               pstChnlLink->stLink.ulMainLinkId,
                               pstChnlLink->stLink.ulAuxLinkId );
            BST_SRV_CHNL_ReportTrafficFlow( pstChnlLink );
        }
        else
        {
            pstDsppUl->Report( BST_DSPP_FLG_CMD_CLOSE,
                               pstChnlLink->stDspp.usProcId,
                               pstChnlLink->stDspp.usTaskId );
        }
        BST_SRV_CHNL_Close( pstChnlLink );
        delete pstChnlLink->pcSocket;
        BST_SRV_Q_RmvItem( (BST_SRV_CHNL_Q **)&g_lstChnlMng,
                           (BST_SRV_CHNL_Q *)pstChnlLink,
                           (BST_SRV_CHNL_Q **)&pstLinkItem2 );
        BST_OS_FREE(pstChnlLink);
        return BST_ERR_SOCKET_CLSD;
    }
    return BST_NO_ERROR_MSG;
}
BST_ERR_ENUM_UINT8 BST_SRV_CHNL_Send_InCB( 
    BST_SRV_CHNL_LINK_STRU     *pstChnlLink,
    BST_SRV_CHNL_HEAD_STRU     *pstPktItem )
{
    BST_SRV_CHNL_SENT_STRU     *pSentItem;
    BST_IP_ERR_T                enIpErr;
    BST_UINT16                  usFlags;
    BST_UINT32                  ulSpinlockCnt;

    BST_ASSERT_NULL_RTN( pstChnlLink, BST_ERR_INVALID_PTR );
    BST_ASSERT_NULL_RTN( pstPktItem, BST_ERR_INVALID_PTR );
    enIpErr                     = BST_IP_ERR_OK;
    if( BST_SRV_ChnlIsTail(pstPktItem) )
    {
        usFlags                 = BST_IP_SEND_FLAG_VOID;
    }
    else
    {
        usFlags                 = BST_IP_SEND_FLAG_MORE;
    }

    if( BST_IP_SKT_PROP_NONE != pstPktItem->ucPropType )
    {
        BST_SRV_CHNL_Set_LinkProp( pstChnlLink, pstPktItem );
        pstChnlLink->ulCurrentSeq= pstPktItem->stProp.ulSeqNum;
    }
    BST_DBG_LOG4("BST_SRV_CHNL_Send_InCB Length, ProcLevel, PackAddr, Flag",
                    pstPktItem->ulUsed,
                    pstPktItem->usProcLevel,
                    pstPktItem->ucPktAddr,
                    usFlags );

    switch( pstPktItem->usProcLevel )
    {
        case BST_DSPP_FLG_LVLTYPE_NORMAL:
            enIpErr             = pstChnlLink->pcSocket->Write
                                  ( (const BST_UINT8 *)&pstPktItem->aucData[0],
                                    (BST_UINT16)pstPktItem->ulUsed, BST_IP_BSTT_DATA, usFlags );
        break;

        case BST_DSPP_FLG_LVLTYPE_HS:
            enIpErr             = pstChnlLink->pcSocket->Write
                                  ( (const BST_UINT8 *)&pstPktItem->aucData[0],
                                    (BST_UINT16)pstPktItem->ulUsed,
                                    BST_IP_HPRI_DATA,
                                    usFlags );
        break;

        case BST_DSPP_FLG_LVLTYPE_LP:
            enIpErr             = pstChnlLink->pcSocket->Write
                                  ( (const BST_UINT8 *)&pstPktItem->aucData[0],
                                    (BST_UINT16)pstPktItem->ulUsed,
                                    BST_IP_LPWR_DATA,
                                    usFlags );
        break;

        default:
            return BST_ERR_PAR_UNKNOW;
    }
    if( BST_IP_ERR_OK == enIpErr )
    {
        pSentItem               = ( BST_SRV_CHNL_SENT_STRU *)BST_OS_MALLOC(
                                  BST_OS_SIZEOF( BST_SRV_CHNL_SENT_STRU ) );
        if( BST_NULL_PTR == pSentItem )
        {
            return BST_ERR_INVALID_PTR;
        }
        pstChnlLink->ulCurrentSeq += pstPktItem->ulUsed;
        pstChnlLink->ulRetryTimes  = 0;
        pSentItem->usProcLevel  = pstPktItem->usProcLevel;
        pSentItem->pNext        = BST_NULL_PTR;
        pSentItem->ulAckNo      = pstChnlLink->ulCurrentSeq;
        BST_SRV_Q_PushToTail( (BST_SRV_CHNL_Q **)&pstChnlLink->pSentList,
                              (BST_SRV_CHNL_Q *)pSentItem );
        if ( BST_DSPP_FLG_LVLTYPE_HS == pstPktItem->usProcLevel )
        {
            ulSpinlockCnt       = BST_OS_SpinLock( &g_HighPriCntSpinLock );
            g_ulHighPriCnt++;
            BST_OS_SpinUnLock( &g_HighPriCntSpinLock , ulSpinlockCnt );
            BST_DBG_LOG2(" g_ulHighPriCnt++, sent", g_ulHighPriCnt, pstPktItem->ulUsed);
        }
    }
    else if( BST_IP_ERR_MEM == enIpErr )
    {
        pstChnlLink->ulRetryTimes++;
        BST_OS_TimerStart( pstChnlLink->ulTimerId, BST_SRV_CHNL_RTX_INTERVAL );
        return BST_ERR_NO_MEMORY;
    }
    else
    {
        return BST_ERR_SOCKET_CLSD;
    }
    return BST_NO_ERROR_MSG;
}