www.pudn.com > PPPOE.rar > channel.cpp


 
//******************************************************************** 
//	ÈÕÆÚ:	2004/08/25 - 25:8:2004   13:57 
//	Ãûǰ:	tiamo 
//	ÃèÊö:	channel 
//********************************************************************* 
 
#include "stdafx.h" 
 
#define __ulFILE__											MAKE_SIG('C','H','N','L') 
 
// create init channel 
PCHANNEL CreateInitializeChannel(ULONG ulLineId) 
{ 
	PCHANNEL pRet = NULL; 
	AllocateMemory(reinterpret_cast(&pRet),sizeof(CHANNEL),CHANNEL_SIG); 
 
	NdisZeroMemory(pRet,sizeof(CHANNEL)); 
 
	pRet->m_ulSig = CHANNEL_SIG; 
	pRet->m_lRefCount = 1; 
	pRet->m_ulState = CHANNEL_CLOSE; 
	pRet->m_ulLineId = ulLineId; 
	pRet->m_ulLinkSpeed = 1000000; 
	pRet->m_ulBearerMode = LINEBEARERMODE_DATA; 
	pRet->m_ulMediaMode = LINEMEDIAMODE_DIGITALDATA; 
 
	pRet->m_wanCoLinkInfo.MaxRecvFrameSize =  
				pRet->m_wanCoLinkInfo.MaxSendFrameSize = g_pAdapter->m_wanCoInfo.MaxFrameSize - PPPOE_HEADER_LEN; 
 
	pRet->m_wanCoLinkInfo.RecvACCM = pRet->m_wanCoLinkInfo.SendACCM = g_pAdapter->m_wanCoInfo.DesiredACCM; 
	pRet->m_wanCoLinkInfo.RecvCompressionBits = pRet->m_wanCoLinkInfo.SendCompressionBits = 0; 
	pRet->m_wanCoLinkInfo.RecvFramingBits = pRet->m_wanCoLinkInfo.SendFramingBits = g_pAdapter->m_wanCoInfo.FramingBits; 
 
	NdisAllocateSpinLock(&pRet->m_lockSelf); 
 
	NdisInitializeListHead(&pRet->m_ltRecvedPacketsHead); 
 
	return pRet; 
} 
 
// shut down channel 
VOID ShutdownChannel(PCHANNEL pChannel) 
{ 
	PAGED_CODE(); 
 
	ASSERT(pChannel && pChannel->m_ulSig == CHANNEL_SIG && !pChannel->m_hNdisSapHandle && !pChannel->m_hNdisVcHandle && 
		   pChannel->m_lRefCount == 1 && !pChannel->m_lSapRefCount && !pChannel->m_lPendingRecvedPackets && 
		   !pChannel->m_lPendingReturnPackets && !pChannel->m_lSendingPackets); 
 
	NdisFreeSpinLock(&pChannel->m_lockSelf); 
 
	FreeMemory(pChannel,sizeof(CHANNEL)); 
} 
 
// ref 
VOID ReferenceChannel(PCHANNEL pChannel,BOOLEAN bAcquireLook) 
{ 
	ASSERT(pChannel && pChannel->m_ulSig == CHANNEL_SIG && pChannel->m_lRefCount > 0); 
 
	if(bAcquireLook) 
		NdisAcquireSpinLock(&pChannel->m_lockSelf); 
 
	pChannel->m_lRefCount ++; 
 
	if(bAcquireLook) 
		NdisReleaseSpinLock(&pChannel->m_lockSelf); 
} 
 
// deref 
VOID DereferenceChannel(PCHANNEL pChannel) 
{ 
	ASSERT(pChannel && pChannel->m_ulSig == CHANNEL_SIG && pChannel->m_lRefCount > 0); 
 
	NdisAcquireSpinLock(&pChannel->m_lockSelf); 
 
	-- pChannel->m_lRefCount; 
 
	NdisReleaseSpinLock(&pChannel->m_lockSelf); 
} 
 
// ref sap 
VOID ReferenceSap(PCHANNEL pChannel,BOOLEAN bAcquireLook) 
{ 
	ASSERT(pChannel && pChannel->m_ulSig == CHANNEL_SIG && pChannel->m_lRefCount > 0 && pChannel->m_lSapRefCount > 0); 
 
	if(bAcquireLook) 
		NdisAcquireSpinLock(&pChannel->m_lockSelf); 
 
	pChannel->m_lSapRefCount ++; 
 
	if(bAcquireLook) 
		NdisReleaseSpinLock(&pChannel->m_lockSelf); 
} 
 
// deref sap 
VOID DereferenceSap(PCHANNEL pChannel) 
{ 
	ASSERT(pChannel && pChannel->m_ulSig == CHANNEL_SIG && pChannel->m_lRefCount > 0 && pChannel->m_lSapRefCount > 0); 
 
	NdisAcquireSpinLock(&pChannel->m_lockSelf); 
 
	LONG lCount = -- pChannel->m_lSapRefCount; 
 
	NDIS_HANDLE hNdisSapHandle = NULL; 
 
	if(!lCount) 
	{ 
		hNdisSapHandle = pChannel->m_hNdisSapHandle; 
		pChannel->m_hNdisSapHandle = NULL; 
	} 
 
	NdisReleaseSpinLock(&pChannel->m_lockSelf); 
 
	if(!lCount) 
	{ 
		ASSERT(hNdisSapHandle); 
		NdisMCmDeregisterSapComplete(NDIS_STATUS_SUCCESS,hNdisSapHandle); 
		DereferenceChannel(pChannel); 
	} 
} 
 
// add channel to bind, 
VOID AddChannel2Bind(PCHANNEL pChannel,PBIND_CONTEXT pBind) 
{ 
	NdisAcquireSpinLock(&pChannel->m_lockSelf); 
 
	// must be at activating state 
	if(pChannel->m_ulState == CHANNEL_ACTIVATING) 
	{ 
		NdisAcquireSpinLock(&pBind->m_lockSelf); 
 
		if(pBind->m_ulBindState == BIND_LOWER_MINIPORT_OPENED) 
		{ 
			ReferenceBind(pBind,FALSE); 
 
			pChannel->m_pBindContext = pBind; 
 
			NdisMoveMemory(pChannel->m_macSelf,pBind->m_macAddress,ETH_ADDR_LEN); 
 
			pChannel->m_ulLinkSpeed = pBind->m_ulLinkSpeed; 
		} 
 
		NdisReleaseSpinLock(&pBind->m_lockSelf); 
	} 
 
	NdisReleaseSpinLock(&pChannel->m_lockSelf); 
} 
 
// remove, 
VOID RemoveChannelFromBind(PCHANNEL pChannel,PBIND_CONTEXT pBind) 
{ 
	NdisAcquireSpinLock(&pChannel->m_lockSelf); 
 
	if(pChannel->m_ulState == CHANNEL_DEACTIVATING) 
	{ 
		pChannel->m_pBindContext = NULL; 
		pChannel->m_ulLinkSpeed = 0; 
	} 
 
	NdisReleaseSpinLock(&pChannel->m_lockSelf); 
 
	DereferenceBind(pBind); 
} 
 
// map session id to connect 
PCHANNEL MapSessionId2Channel(PPACKET pPacket) 
{ 
	ASSERT(DISPATCH_LEVEL == KeGetCurrentIrql()); 
 
	PCHANNEL pChannel = NULL; 
 
	// from session id get connect pointer 
	NdisDprAcquireSpinLock(&g_pAdapter->m_lockSelf); 
 
	for(ULONG i = 0; i < g_pAdapter->m_ulNumChannels; i++) 
	{ 
		pChannel = g_pAdapter->m_ppChannels[i]; 
 
		NdisDprAcquireSpinLock(&pChannel->m_lockSelf); 
 
		if( pChannel->m_ulState == CHANNEL_ACTIVATED &&  
			pChannel->m_usSessionId == ntohs(pPacket->m_pFrame->m_pppFrame.m_usSession) && 
			RtlCompareMemory(pChannel->m_macPeer,pPacket->m_pFrame->m_srcMac,ETH_ADDR_LEN) == ETH_ADDR_LEN && 
			RtlCompareMemory(pChannel->m_macSelf,pPacket->m_pFrame->m_dstMac,ETH_ADDR_LEN) == ETH_ADDR_LEN) 
		{ 
			break; 
		} 
 
		NdisDprReleaseSpinLock(&pChannel->m_lockSelf); 
 
		pChannel = NULL; 
	} 
 
	NdisDprReleaseSpinLock(&g_pAdapter->m_lockSelf); 
 
	return pChannel; 
} 
 
// map without session id to connect 
PCHANNEL MapWithoutSessionId2Channel(PPACKET pPacket) 
{ 
	ASSERT(DISPATCH_LEVEL == KeGetCurrentIrql()); 
 
	PLARGE_INTEGER pllHostUnique = reinterpret_cast(pPacket->m_pHostUnique); 
 
	if(pllHostUnique->LowPart >= g_pAdapter->m_ulNumChannels) 
		return NULL; 
 
	PCHANNEL pChannel = g_pAdapter->m_ppChannels[pllHostUnique->LowPart]; 
 
	if(pChannel) 
	{ 
		NdisDprAcquireSpinLock(&pChannel->m_lockSelf); 
 
		if(pChannel->m_ulState != CHANNEL_ACTIVATING) 
		{ 
			NdisDprReleaseSpinLock(&pChannel->m_lockSelf); 
			pChannel = NULL; 
		} 
	} 
 
	return pChannel; 
}