📄 rilhand.cpp
字号:
hInstSimSec = LoadLibrary(TEXT("simsec.dll"));
if (!hInstSimSec)
{
goto Exit;
}
// Get the address of the simsec ui
typedef HRESULT (*SIMSECURITYUNLOCKPHONE) (HWND hwndMain, DWORD dwStyle);
SIMSECURITYUNLOCKPHONE pfnSIMSecurityUnlockPhone;
pfnSIMSecurityUnlockPhone = (SIMSECURITYUNLOCKPHONE)GetProcAddress(hInstSimSec, TEXT("SIMSecurityUnlockPhone"));
if (pfnSIMSecurityUnlockPhone)
{
// Put up the UI
#ifdef TPC
Result = pfnSIMSecurityUnlockPhone(NULL, SIMSEC_STYLE_CANNOT_CANCEL | SIMSEC_STYLE_EMERGENCY_CALL | SIMSEC_STYLE_BRANDED);
#else
Result = pfnSIMSecurityUnlockPhone(NULL, SIMSEC_STYLE_EMERGENCY_CALL);
#endif
}
else
{
#ifdef TPC
ASSERT(FALSE);
goto Exit;
#else
// backward compatibility for old simsecui, which doesn't have UnlockPhone, and instead uses CheckPin
typedef HRESULT (*SIMSECURITYCHECKPIN) (HWND hwndMain, SIMPIN_TYPE nPinType, DWORD dwStyle);
SIMSECURITYCHECKPIN pfnSIMSecurityCheckPin;
pfnSIMSecurityCheckPin = (SIMSECURITYCHECKPIN)GetProcAddress(hInstSimSec, TEXT("SIMSecurityCheckPin"));
if (pfnSIMSecurityCheckPin)
{
// Put up the UI
Result = pfnSIMSecurityCheckPin(NULL, (SIM_LOCKFACILITY_SIM == g_dwLockFacility) ? SIMPIN_SIM : SIMPIN_SIM2,
SIMSEC_STYLE_AUTO_CLOSE | SIMSEC_STYLE_EMERGENCY_CALL);
}
else
{
goto Exit;
}
#endif // !TPC
}
// Free the library
FreeLibrary(hInstSimSec);
Exit:
// Not prompting anymore
g_PromptingForSim=FALSE;
// Now safe to requeue the pending commands to try again
// Requeue any existing commands
// If the SIM was unlocked, they'll now succeed.
// Otherwise they'll fail as expected.
CCommand* pCmd;
while (g_pSimLockedQueue->Get(pCmd, 0)==S_OK)
{
if (!g_pCmdQ->Put(pCmd, INFINITE))
{
delete pCmd;
}
}
return 0;
}
//
//
//
BOOL PromptForSimAndRequeueCmd(CCommand* pCmd, DWORD dwLockFacility)
{
TBD_FUNCTION(PromptForSimAndRequeueCmd);
TBD_ASSERT(NULL != pCmd);
BOOL fRet=FALSE;
// Queue command up on SIM retry queue
if(pCmd->FDial())
{
// Not re-queuing dial commands
// Leave fRet FALSE to indicate that the existing response should be used
}
else
{
pCmd->ClrCmdOpt(CMDOPT_RETRYONSIMLOCKED);
fRet = g_pSimLockedQueue->Put(pCmd, 0);
if (!fRet)
{
TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("PromptForSimAndRequeueCmd : Unable to queue cmd"));
goto Exit;
}
}
// Is another dialog already up?
// Note: don't need to worry about
if (!g_PromptingForSim)
{
HANDLE hThread;
// Remember to save nPinType;
g_dwLockFacility=dwLockFacility;
hThread = CreateThread(NULL, 0, PromptForSimAndRequeueCmdProc, (LPVOID)NULL, 0, NULL);
if (!hThread)
{
// Eek, we can't create a thread!
if(pCmd->FDial())
{
// Dial commands were not put on the queue, so we don't need to remove them now
}
else
{
// By definition, our command must be the only one in the queue. Just get it back out.
// When we return fRet==FALSE, the calling code will fail the response to the app.
CCommand *pCmdTmp;
g_pSimLockedQueue->Get(pCmdTmp, 0);
TBD_ASSERT(pCmd == pCmdTmp);
}
TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("PromptForSimAndRequeueCmd : Unable to CreateThread(PromptForSimAndRequeueCmdProc)"));
goto Exit;
}
else
{
CloseHandle(hThread); // close handle we don't need
}
g_PromptingForSim=TRUE;
}
if(!pCmd->FDial())
{
// See comment above about leaving fRet FALSE for dial commands
fRet=TRUE;
}
Exit:
return fRet;
}
//
// Handle response to an AT command
//
BOOL CRilHandle::HandleRsp(CCommand*& rpCmd, CResponse*& rpRsp, BOOL& rfHungUp, BOOL& rfRadioOff)
{
// TBD_FUNCTION(CRilHandle::HandleRsp);
TBD_ASSERT(rpCmd != NULL);
TBD_ASSERT(rpRsp != NULL);
void* pBlob = NULL;
UINT cbBlob = 0;
HRESULT hrError;
CNotificationData* pnd = NULL;
BOOL fRet = FALSE;
rfHungUp = FALSE;
// Handle logging of OK and ERROR responses
if (NULL == rpCmd->GetParseFunc() && !rpCmd->FNoOp())
{
DWORD dwZone = rpCmd->CmdOptIsSet(CMDOPT_POLLING) ?
RILLOG_ZONE_CMD_POLLING : RILLOG_ZONE_CMD;
if (RIL_RESULT_OK == rpRsp->GetNotifyCode())
{
g_RilLog.LogEvent(dwZone, RILLOG_EVENT_CMDRSPOK);
}
else if (E_FAIL == rpRsp->GetError())
{
g_RilLog.LogEvent(dwZone, RILLOG_EVENT_CMDRSPERROR);
}
}
// Is this the last modem init command? If so, and if it succeeded, then we're done with initialization
if (rpCmd->FFinalInit())
{
FinishInit(rpCmd,(RIL_RESULT_OK == rpRsp->GetNotifyCode()));
}
if ((rpCmd->CmdOptIsSet(CMDOPT_UNLOCKING)) && (RIL_RESULT_OK == rpRsp->GetNotifyCode()))
{
// Well, looks like we successfully unlocked the phone
TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, TEXT("The phone is now unlocked"));
SendReadyStateNotification(RIL_READYSTATE_UNLOCKED, TRUE);
}
if ((rpCmd->CmdOptIsSet(CMDOPT_RETRYONSIMLOCKED)) && (rpRsp->GetNotifyCode()==RIL_RESULT_ERROR))
{
BOOL bPrompt=FALSE;
void* pBlobSim = NULL;
UINT cbBlobSim = 0;
rpRsp->GetBlob(pBlobSim, cbBlobSim);
ASSERT(cbBlobSim==sizeof(DWORD));
DWORD dwLockFacility;
switch(*(DWORD*)pBlobSim)
{
case RIL_E_PHSIMPINREQUIRED:
case RIL_E_PHFSIMPINREQUIRED:
case RIL_E_PHFSIMPUKREQUIRED:
case RIL_E_SIMPINREQUIRED:
case RIL_E_SIMPUKREQUIRED:
case RIL_E_SIMNOTINSERTED:
case RIL_E_SIMFAILURE:
dwLockFacility=SIM_LOCKFACILITY_SIM;
bPrompt=TRUE;
break;
case RIL_E_SIMPIN2REQUIRED:
case RIL_E_SIMPUK2REQUIRED:
dwLockFacility=SIM_LOCKFACILITY_SIM_PIN2;
bPrompt=TRUE;
}
if (bPrompt)
{
if (PromptForSimAndRequeueCmd(rpCmd,dwLockFacility))
{
delete pnd;
delete rpRsp;
rpCmd = NULL;
rpRsp = NULL;
return TRUE;
}
}
}
#if 0
// This code isn't really used anymore, since the inside of the SendRILCmdHandleRsp function also does something similar
// for timed out commands
// If this was an init command and it failed, try again up to some limit
if (rpCmd->FInit())
{
if (RIL_RESULT_OK != rpRsp->GetNotifyCode())
{
if (rpCmd->OkToRetry())
{
if (!RequeueCmdWithDelay(rpCmd, 5000))
{
goto Error;
}
}
}
}
#endif
// If we need to re-init the modem after this command and the command was sucessful, do it
if (rpCmd->FReinit() && RIL_RESULT_OK == rpRsp->GetNotifyCode())
{
PrepareForReinit();
if (!SendComInitString(COM_REINIT_INDEX))
{
// We failed sending the init strings -- RIL is not initialized
goto Error;
}
}
if (rpCmd->FHangup())
{
// If this is a hangup command and we got a NO CARRIER response, turn it into OK
if (RIL_RESULT_NOCARRIER == rpRsp->GetNotifyCode())
{
rpRsp->NoCarrierToOK();
}
// If hangup was successful, let the caller know
if (RIL_RESULT_OK == rpRsp->GetNotifyCode())
{
rfHungUp = TRUE;
}
}
if (rpCmd->FRequireConnectRsp())
{
// ??? Do we want to set rfHungUp for all commands with NO CARRIER response?
if (RIL_RESULT_NOCARRIER == rpRsp->GetNotifyCode())
{
rfHungUp = TRUE;
}
#ifdef WAVECOM_DRIVER
else if (RIL_RESULT_ERROR == rpRsp->GetNotifyCode() &&
RIL_E_OPNOTALLOWED == rpRsp->GetError())
{
rfHungUp = TRUE;
}
#endif
}
// If we're not supposed to ignore the response and the command succeeded,
// then we should parse the response data now (so that it can be used by the notification
// code below)
if (!rpCmd->FIgnoreRsp() && RIL_RESULT_OK == rpRsp->GetNotifyCode())
{
(void)rpRsp->ParseOKData(rpCmd);
}
if (rpCmd->CmdOptIsSet(CMDOPT_SIMQUERY))
{
// We were just checking to see if the SIM is ready or not. We only care about if the return
// value is NOT READY or not in this case
hrError = rpRsp->GetError();
m_fSimReady = (hrError != RIL_E_NOTREADY);
if (m_fSimReady)
{
// Hey, as long as we got the PIN state, let's see if it's
// locked or not. Why not?
DWORD dwReadyState = RIL_READYSTATE_SIM;
void *pBlobSim = NULL;
UINT cbBlobSim = 0;
if (RIL_RESULT_OK == rpRsp->GetNotifyCode())
{
rpRsp->GetBlob(pBlobSim, cbBlobSim);
TBD_ASSERT(cbBlobSim == sizeof(DWORD));
if ((*(DWORD *) pBlobSim) == RIL_LOCKEDSTATE_READY)
{
TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, TEXT("The phone was unlocked from boot"));
dwReadyState |= RIL_READYSTATE_UNLOCKED;
}
}
SendReadyStateNotification(dwReadyState, TRUE);
}
// Wake up the waiting thread
SetEvent(m_hSimReadyEvent);
fRet = TRUE;
goto Error;
}
// If we got a CONNECT response, it must be a response to successful ATD or ATA -- change it to OK
if (RIL_NOTIFY_CONNECT == rpRsp->GetNotifyCode())
{
rpRsp->ConnectToOK();
// Some networks seem to require a brief delay after a data connection is made
// before data can be sent via the connection. We pause here before sending the
// connect response to the client. The delay is configured using a registry value.
// If the value is not present, then there is no delay.
DWORD dwTemp = 0;
if (rpCmd->CmdOptIsSet(CMDOPT_DELAYCONNECTRSP) &&
GetRegistryDWORD(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("ConnectResponseDelay"), &dwTemp))
{
Sleep(dwTemp);
}
}
else
{
// For non-CONNECT responses, if we have a notification to send upon success, do it now
pnd = rpCmd->GiveUpNotificationData();
if (pnd)
{
if (RIL_RESULT_OK == rpRsp->GetNotifyCode() &&
(!pnd->FDelayedInitFromRsp() || pnd->FinishInitFromRspBlob(*rpRsp)))
{
BroadcastNotification(pnd);
TBD_ASSERT(NULL == pnd);
}
else
{
delete pnd;
pnd = NULL;
}
}
}
// If we got an RIL_E_SIMNOTINSERTED or RIL_E_SIMFAILURE error, send out a "SIM isn't accessible" notification
hrError = rpRsp->GetError();
if (RIL_E_SIMNOTINSERTED == hrError || RIL_E_SIMFAILURE == hrError)
{
(void)BroadcastRealBlobNotification(RIL_NOTIFY_SIMNOTACCESSIBLE, NULL, 0);
}
if (RILERRORCLASS(hrError) == RIL_ERRORCLASS_SIM)
{
UpdateSIMState(hrError);
}
// Forward the response we got to the handle that sent the command
rpRsp->GetBlob(pBlob, cbBlob);
// If we just queried the equipment state, then make
// sure the global on/off state is set appropriately.
if (APIID_GETEQUIPMENTSTATE == rpCmd->GetAPIID() &&
RIL_RESULT_OK == rpRsp->GetNotifyCode())
{
RILEQUIPMENTSTATE * pres;
if (NULL != pBlob)
{
ASSERT(sizeof(RILEQUIPMENTSTATE) == cbBlob);
// Take a peek at the response data
pres = (RILEQUIPMENTSTATE *)pBlob;
if (RIL_RADIOSUPPORT_OFF == pres->dwRadioSupport)
rfRadioOff = TRUE;
else if (RIL_RADIOSUPPORT_ON == pres->dwRadioSupport)
rfRadioOff = FALSE;
}
}
rpCmd->SendResponse(rpRsp->GetNotifyCode(), pBlob, cbBlob);
rpRsp->DeleteBlob();
pBlob = NULL;
cbBlob = 0;
fRet = TRUE;
Error:
delete pnd;
delete rpCmd;
delete rpRsp;
rpCmd = NULL;
rpRsp = NULL;
return fRet;
}
//
//
//
BOOL CRilHandle::AppendReadBytes(LPCSTR szBytes, UINT cbBytes)
{
// TBD_FUNCTION(CRilHandle::AppendReadBytes);
BOOL fRet = FALSE;
if (!m_pReadBytes)
{
// No buffer yet -- need to allocate it
m_pReadBytes = new CBuffer;
if (!m_pReadBytes)
{
goto Error;
}
}
fRet = m_pReadBytes->Append(szBytes, cbBytes);
Error:
if (!fRet)
{
// Critically low on memory
SignalCriticalError(RILLOG_EVENT_LOWMEMORY);
}
return fRet;
}
//
//
//
BOOL CRilHandle::InheritReadBytes(CResponse* const pRsp)
{
// TBD_FUNCTION(CRilHandle::InheritReadBytes);
BOOL fRet = FALSE;
if (!m_pReadBytes)
{
// No buffer yet -- need to allocate it
m_pReadBytes = new CBuffer;
if (!m_pReadBytes)
{
goto Error;
}
}
m_pReadBytes->InheritData(pRsp);
fRet = TRUE;
Error:
return fRet;
}
//
//
//
BOOL CRilHandle::GiveUpReadBytes(LPSTR& rszBytes, UINT& rcbBytes)
{
// TBD_FUNCTION(CRilHandle::GiveUpReadBytes);
BOOL fRet = FALSE;
if (!m_pReadBytes)
{
// No buffer yet, i.e. no bytes to return
goto Error;
}
rcbBytes = m_pReadBytes->GetLength();
rszBytes = m_pReadBytes->GiveUpData();
fRet = TRUE;
Error:
return fRet;
}
//
//
//
BOOL CRilHandle::SetEmergencyMode(const BOOL fMode)
{
// TBD_FUNCTION(CRilHandle::SetEmergencyMode);
SYNCBLOCK(m_csEmergency);
DWORD dwNotificationCode;
BOOL fRet = FALSE;
if (m_fEmergencyMode && fMode)
{
// If we're trying to enter the emergency mode while already in emergency mode, fail
goto Error;
}
TBD_ASSERT(FALSE == m_fEmergencyMode || FALSE == fMode);
TBD_ASSERT(FALSE != m_fEmergencyMode || FALSE != fMode);
// Set the new mode
m_fEmergencyMode = fMode;
if (m_fEmergencyMode)
{
// We just entered emergency mode
TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, TEXT("CRilHandle::SetEmergencyMode : Entering emergency mode"));
// Clear the command queue, sending out "cancelled" responses to response callbacks
g_pCmdQ->Enum(GenerateCancelledRsp, (DWORD)this, TRUE);
dwNotificationCode = RIL_NOTIFY_EMERGENCYMODEENTERED;
}
else
{
// We just exited emergency mode
TBD_OUTPUT(TBDCT_INFO, TBDOL_INFORMATION, TEXT("CRilHandle::SetEmergencyMode : Exiting emergency mode"));
dwNotificationCode = RIL_NOTIFY_EMERGENCYMODEEXITED;
}
// Send out an appropriate notification
(void)BroadcastRealBlobNotification(dwNotificationCode, NULL, 0);
fRet = TRUE;
Error:
return fRet;
}
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -