VOS_UINT32 TAF_CBA_IsRecordExpired(
    TAF_CBA_RECORD_STRU                *pstRecord
)
{
    VOS_UINT32                          ulCurrtTick;
    VOS_UINT32                          ulPassSeconds;

    /* VOS TICK 是递增的,10 ms 为单位 */
    ulCurrtTick = VOS_GetTick();

    /* 有效时长为0则表示一直有效 */
    if ( 0 == pstRecord->ulDupDetcTimeLen )
    {
        return VOS_FALSE;
    }

    if ( ulCurrtTick < pstRecord->ulRcvTimeTick )
    {
        TAF_ERROR_LOG(WUEPS_PID_TAF, "TAF_CBA_IsRecordExpired ,CurrtTick error.\n");
        TAF_CBA_SndOmLogInfo(TAF_CBA_OM_LOG_TICK_ERROR);
        return VOS_FALSE;
    }

    /* 是否超过重复检测时长 */
    ulPassSeconds = (ulCurrtTick - pstRecord->ulRcvTimeTick)/100;
    if ( ulPassSeconds >= pstRecord->ulDupDetcTimeLen )
    {
        return VOS_TRUE;
    }

    return VOS_FALSE;
}
PS_RSLT_CODE_ENUM_UINT32 PS_Qnode_Trace(VOS_UINT16 usFileID, VOS_UINT16 usLineNum,
            VOS_UINT32 ulPid, PS_QNODE_STRU *pstQnode)
{
    VOS_UINT32                      ulTick;
    VOS_UINT32                      ulQnodeAddr;
    VOS_UINT32                      ulFirstQnodeAddr;

    ulTick  =   VOS_GetTick();

    if (VOS_NULL_PTR == pstQnode)
    {
        TTF_LOG4(ulPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "FileId, LineId, Pid, tick, pstQnode is NULL",
            usFileID, usLineNum, (VOS_INT32)ulPid, (VOS_INT32)ulTick);
        return PS_FAIL;
    }

    ulQnodeAddr         =   (VOS_UINT32)pstQnode;
    ulFirstQnodeAddr    =   (VOS_UINT32)(&g_astQnode[0]);

    if (0 != (ulQnodeAddr - ulFirstQnodeAddr) % sizeof(g_astQnode[0]))
    {
        TTF_LOG4(ulPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "FileId, LineId, Pid, tick, pstQnode is invalid",
            usFileID, usLineNum, (VOS_INT32)ulPid, (VOS_INT32)ulTick);
        return PS_FAIL;
    }

    pstQnode->stDbg.ulTraceTick     =   ulTick;
    pstQnode->stDbg.usTraceFileId   =   usFileID;
    pstQnode->stDbg.usTraceLineNum  =   usLineNum;

    return PS_SUCC;
} /* PS_Qnode_Trace */
BST_UINT32 BST_OS_PalTimerNowMs( BST_VOID )
{
    BST_UINT32                          ulSysNow;

    ulSysNow    = VOS_GetTick();
    ulSysNow   *= BST_OS_TICKS_MS;

    return ulSysNow;
}
VOS_VOID diag_Debug(DIAG_DEBUG_MSG_ID_ENUM ulType,
                     VOS_UINT32 ulRserved1, VOS_UINT32 ulRserved2, VOS_UINT32 ulRserved3)
{
    g_ast_diag_debug_info_table[ulType].ulCalledNum += 1;
    g_ast_diag_debug_info_table[ulType].ulRserved1 = ulRserved1;
    g_ast_diag_debug_info_table[ulType].ulRserved2 = ulRserved2;
    g_ast_diag_debug_info_table[ulType].ulRserved3 = ulRserved3;
    g_ast_diag_debug_info_table[ulType].ulRtcTime  = VOS_GetTick();


}
VOS_VOID  TAF_APS_StartDsFlowStats(
    VOS_UINT8                           ucRabId
)
{
    VOS_UINT32                          ulIndex;
    TAF_APS_DSFLOW_STATS_CTX_STRU      *pstApsDsFlowCtx;
    VOS_UINT16                          usModemid;

    /* 判断RAB ID是否有效 */
    if ((ucRabId < TAF_APS_RAB_ID_MIN)
     || (ucRabId > TAF_APS_RAB_ID_MAX))
    {
        return;
    }

    /* 初始化 */
    ulIndex         = ucRabId - TAF_APS_RAB_ID_OFFSET;
    pstApsDsFlowCtx = TAF_APS_GetDsFlowCtxAddr();

    /* 检查RAB是否已经激活 */
    if (VOS_TRUE == pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].ucRabActiveFlag)
    {
        TAF_NORMAL_LOG1(WUEPS_PID_TAF, "TAF_APS_StartDsFlowStats:NORMAL:RABM is already active! RABID:", ucRabId);
        return;
    }

    /*置该RABID激活标志:*/
    pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].ucRabActiveFlag = VOS_TRUE;

    /* 调用CDS API 清除该RABID的历史流量 */
    usModemid = VOS_GetModemIDFromPid(WUEPS_PID_TAF);
    CDS_ClearBearerDataFlowInfo(ucRabId, usModemid);


    /* 初始化APS当前连接流量信息为0 */
    PS_MEM_SET(&pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].stCurrentFlowInfo,
                0,
                sizeof(TAF_DSFLOW_INFO_STRU));
    /* 记录当前连接开始时间 */
    pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].ulStartLinkTime = VOS_GetTick() / PRE_SECOND_TO_TICK;

    /* 启动流量上报定时器 */
    TAF_APS_StartDsFlowRpt();

    /* 如果需要保存到NV项中,启动周期性保存流量到NV定时器 */
    if (VOS_TRUE == pstApsDsFlowCtx->ucDsFlowSave2NvFlg)
    {
        TAF_APS_StartTimer(TI_TAF_APS_DSFLOW_WRITE_NV,
                           (pstApsDsFlowCtx->ucDsFlowSavePeriod * 60 * TIMER_S_TO_MS_1000),
                           TAF_APS_INVALID_PDPID);
    }
    return;
}
PS_RSLT_CODE_ENUM_UINT32 PS_Qnode_FillMemInfo(VOS_UINT16   usFileId,
                            VOS_UINT16                     usLineId,
                            VOS_UINT32                     ulPid,
                            PS_QNODE_STRU                 *pstQnode,
                            PS_QNODE_MEM_SOURCE_STRU      *pstMemSrc,
                            VOS_UINT8                      ucParaOctetCnt,
                            VOS_UINT8                      aucPara[])
{
    VOS_UINT32  ulTick;

    ulTick  =   VOS_GetTick();

    if (VOS_NULL_PTR == pstQnode)
    {
        TTF_LOG4(ulPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "fileid, line, pid, tick, pstQnode is NULL",
            usFileId, usLineId, (VOS_INT32)ulPid, (VOS_INT32)ulTick);
        return PS_FAIL;
    }

    if (VOS_NULL_PTR == pstMemSrc)
    {
        TTF_LOG4(ulPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "fileid, line, pid, tick, pstMemSrc is NULL",
            usFileId, usLineId, (VOS_INT32)ulPid, (VOS_INT32)ulTick);
        return PS_FAIL;
    }

    if (PS_QNODE_FREE_STATE == pstQnode->enState)
    {
        TTF_LOG4(ulPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "fileid, line, pid, tick, pstQnode state is free",
            usFileId, usLineId, (VOS_INT32)ulPid, (VOS_INT32)ulTick);
        return PS_FAIL;
    }

    if (ucParaOctetCnt > MAX_PARA_OCTET_NUM)
    {
        TTF_LOG(ulPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "more than allowed para octet num");
        return PS_FAIL;
    }

    PS_MEM_CPY(&(pstQnode->stMemSrc), pstMemSrc, sizeof(pstQnode->stMemSrc));
    if (0 != ucParaOctetCnt)
    {
        PS_MEM_CPY(&(pstQnode->aucPara[0]), aucPara, (ucParaOctetCnt * sizeof(VOS_UINT8)));
    }

    return PS_SUCC;
} /* PS_Qnode_FillMemInfo */
/*****************************************************************************
 函 数 名  : chap_Challenge
 功能描述  : 构造Challenge帧并发送
 输入参数  : l - PPP链接
 输出参数  : 无
 返 回 值  : 无
 调用函数  :
 被调函数  :

 修改历史      :
  1.日    期   : 2008年10月25日
    作    者   : liukai
    修改内容   : porting from BSD

*****************************************************************************/
VOS_VOID chap_Challenge(struct link *l)
{
    struct chap *chap = &(l->chap);
    VOS_UINT32 len, i;
    VOS_UINT8 *cp;
    VOS_UINT32 ulTick;
    const VOS_CHAR acLocalChallenge[] = "HUAWEI_CHAP_SRVR";   /* we always use "HUAWEI_CHAP_SRVR" as Name of Challenge */

    /* Challenge body: */
    /*
     *  ------------------------ --------------------- ----------
     * |   Challenge-Size(1B)   |   Challenge-Value   |   Name   |
     *  ------------------------ --------------------- ----------
     */
    len = VOS_StrLen((VOS_CHAR *)acLocalChallenge);

    if (0x0 == *(chap->challenge.local)) {    /* as each time local[0] is 0x0, here is always true */
        ulTick = VOS_GetTick();
        VOS_SetSeed(ulTick);    /* use current tick as seed of random algorithm */

        cp = chap->challenge.local;
        /*AT2D19295 测试组建议challenge中随机字符串长度固定为16,和标杆一致 */
        *cp++ = (VOS_UINT8)(MD5DIGESTSIZE);

        /*
          *cp++ = (VOS_UINT8)(PS_RAND(CHAPCHALLENGELEN-MD5DIGESTSIZE) + MD5DIGESTSIZE);
          随机字串长度本为任意长度, 存放在local的第一个字节,为了防止对端只支持MD5而要求长度为16, 特意保证长度至少16字节
        */
        for (i = 0; i < *(chap->challenge.local); i++)
        {
            *cp++ = (VOS_UINT8)PS_RAND(PS_NULL_UINT8+1);    /* 随机字串 */
        }

        /* use memcpy instead of strcpy, as "The Name should not be NUL or CR/LF terminated." in RFC1994 */
        PS_MEM_CPY(cp, acLocalChallenge, len);
    }

    /* each time send challenge, record its packet */
    ChapBufferChallengePacket(chap, chap->auth.id, chap->challenge.local,
                              1 + *(chap->challenge.local) + len);

    ChapOutput(l, CHAP_CHALLENGE, chap->auth.id, chap->challenge.local,
               1 + *(chap->challenge.local) + len, VOS_NULL_PTR);    /* 1: challenge length, *local: 随机字串长度, len: Name length */

    return;
}    /* chap_Challenge */
VOS_VOID  TAF_APS_ClearDsFlowStats(
    VOS_UINT8                           ucRabId
)
{
    VOS_UINT32                          ulIndex;
    VOS_UINT8                           ucRabActiveFlag;
    TAF_APS_DSFLOW_STATS_CTX_STRU      *pstApsDsFlowCtx;
    VOS_UINT16                          usModemid;


    /* 初始化 */
    ulIndex         = ucRabId - TAF_APS_RAB_ID_OFFSET;
    pstApsDsFlowCtx = TAF_APS_GetDsFlowCtxAddr();

    /* 先保存该RABID激活标志 */
    ucRabActiveFlag = pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].ucRabActiveFlag;

    /* 流量统计上下文指定RABID流量信息清零 */
    PS_MEM_SET(&pstApsDsFlowCtx->astApsDsFlowStats[ulIndex],
                0,
                sizeof(TAF_APS_DSFLOW_STATS_STRU));

    /* 恢复该RABID激活标志信息 */
    pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].ucRabActiveFlag = ucRabActiveFlag;

    /* 如果RAB已激活,将当前连接时间置为当前时间,同时通知CDS清除流量信息 */
    if (VOS_TRUE == ucRabActiveFlag)
    {
        /* 调用CDS API 清除该RABID的流量信息 */
        usModemid = VOS_GetModemIDFromPid(WUEPS_PID_TAF);
        CDS_ClearBearerDataFlowInfo(ucRabId, usModemid);

        /* 记录当前连接开始时间 */
        pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].ulStartLinkTime = VOS_GetTick() / PRE_SECOND_TO_TICK;
    }

    return;
}
VOS_VOID mntn_UpdateMsgInfo(L4A_MNTN_MSG_INFO_STRU *pstMsg, VOS_UINT32 ulMsgId)
{
    pstMsg->aulMsgId[pstMsg->ulptr] = ulMsgId;
    pstMsg->aulTime[pstMsg->ulptr]  = VOS_GetTick();
    pstMsg->ulptr                   = (pstMsg->ulptr + 1) % L4A_MNTN_MSG_NUM;
}
VOS_VOID  TAF_APS_GetCurrentFlowInfo(
    VOS_UINT8                           ucRabId,
    TAF_DSFLOW_INFO_STRU               *pstCurrentFlowInfo
)
{
    CDS_BEARER_DATA_FLOW_STRU           stDataFlowInfo;
    TAF_APS_DSFLOW_STATS_CTX_STRU      *pstApsDsFlowCtx;
    VOS_UINT32                          ulIndex;
    VOS_UINT32                          ulCurSysTime;
    VOS_UINT16                          usModemid;

    if (ucRabId < TAF_APS_RAB_ID_OFFSET)
    {
        ucRabId = TAF_APS_RAB_ID_OFFSET;
    }

    /* 初始化 */
    pstApsDsFlowCtx = TAF_APS_GetDsFlowCtxAddr();
    ulIndex         = ucRabId - TAF_APS_RAB_ID_OFFSET;

    /* 如果激活 */
    /* 调用CDS API CDS_GetBearerDataFlowInfo获取当前连接流量 */
    /* RABID当前流量 = CDS返回的当前连接流量 */

    /* 如果未激活 */
    /* RABID当前流量 = APS流量统计上下文保存的当前连接流量 */

    if (ulIndex >= TAF_APS_MAX_RAB_NUM)
    {
        ulIndex = TAF_APS_MAX_RAB_NUM - 1;
    }

    /* 获取指定RABID的当前连接流量信息 */
    if (VOS_TRUE == pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].ucRabActiveFlag)
    {
        /* 流量信息初始化 */
        PS_MEM_SET(&stDataFlowInfo, 0, sizeof(CDS_BEARER_DATA_FLOW_STRU));

        usModemid = VOS_GetModemIDFromPid(WUEPS_PID_TAF);
        CDS_GetBearerDataFlowInfo(ucRabId, &stDataFlowInfo, usModemid);

        /* 刷新流量上下文当前连接流量信息 */
        pstCurrentFlowInfo->ulDSReceiveFluxHigh
                                    = stDataFlowInfo.ulTotalReceiveFluxHigh;

        pstCurrentFlowInfo->ulDSReceiveFluxLow
                                    = stDataFlowInfo.ulTotalReceiveFluxLow;

        pstCurrentFlowInfo->ulDSSendFluxHigh
                                    = stDataFlowInfo.ulTotalSendFluxHigh;

        pstCurrentFlowInfo->ulDSSendFluxLow
                                    = stDataFlowInfo.ulTotalSendFluxLow;

        /* 当前连接时间:当前时间-PDP激活时间 */
        ulCurSysTime = VOS_GetTick() / PRE_SECOND_TO_TICK;

        /*与结构体中开始连接时间运算,得到本次连接总时间:*/
        if ( VOS_OK != TAF_CalcTime(pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].ulStartLinkTime,
                                    ulCurSysTime,
                                    &pstCurrentFlowInfo->ulDSLinkTime) )
        {
            /*打印警告信息---计算最后一次DS从开始连接到现在所经历的时间(秒数)时出错:*/
            TAF_WARNING_LOG1( WUEPS_PID_TAF,
                              "TAF_APS_UpdateCurrentFlowInfo:WARNING:TAF_CalcTime FAIL! RabId:",
                              ucRabId );
        }

    }
    else
    {
        PS_MEM_CPY(pstCurrentFlowInfo,
                  &pstApsDsFlowCtx->astApsDsFlowStats[ulIndex].stCurrentFlowInfo,
                   sizeof(TAF_DSFLOW_INFO_STRU) );
    }

    return;
}
VOS_UINT32 OM_GetSlice(VOS_VOID)
{
    return VOS_GetTick();
}
示例#12
0
/******************************************************************************
 Prototype      : R_ITF_ClearFlowCtrl
 Description    : 根据最新情况,判断是否需要解除流控
 Input          : ulFlowCtrlType    -- 流控类型
                  ulNewLev          -- 该流控类型的最新值
 Output         :
 Return Value   :
 Calls          :
 Called By      :

 History        : ---
  1.Date        : 2008-04-07
    Modification: Created function
******************************************************************************/
VOS_UINT32 R_ITF_ClearFlowCtrl(VOS_UINT32 ulFlowCtrlType, VOS_UINT32 ulNewLev)
{
    R_ITF_FLOW_LEV_STRU    *pFlowLev;
    VOS_INT32               lLockKey;
    VOS_UINT32              ulCurrTick;
    VOS_UINT32              ulResult;                /* 流控执行结果 */
    VOS_UINT32              ulUpdatedMask;


    if (R_ITF_FLOW_CTRL_TYPE_BUTT <= ulFlowCtrlType)
    {
        return VOS_ERR;
    }

    /* 进入流控临界区 */
    lLockKey            = VOS_SplIMP();

    ulNeedExec          = PS_FALSE;
    ulResult            = VOS_OK;
    pFlowLev            = &g_stRItfFlowCtrl.astFlowCtrl[ulFlowCtrlType];
    ulCurrTick          = VOS_GetTick();

    /* 流控实体里保存的当前值需要做互斥保护 */
    pFlowLev->ulCurrLev = ulNewLev;

    /* 并没有因为该种类型导致流控, 无须解除流控 */
    if (0 == (g_stRItfFlowCtrl.ulCtrlMask & pFlowLev->ulMask))
    {
        VOS_Splx(lLockKey);
        return VOS_OK;
    }

    if (ulNewLev < pFlowLev->ulNormalLev)
    {
        if ((ulCurrTick - g_stRItfFlowCtrl.ulLastOptTick) >= g_ulRItfFlowCtrlProTime)
        {
            ulUpdatedMask = g_stRItfFlowCtrl.ulCtrlMask &  (~(pFlowLev->ulMask));

            /*所有流控条件都解除的情况下,执行解除流控操作*/
            if ( 0 == ulUpdatedMask )
            {
                ulNeedExec      = PS_TRUE;

                g_stRItfFlowCtrl.ulLastOptTick = ulCurrTick;
                g_stRItfFlowCtrl.ulCtrlMask   &=  ~(pFlowLev->ulMask);

                g_stRItfFlowCtrl.ulGprsCtrlFlag = R_ITF_FLOW_CTRL_STOP;
            }
        }
    }

    /* 离开流控临界区 */
    VOS_Splx(lLockKey);

    if (PS_TRUE == ulNeedExec)
    {
        ulResult        = R_ITF_GprsFlowCtrlNotify();    /* 调用流控解除函数 */

        if (VOS_OK == ulResult)
        {
            /*流控事件可维可测*/
            R_ITF_MntnFlowCtrlEvent(ulFlowCtrlType, ulNewLev, R_ITF_FLOW_CTRL_STOP, ulResult);
        }
    }

    return ulResult;
} /* R_ITF_ClearFlowCtrl */
示例#13
0
/******************************************************************************
 Prototype      : R_ITF_SetFlowCtrl
 Description    : 根据最新情况,判断是否需要进行流控
 Input          : ulFlowCtrlType    -- 流控类型
                  ulNewLev          -- 该流控类型的最新值
 Output         :
 Return Value   :
 Calls          :
 Called By      :

 History        : ---
  1.Date        : 2008-04-07
    Modification: Created function
  2.Date        : 2011-04-15
    Modification: 重构流控执行函数,增加流控状态标志位设置保护
******************************************************************************/
VOS_UINT32 R_ITF_SetFlowCtrl(VOS_UINT32 ulFlowCtrlType, VOS_UINT32 ulNewLev)
{
    R_ITF_FLOW_LEV_STRU                 *pFlowLev;
    VOS_INT32                           lLockKey;
    VOS_UINT32                          ulOldMask;
    VOS_UINT32                          ulCurrTick;
    VOS_UINT32                          ulResult;                /* 流控执行结果 */


    if (R_ITF_FLOW_CTRL_TYPE_BUTT <= ulFlowCtrlType)
    {
        return VOS_ERR;
    }

    /* 进入流控临界区 */
    lLockKey            = VOS_SplIMP();

    ulNeedExec          = PS_FALSE;
    ulResult            = VOS_OK;
    pFlowLev            = &g_stRItfFlowCtrl.astFlowCtrl[ulFlowCtrlType];
    ulCurrTick          = VOS_GetTick();

    if (pFlowLev->ulMaxLev < ulNewLev)
    {
        pFlowLev->ulMaxLev = ulNewLev;
    }

    /* 流控实体里保存的当前值需要做互斥保护 */
    pFlowLev->ulCurrLev = ulNewLev;
    ulOldMask           = g_stRItfFlowCtrl.ulCtrlMask;

    /* 处于解流控状态时超过阀值, 启动流控 */
    if (ulNewLev >= pFlowLev->ulWarningLev)
    {
        if (0 == ulOldMask)
        {
            ulNeedExec  = PS_TRUE;

            g_stRItfFlowCtrl.ulLastOptTick  = ulCurrTick;
            g_stRItfFlowCtrl.ulCtrlMask    |=  pFlowLev->ulMask;

            g_stRItfFlowCtrl.ulGprsCtrlFlag = R_ITF_FLOW_CTRL_START;
        }
    }

    /* 离开流控临界区 */
    VOS_Splx(lLockKey);

    if (PS_TRUE == ulNeedExec)
    {
        ulResult        = R_ITF_GprsFlowCtrlNotify();    /* 调用流控函数 */
        R_ITF_UpdateFlowCtrlCnt();

        if (VOS_OK == ulResult)
        {
            R_ITF_MntnFlowCtrlEvent(ulFlowCtrlType, ulNewLev, R_ITF_FLOW_CTRL_START, ulResult);
        }
    }

    return ulResult;
} /* R_ITF_SetFlowCtrl */
PS_RSLT_CODE_ENUM_UINT32 PS_Qnode_FreeNode(VOS_UINT16       usFileId,
                                       VOS_UINT16      usLineId,
                                       VOS_UINT32      ulOpPid,
                                       PS_QNODE_STRU  *pstQnode)
{
    VOS_UINT32                      ulTick;
    VOS_INT32                       lLockKey;
    PS_QNODE_TAMPERED_EVENT_STRU    stEvent;
    const VOS_UINT16                us32Bit = 32;
    VOS_UINT16                      usCurrPos;
    VOS_UINT16                      usCurrOffset;
    VOS_UINT32                      ulQnodeAddr;
    VOS_UINT32                      ulFirstQnodeAddr;
    VOS_UINT32                      ulLastQnodeAddr;


    ulTick  =   VOS_GetTick();

    if (VOS_NULL_PTR == pstQnode)
    {
        lLockKey    =   VOS_SplIMP();

        g_stMgmt.stStat.ulFreeNullPtrCnt++;
        g_stMgmt.stStat.ulFreeTotalCnt++;

        VOS_Splx(lLockKey);

        TTF_LOG4(ulOpPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "FileId, LineId, Pid, tick, pstQnode is NULL",
            usFileId, usLineId, (VOS_INT32)ulOpPid, (VOS_INT32)ulTick);
        return PS_FAIL;
    }

    ulQnodeAddr         =   (VOS_UINT32)pstQnode;
    ulFirstQnodeAddr    =   (VOS_UINT32)(&g_astQnode[0]);
    ulLastQnodeAddr     =   (VOS_UINT32)(&g_astQnode[MAX_PS_QNODE_NUM - 1]);

    if ((0 != (ulQnodeAddr - ulFirstQnodeAddr) % sizeof(g_astQnode[0]))
        || ((ulQnodeAddr > ulLastQnodeAddr)
        || (ulQnodeAddr < ulFirstQnodeAddr)))
    {
        lLockKey    =   VOS_SplIMP();

        g_stMgmt.stStat.ulFreeInvalidPrtCnt++;
        g_stMgmt.stStat.ulFreeTotalCnt++;

        VOS_Splx(lLockKey);

        TTF_LOG4(ulOpPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "FileId, LineId, Pid, tick, pstQnode is invalid",
            usFileId, usLineId, (VOS_INT32)ulOpPid, (VOS_INT32)ulTick);
        return PS_FAIL;
    }

    if (PS_QNODE_MAGICNUM == pstQnode->usMagic)    /* 未篡改 */
    {
        if (PS_QNODE_USED_STATE != pstQnode->enState)
        {
            lLockKey    =   VOS_SplIMP();

            g_stMgmt.stStat.ulFreePtrBeforeCnt++;
            g_stMgmt.stStat.ulFreeTotalCnt++;

            VOS_Splx(lLockKey);

            TTF_LOG4(ulOpPid, DIAG_MODE_COMM, PS_PRINT_WARNING,
                "FileId, LineId, Pid, tick, pstQnode has already been freed before",
                usFileId, usLineId, (VOS_INT32)ulOpPid, (VOS_INT32)ulTick);
            return PS_FAIL;
        }
    }
    else    /* 被篡改 */
    {
        lLockKey    =   VOS_SplIMP();

        g_stMgmt.stStat.ulMagicTamperedCnt++;

        /* 强制恢复 */
        pstQnode->usMagic   =   PS_QNODE_MAGICNUM;
        pstQnode->usIndex   =   (VOS_UINT16)((ulQnodeAddr - ulFirstQnodeAddr) / sizeof(g_astQnode[0]));

        VOS_Splx(lLockKey);

        /* 填写event */
        stEvent.usFileId    =   usFileId;
        stEvent.usLineId    =   usLineId;
        stEvent.ulPid       =   ulOpPid;
        stEvent.ulTick      =   ulTick;

        stEvent.usEventId   =   ID_PS_QNODE_FOUND_TAMPERED;

        mdrv_memcpy(&(stEvent.stQnode), pstQnode, sizeof(stEvent.stQnode));

        /* SDT要求event id必须挂接在某个固定的PID下, 暂决定挂在WRLC下 */
        PS_Qnode_SendEvent(WUEPS_PID_RLC, ID_PS_QNODE_FOUND_TAMPERED, &stEvent,
            sizeof(stEvent));

        TTF_LOG4(ulOpPid, 0, PS_PRINT_ERROR,
            "FileId, LineId, Pid, Qnode magic number tampered pstQnode",
            usFileId, usLineId, (VOS_INT32)ulOpPid, (VOS_INT32)pstQnode);
        TTF_LOG1(ulOpPid, 0, PS_PRINT_ERROR,
            "found magic number tampered pstQnode at tick",
            (VOS_INT32)ulTick);
    }

    lLockKey    =   VOS_SplIMP();

    PS_MEM_SET(&(pstQnode->stMemSrc), 0x0, sizeof(pstQnode->stMemSrc));
    PS_MEM_SET(&(pstQnode->aucPara[0]), 0x0, sizeof(pstQnode->aucPara));

    pstQnode->stDbg.ulTraceTick     =   ulTick;
    pstQnode->stDbg.usTraceFileId   =   usFileId;
    pstQnode->stDbg.usTraceLineNum  =   usLineId;

    /* 刷新快表 */
    usCurrPos      =   (pstQnode->usIndex) / us32Bit;
    usCurrOffset   =   (pstQnode->usIndex) % us32Bit;
    TTF_CLEAR_A_BIT(g_stMgmt.aulQuickMap[usCurrPos], ((us32Bit - 1) - usCurrOffset));

    /* 刷新统计 */
    g_stMgmt.stStat.ulFreeTotalCnt++;

    /* 把更新状态放在最后, 因为放前面, 可能出现getnode中一旦发现state可以申请就取走结点了,
       多线程下会出现freenode未结束, 结点已经被取走使用 */
    pstQnode->enState   =   PS_QNODE_FREE_STATE;

    VOS_Splx(lLockKey);

    return PS_SUCC;
} /* PS_Qnode_FreeNode */
PS_QNODE_STRU* PS_Qnode_GetNode(VOS_UINT16 usFileId,
                                VOS_UINT16 usLineId,
                                VOS_UINT32 ulPid)
{
    PS_QNODE_STRU              *pstQnode = VOS_NULL_PTR;
    VOS_UINT16                  usCurrQnodeIdx;
    VOS_UINT32                  ulTick;
    VOS_INT32                   lLockKey;
    const VOS_UINT16            us32Bit = 32;
    VOS_UINT16                  usStartPos;
    VOS_UINT32                  ulCurr32Bit;
    VOS_UINT16                  usCurrPos;
    VOS_UINT32                  ulTmp;
    VOS_UINT32                  ulLoop;
    const VOS_UINT32            ulMask = 0x80000000;

    ulTick          =   VOS_GetTick();
    usCurrQnodeIdx  =   g_stMgmt.usNodeIdx;
    usStartPos      =   usCurrQnodeIdx / us32Bit;    /* 记录StartPos */
    usCurrPos       =   usStartPos;

    do
    {
        ulCurr32Bit = g_stMgmt.aulQuickMap[usCurrPos];

        if (PS_NULL_UINT32 != ulCurr32Bit)    /* 有值为0的bit, 说明有空位 */
        {
            /* 下边找第一个为1的bit */
            ulTmp   =   ~ulCurr32Bit;

            for (ulLoop = 0; ulLoop < us32Bit; ulLoop++)
            {
                if (ulTmp & ulMask)
                {
                    usCurrQnodeIdx = (VOS_UINT16)(PS_MOD_ADD((usCurrPos * us32Bit), ulLoop, MAX_PS_QNODE_NUM));
                    break;
                }

                ulTmp <<= 1;
            }

            pstQnode    =   &(g_astQnode[usCurrQnodeIdx]);

            lLockKey    =   VOS_SplIMP();

            if (PS_QNODE_FREE_STATE == pstQnode->enState)
            {
                pstQnode->enState               =   PS_QNODE_USED_STATE;

                pstQnode->stDbg.ulAllocTick     =   ulTick;
                pstQnode->stDbg.usAllocFileId   =   usFileId;
                pstQnode->stDbg.usAllocLineNum  =   usLineId;

                /* 刷新快表 */
                TTF_SET_A_BIT(ulCurr32Bit, (us32Bit - ulLoop - 1));
                g_stMgmt.aulQuickMap[usCurrPos] = ulCurr32Bit;

                /* 回写返回节点的索引值 */
                g_stMgmt.usNodeIdx = PS_MOD_ADD(usCurrQnodeIdx, 1, MAX_PS_QNODE_NUM);

                /* 刷新统计 */
                g_stMgmt.stStat.ulAllocTotalCnt++;

                VOS_Splx(lLockKey);

                /* 若正在统计申请情况,需统计到申请总次数 */
                if (PS_TRUE == g_stPsQnodeResetStatInfo.enStartStat)
                {
                    g_stPsQnodeResetStatInfo.usTotalStatCnt++;
                }

                return pstQnode;
            }

            VOS_Splx(lLockKey);
        }

        usCurrPos = PS_MOD_ADD(usCurrPos, 1, MAX_PS_QNODE_4BYTE_ALIGN_NUM);
    }
    while (usCurrPos != usStartPos);

    lLockKey    =   VOS_SplIMP();

    g_stMgmt.stStat.ulAllocFailCnt++;
    g_stMgmt.stStat.ulAllocTotalCnt++;

    VOS_Splx(lLockKey);

    /* 调用该函数,用于判断是否满足主动复位条件 */
    PS_Qnode_ResetGetFailProc(usFileId, usLineId, ulPid);

    TTF_LOG4(ulPid, DIAG_MODE_COMM, PS_PRINT_WARNING, "fileid, line, pid, tick, PS_Qnode_GetNode fail",
        usFileId, usLineId, (VOS_INT32)ulPid, (VOS_INT32)ulTick);

    return VOS_NULL_PTR;
} /* PS_Qnode_GetNode */