telephonyprotocols/rawipnif/src/BcaController.cpp
branchopencode
changeset 24 6638e7f4bd8f
parent 23 6b1d113cdff3
--- a/telephonyprotocols/rawipnif/src/BcaController.cpp	Mon May 03 13:37:20 2010 +0300
+++ b/telephonyprotocols/rawipnif/src/BcaController.cpp	Thu May 06 15:10:38 2010 +0100
@@ -1,444 +1,444 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// Implements the interface to Bca & flow control.
-// 
-//
-
-/**
- @file
-*/
-
-#include <e32uid.h>
-#include <nifmbuf.h>
-#include <es_ini.h>
-#include <e32svr.h>
-#include <u32hal.h>
-#include "BcaController.h"
-
-//In order not to flow off SPUD everytime we set the default to 1
-const TUint KDefaultBufferSize=1;
-
-#ifdef __EABI__
-// Patch data is used and KMaxTxIPPacketSize and KMaxRxIPPacketSize can be modified to a different value in RawIpNif.iby file
-extern const TInt KMaxSendQueueLen = KDefaultBufferSize;
-extern const TInt KMaxTxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength;
-extern const TInt KMaxRxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength;
-#endif
-
-CBcaController::CBcaController(MControllerObserver& aObserver,
-	CBttLogger* aTheLogger)
-/**
- * Constructor. 
- */
-	: iObserver(aObserver),  
-	  iTheLogger(aTheLogger),
-	  iTxFlowControl(EFlowControlOff), 
-	  iTxContextActive(ETrue), 
-	  iSendState(EIdle),
-	  iMaxSendQueueLen(KDefaultBufferSize),
-	  iNumPacketsInSendQueue(0)
-	{
-	iSendQueue.Init();
-	}
-
-
-CBcaController::~CBcaController()
-/**
- * Destructor.
- */
-	{
-	iSendQueue.Free();
-	iNumPacketsInSendQueue = 0;
-
-#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
-	delete iIPTagHeader;
-#endif // RAWIP_HEADER_APPENDED_TO_PACKETS
-	}
-
-void CBcaController::BaseConstructL()
-	{
-	_LOG_L1C1(_L8("CBcaController::BaseConstructL"));
-	
-#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
-    iIPTagHeader = new (ELeave) CIPTagHeader(iTheLogger);
-#endif // RAWIP_HEADER_APPENDED_TO_PACKETS
-    
-#if defined (__EABI__)
-    // Default value for queue length
-    iMaxSendQueueLen = KMaxSendQueueLen;
-	// Default value for Tx and Rx packet size
-	iMaxTxPacketSize = KMaxTxIPPacketSize;
-	iMaxRxPacketSize = KMaxRxIPPacketSize;
-#else // WINS
-	// Set default values in case patch is not present in epocrawip.ini
-	iMaxSendQueueLen = KDefaultBufferSize;    
-	iMaxTxPacketSize = KMaxIPPacket + KIPTagHeaderLength;
-	iMaxRxPacketSize = KMaxIPPacket + KIPTagHeaderLength;
-	       
-	// for the emulator process is patched via the epocrawip.ini file
-	UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxSendQueueLen",&iMaxSendQueueLen);
-	UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxTxIPPacketSize",&iMaxTxPacketSize);
-	UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxRxIPPacketSize",&iMaxRxPacketSize);
-#endif
-	}
-
-void CBcaController::UpdateInternalFlowFlag(TFlowControl aValue)
-/**
- *  Updates Internal Flow flag and resumes the data flow if
- *  necessary.
- *
- * @param aValue the new state of iInternalFlow
- */
-	{
-	_LOG_L1C3(_L8("CBcaController::UpdateInternalFlowFlag[NewValue=%d, iSendState=%d]"),
-		aValue, iSendState);
-
-	if(iTxFlowControl == aValue)
-		{
-		// C32 Sent the same indication signal twice. Nif will ignore it.
-		_LOG_L2C1(_L8("WARNING CBcaController: Received same indication twice"));
-		return;
-		}
-	
-	// Update the flag value.
-	iTxFlowControl = aValue;
-
-	if(iTxFlowControl == EFlowControlOff)
-		{
-		// If the indication received turned flow control off...
-		if (IsTxPossible() && (iSendState == EIdle))
-			{
-			// ... if the NIF is in the EWaiting state
-			// then the data flow can be resumed. 
-			ResumeSending();
-			}
-		}		
-	else
-		{
-		// if the Flow Control is on we can remove all queued write requests
-		EmptySendQueue();
-		}
-	}
-
-void CBcaController::UpdateContextStateFlag(TBool aValue)
-/**
- *  Updates Context State flag and resumes the data flow if
- *  necessary.
- *
- * @param aValue the new state of iTxContextState
- */
-	{
-	_LOG_L1C3(_L8("CBcaController::UpdateContextStateFlag[NewValue=%d, OldValue=%d]"),
-		aValue, iTxContextActive);
-	
-	if(iTxContextActive == aValue)
-		{
-		return;
-		}
-
-	// Update the flag value.
-	iTxContextActive = aValue;
-
-	if(iTxContextActive)
-		{
-		// If the PDP context is active and...
-		if (IsTxPossible() && (iSendState == EIdle))
-			{
-			// ... if the NIF is in the EWaiting state
-			// then the data flow can be resumed. 
-			ResumeSending();
-			}
-		}
-	else
-		{
-		// if the PDP context is suspended we can remove all queued write requests
-		EmptySendQueue();
-		}
-	}
-
-TInt CBcaController::Send(RMBufChain& aPdu)
-/**
- *  This method is called by CRawIPNifMain in order to send a packet down
- * to the BCA. 
- *
- *	@param aPdu a data packet
- */
-	{
-	_LOG_L1C1(_L8(">>CBcaController::Send"));
-
-	// Check if NIF is shutting down
-	if (iSendState == EShuttingDown)
-		{
-		_LOG_L2C1(_L8("    ERROR: Nif is shutting down"));
-		
-		aPdu.Free();
-
-		return KErrDisconnected;
-		}
-	
-	// check that this packet isnt too big - If it is, we dont want to send it or
-	// add it to our queue
-	if ((aPdu.Length() - aPdu.First()->Length()) > BcaSendBufferLength())
-		{
-		_LOG_L2C1(_L8("Packet is too large - discarding"));
-		_LOG_L1C1(_L8("<<CSender::Send -> Error"));
-
-		aPdu.Free();
-		return KErrArgument;
-		}
-	
-	if (iSendState == ESending)
-		// If this happens, it means that TCP/IP has sent us an IP packet
-		// while we're still sending the previous one. 
-		{
-		// check that the queue isnt full NB. this check should not be needed as when the 
-		// queue becomes full the IP layer shouldnt send any more packets until it is told to
-		if (!IsSendQueueFull())
-			{
-			_LOG_L1C1(_L8("    Sender busy, appending packet to queue"));
-			//We know that flow control is off and context isnt suspended so can add to queue
-			AppendToSendQueue(aPdu);
-			
-			return IsSendQueueFull() ? KStopSending : KContinueSending;
-			}
-			
-		_LOG_L1C1(_L8("    Queue is full, upper layer is still sending packets, potential memory problems."));
-		AppendToSendQueue(aPdu);
-		return KStopSending;
-		}
-
-	// If we have got here then a write isnt currently happening
-	// We dont need to check flow control is off and context isnt suspended as the BCA always
-	// has room for one packet, so send the packet
-
-	if(!IsSendQueueEmpty())
-		{
-		//make sure that we don't change the order of packets!
-		//first send what has already been lined up
-		RMBufChain tmpPdu;
-		_LOG_L1C1(_L8("    Packet removed from queue to send"));
-		RemoveFromSendQueue(tmpPdu);
-		AppendToSendQueue(aPdu);
-		
-		// Update module state
-		_LOG_L2C1(_L8("     set State to ESending"));
-		iSendState = ESending;
-		
-		BcaSend(tmpPdu);
-		}
-	else
-		{
-		// Update module state
-		_LOG_L2C1(_L8("     set State to ESending"));
-		iSendState = ESending;
-		 
-		BcaSend(aPdu);
-		}
-		
-	_LOG_L2C1(_L8("<<CBcaController::Send - return StopSending/ContinueSending"));
-	return IsSendQueueFull() ? KStopSending : KContinueSending;
-	}
-
-void CBcaController::SendComplete()	
-/**
- *  This method is called after a packet was sent to the board. 
- *  If allowed by flow contol flags the NIF can signal the TCP/IP
- *  protocol indicating that is available to send more packets.
- */
-	{
-	_LOG_L1C1(_L8("CBcaController::SendComplete"));
-	_LOG_L2C1(_L8("     set State to EIdle"));
-	
-	iSendState = EIdle;
-
-	if (IsTxPossible())
-		ResumeSending();
-	}
-
-TBool CBcaController::IsTxPossible()
-/**
- *  This method returns ETrue if both TX flags are set to ETrue
- *
- * @return The Flow control state
- */
-	{
-	_LOG_L1C3(_L8("CBcaController::IsTxPossible (contextActive %d, flowcontrol %d)"), 
-		iTxContextActive, iTxFlowControl);
-
-	if(iTxContextActive && (iTxFlowControl == EFlowControlOff))
-		return ETrue;
-	else
-		return EFalse;
-	}
-
-void CBcaController::Process(TDesC8& aPdu)
-/**
- *  This method will pass on the received data to CBttNifMain. 
- *
- * @param aPdu a data packet
- */
-	{
-	_LOG_L1C1(_L8(">>CBcaController::Process"));
-
-	TInt ret;
-
-	// Create a packet object.
-	RMBufPacket packet;
-	TRAP(ret, packet.CreateL(aPdu));
-	if (ret != KErrNone)
-		{
-		// Couldn't create package. Packet will be ignored...
-		_LOG_L1C2(_L8("<<CBcaController::Process couldn't create MBuf [ret=%d]"), ret);
-		return;
-		}
-	else
-		// Package created...
-		{
-#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
-		TUint16 protocolCode = iIPTagHeader->RemoveHeader(packet);
-#else
-		TUint16 protocolCode = 0;
-#endif // RAWIP_HEADER_APPENDED_TO_PACKETS
-
-		packet.Pack();
-		// Process the packet
-		GetObserver().Process(packet, protocolCode);
-		}
-
-	_LOG_L1C1(_L8("<<CBcaController::Process"));
-	}
-
-void CBcaController::ResumeSending()
-/**
- *  Used to indicate to the TCP/IP protocol layer that the NIF is ready to 
- *	process more packets.
- */
-	{
-	_LOG_L1C1(_L8("CBcaIoController::ResumeSending"));
-
-	// If there are still some packets in the queue to be sent, then carry
-	// on sending them.
-	// NB. we only want to send more packets from the queue if we are currently EIdle
-	if (iSendState == EIdle) 
-		{
-		if(!IsSendQueueEmpty())
-			{
-			RMBufChain tmpPdu;
-			_LOG_L1C1(_L8("    Packet removed from queue to send"));
-			RemoveFromSendQueue(tmpPdu);
-			
-			// Update module state
-			_LOG_L2C1(_L8("     set State to ESending"));
-			iSendState = ESending;
-			
-			BcaSend(tmpPdu);
-			}
-		if(iFullQueueFlag && IsSendQueueEmpty())
-			{
-			iObserver.ResumeSending();
-			}
-		}
-	// if iSendState = ESending - do nothing
-	}
-	
-#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
-void CBcaController::SetType(TUint16 aType)
-	{
-/**
- *  Used to specify the type of the IP header.
- */
- 	_LOG_L1C1(_L8("CBcaController::SetType"));
- 	
- 	iIPTagHeader->SetType(aType);	
-	}
-
-void CBcaController::AddHeader(TDes8& aDes)
-/**
- *  Used to add the IP header to the packet before sending to the BCA.
- */
-	{
-	_LOG_L1C1(_L8("CBcaController::AddHeader"));
-
-	iIPTagHeader->AddHeader(aDes);
-	}
-
-TUint16 CBcaController::RemoveHeader(RMBufChain& aPdu)
-/**
- *  Used to remove the IP header from the received the packet before sending to the 
- *  TCP/IP layer.  
- * @return The IP header that has been removed from the packet
- */
-	{
-	_LOG_L1C1(_L8("CBcaController::RemoveHeader"));
-
-	return (iIPTagHeader->RemoveHeader(aPdu));
-	}	
-#endif // RAWIP_HEADER_APPENDED_TO_PACKETS
-
-TBool CBcaController::IsSendQueueEmpty()
-/**
- *  Indicator of whether the BufferQueue is empty
- * @return TBool.  ETrue if bufferQueue is emtpy, EFalse if queue is not empty
- */
-	{
-	return iSendQueue.IsEmpty();
-	}
-	
-TBool CBcaController::IsSendQueueFull()
-/**
- *  Indicator of whether the BufferQueue is full
- * @return TBool.  ETrue if bufferQueue is full, EFalse if queue is not full
- */
-	{    
-	iFullQueueFlag = iNumPacketsInSendQueue >= iMaxSendQueueLen;
-	return iFullQueueFlag;
-	}	
-
-void CBcaController::AppendToSendQueue(RMBufChain& aPdu)
-/**
- * Appends the packet aPdu to the queue. 
- * Increments the packet count. Doesn't do error checking.
- * @param aChain buffer chain to be added
- */
-	{
-	iSendQueue.Append(aPdu);
-	iNumPacketsInSendQueue++;
-	}
-	
-TBool CBcaController::RemoveFromSendQueue(RMBufChain& aPdu)
-/**
- * Removes the packet aPdu from the queue. 
- * Decrements the packet count.
- * @param aChain buffer chain to be added
- * @return False if chain is empty
- */
-	{
-	TBool ret = iSendQueue.Remove(aPdu);
-	if(ret)
-		{
-		iNumPacketsInSendQueue--;
-		}
-	return ret;
-	}
-	
-void CBcaController::EmptySendQueue()
-/**
- * Removes all the packets from the send queue. Initializes the
- * send queue and sets the packet count to 0.
- */
-	{
-	iSendQueue.Free();
-	iSendQueue.Init();
-	iNumPacketsInSendQueue = 0;
-	}
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implements the interface to Bca & flow control.
+// 
+//
+
+/**
+ @file
+*/
+
+#include <e32uid.h>
+#include <nifmbuf.h>
+#include <es_ini.h>
+#include <e32svr.h>
+#include <u32hal.h>
+#include "BcaController.h"
+
+//In order not to flow off SPUD everytime we set the default to 1
+const TUint KDefaultBufferSize=1;
+
+#ifdef __EABI__
+// Patch data is used and KMaxTxIPPacketSize and KMaxRxIPPacketSize can be modified to a different value in RawIpNif.iby file
+extern const TInt KMaxSendQueueLen = KDefaultBufferSize;
+extern const TInt KMaxTxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength;
+extern const TInt KMaxRxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength;
+#endif
+
+CBcaController::CBcaController(MControllerObserver& aObserver,
+	CBttLogger* aTheLogger)
+/**
+ * Constructor. 
+ */
+	: iObserver(aObserver),  
+	  iTheLogger(aTheLogger),
+	  iTxFlowControl(EFlowControlOff), 
+	  iTxContextActive(ETrue), 
+	  iSendState(EIdle),
+	  iMaxSendQueueLen(KDefaultBufferSize),
+	  iNumPacketsInSendQueue(0)
+	{
+	iSendQueue.Init();
+	}
+
+
+CBcaController::~CBcaController()
+/**
+ * Destructor.
+ */
+	{
+	iSendQueue.Free();
+	iNumPacketsInSendQueue = 0;
+
+#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
+	delete iIPTagHeader;
+#endif // RAWIP_HEADER_APPENDED_TO_PACKETS
+	}
+
+void CBcaController::BaseConstructL()
+	{
+	_LOG_L1C1(_L8("CBcaController::BaseConstructL"));
+	
+#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
+    iIPTagHeader = new (ELeave) CIPTagHeader(iTheLogger);
+#endif // RAWIP_HEADER_APPENDED_TO_PACKETS
+    
+#if defined (__EABI__)
+    // Default value for queue length
+    iMaxSendQueueLen = KMaxSendQueueLen;
+	// Default value for Tx and Rx packet size
+	iMaxTxPacketSize = KMaxTxIPPacketSize;
+	iMaxRxPacketSize = KMaxRxIPPacketSize;
+#else // WINS
+	// Set default values in case patch is not present in epocrawip.ini
+	iMaxSendQueueLen = KDefaultBufferSize;    
+	iMaxTxPacketSize = KMaxIPPacket + KIPTagHeaderLength;
+	iMaxRxPacketSize = KMaxIPPacket + KIPTagHeaderLength;
+	       
+	// for the emulator process is patched via the epocrawip.ini file
+	UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxSendQueueLen",&iMaxSendQueueLen);
+	UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxTxIPPacketSize",&iMaxTxPacketSize);
+	UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"rawip_KMaxRxIPPacketSize",&iMaxRxPacketSize);
+#endif
+	}
+
+void CBcaController::UpdateInternalFlowFlag(TFlowControl aValue)
+/**
+ *  Updates Internal Flow flag and resumes the data flow if
+ *  necessary.
+ *
+ * @param aValue the new state of iInternalFlow
+ */
+	{
+	_LOG_L1C3(_L8("CBcaController::UpdateInternalFlowFlag[NewValue=%d, iSendState=%d]"),
+		aValue, iSendState);
+
+	if(iTxFlowControl == aValue)
+		{
+		// C32 Sent the same indication signal twice. Nif will ignore it.
+		_LOG_L2C1(_L8("WARNING CBcaController: Received same indication twice"));
+		return;
+		}
+	
+	// Update the flag value.
+	iTxFlowControl = aValue;
+
+	if(iTxFlowControl == EFlowControlOff)
+		{
+		// If the indication received turned flow control off...
+		if (IsTxPossible() && (iSendState == EIdle))
+			{
+			// ... if the NIF is in the EWaiting state
+			// then the data flow can be resumed. 
+			ResumeSending();
+			}
+		}		
+	else
+		{
+		// if the Flow Control is on we can remove all queued write requests
+		EmptySendQueue();
+		}
+	}
+
+void CBcaController::UpdateContextStateFlag(TBool aValue)
+/**
+ *  Updates Context State flag and resumes the data flow if
+ *  necessary.
+ *
+ * @param aValue the new state of iTxContextState
+ */
+	{
+	_LOG_L1C3(_L8("CBcaController::UpdateContextStateFlag[NewValue=%d, OldValue=%d]"),
+		aValue, iTxContextActive);
+	
+	if(iTxContextActive == aValue)
+		{
+		return;
+		}
+
+	// Update the flag value.
+	iTxContextActive = aValue;
+
+	if(iTxContextActive)
+		{
+		// If the PDP context is active and...
+		if (IsTxPossible() && (iSendState == EIdle))
+			{
+			// ... if the NIF is in the EWaiting state
+			// then the data flow can be resumed. 
+			ResumeSending();
+			}
+		}
+	else
+		{
+		// if the PDP context is suspended we can remove all queued write requests
+		EmptySendQueue();
+		}
+	}
+
+TInt CBcaController::Send(RMBufChain& aPdu)
+/**
+ *  This method is called by CRawIPNifMain in order to send a packet down
+ * to the BCA. 
+ *
+ *	@param aPdu a data packet
+ */
+	{
+	_LOG_L1C1(_L8(">>CBcaController::Send"));
+
+	// Check if NIF is shutting down
+	if (iSendState == EShuttingDown)
+		{
+		_LOG_L2C1(_L8("    ERROR: Nif is shutting down"));
+		
+		aPdu.Free();
+
+		return KErrDisconnected;
+		}
+	
+	// check that this packet isnt too big - If it is, we dont want to send it or
+	// add it to our queue
+	if ((aPdu.Length() - aPdu.First()->Length()) > BcaSendBufferLength())
+		{
+		_LOG_L2C1(_L8("Packet is too large - discarding"));
+		_LOG_L1C1(_L8("<<CSender::Send -> Error"));
+
+		aPdu.Free();
+		return KErrArgument;
+		}
+	
+	if (iSendState == ESending)
+		// If this happens, it means that TCP/IP has sent us an IP packet
+		// while we're still sending the previous one. 
+		{
+		// check that the queue isnt full NB. this check should not be needed as when the 
+		// queue becomes full the IP layer shouldnt send any more packets until it is told to
+		if (!IsSendQueueFull())
+			{
+			_LOG_L1C1(_L8("    Sender busy, appending packet to queue"));
+			//We know that flow control is off and context isnt suspended so can add to queue
+			AppendToSendQueue(aPdu);
+			
+			return IsSendQueueFull() ? KStopSending : KContinueSending;
+			}
+			
+		_LOG_L1C1(_L8("    Queue is full, upper layer is still sending packets, potential memory problems."));
+		AppendToSendQueue(aPdu);
+		return KStopSending;
+		}
+
+	// If we have got here then a write isnt currently happening
+	// We dont need to check flow control is off and context isnt suspended as the BCA always
+	// has room for one packet, so send the packet
+
+	if(!IsSendQueueEmpty())
+		{
+		//make sure that we don't change the order of packets!
+		//first send what has already been lined up
+		RMBufChain tmpPdu;
+		_LOG_L1C1(_L8("    Packet removed from queue to send"));
+		RemoveFromSendQueue(tmpPdu);
+		AppendToSendQueue(aPdu);
+		
+		// Update module state
+		_LOG_L2C1(_L8("     set State to ESending"));
+		iSendState = ESending;
+		
+		BcaSend(tmpPdu);
+		}
+	else
+		{
+		// Update module state
+		_LOG_L2C1(_L8("     set State to ESending"));
+		iSendState = ESending;
+		 
+		BcaSend(aPdu);
+		}
+		
+	_LOG_L2C1(_L8("<<CBcaController::Send - return StopSending/ContinueSending"));
+	return IsSendQueueFull() ? KStopSending : KContinueSending;
+	}
+
+void CBcaController::SendComplete()	
+/**
+ *  This method is called after a packet was sent to the board. 
+ *  If allowed by flow contol flags the NIF can signal the TCP/IP
+ *  protocol indicating that is available to send more packets.
+ */
+	{
+	_LOG_L1C1(_L8("CBcaController::SendComplete"));
+	_LOG_L2C1(_L8("     set State to EIdle"));
+	
+	iSendState = EIdle;
+
+	if (IsTxPossible())
+		ResumeSending();
+	}
+
+TBool CBcaController::IsTxPossible()
+/**
+ *  This method returns ETrue if both TX flags are set to ETrue
+ *
+ * @return The Flow control state
+ */
+	{
+	_LOG_L1C3(_L8("CBcaController::IsTxPossible (contextActive %d, flowcontrol %d)"), 
+		iTxContextActive, iTxFlowControl);
+
+	if(iTxContextActive && (iTxFlowControl == EFlowControlOff))
+		return ETrue;
+	else
+		return EFalse;
+	}
+
+void CBcaController::Process(TDesC8& aPdu)
+/**
+ *  This method will pass on the received data to CBttNifMain. 
+ *
+ * @param aPdu a data packet
+ */
+	{
+	_LOG_L1C1(_L8(">>CBcaController::Process"));
+
+	TInt ret;
+
+	// Create a packet object.
+	RMBufPacket packet;
+	TRAP(ret, packet.CreateL(aPdu));
+	if (ret != KErrNone)
+		{
+		// Couldn't create package. Packet will be ignored...
+		_LOG_L1C2(_L8("<<CBcaController::Process couldn't create MBuf [ret=%d]"), ret);
+		return;
+		}
+	else
+		// Package created...
+		{
+#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
+		TUint16 protocolCode = iIPTagHeader->RemoveHeader(packet);
+#else
+		TUint16 protocolCode = 0;
+#endif // RAWIP_HEADER_APPENDED_TO_PACKETS
+
+		packet.Pack();
+		// Process the packet
+		GetObserver().Process(packet, protocolCode);
+		}
+
+	_LOG_L1C1(_L8("<<CBcaController::Process"));
+	}
+
+void CBcaController::ResumeSending()
+/**
+ *  Used to indicate to the TCP/IP protocol layer that the NIF is ready to 
+ *	process more packets.
+ */
+	{
+	_LOG_L1C1(_L8("CBcaIoController::ResumeSending"));
+
+	// If there are still some packets in the queue to be sent, then carry
+	// on sending them.
+	// NB. we only want to send more packets from the queue if we are currently EIdle
+	if (iSendState == EIdle) 
+		{
+		if(!IsSendQueueEmpty())
+			{
+			RMBufChain tmpPdu;
+			_LOG_L1C1(_L8("    Packet removed from queue to send"));
+			RemoveFromSendQueue(tmpPdu);
+			
+			// Update module state
+			_LOG_L2C1(_L8("     set State to ESending"));
+			iSendState = ESending;
+			
+			BcaSend(tmpPdu);
+			}
+		if(iFullQueueFlag && IsSendQueueEmpty())
+			{
+			iObserver.ResumeSending();
+			}
+		}
+	// if iSendState = ESending - do nothing
+	}
+	
+#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS
+void CBcaController::SetType(TUint16 aType)
+	{
+/**
+ *  Used to specify the type of the IP header.
+ */
+ 	_LOG_L1C1(_L8("CBcaController::SetType"));
+ 	
+ 	iIPTagHeader->SetType(aType);	
+	}
+
+void CBcaController::AddHeader(TDes8& aDes)
+/**
+ *  Used to add the IP header to the packet before sending to the BCA.
+ */
+	{
+	_LOG_L1C1(_L8("CBcaController::AddHeader"));
+
+	iIPTagHeader->AddHeader(aDes);
+	}
+
+TUint16 CBcaController::RemoveHeader(RMBufChain& aPdu)
+/**
+ *  Used to remove the IP header from the received the packet before sending to the 
+ *  TCP/IP layer.  
+ * @return The IP header that has been removed from the packet
+ */
+	{
+	_LOG_L1C1(_L8("CBcaController::RemoveHeader"));
+
+	return (iIPTagHeader->RemoveHeader(aPdu));
+	}	
+#endif // RAWIP_HEADER_APPENDED_TO_PACKETS
+
+TBool CBcaController::IsSendQueueEmpty()
+/**
+ *  Indicator of whether the BufferQueue is empty
+ * @return TBool.  ETrue if bufferQueue is emtpy, EFalse if queue is not empty
+ */
+	{
+	return iSendQueue.IsEmpty();
+	}
+	
+TBool CBcaController::IsSendQueueFull()
+/**
+ *  Indicator of whether the BufferQueue is full
+ * @return TBool.  ETrue if bufferQueue is full, EFalse if queue is not full
+ */
+	{    
+	iFullQueueFlag = iNumPacketsInSendQueue >= iMaxSendQueueLen;
+	return iFullQueueFlag;
+	}	
+
+void CBcaController::AppendToSendQueue(RMBufChain& aPdu)
+/**
+ * Appends the packet aPdu to the queue. 
+ * Increments the packet count. Doesn't do error checking.
+ * @param aChain buffer chain to be added
+ */
+	{
+	iSendQueue.Append(aPdu);
+	iNumPacketsInSendQueue++;
+	}
+	
+TBool CBcaController::RemoveFromSendQueue(RMBufChain& aPdu)
+/**
+ * Removes the packet aPdu from the queue. 
+ * Decrements the packet count.
+ * @param aChain buffer chain to be added
+ * @return False if chain is empty
+ */
+	{
+	TBool ret = iSendQueue.Remove(aPdu);
+	if(ret)
+		{
+		iNumPacketsInSendQueue--;
+		}
+	return ret;
+	}
+	
+void CBcaController::EmptySendQueue()
+/**
+ * Removes all the packets from the send queue. Initializes the
+ * send queue and sets the packet count to 0.
+ */
+	{
+	iSendQueue.Free();
+	iSendQueue.Init();
+	iNumPacketsInSendQueue = 0;
+	}