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

📄 rilhand.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        goto Error;
    }

    // Create a thread checkpoint
    m_pCheckPoint = new CCheckPoint;
    if (!m_pCheckPoint || !m_pCheckPoint->Init(NumThreads))
    {
        goto Error;
    }

    // Launch a auxiliary threads
    m_hCmdThread = CreateThread(NULL, 0, CmdThreadProc, (LPVOID)this, 0, &m_dwCmdThreadID);
    if (!m_hCmdThread)
    {
        goto Error;
    }

    m_hReadThread = CreateThread(NULL, 0, ReadThreadProc, (LPVOID)this, 0, &m_dwReadThreadID);
    if (!m_hReadThread)
    {
        goto Error;
    }

    // Launch NDIS notification thread.
    if (m_pCRilNdis &&  !m_pCRilNdis->NdisStart(m_hCancelEvent))
    {
      goto Error;
    }
    
    // Wait until all threads reach the checkpoint
    if (!m_pCheckPoint->Wait(10000))
    {
        goto Error;
    }

    DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CRilHandle::LaunchThreads : Launched threads reached ckeckpoint\r\n")));
    fRet = TRUE;

    Error:
    if (!fRet)
    {
        if (m_hCmdThread)
        {
            (void)CloseHandle(m_hCmdThread);
            m_hCmdThread = NULL;
            m_dwCmdThreadID = 0;
        }

        if (m_hReadThread)
        {
            (void)CloseHandle(m_hReadThread);
            m_hReadThread = NULL;
            m_dwReadThreadID = 0;
        }

        delete m_pCheckPoint;
        m_pCheckPoint = NULL;

        delete g_pCmdQ;
        delete g_pRspQ;
        delete g_pSimLockedQueue;
        g_pCmdQ = NULL;
        g_pRspQ = NULL;
        g_pSimLockedQueue = NULL;

        if (m_hCancelEvent)
        {
            (void)CloseHandle(m_hCancelEvent);
            m_hCancelEvent = NULL;
        }
    }
    return fRet;
}


//
// Test the cancel event
//
BOOL CRilHandle::FCancelSet() const
{
    // // FUNCTION_TRACE(CRilHandle::FCancelSet);
    return (WAIT_OBJECT_0 == WaitForSingleObject(m_hCancelEvent, 0));
}


//
//
//
BOOL CRilHandle::WaitForInit(DWORD dwTimeout) const
{
    // FUNCTION_TRACE(CRilHandle::WaitForInit);
    HANDLE rghEvents[] = { m_hInitEvent, m_hCancelEvent };
    switch (WaitForMultipleObjects(2, rghEvents, FALSE, dwTimeout))
    {
    case WAIT_OBJECT_0:
    case WAIT_OBJECT_0 + 1:
        return TRUE;
    default:
        return FALSE;
    }
}


//
// Returns true if there is a command on the command queue that can
// be executed now.
// Returns false if the command thread should quit.
//
BOOL CRilHandle::WaitForCommandOrCancel() const
{
    BOOL fRet = FALSE;
    CCommand* pCmd = NULL;
    HANDLE rghEvents[] = { g_pCmdQ->GetPutEvent(), m_hCancelEvent, m_hInitEvent };

    if (WAIT_OBJECT_0 == WaitForSingleObject(m_hInitEvent, 0))
    {
        // If the init event is signaled now, then it doesn't
        // matter what the next command is. Set return to true.
        // The subsequent call to Get will block if the queue
        // happens to be empty.
        fRet = TRUE;
    }

    while (!fRet)
    {
        // Look for a command on the queue.
        if (g_pCmdQ->Peek(pCmd))
        {
            if (pCmd->FInit())
            {
                // The next command is for init. Send it.
                fRet = TRUE;
                break;
            }
        }

        switch (WaitForMultipleObjects(3, rghEvents, FALSE, INFINITE))
        {
        case WAIT_OBJECT_0:
            // Put signaled. Loop to see if it is an init command.
            break;

        case WAIT_OBJECT_0 + 1:
            // Cancel signaled, so return FALSE now.
            return FALSE;

        case WAIT_OBJECT_0 + 2:
            // Init command signaled, so ok to send next command.
            fRet = TRUE;
            break;

        default:
            return FALSE;
        }
    }

    DEBUGCHK(TRUE == fRet);

    // Check the cancel event before returning
    // in case some other event (like init)
    // preempted this event.
    return (!FCancelSet());
}


//
//
//
BOOL CRilHandle::AddToList(CRilInstanceHandle* const pInstance)
{
    // FUNCTION_TRACE(CRilHandle::AddToList);
    return m_pInstances->Add(pInstance);
}


//
//
//
BOOL CRilHandle::RemoveFromList(CRilInstanceHandle* const pInstance)
{
    // FUNCTION_TRACE(CRilHandle::RemoveFromList);
    return m_pInstances->Remove(pInstance);
}


//
//
//
HRESULT CRilHandle::GetNextCmdID()
{
    // FUNCTION_TRACE(CRilHandle::GetNextCmdID);
    SYNCBLOCK(m_csCmdID);

    // Make sure not to wrap into error values
    if (FAILED(m_hrNextCmdID))
    {
        m_hrNextCmdID = INITIAL_COMMAND_ID;
    }

    return m_hrNextCmdID++;
}


//
// Function passed to CDlbList::Enum() below
//
BOOL NotifyHandle(void* pItem, DWORD dwData)
{
    FUNCTION_TRACE(NotifyHandle);
    DEBUGCHK(pItem != NULL);
    DEBUGCHK(dwData != NULL);

    CRilInstanceHandle* pHandle = (CRilInstanceHandle*)pItem;
    CNotificationData* pnd = (CNotificationData*)dwData;

    if (pHandle->FReadyForNotifications())
    {
        pHandle->Notify(pnd->GetCode(), S_OK, pnd->GetBlob(), pnd->GetSize());
    }

    // Continue enumeration
    return FALSE;
}


//
// Broadcast a notification to all clients
//
void CRilHandle::BroadcastNotification(CNotificationData*& rpnd)
{
    // FUNCTION_TRACE(CRilHandle::BroadcastNotification);
    DEBUGCHK(NULL != m_pInstances);
    DEBUGCHK(NULL != rpnd);

    DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CRilHandle::BroadcastNotification : Broadcasting notification 0x%x\r\n"), rpnd->GetCode()));

    // Notify all RIL proxy instances
    m_pInstances->Enum(NotifyHandle, (DWORD)rpnd);

    // Get rid of the notififcation
    delete rpnd;
    rpnd = NULL;
}


//
//
//
BOOL CRilHandle::BroadcastRealBlobNotification(const DWORD dwNotificationCode, const void* const pBlob,
                                               const UINT cbBlob)
{
    // FUNCTION_TRACE(CRilHandle::BroadcastRealBlobNotification);
    CNotificationData* pnd = NULL;
    BOOL fRet = FALSE;

    pnd = new CNotificationData;
    if (!pnd || !pnd->InitFromRealBlob(dwNotificationCode, pBlob, cbBlob))
    {
        goto Error;
    }

    BroadcastNotification(pnd);
    DEBUGCHK(NULL == pnd);
    fRet = TRUE;

    Error:
    delete pnd;
    return fRet;
}

//
//
//
BOOL CRilHandle::BroadcastATLogBlobNotification(const void* const pBlob,
                                                UINT uBlob, BOOL fResponse)
{
    // FUNCTION_TRACE(CRilHandle::BroadcastRealBlobNotification);
    CNotificationData* pnd = NULL;
    BOOL fRet = FALSE;
    RILLOGATINFO rilATLogInfo;
    CRilInstanceHandle* pCRilInstanceHandle;

    // If we don't have a handle to the application, we can' proceed.
    if ( !m_hATCommandLogOwner )
        return fRet;
    else
        pCRilInstanceHandle = (CRilInstanceHandle*)m_hATCommandLogOwner;
    
    memset(&rilATLogInfo, 0x00, sizeof(rilATLogInfo));
    rilATLogInfo.cbSize = sizeof(rilATLogInfo);
    rilATLogInfo.fResponse = fResponse;
    if ( uBlob >= MAXLENGTH_CMD )
         uBlob = MAXLENGTH_CMD -1;
    
    memcpy(rilATLogInfo.szRsp, pBlob, uBlob);
    rilATLogInfo.cbLength = uBlob;
    
    pnd = new CNotificationData;
    if (!pnd || !pnd->InitFromRealBlob(RIL_NOTIFY_ATLOGGING, &rilATLogInfo, sizeof(rilATLogInfo)))
    {
        goto Error;
    }

    if (pCRilInstanceHandle->FReadyForNotifications())
    {
        pCRilInstanceHandle->Notify(pnd->GetCode(), S_OK, pnd->GetBlob(), pnd->GetSize());
    }
    
    fRet = TRUE;

    Error:
    delete pnd;
    return fRet;
}

//
//
//
BOOL CRilHandle::BroadcastDWORDBlobNotification(const DWORD dwNotificationCode, const DWORD dwBlob)
{
    // FUNCTION_TRACE(CRilHandle::BroadcastDWORDBlobNotification);
    CNotificationData* pnd = NULL;
    BOOL fRet = FALSE;

    pnd = new CNotificationData;
    if (!pnd || !pnd->InitFromDWORDBlob(dwNotificationCode, dwBlob))
    {
        goto Error;
    }

    BroadcastNotification(pnd);
    DEBUGCHK(NULL == pnd);
    fRet = TRUE;

    Error:
    delete pnd;
    return fRet;
}

//
// Handle response to an AT command
//
BOOL CRilHandle::HandleRsp(CCommand*& rpCmd, CResponse*& rpRsp, BOOL& rfHungUp, BOOL& rfRadioOff)
{
    // FUNCTION_TRACE(CRilHandle::HandleRsp);
    DEBUGCHK(rpCmd != NULL);
    DEBUGCHK(rpRsp != NULL);

    void* pBlob = NULL;
    UINT cbBlob = 0;
    HRESULT hrError;
    CNotificationData* pnd = NULL;
    BOOL fRet = FALSE;

    rfHungUp = FALSE;

    // Handle logging of OK and ERROR responses
    if (NULL == rpCmd->GetParseFunc() && !rpCmd->FNoOp())
    {

        if (RIL_RESULT_OK == rpRsp->GetNotifyCode())
        {
            RIL_EVENTLOG_MSG((RILLOG_EVENT_CMDRSPOK));
        }
        else if (E_FAIL == rpRsp->GetError())
        {
            RIL_EVENTLOG_MSG((RILLOG_EVENT_CMDRSPERROR));
        }
    }

    // Is this the last modem init command? If so, and if it succeeded, then we're done with initialization
    if (rpCmd->FFinalInit())
    {
#ifdef RIL_RADIO_RESILIENCE        
        g_fInitedFirstTime = TRUE;
#endif // !RIL_RADIO_RESILIENCE        
        FinishInit(rpCmd,(RIL_RESULT_OK == rpRsp->GetNotifyCode()));
    }

    if ((rpCmd->CmdOptIsSet(CMDOPT_UNLOCKING)) && (RIL_RESULT_OK == rpRsp->GetNotifyCode()))
    {
        // Well, looks like we successfully unlocked the phone
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : The phone is now unlocked\r\n")));
        SendReadyStateNotification(RIL_READYSTATE_UNLOCKED);
    }

#if 0
    // This code isn't really used anymore, since the inside of the SendRILCmdHandleRsp function also does something similar
    // for timed out commands
    // If this was an init command and it failed, try again up to some limit
    if (rpCmd->FInit())
    {
        if (RIL_RESULT_OK != rpRsp->GetNotifyCode())
        {
            if (rpCmd->OkToRetry())
            {
                if (!RequeueCmdWithDelay(rpCmd, 5000))
                {
                    goto Error;
                }
            }
        }
    }
#endif

    // If we need to re-init the modem after this command and the command was sucessful, do it
    if (rpCmd->FReinit() && RIL_RESULT_OK == rpRsp->GetNotifyCode())
    {
        PrepareForReinit();
        if (!SendComInitString(COM_REINIT_INDEX))
        {
            // We failed sending the init strings -- RIL is not initialized
            goto Error;
        }
    }

    if (rpCmd->FHangup())
    {
        // If this is a hangup command and we got a NO CARRIER response, turn it into OK
        if (RIL_RESULT_NOCARRIER == rpRsp->GetNotifyCode())
        {
            rpRsp->NoCarrierToOK();
        }

        // If hangup was successful, let the caller know
        if (RIL_RESULT_OK == rpRsp->GetNotifyCode())
        {
            rfHungUp = TRUE;
        }
    }

    if (rpCmd->FRequireConnectRsp())
    {
        // ??? Do we want to set rfHungUp for all commands with NO CARRIER response?
        if (RIL_RESULT_NOCARRIER == rpRsp->GetNotifyCode())
        {
            rfHungUp = TRUE;
        }
    }

    // Even though we may ultimately ignore the response, we should still parse it
    // so that we can cache it if desired.
    if ((RIL_RESULT_OK == rpRsp->GetNotifyCode()) || rpCmd->CmdOptIsSet(CMDOPT_FORCEPARSE))
    {
            (void)rpRsp->ParseOKData(rpCmd);
    }

    if (rpCmd->CmdOptIsSet(CMDOPT_SIMQUERY))
    {
        // We were just checking to see if the SIM is ready or not.  We only care about if the return
        // value is NOT READY or not in this case
        hrError = rpRsp->GetError();
        m_fSimReady = (hrError != RIL_E_NOTREADY);

        if (m_fSimReady)
        {
            // Hey, as long as we got the PIN state, let's see if it's

⌨️ 快捷键说明

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