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

📄 response.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{
    RIL_REMOTEPARTYINFO_VALID,          // 0
    RIL_REMOTEPARTYINFO_WITHHELD,       // 1
    RIL_REMOTEPARTYINFO_UNAVAILABLE,    // 2
};
#define NUM_VALIDITIES      (sizeof(g_rgdwValidities) / sizeof(DWORD))


//
// Supplementary service data status values
//
static const DWORD g_rgdwSupSvcDataStats[] =
{
    RIL_SUPSVCDATASTATUS_NOINFOREQUIRED,        // 0
    RIL_SUPSVCDATASTATUS_FURTHERINFOREQUIRED,   // 1
    RIL_SUPSVCDATASTATUS_TERMINATED,            // 2
    RIL_SUPSVCDATASTATUS_OTHERCLIENTRESPONDED,  // 3
    RIL_SUPSVCDATASTATUS_UNSUPPORTED,           // 4
    RIL_SUPSVCDATASTATUS_TIMEOUT,               // 5
};
#define NUM_SUPSVCDATASTATS     (sizeof(g_rgdwSupSvcDataStats) / sizeof(DWORD))

#ifdef RIL_LAST_ERROR
extern DWORD g_dwLastError;
#endif

CResponse* g_CachedToolKitNotifs[MAX_TOOLKITNOTIFS];

RILSIGNALQUALITY g_rsq;
BOOL g_fSignalQualityReceived = FALSE;

RILLOCATIONINFO g_rliLocationInfo;
BOOL g_fInitialLocationInfoReceived = FALSE;
BOOL g_fLocationInfoReceived = FALSE;
BOOL g_fSuppressRegStatusNotification = FALSE;
BOOL g_fSuppressGPRSRegStatusNotification = FALSE;

//
// Response ctor
//
CResponse::CResponse()
: m_dwCode(0),
m_fUnsolicited(FALSE),
m_fUnrecognized(FALSE),
m_fPotentialBogusResponse(FALSE),
m_pBlob(NULL),
m_cbBlob(0),
m_nOffset(0)
{
    // FUNCTION_TRACE(CResponse::CResponse);
}

//
// copy Response ctor
//
CResponse::CResponse(const CResponse &Rsp)
: m_dwCode(Rsp.m_dwCode),
m_fUnsolicited(Rsp.m_fUnsolicited),
m_fUnrecognized(Rsp.m_fUnrecognized),
m_fPotentialBogusResponse(Rsp.m_fPotentialBogusResponse),
m_pBlob(NULL),
m_cbBlob(0),
m_nOffset(0)
// CBuffer initialized null.
{
}

//
// Response dtor
//
CResponse::~CResponse()
{
    // FUNCTION_TRACE(CResponse::~CResponse);
    FreeBlob(m_pBlob);
    m_pBlob = NULL;
    m_cbBlob = 0;
}


//
// Append data to the response
//
BOOL CResponse::AppendString(const LPCSTR szString, const UINT cbString, LPCSTR& rszRemainder, UINT& rcbRemainder, BOOL fDataOnNotificationPort)
{
    FUNCTION_TRACE(CResponse::AppendString);
    UINT cbNewLength = 0;
    UINT cbOldLength = m_cbLength;
    BOOL fRet = FALSE;

    // Append the new data to the buffer
    if (!Append(szString, cbString))
    {
        goto Error;
    }

    // Parse the data
    if (Parse(cbNewLength, fDataOnNotificationPort))
    {
        DEBUGCHK(cbNewLength != 0);
        DEBUGCHK(cbNewLength <= m_cbLength);

        m_cbLength = cbNewLength;
        rszRemainder = szString + cbNewLength - cbOldLength;
        rcbRemainder = cbString - (rszRemainder - szString);
    }
    else
    {
        rszRemainder = NULL;
        rcbRemainder = 0;
    }
    fRet = TRUE;

    Error:
    return fRet;
}


//
//
//
BOOL CResponse::SetBlob(const void* const pBlob, const UINT cbBlob)
{
    FUNCTION_TRACE(CResponse::SetBlob);
    BOOL fRet = FALSE;

    DEBUGCHK(NULL == m_pBlob && 0 == m_cbBlob);
    FreeBlob(m_pBlob);
    m_cbBlob = 0;

    if (cbBlob)
    {
        DEBUGCHK(NULL != pBlob);

        m_pBlob = AllocBlob(cbBlob);
        if (!m_pBlob)
        {
            // Critically low on memory
            SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
            goto Error;
        }
        memcpy(m_pBlob, pBlob, cbBlob);
    }

    m_cbBlob = cbBlob;
    fRet = TRUE;

    Error:
    return fRet;
}


//
//
//
BOOL CResponse::OKToError(HRESULT hr)
{
    FUNCTION_TRACE(CResponse::OKToError);
    DEBUGCHK(RIL_RESULT_OK == m_dwCode);
    DEBUGCHK(FALSE == m_fUnsolicited);
    return MakeError(hr);
}


//
//
//
BOOL CResponse::MakeError(const HRESULT hrError)
{
    FUNCTION_TRACE(CResponse::MakeError);
    // Get rid of the old blob
    FreeBlob(m_pBlob);
    m_pBlob = NULL;
    m_cbBlob = 0;

    m_fUnsolicited = FALSE;
    m_dwCode = RIL_RESULT_ERROR;
    return SetBlob((void*)&hrError, sizeof(HRESULT));
}

//
// Parse a response
//
BOOL CResponse::Parse(UINT& rcbNewLength, BOOL fDataOnNotificationPort)
{
    FUNCTION_TRACE(CResponse::Parse);
    // NULL-terminate the response string temporarily
    m_szData[m_cbLength] = '\0';

#ifdef DEBUG
    DEBUGMSG(ZONE_ATCMD, (TEXT("RILDrv : i : Accumulated response: %s\r\n"), TString(PrintableString(m_szData, m_cbLength))));
#else
#ifdef WANT_RETAIL_RILDRV_OUTPUT
    {
        char szPrint[256];
        const char szCR[] = "<cr>";
        const char szLF[] = "<lf>";
        UINT iPrint = 0;
        UINT iChars = 0;
        // convert \r, \n to visible chars.
        while (iChars < m_cbLength && iPrint < (sizeof(szPrint) - sizeof(szLF)))
        {
            if (m_szData[iChars] == '\r')
            {
                strcpy(&szPrint[iPrint], szCR);
                iPrint += (sizeof(szCR) - 1);
            }
            else if (m_szData[iChars] == '\n')
            {
                strcpy(&szPrint[iPrint], szLF);
                iPrint += (sizeof(szLF) - 1);
            }
            else
            {
                szPrint[iPrint] = m_szData[iChars];
                iPrint++;
            }
            iChars++;
        }
        szPrint[iPrint] = '\0';
        NKDbgPrintfW(TEXT("RilDrv: Accumulated response: %a\r\n"), szPrint);
    }
#endif //WANT_RETAIL_RILDRV_OUTPUT
#endif // DEBUG

    return (ParseNotification(rcbNewLength, fDataOnNotificationPort)    ||
            ParseOKOrError(TRUE, rcbNewLength) ||
            ParseOKOrError(FALSE, rcbNewLength));
    // Remove attempts to parse partial responses. Can't be done safely with the current architecture,
    // since we can't safely verify at this point that this isn't a valid partial response.
    //    || ParsePartialResponse(rcbNewLength));
}

// This function searches for strings of the form "+X", where X is a set of at least 2
// uppercase characters. If found, it sets rszPointer to the beginning of the string,
// and returns the number of characters in the string.
int FindNextResponse(LPCSTR szStart, LPCSTR& rszPointer)
{
    FUNCTION_TRACE(FindNextResponse);
    LPCSTR szPointer = szStart;
    LPCSTR szCmd;
    int RespSize;

    while (1)
    {
        // Find the first '+' character
        szPointer = strchr(szPointer, '+');
        if (!szPointer)
        {
            // Didn't find a +, abort
            return 0;
        }

        // We found a '+', now look for some capital letters
        RespSize=1;
        szCmd = szPointer+1;
        while (1)
        {
            UCHAR NextChar = *szCmd;

            // If we hit a NULL in the middle of parsing, abort
            if (NextChar=='\0')
            {
                return 0;
            }
            // Is it a capital letter?
            else if ((NextChar >= 'A') && (NextChar <= 'Z'))
            {
                RespSize++;
                szCmd++;
            }
            // Is it a ':', which ends a response?
            else if (NextChar == ':')
            {
                RespSize++;
                rszPointer=szPointer;
                return RespSize;
            }
            // It's some other character. Keep looking.
            else
            {
                // Remember to increment the initial pointer so we don't try to
                // reparse the same + character in an infinite loop
                szPointer=szCmd;
                break;
            }
        }
    }
}

// This function attempts to weed out invalid responses which were truncated due to comm errors
// Note that if this function thinks there is a partial response, it will throw away
// the partial response up to the '+' character of the next response. This means that it will
// also throw away any leading <cr><lf> prefix on the next call. This works because
// ParseRspPrefix always returns TRUE, even if the <cr><lf> prefix isn't there.
// Note that this function runs after other attempts to recognize notifications, OK, or
// ERROR responses have run. Therefore, it won't mistakenly throw away OEM notifications
// which don't begin with a '+', since they should be caught earlier. However, this code
// does run before parsing of responses to commands, so any such responses which don't
// begin with a '+' may be mistakenly thrown away. So far there are no such responses
// that I know of.
BOOL CResponse::ParsePartialResponse(UINT& rcbNewLength)
{
    FUNCTION_TRACE(CResponse::ParsePartialResponse);
    LPCSTR szPointer = m_szData;
    LPCSTR szResponse1;
    LPCSTR szResponse2;
    int cbResponse1;
    int cbResponse2;

    // Skip initial <cr><lf> if there
    ParseRspPrefix(szPointer, szPointer);

    // Look for the first response in buffer (anything of the form "+X", where X is
    // one or more capital letters). Returns 0 if not found.
    cbResponse1 = FindNextResponse(szPointer, szResponse1);

    // If we didn't find one, abort
    if (cbResponse1==0)
    {
        return FALSE;
    }

    // If the first '+' in the buffer doesn't occur immediately after the prefix (or at the
    // beginning if there wasn't a prefix), treat everything before the '+' as the (junk)
    // response

    // This is somewhat nondeterministic, since this will strip leading data off of
    // valid commands if we haven't received the trailing 0<cr> yet,
    // but won't touch the leading data if we have received the trailing 0<cr> (since this
    // will cause the earlier ParseOKOrError to succeed)

    // The individual command response parsers should really be using MatchStringAnywhere
    // to skip past any initial cruft, but most of them use MatchStringBeginning and are
    // therefore somewhat finicky about the +XXX appearing at the beginning or immediately
    // after the prefix. Someday I should go back and fix that. So far the only ones I've
    // made sure to fix are those for parsing SMS Send & Write, which normally have an
    // extra "<cr><lf>> " prepended which may or may not get thrown away by the code below.
    if (szResponse1!=szPointer)
    {
        rcbNewLength = szResponse1 - m_szData;
        m_fUnrecognized = TRUE;
        return TRUE;
    }

    // Look for the second response in buffer.
    cbResponse2 = FindNextResponse(szResponse1+cbResponse1, szResponse2);
    if (cbResponse2==0)
    {
        // If we didn't find a second response, maybe we're still waiting
        // for the rest of the first, so abort
        return FALSE;
    }

    // If the first & second responses differ,
    // assume the first is a partial response and throw it away
    if ( (cbResponse1!=cbResponse2) || strncmp(szResponse1,szResponse2,cbResponse1) )
    {
        rcbNewLength = szResponse2 - m_szData;
        m_fUnrecognized = TRUE;
        return TRUE;
    }

    // Didn't find a partial response (or at least we're not sure it was a partial response)
    return FALSE;
}

//
//
//
BOOL CResponse::ParseOKOrError(const BOOL fOK, UINT& rcbNewLength)
{
    FUNCTION_TRACE(CResponse::ParseOKOrError);
    LPCSTR szPointer = m_szData;
    LPCSTR szCode = (fOK ? "0\r" : "4\r");
    HRESULT hrError;
    BOOL fRet;

    Pre_ParseOKOrErrorOEM(szPointer);
    
    while (1)
    {
        // First search in the beginning of the response
        fRet = MatchStringBeginning(szPointer, szCode, szPointer);
        if (fRet && '\n' != *szPointer)
        {
            // We found "<code><CR>" not followed by <LF> in the beginning of the response
            break;
        }
        else
        {
            // Now search elsewhere in the response
            fRet = MatchStringAnywhere(szPointer, szCode, szPointer);
            if (!fRet)
            {
                // We didn't find "<code><CR>"
                break;
            }
            else if ('\n' != *szPointer &&
                     ('\n' == *(szPointer - 3) || '\r' == *(szPointer - 3)))
            {
                // We found "<code><CR>" not followed by <LF> and preceded by <LF> or <CR>
                break;
            }
        }
    }

    if (!fRet)
    {
        // If we couldn't find the numeric OK or ERROR, try looking for verbose responses
        fRet = MatchStringAnywhere(m_szData, (fOK ? "\r\nOK\r\n" : "\r\nERROR\r\n"), szPointer);
    }

⌨️ 快捷键说明

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