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

📄 rilhand.cpp

📁 Xcale270Bsp包,wince平台
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
//
BOOL CRilHandle::RegisterWithCPM()
{
    // TBD_FUNCTION(CRilHandle::RegisterWithCPM);
    BOOL fRet = FALSE;

    m_pMonitor = new CMonitor;
    if (!m_pMonitor || !m_pMonitor->Init(m_hCancelEvent, m_dwCmdThreadID, m_dwReadThreadID))
    {
        goto Error;
    }
    fRet = TRUE;

    Error:
    if (!fRet)
    {
        delete m_pMonitor;
        m_pMonitor = NULL;
    }
    return fRet;
}


//
//
//
void CRilHandle::GetAPIInfo(APIID apiid, APIINFO& rapii)
{
    // TBD_FUNCTION(CRilHandle::GetAPIInfo);
    TCHAR tszRegKey[MAX_PATH];
    char szID[40];
    APIINFO* pNewAPIInfo = NULL;

    // Intialize the output struct with defaults
    rapii.dwExecTime = EXECTIME_API_DEFAULT;
    rapii.dwTimeout  = g_TimeoutAPIDefault;

    // See if already loaded info for this API
    if (!m_rgpAPIInfo[apiid])
    {
        // Allocate new API info
        pNewAPIInfo = new APIINFO;
        if (!pNewAPIInfo)
        {
            goto Error;
        }

        // Compose the registry key
        (void)_itoa((int)apiid, szID, 10);
        (void)_tcsncpyz(tszRegKey, g_tszRegKeyAPIInfo, MAX_PATH);
        (void)_tcsncatz(tszRegKey, TString(szID), MAX_PATH);

        // Read the execution time and the timeout
        if (!GetRegistryDWORD(HKEY_LOCAL_MACHINE, tszRegKey, TEXT("ExecutionTime"), &pNewAPIInfo->dwExecTime))
        {
            // Just use the default
            pNewAPIInfo->dwExecTime = EXECTIME_API_DEFAULT;
        }
        if (!GetRegistryDWORD(HKEY_LOCAL_MACHINE, tszRegKey, TEXT("Timeout"), &pNewAPIInfo->dwTimeout))
        {
            // Just use the default
            pNewAPIInfo->dwTimeout  = g_TimeoutAPIDefault;
        }

        // If the timeout is specified as 0 milliseconds, assume INFINITE timeout
        if (!pNewAPIInfo->dwTimeout)
        {
            pNewAPIInfo->dwTimeout = INFINITE;
        }

        // Cache the data we just read
        m_rgpAPIInfo[apiid] = pNewAPIInfo;
        pNewAPIInfo = NULL;
    }

    TBD_ASSERT(NULL != m_rgpAPIInfo[apiid]);
    rapii = *m_rgpAPIInfo[apiid];

    Error:
    delete pNewAPIInfo;

    TBD_OUTPUT(TBDCT_INFO, TBDOL_TRACE, TEXT("CRilHandle::GetAPIInfo : Info for API %d: exec time: %d msec, timeout: %d msec"),
               apiid, rapii.dwExecTime, rapii.dwTimeout);
}


//
// Send an intialization command string to the COM port
//
BOOL SendComInitString(UINT iString)
{
    TBD_FUNCTION(SendComInitString);
    TBD_ASSERT(iString < sizeof(g_rgisdModuleInit) / sizeof(INITSTRING_DATA));

    char szInit[1024];
    BOOL fRet  = FALSE;

    szInit[0]=TEXT('\0');

#if !defined(OEMW_DRIVER)
    if (SENDREGINIT(iString))
    {
        TCHAR tszRegInit[MAX_PATH];

        const TCHAR cszPreInitString[] = TEXT("PreInitString");
        tszRegInit[0]=TEXT('\0');
        GetRegistrySZ(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, cszPreInitString, tszRegInit, MAX_PATH);
        if (tszRegInit[0])
        {
            strncatz(szInit,AnsiString(tszRegInit),sizeof(szInit));
        }

        const TCHAR cszTmpInitString[] = TEXT("TmpInitString");
        tszRegInit[0]=TEXT('\0');
        GetRegistrySZ(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, cszTmpInitString, tszRegInit, MAX_PATH);
        if (tszRegInit[0])
        {
            strncatz(szInit,AnsiString(tszRegInit),sizeof(szInit));

            HKEY hKey;
            long lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,g_tszRegKeyRIL,0,0,&hKey);
            if (lResult == ERROR_SUCCESS)
            {
                RegDeleteValue(hKey,cszTmpInitString);
                RegCloseKey(hKey);
            }
        }
    }
#endif

    if (g_rgisdModuleInit[iString].szCmd[0])
    {
        strncatz(szInit,g_rgisdModuleInit[iString].szCmd,sizeof(szInit));
    }

#if !defined(OEMW_DRIVER)
    if (SENDREGINIT(iString))
    {
        TCHAR tszRegInit[MAX_PATH];

        const TCHAR cszInitString[] = TEXT("ComInitString");
        tszRegInit[0]=TEXT('\0');
        GetRegistrySZ(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, cszInitString, tszRegInit, MAX_PATH);
        if (tszRegInit[0])
        {
            strncatz(szInit,AnsiString(tszRegInit),sizeof(szInit));
        }
    }
#endif

    // Now go through the string and break it up into individual commands separated by a '|'
    char szCmd[MAX_PATH];
    char *pszStart, *pszEnd;
    DWORD dwCmdOption = g_rgisdModuleInit[iString].dwCmdOption;
    pszStart = szInit;
    for (;;)
    {
        // Look for the end of the current command
        pszEnd = strchr(pszStart, '|');
        if (pszEnd)
        {
            // If we found a termination char, terminate the command there
            *pszEnd = '\0';
        }
        else
        {
            // This must be the last init command of the initial init phase
            dwCmdOption|=CMDOPT_FINALINIT;
        }

        UINT nRetriesOnError = 0;
        UINT nRetryOnErrorDelay = 0;
        char * pszRetry = strchr(pszStart, '\\');
        if (pszRetry)
        {
            char *pszOpt = pszRetry++;
            if (! ParseUInt(pszRetry, FALSE, nRetriesOnError, pszRetry) ||
                ! MatchStringBeginning(pszRetry, ",", pszRetry) ||
                ! ParseUInt(pszRetry, FALSE, nRetryOnErrorDelay, pszRetry) ||
                ! MatchStringBeginning(pszRetry, "\\", pszRetry))
            {
                nRetriesOnError = 0;
                nRetryOnErrorDelay = 0;
            }
            else
            {
                *pszOpt = '\0';
            }
        }

        // Send the command
        (void)_snprintfz(szCmd, MAX_PATH, "AT%s\r", pszStart);
        if (!QueueCmdIgnoreRsp(szCmd, dwCmdOption, g_TimeoutCmdInit, 2, nRetriesOnError, nRetryOnErrorDelay))
        {
            goto Error;
        }

        // If this was the last command, get out now
        if (!pszEnd)
        {
            break;
        }

        // Get the next command
        pszStart = pszEnd+1;
    }

#if defined(OEM1_DRIVER)
    // This driver doesn't have a way to query current
    // uplink and downlink volume, so we have to cache them.
    if (COM_REINIT_INDEX == iString) {
        extern DWORD g_dwCacheUplinkVolume;
        extern DWORD g_dwCacheDownlinkVolume;

        // These numbers are set according to the
        // values in the reinit string.
        g_dwCacheUplinkVolume = 200;
        g_dwCacheDownlinkVolume = 200;
    }
#endif

    fRet = TRUE;

    Error:
    if (!fRet)
    {
        // Couldn't send an init string -- signal critical error
        SignalCriticalError(RILLOG_EVENT_COULDNTSENDINIT);
    }

    return fRet;
}


//
// Used for cleaning up notification items
// when the notification queue is destroyed.
//
void NotificationItemDtor(void *pItem)
{
    LocalFree(pItem);
}

//
// Instance handle ctor
//
CRilInstanceHandle::CRilInstanceHandle()
: CListElem(),
m_pDevice(NULL),
m_pCmdList(NULL),
m_hNotifyCancelEvent(NULL),
m_notificationQ(NotificationItemDtor),
m_fInited(FALSE),
m_fPreferred(FALSE)
{
    TBD_FUNCTION(CRilInstanceHandle::CRilInstanceHandle);
}


//
// Instance handle dtor
//
CRilInstanceHandle::~CRilInstanceHandle()
{
    TBD_FUNCTION(CRilInstanceHandle::~CRilInstanceHandle);
    if (m_fPreferred)
    {
        // Switch RIL out of emergency mode
        (void)m_pDevice->SetEmergencyMode(FALSE);

        // This handle is not preferred anymore
        m_fPreferred = FALSE;
    }

    CancelNotifications();

    delete m_pCmdList;
    m_pCmdList = NULL;

    if (m_hNotifyCancelEvent)
    {
        (void)CloseHandle(m_hNotifyCancelEvent);
        m_hNotifyCancelEvent = NULL;
    }
    m_fInited = FALSE;
}


//
// Initalization
//
BOOL CRilInstanceHandle::Init(CRilHandle* const pDevice)
{
    TBD_FUNCTION(CRilInstanceHandle::Init);
    BOOL fRet = FALSE;

    if (pDevice->FInEmergencyMode())
    {
        // We can't create any additional RIL instances in emergency mode
        TBD_ASSERT(FALSE == m_fPreferred);
        goto Error;
    }

    // Create command list
    m_pCmdList = new CDblList<CCommand>;
    if (!m_pCmdList)
    {
        goto Error;
    }

    m_pDevice = pDevice;
    m_fInited = TRUE;
    fRet = TRUE;

    Error:
    return fRet;
}


//
//
//
void CRilInstanceHandle::Notify(const DWORD dwCode, const HRESULT hrCmdID, const void* const pBlob,
                                const UINT cbBlob)
{
    TBD_FUNCTION(CRilInstanceHandle::Notify);
    TBD_ASSERT(FALSE != m_fInited);

    RILDRVNOTIFICATION* prdn = NULL;
    UINT cbTotal;

    // Alocate a notification data structure
    // NOTE: LocalAlloc() is used to prevent allocated memory from being tracked
    //       (since it may be freed by a thread coming from RIL proxy)
    cbTotal = sizeof(RILDRVNOTIFICATION) + cbBlob;
    prdn = (RILDRVNOTIFICATION*)LocalAlloc(0, cbTotal);
    if (!prdn)
    {
        goto Error;
    }

    // Fill in the structure fields
    prdn->cbSize = cbTotal;
    prdn->cbSizeNeeded = cbTotal;
    prdn->dwCode = dwCode;
    prdn->hrCmdID = hrCmdID;
    if (cbBlob)
    {
        memcpy(prdn->pbData, pBlob, cbBlob);
    }

    // Try to queue the structure into the Notification Queue
    // (NOTE: this will fail if the queue is already full -- this guarantees that this RIL thread can't
    //        be blocked by a hanging RIL client)
    if (!m_notificationQ.Put(prdn))
    {
        TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("CRilInstanceHandle::Notify : Dropped RIL notification - out of memory? (0x%x)"), this);
        goto Error;
    }

#ifdef TBD_DEBUG
    if (m_notificationQ.GetSize() > 10)
    {
        TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("CRilInstanceHandle::Notify : Notify queue for handle 0x%x has size %d"), this, m_notificationQ.GetSize());
    }
#endif

    // The queue took ownership of the notification data
    //prdn = NULL;
    return;

    Error:
    // NOTE: Since we allocated this structure using LocalAlloc(), we need to use LocalFree() to delete it
    //       (or else the memory tracker will assert)
    LocalFree(prdn);
}


//
// Function passed to CQueue::ConditionalGet() below
//
BOOL FEnoughStorage(void* pItem, DWORD dwData)
{
    TBD_FUNCTION(FEnoughStorage);
    TBD_ASSERT(NULL != pItem);

    RILDRVNOTIFICATION* prdnNextNotification = (RILDRVNOTIFICATION*)pItem;
    RILDRVNOTIFICATION* prdnSuppliedStruct   = (RILDRVNOTIFICATION*)dwData;

    prdnSuppliedStruct->cbSizeNeeded = prdnNextNotification->cbSizeNeeded;
    return (prdnSuppliedStruct->cbSize >= prdnSuppliedStruct->cbSizeNeeded);
}


//
//
//
BOOL CRilInstanceHandle::GetNextNotification(RILDRVNOTIFICATION& rrdnSuppliedStruct)
{
    TBD_FUNCTION(CRilInstanceHandle::GetNextNotification);
    TBD_ASSERT(FALSE != m_fInited);

    RILDRVNOTIFICATION* prdnNextNotification = NULL;
    UINT cbBlob;
    HRESULT hr;
    BOOL fRet = FALSE;

    // Initialize cbSizeNeeded field
    rrdnSuppliedStruct.cbSizeNeeded = rrdnSuppliedStruct.cbSize;

    // Get the next notification from the queue, if the provided size is sufficient
    hr = m_notificationQ.ConditionalGet(FEnoughStorage, (DWORD)&rrdnSuppliedStruct, &prdnNextNotification);
    if (E_FAIL == hr)
    {
        // The supplied size wasn't enough - return TRUE
        fRet = TRUE;
        goto Error;
    }
    else if (S_FALSE == hr)
    {
        goto Error;
    }

    // We shouldn't have to worry about any error result other than E_FAIL.
    TBD_ASSERT(SUCCEEDED(hr));

    // The supplied size is enough, so we retrieved the next notification
    TBD_ASSERT(NULL != prdnNextNotification);
    TBD_ASSERT(prdnNextNotification->cbSize == prdnNextNotification->cbSizeNeeded);

    rrdnSuppliedStruct.dwCode = prdnNextNotification->dwCode;
    rrdnSuppliedStruct.hrCmdID = prdnNextNotification->hrCmdID;
    cbBlob = prdnNextNotification->cbSize - sizeof(RILDRVNOTIFICATION);
    if (cbBlob)
    {
        memcpy(rrdnSuppliedStruct.pbData, prdnNextNotification->pbData, cbBlob);
    }
    fRet = TRUE;

    Error:
    (void)LocalFree(prdnNextNotification);
    return fRet;
}


//
//
//
BOOL CRilInstanceHandle::MakePreferred()
{
    TBD_FUNCTION(CRilInstanceHandle::MakePreferred);
    TBD_ASSERT(NULL != m_pDevice);

    BOOL fRet = FALSE;

    // Switch RIL into emergency mode
    if (!m_pDevice->SetEmergencyMode(TRUE))
    {
        goto Error;
    }

    // Mark this handle as preferred
    m_fPreferred = TRUE;
    fRet = TRUE;

    Error:
    return fRet;
}


//
//
//
BOOL CRilInstanceHandle::CreateNotificationQueue(LPCTSTR tszCancelEventName,
                                                 PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
{
    TBD_FUNCTION(CRilInstanceHandle::CreateNotificationQueue);
    TBD_ASSERT(FALSE != m_fInited);

    BOOL fRet = FALSE;
    DWORD dwOut = 0;

    if (!pBufOut || !dwLenOut || !pdwActualOut)
    {
        goto Error;
    }

    // Initialize Notification Q
    if (!m_notificationQ.Init(5))
    {
        goto Error;
    }

    // Create the cancel event
    m_hNotifyCancelEvent = CreateEvent(NULL, TRUE, FALSE, tszCancelEventName);
    if (!m_hNotifyCancelEvent)
    {
        goto Error;
    }
    TBD_ASSERT(ERROR_ALREADY_EXISTS == GetLastError());

    dwOut = _tcslen(m_notificationQ.GetItemsEventName()) * sizeof(TCHAR) + sizeof(TCHAR);
    if (dwOut > dwLenOut)
    {
        goto Error;
    }

    _tcscpy((TCHAR*)pBufOut, m_notificationQ.GetItemsEventName());
    *pdwActualOut = dwOut;


    fRet = TRUE;

    Error:
    return fRet;
}


//
// Wrap up the serial port operations
//
BOOL DeinitComPort(const CComHandle* const pComDevice)
{
    TBD_FUNCTION(DeinitComPort);
    /*
        DWORD dwWritten;
        return pComDevice->Write("ATZ\r", 4, dwWritten);
    */

    return pComDevice->VirtSetCommMask(0);
}

⌨️ 快捷键说明

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