📄 atcmd.cpp
字号:
#endif
}
delete pRsp;
pRsp = NULL;
}
// Throw up a location update notification if required.
if (g_fLocationInfoReceived)
{
BroadcastRealBlobNotification(RIL_NOTIFY_LOCATIONUPDATE, &g_rliLocationInfo, sizeof(g_rliLocationInfo));
g_fLocationInfoReceived = FALSE;
}
// perform external calltype determination processing
if (g_rfExternalCalltypeDetermination)
{
// Throw up a ring notification if required. This is only required after a +CLIP notification is the first
// notification to provide a reliable calltype after an initial CRING notification has been suppressed.
// This is perfromed here to to stay consistent with the way the RIL handles other secondary or
// after-the-fact notifications (e.g. SIM Toolkit notifications) that are sent along with primary notifications.
EnterCriticalSection(&g_csRingingCallData);
if (g_rcdRingingCallData.fForceRingNotification)
{
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Throwing delayed ring notification.\r\n")));
RILRINGINFO rri; memset(&rri,0,sizeof(rri));
rri.cbSize = sizeof(RILRINGINFO);
rri.dwParams |= RIL_PARAM_RI_CALLTYPE;
rri.dwCallType = g_rcdRingingCallData.dwCalltype;
g_rcdRingingCallData.fForceRingNotification = FALSE;
LeaveCriticalSection(&g_csRingingCallData);
BroadcastRealBlobNotification(RIL_NOTIFY_RING, &rri, sizeof(rri));
}
else
{
LeaveCriticalSection(&g_csRingingCallData);
}
}
// Append the remaining data to the read bytes buffer
if (cbRemainder && !AppendReadBytes(szRemainder, cbRemainder, fDataOnNotificationComPort))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : cbRemainder and AppendReadBytes failed\r\n")));
goto Exit;
}
}
// Free memory occupied by szAppend
delete[] szAppend;
szAppend = NULL;
szRemainder = NULL;
cbAppend = 0;
}
bSuccess=TRUE;
Exit:
delete pRsp;
return bSuccess;
}
#define RESP_DATA_BUF 1024
DWORD CRilHandle::ResponseThread()
{
FUNCTION_TRACE(CRilHandle::ResponseThread);
char szData[RESP_DATA_BUF];
DWORD dwMask;
DWORD dwRead;
DWORD dwErrors;
#ifdef OEM2_DRIVER // use a seperate port for unsoliticated notifications
char szData2[RESP_DATA_BUF];
DWORD dwRead2;
#endif // OEM2_DRIVER
DEBUGCHK(m_pComDevice != NULL);
NKDbgPrintfW(TEXT("ResponseThread Start\r\n"));
// Tell the main thread that we've reached the checkpoint
GetCheckPoint()->Reached();
NKDbgPrintfW(TEXT("ResponseThread Reached CheckPoint\r\n"));
while (1)
{
// See if the thread needs to terminate
if (FCancelSet())
{
break;
}
// Wait for more data
if ( (!m_pComDevice->VirtWaitCommEvent(&dwMask)) || (!dwMask) )
{
// Due to the way the comm handle is passed around, we could have a race condition such that the event mask gets reset
// just before or while we're waiting. To handle this case, we just check to see if the mask was reset out from
// under us, and if it was, we just try again after resetting to a valid state.
// This should never happen though
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : VirtWaitCommEvent failed\r\n")));
DWORD dwCommMask=0;
if (!m_pComDevice->VirtGetCommMask(&dwCommMask) || (dwCommMask!=DEFAULT_COM_MASK))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : VirtWaitCommEvent failed, CommMask was 0x%x\r\n"),dwCommMask));
m_pComDevice->VirtSetCommMask(DEFAULT_COM_MASK);
}
continue;
}
if (dwMask & EV_ERR)
{
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : VirtWaitCommEvent returned EV_ERR\r\n")));
// Error is detected on the downstream port
if (m_pComDevice->VirtClearCommError(&dwErrors, NULL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Detected comm error: %x\r\n"), dwErrors));
}
}
if (dwMask & EV_BREAK)
{
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : VirtWaitCommEvent returned EV_BREAK\r\n")));
// Break is detected on the downstream port
if (m_pComDevice->VirtClearCommBreak())
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Detected comm break\r\n")));
}
}
if (dwMask & EV_RXCHAR)
{
// DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : VirtWaitCommEvent returned EV_RXCHAR\r\n")));
do
{
if (!m_pComDevice->Read(szData, RESP_DATA_BUF, dwRead))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Read failed\r\n")));
break;
}
if (!dwRead)
{
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread no data?!\r\n")));
break;
}
#ifdef SIMULATE_HUNG_RADIO
if (g_fSimulateHungRadio == TRUE)
{
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread Simulating hung radio, discarding data\r\n")));
dwRead = 0;
break;
}
#endif
//Alan: Change the order of CLIP and CRING response.(CRING first)
//#ifdef PHILIP_DRIVER
//only for test
#if 0
char* cpSwap[3];
bool bStepNext = FALSE;
int nCLIPLen = 0;
int nCRINGLen = 0;
if(dwRead < RESP_DATA_BUF)
{
szData[dwRead] = 0;
}
cpSwap[0] = strstr(szData, "\r\n+CLIP:");
if(cpSwap[0] != NULL)
{
cpSwap[1] = strstr(cpSwap[0], "\r\n+CRING:");
if((cpSwap[1] != NULL) && (cpSwap[1] > cpSwap[0]))
{
bStepNext = TRUE;
}
}
if(bStepNext)
{
bStepNext = FALSE;
cpSwap[2] = strstr((cpSwap[1] + 2), "\r\n");
if(cpSwap[2] != NULL)
{
nCLIPLen = cpSwap[1] - cpSwap[0];
nCRINGLen = cpSwap[2] + 2 - cpSwap[1];
bStepNext = TRUE;
}
}
if(bStepNext)
{
char * cpTmp = NULL;
if((nCLIPLen + nCRINGLen) >= 21)
{
cpTmp = new char[nCLIPLen + nCRINGLen];
if(cpTmp != NULL)
{
memcpy(cpTmp, cpSwap[0], nCLIPLen);
memcpy(cpSwap[0], cpSwap[1], nCRINGLen);
memcpy(cpSwap[0] + nCRINGLen, cpTmp, nCLIPLen);
delete cpTmp;
cpTmp = NULL;
}
}
}
#endif
if (!HandleRxData(szData,dwRead,false))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread: HandleRxData failed?!\r\n")));
break;
}
} while (dwRead==RESP_DATA_BUF);
}
#ifdef OEM2_DRIVER // use szData2 and dwRead2
if (dwMask & EV_EVENT2)
{
// DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread : VirtWaitCommEvent returned EV_RXCHAR\r\n")));
do
{
if (!m_pComDevice->Read2(szData2, RESP_DATA_BUF, dwRead2))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread : Read failed\r\n")));
break;
}
if (!dwRead2)
{
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread no data?!\r\n")));
break;
}
#ifdef SIMULATE_HUNG_RADIO
if (g_fSimulateHungRadio == TRUE)
{
DEBUGMSG(ZONE_INFO, (TEXT("RILDrv : i : CRilHandle::ResponseThread Simulating hung radio, discarding data\r\n")));
dwRead2 = 0;
break;
}
#endif
if (!HandleRxData(szData2,dwRead2,true))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilHandle::ResponseThread: HandleRxData failed?!\r\n")));
break;
}
} while (dwRead2==RESP_DATA_BUF);
}
#endif // OEM2_DRIVER
}
NKDbgPrintfW(TEXT("ResponseThread End\r\n"));
return 0;
}
/**********************************************************************/
ATCmd::ATCmd()
{
InitializeCriticalSection( &m_cs );
m_hEvent = NULL;
m_hr = E_NOTIMPL;
m_fInProgress = FALSE;
}
ATCmd::~ATCmd()
{
if ( m_hEvent != NULL )
{
CloseHandle( m_hEvent );
m_hEvent = NULL;
}
DeleteCriticalSection( &m_cs );
}
void
ATCmd::Dump() const
{
#ifdef DEBUG
SYNCBLOCK( m_cs );
_tprintf(TEXT("event [%08x]"), m_hEvent);
_tprintf(TEXT("hr [%08x]"), m_hr);
_tprintf(TEXT("in progress [%d]"), (int)m_fInProgress);
#endif
}
HRESULT
ATCmd::Execute( const char *cmd )
{
HRESULT hr = E_INVALIDARG;
if ( cmd != NULL )
{
SYNCBLOCK( m_cs );
hr = E_FAIL;
HRESULT hr2 = Initialize();
if ( SUCCEEDED( hr2 ) && !m_fInProgress )
{
if ( QueueCmdIgnoreRspWithData(APIID_NONE, // appiid
cmd, // szCmd
CMDOPT_FORCEPARSE, // dwOptions
20000, // dwTimeout
NULL, // Parse fn
NULL, // Ptr to notification data
0, // dwRetries
0, // dwRetriesOnError
0, // dwRetryOnErrorDelay
&ATCmd::s_ParseFunc, // parse fn with data
this) ) // Data
{
m_fInProgress = TRUE;
{
UNSYNCBLOCK( m_cs );
/* wait till the result comes back */
DWORD dwWaitResult = WaitForSingleObject( m_hEvent, INFINITE );
}
/* return the result of the parsing */
hr = m_hr;
}
}
}
return hr;
}
HRESULT
ATCmd::Initialize()
{
HRESULT hr = E_OUTOFMEMORY;
{
SYNCBLOCK( m_cs );
if ( m_hEvent == NULL )
{
m_hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
}
if ( m_hEvent != NULL )
{
hr = S_OK;
}
}
return hr;
}
HRESULT
ATCmd::s_ParseFunc( LPCSTR szRsp, void*& pBlob, UINT& cbBlob, PVOID& pfnParseData )
{
HRESULT hr = E_INVALIDARG;
pBlob = NULL;
cbBlob = 0;
if ( pfnParseData != NULL )
{
ATCmd *pATCmd = reinterpret_cast<ATCmd*>( pfnParseData );
if ( pATCmd != NULL )
{
hr = pATCmd->ParseFunc( szRsp );
}
else
{
hr = E_NOTIMPL;
}
pATCmd = NULL;
}
return hr;
}
HRESULT
ATCmd::ParseFunc( LPCSTR szRsp )
{
HRESULT hr = Parse( szRsp );
{
SYNCBLOCK( m_cs );
/* store the result of the parsing */
m_hr = hr;
m_fInProgress = FALSE;
}
/* notify */
SetEvent( m_hEvent );
hr = S_OK;
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -