📄 atcmd.cpp
字号:
{
// Allocate a new response, if we need it
pRsp = new CResponse(this); //modified by viking wang
if (!pRsp)
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Unable to construct CResponse\r\n")));
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
goto Exit;
}
}
if (m_fLastCommandTimedOut)
{
pRsp->SetPotentialBogusResponseFlag();
m_fLastCommandTimedOut = FALSE;
}
if (!pRsp->AppendString(szAppend, cbAppend, szRemainder, cbRemainder, fDataOnNotificationComPort))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : AppendString failed\r\n")));
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
goto Exit;
}
// Does this contain a complete response?
if (!szRemainder)
{
// No -- break out of this loop and wait for more data to come
// Move the data back to the Read Bytes buffer
if (!InheritReadBytes(pRsp, fDataOnNotificationComPort))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : InheritReadBytes failed\r\n")));
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
goto Exit;
}
// Free memory occupied by szAppend
delete[] szAppend;
szAppend = NULL;
cbAppend = 0;
break;
}
else
{
// We have complete response. Now is a good time to pass the response on to the logging application if one exists.
LogATCommand(pRsp->GetData(), pRsp->GetLength(), ATCMD_LOG_RESPONSE);
#ifdef RIL_WATSON_REPORT
// If the radio was previously hung, Watson logging was reported once and disabled to
// prevent duplicate logs reported when the radio hangs.
// We are receiving data from the radio, so make sure the Watson called flag is reset
// so subsequent problems will be reported.
g_fWatsonCalled = FALSE;
#endif // RIL_WATSON_REPORT
//modified by viking wang on July 10,12007
#if defined(OEM1_DRIVER) || defined(OEM2_SIMTOOLKIT) || defined(EMP_DRIVER)
if (g_CachedToolKitNotifs[0] && IsAPIReady(SH_SHELL))
{
UINT i;
// shell's started. safe to send toolkit notifications now.
for (i = 0; (i < MAX_TOOLKITNOTIFS) && (g_CachedToolKitNotifs[i]); i++)
{
CResponse *pRspCached = g_CachedToolKitNotifs[i];
void* pBlobCached;
UINT cbBlobCached;
pRspCached->GetBlob(pBlobCached, cbBlobCached);
(void)BroadcastRealBlobNotification(pRspCached->GetNotifyCode(), pBlobCached, cbBlobCached);
pRspCached->DeleteBlob();
pBlobCached = NULL;
cbBlobCached = 0;
delete pRspCached;
g_CachedToolKitNotifs[i] = NULL;
}
}
#endif
if ( g_cphschange )
{
/* let upper layer know about CPHS */
BroadcastRealBlobNotification( RIL_NOTIFY_REGSTATUSCHANGED, &g_dwRegStatus, sizeof(g_dwRegStatus) );
g_cphschange = FALSE;
}
#ifdef EMP_DRIVER
if (g_fSystemChanged)
{
// Notify that the system and its capability are changed
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : Sending RIL_NOTIFY_SYSTEMCHANGED and RIL_NOTIFY_SYSTEMCAPSCHANGED\r\n")));
(void)BroadcastDWORDBlobNotification(RIL_NOTIFY_SYSTEMCHANGED, g_dwSystemType);
(void)BroadcastDWORDBlobNotification(RIL_NOTIFY_SYSTEMCAPSCHANGED, g_dwSystemCaps);
g_fSystemChanged = FALSE;
}
#endif
#ifdef RIL_ENABLE_EONS
if ( g_eonschange )
{
/* let upper layer know about EONS */
BroadcastRealBlobNotification( RIL_NOTIFY_EONS, NULL, 0 );
g_eonschange = FALSE;
}
#endif
if (pRsp->FUnrecognized())
{
// We couldn't recognize this response -- assume it was corrupted and throw it away
#ifdef DEBUG
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : Ignoring an unrecognized response: %d chars of %s\r\n"),
pRsp->GetLength(), VerboseString(TString(pRsp->GetData()))));
#endif // DEBUG
g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_UNRECOGNIZEDRSP, PrintableString(pRsp->GetData(), pRsp->GetLength()));
delete pRsp;
pRsp = NULL;
}
else if (!pRsp->FUnsolicited() ||
(RIL_RESULT_BUSY == pRsp->GetNotifyCode() && FWaitingForRsp() && (NULL != m_pCurrCommand && m_pCurrCommand->FDial()) ))
{
#if defined(OEM1_DRIVER) || defined(OEM2_DRIVER) || defined(EMP_DRIVER)
if (!pRsp->GetNotifyCode() && m_fInited)
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Module reset itself?!, rebooting via CPM\r\n")));
if(!CreateProcess(TEXT("rs.exe"), NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL))
{
SignalCriticalError(RILLOG_EVENT_TOOMANYTIMEOUTS, __LINE__, __FILE__);
}
}
#endif
//
// This is a command result
//
// Is someone waiting for this command result?
#if defined(OEM2_DRIVER)
// On TTPCOM, some CPINN command responses come from notification COM port
if (FWaitingForRsp() && ((FALSE == fDataOnNotificationComPort) || pRsp->FCPINNRsp()))
#else
if (FWaitingForRsp() && (FALSE == fDataOnNotificationComPort))
#endif
{
#if 0 // NOT USED
// Treat +CLCC responses while waiting for dial as notifications
if ((m_pCurrCommand->FDial()) && (ParseCLCCNotification(this, m_pCurrCommand, pRsp)))
{
delete pRsp;
pRsp = NULL;
}
else
#endif // 0
#ifdef RIL_RADIO_RESILIENCE
if ( m_pCurrCommand && (RIL_RESULT_OK != pRsp->GetNotifyCode()) && (m_pCurrCommand->CmdOptIsSet(CMDOPT_CPINENTERED)) )
{
// Someone just tried to set the CPIN and failed. Flush the CPIN cache so we don't auto-unlock the phone or PUK the SIM.
SavePINSecure("");
}
if(m_pCurrCommand && (RIL_RESULT_OK == pRsp->GetNotifyCode()) && (m_pCurrCommand->CmdOptIsSet(CMDOPT_ANSWER)))
{ //handle the answer process by viking wang
(void)BroadcastDWORDBlobNotification(RIL_NOTIFY_CALLSTATECHANGED, 0);
}
if (RIL_RESULT_ERROR == pRsp->GetNotifyCode())
{
UINT cbSize = 0;
LPVOID pBlob = NULL;
pRsp->GetBlob(pBlob, cbSize);
if((sizeof(HRESULT) == cbSize) && (RIL_E_RADIOREBOOTED == *(HRESULT *)pBlob))
{
// Reset g_rcdRingingCallData.fCalltypeValid
g_rcdRingingCallData.fCalltypeValid = FALSE;
// The command failed because the radio rebooted.
// Send up a disconnect notification just in case.
(void)m_pComDevice->ExitDataMode();
(void)BroadcastDWORDBlobNotification(RIL_NOTIFY_DISCONNECT,
RIL_DISCINIT_REMOTE);
}
/*if(strstr(m_pCurrCommand->GetCmd(),"AT+PPSTUR="))
{
char tempBuf[40], *tempPtr;
UINT nCmdType;
CCommand *tempCmd = new CCommand;
MatchStringBeginning(m_pCurrCommand->GetCmd(), "AT+PPSTUR=", tempPtr);
MatchStringBeginning(tempPtr,",",tempPtr);
ParseUInt(tempPtr, FALSE, nCmdType, tempPtr);
sprintf(tempBuf,"AT+PPSTUR=%d,16\r",nCmdType);
if (!tempCmd || !tempCmd->Init(NULL, tempBuf, NULL, CMDOPT_SMSINIT | CMDOPT_IGNORERSP, EXECTIME_API_DEFAULT, g_TimeoutCmdInit, NULL, NULL, 0, 0, 0, APIID_NONE, NULL, NULL))
{
g_pCmdQ->Put(tempCmd, INFINITE);
}
}*/
}
#endif // RIL_RADIO_RESILIENCE
// Yes -- place it into the Response Q
#if defined(OEM1_GPRS_DEACT) || defined(EMP_DRIVER)
bool fQueueResponse = TRUE;
// The current command is a GPRS deactivation command
if (m_pCurrCommand && m_pCurrCommand->CmdOptIsSet(CMDOPT_DEACT)) {
// This is a ME DEACT notification (note that only a ME DEACT notification maps to a solicited
// response with a dwCode of RIL_NOTIFY_GPRS_DISCONNECT)
EnterCriticalSection(&g_csGPRSDeactLock);
if (RIL_NOTIFY_GPRS_DISCONNECT == pRsp->GetNotifyCode()) {
// The command response has already been received, convert the dwCode to look like a result
// and make this as the command response, reset all the flags as we are done
if (g_fDeactResponseRcvd) {
// AT+CGACT, 0, ME case - COMPLETE HERE
pRsp->MakeOK();
g_fDeactNotificationRcvd = g_fDeactResponseRcvd = FALSE;
}
// Otherwise, do not queue this response as we have to wait for the actual command response
else {
// AT+CGACT, ME, 0 case - INCOMPLETE HERE
fQueueResponse = FALSE;
(VOID) pRsp->UpdateDataPointer((UINT)strlen("4\r"));
}
}
// This is the response for the deactivation command
else {
g_fDeactResponseRcvd = TRUE;
// The ME DEACT notification has already been received
if (g_fDeactNotificationRcvd) {
// The ME DEACT notification is stale, wait for a new one, do not queue this response
// Note the calculation below is rollover safe but it will not work if the MEDEACT is as stale
// as 49 days - the assumption is we will not have such a stale ME DEACT under normal
// usage
if ((GetTickCount() - g_LastDeactNotificationRcvd) > STALE_MEDEACT_THRESHOLD) {
// Stale ME, AT+CGACT, 0 case (becomes AT+CGACT, 0, ME case) - INCOMPLETE HERE
g_fDeactNotificationRcvd = FALSE;
fQueueResponse = FALSE;
}
// The ME DEACT notification is not stale, this response becomes the real response
else {
// Fresh ME, AT+CGACT, 0 case - COMPLETE HERE
g_fDeactNotificationRcvd = g_fDeactResponseRcvd = FALSE;
}
}
// Otherwise, wait for a ME DEACT, do not queue this response
else {
// AT+CGACT, 0, ME case - INCOMPLETE HERE
fQueueResponse = FALSE;
(VOID) pRsp->UpdateDataPointer((UINT)strlen("0\r"));
}
}
LeaveCriticalSection(&g_csGPRSDeactLock);
}
if (fQueueResponse) {
#endif
if (!QueueRsp(this, pRsp))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : QueueRsp failed\r\n")));
goto Exit;
}
DEBUGCHK(NULL == pRsp);
#if defined(OEM1_GPRS_DEACT) || defined(EMP_DRIVER)
}
#endif
}
else
{
// No -- see if it's one of the exceptions, and if not, throw it away
if (RIL_RESULT_NOCARRIER == pRsp->GetNotifyCode())
{
// This is an unsolicited NOCARRIER, the remote end must have hung up -- exit
// out of the data mode and send out a notification
(void)m_pComDevice->ExitDataMode();
// Reset g_rcdRingingCallData.fCalltypeValid
g_rcdRingingCallData.fCalltypeValid = FALSE;
// For OEM1, ignore unsolicited NOCARRIER. OEM1 implements call progress notifications
// which is the preferred way to get status of the call (including remote side hanging up)
#if !defined(OEM1_GPRS_DEACT) && !defined(EMP_DRIVER)
(void)BroadcastDWORDBlobNotification(RIL_NOTIFY_DISCONNECT,
RIL_DISCINIT_REMOTE);
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : Detected remote disconnect (AT)\r\n")));
#endif
//#if !defined(PHILIP_DRIVER)
#if 1
// Indicate call is inactive to audio driver only if call list is empty.
IndicateCallActivityToAudioSubsystem ( FALSE, TRUE );
#endif
#if defined(WAVECOM_DRIVER) || defined(PHILIP_DRIVER)
// HW-SPECIFIC: WaveCom hardware sends unsolicited "+CME ERROR: 13" when it can't
// detect a SIM card
}
else if (RIL_E_SIMFAILURE == pRsp->GetError())
{
// This is an unsolicited "+CME ERROR: 13" -- send out a "SIM isn't accessible"
// notification
(void)BroadcastRealBlobNotification(RIL_NOTIFY_SIMNOTACCESSIBLE, NULL, 0);
#endif // WAVECOM_DRIVER
#if defined(WAVECOM_DRIVER) || defined(PHILIP_DRIVER)
// HW-SPECIFIC: WaveCom hardware sends unsolicited "+CME ERROR: 3" after a rejected
// USSD transaction
}
else if (RIL_E_OPNOTALLOWED == pRsp->GetError())
{
// This is an unsolicited "+CME ERROR: 3" -- send out a "USSD error" notification
RILSUPSERVICEDATA rssd;
rssd.cbSize = sizeof(RILSUPSERVICEDATA);
rssd.dwStatus = RIL_SUPSVCDATASTATUS_ERROR;
rssd.dwParams = RIL_PARAM_SSDI_STATUS;
(void)BroadcastRealBlobNotification(RIL_NOTIFY_SUPSERVICEDATA,
&rssd, sizeof(RILSUPSERVICEDATA));
#endif // WAVECOM_DRIVER
}
else
{
#ifdef DEBUG
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : Ignoring a response no one is waiting for: %d chars of %s\r\n"),
pRsp->GetLength(), VerboseString(TString(pRsp->GetData()))));
#endif // DEBUG
g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_NOONEWAITING, PrintableString(pRsp->GetData(), pRsp->GetLength()));
}
delete pRsp;
pRsp = NULL;
}
}
else
{
if (RIL_RESULT_BUSY == pRsp->GetNotifyCode())
{
// Reset g_rcdRingingCallData.fCalltypeValid
g_rcdRingingCallData.fCalltypeValid = FALSE;
(void)BroadcastDWORDBlobNotification(RIL_NOTIFY_DISCONNECT, RIL_DISCINIT_BUSY);
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : Detected busy signal\r\n")));
}
else
{
// This is an unsolicited notification -- broadcast it to all clients
// (with the exceptions :
// CONNECT's received while in data mode, because they are effectively
// internal to RIL/VSP
// Notify Codes of NULL, which means the parser is declining to send a
// properly parsed radio notification
// Make sure the registration actually changed (rather than the location data only) before
// sending up a RIL_NOTIFY_REGSTATUSCHANGED.
if ((!((RIL_NOTIFY_REGSTATUSCHANGED == pRsp->GetNotifyCode()) && g_fSuppressRegStatusNotification)) &&
(!((RIL_NOTIFY_GPRSREGSTATUSCHANGED == pRsp->GetNotifyCode()) && g_fSuppressGPRSRegStatusNotification)))
{
if ((!m_pComDevice->FDataMode() || RIL_NOTIFY_CONNECT != pRsp->GetNotifyCode()) &&
(NULL != pRsp->GetNotifyCode()))
{
pRsp->GetBlob(pBlob, cbBlob);
(void)BroadcastRealBlobNotification(pRsp->GetNotifyCode(), pBlob, cbBlob);
pRsp->DeleteBlob();
pBlob = NULL;
cbBlob = 0;
}
}
////////////added by viking wang////////////
// if(RIL_RESULT_NOCARRIER == pRsp->GetNotifyCode())
// (void)(void)BroadcastDWORDBlobNotification(RIL_NOTIFY_CALLSTATECHANGED, 0);
///////////end adding by viking wang///////////
// See if the last command caused us to enter (or return) to data mode
if (RIL_NOTIFY_CONNECT == pRsp->GetNotifyCode())
{
// Yes -- let the virtual serial driver know
if (m_pComDevice->EnterDataMode(szRemainder, cbRemainder))
{
szRemainder += cbRemainder;
cbRemainder = 0;
// Place a response to command that caused connection into the Response Queue
// (the response will later be changed to OK)
if (!QueueRsp(this, pRsp))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : QueueRsp failed\r\n")));
goto Exit;
}
DEBUGCHK(NULL == pRsp);
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : Waiting for command mode\r\n")));
// Wait until module drops out of data mode
if (!m_pComDevice->WaitForCommandMode())
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : WaitForCommandMode failed\r\n")));
goto Exit;
}
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : Done waiting for command mode\r\n")));
}
}
#if defined(OEM1_CSQ_NOTIFICATION) || defined(OEM2_DRIVER) || defined(EMP_DRIVER)
else if (RIL_NOTIFY_REGSTATUSCHANGED == pRsp->GetNotifyCode() && g_fSignalQualityReceived)
{
// Throw up a signal quality notification for good measure.
BroadcastRealBlobNotification(RIL_NOTIFY_SIGNALQUALITY, &g_rsq, sizeof(g_rsq));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -