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

📄 response.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    if (!fRet && fOK)
    {
        // If that didn't succeed either, see if we got an SMS intermediary prompt
        // we'll treat this as an OK for now, but this will cause the command thread
        // to send down the second part of the command which will be the SMS PDU
 
        fRet = MatchStringBeginning(m_szData, g_rppPDDParams->pchSMSIntermediaryPrompt, szPointer);
    }

    if (fRet)
    {
        m_fUnsolicited = FALSE;
        m_dwCode = (fOK ? RIL_RESULT_OK : RIL_RESULT_ERROR);
        rcbNewLength = szPointer - m_szData;

        if (!fOK)
        {
            // For error responses, we have additional info -- error code
            hrError = E_FAIL;
            if (!SetBlob((void*)&hrError, sizeof(HRESULT)))
            {
                fRet = FALSE;
                goto Error;
            }
        }
    }

    Error:
    return fRet;
}

//
//  This function gets a remotely determined calltype based on information in a RILREMOTEPARTYINFO
//  structure
//
DWORD GetCalltypeFromRemotePartyInfo(RILREMOTEPARTYINFO*prrpi)
{
    DWORD dwLocalCalltype = RIL_CALLTYPE_UNKNOWN;
    if (NULL != g_rlpfExternalCalltypeFunction)
    {
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : GetCalltypeFromRemotePartyInfo : Making Calltype Callback.\r\n")));
        dwLocalCalltype = g_rlpfExternalCalltypeFunction(prrpi);
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : GetCalltypeFromRemotePartyInfo : Calltype Received = %d\r\n"), dwLocalCalltype));
        //  validate calltype
        if ((dwLocalCalltype < RIL_CALLTYPE_UNKNOWN) ||
            (dwLocalCalltype > RIL_CALLTYPE_LAST))
        {
            dwLocalCalltype = RIL_CALLTYPE_UNKNOWN;
        }
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : GetCalltypeFromRemotePartyInfo : Calltype Returned = %d\r\n"), dwLocalCalltype));
    }
    else
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : GetCalltypeFromRemotePartyInfo : g_rlpfExternalCalltypeFunction is NULL.\r\n")));
    }
    return dwLocalCalltype;
}

//
//  This function sets a remotely determined calltype based on information in a RILCALLINFO
//  structure.  It first checks for previously validated data from previous calls to this function.  It then
//  looks for valid data from a RILDrv_Dial call.  If these two fail, it calls GetCalltypeFromRemotePartyInfo.
//  This data is then used to update the necessary calltype and call state structures.
//
VOID SetCalltypeFromCallInfo(RILCALLINFO *prci)
{
    if ( !prci || prci->dwID >= ARRAY_LENGTH(g_rgfCalltypeChecked) )
    {
        ASSERT( FALSE );  //  it may be necessary to increase MAX_TRACKED_CALLS
        return;
    }

    DWORD dwLocalCalltype = RIL_CALLTYPE_UNKNOWN;
    BOOL fFoundDialedCalltype = FALSE;

    if (g_rgfCalltypeChecked[prci->dwID] != TRUE)
    {
        EnterCriticalSection(&g_csDialedCallData);
        // need to see if the calltype has been set up through a dial command
        if (TRUE == g_rcdDialedCallData.fValid)
        {
            //  check the address
            if (!wcsncmp(g_rcdDialedCallData.wszAddress,prci->raAddress.wszAddress,MAXLENGTH_ADDRESS))
            {
                // The address matches, so this is the call associated with the dial in progress.
                dwLocalCalltype = g_rcdDialedCallData.dwCalltype;
                //  invalidate the cache data
                g_rcdDialedCallData.fValid= FALSE;
                fFoundDialedCalltype = TRUE;
                DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : SetCalltypeFromCallInfo : Using g_rcdDialedCallData.dwCalltype = %d\r\n"), dwLocalCalltype));
            }
        }
        LeaveCriticalSection(&g_csDialedCallData);
        if (FALSE == fFoundDialedCalltype)
        {
            //  Haven't got a calltype yet, need to see if a calltype has been set up through a call waiting notification
            if (TRUE == g_rcdWaitingCallData.fValid)
            {
                //  check the address
                if (!wcsncmp(g_rcdWaitingCallData.wszAddress,prci->raAddress.wszAddress,MAXLENGTH_ADDRESS))
                {
                    // The address matches, so this is the call associated with the call waiting call
                    dwLocalCalltype = g_rcdWaitingCallData.dwCalltype;
                    //  invalidate the cache data
                    g_rcdWaitingCallData.fValid = FALSE;
                }
            }
            else
            {
                RILREMOTEPARTYINFO rrpi; memset(&rrpi, 0, sizeof(RILREMOTEPARTYINFO));
                rrpi.cbSize = sizeof(RILREMOTEPARTYINFO);
                rrpi.raAddress = prci->raAddress;
                rrpi.dwValidity = RIL_REMOTEPARTYINFO_VALID;
                // rrpi validity set correctly by memset above
                rrpi.dwParams = RIL_PARAM_RPI_ADDRESS | RIL_PARAM_RPI_VALIDITY;
                //  Haven't got a calltype yet, so query the remote function
                dwLocalCalltype = GetCalltypeFromRemotePartyInfo(&rrpi);
            }
        }
        
        if (RIL_CALLTYPE_UNKNOWN != dwLocalCalltype)
        {
            //  Only override the original calltype if the determined calltype is not unknown
            prci->dwType = dwLocalCalltype;
        }
        g_rgctCalltype[prci->dwID] = prci->dwType;
        g_rgfCalltypeChecked[prci->dwID] = TRUE;
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : SetCalltypeFromCallInfo : External Calltype = %d, Final Calltype = %d, Call ID = %d.\r\n"), dwLocalCalltype, g_rgctCalltype[prci->dwID], prci->dwID));

        EnterCriticalSection(&g_csRingingCallData);
        if (TRUE == g_rcdRingingCallData.fDelayRingNotification)
        {
            // call is ringing but calltype was undetermined - now it is
            g_rcdRingingCallData.dwCalltype = g_rgctCalltype[prci->dwID];
            g_rcdRingingCallData.fCalltypeValid = TRUE;
            g_rcdRingingCallData.fDelayRingNotification = FALSE;
            g_rcdRingingCallData.fForceRingNotification = TRUE;
            g_rcdRingingCallData.fCallIdValid = TRUE;
            g_rcdRingingCallData.dwCallId = prci->dwID;
            DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : SetCalltypeFromCallInfo : Setting g_rcdRingingCallData.fForceRingNotification.\r\n")));
        }
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : SetCalltypeFromCallInfo : Ringing Call TypeValid = %d, type = %d, IdValid = %d, Id = %d, Delay = %d, Force = %d\r\n"), 
            g_rcdRingingCallData.fCalltypeValid, g_rcdRingingCallData.dwCalltype,g_rcdRingingCallData.fCallIdValid,g_rcdRingingCallData.dwCallId,g_rcdRingingCallData.fDelayRingNotification,g_rcdRingingCallData.fForceRingNotification));
        LeaveCriticalSection(&g_csRingingCallData);
    }
    else
    {
        DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : SetCalltypeFromCallInfo : Previously calculated Calltype = %d, Call ID = %d.\r\n"), g_rgctCalltype[prci->dwID], prci->dwID));
        prci->dwType = g_rgctCalltype[prci->dwID];
    }
}

//
// Function passed to CQueue::Enum().
// A REGISTERING response can be immediately followed by a REGISTERED notification.
// Since notificaiton thread has higher priority than command thread, sometimes the REGISTERING response
// arrives at upper layer later than than REGISTERED notification without special synchronization in RIL.
// This will confuse upper layer such as UI. The UI registration state is changed from REGISTERED to 
// REGISTERING and stays as REGISTERING. See bug 130366 for details.
// The solution is to update response queue item from REGISTERING(if there are any) to REGISTERED once 
// a REGISTERED notification is received.
//
BOOL UpdateCREGResponse(void* pItem, DWORD dwData)
{
    FUNCTION_TRACE(UpdateCREGResponse);
    DEBUGCHK(pItem != NULL);

    CResponse* pRsp = (CResponse*)pItem;
    UINT cbLength = pRsp->GetLength();
    LPSTR szData = pRsp->GiveUpData();
    LPSTR szRsp = szData;
    UINT nMode = 0;

    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : UpdateCREGResponse : Response Queue Item: %s\r\n"), szData));

    // Parse "<prefix>+CREG: <mode>,<status>"
    if (!ParseRspPrefix((LPCSTR)szRsp, (LPCSTR &)szRsp)                  ||
        !MatchStringBeginning((LPCSTR)szRsp, "+CREG: ", (LPCSTR &)szRsp) ||
        !ParseUInt((LPCSTR)szRsp, TRUE, nMode, (LPCSTR &)szRsp)         ||
        !MatchStringBeginning((LPCSTR)szRsp, ",", (LPCSTR &)szRsp)) {
        goto Exit;
    }
    SkipChars( (LPCSTR)szRsp, (LPCSTR &)szRsp, " " );

    if((char)dwData != *szRsp)
    {
        *szRsp = (char)dwData;
    }

    DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : UpdateCREGResponse : Response Queue Item Updated: %s\r\n"), szData));

Exit:
    if (!pRsp->Append(szData, cbLength))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : UpdateCREGResponse : CResponse::Append failed\r\n")));
        // Critically low on memory
        SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
        return TRUE; // Stop enumeration
    }

    // Continue enumeration
    return FALSE;
}


//
//
//
BOOL CResponse::ParseNotification(UINT& rcbNewLength, BOOL fDataOnNotificationPort)
{
    FUNCTION_TRACE(CResponse::ParseNotification);
    UINT nCode;
    LPCSTR szPointer = m_szData + m_nOffset;
    BOOL fExpectCRLF = TRUE;
    BOOL fSuppressLogging = FALSE;
#ifdef RIL_WATSON_REPORT
    BOOL fErrorNotification = false;
    LPSTR szData = m_szData;
#endif // RIL_WATSON_REPORT
    BOOL fRet = FALSE;

    // Parse "<prefix>"
    if (!ParseRspPrefix(szPointer, szPointer))
    {
        goto Error;
    }

    if (MatchStringBeginning(szPointer, "+++", szPointer) &&
        ParseUInt(szPointer, FALSE, nCode, szPointer)     &&
        3 == nCode)
    {
        // Special case for "+++" followed by 3(NO CARRIER)
        m_fUnsolicited = FALSE;
        m_dwCode = RIL_RESULT_NOCARRIER;
        fExpectCRLF = FALSE;
    }
    else if (ParseUInt(szPointer, FALSE, nCode, szPointer))
    {
        // Classic V.25ter numeric response (except for 0(OK) and 4(ERROR))
        if (!ParseV25Response(nCode))
        {
            goto Error;
        }
        fExpectCRLF = FALSE;
    }
    else if (MatchStringBeginning(szPointer, "+CREG: ", szPointer))
    {
        if (!ParseRegistrationStatus(szPointer,RIL_NOTIFY_REGSTATUSCHANGED))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CGREG: ", szPointer))
    {
        if (!ParseRegistrationStatus(szPointer,RIL_NOTIFY_GPRSREGSTATUSCHANGED))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CRING: ", szPointer))
    {
        // Ring notification

        // Need to ask for the call list to send the differences. The new incoming call better
        // be in the call list of the radio.
        SetupCallListEvaluation ();
    
        if (!ParseExtRing(szPointer))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CR: ", szPointer))
    {
        // Connection service notification
        if (!ParseServiceInfo(szPointer))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CLIP: ", szPointer))
    {
        // Caller ID notification
        if (!ParseRemotePartyInfo(szPointer, TRUE))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+COLP: ", szPointer))
    {
        // Caller ID notification
        if (!ParseRemotePartyInfo(szPointer, FALSE))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CCWA: ", szPointer))
    {
        // Call waiting notification

        // Need to ask for the call list to send the differences. The new incoming call better
        // be in the call list of the radio.
        SetupCallListEvaluation ();

        if (!ParseCallWaitingInfo(szPointer))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CSSU: ", szPointer))
    {
        // Unsolicited Supplementary Service notification
        if (!ParseUnsolicitedSSInfo(szPointer))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CSSI: ", szPointer))
    {
        // Intermediate Supplementary Service notification
        if (!ParseIntermediateSSInfo(szPointer))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CCCM: ", szPointer))
    {
        // Current Call Meter notification
        if (!ParseCallMeter(szPointer))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CMT: ", szPointer))
    {
        // SMS-DELIVER notification
        char szAlpha[MAXLENGTH_DESCRIPTION];
        (void)ParseString(szPointer, szAlpha, MAXLENGTH_DESCRIPTION, szPointer);
        if (!MatchStringBeginning(szPointer, ",", szPointer) ||
            !ParseMessage(szPointer, RIL_NOTIFY_MESSAGE))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CBM: ", szPointer))
    {
        // Broadcast notification
        if (!ParseMessage(szPointer, RIL_NOTIFY_BCMESSAGE))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CDS: ", szPointer))
    {
        // SMS-STATUS-REPORT notification
        if (!ParseMessage(szPointer, RIL_NOTIFY_STATUSMESSAGE))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CMTI: ", szPointer))
    {
        if (!ParseMessageInSim(szPointer, RIL_NOTIFY_MESSAGE_IN_SIM))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CBMI: ", szPointer))
    {
        if (!ParseMessageInSim(szPointer, RIL_NOTIFY_BCMESSAGE_IN_SIM))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CDSI: ", szPointer))
    {
        if (!ParseMessageInSim(szPointer, RIL_NOTIFY_STATUSMESSAGE_IN_SIM))
        {
            goto Error;
        }
    }
    else if (MatchStringBeginning(szPointer, "+CUSD: ", szPointer))
    {
        // USSD notification
        if (!ParseUSSDInfo(szPointer))
        {
            goto Error;
        }
        fSuppressLogging = TRUE;    // USSD content should not be recorded
        RIL_EVENTLOG_MSG((RILLOG_EVENT_USSDRECEIVED));
    }
    else if (MatchStringBeginning(szPointer, "+CHSR: ", szPointer))
    {
        // HSCSD call parameters notification
        if (!ParseHSCSDParams(szPointer))
        {
            goto Error;
        }
    }
    else if (MatchStringAnywhere(szPointer, "+CME ERROR: ", szPointer))
    {
        if (!ParseExtError(szPointer, g_rgemCMEErrors, NUM_CMEERRORS, g_rppPDDParams->pemCMEErrorTable, g_rppPDDParams->uiCMEErrorTableSize, nCode, FALSE))
        {
#ifdef RIL_RADIO_RESILIENCE
            if (!ParseExtError(szPointer, g_rgemGPRSCMEErrors, NUM_GPRSCMEERRORS, NULL, 0, nCode, FALSE))
#endif // RIL_RADIO_RESILIENCE
            {
                DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Unrecognized CME Error response\r\n")));
                goto Error;
            }

⌨️ 快捷键说明

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