📄 response.cpp
字号:
}
#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 + -