📄 rilhandndisoem1.cpp
字号:
//
// Arguments: IN cid, OUT LPRILNDISGPRSCONTEXT
//
// Return Values: E_FAIL if not found.
//
// Side effects:
//
// Description:
// **************************************************************************
BOOL CRilNDIS::NdisRilGprsContextFromCID( DWORD ContextID, LPRILNDISGPRSCONTEXT pRilGprsContext)
{
BOOL fReturn = FALSE;
EnterCriticalSection(&m_ConnectionList);
if ( pRilGprsContext )
{
for(DWORD i=0;i<m_NumNdisChannels;i++)
{
if ( ContextID && (m_pNdisChannels[i].ContextID == ContextID) )
{
CeSafeCopyMemory(pRilGprsContext, &m_pNdisChannels[i].RilNdisGprsContext, sizeof(m_pNdisChannels[i].RilNdisGprsContext));
fReturn = TRUE;
break;
}
}
}
LeaveCriticalSection(&m_ConnectionList);
return fReturn;
}
// **************************************************************************
// 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].RilNdisGprsContext.pCallbackContext = NULL;
m_pNdisChannels[i].RilNdisGprsContext.pfnNdisReceive= NULL;
m_pNdisChannels[i].RilNdisGprsContext.pfnNdisStatus = NULL;
m_pNdisChannels[i].RilNdisGprsContext.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;
HRESULT Result = E_FAIL;
OEMNDISINITIALIZE OemNdisInitialize;
CPdpContext *pCPdpContext = NULL;
RILGPRSCONTEXTACTIVATED RilGprsContexActivated;
// 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 */
NdisThreadEvents[NDIS_STOP_THREAD_INDEX] = m_CancelEvent;
NdisThreadEvents[NDIS_RX_QUEUE_INDEX] = m_RxMsgQueue;
m_NumNdisChannels = 3;
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_OPEN_COMPLETE:
memset(&OemNdisApiReference, 0, sizeof(OemNdisApiReference));
OemNdisApiReference.EventType= OEM_NDIS_OPEN_COMPLETE;
OemNdisApiReference.ContextID = OemNdisEvent.ContextID;
OemNdisApiReference.RilNdisGprsContextResponse.dwError = OemNdisEvent.Status;
OemNdisApiReference.RilNdisGprsContextResponse.cbSize = sizeof(OemNdisApiReference.RilNdisGprsContextResponse);
OemNdisApiReference.RilNdisGprsContextResponse.dwContextID = OemNdisEvent.ContextID;
if ( 0 == OemNdisEvent.Status )
{
OemNdisEvent.Status = 1; //default error condition.
if ( TRUE == NdisRilGprsContextFromCID( OemNdisEvent.ContextID, &OemNdisInitialize.RilNdisGprsContext))
{
if ( g_pfnNdisInitialize )
{
OemNdisInitialize.Size = sizeof(OemNdisInitialize);
OemNdisInitialize.dwType = OEM_NDIS_INITIALIZE_INIT;
Result = g_pfnNdisInitialize ( &OemNdisInitialize );
if ( S_OK == Result )
{
OemNdisEvent.Status = 0;
CeSafeCopyMemory(&OemNdisApiReference.RilNdisGprsContextResponse, &OemNdisInitialize.RilNdisGprsContextResponse,sizeof(OemNdisApiReference.RilNdisGprsContextResponse));
NdisConvertConfig ( &OemNdisEvent.IpConfig, &OemNdisApiReference.RilNdisGprsContextResponse.RilNdisIPConfig);
OemNdisApiReference.RilNdisGprsContextResponse.RilNdisIPConfig.dwContextId = OemNdisEvent.ContextID;
DumpNdisIPConfig( &OemNdisApiReference.RilNdisGprsContextResponse.RilNdisIPConfig );
OemNdisApiReference.RilNdisGprsContextResponse.dwParams = RIL_PARAM_RILNDISGPRSCONTEXTRESPONSE_IPCONFIG | RIL_PARAM_RILNDISGPRSCONTEXTRESPONSE_FUNCTIONS;
}
}
}
}
OemNdisApiReference.Status = OemNdisEvent.Status;
m_NdisAsyncCommandList.ProcessCommand ( &OemNdisApiReference );
if ( OemNdisEvent.Status ) // FAILURE!
{
pCPdpContext = (CPdpContext*)NdisPdpContextFromCid( OemNdisEvent.ContextID );
ASSERT(pCPdpContext);
pCPdpContext->CloseContext(OemNdisEvent.ContextID);
NdisShutdownConnection ( OemNdisEvent.ContextID);
}
else
{
RilGprsContexActivated.cbSize = sizeof(RILGPRSCONTEXTACTIVATED);
RilGprsContexActivated.fActivated = TRUE;
RilGprsContexActivated.dwContextID = OemNdisEvent.ContextID;
RilGprsContexActivated.dwEvent = RIL_RILGPRSCONTEXTACTIVATED_MEACT;
((CRilHandle*)m_pCRilHandle)->BroadcastRealBlobNotification(RIL_NOTIFY_GPRSCONNECTIONSTATUS, &RilGprsContexActivated, sizeof(RILGPRSCONTEXTACTIVATED));
}
ProcessNextContextRequest();
break;
case OEM_NDIS_CLOSE_COMPLETE:
memset(&OemNdisApiReference, 0, sizeof(OemNdisApiReference));
OemNdisApiReference.Status = OemNdisEvent.Status;
OemNdisApiReference.EventType= OEM_NDIS_CLOSE_COMPLETE;
OemNdisApiReference.ContextID = OemNdisEvent.ContextID;
OemNdisApiReference.RilNdisGprsContextResponse.dwError = OemNdisEvent.Status;
OemNdisApiReference.RilNdisGprsContextResponse.cbSize = sizeof(OemNdisApiReference.RilNdisGprsContextResponse);
OemNdisApiReference.RilNdisGprsContextResponse.dwContextID = OemNdisEvent.ContextID;
m_NdisAsyncCommandList.ProcessCommand ( &OemNdisApiReference );
NdisShutdownConnection ( OemNdisEvent.ContextID );
if ( g_pfnNdisInitialize )
{
memset(&OemNdisInitialize, 0, sizeof(OemNdisInitialize));
// Reset the context count.
OemNdisInitialize.Size = sizeof(OemNdisInitialize);
OemNdisInitialize.dwType = OEM_NDIS_INITIALIZE_CLOSE;
OemNdisInitialize.RilNdisGprsContext.dwContextID = OemNdisEvent.ContextID;
Result = g_pfnNdisInitialize ( &OemNdisInitialize );
}
ProcessNextContextRequest();
break;
}
}
}
continue;
}
else
{
ASSERT(0);
}
}while(1);
Exit:
CloseMsgQueue (m_RxMsgQueue);
CloseMsgQueue (m_RxMsgQueueWrite);
if ( m_pNdisChannels )
{
LocalFree(m_pNdisChannels);
}
return 0;
}
// **************************************************************************
// Function Name: NdisAllocateCommand
//
// Purpose: Allocate an asynchronous command. This method is used
// when the response will key off of the event type.
//
// Arguments: IN eType: expected event.
//
// Return Values:
//
// Side effects:
//
// Description:
// **************************************************************************
void CRilNDIS::NdisAllocateCommand ( OEMNDISEVENTTYPE Type, DWORD ContextID, LPVOID pCRilInstance, HRESULT CommandID )
{
if ( ContextID && pCRilInstance )
{
OEMNDISAPIREFERENCE OemNdisApiReference;
memset(&OemNdisApiReference,0,sizeof(OemNdisApiReference));
OemNdisApiReference.pCRilInstance = pCRilInstance;
OemNdisApiReference.EventType = Type;
OemNdisApiReference.ContextID = ContextID;
OemNdisApiReference.CommandID = CommandID;
m_NdisAsyncCommandList.AddCommand ( &OemNdisApiReference );
}
}
void
CRilNDIS:: NdisRemoveCommand ( HRESULT hrCommandID )
{
if ( hrCommandID )
{
m_NdisAsyncCommandList.RemoveCommand ( hrCommandID );
}
}
void CRilNDIS::NdisConvertConfig ( const OEMNDISIPCONFIG* pOemNdisConfig, RILNDISIPCONFIG* pRilNdisIpConfig)
{
if ( pOemNdisConfig && pRilNdisIpConfig )
{
memset( pRilNdisIpConfig, 0, sizeof(RILNDISIPCONFIG));
pRilNdisIpConfig->cbSize = sizeof(RILNDISIPCONFIG);
/* derive whether address is IPv4(default) or IPv6 */
pRilNdisIpConfig->dwProtocol = RIL_PARAM_NDISIPCONFIG_PROTOCOL_IPV4;
if ( pOemNdisConfig->ipAddress.length == IPV6_ADDRESS_LENGTH )
{
pRilNdisIpConfig->dwProtocol = RIL_PARAM_NDISIPCONFIG_PROTOCOL_IPV6;
}
/* fill in protocol specific parameters */
if ( pRilNdisIpConfig->dwProtocol == RIL_PARAM_NDISIPCONFIG_PROTOCOL_IPV4 )
{
pRilNdisIpConfig->ipv4.dwFlags |= RIL_PARAM_NDISIPCONFIG_SUBNETMASK;
pRilNdisIpConfig->ipv4.inSubnetMask = 0xffffff00;
if ( pOemNdisConfig->ipAddress.length && pOemNdisConfig->ipAddress.address )
{
pRilNdisIpConfig->ipv4.dwFlags |= RIL_PARAM_NDISIPCONFIG_IPADDR;
pRilNdisIpConfig->ipv4.dwFlags |= RIL_PARAM_NDISIPCONFIG_DEFAULTGATEWAY;
pRilNdisIpConfig->ipv4.inIPAddress = myinet_addr( pOemNdisConfig->ipAddress.address, pOemNdisConfig->ipAddress.length );
pRilNdisIpConfig->ipv4.inDefaultGateway = pRilNdisIpConfig->ipv4.inIPAddress ^ 0xFF;
}
if ( pOemNdisConfig->primaryDnsAddress.length && pOemNdisConfig->primaryDnsAddress.address)
{
pRilNdisIpConfig->ipv4.dwFlags |= RIL_PARAM_NDISIPCONFIG_PRIMARYDNS;
pRilNdisIpConfig->ipv4.inPrimaryDNS = myinet_addr( pOemNdisConfig->primaryDnsAddress.address, pOemNdisConfig->primaryDnsAddress.length );
}
if ( pOemNdisConfig->secondaryDnsAddress.length && pOemNdisConfig->secondaryDnsAddress.address)
{
pRilNdisIpConfig->ipv4.dwFlags |= RIL_PARAM_NDISIPCONFIG_SECONDARYDNS;
pRilNdisIpConfig->ipv4.inSecondaryDNS = myinet_addr( pOemNdisConfig->secondaryDnsAddress.address, pOemNdisConfig->secondaryDnsAddress.length );
}
}
else if ( pRilNdisIpConfig->dwProtocol == RIL_PARAM_NDISIPCONFIG_PROTOCOL_IPV6 )
{
if ( pOemNdisConfig->ipAddress.length )
{
pRilNdisIpConfig->ipv6.dwFlags |= RIL_PARAM_NDISIPCONFIG_IPV6_IPADDR;
pRilNdisIpConfig->ipv6.inIPAddress = myinet_ipv6addr( pOemNdisConfig->ipAddress.address, pOemNdisConfig->ipAddress.length );
UCHAR subnetmask[IPV6_ADDRESS_LENGTH];
memset( subnetmask, 0xFF, sizeof(subnetmask) );
pRilNdisIpConfig->ipv6.dwFlags |= RIL_PARAM_NDISIPCONFIG_IPV6_SUBNETMASK;
pRilNdisIpConfig->ipv6.inSubnetMask = myinet_ipv6addr( subnetmask, IPV6_ADDRESS_LENGTH );
pRilNdisIpConfig->ipv6.dwFlags |= RIL_PARAM_NDISIPCONFIG_IPV6_DEFAULTGATEWAY;
pRilNdisIpConfig->ipv6.inDefaultGateway = pRilNdisIpConfig->ipv6.inIPAddress;
}
if ( pOemNdisConfig->primaryDnsAddress.length )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -