📄 rilhand.cpp
字号:
// Create the instance handle list
m_pInstances = new CDblList<CRilInstanceHandle>;
if (!m_pInstances)
{
goto Error;
}
#ifdef BSP_MAINSTONE
// does the USER WANT RIL loaded
BOOL bSuccess;
v_pBCRRegs =(volatile XLLP_BCR_T *) VirtualAlloc( 0, sizeof(XLLP_BCR_T), MEM_RESERVE, PAGE_NOACCESS);
if (v_pBCRRegs)
{
bSuccess = VirtualCopy( (PVOID)v_pBCRRegs,
(PVOID)FPGA_REGS_BASE_U_VIRTUAL,
sizeof(XLLP_BCR_T),
PAGE_READWRITE | PAGE_NOCACHE
);
if (!bSuccess)
{
VirtualFree((PVOID)v_pBCRRegs, 0, MEM_RELEASE);
v_pBCRRegs=NULL;
TBD_ASSERT(NULL);
goto Error;
}
}
// Note: Bit set if no-dot position
if (v_pBCRRegs->GPSR & BCR_GPSWR_SW10_MSK)
{
//if switch 10 is no dot position then load ril
VirtualFree((PVOID)v_pBCRRegs, 0, MEM_RELEASE);
}
else
{
// if switch 10 is in dot then don't load RIL
TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("Mainstone SW10 in Dot position--not loading RIL"));
VirtualFree((PVOID)v_pBCRRegs, 0, MEM_RELEASE);
goto Error;
}
#endif
// Open the serial port
m_pComDevice = COM_OpenInternal();
if (!m_pComDevice)
{
TBD_OUTPUT(TBDCT_INFO, TBDOL_TRACE, TEXT("CRilHandle::StartInit : Couldn't open VSP"));
goto Error;
}
TBD_OUTPUT(TBDCT_INFO, TBDOL_TRACE, TEXT("CRilHandle::StartInit : VSP is opened successfully"));
// Initialize the serial port
if (!m_pComDevice->InitComPortForRIL(NULL, NULL))
{
goto Error;
}
// Launch the auxiliary threads
if (!LaunchThreads())
{
goto Error;
}
#if defined(NO_INIT_ON_BOOT)
GeneralInitDone(TRUE);
#else
// Send the first init string to the COM port
if (!SendComInitString(COM_INIT_INDEX))
{
goto Error;
}
#endif
fRet = TRUE;
Error:
if (!fRet)
{
if (m_pComDevice)
{
COM_CloseInternal(m_pComDevice);
m_pComDevice = NULL;
}
if (m_hInitEvent)
{
(void)CloseHandle(m_hInitEvent);
m_hInitEvent = NULL;
}
if (m_hDataEvent)
{
(void)CloseHandle(m_hDataEvent);
m_hDataEvent = NULL;
}
}
return fRet;
}
void CRilHandle::GeneralInitDone(BOOL bSucceeded)
{
if (m_fInited)
{
TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("CRilHandle::FinishInit : Trying to reinit? Module reset itself?!, rebooting via CPM"));
SignalCriticalError(RILLOG_EVENT_GENERALREINIT);
}
if (bSucceeded)
{
m_fInited = TRUE;
}
else
{
TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("CRilHandle::FinishInit : Module failed initialization!"));
m_fFailedInit = TRUE;
}
(void)SetEvent(m_hInitEvent);
// Now we need to send a notification that we've intiailized properly
SendReadyStateNotification(RIL_READYSTATE_INITIALIZED, TRUE);
}
//
// Finish intialization
//
void CRilHandle::FinishInit(CCommand* pInitCmd, BOOL bSucceeded)
{
// TBD_FUNCTION(CRilHandle::FinishInit);
TBD_ASSERT(NULL != pInitCmd);
if (pInitCmd->FGeneralInit())
{
GeneralInitDone(bSucceeded);
}
if (pInitCmd->FSMSInit())
{
if (m_fInitedForSMS)
{
TBD_OUTPUT(TBDCT_INFO, TBDOL_ERROR, TEXT("CRilHandle::FinishInit : Trying to reinit SMS? Module reset itself?!, rebooting via CPM"));
SignalCriticalError(RILLOG_EVENT_SMSREINIT);
}
if (bSucceeded)
{
m_fInitedForSMS = TRUE;
}
}
}
//
// Function passed to CQueue::Enum() below
//
BOOL GenerateCancelledRsp(void* pItem, DWORD dwData)
{
TBD_FUNCTION(GenerateCancelledRsp);
TBD_ASSERT(pItem != NULL);
TBD_ASSERT(dwData != NULL);
CCommand* pCmd = (CCommand*)pItem;
CRilHandle* pRilDevice = (CRilHandle*)dwData;
HRESULT dwError = RIL_E_CANCELLED;
// Send out cancelled response as a notification
pCmd->SendResponse(RIL_RESULT_ERROR, &dwError, sizeof(HRESULT));
// Continue enumeration
return FALSE;
}
//
//
//
void CRilHandle::PrepareForReinit()
{
// TBD_FUNCTION(CRilHandle::PrepareForReinit);
(void)ResetEvent(m_hInitEvent);
m_fInited = FALSE;
m_fFailedInit = FALSE;
m_fInitedForSMS = FALSE;
// Reset g_dwReadyState
SendReadyStateNotification(RIL_READYSTATE_NONE, FALSE);
// Clear the command queue, sending out "cancelled" responses to response callbacks
// NOTE: The following line has been commented out to prevent commands
// from being cancelled on start up when the shell turns the radio on.
//g_pCmdQ->Enum(GenerateCancelledRsp, (DWORD)this, TRUE);
}
//
// Launch auxiliary threads
//
BOOL CRilHandle::LaunchThreads()
{
// TBD_FUNCTION(CRilHandle::LaunchThreads);
BOOL fRet = FALSE;
// Create a cancel event
m_hCancelEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!m_hCancelEvent)
{
goto Error;
}
// Create command and response queues
g_pCmdQ = new CPriorityQueue<CCommand, 40>;
if (!g_pCmdQ || !g_pCmdQ->Init(m_hCancelEvent))
{
goto Error;
}
g_pRspQ = new CQueue<CResponse, 10>;
if (!g_pRspQ || !g_pRspQ->Init(m_hCancelEvent))
{
goto Error;
}
g_pSimLockedQueue = new CQueue<CCommand, 10>;
if (!g_pSimLockedQueue || !g_pSimLockedQueue->Init(m_hCancelEvent))
{
goto Error;
}
// Create a thread checkpoint
m_pCheckPoint = new CCheckPoint;
if (!m_pCheckPoint || !m_pCheckPoint->Init(2))
{
goto Error;
}
// Launch a auxiliary threads
m_hCmdThread = CreateThread(NULL, 0, CmdThreadProc, (LPVOID)this, 0, &m_dwCmdThreadID);
if (!m_hCmdThread)
{
goto Error;
}
m_hReadThread = CreateThread(NULL, 0, ReadThreadProc, (LPVOID)this, 0, &m_dwReadThreadID);
if (!m_hReadThread)
{
goto Error;
}
// Wait until all threads reach the checkpoint
if (!m_pCheckPoint->Wait(10000))
{
goto Error;
}
TBD_OUTPUT(TBDCT_INFO, TBDOL_TRACE, TEXT("CRilHandle::LaunchThreads : Launched threads reached ckeckpoint"));
fRet = TRUE;
Error:
if (!fRet)
{
if (m_hCmdThread)
{
(void)CloseHandle(m_hCmdThread);
m_hCmdThread = NULL;
m_dwCmdThreadID = 0;
}
if (m_hReadThread)
{
(void)CloseHandle(m_hReadThread);
m_hReadThread = NULL;
m_dwReadThreadID = 0;
}
delete m_pCheckPoint;
m_pCheckPoint = NULL;
delete g_pCmdQ;
delete g_pRspQ;
delete g_pSimLockedQueue;
g_pCmdQ = NULL;
g_pRspQ = NULL;
g_pSimLockedQueue = NULL;
if (m_hCancelEvent)
{
(void)CloseHandle(m_hCancelEvent);
m_hCancelEvent = NULL;
}
}
return fRet;
}
//
// Test the cancel event
//
BOOL CRilHandle::FCancelSet() const
{
// // TBD_FUNCTION(CRilHandle::FCancelSet);
return (WAIT_OBJECT_0 == WaitForSingleObject(m_hCancelEvent, 0));
}
//
//
//
BOOL CRilHandle::WaitForInit(DWORD dwTimeout) const
{
// TBD_FUNCTION(CRilHandle::WaitForInit);
HANDLE rghEvents[] = { m_hInitEvent, m_hCancelEvent };
switch (WaitForMultipleObjects(2, rghEvents, FALSE, dwTimeout))
{
case WAIT_OBJECT_0:
case WAIT_OBJECT_0 + 1:
return TRUE;
default:
return FALSE;
}
}
//
// Returns true if there is a command on the command queue that can
// be executed now.
// Returns false if the command thread should quit.
//
BOOL CRilHandle::WaitForCommandOrCancel() const
{
BOOL fRet = FALSE;
CCommand* pCmd = NULL;
HANDLE rghEvents[] = { g_pCmdQ->GetPutEvent(), m_hCancelEvent, m_hInitEvent };
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hInitEvent, 0))
{
// If the init event is signaled now, then it doesn't
// matter what the next command is. Set return to true.
// The subsequent call to Get will block if the queue
// happens to be empty.
fRet = TRUE;
}
while (!fRet)
{
// Look for a command on the queue.
if (g_pCmdQ->Peek(pCmd))
{
if (pCmd->FInit())
{
// The next command is for init. Send it.
fRet = TRUE;
break;
}
}
switch (WaitForMultipleObjects(3, rghEvents, FALSE, INFINITE))
{
case WAIT_OBJECT_0:
// Put signaled. Loop to see if it is an init command.
break;
case WAIT_OBJECT_0 + 1:
// Cancel signaled, so return FALSE now.
return FALSE;
case WAIT_OBJECT_0 + 2:
// Init command signaled, so ok to send next command.
fRet = TRUE;
break;
default:
return FALSE;
}
}
TBD_ASSERT(TRUE == fRet);
// Check the cancel event before returning
// in case some other event (like init)
// preempted this event.
return (!FCancelSet());
}
//
//
//
BOOL CRilHandle::AddToList(CRilInstanceHandle* const pInstance)
{
// TBD_FUNCTION(CRilHandle::AddToList);
return m_pInstances->Add(pInstance);
}
//
//
//
BOOL CRilHandle::RemoveFromList(CRilInstanceHandle* const pInstance)
{
// TBD_FUNCTION(CRilHandle::RemoveFromList);
return m_pInstances->Remove(pInstance);
}
//
//
//
HRESULT CRilHandle::GetNextCmdID()
{
// TBD_FUNCTION(CRilHandle::GetNextCmdID);
SYNCBLOCK(m_csCmdID);
// Make sure not to wrap into error values
if (FAILED(m_hrNextCmdID))
{
m_hrNextCmdID = INITIAL_COMMAND_ID;
}
return m_hrNextCmdID++;
}
//
// Function passed to CDlbList::Enum() below
//
BOOL NotifyHandle(void* pItem, DWORD dwData)
{
TBD_FUNCTION(NotifyHandle);
TBD_ASSERT(pItem != NULL);
TBD_ASSERT(dwData != NULL);
CRilInstanceHandle* pHandle = (CRilInstanceHandle*)pItem;
CNotificationData* pnd = (CNotificationData*)dwData;
if (pHandle->FReadyForNotifications())
{
pHandle->Notify(pnd->GetCode(), S_OK, pnd->GetBlob(), pnd->GetSize());
}
// Continue enumeration
return FALSE;
}
//
// Broadcast a notification to all clients
//
void CRilHandle::BroadcastNotification(CNotificationData*& rpnd)
{
// TBD_FUNCTION(CRilHandle::BroadcastNotification);
TBD_ASSERT(NULL != m_pInstances);
TBD_ASSERT(NULL != rpnd);
TBD_OUTPUT(TBDCT_INFO, TBDOL_TRACE, TEXT("CRilHandle::BroadcastNotification : Broadcasting notification 0x%x"), rpnd->GetCode());
// Notify all RIL proxy instances
m_pInstances->Enum(NotifyHandle, (DWORD)rpnd);
// Get rid of the notififcation
delete rpnd;
rpnd = NULL;
}
//
//
//
BOOL CRilHandle::BroadcastRealBlobNotification(const DWORD dwNotificationCode, const void* const pBlob,
const UINT cbBlob)
{
// TBD_FUNCTION(CRilHandle::BroadcastRealBlobNotification);
CNotificationData* pnd = NULL;
BOOL fRet = FALSE;
pnd = new CNotificationData;
if (!pnd || !pnd->InitFromRealBlob(dwNotificationCode, pBlob, cbBlob))
{
goto Error;
}
BroadcastNotification(pnd);
TBD_ASSERT(NULL == pnd);
fRet = TRUE;
Error:
delete pnd;
return fRet;
}
//
//
//
BOOL CRilHandle::BroadcastDWORDBlobNotification(const DWORD dwNotificationCode, const DWORD dwBlob)
{
// TBD_FUNCTION(CRilHandle::BroadcastDWORDBlobNotification);
CNotificationData* pnd = NULL;
BOOL fRet = FALSE;
pnd = new CNotificationData;
if (!pnd || !pnd->InitFromDWORDBlob(dwNotificationCode, dwBlob))
{
goto Error;
}
BroadcastNotification(pnd);
TBD_ASSERT(NULL == pnd);
fRet = TRUE;
Error:
delete pnd;
return fRet;
}
//
//
//
DWORD WINAPI PromptForSimAndRequeueCmdProc(LPVOID lpParameter)
{
TBD_FUNCTION(PromptForSimAndRequeueCmdProc);
HRESULT Result;
HINSTANCE hInstSimSec;
// Load the simsec library
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -