?? atcmd.cpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
atcmd.cpp
Abstract:
Notes:
--*/
#include "precomp.h"
#ifndef _PREFAST_
#pragma warning( disable: 4068 )
#endif
//
// Globals
//
// Command Queue
CPriorityQueue<CCommand, 40>* g_pCmdQ = NULL;
// Response Queue
CQueue<CResponse, 10>* g_pRspQ = NULL;
/* last locked state */
static DWORD g_lastLockedState = RIL_LOCKEDSTATE_UNKNOWN;
extern CQueue<CCommand, 10>* g_pSimLockedQueue;
// certain commands like COPS need to wait for the module to
// "settle" after it's been unlocked.
DWORD g_dwUnlocked;
#ifdef RIL_RADIO_RESILIENCE
extern CRITICAL_SECTION g_csReboot;
#endif // RIL_RADIO_RESILIENCE
extern RILSIGNALQUALITY g_rsq;
extern BOOL g_fSignalQualityReceived;
extern BOOL g_rgfCalltypeChecked[RIL_MAX_TRACKED_CALL_ID];
extern DWORD g_rgctCalltype[RIL_MAX_TRACKED_CALL_ID];
extern RILLOCATIONINFO g_rliLocationInfo;
extern BOOL g_fInitialLocationInfoReceived;
extern BOOL g_fLocationInfoReceived;
extern BOOL g_fSuppressRegStatusNotification;
extern BOOL g_fSuppressGPRSRegStatusNotification;
extern BOOL g_rfExternalCalltypeDetermination;
extern BOOL SetupCallListEvaluation (void);
extern RINGINGCALLDATA g_rcdRingingCallData;
extern CRITICAL_SECTION g_csRingingCallData;
extern BOOL g_fSystemChanged;
extern DWORD g_dwSystemType;
extern DWORD g_dwSystemCaps;
//
// Place a command into the Command Queue
//
BOOL QueueCmdWithTimeout(CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const LPCSTR szCmdPart2, const DWORD dwOptions, const APIID apiid,
const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID, DWORD dwTimeout, DWORD dwRetries)
{
FUNCTION_TRACE(QueueCmdWithTimeout);
DEBUGCHK(0 != (dwOptions & CMDOPT_NOOP) || NULL != szCmd);
CRilHandle* pRilDevice = pHandle->GetDevice();
CCommand* pCmd = NULL;
CNotificationData* pndNotify = pnd;
APIINFO apiiInfo; memset(&apiiInfo,0,sizeof(apiiInfo)); // zero struct
BOOL fRet = FALSE;
DEBUGCHK(NULL != pRilDevice);
rhrCmdID = E_FAIL;
// Get the info about this API
pRilDevice->GetAPIInfo(apiid, apiiInfo);
if (dwTimeout==0)
{
dwTimeout=apiiInfo.dwTimeout;
}
// Set up a command to be sent
pCmd = new CCommand;
if (!pCmd || !pCmd->Init(pHandle, szCmd, szCmdPart2, dwOptions, apiiInfo.dwExecTime, dwTimeout, pndNotify, pfnParse, dwRetries, 0, 0, apiid, NULL, NULL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : QueueCmdWithTimeout : Unable to construct or Init CCommand\r\n")));
goto Error;
}
pndNotify = NULL;
// Add this command to the handle's command list
pHandle->GetCmdList()->Add(pCmd);
rhrCmdID = pCmd->GetID();
DEBUGMSG(ZONE_TRACE, (TEXT("RILDrv : t : Queueing command with ID: 0x%08x\r\n"), rhrCmdID));
#ifdef RIL_RADIO_RESILIENCE
EnterCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
// Place the command into the command queue
// (this may block if the queue is full)
if (!g_pCmdQ->Put(pCmd, INFINITE))
{
#ifdef RIL_RADIO_RESILIENCE
LeaveCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : QueueCmdWithTimeout : Unable to Put CCommand\r\n")));
goto Error;
}
#ifdef RIL_RADIO_RESILIENCE
LeaveCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
// If this is a hangup command, and we're in data mode, we should drop out of data mode immediately
// to handle this request
if (pCmd->FHangup() && pRilDevice->GetComDevice()->FDataMode())
{
pRilDevice->SetDataEvent();
}
if (pCmd->FHangup() || pCmd->FDial() || pCmd->FAnswer())
{
SetEvent(g_hNewDialOrHangupEvent);
}
pCmd = NULL;
fRet = TRUE;
Error:
if (!fRet)
{
delete pCmd;
delete pndNotify;
}
return fRet;
}
//
// Place a command into the Command Queue
//
BOOL QueueCmd(CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const DWORD dwOptions, const APIID apiid,
const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID)
{
FUNCTION_TRACE(QueueCmd);
return QueueCmdWithTimeout(pHandle, szCmd, NULL, dwOptions, apiid, pfnParse, pnd, rhrCmdID, 0, 0);
}
//
// Place a multipart command into the Command Queue
//
BOOL QueueMultipartCmd(CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const LPCSTR szCmdPart2, const DWORD dwOptions, const APIID apiid,
const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, HRESULT& rhrCmdID)
{
FUNCTION_TRACE(QueueCmd);
return QueueCmdWithTimeout(pHandle, szCmd, szCmdPart2, dwOptions, apiid, pfnParse, pnd, rhrCmdID, 0, 0);
}
//
// Place a command into the Command Queue and ignore the response
//
BOOL QueueCmdIgnoreRsp(const APIID apiid, const LPCSTR szCmd, const DWORD dwOptions, DWORD dwTimeout, const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, DWORD dwRetries, DWORD dwRetriesOnError, DWORD dwRetryOnErrorDelay)
{
FUNCTION_TRACE(QueueCmdIgnoreRsp);
DEBUGCHK(0 != (dwOptions & CMDOPT_NOOP) || NULL != szCmd);
CCommand* pCmd = NULL;
BOOL fRet = FALSE;
// Set up a command to be sent
pCmd = new CCommand;
if (!pCmd || !pCmd->Init(NULL, szCmd, NULL, dwOptions | CMDOPT_IGNORERSP, EXECTIME_API_DEFAULT, dwTimeout, pnd, pfnParse, dwRetries, dwRetriesOnError, dwRetryOnErrorDelay, apiid, NULL, NULL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : QueueCmdIgnoreRsp : Unable to construct or Init CCommand\r\n")));
goto Error;
}
#ifdef RIL_RADIO_RESILIENCE
EnterCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
// Place the command into the command queue
// (this may block if the queue is full)
if (!g_pCmdQ->Put(pCmd, INFINITE))
{
#ifdef RIL_RADIO_RESILIENCE
LeaveCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : QueueCmdIgnoreRsp : Unable to Put CCommand\r\n")));
goto Error;
}
#ifdef RIL_RADIO_RESILIENCE
LeaveCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
pCmd = NULL;
fRet = TRUE;
Error:
if (!fRet)
{
delete pCmd;
}
return fRet;
}
//
// Place a command into the Command Queue and ignore the response
//
BOOL QueueCmdIgnoreRspWithData(const APIID apiid, const LPCSTR szCmd, const DWORD dwOptions, DWORD dwTimeout, const PFN_CMD_PARSE pfnParse, CNotificationData* const pnd, DWORD dwRetries, DWORD dwRetriesOnError, DWORD dwRetryOnErrorDelay, const PFN_CMD_PARSE_DATA pfnParseWithData, const PVOID pParseData)
{
FUNCTION_TRACE(QueueCmdIgnoreRsp);
DEBUGCHK(0 != (dwOptions & CMDOPT_NOOP) || NULL != szCmd);
CCommand* pCmd = NULL;
BOOL fRet = FALSE;
// Set up a command to be sent
pCmd = new CCommand;
if (!pCmd || !pCmd->Init(NULL, szCmd, NULL, dwOptions | CMDOPT_IGNORERSP, EXECTIME_API_DEFAULT, dwTimeout, pnd, NULL, dwRetries, dwRetriesOnError, dwRetryOnErrorDelay, apiid, pfnParseWithData, pParseData))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : QueueCmdIgnoreRsp : Unable to construct or Init CCommand\r\n")));
goto Error;
}
#ifdef RIL_RADIO_RESILIENCE
EnterCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
// Place the command into the command queue
// (this may block if the queue is full)
if (!g_pCmdQ->Put(pCmd, INFINITE))
{
#ifdef RIL_RADIO_RESILIENCE
LeaveCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : QueueCmdIgnoreRsp : Unable to Put CCommand\r\n")));
goto Error;
}
#ifdef RIL_RADIO_RESILIENCE
LeaveCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
pCmd = NULL;
fRet = TRUE;
Error:
if (!fRet)
{
delete pCmd;
}
return fRet;
}
//
//
//
DWORD WINAPI RequeueThreadProc(LPVOID lpParameter)
{
FUNCTION_TRACE(RequeueThreadProc);
REQUEUE_THREAD_DATA* prtd = (REQUEUE_THREAD_DATA*)lpParameter;
DEBUGCHK(NULL != prtd);
DEBUGCHK(NULL != prtd->pCmd);
Sleep(prtd->dwDelay);
#ifdef RIL_RADIO_RESILIENCE
EnterCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
// Place the command into the command queue
// (this may block if the queue is full)
if (!g_pCmdQ->Put(prtd->pCmd, INFINITE))
{
delete prtd->pCmd;
}
#ifdef RIL_RADIO_RESILIENCE
LeaveCriticalSection(&g_csReboot);
#endif // RIL_RADIO_RESILIENCE
prtd->pCmd = NULL;
delete prtd;
return 0;
}
//
//
//
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:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -