📄 comhand.cpp
字号:
}
LeaveCriticalSection(&g_csDeactCringLock);
}
if (rpCmd->FNoOp())
{
// This command is a no-op, so we can avoid sending it
// Allocate a new response
pRsp = new CResponse;
if (!pRsp)
{
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
goto Error;
}
// Create an OK response (since the command was a no-op, it can't fail)
pRsp->MakeOK();
// We can't possibly fail a no-op
hr = S_OK;
}
#ifdef RIL_RADIO_RESILIENCE
else if (g_bRadioReboot /*&& !rpCmd->FInit()*/)
{
// The radio is rebooting and the current command is not acceptable
// while the radio is in this state.
pRsp = new CResponse;
if (!pRsp)
{
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
goto Error;
}
RETAILMSG(1, (TEXT("[TI] RILDrv : t : response RIL_E_RADIOREBOOTED\r\n")));
// Create an error response to indicate that the radio is rebooting.
if (!pRsp->MakeError(RIL_E_RADIOREBOOTED))
goto Error;
}
#endif
else if (g_bRadioOff && !rpCmd->FInit() && !rpCmd->CmdOptIsSet(CMDOPT_IGNORERADIOOFF))
{
// The radio is off and the current command is not acceptable
// while the radio is in this state.
//
// Note: These conditions should really be handled in the radio with
// a CME error, but the radio corresponding to the OEM1_DRIVER does
// not behave well when some commands are sent when the radio is in
// the minimum power mode. We keep this logic for the Wavecom driver
// for consistency and testing purposes.
//
// Allocate a new response
pRsp = new CResponse;
if (!pRsp)
{
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
goto Error;
}
// Create an error response to indicate that the radio is off.
if (!pRsp->MakeError(RIL_E_RADIOOFF))
goto Error;
}
else
{
if((rpCmd->GetAPIID() == APIID_GETUSERIDENTITY) && g_HasGetISMI)
{
RETAILMSG(1, (TEXT("[TI] SendRILCmdHandleRsp : GETUSERIDENTITY begin...\r\n")));
// Allocate a new response
pRsp = new CResponse;
if (!pRsp)
{
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
goto Error;
}
// Create an OK response (since the command was a no-op, it can't fail)
char *szRemainder = NULL;
UINT cbRemainder = 0;
if (!pRsp->AppendString(g_szUserIdentityString, strlen(g_szUserIdentityString), szRemainder, cbRemainder, FALSE))
{
goto Error;
}
RETAILMSG(1, (TEXT("[TI] SendRILCmdHandleRsp : GETUSERIDENTITY end...\r\n")));
}
else if(rpCmd->GetAPIID() == APIID_GETLINESTATUS)
{
//add by fengguisen for new CHINA MOBILE specification
//if GETCALLLIST and current FakeHangUp flag is True,return <cr><lf>0<cr><lf> directly
RETAILMSG(1, (TEXT("[TI] SendRILCmdHandleRsp : APIID_GETLINESTATUS begin...\r\n")));
// Allocate a new response
pRsp = new CResponse;
if (!pRsp)
{
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY, __LINE__, __FILE__);
goto Error;
}
// Create an OK response (since the command was a no-op, it can't fail)
char *szRemainder = NULL;
UINT cbRemainder = 0;
char szCLCC[128] = {0};
UINT8 nLineStatus = RILDrv_CC_GetCPASStatus();
_snprintfz(szCLCC, ARRAY_LENGTH(szCLCC), "\r\n+CPAS: %d\r\n0\r", nLineStatus);
if (!pRsp->AppendString(szCLCC, strlen(szCLCC), szRemainder, cbRemainder, FALSE))
{
RETAILMSG(1, (TEXT("[TI] SendRILCmdHandleRsp : APIID_GETLINESTATUS AppendString failed...\r\n")));
goto Error;
}
RETAILMSG(1, (TEXT("[TI] SendRILCmdHandleRsp : APIID_GETLINESTATUS end...\r\n")));
}
else
{
int NumRetries = rpCmd->GetRetries();
while (NumRetries-->=0)
{
if(pRsp)
{
delete pRsp;
pRsp = NULL;
}
// This command wasn't a no-op, so we need to send it
szCmd = rpCmd->GetCmd();
DEBUGCHK(NULL != szCmd);
// Let RIL know we're waiting for AT response
pRilDevice->StartWaitingForRsp(rpCmd);
// We want the response that follows the command we are about to send.
// Discard any responses that have accidentally queued up.
while (!g_pRspQ->FEmpty())
{
hr = g_pRspQ->Get(pRsp, 0);
if (SUCCEEDED(hr))
{
#ifdef DEBUG
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CComHandle::SendRILCmdHandleRsp : Discarding extra queued response: %s\r\n"),
VerboseString(TString(pRsp->GetData()))));
#endif // DEBUG
delete pRsp;
pRsp = NULL;
}
}
#ifdef OEM2_DRIVER
// On OEM2 we need to reset the CPINN event in case one has happened previously.
if (rpCmd->CmdOptIsSet(CMDOPT_SETRADIOON) && (NULL != g_hCPINNEvent))
{
ResetEvent(g_hCPINNEvent);
}
#endif
#ifdef OEM1_GPRS_DEACT
if (rpCmd->CmdOptIsSet(CMDOPT_DEACT)) {
EnterCriticalSection(&g_csGPRSDeactLock);
// In case the previous deactivation attempt did not result in a expected ME DEACT notification
// after a response was received, we want to be sure to not confuse the response for that
// transaction with that for this new transaction, so we clear it
g_fDeactResponseRcvd = FALSE;
LeaveCriticalSection(&g_csGPRSDeactLock);
}
#endif
bool fSendingSecondPart = false;
// Write the command out to the com port
UINT iCmdLen = strlen(szCmd);
if (!WriteCmdsToComPort(pRilDevice, szCmd, iCmdLen))
{
#ifdef DEBUG
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Error writing command: %s\r\n"), VerboseString(TString(szCmd))));
#endif // DEBUG
// Ignore the error. Even if we know that there was a problem writing to the com port,
// we don't know what exactly was written nor whether we should expect a response.
// It's best at this point to wait normally for a response. If no response is generated
// due to the error, then we'll time out and continue as usual.
}
else
{
DWORD dwZone = rpCmd->CmdOptIsSet(CMDOPT_POLLING) ?
RILLOG_ZONE_CMD_POLLING : RILLOG_ZONE_CMD;
if (!rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING))
{
g_RilLog.LogEvent(dwZone, RILLOG_EVENT_SENDINGCMD, PrintableString(szCmd, iCmdLen));
}
else
{
g_RilLog.LogEvent(dwZone, RILLOG_EVENT_SENDINGCMDSUPPRESSED, rpCmd->GetAPIID());
}
#ifdef RIL_WATSON_REPORT
// Store last command in info cache.
EnterCriticalSection(&g_csRilInfoCache);
strncpy(g_RilInfoCache.szLastCmd, szCmd, MAXLENGTH_CMD);
g_RilInfoCache.fLastCmdSuppress = rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING);
LeaveCriticalSection(&g_csRilInfoCache);
#endif //RIL_WATSON_REPORT
}
// If we've just sent a dial or answer command, prepare to handle a hangup command before getting a response
if (rpCmd->FDial() || rpCmd->FAnswer())
{
// Launch a thread to wait for a hangup
HANDLE hThread = NULL;
hQuitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (hQuitEvent)
{
HANGUP_THREAD_DATA* phtd = new HANGUP_THREAD_DATA;
if (phtd)
{
(void)memset(phtd, 0x00, sizeof(HANGUP_THREAD_DATA));
phtd->hQuitEvent = hQuitEvent;
phtd->pComDevice = this;
phtd->pRilDevice = pRilDevice;
hThread = CreateThread(NULL, 0, HangupThreadProc, (LPVOID)phtd, 0, NULL);
}
if (hThread)
{
// We created the thread
// Don't need a handle to the thread...
CloseHandle(hThread);
// The thread takes care of freeing pthd and closing the event handle
// Therefore, don't touch phtd after this point
}
else
{
// If we didn't create the thread, clean up and soldier on...
delete phtd;
phtd=NULL;
CloseHandle(hQuitEvent);
hQuitEvent=NULL;
}
}
}
//WM600029046,ATD have been put in the command array, and last call clcc is 0,and clear sharememory status,so we need reset the dial status now
if(rpCmd->FDial()&&!rpCmd->CmdOptIsSet(CMDOPT_DELAYCONNECTRSP))
{
CALLCTRL_SHARE_MEMORY_OPTION stShareMemOpt;
if(RILDrv_CC_GetShareMemOpt(stShareMemOpt))
{
if(!RILDrv_CC_IsCallExist(stShareMemOpt.nRILDriver1CallFlag,CALL_FLAG_VOICE_FIRST))
{
CC_OPTION stCCOption;
BOOL bSendSpechangup = FALSE;
memset(&stCCOption, 0, sizeof(stCCOption));
stCCOption.bAddCall = TRUE;
stCCOption.nCallType = CALL_TYPE_VOICE_FIRST;
stCCOption.bArranageCID = FALSE;
stCCOption.bReleaseTotalCID = FALSE ;
stCCOption.nLocalCID = 0 ;
stCCOption.nTotalCID = 0 ;
stCCOption.bVoice2ndTo1st = FALSE;
stCCOption.bVoice1stToFakeHangUp = FALSE;
stCCOption.bDial = TRUE;
if(ChangePhoneCallStatus(stCCOption,bSendSpechangup))
{
RETAILMSG(1, (TEXT("[TI]SendRILCmdHandleRsp:VOICE DIAL:call ChangePhoneCallStatus OK\r\n")));
}
else
{
RETAILMSG(1, (TEXT("[TI]SendRILCmdHandleRsp:VOICE DIAL:call ChangePhoneCallStatus failed\r\n")));
}
}
}
}
//end by sunrenhong for fix the bug WM600029046
// Get the response out of the Response Queue
hr = g_pRspQ->Get(pRsp, rpCmd->GetTimeout());
if (SUCCEEDED(hr) && (rpCmd->CmdOptIsSet(CMDOPT_INTERMEDIATERESPONSE)) && (RIL_RESULT_OK == pRsp->GetNotifyCode()))
{
szCmd = rpCmd->GetCmdPart2();
if (NULL != szCmd)
{
// if there is a secondary command, send it out now. This is primarily to handle SMS send commands
// that need an intermediary prompt.
pRilDevice->StopWaitingForRsp();
pRilDevice->StartWaitingForRsp(rpCmd);
fSendingSecondPart = true;
iCmdLen = strlen(szCmd);
if (!WriteCmdsToComPort(pRilDevice, szCmd, iCmdLen))
{
#ifdef DEBUG
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Error writing command: %s\r\n"), VerboseString(TString(szCmd))));
#endif // DEBUG
// Ignore the error. Even if we know that there was a problem writing to the com port,
// we don't know what exactly was written nor whether we should expect a response.
// It's best at this point to wait normally for a response. If no response is generated
// due to the error, then we'll time out and continue as usual.
}
else
{
DWORD dwZone = rpCmd->CmdOptIsSet(CMDOPT_POLLING) ?
RILLOG_ZONE_CMD_POLLING : RILLOG_ZONE_CMD;
if (!rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING))
{
g_RilLog.LogEvent(dwZone, RILLOG_EVENT_SENDINGCMD, PrintableString(szCmd, iCmdLen));
}
else
{
g_RilLog.LogEvent(dwZone, RILLOG_EVENT_SENDINGCMDSUPPRESSED, rpCmd->GetAPIID());
}
#ifdef RIL_WATSON_REPORT
// Store last command in info cache.
EnterCriticalSection(&g_csRilInfoCache);
strncpy(g_RilInfoCache.szLastCmd, szCmd, MAXLENGTH_CMD);
g_RilInfoCache.fLastCmdSuppress = rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING);
LeaveCriticalSection(&g_csRilInfoCache);
#endif //RIL_WATSON_REPORT
}
}
// Now wait for the secondary response which will be the real deal.
delete pRsp;
pRsp = NULL;
hr = g_pRspQ->Get(pRsp, rpCmd->GetTimeout());
}
if (RIL_E_TIMEDOUT == hr)
{
// If we timed out, just print out a warning and (maybe) try again
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CComHandle::SendRILCmdHandleRsp : Cmd timed out? (Before StopWaitingForRsp)\r\n")));
#ifdef RIL_LAST_ERROR
g_dwLastError = MAKELONG(0, RADIO_TIMEOUTERROR);
#endif
if (rpCmd->CmdOptIsSet(CMDOPT_SUPPRESSLOGGING))
{
g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_CMDTIMEDOUTSUPPRESSED, rpCmd->GetAPIID());
}
else
{
g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_CMDTIMEDOUT, PrintableString(szCmd, iCmdLen));
}
#ifndef OEM2_DRIVER
// Bug 29018 Send an extra AT\r to try to kick the modem out of its stupor!
if (fSendingSecondPart)
{
WriteCharsToComPort(pRilDevice, "\x1b\r", 2);
g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_SENDINGCMD, PrintableString("<esc>\r", 6));
}
else
{
WriteCharsToComPort(pRilDevice, "AT\r", 3);
g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_SENDINGCMD, PrintableString("AT\r", 3));
}
HRESULT hrTmp;
CResponse* pRspTmp = NULL;
hrTmp = g_pRspQ->Get(pRspTmp, 500); // Wait 1/2 second for a response
delete pRspTmp;
#endif // ! OEM2_DRIVER
}
// Let RIL know we're not waiting for AT response anymore
pRilDevice->StopWaitingForRsp();
// If we lauched a thread to wait for hangup, kill it
if (hQuitEvent)
{
(void)SetEvent(hQuitEvent);
hQuitEvent = NULL;
}
if (SUCCEEDED(hr))
{
// There is a remote chance that while waiting for a connect code
// to go back into data mode, that we pick up some other rogue
// response. We don't want RIL to go into data mode until we're
// sure there is a connect. So, if we don't get a connect result,
// try the command again.
// If the command generates its own error response, then we will be
// repeating this command/error for NUM_TIMEOUT_INIT_ATTEMPTS.
// The last error response will be returned to the caller.
if (rpCmd->FRequireConnectRsp() &&
RIL_NOTIFY_CONNECT != pRsp->GetNotifyCode())
{
continue;
}
// If we cancelled the last dial command, turn the OK response into a NOCARRIER
if (m_fCancelledDial)
{
if (rpCmd->FDial() || rpCmd->FAnswer())
{
pRsp->SetCallAborted();
}
m_fCancelledDial = FALSE;
}
else if (rpCmd->FDial() && RIL_RESULT_ERROR == pRsp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -