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

📄 response.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }
#ifdef RIL_LAST_ERROR
        g_dwLastError = MAKELONG(nCode, RADIO_CMEERROR);
#endif
#ifdef RIL_WATSON_REPORT
        EnterCriticalSection(&g_csRilInfoCache);
        strncpyz(g_RilInfoCache.szLastError, szData, MAXLENGTH_CMD);
        LeaveCriticalSection(&g_csRilInfoCache);
        fErrorNotification = true;
#endif // RIL_WATSON_REPORT
        DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Got CME Error response\r\n")));
        fExpectCRLF = FALSE;
    }
    else if (MatchStringAnywhere(szPointer, "+CMS ERROR: ", szPointer))
    {
        if (!ParseExtError(szPointer, g_rgemCMSErrors, NUM_CMSERRORS, g_rppPDDParams->pemCMSErrorTable, g_rppPDDParams->uiCMSErrorTableSize, nCode, FALSE))
        {
            DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Unrecognized CMS Error response\r\n")));
            goto Error;
        }
#ifdef RIL_LAST_ERROR
        g_dwLastError = MAKELONG(nCode, RADIO_CMSERROR);
#endif
#ifdef RIL_WATSON_REPORT
        EnterCriticalSection(&g_csRilInfoCache);
        strncpyz(g_RilInfoCache.szLastError, szData, MAXLENGTH_CMD);
        LeaveCriticalSection(&g_csRilInfoCache);
        fErrorNotification = true;
#endif // RIL_WATSON_REPORT
        DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Got CMS Error response\r\n")));
        fExpectCRLF = FALSE;
    }
    else if (!ParseNotificationOEM
                  (
                        szPointer, 
                        fExpectCRLF,
                        fDataOnNotificationPort
#ifdef RIL_WATSON_REPORT    
                        , fErrorNotification
#endif
                    )
               )
    {
        goto Error;
    }

    if (fExpectCRLF)
    {
        if (!ParseRspPostfix(szPointer, szPointer))
        {
            DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Failed to find <cr><lf> at end of response\r\n")));
            goto Error;
        }
    }
    else if (!MatchStringBeginning(szPointer, "\r", szPointer))
    {
        DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Failed to find <cr> at end of response\r\n")));
        goto Error;
    }
    rcbNewLength = szPointer - m_szData;
    fRet = TRUE;

    if (!fSuppressLogging)
    {
        RIL_EVENTLOG_MSG((RILLOG_EVENT_PARSEDNOTIFICATION, PrintableString(m_szData, rcbNewLength)));
    }

    Error:
    if (!fRet)
    {
        if (m_fPotentialBogusResponse)
        {
            DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Attempting to filter bogus response\r\n")));

            // Heuristic used is to parse everything up to the first CR.
            if (MatchStringAnywhere(szPointer, "\r", szPointer))
            {
                // If the CR is followed by a LF, then consume that, too.
                (void)MatchStringBeginning(szPointer, "\n", szPointer);

                // If what was just parsed is followed by a simple v.25ter response,
                // then consume that as well.
                if (MatchStringBeginning(szPointer+1, "\r", szPointer))
                {
                    (void)MatchStringBeginning(szPointer, "\n", szPointer);
                }

                // The drawback with the preceding heuristic is that two
                // consecutive responses could be consumed, the second one
                // being potentially valid.

                // Whatever is parsed here should be treated as unrecognized
                m_fUnrecognized = TRUE;

                rcbNewLength = szPointer - m_szData;
                fRet = TRUE;

                if (!fSuppressLogging)
                {
                    RIL_EVENTLOG_MSG((RILLOG_EVENT_PARSEDGARBAGE, PrintableString(m_szData, rcbNewLength)));
                }
            }
        }

        // Blow away a blob we may have allocated
        FreeBlob(m_pBlob);
        m_pBlob = NULL;
        m_cbBlob = 0;
    }

#ifdef RIL_WATSON_REPORT
    // Reset the info cache last error when no error occurred.
    if (!fErrorNotification)
    {
        EnterCriticalSection(&g_csRilInfoCache);
        strncpyz(g_RilInfoCache.szLastError, "", MAXLENGTH_CMD);
        LeaveCriticalSection(&g_csRilInfoCache);
    }
#endif // RIL_WATSON_REPORT

    m_fPotentialBogusResponse = FALSE;

    return fRet;
}


//
//
//
BOOL CResponse::ParseV25Response(const UINT nResponseCode)
{
    FUNCTION_TRACE(CResponse::ParseV25Response);
    RILRINGINFO rri; memset(&rri,0,sizeof(rri)); // zero struct
    RILCONNECTINFO rci; memset(&rci,0,sizeof(rci)); // zero struct
    BOOL fRet = FALSE;

    // NOTE: if IMSI can ever be shorter than 3 characters, this code won't help us
    if (!nResponseCode || 99 < nResponseCode)
    {
        // This can't be a response code
        goto Error;
    }

    switch (nResponseCode)
    {
    case 2:
        m_fUnsolicited = TRUE;
        m_dwCode = RIL_NOTIFY_RING;
        rri.cbSize = sizeof(RILRINGINFO);
        rri.dwCallType = RIL_CALLTYPE_UNKNOWN;
        rri.dwParams |= RIL_PARAM_RI_CALLTYPE;
        if (!SetBlob((void*)&rri, sizeof(RILRINGINFO)))
        {
            goto Error;
        }
        break;

    case 3:
        m_fUnsolicited = FALSE;
        m_dwCode = RIL_RESULT_NOCARRIER;
        break;

    case 6:
        m_fUnsolicited = FALSE;
        m_dwCode = RIL_RESULT_NODIALTONE;
        break;

    case 7:
        m_fUnsolicited = TRUE;
        m_dwCode = RIL_RESULT_BUSY;
        break;

    case 8:
        m_fUnsolicited = FALSE;
        m_dwCode = RIL_RESULT_NOANSWER;
        break;

    case 10:
        m_fUnsolicited = TRUE;
        m_dwCode = RIL_NOTIFY_CONNECT;
        rci.dwBaudRate = 300;
        rci.dwParams |= RIL_PARAM_CNI_BAUDRATE;
        break;

    case 11:
    case 12:
        m_fUnsolicited = TRUE;
        m_dwCode = RIL_NOTIFY_CONNECT;
        rci.dwBaudRate = 1200;
        rci.dwParams |= RIL_PARAM_CNI_BAUDRATE;
        break;

    case 13:
        m_fUnsolicited = TRUE;
        m_dwCode = RIL_NOTIFY_CONNECT;
        rci.dwBaudRate = 2400;
        rci.dwParams |= RIL_PARAM_CNI_BAUDRATE;
        break;

    case 14:
        m_fUnsolicited = TRUE;
        m_dwCode = RIL_NOTIFY_CONNECT;
        rci.dwBaudRate = 4800;
        rci.dwParams |= RIL_PARAM_CNI_BAUDRATE;
        break;

    case 15:
        m_fUnsolicited = TRUE;
        m_dwCode = RIL_NOTIFY_CONNECT;
        rci.dwBaudRate = 9600;
        rci.dwParams |= RIL_PARAM_CNI_BAUDRATE;
        break;

    case 0:
    case 4:
    case 9:
        goto Error;

    default:
        m_fUnsolicited = TRUE;
        m_dwCode = RIL_NOTIFY_CONNECT;
        break;
    }

    // For data connections, set up the associated RILCONNECTINFO structure
    if (RIL_NOTIFY_CONNECT == m_dwCode)
    {
        rci.cbSize = sizeof(RILCONNECTINFO);
        rci.dwCallType = RIL_CALLTYPE_DATA;
        rci.dwParams |= RIL_PARAM_CNI_CALLTYPE;
        if (!SetBlob((void*)&rci, sizeof(RILCONNECTINFO)))
        {
            goto Error;
        }
    }
    fRet = TRUE;

    Error:
    return fRet;
}


//
// Comparison routine used for binary search below
//
static int _cdecl BSCompareErrors(const void* pElem1, const void* pElem2)
{
    DWORD dwCode1 = ((ERRORMAP*)pElem1)->dwCode;
    DWORD dwCode2 = ((ERRORMAP*)pElem2)->dwCode;
    int iRet;

    if (dwCode1 < dwCode2)
    {
        iRet = -1;
    }
    else if (dwCode1 == dwCode2)
    {
        iRet = 0;
    }
    else
    {
        iRet = 1;
    }
    return iRet;
}


//
//
//
BOOL CResponse::ParseExtError(LPCSTR& rszPointer, const ERRORMAP* const rgErrorMap, const UINT nMapEntries, const ERRORMAP* const rgOEMErrorMap, const UINT nOEMMapEntries, UINT &nCode, BOOL fSigned)
{
    FUNCTION_TRACE(CResponse::ParseExtError);
    HRESULT hrError;
    ERRORMAP emKey;
    ERRORMAP* pemFound=NULL;
    LPCSTR szDummy;
    BOOL fRet = FALSE;

    // Look for a "<cr>" to make sure we got the whole number
    if (!MatchStringAnywhere(rszPointer, "\r", szDummy))
    {
        // This isn't a complete error notification -- no need to parse it
        goto Error;
    }

    if (fSigned)
        fRet = ParseIntAsUInt(rszPointer, nCode, rszPointer);
    else
        fRet = ParseUInt(rszPointer, FALSE, nCode, rszPointer);

    if (!fRet)
    {
        // We failed parsing
        ParseJunk(1, rszPointer);
        fRet = TRUE;
        goto Error;
    }

    emKey.dwCode = nCode;

    // first lookup the standard error table

    if (NULL != rgErrorMap) {
        pemFound = (ERRORMAP*)bsearch(&emKey, rgErrorMap, nMapEntries, sizeof(ERRORMAP), BSCompareErrors);
        }

    //if not found, lookup the OEM specific error table

    if ((NULL == pemFound) && (NULL != rgOEMErrorMap)) {
        pemFound = (ERRORMAP*)bsearch(&emKey, rgOEMErrorMap, nOEMMapEntries, sizeof(ERRORMAP), BSCompareErrors);
        }        
    
    hrError = (pemFound ? pemFound->hrError : E_FAIL);

    m_fUnsolicited = FALSE;
    m_dwCode = RIL_RESULT_ERROR;
    if (!SetBlob((void*)&hrError, sizeof(HRESULT)))
    {
        goto Error;
    }
    fRet = TRUE;

    Error:
    return fRet;
}

//
//  See if there is a new presenting call detected via a call progress notification.
//  This is used for Ring and Call Waiting notification processing.  There can be
//  only one new call presenting at a time
//
UINT CachedCallIdOfPresentingCall(VOID)
{
    UINT i;
    //  Check each call id
    for (i=0;i<RIL_MAX_TRACKED_CALL_ID;i++)
    {
        //  Have we determined the type for this call id?
        if (g_rgfCalltypeChecked[i])
        {
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CachedCallIdOfPresentingCall : We have previously determined the type for call id %d.\r\n"), i));
            // Is this call the new incoming call?
            if (FALSE != (RIL_PARAM_CI_CPISTATUS & g_rgfCallStates[i].dwParams))
            {
                DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CachedCallIdOfPresentingCall : CPI Status for this call ID is TRUE.\r\n")));
                if ((RIL_CPISTAT_NEW_INCOMING == g_rgfCallStates[i].dwStatus) ||
                    (RIL_CPISTAT_UNKNOWN == g_rgfCallStates[i].dwStatus))
                {
                    //  This is the  new incoming call, no need to look further
                    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CachedCallIdOfPresentingCall : This is the  new incoming call.\r\n")));
                    break;
                }
            }
        }
    }
    return i;
}

//
//  Find out the externally determined calltype of an incoming ringing call.
//  Return value indicates success (TRUE) or failure (FALSE).  This value
//  should be used to determine whether the ring notification is ready to
//  be sent or needs to be delayed because the calltype is still unknown.
//
BOOL DetermineRingingCalltype(DWORD * pdwCallType)
{
    BOOL fRet = TRUE;
    UINT uiCallId;
    EnterCriticalSection(&g_csRingingCallData);
    //  do we already have the calltype?  if so, then use it
    if (TRUE == g_rcdRingingCallData.fCalltypeValid)
    {
        *pdwCallType = g_rcdRingingCallData.dwCalltype;
    }
    else
    {
        //  look for a presenting call id
        uiCallId = CachedCallIdOfPresentingCall();
        if (RIL_MAX_TRACKED_CALL_ID > uiCallId)
        {
            //  we found an incoming call
            *pdwCallType = g_rgctCalltype[uiCallId];
            g_rcdRingingCallData.dwCalltype = g_rgctCalltype[uiCallId];
            g_rcdRingingCallData.fCalltypeValid = TRUE;
            g_rcdRingingCallData.fCallIdValid = TRUE;
            g_rcdRingingCallData.dwCallId = uiCallId;
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : DetermineRingingCalltype : Setting g_rcdRingingCallData.dwCalltype to %d, ID = %d.\r\n"), g_rgctCalltype[uiCallId],uiCallId));
        }
        else
        {
            // no incoming call with calltype found - delay notification until we know
            g_rcdRingingCallData.fDelayRingNotification = TRUE;
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : DetermineRingingCalltype : Setting g_rcdRingingCallData.fDelayRingNotification.\r\n")));
            fRet = FALSE;
        }
    }
    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : DetermineRingingCalltype : Ringing Call TypeValid = %d, type = %d, IdValid = %d, Id = %d, \r\n"), 
        g_rcdRingingCallData.fCalltypeValid, g_rcdRingingCallData.dwCalltype,g_rcdRingingCallData.fCallIdValid,g_rcdRingingCallData.dwCallId));
    LeaveCriticalSection(&g_csRingingCallData);
    return fRet;
}


//
//
//
BOOL CResponse::ParseExtRing(LPCSTR& rszPointer)
{
    FUNCTION_TRACE(CResponse::ParseExtRing

⌨️ 快捷键说明

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