/*****************************************************************************
 函 数 名  : GU_OamSndPcCmsMsg
 功能描述  : 用于ACPU上面把PC侧数据通过ICC发送给CCPU OM模块
 输入参数  : pucData:   需要发送的数据内容
             ulDataLen: 数据长度
 输出参数  : 无
 返 回 值  : VOS_ERROR/VOS_OK
 调用函数  :
 被调函数  :
 修改历史  :
   1.日    期  : 2011年3月10日
     作    者  : l46160
     修改内容  : Creat Function
*****************************************************************************/
VOS_UINT32 GU_OamSndPcMsgToCcpu(OMRL_RCV_CHAN_CTRL_INFO_STRU *pstCtrlInfo, VOS_UINT8 *pucData, VOS_UINT32 ulSize)
{
    VOS_INT32  lResult = VOS_ERROR;

    lResult = DRV_ICC_WRITE(UDI_ICC_GUOM0, pucData, (VOS_INT32)ulSize);

    /* 由于C核复位,写ICC通道失败会返回一个特殊值,不能复位单板 */
    if (BSP_ERR_ICC_CCORE_RESETTING == lResult )
    {
        LogPrint1("\n# GU_OamSndPcMsgToCcpu Error,Ccore Reset,ulSize %d .\n",(VOS_INT)ulSize);

        return VOS_ERR;
    }

    /* 当前写操作失败 */
    if(ulSize != (VOS_UINT32)lResult)
    {
        LogPrint2("GU_OamSndPcMsgToCcpu: The ICC UDI Write is Error.Size:%d,lResult:%d\n",(VOS_INT)ulSize,lResult);

        pstCtrlInfo->stPcToUeErrRecord.stICCSendFailInfo.ulICCOmSendErrNum++;
        pstCtrlInfo->stPcToUeErrRecord.stICCSendFailInfo.ulICCOmSendErrLen += ulSize;
        pstCtrlInfo->stPcToUeErrRecord.stICCSendFailInfo.ulICCOmSendErrSlice= VOS_GetSlice();

        return VOS_ERR;
    }
    pstCtrlInfo->stPcToUeSucRecord.stICCSendSUCInfo.ulICCOmSendMsgNum++;
    pstCtrlInfo->stPcToUeSucRecord.stICCSendSUCInfo.ulICCOmSendLen += ulSize;
    pstCtrlInfo->stPcToUeSucRecord.stICCSendSUCInfo.ulICCOmSendSlice= VOS_GetSlice();

    return VOS_OK;
}
VOS_UINT OM_ComRx_ICCError_CB(VOS_UINT ulChanID, VOS_UINT ulEvent, VOS_VOID* pParam)
{
    OAM_MNTN_ICC_ERROR_EVENT_STRU stIccErrorInfo;

    stIccErrorInfo.ulEvent = ulEvent;

    if (g_astOMCCPUIccCtrlTable[OM_OM_ICC_CHANNEL].UDIHdle == (UDI_HANDLE)ulChanID)
    {
        stIccErrorInfo.ulChannelID = OM_OM_ICC_CHANNEL;
    }
    else if(g_astOMCCPUIccCtrlTable[OM_OSA_MSG_ICC_CHANNEL].UDIHdle == (UDI_HANDLE)ulChanID)
    {
        stIccErrorInfo.ulChannelID = OM_OSA_MSG_ICC_CHANNEL;
    }
    else
    {
        LogPrint("OM_ComRx_ICCError_CB: The Channel ID is not used by OAM\n");

        return VOS_ERR;
    }

    LogPrint2("OM_ComRx_ICCError_CB: The Error ICC Channel is %d, and Error Event is %d",
                    (VOS_INT32)stIccErrorInfo.ulChannelID, (VOS_INT32)ulEvent);

    /*通道ID和错误原因写入ErrorLog*/
    MNTN_RecordErrorLog(MNTN_OAM_ICC_ERROR_EVENT, &stIccErrorInfo, sizeof(stIccErrorInfo));

    return VOS_OK;
}
/*****************************************************************************
 函 数 名  : GU_OamPortStatus
 功能描述  : 用于ACPU上面处理物理端口断开后的OM链接断开
 输入参数  : pucData:   需要发送的数据内容
             ulDataLen: 数据长度
 输出参数  : 无
 返 回 值  : 无
 调用函数  :
 被调函数  :
 修改历史  :
   1.日    期  : 2012年2月2日
     作    者  : zhuli
     修改内容  : Creat Function
*****************************************************************************/
VOS_VOID GU_OamPortStatus(OM_PROT_HANDLE_ENUM_UINT32 enHandle, CPM_PHY_PORT_ENUM_UINT32 enPhyPort,ACM_EVT_E enPortState)
{
    if(ACM_EVT_DEV_SUSPEND == enPortState)
    {
        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBOutNum++;

        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBOutTime = OM_GetSlice();

        if (enPhyPort == CPM_QueryPhyPort(CPM_OM_COMM))
        {
            GU_OamDisconnectPorts(enPhyPort);

            g_stAcpuPcToUeSucRecord.stRlsInfo.ulRlsDrvSuspend++;
            g_stAcpuPcToUeSucRecord.stRlsInfo.ulSlice = OM_GetSlice();
        }
    }
    else if(ACM_EVT_DEV_READY == enPortState)
    {
        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBINNum++;

        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBINTime = OM_GetSlice();
    }
    else
    {
        LogPrint2("GU_OamUSBStatusCB: The USB Port %d State %d is Unknow", (VOS_INT)enPhyPort, (VOS_INT)enPortState);

        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBStateErrNum++;

        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBStateErrTime = OM_GetSlice();
    }

    return;
}
VOS_UINT32 GU_OamSndPcMsgToCcpu(VOS_UINT8 *pucData, VOS_UINT32 ulSize)
{
    VOS_INT32  lResult = VOS_ERROR;

    lResult = DRV_UDI_WRITE(g_astOMACPUIccCtrlTable[OM_OM_ICC_CHANNEL].UDIHdle, pucData, ulSize);

    /* 由于C核复位,写ICC通道失败会返回一个特殊值,不能复位单板 */
    if (BSP_ERR_ICC_CCORE_RESETTING == lResult )
    {
        LogPrint1("\n# GU_OamSndPcMsgToCcpu Error,Ccore Reset,ulSize %d .\n",(VOS_INT)ulSize);

        return VOS_ERR;
    }

    /* 当前写操作失败 */
    if(ulSize != lResult)
    {
        LogPrint2("GU_OamSndPcMsgToCcpu: The ICC UDI Write is Error.Size:%d,lResult:%d\n",(VOS_INT)ulSize,lResult);

        g_stAcpuPcToUeErrRecord.stICCSendFailInfo.ulICCOmSendErrNum++;
        g_stAcpuPcToUeErrRecord.stICCSendFailInfo.ulICCOmSendErrLen += ulSize;
        g_stAcpuPcToUeErrRecord.stICCSendFailInfo.ulICCOmSendErrSlice= VOS_GetSlice();

        return VOS_ERR;
    }
    g_stAcpuPcToUeSucRecord.stICCSendSUCInfo.ulICCOmSendMsgNum++;
    g_stAcpuPcToUeSucRecord.stICCSendSUCInfo.ulICCOmSendLen += ulSize;
    g_stAcpuPcToUeSucRecord.stICCSendSUCInfo.ulICCOmSendSlice= VOS_GetSlice();

    return VOS_OK;
}
VOS_UINT32 VOS_SmV( VOS_SEM Sm_ID )
{
    SEM_CONTROL_BLOCK  *temp_Ptr;

    temp_Ptr = (SEM_CONTROL_BLOCK *)Sm_ID;

    if( temp_Ptr == temp_Ptr->SemId )
    {
        if( temp_Ptr->Flag == VOS_SEM_CTRL_BLK_IDLE)
        {
            VOS_SetErrorNo(VOS_ERRNO_SEMA4_V_NOTACTIVE);
            return(VOS_ERRNO_SEMA4_V_NOTACTIVE);
        }

        if ( NU_SUCCESS == NU_Release_Semaphore( &(temp_Ptr->NuSem) ) )
        {
            return(VOS_OK);
        }
        else
        {
            LogPrint2("# VOS_SmV ID %x Name %s.\r\n", Sm_ID, temp_Ptr->Name);

            VOS_SetErrorNo(VOS_ERRNO_SEMA4_V_CANOTV);
            return(VOS_ERRNO_SEMA4_V_CANOTV);
        }
    }
    else
    {
        VOS_SetErrorNo(VOS_ERRNO_SEMA4_V_IDERR);
        return(VOS_ERRNO_SEMA4_V_IDERR);
    }
}
/*****************************************************************************
 函 数 名  : GU_OamPortWriteAsyCB
 功能描述  : 用于处理OM的异步发送数据的回调
 输入参数  : pucData:   需要发送的数据内容
             ulDataLen: 数据长度
 输出参数  : 无
 返 回 值  : 无
 调用函数  :
 被调函数  :
 修改历史  :
   1.日    期  : 2012年2月2日
     作    者  : zhuli
     修改内容  : Creat Function
*****************************************************************************/
VOS_VOID GU_OamPortWriteAsyCB(OM_PROT_HANDLE_ENUM_UINT32 enHandle, VOS_UINT8* pucData, VOS_INT lLen)
{
    VOS_UINT32 ulResult;

    if(lLen < 0)        /*USB返回的错误值,保证可以打开SOCP的中断屏蔽*/
    {
        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBCBErrNum++;
        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBCBErrTime = OM_GetSlice();

        SCM_RlsDestBuf(SOCP_CODER_DST_GU_OM, 0);
    }
    else
    {
        ulResult = SCM_RlsDestBuf(SOCP_CODER_DST_GU_OM, (VOS_UINT32)lLen);

        if(VOS_OK != ulResult)
        {
            LogPrint2("\r\nGU_OamUSBWriteDataCB: SCM_RlsDestBuf return Error 0x%x, Data Len is %d", (VOS_INT)ulResult, lLen);
            g_stAcpuDebugInfo.ulSocpReadDoneErrLen += lLen;
            g_stAcpuDebugInfo.ulSocpReadDoneErrNum++;
        }
    }

    g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBWriteCBNum++;

    return;
}
VOS_UINT VOS_ICCError_CB(VOS_UINT ulChanID, VOS_UINT ulEvent, VOS_VOID* pParam)
{
    /*lint -e534*/
    LogPrint2("VOS_ICCError_CB: The Error ICC Channel is %d, and Error Event is %d",
                    (VOS_INT32)ulChanID, (VOS_INT32)ulEvent);
    /*lint +e534*/

    return VOS_OK;
}
VOS_UINT GU_OamAcpu_ICCError_CB(VOS_UINT ulChanID, VOS_UINT ulEvent, VOS_VOID* pParam)
{
    VOS_UINT32 ulChannelID;

    if(UDI_ICC_GUOM0 == (UDI_HANDLE)ulChanID)
    {
        ulChannelID = OM_OM_ICC_CHANNEL;
    }
    else
    {
        LogPrint("GU_OamAcpu_ICCError_CB: The Channel ID is not used by OAM\n");

        return VOS_ERR;
    }

    LogPrint2("GU_OAMAcpu_ICCError_CB: The Error Channel ID is %d,and Event is %d\n",
                (VOS_INT32)ulChannelID, (VOS_INT32)ulEvent);

    return VOS_OK;
}
/*****************************************************************************
 Function   : V_IntUnlock
 Description: Turn on the interrupt
 Input      : CPSR
 Return     : void;
 Other      : none
 *****************************************************************************/
VOS_VOID V_IntUnlock(VOS_INT lLockKey)
{
    g_stVosIntLockNestedInfo.ulSuffix--;

    if ( VOS_NESTED_INTLOCK_MAX_NUM <= g_stVosIntLockNestedInfo.ulSuffix )
    {
        SRE_IntRestore((VOS_UINT32)lLockKey);

        return;
    }

    if ( VOS_INTLOCK_MAX_INTERVAL <
        (VOS_GetSlice() - g_stVosIntLockNestedInfo.astNestedInfo[g_stVosIntLockNestedInfo.ulSuffix].ulSlice) )
    {
         LogPrint2("# Info: intlock time too big.F %d L %d.\r\n",
            (VOS_INT32)g_stVosIntLockNestedInfo.astNestedInfo[g_stVosIntLockNestedInfo.ulSuffix].ulFile,
            (VOS_INT32)g_stVosIntLockNestedInfo.astNestedInfo[g_stVosIntLockNestedInfo.ulSuffix].lLine);
    }

    SRE_IntRestore((VOS_UINT32)lLockKey);

    return;
}
VOS_UINT GU_OamAcpu_ICCError_CB(VOS_UINT ulChanID, VOS_UINT ulEvent, VOS_VOID* pParam)
{
    VOS_UINT32 ulChannelID;

    if(g_astOMACPUIccCtrlTable[OM_OM_ICC_CHANNEL].UDIHdle == ulChanID)
    {
        ulChannelID = OM_OM_ICC_CHANNEL;
    }
    else if(g_astOMACPUIccCtrlTable[OM_OSA_MSG_ICC_CHANNEL].UDIHdle == ulChanID)
    {
        ulChannelID = OM_OSA_MSG_ICC_CHANNEL;
    }
    else
    {
        LogPrint("OM_ComRx_ICCError_CB: The Channel ID is not used by OAM\n");

        return VOS_ERR;
    }

    LogPrint2("GU_OAMAcpu_ICCError_CB: The Error Channel ID is %d,and Event is %d\n",
                (VOS_INT32)ulChannelID, (VOS_INT32)ulEvent);

    return VOS_OK;
}
/*****************************************************************************
 Function   : V_IntLock
 Description: Turn off the interrupt
 Input      : file line
 Return     : CPSR;
 Other      : none
 *****************************************************************************/
VOS_INT V_IntLock(VOS_UINT32 ulFileID, VOS_INT32 lLineNo)
{
    VOS_INT lFlag;

    lFlag = intLock();

    if ( VOS_NESTED_INTLOCK_MAX_NUM <= g_stVosIntLockNestedInfo.ulSuffix )
    {
        g_stVosIntLockNestedInfo.ulSuffix++;

        LogPrint2("# Info: intlock nested too big.F %d L %d.\r\n", (VOS_INT32)ulFileID, (VOS_INT32)lLineNo);

        return lFlag;
    }

    g_stVosIntLockNestedInfo.astNestedInfo[g_stVosIntLockNestedInfo.ulSuffix].ulFile  = ulFileID;
    g_stVosIntLockNestedInfo.astNestedInfo[g_stVosIntLockNestedInfo.ulSuffix].lLine   = lLineNo;
    g_stVosIntLockNestedInfo.astNestedInfo[g_stVosIntLockNestedInfo.ulSuffix].ulSlice = VOS_GetSlice();

    g_stVosIntLockNestedInfo.ulSuffix++;

    return lFlag;

}
VOS_VOID PPM_PortStatus(OM_PROT_HANDLE_ENUM_UINT32 enHandle, CPM_PHY_PORT_ENUM_UINT32 enPhyPort,ACM_EVT_E enPortState)
{
    VOS_ULONG                           ulLockLevel;
    OM_LOGIC_CHANNEL_ENUM_UINT32        enChannel;
    VOS_BOOL                            ulSndMsg;

    if (ACM_EVT_DEV_SUSPEND == enPortState)
    {
        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBOutNum++;

        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBOutTime = OM_GetSlice();

        VOS_SpinLockIntLock(&g_stPpmPortSwitchSpinLock, ulLockLevel);

        ulSndMsg  = VOS_FALSE;
        enChannel = OM_LOGIC_CHANNEL_BUTT;

        /* CFG端口处理GU和TL的端口断开,发消息到GU和TL去处理,但不断开CPM的关联 */
        if (OM_USB_CFG_PORT_HANDLE == enHandle)
        {
            if (enPhyPort == CPM_QueryPhyPort(CPM_OM_CFG_COMM))
            {
                ulSndMsg  = VOS_TRUE;
                enChannel = OM_LOGIC_CHANNEL_CNF;
            }
        }
        /* IND端口断开时发消息到GU和TL去处理 */
        else if (OM_USB_IND_PORT_HANDLE == enHandle)
        {
            if (enPhyPort == CPM_QueryPhyPort(CPM_OM_IND_COMM))
            {
                ulSndMsg  = VOS_TRUE;
                enChannel = OM_LOGIC_CHANNEL_IND;
            }
        }
        else
        {

        }

        VOS_SpinUnlockIntUnlock(&g_stPpmPortSwitchSpinLock, ulLockLevel);

        if (VOS_TRUE == ulSndMsg)
        {
            PPM_DisconnectAllPort(enChannel);
        }
    }
    else if(ACM_EVT_DEV_READY == enPortState)
    {
        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBINNum++;

        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBINTime = OM_GetSlice();
    }
    else
    {
        LogPrint2("PPM_PortStatus: The USB Port %d State %d is Unknow", (VOS_INT)enPhyPort, (VOS_INT)enPortState);

        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBStateErrNum++;

        g_stAcpuDebugInfo.astPortInfo[enHandle].ulUSBStateErrTime = OM_GetSlice();
    }

    return;
}