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

📄 rilhand.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            StringCchCopyA( szPrint + iPrint, MAXLENGTH_CMD - iPrint, szCR );
            iPrint += (sizeof(szCR) - 1);
        }
        else if (szChars[iChars] == '\n')
        {
            StringCchCopyA( szPrint + iPrint, MAXLENGTH_CMD - iPrint, szLF );
            iPrint += (sizeof(szLF) - 1);
        }
        else
        {
            szPrint[iPrint] = szChars[iChars];
            iPrint++;
        }
        iChars++;
    }

    if ( iPrint < MAXLENGTH_CMD )
    {
        szPrint[iPrint] = '\0';
    }
    else
    {
        ASSERT( FALSE );
        szPrint[ MAXLENGTH_CMD - 1 ] = 0;
    }

#ifdef RIL_WATSON_REPORT
    // Create AT Cmd string suitable for log buffer
    GetSystemTime(&st);
    cbSize = sizeof(szATLog);
    nLogChars =_snprintf(szATLog, cbSize, "%d/%d/%d %d:%.2d:%.2d  %s%s", 
                         st.wMonth, st.wDay, st.wYear,
                         st.wHour, st.wMinute, st.wSecond,
                         szPrint, szFileEOL);

    if (nLogChars < 0)
    {
        // Buffer was filled. Overwrite end of AT cmd with file EOL.
        szATLog[cbSize-2] = '\r';
        szATLog[cbSize-1] = '\n';
        nLogChars = cbSize - 1;
    }

    // Write results to watson ATCmd log.
    g_RilATCmdLogBuffer.Write((BYTE*)szATLog, nLogChars);
#endif // RIL_WATSON_REPORT


    // Only send the notification if a have an application handle
    if (m_hATCommandLogOwner)
    {
        (void)this->BroadcastATLogBlobNotification(szPrint, iPrint,fResponse);
    }
}

//
// Send an intialization command string to the COM port
//
BOOL SendComInitString(UINT iInitLevel)
{
    FUNCTION_TRACE(SendComInitString);

    char szInit[1024];
    BOOL fRet  = FALSE;
//    extern BOOL g_rgfFirstParseCLCC;
    
    szInit[0]=TEXT('\0');

#ifdef GPRS_CONTEXT_CACHING
        ClearGPRSContextCommandCache();
#endif // GPRS_CONTEXT_CACHING
    
    // Regular initialization
    if (COM_INIT_INDEX == iInitLevel)
    {
        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);
            }
        }
    }

    // Check if the incoming init level is supported by the PDD
    // If so access the init string data using the init level as an index into the PDD's init string table

    const INITSTRING_DATA* psInitStringData = NULL;
    if ( iInitLevel < g_rppPDDParams->uiInitStringDataTableSize )
    {
        psInitStringData = &g_rppPDDParams->pisdInitStringDataTable[ iInitLevel ];
    }

    if (!psInitStringData)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : SendComInitString : psInitStringData==NULL for iInitLevel of %d\r\n"), iInitLevel));
        goto Error;
    }

    if (psInitStringData->szCmd[0])
    {
        strncatz(szInit,psInitStringData->szCmd,sizeof(szInit));
    }

    if (COM_INIT_INDEX == iInitLevel)
    {
        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));
        }
    }

    if (COM_REINIT_INDEX == iInitLevel)
    {
        // send these down after CFUN=1
        char szNextInitCmd[MAX_PATH];
        (void)_snprintfz(szNextInitCmd, MAX_PATH, "+CLIP=%u|+CLIR=%u|", g_dwLastCLIP, g_dwLastCLIR);
        strncatz(szInit,szNextInitCmd,sizeof(szInit));
    }

    // Now go through the string and break it up into individual commands separated by a '|'
    char szCmd[MAX_PATH];
    char *pszStart, *pszEnd;
    DWORD dwCmdOption = psInitStringData->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, const_cast<LPCSTR&>(pszRetry)) ||
                ! MatchStringBeginning(pszRetry, ",", const_cast<LPCSTR&>(pszRetry)) ||
                ! ParseUInt(pszRetry, FALSE, nRetryOnErrorDelay, const_cast<LPCSTR&>(pszRetry)) ||
                ! MatchStringBeginning(pszRetry, "\\", const_cast<LPCSTR&>(pszRetry)))
            {
                nRetriesOnError = 0;
                nRetryOnErrorDelay = 0;
            }
            else
            {
                *pszOpt = '\0';
            }
        }

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

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

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

    // This driver doesn't have a way to query current
    // uplink and downlink volume, so we have to cache them.
    if (COM_REINIT_INDEX == iInitLevel) {
        // These numbers are set according to the
        // values in the reinit string.

        HRESULT hr = PDD_SetUplinkVolume (200);
        if ( FAILED( hr ) )
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : SendComInitString : PDD_SetUplinkVolume failed , hr = [0x%08x]\r\n"), hr));
            goto Error;
        }
        
        hr = PDD_SetDownlinkVolume (200);
        if ( FAILED( hr ) )
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : SendComInitString : PDD_SetDownlinkVolume failed , hr = [0x%08x]\r\n"), hr));
            goto Error;
        }        
    }

#if defined (RIL_CACHE_AUDIO_MUTING)

    // We know the mute is turned off here
    extern BOOL g_fAudioMutingOn;
    g_fAudioMutingOn = FALSE;
#endif

    fRet = TRUE;

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

    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)
{
    FUNCTION_TRACE(CRilInstanceHandle::CRilInstanceHandle);

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

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

//
// Instance handle dtor
//
CRilInstanceHandle::~CRilInstanceHandle()
{
    FUNCTION_TRACE(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;

    delete m_pCRilInstanceNdis;
    m_pCRilInstanceNdis = NULL;
}


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

    if (pDevice->FInEmergencyMode())
    {
        // We can't create any additional RIL instances in emergency mode
        DEBUGCHK(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)
{
    FUNCTION_TRACE(CRilInstanceHandle::Notify);
    DEBUGCHK(FALSE != m_fInited);

    RILDRVNOTIFICATION* prdn = NULL;
    DWORD 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))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilInstanceHandle::Notify : Dropped RIL notification - out of memory? (0x%x)\r\n"), this));
        goto Error;
    }

#ifdef DEBUG
    if (m_notificationQ.GetSize() > 10)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilInstanceHandle::Notify : Notify queue for handle 0x%x has size %d\r\n"), 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)
{
    FUNCTION_TRACE(FEnoughStorage);
    DEBUGCHK(NULL != pItem);

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

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


//
//
//
BOOL CRilInstanceHandle::GetNextNotification(RILDRVNOTIFICATION& rrdnSuppliedStruct)
{
    FUNCTION_TRACE(CRilInstanceHandle::GetNextNotification);
    DEBUGCHK(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.
    DEBUGCHK(SUCCEEDED(hr));

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

⌨️ 快捷键说明

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