📄 atcmd.cpp
字号:
if (!fRet)
{
delete prtd;
delete pCmd;
}
return fRet;
}
//
//
//
BOOL QueueRsp(CRilHandle* pRilDevice, CResponse*& rpRsp)
{
FUNCTION_TRACE(QueueRsp);
BOOL fRet = FALSE;
// Remember that we're not waiting for AT response anymore
pRilDevice->StopWaitingForRsp();
// Queue the command response
if (!g_pRspQ->Put(rpRsp, INFINITE))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : QueueRsp : Unable to Put CResponse\r\n")));
goto Error;
}
rpRsp = NULL;
fRet = TRUE;
Error:
return fRet;
}
BOOL ParseCLCCNotification(CRilHandle *pRilDevice, CCommand* pCmd, CResponse* pRsp)
{
FUNCTION_TRACE(ParseCLCCNotification);
BOOL Found=FALSE;
LPCSTR szRsp;
UINT nId;
UINT nDirection;
UINT nStatus;
UINT nType;
UINT nMultiParty;
szRsp = pRsp->GetData();
// Parse "+CLCC: "
while (MatchStringAnywhere(szRsp,"+CLCC: ",szRsp))
{
Found=TRUE;
// Parse "<id>"
if (!ParseUInt(szRsp, TRUE, nId, szRsp))
{
continue;
}
// Parse ",<direction>"
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUInt(szRsp, TRUE, nDirection, szRsp))
{
continue;
}
// Parse ",<status>"
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUInt(szRsp, TRUE, nStatus, szRsp))
{
continue;
}
// Parse ",<type>"
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUInt(szRsp, TRUE, nType, szRsp))
{
continue;
}
// Parse ",<multiparty>"
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUInt(szRsp, TRUE, nMultiParty, szRsp))
{
continue;
}
if (nStatus==2)
{
RILDIALINFO rdi;
rdi.cbSize = sizeof(rdi);
rdi.dwParams = RIL_PARAM_DI_ALL;
rdi.hrCmdId = pCmd->GetID();
rdi.dwCallId = nId;
(void)pRilDevice->BroadcastRealBlobNotification(RIL_NOTIFY_DIAL,
&rdi, sizeof(RILDIALINFO));
break;
}
}
return Found;
}
//
// Thread responsible for sending commands from the Command Queue to COM port
//
DWORD WINAPI CmdThreadProc(LPVOID lpParameter)
{
FUNCTION_TRACE(CmdThreadProc);
DEBUGCHK(lpParameter != NULL);
CRilHandle* pRilDevice = (CRilHandle*)lpParameter;
DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : CmdThreadProc : Entering, pRilDevice=0x%x\r\n"),pRilDevice));
const DWORD dwReturn = pRilDevice->CommandThread();
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CmdThreadProc : THREAD IS EXITING, dwReturn=0x%x\r\n"),dwReturn));
return dwReturn;
}
//
// Thread responsible for reading responses from COM port into the Response Queue
//
DWORD WINAPI ReadThreadProc(LPVOID lpParameter)
{
FUNCTION_TRACE(ReadThreadProc);
DEBUGCHK(lpParameter != NULL);
CRilHandle* pRilDevice = (CRilHandle*)lpParameter;
// Switch the thread into higher priority (to guarantee that the module's in buffer doesn't get overflown)
if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ReadThreadProc : Unable to raise priority of read thread!!\r\n")));
return 0;
}
DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : ReadThreadProc : Entering, pRilDevice=0x%x\r\n"),pRilDevice));
const DWORD dwReturn = pRilDevice->ResponseThread();
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ReadThreadProc : THREAD IS EXITING, dwReturn=0x%x\r\n"),dwReturn));
return dwReturn;
}
DWORD CRilHandle::CommandThread()
{
FUNCTION_TRACE(CRilHandle::CommandThread);
CCommand* pCmd = NULL;
BOOL fBackToCmdMode = FALSE;
DWORD dwReferenceTime;
BOOL fDummy;
HRESULT hr;
DEBUGCHK(m_pComDevice != NULL);
// Tell the main thread that we've reached the checkpoint
GetCheckPoint()->Reached();
if(g_rppPDDParams->fRadioSignonRequired && !m_pComDevice->WaitForRadioSignon(this))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : WaitForRadioSignon failed\r\n")));
}
while (1)
{
// Make sure the module is prepared to handle the command before sending it (except for init commands)
if (!WaitForCommandOrCancel())
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : Cancel was set\r\n")));
goto Error;
}
// Get the next command from the Queue
hr = g_pCmdQ->Get(pCmd, INFINITE);
if (RIL_E_CANCELLED == hr)
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : Get returned RIL_E_CANCELLED\r\n")));
goto Error;
}
DEBUGCHK(FALSE == FAILED(hr));
// If we failed initialization, ignore any non-init commands in the queue
if (m_fFailedInit && !pCmd->FInit())
{
HRESULT dwError = RIL_E_RADIOFAILEDINIT;
pCmd->SendResponse(RIL_RESULT_ERROR, &dwError, sizeof(HRESULT));
continue;
}
if (g_dwUnlocked)
{
DWORD dwTimeSinceUnlock = GetTickCount() - g_dwUnlocked;
// this number was picked by guesswork/experimentation
#define WAIT_FOR_MODULE_TO_SETTLE 500
if (dwTimeSinceUnlock < WAIT_FOR_MODULE_TO_SETTLE)
{
// certain commands like COPS need to wait for the module to
// "settle" after it's been unlocked.
Sleep(WAIT_FOR_MODULE_TO_SETTLE - dwTimeSinceUnlock);
}
g_dwUnlocked = 0;
}
// Send the command to comm port
if (!m_pComDevice->SendRILCmdHandleRsp(this, pCmd, fDummy, fDummy))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : SendRILCmdHandleRsp failed\r\n")));
// Don't give up and exit, just try again
continue;
}
DEBUGCHK(NULL == pCmd);
// If this command dropped the modem into the data mode, switch to data-mode operation
if (m_pComDevice->FDataMode())
{
fBackToCmdMode = FALSE;
dwReferenceTime = GetTickCount();
ResetEvent(m_hDataEvent);
while (!fBackToCmdMode)
{
BOOL fSentCommands = FALSE;
// Sleep for a timeout
WaitForSingleObject(m_hDataEvent, GetDataModeCmdDelay());
// If there is a pending command in the queue, send it through the VSP backdoor
if (!g_pCmdQ->FEmpty() &&
m_pComDevice->SendRILCmdsInDataMode(this, fBackToCmdMode))
{
fSentCommands = TRUE;
}
// See if there's a command pending
if (!fSentCommands &&
GetMaxDataModeTimeWithoutCmd() < GetTickCount() - dwReferenceTime)
{
// The command queue is empty and we haven't sent a command for too long -- queue a no-op command
(void)QueueCmdIgnoreRsp(APIID_NONE, "AT\r", CMDOPT_NONE, g_TimeoutCmdNoOp,NULL, NULL,0,0,0);
(void)m_pComDevice->SendRILCmdsInDataMode(this, fBackToCmdMode);
fSentCommands = TRUE;
}
if (fSentCommands)
{
// Update the reference time
dwReferenceTime = GetTickCount();
}
if (fBackToCmdMode || FCancelSet())
{
break;
}
#ifndef NO_RLSD_SUPPORT
DWORD dwStatus;
if (m_pComDevice->VirtGetCommModemStatus(&dwStatus) && !(dwStatus & MS_RLSD_ON))
{
// RLSD is OFF, which means that data connection has been dropped
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::CommandThread : Detected remote disconnect due to loss of RLSD\r\n")));
// Exit out of the data mode
(void)m_pComDevice->ExitDataMode();
if (!SetupCallListEvaluation ())
{
DEBUGMSG(ZONE_ERROR, (TEXT("CommandThread : E : Error setting up Call List Evaluation\r\n")));
}
fBackToCmdMode = TRUE;
}
#endif
}
}
}
Error:
delete pCmd;
RIL_EVENTLOG_MSG((RILLOG_EVENT_COMMANDTHREADEXIT));
return 0;
}
BOOL CRilHandle::HandleRxData(const char *szData, DWORD dwRead, bool fDataOnNotificationComPort)
{
LPSTR szAppend = NULL;
LPSTR szRemainder = NULL;
UINT cbAppend;
UINT cbRemainder;
void* pBlob;
UINT cbBlob;
CResponse* pRsp = NULL;
BOOL bSuccess=FALSE;
HRESULT hr = E_FAIL;
// DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : ResponseThread read %s\r\n"), TString(PrintableString(szData, dwRead))));
if (!AppendReadBytes(szData, dwRead, fDataOnNotificationComPort))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : AppendReadBytes failed\r\n")));
goto Exit;
}
while (GiveUpReadBytes(szAppend, cbAppend, fDataOnNotificationComPort))
{
if (!cbAppend)
{
// Free memory occupied by szAppend
delete[] szAppend;
szAppend = NULL;
break;
}
if (!pRsp)
{
// Allocate a new response, if we need it
if (FAILED(PDD_GetResponseObject(pRsp)) || !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, const_cast<LPCSTR&>(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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -