📄 rilhandndisoem1.cpp
字号:
if ( 0 == m_pNdisChannels[IndexCount].ContextID )
{
Result = S_OK;
*Index = IndexCount;
break;
}
}
LeaveCriticalSection(&m_ConnectionList);
return Result;
}
void
CRilNDIS::NdisRemoveNdisEntry ( DWORD ContextID )
{
EnterCriticalSection(&m_ConnectionList);
for(DWORD i=0;i<m_NumNdisChannels;i++)
{
if ( ContextID && (m_pNdisChannels[i].ContextID == ContextID) )
{
if ( m_pNdisChannels[i].pCPdpContext )
{
delete (CPdpContext*)m_pNdisChannels[i].pCPdpContext;
}
m_NdisAsyncCommandList.RemoveAllCommands( ContextID );
memset( &m_pNdisChannels[i], 0, sizeof(OEMNDISCHANNELS));
break;
}
}
LeaveCriticalSection(&m_ConnectionList);
}
void
CRilNDIS::NdisAddNdisEntry ( DWORD ContextID, DWORD Index, PVOID pCRilInstance, PVOID pCPdpContext, const RILNDISGPRSCONTEXT *lpRilNdisGprsContext )
{
DEBUGMSG( ZONE_NDIS, (TEXT("RILNDIS: NdisAddNdisEntry cid = %x, index = %x, pCrilInstance = %x pCPdpContext = %x \r\n"), ContextID, Index, pCRilInstance, pCPdpContext));
EnterCriticalSection(&m_ConnectionList);
ASSERT((Index >= 0) && (Index < m_NumNdisChannels));
if ( pCRilInstance )
{
m_pNdisChannels[Index].ContextID= ContextID;
m_pNdisChannels[Index].pCRilInstance = pCRilInstance;
m_pNdisChannels[Index].pCPdpContext = pCPdpContext;
CeSafeCopyMemory(&m_pNdisChannels[Index].OemNdisOpenRequest, lpRilNdisGprsContext, sizeof(m_pNdisChannels[Index].OemNdisOpenRequest));
DumpNdisChannelEntry(&m_pNdisChannels[Index]);
}
LeaveCriticalSection(&m_ConnectionList);
}
PVOID
CRilNDIS::NdisPdpContextFromCid( DWORD ContextID )
{
PVOID pReturn = NULL;
EnterCriticalSection(&m_ConnectionList);
for(DWORD i=0;i<m_NumNdisChannels;i++)
{
if ( ContextID && (m_pNdisChannels[i].ContextID== ContextID) )
{
pReturn = m_pNdisChannels[i].pCPdpContext;
break;
}
}
LeaveCriticalSection(&m_ConnectionList);
return pReturn;
}
// **************************************************************************
// Function Name: NdisRilInstanceFromHandle
//
// Purpose: Search of the NDIS channel handle associated with a cid.
//
// Arguments: IN cid, OUT hNdisHandle
//
// Return Values: E_FAIL if not found.
//
// Side effects:
//
// Description:
// **************************************************************************
VOID* CRilNDIS::NdisRilInstanceFromCID( DWORD ContextID )
{
PVOID pReturn = NULL;
EnterCriticalSection(&m_ConnectionList);
for(DWORD i=0;i<m_NumNdisChannels;i++)
{
if ( ContextID && (m_pNdisChannels[i].ContextID == ContextID) )
{
pReturn = m_pNdisChannels[i].pCRilInstance;
break;
}
}
LeaveCriticalSection(&m_ConnectionList);
return pReturn;
}
// **************************************************************************
// Function Name: NdisRilCallbackFromCID
//
// Purpose: Search of the NDIS channel handle associated with a cid.
//
// Arguments: IN cid, OUT hNdisHandle
//
// Return Values: E_FAIL if not found.
//
// Side effects:
//
// Description:
// **************************************************************************
void CRilNDIS::NdisRilCallbacksFromCID( DWORD ContextID, PVOID *pCallbackContext, RILNDISRECEIVECALLBACK *pfnRilReceiveCallback, RILNDISTRANSMITCALLBACK *pfnRilTransmitCallback, RILNDISSTATUSCALLBACK *pfnRilStatusCallback)
{
EnterCriticalSection(&m_ConnectionList);
*pfnRilReceiveCallback = NULL;
*pfnRilTransmitCallback = NULL;
*pfnRilStatusCallback = NULL;
*pCallbackContext = NULL;
for(DWORD i=0;i<m_NumNdisChannels;i++)
{
if ( ContextID && (m_pNdisChannels[i].ContextID == ContextID) )
{
*pfnRilReceiveCallback = m_pNdisChannels[i].OemNdisOpenRequest.pfnNdisReceive;
*pfnRilTransmitCallback = m_pNdisChannels[i].OemNdisOpenRequest.pfnNdisTransmit;
*pfnRilStatusCallback = m_pNdisChannels[i].OemNdisOpenRequest.pfnNdisStatus;
*pCallbackContext = m_pNdisChannels[i].OemNdisOpenRequest.pCallbackContext;
break;
}
}
LeaveCriticalSection(&m_ConnectionList);
}
// **************************************************************************
// Function Name: NdisRemoveCallbacks
//
// Purpose:
//
// Arguments:
//
// Return Values:
//
// Side effects:
//
// Description:
// **************************************************************************
void CRilNDIS::NdisRemoveCallbacks ( DWORD ContextID )
{
DEBUGMSG( ZONE_NDIS, (TEXT("RILNDIS: NdisRemoveCallbacks cid = %x \r\n"), ContextID));
EnterCriticalSection(&m_ConnectionList);
for(DWORD i=0;i<m_NumNdisChannels;i++)
{
if ( ContextID && (m_pNdisChannels[i].ContextID == ContextID) )
{
m_pNdisChannels[i].OemNdisOpenRequest.pCallbackContext = NULL;
m_pNdisChannels[i].OemNdisOpenRequest.pfnNdisReceive = NULL;
m_pNdisChannels[i].OemNdisOpenRequest.pfnNdisStatus = NULL;
m_pNdisChannels[i].OemNdisOpenRequest.pfnNdisTransmit = NULL;
break;
}
}
LeaveCriticalSection(&m_ConnectionList);
}
// **************************************************************************
// Function Name: NdisCloseAllConnections
//
// Purpose: Close all NDIS connections
//
// Arguments:
//
// Return Values:
//
// Side effects:
//
// Description:
// **************************************************************************
void CRilNDIS::NdisCloseAllConnections ( void )
{
EnterCriticalSection(&m_ConnectionList);
for(DWORD i=0;i<m_NumNdisChannels;i++)
{
if ( m_pNdisChannels[i].ContextID)
{
RemoveAndSignalAllPdpContextEntries(m_pNdisChannels[i].ContextID);
NdisShutdownConnection(m_pNdisChannels[i].ContextID);
}
}
LeaveCriticalSection(&m_ConnectionList);
}
// **************************************************************************
// Function Name: NdisShutdownConnection
//
// Purpose: Shutdown and NDIS connection and cleanup related items.
//
// Arguments: IN handle to channel to close.
//
// Return Values:
//
// Side effects:
//
// Description:
// **************************************************************************
void CRilNDIS:: NdisShutdownConnection ( DWORD ContextID )
{
if ( ContextID )
{
// Notify it's down
RILGPRSCONTEXTACTIVATED RilGprsContexActivated;
RilGprsContexActivated.cbSize = sizeof(RILGPRSCONTEXTACTIVATED);
RilGprsContexActivated.fActivated = FALSE;
RilGprsContexActivated.dwContextID = ContextID;
RilGprsContexActivated.dwEvent = RIL_RILGPRSCONTEXTACTIVATED_MEDEACT;
((CRilHandle*)m_pCRilHandle)->BroadcastRealBlobNotification(RIL_NOTIFY_GPRSCONNECTIONSTATUS, &RilGprsContexActivated, sizeof(RILGPRSCONTEXTACTIVATED));
// Remove the entry from our list of Ndis handles/Cids
NdisRemoveNdisEntry(ContextID);
}
}
// **************************************************************************
// Function Name: NdisNotifyThread
//
// Purpose: Thread running to process NDIS events.
//
// Arguments:
//
// Return Values:
//
// Side effects:
//
// Description:
// **************************************************************************
DWORD CRilNDIS:: NdisNotifyThread(void)
{
DWORD Triggered, Index;
OEMNDISAPIREFERENCE OemNdisApiReference;
OEMNDISEVENT OemNdisEvent;
CRilInstanceHandle *pCRilInstance = NULL;
HANDLE NdisThreadEvents[MAX_OEMNDIS_EVENTS];
MSGQUEUEOPTIONS MsgQueueOptions;
DWORD RxQueueBytesRead;
DWORD RxQueueReadFlags;
RILNDISIPCONFIG RilNdisIpConfig;
HRESULT Result = E_FAIL;
OEMNDISINITIALIZE OemNdisInitialize;
OEMNDISINITIALIZEOUT OemNdisInitializeOut;
DWORD ResultDetails = 0;
CPdpContext *pCPdpContext = NULL;
RILGPRSCONTEXTACTIVATED RilGprsContexActivated;
RILNDISTRANSMITCALLBACK pfnRilTransmitCallback;
RILNDISSTATUSCALLBACK pfnRilStatusCallback;
RILNDISRECEIVECALLBACK pfnRilReceiveCallback;
PVOID pCallbackContext;
RILNDISSTATUS RilNdisStatus;
DWORD ContextIDIndex;
// Tell the main thread that we've reached the checkpoint
((CRilHandle*)m_pCRilHandle)->GetCheckPoint()->Reached();
/* Setup our Rx Message Queue */
MsgQueueOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
MsgQueueOptions.dwFlags = 0;
MsgQueueOptions.dwMaxMessages = 0;
MsgQueueOptions.cbMaxMessage = sizeof(OEMNDISEVENT);
MsgQueueOptions.bReadAccess = TRUE;
m_RxMsgQueue = CreateMsgQueue(NULL,&MsgQueueOptions);
ASSERT(m_RxMsgQueue);
if ( NULL == m_RxMsgQueue )
{
goto Exit;
}
/* Setup the handle to write to the Rx Message Queue */
MsgQueueOptions.bReadAccess = FALSE;
m_RxMsgQueueWrite = OpenMsgQueue(GetCurrentProcess(),m_RxMsgQueue, &MsgQueueOptions);
ASSERT ( m_RxMsgQueueWrite );
if ( NULL == m_RxMsgQueueWrite )
{
goto Exit;
}
/* Setup Rx Message Queue Done */
/* Setup our Tx Message Queue */
MsgQueueOptions.bReadAccess = FALSE;
m_TxMsgQueue = CreateMsgQueue(NULL,&MsgQueueOptions);
ASSERT(m_TxMsgQueue);
if ( NULL == m_TxMsgQueue )
{
goto Exit;
}
/* Setup the handle to read from the Tx Message Queue */
MsgQueueOptions.bReadAccess = TRUE;
m_TxMsgQueueRead = OpenMsgQueue(GetCurrentProcess(),m_TxMsgQueue, &MsgQueueOptions);
ASSERT(m_TxMsgQueueRead);
if ( NULL == m_TxMsgQueueRead )
{
goto Exit;
}
NdisThreadEvents[NDIS_STOP_THREAD_INDEX] = m_CancelEvent;
NdisThreadEvents[NDIS_RX_QUEUE_INDEX] = m_RxMsgQueue;
/* Set up the default NumContexts. In reality, if the call to initialize
fails, we can't do anything. Since the library does not exist yet,
we need to simply fall through. */
memset(&OemNdisInitializeOut, 0, sizeof(OemNdisInitializeOut));
OemNdisInitializeOut.Size = sizeof(OemNdisInitializeOut);
OemNdisInitializeOut.NumContexts = MAX_OEMNDIS_CHANNELS;
if ( g_pfnNdisInitialize )
{
// Reset the context count.
OemNdisInitializeOut.NumContexts = 0;
OemNdisInitialize.Size = sizeof(OemNdisInitialize);
OemNdisInitialize.RilRxMsgQueue = m_RxMsgQueueWrite;
OemNdisInitialize.RilTxMsgQueue = m_TxMsgQueueRead;
Result = g_pfnNdisInitialize ( &OemNdisInitialize, &OemNdisInitializeOut );
//ASSERT(SUCCEEDED(Result));
if ( FAILED(Result) )
{
goto Exit;
}
}
ASSERT( OemNdisInitializeOut.NumContexts < 10 );
if ( OemNdisInitializeOut.NumContexts > 10 )
{
goto Exit;
}
m_NumNdisChannels = OemNdisInitializeOut.NumContexts;
m_pNdisChannels = (POEMNDISCHANNELS) LocalAlloc ( LPTR, m_NumNdisChannels*sizeof(OEMNDISCHANNELS));
if ( NULL == m_pNdisChannels )
{
goto Exit;
}
memset(m_pNdisChannels, 0, m_NumNdisChannels * sizeof(OEMNDISCHANNELS));
for(DWORD DebugChannelIndex = 0; DebugChannelIndex < m_NumNdisChannels; DebugChannelIndex++ )
{
DumpNdisChannelEntry(&m_pNdisChannels[DebugChannelIndex]);
}
do
{
Triggered = WaitForMultipleObjects( MAX_OEMNDIS_EVENTS, NdisThreadEvents, FALSE, INFINITE );
Index = Triggered - WAIT_OBJECT_0;
if ( Index == NDIS_STOP_THREAD_INDEX )
{
NdisCloseAllConnections();
break;
}
// The notification is coming from the RADIO/Context Control
if( Index == NDIS_RX_QUEUE_INDEX )
{
while (ReadMsgQueue(
m_RxMsgQueue,
&OemNdisEvent,
sizeof(OemNdisEvent),
&RxQueueBytesRead,
1,
&RxQueueReadFlags))
{
if ( RxQueueBytesRead == sizeof(OemNdisEvent))
{
DEBUG_TYPE(OemNdisEvent.Type);
memset(&OemNdisApiReference,0,sizeof(OemNdisApiReference));
switch ( OemNdisEvent.Type )
{
case OEM_NDIS_RX_PACKET:
DEBUGMSG(ZONE_NDIS, (TEXT("RILNDIS: OEM_NDIS_RX_PACKET Packet = %x, ContextID = %x \r\n"), OemNdisEvent.pPacket, OemNdisEvent.pPacket->dwContextId));
DumpPacket(OemNdisEvent.pPacket);
PacketPointers ( OemNdisEvent.pPacket );
pfnRilReceiveCallback = NULL;
NdisRilCallbacksFromCID( OemNdisEvent.pPacket->dwContextId, &pCallbackContext, &pfnRilReceiveCallback, &pfnRilTransmitCallback, &pfnRilStatusCallback );
if ( pfnRilReceiveCallback )
{
pfnRilReceiveCallback(pCallbackContext,OemNdisEvent.pPacket);
}
else // The context must be closed
{
DEBUGMSG(ZONE_NDIS, (TEXT("RILNDIS: OEM_NDIS_RX_PACKET WARNING Context Closed - Freeing \r\n")));
OemNdisEvent.Type = OEM_NDIS_RX_PACKET_COMPLETE;
WriteMsgQueue(m_TxMsgQueue, &OemNdisEvent, sizeof(OemNdisEvent),0, 0 );
}
break;
case OEM_NDIS_TX_PACKET_COMPLETE:
DEBUGMSG(ZONE_NDIS, (TEXT("RILNDIS: OEM_NDIS_TX_PACKET_COMPLETE Packet = %x, ContextID = %x \r\n"), OemNdisEvent.pPacket, OemNdisEvent.pPacket->dwContextId));
pfnRilTransmitCallback = NULL;
NdisRilCallbacksFromCID( OemNdisEvent.pPacket->dwContextId, &pCallbackContext, &pfnRilReceiveCallback, &pfnRilTransmitCallback, &pfnRilStatusCallback );
if ( pfnRilTransmitCallback )
{
pfnRilTransmitCallback(pCallbackContext,OemNdisEvent.pPacket);
}
else
{
DEBUGMSG(ZONE_NDIS, (TEXT("RILNDIS: OEM_NDIS_TX_PACKET_COMPLETE WARNING No Callback \r\n")));
}
break;
case OEM_NDIS_XOFF:
case OEM_NDIS_XON:
RilNdisStatus.dwContextId=0;
RilNdisStatus.dwSize=sizeof(RilNdisStatus);
RilNdisStatus.dwStatusType=RIL_PARAM_RILNDISSTATUS_FLOWCONTROL;
RilNdisStatus.dwFlowControl=(OemNdisEvent.Type == OEM_NDIS_XON) ? RIL_NDIS_XON : RIL_NDIS_XOFF;
m_Xon = RilNdisStatus.dwFlowControl;
pfnRilStatusCallback = NULL;
for( ContextIDIndex=0;ContextIDIndex<m_NumNdisChannels;ContextIDIndex++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -