📄 rilhandndis.cpp
字号:
CRilInstanceNDIS *pCRilInstanceNdis;
pCRilInstanceNdis = (CRilInstanceNDIS*)g_pCRilNdis->NdisRilInstanceFromHandle( hNdis );
if ( pCRilInstanceNdis )
{
pCRilInstanceNdis->NdisReceivePacketDone(lpPacketReceived);
}
}
}
}
}
// **************************************************************************
// Function Name: NdisNotifyThread
//
// Purpose: Thread running to process NDIS events.
//
// Arguments:
//
// Return Values:
//
// Side effects:
//
// Description:
// **************************************************************************
DWORD CRilNDIS:: NdisNotifyThread(void)
{
DWORD dwTriggered, dwIndex, ChannelIndex=0;
BOOL fMoreEvents,fSuccess;
OEMNDISAPIREFERENCE OemNdisApiReference;
HRESULT hr;
RILNDISIPCONFIG RilNdisIpConfig;
OEMNDISEVENT OemNdisEvent,ReceiveOemNdisEvent;
CRilInstanceHandle *pCrilInstanceHandle = NULL;
RILNDISGPRSCONTEXT RilNdisGprsContext;
RILGPRSCONTEXTACTIVATED RilGprsContexActivated;
DWORD ResultDetails = 0;
DWORD ContextID = 0;
HANDLE hNdisChannelHandle = NULL;
BOOL HandlePdpContextListEntry = FALSE;
BOOL ProcessCommandFlag = FALSE;
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();
memset ( &m_rgpNdisEvents, 0, sizeof(OEMNDISWAITEVENTOBJECT));
// Create the event used to indicate new events
m_rgpNdisEvents.hNdisAddChannelEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(!m_rgpNdisEvents.hNdisAddChannelEvent)
{
goto Exit;
}
m_rgpNdisEvents.lpNdisEventHandlesPrimary[NDIS_ADD_CHANNEL_EVENT_INDEX] = m_rgpNdisEvents.hNdisAddChannelEvent ;
m_rgpNdisEvents.lpNdisEventHandlesUpdate[NDIS_ADD_CHANNEL_EVENT_INDEX] = m_rgpNdisEvents.hNdisAddChannelEvent ;
m_rgpNdisEvents.nObjectCount = 1;
m_rgpNdisEvents.lpNdisEventHandlesPrimary[NDIS_STOP_THREAD_INDEX] = m_hCancelEvent;
m_rgpNdisEvents.lpNdisEventHandlesUpdate[NDIS_STOP_THREAD_INDEX] = m_hCancelEvent;
m_rgpNdisEvents.nObjectCount++;
do
{
dwTriggered = WaitForMultipleObjects( m_rgpNdisEvents.nObjectCount, m_rgpNdisEvents.lpNdisEventHandlesPrimary, FALSE, INFINITE );
dwIndex = dwTriggered - WAIT_OBJECT_0;
// The events from NDIS are created with manual reset enabled. The event will be reset by the RADIO when
// the last event is read from the queue.
if ( dwIndex == NDIS_ADD_CHANNEL_EVENT_INDEX ) // index reserved for the m_rgpNdisEvents.hNdisAddChannelEvent event.
{
EnterCriticalSection(&m_csNdisEventList);
memmove( m_rgpNdisEvents.lpNdisEventHandlesPrimary,
m_rgpNdisEvents.lpNdisEventHandlesUpdate,
sizeof(m_rgpNdisEvents.lpNdisEventHandlesPrimary));
m_rgpNdisEvents.nObjectCount = NdisCountEvents();
LeaveCriticalSection(&m_csNdisEventList);
continue; // Get the upcoming notification
}
if ( dwIndex == NDIS_STOP_THREAD_INDEX )
{
NdisCloseAllConnections();
break;
}
// The notification is coming from the RADIO
else
{
// We maintain a parallel array that contains the RADIO handle so we don't need to extract them from the event
// name. Get RADIO events and process them.
do {
memset ( &ReceiveOemNdisEvent, 0, sizeof(OEMNDISEVENT));
fSuccess = NdisInterfaceReceiveEvent( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ReceiveOemNdisEvent, &fMoreEvents);
if ( fSuccess )
{
DEBUG_TYPE(ReceiveOemNdisEvent.type);
memset(&OemNdisApiReference,0,sizeof(OemNdisApiReference));
OemNdisApiReference.hNdisHandle = m_rgpNdisEvents.lpNdisHandles[dwIndex]; // the radio handle
switch ( ReceiveOemNdisEvent.type )
{
case OEM_NDIS_RX_PACKET:
ReceiveOemNdisEvent.event.packet_p->dwContextId = 0;
NdisCidFromHandle ( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ReceiveOemNdisEvent.event.packet_p->dwContextId );
DumpPacket(ReceiveOemNdisEvent.event.packet_p);
PacketPointers ( ReceiveOemNdisEvent.event.packet_p );
pfnRilReceiveCallback = NULL;
NdisRilCallbacksFromCID( ReceiveOemNdisEvent.event.packet_p->dwContextId, &pCallbackContext, &pfnRilReceiveCallback, &pfnRilTransmitCallback, &pfnRilStatusCallback );
if ( pfnRilReceiveCallback )
{
pfnRilReceiveCallback(pCallbackContext,ReceiveOemNdisEvent.event.packet_p);
}
else // The context must be closed
{
DEBUGMSG(ZONE_NDIS, (TEXT("RILNDIS: OEM_NDIS_RX_PACKET WARNING Context Closed - Freeing \r\n")));
ReceiveOemNdisEvent.type = OEM_NDIS_RX_PACKET_COMPLETE;
NdisInterfaceTransmitEvent( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ReceiveOemNdisEvent);
}
break;
case OEM_NDIS_TX_PACKET_COMPLETE:
NdisCidFromHandle ( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ReceiveOemNdisEvent.event.packet_p->dwContextId );
pfnRilTransmitCallback = NULL;
NdisRilCallbacksFromCID( ReceiveOemNdisEvent.event.packet_p->dwContextId, &pCallbackContext, &pfnRilReceiveCallback, &pfnRilTransmitCallback, &pfnRilStatusCallback );
if ( pfnRilTransmitCallback )
{
pfnRilTransmitCallback(pCallbackContext,ReceiveOemNdisEvent.event.packet_p);
}
else // The context must be closed
{
DEBUGMSG(ZONE_NDIS, (TEXT("RILNDIS: OEM_NDIS_TX_PACKET_COMPLETE WARNING Context Closed - Freeing \r\n")));
}
break;
case OEM_NDIS_IP_CONFIGURATION:
memset ( &RilNdisIpConfig, 0, sizeof(RILNDISIPCONFIG));
NdisConvertConfig ( &ReceiveOemNdisEvent.event.configuration, &RilNdisIpConfig);
NdisCidFromHandle ( m_rgpNdisEvents.lpNdisHandles[dwIndex], &RilNdisIpConfig.dwContextId );
DumpNdisIPConfig( &RilNdisIpConfig );
OemNdisApiReference.RilNdisGprsContextResponse.cbSize = sizeof(OemNdisApiReference.RilNdisGprsContextResponse);
OemNdisApiReference.dwStatus = 0; // No error
OemNdisApiReference.eEventType= OEM_NDIS_OPEN_COMPLETE;
OemNdisApiReference.ContextID = ContextID;
OemNdisApiReference.RilNdisGprsContextResponse.dwError = OemNdisApiReference.dwStatus;
ContextID = 0;
NdisCidFromHandle( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ContextID);
OemNdisApiReference.RilNdisGprsContextResponse.dwContextID = ContextID;
OemNdisApiReference.RilNdisGprsContextResponse.pfnNdisReceivePacketDone = RilNdisRecievePacketDone;
OemNdisApiReference.RilNdisGprsContextResponse.pfnNdisSendPacket = RilNdisSendPacket;
CeSafeCopyMemory(&OemNdisApiReference.RilNdisGprsContextResponse.RilNdisIPConfig, &RilNdisIpConfig,sizeof(OemNdisApiReference.RilNdisGprsContextResponse.RilNdisIPConfig));
OemNdisApiReference.RilNdisGprsContextResponse.dwParams = RIL_PARAM_RILNDISGPRSCONTEXTRESPONSE_IPCONFIG | RIL_PARAM_RILNDISGPRSCONTEXTRESPONSE_FUNCTIONS;
ProcessCommandFlag = m_NdisAsyncCommandList.ProcessCommand ( &OemNdisApiReference );
ProcessNextContextRequest();
break;
case OEM_NDIS_XOFF:
case OEM_NDIS_XON:
RilNdisStatus.dwContextId=0;
RilNdisStatus.dwSize=sizeof(RilNdisStatus);
RilNdisStatus.dwStatusType=RIL_PARAM_RILNDISSTATUS_FLOWCONTROL;
RilNdisStatus.dwFlowControl = (ReceiveOemNdisEvent.type == OEM_NDIS_XON) ? RIL_NDIS_XON : RIL_NDIS_XOFF;
m_fXon = RilNdisStatus.dwFlowControl;
pfnRilStatusCallback = NULL;
for( ContextIDIndex=FIRST_VALID_NDIS_INDEX;ContextIDIndex<MAX_OEMNDIS_CHANNELS;ContextIDIndex++)
{
NdisRilCallbacksFromCID( ContextIDIndex, &pCallbackContext, &pfnRilReceiveCallback, &pfnRilTransmitCallback, &pfnRilStatusCallback );
if ( pfnRilStatusCallback )
{
pfnRilStatusCallback(pCallbackContext,&RilNdisStatus);
}
else
{
DEBUGMSG(ZONE_NDIS, (TEXT("RILNDIS: %s WARNING No Callback on context %x\r\n"),(ReceiveOemNdisEvent.type == OEM_NDIS_XON) ? L"OEM_NDIS_XON" : L"OEM_NDIS_XOFF", ContextIDIndex));
}
}
break;
case OEM_NDIS_INITIALISE_COMPLETE:
ContextID = 0;
NdisCidFromHandle( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ContextID);
ASSERT(ContextID);
if ( ReceiveOemNdisEvent.event.NdisStatus.dwErrorStatus == 0 ) // SUCCESS
{
memset(&OemNdisEvent, 0, sizeof ( OEMNDISEVENT ));
OemNdisEvent.type = OEM_NDIS_OPEN_CONNECTION;
hr = NdisOemNdisOpenRequestFromHandle(m_rgpNdisEvents.lpNdisHandles[dwIndex], &RilNdisGprsContext);
if ( hr == S_OK )
{
if ( RilNdisGprsContext.dwParams & RIL_PARAM_RILNDISGPRSCONTEXT_USERNAME )
{
strncpy(OemNdisEvent.event.open.psUsername,AnsiString(RilNdisGprsContext.tszUserName),NDIS_USERNAME_MAX_LENGTH-1);
strncpy(OemNdisEvent.event.open.psPassword,AnsiString(RilNdisGprsContext.tszPassword),NDIS_PASSWORD_MAX_LENGTH-1);
OemNdisEvent.event.open.dwUsernameLength = strlen(OemNdisEvent.event.open.psUsername);
OemNdisEvent.event.open.dwPasswordLength = strlen(OemNdisEvent.event.open.psPassword);
DEBUGMSG( ZONE_NDIS, (TEXT("RILNDIS: NdisNotifyThread Username = %hs, Length = %d, Password = %hs Length = %d \r\n"),
OemNdisEvent.event.open.psUsername, OemNdisEvent.event.open.dwUsernameLength,
OemNdisEvent.event.open.psPassword,OemNdisEvent.event.open.dwPasswordLength ));
}
OemNdisEvent.event.open.cid = ContextID;
}
if ( !NdisInterfaceTransmitEvent( m_rgpNdisEvents.lpNdisHandles[dwIndex], &OemNdisEvent) )
{
hr = E_FAIL;
ReceiveOemNdisEvent.event.NdisStatus.dwErrorStatus = 1; // Set error
}
}
else
{
hr = E_FAIL;
}
if ( S_OK != hr )
{
OemNdisApiReference.eEventType= OEM_NDIS_OPEN_COMPLETE;
OemNdisApiReference.dwStatus = ReceiveOemNdisEvent.event.NdisStatus.dwErrorStatus;
OemNdisApiReference.ContextID = ContextID;
OemNdisApiReference.RilNdisGprsContextResponse.cbSize = sizeof(OemNdisApiReference.RilNdisGprsContextResponse);
OemNdisApiReference.RilNdisGprsContextResponse.dwError = OemNdisApiReference.dwStatus;
ProcessCommandFlag = m_NdisAsyncCommandList.ProcessCommand ( &OemNdisApiReference );
ASSERT(ProcessCommandFlag);
NdisShutdownConnection ( m_rgpNdisEvents.lpNdisHandles[dwIndex] );
ProcessNextContextRequest();
}
break;
case OEM_NDIS_OPEN_COMPLETE:
ContextID = 0;
NdisCidFromHandle( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ContextID);
ASSERT(ContextID);
NdisRilCallbacksFromCID( ContextID, &pCallbackContext, &pfnRilReceiveCallback, &pfnRilTransmitCallback, &pfnRilStatusCallback );
if ( NULL == pfnRilStatusCallback )
{
ReceiveOemNdisEvent.event.NdisStatus.dwErrorStatus = RIL_E_CANCELLED;
}
OemNdisApiReference.dwStatus = ReceiveOemNdisEvent.event.NdisStatus.dwErrorStatus;
OemNdisApiReference.eEventType= OEM_NDIS_OPEN_COMPLETE;
OemNdisApiReference.ContextID = ContextID;
OemNdisApiReference.RilNdisGprsContextResponse.dwError = OemNdisApiReference.dwStatus;
OemNdisApiReference.RilNdisGprsContextResponse.cbSize = sizeof(OemNdisApiReference.RilNdisGprsContextResponse);
if ( ReceiveOemNdisEvent.event.NdisStatus.dwErrorStatus != 0 ) // FAILURE!
{
ProcessCommandFlag = m_NdisAsyncCommandList.ProcessCommand ( &OemNdisApiReference );
NdisShutdownConnection ( m_rgpNdisEvents.lpNdisHandles[dwIndex] );
ProcessNextContextRequest();
ASSERT(ProcessCommandFlag);
}
else
{
RilGprsContexActivated.cbSize = sizeof(RILGPRSCONTEXTACTIVATED);
RilGprsContexActivated.fActivated = TRUE;
RilGprsContexActivated.dwContextID = ContextID;
RilGprsContexActivated.dwEvent = RIL_RILGPRSCONTEXTACTIVATED_MEACT;
((CRilHandle*)m_pCrilHandle)->BroadcastRealBlobNotification(RIL_NOTIFY_GPRSCONNECTIONSTATUS, &RilGprsContexActivated, sizeof(RILGPRSCONTEXTACTIVATED));
}
break;
case OEM_NDIS_CLOSE_COMPLETE:
ContextID = 0;
NdisCidFromHandle( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ContextID);
ASSERT(ContextID);
OemNdisApiReference.dwStatus = ReceiveOemNdisEvent.event.NdisStatus.dwErrorStatus;
OemNdisApiReference.eEventType= OEM_NDIS_CLOSE_COMPLETE;
OemNdisApiReference.ContextID = ContextID;
ProcessCommandFlag=m_NdisAsyncCommandList.ProcessCommand ( &OemNdisApiReference );
NdisShutdownConnection ( m_rgpNdisEvents.lpNdisHandles[dwIndex] );
ProcessNextContextRequest();
break;
case OEM_NDIS_REGISTRATION_STATUS:
DEBUGMSG( ZONE_NDIS, (TEXT("RILNDIS: fGsmRegistered = %x, fGprsAttached = %x\r\n"),
ReceiveOemNdisEvent.event.regStatus.fGsmRegistered,
ReceiveOemNdisEvent.event.regStatus.fGprsAttached));
if ( FALSE == ReceiveOemNdisEvent.event.regStatus.fGprsAttached )
{
if ( S_OK == NdisCidFromHandle( m_rgpNdisEvents.lpNdisHandles[dwIndex], &ContextID) )
{
RilGprsContexActivated.cbSize = sizeof(RILGPRSCONTEXTACTIVATED);
RilGprsContexActivated.fActivated = FALSE;
RilGprsContexActivated.dwContextID = ContextID;
RilGprsContexActivated.dwEvent = RIL_RILGPRSCONTEXTACTIVATED_NWDEACT;
((CRilHandle*)m_pCrilHandle)->BroadcastRealBlobNotification(RIL_NOTIFY_GPRSCONNECTIONSTATUS, &RilGprsContexActivated, sizeof(RILGPRSCONTEXTACTIVATED));
}
}
break;
case OEM_NDIS_BUFFER_STATUS:
DEBUGMSG( ZONE_NDIS, (TEXT("RILNDIS: reason = %x, maxRxBuffers = %x rxBuffersInUse = %0x maxTxBuffers = %0x txBuffersQueued = %0x \r\n"),
ReceiveOemNdisEvent.event.bufferStatus.eReason,
ReceiveOemNdisEvent.event.bufferStatus.dwMaxRxBuffers,
ReceiveOemNdisEvent.event.bufferStatus.dwRxBuffersInUse,
ReceiveOemNdisEvent.event.bufferStatus.dwMaxTxBuffers,
ReceiveOemNdisEvent.event.bufferStatus.dwTxBuffersQueued));
break;
case OEM_NDIS_NULL_EVENT:
break;
}
}
}while ( fMoreEvents && fSuccess );
}
}while(1);
Exit:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -