// Copyright (c) 2004-2010 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.+ −
// + −
//+ −
+ −
/**+ −
@file BcaIoController.cpp+ −
*/+ −
+ −
+ −
#include "OstTraceDefinitions.h"+ −
#ifdef OST_TRACE_COMPILER_IN_USE+ −
#include "BcaIoControllerTraces.h"+ −
#endif+ −
+ −
#include <e32uid.h>+ −
#include <nifmbuf.h>+ −
#include <e32svr.h>+ −
#include <u32hal.h>+ −
+ −
#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)+ −
/**+ −
* Constructor. + −
*+ −
* @param aObserver Reference to the observer of this state machine+ −
*/+ −
: iSendState(EIdle),+ −
iFlowBlocked(EFalse),+ −
iNumPacketsInSendQueue(0),+ −
iObserver(aObserver),+ −
iMBca(NULL),+ −
iSender(NULL),+ −
iReceiver(NULL),+ −
iLoader(NULL) + −
{+ −
}+ −
+ −
CBcaIoController* CBcaIoController::NewL(MControllerObserver& aObserver)+ −
/**+ −
* Two-phase constructor. Creates a new CBcaIoController object, performs + −
* second-phase construction, then returns it.+ −
*+ −
* @param aObserver The observer, to which events will be reported+ −
* @return A newly constructed CBcaIoController object+ −
*/+ −
{+ −
CBcaIoController* self = new (ELeave) CBcaIoController(aObserver);+ −
CleanupStack::PushL(self);+ −
self->ConstructL();+ −
CleanupStack::Pop(self);+ −
return self;+ −
}+ −
+ −
void CBcaIoController::ConstructL()+ −
/**+ −
* Second-phase constructor. Creates all the state objects it owns.+ −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_CONSTRUCTL_1, "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, iMaxTxPacketSize);+ −
iReceiver = CReceiver::NewL(*this, iMaxRxPacketSize);+ −
iLoader = new (ELeave) CBcaControl(*this);+ −
}+ −
+ −
+ −
+ −
CBcaIoController::~CBcaIoController()+ −
/**+ −
* 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+ −
+ −
* @param aBcaStack Text composed of bca stack and next bca names+ −
*/ + −
void CBcaIoController::SetBcaStackAndName(const TDesC& aBcaStack, const TDesC& aBcaName)+ −
{+ −
iBcaName.Set(aBcaName);+ −
iBcaStack.Set(aBcaStack);+ −
}+ −
+ −
+ −
void CBcaIoController::StartL()+ −
/**+ −
* Used to kick off the initialisation for this module+ −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_STARTL_1, "CBcaIoController::StartL is called.");+ −
+ −
iLoader->StartLoadL();+ −
}+ −
+ −
void CBcaIoController::Stop(TInt aError)+ −
/**+ −
* Used to shutdown this module. This will cancel all the outstanding + −
* requests on the active objects owned by this module and shutdown.+ −
* @param aError the passed in error code as to why Stop has been called+ −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_STOP_1, "CBcaIoController::Stop is called.");+ −
+ −
//Stop all the active objects+ −
iReceiver->Cancel();+ −
+ −
if (iSendState == ESending)+ −
{+ −
iSender->Cancel();+ −
}+ −
+ −
// Update module state+ −
SendState(EShuttingDown);+ −
+ −
iLoader->ShutdownBca(aError); + −
}+ −
+ −
+ −
ESock::MLowerDataSender::TSendResult CBcaIoController::Send(RMBufChain& aPdu)+ −
/**+ −
* This method is called by CRawIPFlow in order to send a packet down+ −
* to the BCA. + −
*+ −
* @param aPdu a data packet+ −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_1, "<<CBcaIoController::Send");+ −
+ −
// Check if flow is shutting down+ −
if (iSendState == EShuttingDown)+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_2, " 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)+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_3, "Packet is too large - discarding");+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_4, "<<CSender::Send -> Error");+ −
+ −
// 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).+ −
+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_5, "<<CBcaIoController::Send - return ContinueSending");+ −
return ESock::MLowerDataSender::ESendAccepted;+ −
}+ −
+ −
// transmit flow control.+ −
if (iFlowBlocked)+ −
{+ −
// Transmit is off for this flow - we must have received a block+ −
// message from our control. append this message to the queue+ −
// and tell the layer above it to kindly stop sending.+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_6, " Sender blocked, appending packet to queue");+ −
+ −
AppendToSendQueue(aPdu);+ −
+ −
// may be a bit counter-intuitive, however, even if the flow is blocked+ −
// there is no reason not to ask for more data as long as our send+ −
// queue isn't full.+ −
+ −
if (IsSendQueueFull())+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_7, "<<CBcaIoController::Send - return StopSending");+ −
return ESock::MLowerDataSender::ESendBlocked;+ −
}+ −
else+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_8, "<<CBcaIoController::Send - return ContinueSending");+ −
return ESock::MLowerDataSender::ESendAccepted; + −
}+ −
}+ −
+ −
// transmit is on for this flow. send a packet or queue it+ −
// if we're already sending one.+ −
+ −
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. + −
{ + −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_9, " Sender busy, appending packet to queue");+ −
AppendToSendQueue(aPdu);+ −
+ −
if (IsSendQueueFull())+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_10, "<<CBcaIoController::Send - return StopSending");+ −
return ESock::MLowerDataSender::ESendBlocked;+ −
}+ −
}+ −
else+ −
{+ −
// if we're idle, then we must not be sending. If we're not idle+ −
// then the SendComplete() will handle sending any additional + −
// packets that might have been queued onto the send queue.+ −
+ −
// Update module state+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_11, " set State to ESending");+ −
iSendState = ESending;+ −
+ −
iSender->Send(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+ −
+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SEND_12, "<<CBcaIoController::Send - return ContinueSending");+ −
+ −
return ESock::MLowerDataSender::ESendAccepted;+ −
}+ −
+ −
void CBcaIoController::SendComplete()+ −
/**+ −
* A packet has finished sending - check to see if we need+ −
* to process more packets.+ −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SENDCOMPLETE_1, ">>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;+ −
+ −
// 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;+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SENDCOMPLETE_2, " Packet removed from queue to send");+ −
RemoveFromSendQueue(tmpPdu);+ −
+ −
// Update module state+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SENDCOMPLETE_3, " 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();+ −
}+ −
}+ −
}+ −
+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SENDCOMPLETE_4, "<<CBcaIoController::SendComplete");+ −
}+ −
+ −
+ −
void CBcaIoController::ResumeSending()+ −
/**+ −
* Flow is being unblocked this will resume sending.+ −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_RESUMESENDING_1, ">>CBcaIoController::ResumeSending");+ −
+ −
// 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;+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_RESUMESENDING_2, " Packet removed from queue to send");+ −
RemoveFromSendQueue(tmpPdu);+ −
+ −
// Update module state+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_RESUMESENDING_3, " 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();+ −
}+ −
}+ −
}+ −
+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_RESUMESENDING_4, "<<CBcaIoController::ResumeSending");+ −
}+ −
+ −
#ifdef RAWIP_HEADER_APPENDED_TO_PACKETS+ −
void CBcaIoController::SetType(TUint16 aType)+ −
{+ −
/**+ −
* Used to specify the type of the IP header.+ −
*/+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_SETTYPE_1, "CBcaController::SetType");+ −
+ −
iIPTagHeader->SetType(aType); + −
}+ −
+ −
void CBcaIoController::AddHeader(TDes8& aDes)+ −
/**+ −
* Used to add the IP header to the packet before sending to the BCA.+ −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_ADDHEADER_1, "CBcaController::AddHeader");+ −
+ −
iIPTagHeader->AddHeader(aDes);+ −
}+ −
+ −
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+ −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCAIOCONTROLLER_REMOVEHEADER_1, "CBcaController::RemoveHeader");+ −
+ −
return (iIPTagHeader->RemoveHeader(aPdu));+ −
} + −
#endif // RAWIP_HEADER_APPENDED_TO_PACKETS+ −
+ −
+ −
CBcaControl::CBcaControl(CBcaIoController& aObserver)+ −
/**+ −
* Constructor. Performs standard active object initialisation.+ −
*+ −
* @param aObserver Reference to the observer of this state machine+ −
*/+ −
: CActive(EPriorityStandard), + −
iObserver(aObserver), + −
iMBca(NULL),+ −
iState(EIdling),+ −
iError(KErrNone)+ −
+ −
{+ −
CActiveScheduler::Add(this);+ −
}+ −
+ −
CBcaControl::~CBcaControl()+ −
/**+ −
* Destructor.+ −
*/+ −
{+ −
Cancel();+ −
if(iMBca)+ −
{+ −
//If the Bca is still open, close it+ −
if(EBcaOpened == iState)+ −
{+ −
iMBca->Close();+ −
}+ −
//delete the BCA instance+ −
iMBca->Release(); + −
}+ −
// Library will be Closed when iBcaDll is destroyed.+ −
}+ −
+ −
void CBcaControl::RunL()+ −
/**+ −
* Called after request is completed. + −
* + −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_1, "CBcaControl::RunL() called");+ −
switch (iState)+ −
{+ −
//in this state, Ioctl is called to set IAP ID, check the result of+ −
// Ioctl, then either set the BCA stack with another Ioctl call, + −
// open the BCA (if there's no BCA stack to set), or stop the NIF.+ −
case EIdling:+ −
{+ −
if(iStatus == KErrNone || iStatus == KErrNotSupported)+ −
{+ −
if(iStatus == KErrNotSupported)+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_2, "This BCA does not support IAPID set");+ −
}+ −
else+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_3, "This BCA supports IAPID set");+ −
}+ −
+ −
TPtrC bcaStack = iObserver.BcaStack();+ −
if(bcaStack.Length())+ −
{+ −
TBuf8<KMaxName> remainingBcaStack8;+ −
remainingBcaStack8.Copy(bcaStack);+ −
iMBca->Ioctl(iStatus, KBcaOptLevelGeneric,KBCASetBcaStack,remainingBcaStack8);+ −
}+ −
else+ −
{+ −
TRequestStatus* statusPtr=&iStatus;+ −
User::RequestComplete(statusPtr,KErrNone);+ −
}+ −
iState = EIAPSet;+ −
SetActive(); + −
}+ −
else+ −
{+ −
OstTraceDef1(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_4, "ERROR in BCA IAPID set = %d", iStatus.Int());+ −
iObserver.Stop(iStatus.Int());+ −
}+ −
+ −
break;+ −
}+ −
+ −
//in this case, we receive the result of Ioctl call to set Bca Stack.+ −
// Check the result of Ioctl, then Open the Bca or stop the NIF+ −
case EIAPSet:+ −
{+ −
if(iStatus == KErrNotSupported || iStatus == KErrNone)+ −
{+ −
if(iStatus == KErrNotSupported)+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_5, "This BCA does not support BCA stacking");+ −
}+ −
else+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_6, "This BCA supports BCA stacking");+ −
}+ −
iMBca->Open(iStatus, iObserver.Port());+ −
iState = EBcaStackSet;+ −
SetActive(); + −
}+ −
else+ −
{+ −
OstTraceDef1(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_7, "ERROR in BCA stack set = %d", iStatus.Int());+ −
iObserver.Stop(iStatus.Int());+ −
}+ −
break;+ −
}+ −
+ −
//in this state, BCA Open is called. Checks the result of Open.+ −
// If it is successful,then start the NIF. Otherwise stops the NIF.+ −
case EBcaStackSet:+ −
{+ −
if(iStatus != KErrNone && iStatus != KErrAlreadyExists)+ −
{+ −
OstTraceDef1(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_8, "ERROR in BCA Open = %d", iStatus.Int());+ −
iObserver.Stop(iStatus.Int());+ −
}+ −
else+ −
{+ −
iState = EBcaOpened;+ −
//Activate the receiver Active Object+ −
iObserver.Receiver().StartListening();+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_9, "CBcaIoController Is Initialised");+ −
TRAPD(err, iObserver.GetObserver().InitialiseL(MRawIPObserverBase::EBcaController,KErrNone));+ −
if(err != KErrNone)+ −
{+ −
OstTraceDef1(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_10, "ERROR in BCA Open Initialise observer = %d", err);+ −
iObserver.Stop(err);+ −
}+ −
}+ −
break;+ −
}+ −
+ −
//in this state, BCA is Shutdown, shutdown the NIF.+ −
case EClosing:+ −
{+ −
// linklayer shutdown+ −
iState = EIdling;+ −
iObserver.GetObserver().ShutDown(MControllerObserver::EBcaController, iError);+ −
break;+ −
}+ −
// Wrong state.+ −
default:+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_11, "ERROR CBcaControl::RunL(): Unknown state");+ −
OstTraceDefExt2(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_RUNL_12, "PANIC: %S %d", KNifName, KBcaUnkownState);+ −
User::Panic(KNifName, KBcaUnkownState);+ −
break;+ −
}+ −
}+ −
+ −
}+ −
+ −
void CBcaControl::DoCancel()+ −
/**+ −
* cancel active request. + −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_DOCANCEL_1, "CBcaControl::DoCancel called.");+ −
OstTraceDef1(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_DOCANCEL_2, "iState value is %d", iState);+ −
switch (iState)+ −
{+ −
case EIdling:+ −
case EIAPSet:+ −
case EBcaStackSet:+ −
if(iMBca)+ −
{+ −
iMBca->CancelIoctl();+ −
}+ −
iState = EIdling;+ −
break;+ −
case EClosing:+ −
iState = EIdling; + −
break; + −
default:+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_DOCANCEL_3, "ERROR CBcaControl::DoCancel(): Unknown state");+ −
OstTraceDefExt2(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_DOCANCEL_4, "PANIC: %S %d", KNifName, KBcaUnkownState);+ −
User::Panic(KNifName, KBcaUnkownState);+ −
break;+ −
}+ −
}+ −
+ −
void CBcaControl::StartLoadL()+ −
/**+ −
* This method loads the C32BCA library and uses Ioctl to set the Bca iIapId. + −
*/+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_STARTLOADL_1, "CBcaControl::StartLoad");+ −
+ −
//iMBca should not be initialized at this point+ −
__ASSERT_DEBUG(!iMBca,Panic(KBcaAlreadyExists));+ −
+ −
//We don't expect iMBca here, but if it occurs, we delete previous BCA Instance+ −
if(iMBca)+ −
{+ −
//If the state is still "open", close it first+ −
if(EBcaOpened == iState)+ −
{+ −
iMBca->Close();+ −
}+ −
iMBca->Release();+ −
}+ −
+ −
// Loads Bca Dll and creates a Bca instance;+ −
User::LeaveIfError(iBcaDll.iObj.Load(iObserver.BcaName()));+ −
+ −
TNewBcaFactoryL newBcaFactoryProcL = (TNewBcaFactoryL)iBcaDll.iObj.Lookup(1);+ −
if (NULL == newBcaFactoryProcL)+ −
{+ −
OstTraceDef1(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_STARTLOADL_2, "Library entry point found error %d", KErrBadLibraryEntryPoint);+ −
User::Leave(KErrBadLibraryEntryPoint); + −
}+ −
+ −
MBcaFactory* bcaFactory = (*newBcaFactoryProcL)();+ −
+ −
if(!bcaFactory)+ −
{+ −
OstTraceDef1(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_STARTLOADL_3, "BcaFactory creation error %d", KErrCompletion);+ −
User::Leave(KErrCompletion); + −
}+ −
CleanupReleasePushL(*bcaFactory);+ −
+ −
iMBca = bcaFactory->NewBcaL();+ −
CleanupStack::PopAndDestroy(bcaFactory);+ −
+ −
iObserver.SetBca(iMBca); //Pass BCA pointer.+ −
+ −
TPckg<TUint32> aOpt(iObserver.IapId());+ −
iMBca->Ioctl(iStatus,KBcaOptLevelGeneric,KBCASetIapId,aOpt);+ −
+ −
iState = EIdling;+ −
SetActive();+ −
}+ −
+ −
+ −
void CBcaControl::ShutdownBca(TInt aError)+ −
/**+ −
* Bca Shutdown.+ −
+ −
* @param aError the error code to shutdown the NIF. + −
*/+ −
{+ −
__ASSERT_DEBUG(iMBca,Panic(KBcaNotExist));+ −
Cancel();+ −
+ −
//We should only call shutdown or close if we have successfully opened a BCA Channel+ −
if((iMBca) && (EBcaOpened == iState))+ −
{+ −
if(aError == KErrConnectionTerminated )+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_SHUTDOWNBCA_1, "This is an emergency shutdown, it kills the NIF immediately.");+ −
// It is a emergency shutdown, it kills the NIF immediately.+ −
iMBca->Close();+ −
iState = EIdling;+ −
iObserver.GetObserver().ShutDown(MControllerObserver::EBcaController, aError);+ −
}+ −
else+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_SHUTDOWNBCA_2, "This is a graceful termination which takes a while.");+ −
//It is a graceful termination which takes a while.+ −
iError = aError;+ −
iState = EClosing;+ −
iMBca->Shutdown(iStatus);+ −
SetActive(); + −
}+ −
}+ −
else //nothing to shutdown, just notify linklayer down.+ −
{+ −
OstTraceDef0(OST_TRACE_CATEGORY_DEBUG, TRACE_INTERNALS, CBCACONTROL_SHUTDOWNBCA_3, "Bca is not initialized or opened, bring the linklayer down");+ −
iState = EIdling;+ −
iObserver.GetObserver().ShutDown(MControllerObserver::EBcaController, aError);+ −
}+ −
+ −
}+ −
+ −
/** Panic function for RawIpNif + −
+ −
* @param aPanic panic code */+ −
void Panic(TRawIPNifPanic aPanic)+ −
{+ −
User::Panic(KNifName,aPanic);+ −
}+ −
+ −