diff -r fc69e1e37771 -r fe8b59ab9fa0 telephonyprotocols/rawipnif/src/BcaIoController.cpp --- a/telephonyprotocols/rawipnif/src/BcaIoController.cpp Mon Mar 15 12:45:06 2010 +0200 +++ b/telephonyprotocols/rawipnif/src/BcaIoController.cpp Wed Mar 31 23:24:02 2010 +0300 @@ -21,12 +21,23 @@ #include #include +#include +#include #include "Constants.h" #include "BcaIoController.h" #include "Sender.h" #include "Receiver.h" +const TUint KDefaultSendQueueSize=5; + +#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 = KDefaultSendQueueSize; +extern const TInt KMaxTxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength; +extern const TInt KMaxRxIPPacketSize = KMaxIPPacket + KIPTagHeaderLength; +#endif + CBcaIoController::CBcaIoController(MControllerObserver& aObserver, CBttLogger* aTheLogger) /** @@ -35,14 +46,17 @@ * @param aObserver Reference to the observer of this state machine * @param aTheLogger The logging object */ - : - CBcaController(aObserver, aTheLogger), - iMBca(NULL), - iSender(NULL), - iReceiver(NULL), - iLoader(NULL) - { - } + : iTheLogger(aTheLogger), + iSendState(EIdle), + iFlowBlocked(EFalse), + iNumPacketsInSendQueue(0), + iObserver(aObserver), + iMBca(NULL), + iSender(NULL), + iReceiver(NULL), + iLoader(NULL) + { + } CBcaIoController* CBcaIoController::NewL(MControllerObserver& aObserver, CBttLogger* aTheLogger) /** @@ -53,25 +67,49 @@ * @param aTheLogger The logging object * @return A newly constructed CBcaIoController object */ - { - CBcaIoController* self = new (ELeave) CBcaIoController(aObserver, aTheLogger); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } + { + CBcaIoController* self = new (ELeave) CBcaIoController(aObserver, aTheLogger); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } void CBcaIoController::ConstructL() /** * Second-phase constructor. Creates all the state objects it owns. */ - { - _LOG_L1C1(_L8("CBcaIoController::ConstructL")); - BaseConstructL(); - iSender = CSender::NewL(*this, iTheLogger, iMaxTxPacketSize); - iReceiver = CReceiver::NewL(*this, iTheLogger, iMaxRxPacketSize); - iLoader = new (ELeave) CBcaControl(*this, iTheLogger); - } + { + _LOG_L1C1(_L8("CBcaIoController::ConstructL")); + +#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 = KDefaultSendQueueSize; + 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 + + // end note + + iSender = CSender::NewL(*this, iTheLogger, iMaxTxPacketSize); + iReceiver = CReceiver::NewL(*this, iTheLogger, iMaxRxPacketSize); + iLoader = new (ELeave) CBcaControl(*this, iTheLogger); + } CBcaIoController::~CBcaIoController() @@ -79,10 +117,16 @@ * Destructor. */ { + iSendQueue.Free(); + iNumPacketsInSendQueue = 0; + delete iReceiver; delete iSender; delete iLoader; - + +#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS + delete iIPTagHeader; +#endif // RAWIP_HEADER_APPENDED_TO_PACKETS } /** sets the BCA Stack name @@ -103,7 +147,7 @@ { _LOG_L1C1(_L8("CBcaIoController::StartL is called.")); - InitialiseBcaL(); + iLoader->StartLoadL(); } void CBcaIoController::Stop(TInt aError) @@ -118,7 +162,7 @@ //Stop all the active objects iReceiver->Cancel(); - if(GetSendState() == ESending) + if (iSendState == ESending) { iSender->Cancel(); } @@ -129,61 +173,269 @@ iLoader->ShutdownBca(aError); } -void CBcaIoController::InitialiseBcaL() -/** - * Load & Initialise Bca. - */ - { - _LOG_L1C1(_L8("<StartLoadL(); - } -void CBcaIoController::BcaProcess(TDesC8& aPdu) +ESock::MLowerDataSender::TSendResult CBcaIoController::Send(RMBufChain& aPdu) /** - * This method will pass on the received data to CRawIPNifMain. + * This method is called by CRawIPFlow in order to send a packet down + * to the BCA. * - * @param aPdu a data packet + * @param aPdu a data packet */ - { - _LOG_L1C1(_L8(">>CBcaIoController::Process")); + { + _LOG_L1C1(_L8(">>CBcaIoController::Send")); + + // Check if flow is shutting down + if (iSendState == EShuttingDown) + { + _LOG_L2C1(_L8(" ERROR: Nif is shutting down")); + + // when the flow is destroyed the memory for this packet will be + // cleaned up - just tell the layers above to stop sending. + aPdu.Free(); + + return ESock::MLowerDataSender::ESendBlocked; + } + + // 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()) > iMaxTxPacketSize) + { + _LOG_L2C1(_L8("Packet is too large - discarding")); + _LOG_L1C1(_L8("< Error")); - Process(aPdu); + // in debug panic - this should not happen, MTU on the uplink should + // be strictly enforced + __ASSERT_DEBUG(ETrue,Panic(KFlowInvalidULPacketSize)); + + aPdu.Free(); + + // may be counter intuitive, however the only options here are either + // send accepted or blocked (MLowerDataSender). + + _LOG_L2C1(_L8("<Send(aPdu); + } -void CBcaIoController::BcaSend(RMBufChain& aPdu) + // if our send queue isn't full, then the send is accepted + // otherwise, block this flow until we have room for the next + // packet + + _LOG_L2C1(_L8("<>CBcaIoController::SendComplete")); + + // if we've been blocked while in the middle of a + // send - don't continue sending, this will happen + // when the flow is resumed. + + iSendState = EIdle; - iSender->Send(aPdu); - } + // are we available to transmit? + + if (iFlowBlocked == EFalse) + { + // flow transmit is on + + TBool resumeSending = EFalse; + + // if the queue is full, it means that while a packet was + // outstanding in BCA, we've filled up our send queue and + // informed the upper layers to stop sending. + + if (IsSendQueueFull()) + { + resumeSending = ETrue; + } + + // if the queue has anything inside it, we need to send the + // first packet in the queue. note: the resumeSending check is to + // short circuit this so we don't check the queue length twice + // in the case that it is full + + if ((resumeSending) || (!IsSendQueueEmpty())) + { + iSendState = ESending; + + RMBufChain tmpPdu; + _LOG_L1C1(_L8(" Packet removed from queue to send")); + RemoveFromSendQueue(tmpPdu); + + // Update module state + _LOG_L2C1(_L8(" set State to ESending")); + + iSender->Send(tmpPdu); + + // if the queue was full, again, we told the upper layers + // to stop sending, we need to resume this flow. order is + // important as we don't want to get a packet before we've + // given one to BCA to send. + if (resumeSending) + { + iObserver.ResumeSending(); + } + } + } + + _LOG_L1C1(_L8("<>CBcaIoController::ResumeSending")); -TInt CBcaIoController::BcaSendBufferLength() - { - return iSender->SendBufferLength(); - } + // allows for normal SendComplete behaviour if there is + // a packet outstanding with BCA + iFlowBlocked = EFalse; + + // If the send state is idle, then there isn't a packet + // outstanding, check the send queue to see if there are + // packets to send. + + if (iSendState == EIdle) + { + // flow transmit is on + + TBool resumeSending = EFalse; + + if (IsSendQueueFull()) + { + resumeSending = ETrue; + } + + // if the queue has anything inside it, we need to send the + // first packet in the queue. note: the resumeSending check is to + // short circuit this so we don't check the queue length twice + // in the case that it is full + + if ((resumeSending) || (!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; + + iSender->Send(tmpPdu); + + // if the queue was full, again, we told the upper layers + // to stop sending, we need to resume this flow. order is + // important as we don't want to get a packet before we've + // given one to BCA to send. + if (resumeSending) + { + iObserver.ResumeSending(); + } + } + } + + _LOG_L1C1(_L8("<SetType(aType); + } + +void CBcaIoController::AddHeader(TDes8& aDes) +/** + * Used to add the IP header to the packet before sending to the BCA. */ - { - _LOG_L1C1(_L8("CBcaController::SendComplete")); + { + _LOG_L1C1(_L8("CBcaController::AddHeader")); + + iIPTagHeader->AddHeader(aDes); + } - SendComplete(); - } +TUint16 CBcaIoController::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 + + CBcaControl::CBcaControl(CBcaIoController& aObserver, CBttLogger* aTheLogger) /** * Constructor. Performs standard active object initialisation.