📄 atcmd.cpp
字号:
//
BOOL RequeueCmdWithDelay(CCommand* pCmd, DWORD dwDelay)
{
FUNCTION_TRACE(RequeueCmdWithDelay);
DEBUGCHK(NULL != pCmd);
DEBUGCHK(TRUE == pCmd->FIgnoreRsp());
REQUEUE_THREAD_DATA* prtd = NULL;
CCommand* pCmdNew = NULL;
DWORD dwThreadID;
BOOL fRet = FALSE;
// Allocate parameter structure to be passed to the thread proc
prtd = new REQUEUE_THREAD_DATA;
if (!prtd)
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : RequeueCmdWithDelay : Unable to construct REQUEUE_THREAD_DATA\r\n")));
goto Error;
}
// Set up a command to be sent
pCmdNew = new CCommand;
if (!pCmdNew || !pCmdNew->Init(pCmd))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : RequeueCmdWithDelay : Unable to construct or Init CCommand\r\n")));
goto Error;
}
prtd->pCmd = pCmdNew;
prtd->dwDelay = dwDelay;
if (!CreateThread(NULL, 0, RequeueThreadProc, (LPVOID)prtd, 0, &dwThreadID))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : RequeueCmdWithDelay : Unable to CreateThread(RequeueThreadProc)\r\n")));
goto Error;
}
fRet = TRUE;
Error:
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));
// NKDbgPrintfW(TEXT("CmdThreadProc return\r\n"));
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));
NKDbgPrintfW(TEXT("ReadThreadProc return\r\n"));
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);
NKDbgPrintfW(TEXT("CommandThread Start\r\n"));
// Tell the main thread that we've reached the checkpoint
GetCheckPoint()->Reached();
NKDbgPrintfW(TEXT("CommandThread Reached CheckPoint\r\n"));
#if defined(OEM1_DRIVER) && !defined(OEM2_DRIVER) && !defined(EMP_DRIVER)
// On this hardware, we need to wait for the radio to send us it's wakeup string before we start
// sending it commands.
if(!m_pComDevice->WaitForRadioSignon(this))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::CommandThread : WaitForRadioSignon failed\r\n")));
}
#endif // OEM1_DRIVER
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 defined(OEM1_DRIVER) || defined(OEM2_DRIVER) || defined(EMP_DRIVER)
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;
}
#endif
// 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")));
//NKDbgPrintfW(TEXT("RILDrv : E : CRilHandle::CommandThread : SendRILCmdHandleRsp failed fDummy = 0x%x fDummy = 0x%x\r\n"), fDummy, fDummy);
// 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());
NKDbgPrintfW(TEXT("RILDrv :SendRILCmdsInDataMode1 before\r\n"));
// 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
NKDbgPrintfW(TEXT("See if there's a command pending\r\n"));
(void)QueueCmdIgnoreRsp(APIID_NONE, "AT\r", CMDOPT_NONE, g_TimeoutCmdNoOp,NULL, NULL,0,0,0);
NKDbgPrintfW(TEXT("RILDrv :SendRILCmdsInDataMode2 before\r\n"));
(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")));
NKDbgPrintfW(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();
// Notify all clients
(void)BroadcastRealBlobNotification(RIL_NOTIFY_CALLSTATECHANGED, NULL, 0);
fBackToCmdMode = TRUE;
}
#endif
}
}
}
Error:
delete pCmd;
g_RilLog.LogEvent(RILLOG_ZONE_CMD, RILLOG_EVENT_COMMANDTHREADEXIT);
NKDbgPrintfW(TEXT("CommandThread End\r\n"));
return 0;
}
BOOL CRilHandle::HandleRxData(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;
// DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : ResponseThread read %s\r\n"), TString(PrintableString(szData, dwRead))));
//for test
#if 0
NKDbgPrintfW(TEXT("\r\n--------Rcv data-------\r\n"));
for(DWORD i = 0; i < dwRead; i ++)
{
NKDbgPrintfW(TEXT("%0x "), szData[i]);
}
NKDbgPrintfW(TEXT("\r\n--------Rcv data-------\r\n"));
#endif
//added by viking wang to fix bug
{
LPSTR tmpPtr;
if('\0' == szData[dwRead-1] )
{
if('K' == szData[dwRead-2] &&
'O'== szData[dwRead-3])
{
tmpPtr = szData + dwRead-3;
tmpPtr[0]=0x0d;
tmpPtr[1]=0x0a;
tmpPtr[2]='O';
tmpPtr[3]='K';
tmpPtr[4]=0x0d;
tmpPtr[5]=0x0a;
dwRead += 3;
}
else if(dwRead >= 16 &&
'R' == szData[dwRead-2] &&
'E' == szData[dwRead-3] &&
'I' == szData[dwRead-4] &&
'R' == szData[dwRead-5] &&
'R' == szData[dwRead-6] &&
'A' == szData[dwRead-7] &&
'C' == szData[dwRead-8] &&
' ' == szData[dwRead-9] &&
'O' == szData[dwRead-10] &&
'N' == szData[dwRead-11] &&
' ' == szData[dwRead-12] &&
'S' == szData[dwRead-13] &&
'R' == szData[dwRead-14] &&
'P' == szData[dwRead-15] &&
'G' == szData[dwRead-16]
)
{
return TRUE;
}
else szData[dwRead-1]= 0x20;
}
}
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -