diff -r 000000000000 -r af10295192d8 linklayercontrol/networkinterfacemgr/netcfgext/src/netcfgextnbase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linklayercontrol/networkinterfacemgr/netcfgext/src/netcfgextnbase.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,842 @@ +// Copyright (c) 2003-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 generic base for NIFMAN side of configuration daemon +// +// + +/** + @file NIFConfigurationControl.cpp + @internalTechnology +*/ + +#include "networkconfigextensionbase.h" +#include +#include +#include +#include + + +#ifdef _DEBUG +// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module +// (if it could happen through user error then you should give it an explicit, documented, category + code) +_LIT(KSpecAssert_NifManNetCfgExtn, "NifManNetCfgExtn"); +#endif + +_LIT(KIAPId, "IAP\\Id"); +_LIT(KIAPNetwork, "IAP\\IAPNetwork"); + + +/** + ADeletionNotifier +*/ +ADeletionNotifier::~ADeletionNotifier() + { + iDeletionListener->NotifyDeletionL(this); + } + +/** + ADeferredDeletion +*/ +void ADeferredDeletion::ListenForObjectDeletionL(ADeletionNotifier */*aDelete*/) + { + iDeletionObjectCount++; + } + +EXPORT_C void ADeferredDeletion::DeleteThis() + { + iDeleteWhenAllObjectsDeleted = ETrue; + if (iDeletionObjectCount == 0) + { + delete this; + } + } + +EXPORT_C void ADeferredDeletion::NotifyDeletionL(ADeletionNotifier */*aDelete*/) + { + iDeletionObjectCount--; + if (iDeleteWhenAllObjectsDeleted && iDeletionObjectCount == 0) + { + DeleteThis(); + } + } + +NONSHARABLE_CLASS(CAsynchDaemonCancel) : public CActive, public ADeletionNotifier +{ +public: + CAsynchDaemonCancel(ADeferredDeletion* aDeletionListener) : + CActive(EPriorityStandard), ADeletionNotifier(aDeletionListener) + { + } + + void AsyncDelete(); + + void CancelControl(RConfigDaemon& aConfigDaemon, TBool aDeleteOnCompletion); + void CancelControl(RConfigDaemon& aConfigDaemon, TInt aOpMask, TBool aDeleteOnCompletion); + +protected: + virtual void RunL(); + virtual void DoCancel(); + +protected: + TBool iDeleteOnCompletion; + }; + +NONSHARABLE_CLASS(CNifDaemonProgress) : public CActive, public ADeletionNotifier, public ADeferredDeletion +/** + * Active object class used by CNetworkConfigExtensionBase to maintain a persistent + * ProgressNotification call against the daemon. Delete this object only using the + * AsyncDelete method. + * + * @internalComponent + */ + { +public: + static CNifDaemonProgress* NewL(RConfigDaemon& aConfigDaemon, CNetworkConfigExtensionBase* aProgressDest, ADeferredDeletion* aDeletionListener); + void ProgressNotification(); + void AsyncDelete(); + void DeleteThis(); + void CancelControl(); + +protected: + void RunL(); + void DoCancel(); + + // This is protectde so that you MUST use AsyncDelete. + virtual ~CNifDaemonProgress() {}; + +private: + + void ConstructL(); + CNifDaemonProgress(RConfigDaemon& aConfigDaemon, CNetworkConfigExtensionBase* aProgressDest, ADeferredDeletion* aDeletionListener); + /** Reference to the configuration daemon interface. */ + RConfigDaemon& iConfigDaemon; + /** Used to asynchrounously cancel any outstanding request on iConfigDaemon so that esock is never blocked. */ + CAsynchDaemonCancel* iAsynchDaemonCancel; + /** The target for progress notifications. */ + CNetworkConfigExtensionBase* iProgressDest; + /** Stores the progress notification. */ + TDaemonProgressBuf iProgressBuf; + /** If ETrue, the object should delete itself when the outstanding request completes. */ + TBool iDeleteOnCompletion; + }; + +void CAsynchDaemonCancel::AsyncDelete() +/** + * Delete the instance of CAsynchDaemonCancel safely. + * + * @internalComponent + */ + { + if (IsActive()) + iDeleteOnCompletion = ETrue; + else + delete this; + } + +void CAsynchDaemonCancel::DoCancel() + {//nothing to do + } + +void CAsynchDaemonCancel::CancelControl(RConfigDaemon& aConfigDaemon, TBool aDeleteOnCompletion) + { + if (!IsActive()) + { + __ASSERT_DEBUG(!IsAdded(), User::Panic(KSpecAssert_NifManNetCfgExtn, 1)); + CActiveScheduler::Add(this); + aConfigDaemon.Cancel(iStatus); + SetActive(); + } + iDeleteOnCompletion = aDeleteOnCompletion; + } + +void CAsynchDaemonCancel::CancelControl(RConfigDaemon& aConfigDaemon, TInt aOpMask, TBool aDeleteOnCompletion) +/** + * CancelControl - Asynchronously cancels the last server request according to aOpMask. + * + * @internalComponent + */ + { + if (!IsActive()) + { + __ASSERT_DEBUG(!IsAdded(), User::Panic(KSpecAssert_NifManNetCfgExtn, 2)); + CActiveScheduler::Add(this); + aConfigDaemon.Cancel(aOpMask,iStatus); + SetActive(); + } + iDeleteOnCompletion = aDeleteOnCompletion; + } + +void CAsynchDaemonCancel::RunL() + { + if ( iDeleteOnCompletion ) + { + delete this; + } + else + { + Deque(); + } + } + +CNifDaemonProgress* CNifDaemonProgress::NewL(RConfigDaemon& aConfigDaemon, CNetworkConfigExtensionBase* aProgressDest, ADeferredDeletion* aDeletionListener) +/** + * Standard NewL for CNifDaemonProgress. + * + * @internalComponent + * + * @param aConfigDaemon Daemon client to be used. + * @param aProgressDest Destination for progress notifications. + * @leave KErrNoMemory if there is insufficient heap. + */ + { + CNifDaemonProgress* pDaemonProgress = new(ELeave)CNifDaemonProgress(aConfigDaemon, aProgressDest, aDeletionListener); + CleanupStack::PushL(pDaemonProgress); + pDaemonProgress->ConstructL(); + CleanupStack::Pop(pDaemonProgress); + return pDaemonProgress; + } + +void CNifDaemonProgress::DeleteThis() + { + if (iAsynchDaemonCancel) + { + iAsynchDaemonCancel->AsyncDelete(); + iAsynchDaemonCancel = NULL; + } + ADeferredDeletion::DeleteThis(); + } + +void CNifDaemonProgress::ConstructL() +/** + * Standard ConstructL for CNifDaemonProgress. + * + * @internalComponent + * + * @leave KErrNoMemory if there is insufficient heap. + */ + { + iAsynchDaemonCancel = new(ELeave)CAsynchDaemonCancel(this); + } + +CNifDaemonProgress::CNifDaemonProgress( + RConfigDaemon& aConfigDaemon, + CNetworkConfigExtensionBase* aProgressDest, + ADeferredDeletion* aDeletionListener) : + CActive(EPriorityStandard), + ADeletionNotifier(aDeletionListener), + iConfigDaemon(aConfigDaemon), + iAsynchDaemonCancel(NULL), + iProgressDest(aProgressDest), + iDeleteOnCompletion(EFalse) +/** + * Construct the progress active object. Adds the active object to the scheduler and + * issues the asynchronous call. + * + * @internalComponent + * + * @param aConfigDaemon Daemon client to be used. + * @param aProgressDest Destination for progress notifications. + */ + { + CActiveScheduler::Add(this); + ProgressNotification(); + } + +void CNifDaemonProgress::ProgressNotification() +/** + * Issues the asynchronous progress notification request. + * + * @internalComponent + */ + { + iConfigDaemon.ProgressNotification(iProgressBuf, iStatus); + SetActive(); + } + +void CNifDaemonProgress::RunL() +/** + * Indicates that a progress notification was received. + * The progress info will be found in iProgressBuf. + * + * @internalComponent + */ + { + if (iDeleteOnCompletion) + { + // if iDeleteOnCompletion is true, we are to delete ourselves + __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::RunL - Deleting ourselves.")); + DeleteThis(); + } + else if (iStatus.Int() == KErrNone) + { + // We successfully got a progress notification. Pass it + // on the the target and re-issue the request. + __FLOG_STATIC1(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::RunL - Successfully received progress notification %d. Re-issuing request."),iProgressBuf().iStage); + iProgressDest->DoOnDaemonProgress(iProgressBuf().iStage, iProgressBuf().iError); + ProgressNotification(); + } + else if (iStatus.Int() == KErrNotReady) + { + // The daemon is starting-up. Re-issue the request. + __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::RunL - Progress notification. Waiting for server to start.")); + ProgressNotification(); + } + else + { + // We failed to get a progress notification. + // The daemon either does not support this request, + // has exited or has died. Do not issue another request. + // We'll get into a tight loop if we do. + __FLOG_STATIC1(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::RunL - Failed to get progress notification from daemon. The error was %d"),iStatus.Int()); + } + } + +void CNifDaemonProgress::AsyncDelete() +/** + * Cancels any outstanding progress notification and optionally + * the instance of CNifDaemonProgress asynchronously to avoid + * potential deadlock in Esock. + * + * @internalComponent + */ + { + if (IsActive()) + { + __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNifDaemonProgress::AsyncDelete - Waiting for CancelControl to complete")); + iDeleteOnCompletion = ETrue; + CancelControl(); + } + else + { + DeleteThis(); + } + } + +void CNifDaemonProgress::CancelControl() +/** + * Cancels any outstanding progress asynchronously to avoid + * potential deadlock in Esock. + * + * @internalComponent + */ + { + if (IsActive()) + { + iAsynchDaemonCancel->CancelControl(iConfigDaemon, KConfigDaemonOpMaskProgress, iDeleteOnCompletion); + if (iDeleteOnCompletion) + iAsynchDaemonCancel = NULL; + } + } + +void CNifDaemonProgress::DoCancel() +/** + * Standard active object DoCancel. + * + * @internalComponent + */ + { + // DoCancel() is only used by Cancel(), which is can not be + // used as it will block the ESOCK thread. + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_NifManNetCfgExtn, 3)); + } + +CNetworkConfigExtensionBase* CNetworkConfigExtensionBase::NewL( TAny* aMNifIfNotify ) + { + MNifIfNotify* nifIfNotify = reinterpret_cast(aMNifIfNotify); + CNetworkConfigExtensionBase* pDaemon = new(ELeave)CNetworkConfigExtensionBase( *nifIfNotify ); + CleanupStack::PushL(pDaemon); + pDaemon->ConstructL(); + CleanupStack::Pop(pDaemon); + return pDaemon; + } + +EXPORT_C void CNetworkConfigExtensionBase::ConstructL() + { + __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNetworkConfigExtensionBase::ConstructL")); + iAsynchDaemonCancel = new(ELeave)CAsynchDaemonCancel(this); + } + +EXPORT_C void CNetworkConfigExtensionBase::ConfigureNetworkL() +/** +ConfigureNetworkL - starts a daemon and issues configuration request +@internalTechnology +@version 0.02 +**/ + { + __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNetworkConfigExtensionBase::ConfigureNetworkL")); + //it could access directly CNifAgentRef::ConnectionInfo but i don't want the class be + //CNifAgentRef dependent + __ASSERT_DEBUG(iMessage.IsNull(), User::Panic(KSpecAssert_NifManNetCfgExtn, 4)); + + User::LeaveIfError(iNifIfNotify->ReadInt(KIAPId(), iConnectionInfoBuf().iIapId)); + User::LeaveIfError(iNifIfNotify->ReadInt(KIAPNetwork(), iConnectionInfoBuf().iNetId)); + //this is the same read as in CNifConfigurationControl::NewL we do the read rather than storing the + //server name since the db access should really provide an efficient access to the settings + //already selected by NETCON + TBuf serverName; /*100 bytes if unicode*/ + User::LeaveIfError(iNifIfNotify->ReadDes(TPtrC(SERVICE_CONFIG_DAEMON_NAME), serverName)); + // safe to pass stack var here, as its copied down the track... + + // For security reasons, ensure that the server name has the "!" prefix - only protected + // servers should be involved with Network Configuration. + + _LIT(KExclamationMark, "!"); + if (serverName.Left(1).Compare(KExclamationMark()) != 0) + serverName.Insert(0,KExclamationMark()); + + __ASSERT_DEBUG(!ipStartServer, User::Panic(KSpecAssert_NifManNetCfgExtn, 5)); + DoOnGenericProgress(KConfigDaemonLoading, KErrNone); + ipStartServer = new(ELeave)CStartServer(iConfigDaemon, iConfigDaemon.Version(), 10); + ipStartServer->Connect(serverName, iStatus); + SetActive(); + } + +EXPORT_C void CNetworkConfigExtensionBase::LinkLayerDown() +/** + * Generates an EConfigDaemonLinkLayerDown request. Used to inform the + * daemon that link-layer renegotiation has started. + * + * @internalComponent + */ + { + if (iSuccessfullyCreatedDaemon) + iConfigDaemon.LinkLayerDown(); + } + +EXPORT_C void CNetworkConfigExtensionBase::LinkLayerUp() +/** + * Generates an EConfigDaemonLinkLayerUp request. Used to inform the + * daemon that link-layer renegotiation has completed. + * + * @internalComponent + */ + { + if (iSuccessfullyCreatedDaemon) + iConfigDaemon.LinkLayerUp(); + } + +EXPORT_C void CNetworkConfigExtensionBase::Deregister( + TInt aCause) +/** + * Generates a deregistration request. + * + * @internalComponent + * + * @param aCause Specifies what caused the deregistration request (idle timer or Stop call) + */ + { + if (IsActive()) + { + // if a deregistration request isn't queued up, queue one up + if (!iDeregisterOnCompletionOfRequest) + { + iDeregisterOnCompletionOfRequest = ETrue; + iDeregistrationCauseCode = aCause; + } + } + else if (!iSuccessfullyCreatedDaemon) + { + // note that there is no longer a queued deregistration + // request + iDeregisterOnCompletionOfRequest = EFalse; + // fake the behaviour of the daemon and report + // KErrNotFound to be compatible with the previous + // behaviour expected by the DHCP tests - KErrNotFound + // as in the daemon "was not found" + DoOnGenericProgress(KConfigDaemonStartingDeregistration, KErrNone); + DoOnGenericProgress(KConfigDaemonFinishedDeregistrationStop, KErrNotFound); + } + else + { + // note that there is no longer a queued deregistration + // request + iDeregisterOnCompletionOfRequest = EFalse; + // progress notification before the operation + DoOnGenericProgress(KConfigDaemonStartingDeregistration, KErrNone); + // ask the daemon to deregister + iConfigDaemon.Deregister(aCause, &iDesDeregActionStatus, iStatus); + SetActive(); + } + } + +EXPORT_C void CNetworkConfigExtensionBase::SendIoctlMessageL(const ESock::RLegacyResponseMsg& aMessage) +/** +* SendIoctlMessageL forwards Ioctl request to the daemon and activates the AO to wait for response +* +@internalTechnology +@version 0.02 +@param aMessage[in] a message to be processed (it's the caller's resposibility to forward just Ioctl +* messages) +**/ + { + __FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNetworkConfigExtensionBase::SendIoctlMessageL")); + if (static_cast(aMessage.Int0()) != KCOLConfiguration) + { + User::Leave(KErrNotSupported); + } + else + { + if (!IsActive()) + { + TDes8* ptr = NULL; + // may not always have a buffer to read... + if (aMessage.Ptr2()) + { + + delete iIoBuf; + iIoBuf = NULL; + TInt maxLength = aMessage.GetDesMaxLengthL(2); + iIoBuf=HBufC8::NewMaxL(maxLength); + iIoPtr.Set(iIoBuf->Des()); + aMessage.ReadL(2, iIoPtr); + + TInt length = aMessage.GetDesLength(2); + if (length<1) //length could be -ve due to error return from GetDesLength + { + iIoPtr.SetLength(maxLength); + } + else + { + iIoPtr.SetLength(length); + } + ptr = &iIoPtr; + } + //store msg after ReadDescriptorL which could leave + iMessage = aMessage; + iConfigDaemon.Ioctl(aMessage.Int0(), aMessage.Int1(), iStatus, ptr); + SetActive(); + } + else + { + User::Leave(KErrInUse); + } + } + } + +EXPORT_C void CNetworkConfigExtensionBase::AsyncDelete() +/** +Provide a clever method for deletion and +asynchronously cancelling any outstanding event +so as to avoid any problems of deadlock +**/ + { + if (IsActive()) //are we waiting? + { + //yes + // complete any blocked client message immediately - no sense in keeping them hanging on and in a session close + // case the dealer may race us to this + if (!iMessage.IsNull()) + { + iMessage.Complete(KErrCancel); + } + iDeleteOnCompletion = ETrue; + CancelControl(); + // Zero our reference to the NIFMAN CNifAgentRef as it can be destroyed + // ahead of us (this problem manifests itself during cycles of connection + // start immediately followed by connection stop). + iNifIfNotify = NULL; + } + else + { + DeleteThis(); + } + } + +EXPORT_C void CNetworkConfigExtensionBase::CancelControl() +/** + CancelControl - cancels request asynchronously to avoid deadlock + @internalAll + @version 0.01 +**/ + { + if (IsActive()) //are we waiting? + { + //yes + if (ipStartServer) + { + ipStartServer->Cancel(); //it'll set an error code to KErrCancel meaning that + //the requests will complete with KErrCancel + } + else + { + if(iLastGenericProgressStage != KConfigDaemonStartingDeregistration) + { + iAsynchDaemonCancel->CancelControl(iConfigDaemon, iDeleteOnCompletion); + if ( iDeleteOnCompletion ) + { + iAsynchDaemonCancel = NULL; + } + } + } + //the RunL method will be called on the original request cancellation + } + } + +EXPORT_C void CNetworkConfigExtensionBase::DoCancel() +/** +DoCancel - cancels current request +@internalTechnology +@version 0.01 +@see CActive::DoCancel +**/ + { + __ASSERT_DEBUG(0, User::Panic(KSpecAssert_NifManNetCfgExtn, 6)); //we shouldn't ever get here, would block NIFMAN/ESOCK thread + } + +EXPORT_C void CNetworkConfigExtensionBase::RunL() +/** +RunL - called when request completes +@internalTechnology +@version 0.03 +@see CActive::RunL +**/ + { + //__FLOG_STATIC0(KLogSubSysNifman, KLogTagCsDaemon, _L("CNetworkConfigExtensionBase::RunL")); + + if (iDeleteOnCompletion) + { + // if iDeleteOnCompletion is true, we are to delete ourselves + + // if there was an outstanding IOCTL request, complete the message + if (!iMessage.IsNull()) + { + // client request completion + const TAny* ptr = iMessage.Ptr2(); + if (ptr) + { + __ASSERT_DEBUG(iIoBuf, User::Panic(KSpecAssert_NifManNetCfgExtn, 7)); + iMessage.WriteL(2, *iIoBuf); + delete iIoBuf; //no longer needed + iIoBuf = NULL; + } + iMessage.Complete(iStatus.Int()); + } + + __ASSERT_DEBUG(!ipStartServer || !ipStartServer->IsActive(), User::Panic(KSpecAssert_NifManNetCfgExtn, 8)); + delete ipStartServer; //no needed any more + ipStartServer = NULL; + DeleteThis(); + // ********************************************* + // CAREFUL... don't do anything after this point + // because this object has been deleted + // ********************************************* + } + else if (ipStartServer) + { + // the daemon server was created (or the creation failed) + + // if ipStartServer is not null, then the server has just been + // started + delete ipStartServer; //no needed any more + ipStartServer = NULL; + if (iStatus.Int() == KErrNone) + { + // record the fact that the daemon was successfully + // launched + iSuccessfullyCreatedDaemon = ETrue; + // signal that the daemon was loaded successfully + DoOnGenericProgress(KConfigDaemonLoaded, KErrNone); + // create progress instance - this registers for daemon progress notifications + iDaemonProgress = CNifDaemonProgress::NewL(iConfigDaemon, this, this); + // signal before the Configure method is called + DoOnGenericProgress(KConfigDaemonStartingRegistration, KErrNone); + //complete connection + iConfigDaemon.Configure(iConnectionInfoBuf, iStatus); + SetActive(); + //wait for the Configure to complete + } + else + { + //we're done with en error + iNifIfNotify->IfProgress(KLinkLayerOpen, iStatus.Int()); + } + } + else if (!iMessage.IsNull()) + { + // the ioctl request completed + + // complete the message + const TAny* ptr = iMessage.Ptr2(); + if (ptr) + { + __ASSERT_DEBUG(iIoBuf, User::Panic(KSpecAssert_NifManNetCfgExtn, 9)); + iMessage.WriteL(2, *iIoBuf); + delete iIoBuf; //no longer needed + iIoBuf = NULL; + } + iMessage.Complete(iStatus.Int()); + + // start to deregister if we happen to have one queued + if (iDeregisterOnCompletionOfRequest) + Deregister(iDeregistrationCauseCode); + } + else if (iLastGenericProgressStage == KConfigDaemonStartingRegistration) + { + // the configure call completed + + // signal the completed Configure call + DoOnGenericProgress(KConfigDaemonFinishedRegistration, iStatus.Int()); + //no user request => must be configuration completion => signal it up + iNifIfNotify->IfProgress(KLinkLayerOpen, iStatus.Int()); + // start to deregister if we happen to have one queued + if (iDeregisterOnCompletionOfRequest) + Deregister(iDeregistrationCauseCode); + } + else if (iLastGenericProgressStage == KConfigDaemonStartingDeregistration) + { + // the deregistration request completed + + // if any error occurred, we should assume stop + // is the desired result + if (iStatus.Int() != KErrNone) + iDeregActionStatus = EConfigDaemonDeregisterActionStop; + // if the daemon doesn't support deregistration, + // we act as if everything succeeded + if (iStatus.Int() == KErrNotSupported) + iStatus = KErrNone; + // handle the result + switch (iDeregActionStatus) + { + case EConfigDaemonDeregisterActionStop: + // progress notification - note that this specific + // notification will delete this object + DoOnGenericProgress(KConfigDaemonFinishedDeregistrationStop, iStatus.Int()); + // ***************************************************** + // CAREFUL... don't do anything after this point because + // this object has been deleted as a result of this + // progress notification + // ***************************************************** + break; + case EConfigDaemonDeregisterActionPreserve: + // progress notification + DoOnGenericProgress(KConfigDaemonFinishedDeregistrationPreserve, iStatus.Int()); + // start to deregister if we happen to have one queued + if (iDeregisterOnCompletionOfRequest) + Deregister(iDeregistrationCauseCode); + break; + default: + User::Leave(KErrNotSupported); + break; + } + } + else + { + // should never get here. + __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_NifManNetCfgExtn, 10)); + } + // ******************************************** + // CAREFUL... consider the possible deletion of + // this object in the code above before adding + // anything down here + // ******************************************** + } + +EXPORT_C TInt CNetworkConfigExtensionBase::RunError(TInt aError) + {//see CNetworkConfigExtensionBase::RunL the only case it can leave is when iMessage is valid + if (!iMessage.IsNull()) + { + iMessage.Complete(aError); + } + return KErrNone; + } + +EXPORT_C void CNetworkConfigExtensionBase::DeleteThis() + { + // delete safely the progress request + if (iDaemonProgress) + { + iDaemonProgress->AsyncDelete(); + iDaemonProgress = NULL; + } + + // delete safely the cancel request + if (iAsynchDaemonCancel) + { + iAsynchDaemonCancel->AsyncDelete(); + iAsynchDaemonCancel = NULL; + } + + ADeferredDeletion::DeleteThis(); +/* iDeleteWhenAllObjectsDeleted = ETrue; + if (iDeletionObjectCount == 0) + { + delete this; + }*/ + } + +EXPORT_C CNetworkConfigExtensionBase::~CNetworkConfigExtensionBase() +/** +~CNetworkConfigExtensionBase - destructor +@internalTechnology +@version 0.02 +**/ + { + // complete any outstanding messages + if (!iMessage.IsNull()) + { + //client request completion - no point to write any data back to client here + iMessage.Complete(KErrCancel); + } + __ASSERT_DEBUG(!ipStartServer, User::Panic(KSpecAssert_NifManNetCfgExtn, 11)); + + // unload the daemon + DoOnGenericProgress(KConfigDaemonUnloading, KErrNone); + iConfigDaemon.Close(); + DoOnGenericProgress(KConfigDaemonUnloaded, KErrNone); + + delete iIoBuf; + } + +EXPORT_C void CNetworkConfigExtensionBase::EventNotification(TNetworkAdaptorEventType /*aEventType*/, TUint /*aEvent*/, const TDesC8& /*aEventData*/, TAny* /*aSource*/) +/** + Notification - does nothing. Needs to be implemented by deriving class to achieve functionality. + @internalTechnology + @version 0.01 +**/ + {} + +void CNetworkConfigExtensionBase::DoOnDaemonProgress(TInt aStage, TInt aError) +/** + * Called by CNifDaemonProgress when it receives a progress notification. + * Passes the notification to CNifAgentRef. + * + * @internalComponent + * + * @param aStage Progress stage reported by the daemon + * @param aError Error code associated with the stage + */ + { + if (iNifIfNotify) // see comment in AsyncDelete() + { + iNifIfNotify->IfProgress(aStage, aError); + } + } + +void CNetworkConfigExtensionBase::DoOnGenericProgress(TInt aStage, TInt aError) +/** + * Called to generate the cs_daemon generic progress notifications. + * + * @internalComponent + * + * @param aStage Generic progress stage + * @param aError Error code associated with the stage + */ + { + iLastGenericProgressStage = aStage; + if (iNifIfNotify) // see comment in AsyncDelete() + { + iNifIfNotify->IfProgress(aStage, aError); + } + } +