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

📄 rilhand.cpp

📁 Xcale270Bsp包,wince平台
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    hInstSimSec = LoadLibrary(TEXT("simsec.dll"));
    if (!hInstSimSec)
    {
        goto Exit;
    }

    // Get the address of the simsec ui
    typedef HRESULT (*SIMSECURITYUNLOCKPHONE) (HWND hwndMain, DWORD dwStyle);
    SIMSECURITYUNLOCKPHONE pfnSIMSecurityUnlockPhone;
    pfnSIMSecurityUnlockPhone = (SIMSECURITYUNLOCKPHONE)GetProcAddress(hInstSimSec, TEXT("SIMSecurityUnlockPhone"));
    if (pfnSIMSecurityUnlockPhone)
    {
        // Put up the UI
#ifdef TPC
        Result = pfnSIMSecurityUnlockPhone(NULL, SIMSEC_STYLE_CANNOT_CANCEL | SIMSEC_STYLE_EMERGENCY_CALL | SIMSEC_STYLE_BRANDED);
#else
        Result = pfnSIMSecurityUnlockPhone(NULL, SIMSEC_STYLE_EMERGENCY_CALL);
#endif
    }
    else
    {
#ifdef TPC
        ASSERT(FALSE);
        goto Exit;
#else
        // backward compatibility for old simsecui, which doesn't have UnlockPhone, and instead uses CheckPin
        typedef HRESULT (*SIMSECURITYCHECKPIN) (HWND hwndMain, SIMPIN_TYPE nPinType, DWORD dwStyle);
        SIMSECURITYCHECKPIN pfnSIMSecurityCheckPin;
        pfnSIMSecurityCheckPin = (SIMSECURITYCHECKPIN)GetProcAddress(hInstSimSec, TEXT("SIMSecurityCheckPin"));
        if (pfnSIMSecurityCheckPin)
        {
            // Put up the UI
            Result = pfnSIMSecurityCheckPin(NULL, (SIM_LOCKFACILITY_SIM == g_dwLockFacility) ? SIMPIN_SIM : SIMPIN_SIM2,
                SIMSEC_STYLE_AUTO_CLOSE | SIMSEC_STYLE_EMERGENCY_CALL);
        }
        else
        {
            goto Exit;
        }
#endif // !TPC
    }


    // Free the library
    FreeLibrary(hInstSimSec);

Exit:
    // Not prompting anymore
    g_PromptingForSim=FALSE;

    // Now safe to requeue the pending commands to try again
    // Requeue any existing commands
    // If the SIM was unlocked, they'll now succeed.
    // Otherwise they'll fail as expected.
    CCommand* pCmd;
    while (g_pSimLockedQueue->Get(pCmd, 0)==S_OK)
    {
        if (!g_pCmdQ->Put(pCmd, INFINITE))
        {
            delete pCmd;
        }
    }

    return 0;
}

//
//
//
BOOL PromptForSimAndRequeueCmd(CCommand* pCmd, DWORD dwLockFacility)
{
    TBD_FUNCTION(PromptForSimAndRequeueCmd);
    TBD_ASSERT(NULL != pCmd);

    BOOL fRet=FALSE;

    // Queue command up on SIM retry queue
    if(pCmd->FDial())
    {
        // Not re-queuing dial commands
        // Leave fRet FALSE to indicate that the existing response should be used
    }
    else
    {
        pCmd->ClrCmdOpt(CMDOPT_RETRYONSIMLOCKED);
        fRet = g_pSimLockedQueue->Put(pCmd, 0);
        if (!fRet)
        {
            TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("PromptForSimAndRequeueCmd : Unable to queue cmd"));
            goto Exit;
        }
    }

    // Is another dialog already up?
    // Note: don't need to worry about
    if (!g_PromptingForSim)
    {
        HANDLE hThread;
        // Remember to save nPinType;
        g_dwLockFacility=dwLockFacility;
        hThread = CreateThread(NULL, 0, PromptForSimAndRequeueCmdProc, (LPVOID)NULL, 0, NULL);
        if (!hThread)
        {
            // Eek, we can't create a thread!
            if(pCmd->FDial())
            {
                // Dial commands were not put on the queue, so we don't need to remove them now
            }
            else
            {
                // By definition, our command must be the only one in the queue. Just get it back out.
                // When we return fRet==FALSE, the calling code will fail the response to the app.
                CCommand *pCmdTmp;
                g_pSimLockedQueue->Get(pCmdTmp, 0);
                TBD_ASSERT(pCmd == pCmdTmp);
            }
            TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("PromptForSimAndRequeueCmd : Unable to CreateThread(PromptForSimAndRequeueCmdProc)"));
            goto Exit;
        }
        else
        {
            CloseHandle(hThread);   // close handle we don't need
        }
        g_PromptingForSim=TRUE;
    }

    if(!pCmd->FDial())
    {
        // See comment above about leaving fRet FALSE for dial commands
        fRet=TRUE;
    }
Exit:
    return fRet;
}

//
// Handle response to an AT command
//
BOOL CRilHandle::HandleRsp(CCommand*& rpCmd, CResponse*& rpRsp, BOOL& rfHungUp, BOOL& rfRadioOff)
{
    // TBD_FUNCTION(CRilHandle::HandleRsp);
    TBD_ASSERT(rpCmd != NULL);
    TBD_ASSERT(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())
    {
        DWORD dwZone = rpCmd->CmdOptIsSet(CMDOPT_POLLING) ?
            RILLOG_ZONE_CMD_POLLING : RILLOG_ZONE_CMD;
        if (RIL_RESULT_OK == rpRsp->GetNotifyCode())
        {
            g_RilLog.LogEvent(dwZone, RILLOG_EVENT_CMDRSPOK);
        }
        else if (E_FAIL == rpRsp->GetError())
        {
            g_RilLog.LogEvent(dwZone, 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())
    {
        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
        TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, TEXT("The phone is now unlocked"));
        SendReadyStateNotification(RIL_READYSTATE_UNLOCKED, TRUE);
    }

    if ((rpCmd->CmdOptIsSet(CMDOPT_RETRYONSIMLOCKED)) && (rpRsp->GetNotifyCode()==RIL_RESULT_ERROR))
    {
        BOOL bPrompt=FALSE;
        void* pBlobSim = NULL;
        UINT cbBlobSim = 0;
        rpRsp->GetBlob(pBlobSim, cbBlobSim);
        ASSERT(cbBlobSim==sizeof(DWORD));
        DWORD dwLockFacility;
        switch(*(DWORD*)pBlobSim)
        {
        case RIL_E_PHSIMPINREQUIRED:
        case RIL_E_PHFSIMPINREQUIRED:
        case RIL_E_PHFSIMPUKREQUIRED:
        case RIL_E_SIMPINREQUIRED:
        case RIL_E_SIMPUKREQUIRED:
        case RIL_E_SIMNOTINSERTED:
        case RIL_E_SIMFAILURE:
            dwLockFacility=SIM_LOCKFACILITY_SIM;
            bPrompt=TRUE;
            break;
        case RIL_E_SIMPIN2REQUIRED:
        case RIL_E_SIMPUK2REQUIRED:
            dwLockFacility=SIM_LOCKFACILITY_SIM_PIN2;
            bPrompt=TRUE;
        }

        if (bPrompt)
        {
            if (PromptForSimAndRequeueCmd(rpCmd,dwLockFacility))
            {
                delete pnd;
                delete rpRsp;
                rpCmd = NULL;
                rpRsp = NULL;
                return TRUE;
            }
        }
    }

#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;
        }
#ifdef WAVECOM_DRIVER
        else if (RIL_RESULT_ERROR == rpRsp->GetNotifyCode() &&
                 RIL_E_OPNOTALLOWED == rpRsp->GetError())
        {
            rfHungUp = TRUE;
        }
#endif
    }

    // If we're not supposed to ignore the response and the command succeeded,
    //    then we should parse the response data now (so that it can be used by the notification
    //    code below)
    if (!rpCmd->FIgnoreRsp() && RIL_RESULT_OK == rpRsp->GetNotifyCode())
    {
            (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
            // locked or not.  Why not?
            DWORD dwReadyState = RIL_READYSTATE_SIM;
            void *pBlobSim = NULL;
            UINT cbBlobSim = 0;

            if (RIL_RESULT_OK == rpRsp->GetNotifyCode())
            {
                rpRsp->GetBlob(pBlobSim, cbBlobSim);
                TBD_ASSERT(cbBlobSim == sizeof(DWORD));

                if ((*(DWORD *) pBlobSim) == RIL_LOCKEDSTATE_READY)
                {
                    TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, TEXT("The phone was unlocked from boot"));
                    dwReadyState |= RIL_READYSTATE_UNLOCKED;
                }
            }

            SendReadyStateNotification(dwReadyState, TRUE);
        }

        // Wake up the waiting thread
        SetEvent(m_hSimReadyEvent);
        fRet = TRUE;
        goto Error;
    }

    // If we got a CONNECT response, it must be a response to successful ATD or ATA -- change it to OK
    if (RIL_NOTIFY_CONNECT == rpRsp->GetNotifyCode())
    {
        rpRsp->ConnectToOK();

        // Some networks seem to require a brief delay after a data connection is made
        // before data can be sent via the connection. We pause here before sending the
        // connect response to the client. The delay is configured using a registry value.
        // If the value is not present, then there is no delay.
        DWORD dwTemp = 0;
        if (rpCmd->CmdOptIsSet(CMDOPT_DELAYCONNECTRSP) &&
            GetRegistryDWORD(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("ConnectResponseDelay"), &dwTemp))
        {
            Sleep(dwTemp);
        }
    }
    else
    {
        // For non-CONNECT responses, if we have a notification to send upon success, do it now
        pnd = rpCmd->GiveUpNotificationData();
        if (pnd)
        {
            if (RIL_RESULT_OK == rpRsp->GetNotifyCode() &&
                (!pnd->FDelayedInitFromRsp() || pnd->FinishInitFromRspBlob(*rpRsp)))
            {

                BroadcastNotification(pnd);
                TBD_ASSERT(NULL == pnd);
            }
            else
            {
                delete pnd;
                pnd = NULL;
            }
        }
    }

    // If we got an RIL_E_SIMNOTINSERTED or RIL_E_SIMFAILURE error, send out a "SIM isn't accessible" notification
    hrError = rpRsp->GetError();
    if (RIL_E_SIMNOTINSERTED == hrError || RIL_E_SIMFAILURE == hrError)
    {
        (void)BroadcastRealBlobNotification(RIL_NOTIFY_SIMNOTACCESSIBLE, NULL, 0);
    }
    if (RILERRORCLASS(hrError) == RIL_ERRORCLASS_SIM)
    {
            UpdateSIMState(hrError);
    }

    // Forward the response we got to the handle that sent the command
    rpRsp->GetBlob(pBlob, cbBlob);

    // If we just queried the equipment state, then make
    // sure the global on/off state is set appropriately.
    if (APIID_GETEQUIPMENTSTATE == rpCmd->GetAPIID() &&
        RIL_RESULT_OK == rpRsp->GetNotifyCode())
    {
        RILEQUIPMENTSTATE * pres;
        if (NULL != pBlob)
        {
            ASSERT(sizeof(RILEQUIPMENTSTATE) == cbBlob);

            // Take a peek at the response data
            pres = (RILEQUIPMENTSTATE *)pBlob;
            if (RIL_RADIOSUPPORT_OFF == pres->dwRadioSupport)
                rfRadioOff = TRUE;
            else if (RIL_RADIOSUPPORT_ON == pres->dwRadioSupport)
                rfRadioOff = FALSE;
        }
    }

    rpCmd->SendResponse(rpRsp->GetNotifyCode(), pBlob, cbBlob);
    rpRsp->DeleteBlob();
    pBlob = NULL;
    cbBlob = 0;
    fRet = TRUE;

    Error:
    delete pnd;
    delete rpCmd;
    delete rpRsp;
    rpCmd = NULL;
    rpRsp = NULL;
    return fRet;
}


//
//
//
BOOL CRilHandle::AppendReadBytes(LPCSTR szBytes, UINT cbBytes)
{
    // TBD_FUNCTION(CRilHandle::AppendReadBytes);
    BOOL fRet = FALSE;

    if (!m_pReadBytes)
    {
        // No buffer yet -- need to allocate it
        m_pReadBytes = new CBuffer;
        if (!m_pReadBytes)
        {
            goto Error;
        }
    }
    fRet = m_pReadBytes->Append(szBytes, cbBytes);

    Error:
    if (!fRet)
    {
        // Critically low on memory
        SignalCriticalError(RILLOG_EVENT_LOWMEMORY);
    }
    return fRet;
}


//
//
//
BOOL CRilHandle::InheritReadBytes(CResponse* const pRsp)
{
    // TBD_FUNCTION(CRilHandle::InheritReadBytes);
    BOOL fRet = FALSE;

    if (!m_pReadBytes)
    {
        // No buffer yet -- need to allocate it
        m_pReadBytes = new CBuffer;
        if (!m_pReadBytes)
        {
            goto Error;
        }
    }

    m_pReadBytes->InheritData(pRsp);
    fRet = TRUE;

    Error:
    return fRet;
}


//
//
//
BOOL CRilHandle::GiveUpReadBytes(LPSTR& rszBytes, UINT& rcbBytes)
{
    // TBD_FUNCTION(CRilHandle::GiveUpReadBytes);
    BOOL fRet = FALSE;

    if (!m_pReadBytes)
    {
        // No buffer yet, i.e. no bytes to return
        goto Error;
    }
    rcbBytes = m_pReadBytes->GetLength();
    rszBytes = m_pReadBytes->GiveUpData();
    fRet = TRUE;

    Error:
    return fRet;
}


//
//
//
BOOL CRilHandle::SetEmergencyMode(const BOOL fMode)
{
    // TBD_FUNCTION(CRilHandle::SetEmergencyMode);
    SYNCBLOCK(m_csEmergency);

    DWORD dwNotificationCode;
    BOOL fRet = FALSE;

    if (m_fEmergencyMode && fMode)
    {
        // If we're trying to enter the emergency mode while already in emergency mode, fail
        goto Error;
    }
    TBD_ASSERT(FALSE == m_fEmergencyMode || FALSE == fMode);
    TBD_ASSERT(FALSE != m_fEmergencyMode || FALSE != fMode);

    // Set the new mode
    m_fEmergencyMode = fMode;

    if (m_fEmergencyMode)
    {
        // We just entered emergency mode
        TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, TEXT("CRilHandle::SetEmergencyMode : Entering emergency mode"));

        // Clear the command queue, sending out "cancelled" responses to response callbacks
        g_pCmdQ->Enum(GenerateCancelledRsp, (DWORD)this, TRUE);
        dwNotificationCode = RIL_NOTIFY_EMERGENCYMODEENTERED;
    }
    else
    {
        // We just exited emergency mode
        TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, TEXT("CRilHandle::SetEmergencyMode : Exiting emergency mode"));
        dwNotificationCode = RIL_NOTIFY_EMERGENCYMODEEXITED;
    }

    // Send out an appropriate notification
    (void)BroadcastRealBlobNotification(dwNotificationCode, NULL, 0);
    fRet = TRUE;

    Error:
    return fRet;
}


//

⌨️ 快捷键说明

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