📄 rilhand.cpp
字号:
StringCchCopyA( szPrint + iPrint, MAXLENGTH_CMD - iPrint, szCR );
iPrint += (sizeof(szCR) - 1);
}
else if (szChars[iChars] == '\n')
{
StringCchCopyA( szPrint + iPrint, MAXLENGTH_CMD - iPrint, szLF );
iPrint += (sizeof(szLF) - 1);
}
else
{
szPrint[iPrint] = szChars[iChars];
iPrint++;
}
iChars++;
}
if ( iPrint < MAXLENGTH_CMD )
{
szPrint[iPrint] = '\0';
}
else
{
ASSERT( FALSE );
szPrint[ MAXLENGTH_CMD - 1 ] = 0;
}
#ifdef RIL_WATSON_REPORT
// Create AT Cmd string suitable for log buffer
GetSystemTime(&st);
cbSize = sizeof(szATLog);
nLogChars =_snprintf(szATLog, cbSize, "%d/%d/%d %d:%.2d:%.2d %s%s",
st.wMonth, st.wDay, st.wYear,
st.wHour, st.wMinute, st.wSecond,
szPrint, szFileEOL);
if (nLogChars < 0)
{
// Buffer was filled. Overwrite end of AT cmd with file EOL.
szATLog[cbSize-2] = '\r';
szATLog[cbSize-1] = '\n';
nLogChars = cbSize - 1;
}
// Write results to watson ATCmd log.
g_RilATCmdLogBuffer.Write((BYTE*)szATLog, nLogChars);
#endif // RIL_WATSON_REPORT
// Only send the notification if a have an application handle
if (m_hATCommandLogOwner)
{
(void)this->BroadcastATLogBlobNotification(szPrint, iPrint,fResponse);
}
}
//
// Send an intialization command string to the COM port
//
BOOL SendComInitString(UINT iInitLevel)
{
FUNCTION_TRACE(SendComInitString);
char szInit[1024];
BOOL fRet = FALSE;
// extern BOOL g_rgfFirstParseCLCC;
szInit[0]=TEXT('\0');
#ifdef GPRS_CONTEXT_CACHING
ClearGPRSContextCommandCache();
#endif // GPRS_CONTEXT_CACHING
// Regular initialization
if (COM_INIT_INDEX == iInitLevel)
{
TCHAR tszRegInit[MAX_PATH];
const TCHAR cszPreInitString[] = TEXT("PreInitString");
tszRegInit[0]=TEXT('\0');
GetRegistrySZ(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, cszPreInitString, tszRegInit, MAX_PATH);
if (tszRegInit[0])
{
strncatz(szInit,AnsiString(tszRegInit),sizeof(szInit));
}
const TCHAR cszTmpInitString[] = TEXT("TmpInitString");
tszRegInit[0]=TEXT('\0');
GetRegistrySZ(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, cszTmpInitString, tszRegInit, MAX_PATH);
if (tszRegInit[0])
{
strncatz(szInit,AnsiString(tszRegInit),sizeof(szInit));
HKEY hKey;
long lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,g_tszRegKeyRIL,0,0,&hKey);
if (lResult == ERROR_SUCCESS)
{
RegDeleteValue(hKey,cszTmpInitString);
RegCloseKey(hKey);
}
}
}
// Check if the incoming init level is supported by the PDD
// If so access the init string data using the init level as an index into the PDD's init string table
const INITSTRING_DATA* psInitStringData = NULL;
if ( iInitLevel < g_rppPDDParams->uiInitStringDataTableSize )
{
psInitStringData = &g_rppPDDParams->pisdInitStringDataTable[ iInitLevel ];
}
if (!psInitStringData)
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : SendComInitString : psInitStringData==NULL for iInitLevel of %d\r\n"), iInitLevel));
goto Error;
}
if (psInitStringData->szCmd[0])
{
strncatz(szInit,psInitStringData->szCmd,sizeof(szInit));
}
if (COM_INIT_INDEX == iInitLevel)
{
TCHAR tszRegInit[MAX_PATH];
const TCHAR cszInitString[] = TEXT("ComInitString");
tszRegInit[0]=TEXT('\0');
GetRegistrySZ(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, cszInitString, tszRegInit, MAX_PATH);
if (tszRegInit[0])
{
strncatz(szInit,AnsiString(tszRegInit),sizeof(szInit));
}
}
if (COM_REINIT_INDEX == iInitLevel)
{
// send these down after CFUN=1
char szNextInitCmd[MAX_PATH];
(void)_snprintfz(szNextInitCmd, MAX_PATH, "+CLIP=%u|+CLIR=%u|", g_dwLastCLIP, g_dwLastCLIR);
strncatz(szInit,szNextInitCmd,sizeof(szInit));
}
// Now go through the string and break it up into individual commands separated by a '|'
char szCmd[MAX_PATH];
char *pszStart, *pszEnd;
DWORD dwCmdOption = psInitStringData->dwCmdOption;
pszStart = szInit;
for (;;)
{
// Look for the end of the current command
pszEnd = strchr(pszStart, '|');
if (pszEnd)
{
// If we found a termination char, terminate the command there
*pszEnd = '\0';
}
else
{
// This must be the last init command of the initial init phase
dwCmdOption|=CMDOPT_FINALINIT;
}
UINT nRetriesOnError = 0;
UINT nRetryOnErrorDelay = 0;
char * pszRetry = strchr(pszStart, '\\');
if (pszRetry)
{
char *pszOpt = pszRetry++;
if (! ParseUInt(pszRetry, FALSE, nRetriesOnError, const_cast<LPCSTR&>(pszRetry)) ||
! MatchStringBeginning(pszRetry, ",", const_cast<LPCSTR&>(pszRetry)) ||
! ParseUInt(pszRetry, FALSE, nRetryOnErrorDelay, const_cast<LPCSTR&>(pszRetry)) ||
! MatchStringBeginning(pszRetry, "\\", const_cast<LPCSTR&>(pszRetry)))
{
nRetriesOnError = 0;
nRetryOnErrorDelay = 0;
}
else
{
*pszOpt = '\0';
}
}
// Send the command
(void)_snprintfz(szCmd, MAX_PATH, "AT%s\r", pszStart);
if (!QueueCmdIgnoreRsp(APIID_NONE, szCmd, dwCmdOption, g_TimeoutCmdInit, NULL, NULL, 2, nRetriesOnError, nRetryOnErrorDelay))
{
goto Error;
}
// If this was the last command, get out now
if (!pszEnd)
{
break;
}
// Get the next command
pszStart = pszEnd+1;
}
// This driver doesn't have a way to query current
// uplink and downlink volume, so we have to cache them.
if (COM_REINIT_INDEX == iInitLevel) {
// These numbers are set according to the
// values in the reinit string.
HRESULT hr = PDD_SetUplinkVolume (200);
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : SendComInitString : PDD_SetUplinkVolume failed , hr = [0x%08x]\r\n"), hr));
goto Error;
}
hr = PDD_SetDownlinkVolume (200);
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : SendComInitString : PDD_SetDownlinkVolume failed , hr = [0x%08x]\r\n"), hr));
goto Error;
}
}
#if defined (RIL_CACHE_AUDIO_MUTING)
// We know the mute is turned off here
extern BOOL g_fAudioMutingOn;
g_fAudioMutingOn = FALSE;
#endif
fRet = TRUE;
Error:
if (!fRet)
{
// Couldn't send an init string -- signal critical error
SignalCriticalError(RILLOG_EVENT_COULDNTSENDINIT, __LINE__, __FILE__);
}
return fRet;
}
//
// Used for cleaning up notification items
// when the notification queue is destroyed.
//
void NotificationItemDtor(void *pItem)
{
LocalFree(pItem);
}
//
// Instance handle ctor
//
CRilInstanceHandle::CRilInstanceHandle()
: CListElem(),
m_pDevice(NULL),
m_pCmdList(NULL),
m_hNotifyCancelEvent(NULL),
m_notificationQ(NotificationItemDtor),
m_fInited(FALSE),
m_fPreferred(FALSE)
{
FUNCTION_TRACE(CRilInstanceHandle::CRilInstanceHandle);
if (TRUE == GetRegistryPacketSupport())
{
// This object owns the pointer returned by PDD_GetRilInstanceNdisObject
// PDD_GetRilInstanceNdisObject is not expected to return E_NOTIMPL here since the above check succeeds
HRESULT hr = PDD_GetRilInstanceNdisObject(this, m_pCRilInstanceNdis);
if ( FAILED( hr ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilInstanceHandle ctor : PDD_GetRilInstanceNdisObject failed , hr = [0x%08x]\r\n"), hr));
}
}
else
{
m_pCRilInstanceNdis = NULL;
}
}
//
// Instance handle dtor
//
CRilInstanceHandle::~CRilInstanceHandle()
{
FUNCTION_TRACE(CRilInstanceHandle::~CRilInstanceHandle);
if (m_fPreferred)
{
// Switch RIL out of emergency mode
(void)m_pDevice->SetEmergencyMode(FALSE);
// This handle is not preferred anymore
m_fPreferred = FALSE;
}
CancelNotifications();
delete m_pCmdList;
m_pCmdList = NULL;
if (m_hNotifyCancelEvent)
{
(void)CloseHandle(m_hNotifyCancelEvent);
m_hNotifyCancelEvent = NULL;
}
m_fInited = FALSE;
delete m_pCRilInstanceNdis;
m_pCRilInstanceNdis = NULL;
}
//
// Initalization
//
BOOL CRilInstanceHandle::Init(CRilHandle* const pDevice)
{
FUNCTION_TRACE(CRilInstanceHandle::Init);
BOOL fRet = FALSE;
if (pDevice->FInEmergencyMode())
{
// We can't create any additional RIL instances in emergency mode
DEBUGCHK(FALSE == m_fPreferred);
goto Error;
}
// Create command list
m_pCmdList = new CDblList<CCommand>;
if (!m_pCmdList)
{
goto Error;
}
m_pDevice = pDevice;
m_fInited = TRUE;
fRet = TRUE;
Error:
return fRet;
}
//
//
//
void CRilInstanceHandle::Notify(const DWORD dwCode, const HRESULT hrCmdID, const void* const pBlob,
const UINT cbBlob)
{
FUNCTION_TRACE(CRilInstanceHandle::Notify);
DEBUGCHK(FALSE != m_fInited);
RILDRVNOTIFICATION* prdn = NULL;
DWORD cbTotal;
// Alocate a notification data structure
// NOTE: LocalAlloc() is used to prevent allocated memory from being tracked
// (since it may be freed by a thread coming from RIL proxy)
cbTotal = sizeof(RILDRVNOTIFICATION) + cbBlob;
prdn = (RILDRVNOTIFICATION*)LocalAlloc(0, cbTotal);
if (!prdn)
{
goto Error;
}
// Fill in the structure fields
prdn->cbSize = cbTotal;
prdn->cbSizeNeeded = cbTotal;
prdn->dwCode = dwCode;
prdn->hrCmdID = hrCmdID;
if (cbBlob)
{
memcpy(prdn->pbData, pBlob, cbBlob);
}
// Try to queue the structure into the Notification Queue
// (NOTE: this will fail if the queue is already full -- this guarantees that this RIL thread can't
// be blocked by a hanging RIL client)
if (!m_notificationQ.Put(prdn))
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilInstanceHandle::Notify : Dropped RIL notification - out of memory? (0x%x)\r\n"), this));
goto Error;
}
#ifdef DEBUG
if (m_notificationQ.GetSize() > 10)
{
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : CRilInstanceHandle::Notify : Notify queue for handle 0x%x has size %d\r\n"), this, m_notificationQ.GetSize()));
}
#endif
// The queue took ownership of the notification data
//prdn = NULL;
return;
Error:
// NOTE: Since we allocated this structure using LocalAlloc(), we need to use LocalFree() to delete it
// (or else the memory tracker will assert)
LocalFree(prdn);
}
//
// Function passed to CQueue::ConditionalGet() below
//
BOOL FEnoughStorage(void* pItem, DWORD dwData)
{
FUNCTION_TRACE(FEnoughStorage);
DEBUGCHK(NULL != pItem);
RILDRVNOTIFICATION* prdnNextNotification = (RILDRVNOTIFICATION*)pItem;
RILDRVNOTIFICATION* prdnSuppliedStruct = (RILDRVNOTIFICATION*)dwData;
prdnSuppliedStruct->cbSizeNeeded = prdnNextNotification->cbSizeNeeded;
return (prdnSuppliedStruct->cbSize >= prdnSuppliedStruct->cbSizeNeeded);
}
//
//
//
BOOL CRilInstanceHandle::GetNextNotification(RILDRVNOTIFICATION& rrdnSuppliedStruct)
{
FUNCTION_TRACE(CRilInstanceHandle::GetNextNotification);
DEBUGCHK(FALSE != m_fInited);
RILDRVNOTIFICATION* prdnNextNotification = NULL;
UINT cbBlob;
HRESULT hr;
BOOL fRet = FALSE;
// Initialize cbSizeNeeded field
rrdnSuppliedStruct.cbSizeNeeded = rrdnSuppliedStruct.cbSize;
// Get the next notification from the queue, if the provided size is sufficient
hr = m_notificationQ.ConditionalGet(FEnoughStorage, (DWORD)&rrdnSuppliedStruct, &prdnNextNotification);
if (E_FAIL == hr)
{
// The supplied size wasn't enough - return TRUE
fRet = TRUE;
goto Error;
}
else if (S_FALSE == hr)
{
goto Error;
}
// We shouldn't have to worry about any error result other than E_FAIL.
DEBUGCHK(SUCCEEDED(hr));
// The supplied size is enough, so we retrieved the next notification
DEBUGCHK(NULL != prdnNextNotification);
DEBUGCHK(prdnNextNotification->cbSize == prdnNextNotification->cbSize
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -