⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rilhandndisoem1.cpp

📁 手机RILGSM实现的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		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 + -