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

📄 rilhand.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

rilhand.cpp

Abstract:


Notes:


--*/


#include "precomp.h"
#include "simmgr.h"

extern HANDLE g_mtxSetEquipmentState;
HRESULT ParseGetPhoneLockedState(LPCSTR szRsp, void*& pBlob, UINT& cbBlob);
#ifdef RIL_WATSON_REPORT
HRESULT ParseGetEquipmentInfo(LPCSTR szRsp, void*& pBlob, UINT& cbBlob);
#endif // RIL_WATSON_REPORT
HRESULT ParseGetPhonebookOptions(LPCSTR szRsp, void*& pBlob, UINT& cbBlob);
// RIL OEM independent registry key
const LPCTSTR g_tszRegKeyRILMS = TEXT("Software\\Microsoft\\RIL");

// RIL API info registry key
const LPCTSTR g_tszRegKeyAPIInfo = TEXT("Software\\Microsoft\\RIL\\APIInfo\\");

// RIL opertor names registry key
const LPCTSTR g_tszRegKeyOperNames = TEXT("Software\\Microsoft\\RIL\\OperatorNames");

// RIL Remote Calltype Determination registry key
const LPCTSTR g_tszRegKeyRemoteCalltype = TEXT("Comm\\Cellular\\RIL\\RemoteCalltype");

const HRESULT INITIAL_COMMAND_ID = 1;

DWORD g_TimeoutCmdInit;
DWORD g_TimeoutCmdNoOp;
DWORD g_TimeoutCmdOnline;
DWORD g_TimeoutAPIDefault;
DWORD g_TimeoutDTRDrop;
DWORD g_TimeoutWaitForInit;

DWORD g_dwLastCLIP = 1;
DWORD g_dwLastCLIR = 0;

// It's safe to put these params in globals since the SIM PW prompt thread is only launched from the command thread,
// and no more than one SIM PW prompt thread at a time is launched.
BOOL g_PromptingForSim=FALSE;
DWORD g_dwLockFacility;
CQueue<CCommand, 10>* g_pSimLockedQueue;

//
// RIL handle ctor
//
CRilHandle::CRilHandle()
: m_hInitEvent(NULL),
m_hCancelEvent(NULL),
m_hDataEvent(NULL),
m_hSimReadyEvent(NULL),
m_hInitedForSMSEvent(NULL),
m_hATCommandLogOwner(NULL),
m_hInitedForSIMPBEvent(NULL),
m_hCmdThread(NULL),
m_hReadThread(NULL),
m_fQuitReadyStateThread(FALSE),
m_dwCmdThreadID(0),
m_dwReadThreadID(0),
m_pCheckPoint(NULL),
#ifndef RIL_RADIO_RESILIENCE
m_pMonitor(NULL),
#endif // ! RIL_RADIO_RESILIENCE
m_pInstances(NULL),
m_hrNextCmdID(INITIAL_COMMAND_ID),
m_pComDevice(NULL),
m_pReadBytes(NULL),
m_pReadBytes2(NULL),
m_dwDataModeCmdDelay(3000),
m_dwMaxDataModeTimeWithoutCmd(30000),
m_fInited(FALSE),
m_fFailedInit(FALSE),
m_fInitedForSMS(FALSE),
m_fInitedForSIMPB(FALSE),
m_fWaitingForRsp(FALSE),
m_fEmergencyMode(FALSE),
m_fSimReady(FALSE),
m_dwSIMPBLastSize((DWORD)-1),
m_fLastCommandTimedOut(FALSE),
m_pCurrCommand(NULL)
{
    // // FUNCTION_TRACE(CRilHandle::CRilHandle);
    // Intialize critical sections
    InitializeCriticalSection(&m_cs);
    InitializeCriticalSection(&m_csInstances);
    InitializeCriticalSection(&m_csCmdID);
    InitializeCriticalSection(&m_csEmergency);

    if ( TRUE == GetRegistryPacketSupport())
    {
        // This object owns the pointer returned by PDD_GetRilNdisObject
        // PDD_GetRilNdisObject is not expected to return E_NOTIMPL here since the above check succeeds

        HRESULT hr = PDD_GetRilNdisObject(this, m_pCRilNdis);
        if ( FAILED( hr ) )
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle ctor : PDD_GetRilNdisObject failed , hr = [0x%08x]\r\n"), hr));
        }              
    }
    else 
    {
        m_pCRilNdis = NULL;
    }

    memset(m_rgpAPIInfo, 0x00, APIID_TOTAL * sizeof(APIINFO*));
}


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

    CRilInstanceHandle* pHandle = (CRilInstanceHandle*)pItem;
    delete pHandle;

    // Continue enumeration
    return FALSE;
}

//
// RIL handle dtor
//
CRilHandle::~CRilHandle()
{
    // // FUNCTION_TRACE(CRilHandle::~CRilHandle);

    UINT i;

    {
        SYNCBLOCK(m_cs);

        // Signal the cancel event to kill the thread
        if (m_hCancelEvent)
        {
            (void)SetEvent(m_hCancelEvent);
        }

        // Reset the COM port
        if (m_pComDevice)
        {
            (void)DeinitComPort(m_pComDevice);
        }

        StopReadyStateQuery();

        // Wait for auxiliary threads to terminate
        (void)WaitForSingleObject(m_hCmdThread, 10000);
        (void)WaitForSingleObject(m_hReadThread, 10000);
        
        // Kill NDIS Thread
        if (m_pCRilNdis) {
            m_pCRilNdis->NdisStop();
            delete m_pCRilNdis;
            m_pCRilNdis = NULL;
            }
        
        // Get rid of the threads
        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;
        }

        // Get rid of the event
        if (m_hCancelEvent)
        {
            (void)CloseHandle(m_hCancelEvent);
            m_hCancelEvent = NULL;
        }

        // Get rid of the checkpoint
        delete m_pCheckPoint;
        m_pCheckPoint = NULL;

#ifndef RIL_RADIO_RESILIENCE
        // Get rid of the monitor
        delete m_pMonitor;
        m_pMonitor = NULL;
#endif // RIL_RADIO_RESILIENCE

        // Get rid of the queues
        delete g_pCmdQ;
        delete g_pRspQ;
        delete g_pSimLockedQueue;
        g_pCmdQ = NULL;
        g_pRspQ = NULL;
        g_pSimLockedQueue = NULL;

        // Close the equipment state mutex
        if ( g_mtxSetEquipmentState )
        {
            BOOL fMutex = CloseHandle(g_mtxSetEquipmentState);
            ASSERT ( fMutex );
        }


        // Close the serial port
        if (m_pComDevice)
        {
            COM_CloseInternal(m_pComDevice);
            m_pComDevice = NULL;
        }

        // All of the instance handles should be closed
        // before the driver handle is destroyed.
        m_pInstances->Enum(DeleteInstanceHandle, 0);

        // Delete the instance handle list
        delete m_pInstances;
        m_pInstances = NULL;

        // Delete the Read Bytes buffer
        delete m_pReadBytes;
        m_pReadBytes = NULL;

        // Delete the Read Bytes buffer
        delete m_pReadBytes2;
        m_pReadBytes2 = NULL;

        // Get rid of init event
        if (m_hInitEvent)
        {
            (void)CloseHandle(m_hInitEvent);
            m_hInitEvent = NULL;
        }

        // Get rid of data event
        if (m_hDataEvent)
        {
            (void)CloseHandle(m_hDataEvent);
            m_hDataEvent = NULL;
        }

        // Delete the API information structures
        for (i = 0; i < APIID_TOTAL; i++)
        {
            delete m_rgpAPIInfo[i];
            m_rgpAPIInfo[i] = NULL;
        }

        DeleteCriticalSection(&m_csInstances);
        DeleteCriticalSection(&m_csCmdID);
        DeleteCriticalSection(&m_csEmergency);
        m_fInited = FALSE;
        m_fFailedInit=FALSE;
        m_fInitedForSMS = FALSE;
        m_fInitedForSIMPB = FALSE;
        m_dwSIMPBLastSize = (DWORD)-1;
    }

    DeleteCriticalSection(&m_cs);
}

//
// Broadcasts a change in the radio ready state
//
void CRilHandle::SendReadyStateNotification(DWORD dwReadyState)
{
    RILEQUIPMENTSTATE res;
    CNotificationData *pnd = NULL;

    if ((dwReadyState & RIL_READYSTATE_UNLOCKED) && !(g_dwReadyState & RIL_READYSTATE_UNLOCKED))
    {
        // certain commands like COPS need to wait for the module to
        // "settle" after it's been unlocked.
        g_dwUnlocked = GetTickCount();
    }

    // Set this in our global
    if (dwReadyState)
    {
        g_dwReadyState |= dwReadyState;
    }
    else
    {
        g_dwReadyState = 0;
    }

    // Broadcast the notification
    memset(&res, 0x00, sizeof(RILEQUIPMENTSTATE));
    res.cbSize = sizeof(RILEQUIPMENTSTATE);
    res.dwParams = RIL_PARAM_EQUIPMENTSTATE_READYSTATE;
    res.dwReadyState = g_dwReadyState;
    pnd = new CNotificationData;
    if (pnd && pnd->InitFromRealBlob(RIL_NOTIFY_RADIOEQUIPMENTSTATECHANGED, (void *) &res, res.cbSize))
    {
        // Note that BroadcastNotification frees pnd
        BroadcastNotification(pnd);
        pnd = NULL;
    }
    delete pnd;

    if (g_rppPDDParams->fSendRegStatusChangedAfterEveryReadyStateNotification)
    {
        pnd = new CNotificationData;
        if (pnd && pnd->InitFromRealBlob(RIL_NOTIFY_REGSTATUSCHANGED, (void *) &g_dwRegStatus, sizeof(g_dwRegStatus)))
        {
            // Note that BroadcastNotification frees pnd
            BroadcastNotification(pnd);
            pnd = NULL;
        }
        delete pnd;
    }
}

//
// Thread responsible for sending commands from the Command Queue to COM port
//
DWORD WINAPI SimReadyThreadProc(LPVOID lpParameter)
{
    FUNCTION_TRACE(SimReadyThreadProc);
    DEBUGCHK(lpParameter != NULL);
    CRilHandle* pRilDevice = (CRilHandle*)lpParameter;
    DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : SimReadyThreadProc : Entering, pRilDevice=0x%x\r\n"),pRilDevice));
    const DWORD dwReturn = pRilDevice->SimReadyThread();
    DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : SimReadyThreadProc : THREAD IS EXITING, dwReturn=0x%x\r\n"),dwReturn));
    return dwReturn;
}

//
// Loop until RIL is ready to process SIM commands
//
DWORD CRilHandle::SimReadyThread()
{
    CCommand *pCmd = NULL;
    APIINFO apiiInfo;
    const APIID apiid = APIID_GETPHONELOCKEDSTATE;

    // Create an event
    m_fSimReady = FALSE;
    m_hSimReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!m_hSimReadyEvent)
    {
        goto Error;
    }

    // Get the info about this API
    memset(&apiiInfo,0,sizeof(apiiInfo));
    GetAPIInfo(apiid, apiiInfo);

    // Query for the PIN until we don't get back 515 as an error
    do
    {
        DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : SimReadyThread : Sending SIM Query Command...\r\n")));

        // Set up a CPIN command to be sent
        // Note that we don't care what the return value is, so long as it's not that the radio isn't ready
        pCmd = new CCommand;
        if (!pCmd || !pCmd->Init(NULL, "AT+CPIN?\r", NULL, CMDOPT_SIMQUERY, apiiInfo.dwExecTime, apiiInfo.dwTimeout, NULL, ParseGetPhoneLockedState, 0, 0, 0, apiid, NULL, NULL))
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : SimReadyThread : Unable to construct or Init CCommand\r\n")));
            goto SMSReady;
        }

        // Place the command into the command queue
        //    (this may block if the queue is full)
        if (!g_pCmdQ->Put(pCmd, INFINITE))
        {
            goto SMSReady;
        }

        // Now, block until we get a response back
        WaitForSingleObject(m_hSimReadyEvent, apiiInfo.dwTimeout);

        // Sleep a bit before the next try
        if (!m_fSimReady && !m_fQuitReadyStateThread)
        {
            Sleep(2000);
        }
    }
    while (!m_fSimReady && !m_fQuitReadyStateThread);

    if (m_fQuitReadyStateThread)
    {
        goto Error;
    }

SMSReady:
    if (g_rppPDDParams->fRequireWaitingForSMSReady) {
        // Phase 1 - Wait for SMS to be ready
        
        // Create the needed event
        m_fInitedForSMS = FALSE;
        m_hInitedForSMSEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (!m_hInitedForSMSEvent)
        {
            goto Error;
        }

        // for some platforms the measure of SMS readiness is a successful CNMI initialization
        do
        {
            Sleep(10000); //retry every 10s

            if (g_dwReadyState & RIL_READYSTATE_UNLOCKED)
            {
                DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : SMSReadyThread : Sending CNMI Init Command...\r\n")));
                
                pCmd = new CCommand;
#ifdef RIL_CELL_BROADCAST
                if (!pCmd || !pCmd->Init(NULL, "AT+CNMI=2,2,2,1,0\r", NULL, CMDOPT_SMSINIT | CMDOPT_IGNORERSP, EXECTIME_API_DEFAULT, g_TimeoutCmdInit, NULL, NULL, 0, 0, 0, APIID_NONE, NULL, NULL))
#else
                if (!pCmd || !pCmd->Init(NULL, "AT+CNMI=2,2,0,1,0\r", NULL, CMDOPT_SMSINIT | CMDOPT_IGNORERSP, EXECTIME_API_DEFAULT, g_TimeoutCmdInit, NULL, NULL, 0, 0, 0, APIID_NONE, NULL, NULL))
#endif
                {
                    DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : SMSReadyThread : Unable to construct or Init CCommand\r\n")));
                    goto SimPhoneBookReady;
                }
        
                // Place the command into the command queue
                //    (this may block if the queue is full)
                if (!g_pCmdQ->Put(pCmd, INFINITE))
                {
                    goto SimPhoneBookReady;
                }
        
                // Now, block until we get a response back
                WaitForSingleObject(m_hInitedForSMSEvent, g_TimeoutCmdInit);            
            }

⌨️ 快捷键说明

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