--- /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 <comms-infras/nifif.h>
+#include <comms-infras/ca_startserver.h>
+#include <cdbcols.h>
+#include <comms-infras/commsdebugutility.h>
+
+
+#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<MNifIfNotify*>(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<KCommsDbSvrMaxFieldLength> 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<TUint>(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);
+ }
+ }
+