diff -r 000000000000 -r dfb7c4ff071f datacommsserver/networkcontroller/src/CNetworkController.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/datacommsserver/networkcontroller/src/CNetworkController.cpp Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,811 @@ +// 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: +// + +/** + @file CNetworkController.cpp +*/ + +#include "CNetworkController.h" +#include +#include +#include +#include "NetConPanic.h" +#include "NetConLog.h" +#include "CTelBearer.h" +#include "CNetConDlgProcessor.h" + +CNetworkController::~CNetworkController() +/** +Destuctor + +Implementation of CNetworkController +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("~CNetworkController()")); ) + + if (iImplicitNotificationCb) + { + delete iImplicitNotificationCb; + } + + iImplicitNotifyList.Close(); + + if(iImplicitConnectionAgentName) + { + delete iImplicitConnectionAgentName; + iImplicitConnectionAgentName = NULL; + } + + // delete all CNetConRequestBase objects + while(!iRequestQueue.IsEmpty()) + { + CNetConRequestBase* request = iRequestQueue.First(); + iRequestQueue.Remove(*request); + delete request; + } + iRequestQueue.Reset(); + + if (iCurrentRequest) + { + iCurrentRequest->CancelRequest(); + delete iCurrentRequest; + iCurrentRequest = NULL; + } + + if (iProcessRequestCb) + { + delete iProcessRequestCb; + } + + + LOG ( NetConLog::Printf(_L("--------------- Network Controller Finished ---------------")); ) + } + +CNetworkController* CNetworkController::NewL() +/** +Factory function + +@return the new CNetworkController object +@exception leaves if memory allocation fails +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::NewL()")); ) + CNetworkController* self = new(ELeave) CNetworkController(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self + return self; + } + +CNetworkController::CNetworkController() +/** +Constructor +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController()")); ) + + iRequestQueue.SetOffset(_FOFF(CNetConRequestBase, iLink)); + } + +void CNetworkController::ConstructL() +/** +2nd phase of construction + +@exception leaves if callback, database, dialog processor or bearer construction fails +*/ + { + LOG ( NetConLog::Printf(_L("--------------- Network Controller Starting ---------------")); ) + LOG_DETAILED( NetConLog::Printf(_L("Detailed logging enabled")); ) + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::ConstructL()")); ) + + // create a callback for processing requests + TCallBack callback(ProcessRequestCb, this); + iProcessRequestCb = new(ELeave) CAsyncCallBack(callback, CActive::EPriorityStandard); + + // there is no existing implicitly started connection + iImplicitConnectionAgentName = NULL; + + // set up callback for implicit connection event notification + TCallBack implicitCallBack(ImplicitNotificationCb, this); + iImplicitNotificationCb = new(ELeave) CAsyncCallBack(implicitCallBack, CActive::EPriorityStandard); + + // set up telephony bearer with this object as observer and dbaccess + // note that all bearers are deleted in the CNetworkControllerBase d'tor + CTelBearer* telBearer = CTelBearer::NewLC(this); + AddBearerL(telBearer); + CleanupStack::Pop(); // telBearer + + // ensure that the telephony bearer was added where we expect + __ASSERT_DEBUG(iBearers[KTelBearerPosition] == telBearer, NetConPanic(NetworkController::ENetConTelBearerMissing)); + } + +TInt CNetworkController::FindExistingAgentForSelection(CNifAgentBase*& aAgent, CCommsDbAccess* aDatabase) const +/** +Searches for an Agent associated with the selected IAP + +@note that there is a one-to-one relationship between agents and IAPs +@param aAgent if found a pointer to the CNifAgentBase +@return KErrNotFound if the agent with selected IAP is not found else KErrNone +@pre the selected IAP setting is stored in the DbAccess object. +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::FindExistingAgentForSelection()")); ) + + // read the CommDb ID of the current IAP + TUint32 iapId(0); + TInt err(KErrNone); + + TRAP(err, aDatabase->GetIntL(TPtrC(IAP), TPtrC(COMMDB_ID), iapId)); + if (err != KErrNone) + { + return KErrNotFound; + } + + // read network ID of the current IAP + TUint32 networkId(0); + TRAP(err, aDatabase->GetIntL(TPtrC(IAP), TPtrC(IAP_NETWORK), networkId)); + if (err != KErrNone) + { + return KErrNotFound; + } + + // find the network + CNetwork* network = NULL; + err = FindNetworkById(networkId, network); + if (err!=KErrNone) + { + return err; + } + + // ask network to find the agent + return network->FindAgentByIap(iapId, aAgent); + } + +void CNetworkController::SelectAgent(MNetworkControllerObserver* aObserver, MServiceChangeObserver* apServiceChangeObserver, TConnStartType aStartType, TInt aConnectionAttempt, TInt aLastConnectionError, const TConnPref& aPrefs) + +/** +Adds a selection request to the queue and calls the Process Request Callback +This allows the current callstack to unwind. Processing is resumed at ProcessRequestCb + +@param aObserver the pointer to the MNetworkControllerObserver that requested the selection +@param apServiceChangeObserver that requests service change notification +@param aStartType how this connection request was started - either Implicit or Explicit +@param aConnectionAttempt the connection attempt +@param aLastConnectionError if this is not the first connection attempt the error from the last connection +@param aPrefs the connection preferences to use in preference(?!) to the ones stored in commdb +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::SelectAgent()")); ) + + // create a new request and add it to the queue + CNetConRequestBase* newRequest = NULL; + TRAPD(err, newRequest = CSelectionRequest::NewL(this, aObserver, aStartType, aPrefs, aConnectionAttempt, aLastConnectionError)); + if(err!=KErrNone) + { + aObserver->SelectComplete(err); + return; + } + + newRequest->ipServiceChangeObserver = apServiceChangeObserver; + iRequestQueue.AddLast(*newRequest); + + LOG( NetConLog::Printf(_L("\tAdded request [0x%08x] to queue"), newRequest); ) + + // start to process request if not already processing + if(!iCurrentRequest) + { + iProcessRequestCb->CallBack(); + } + } + +void CNetworkController::SelectAgent(MNetworkControllerObserver* aObserver, MServiceChangeObserver* apServiceChangeObserver, TConnStartType aStartType, TInt aConnectionAttempt, TInt aLastConnectionError) + +/** +SelectAgent + +@param aObserver the pointer to the MNetworkControllerObserver that requested the selection +@param apServiceChangeObserver that requests service change notification +@param aStartType how this connection request was started - either Implicit or Explicit +@param aConnectionAttempt the connection attempt +@param aLastConnectionError if this is not the first connection attempt the error from the last connection +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::SelectAgent2()")); ) + + // construct some default connection preference - this will cause the default commdb settings to be used + TConnPref prefs; + + SelectAgent(aObserver, apServiceChangeObserver, aStartType, aConnectionAttempt, aLastConnectionError, prefs); + } + +void CNetworkController::Reconnect(MNetworkControllerObserver* aObserver, CNifAgentBase* aAgent) +/** +Reconnect + +@param aObserver the pointer to the MNetworkControllerObserver that requested the selection +@param aAgent,the agent who's connection failed +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::Reconnect()")); ) + + Reconnect(aObserver, aAgent, NULL); + } + +void CNetworkController::Reconnect(MNetworkControllerObserver* aObserver, CNifAgentBase* aAgent, CStoreableOverrideSettings* aOverrides) +/** +Adds a reconnect request to the queue and calls the Process Request Callback +This allows the current callstack to unwind. Processing is resumed at ProcessRequestCb + +@param aObserver the pointer to the MNetworkControllerObserver that requested the selection +@param aAgent,the agent who's connection failed +@param aOverrides,pointer to the override settings to store. +@note that ownership of these overrides is retained by the caller. +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::Reconnect2()")); ) + + CNetConRequestBase* newRequest = NULL; + TRAPD(err, newRequest = CReconnectRequest::NewL(this, aObserver, aAgent, aOverrides);) + if(err!=KErrNone) + { + aObserver->ReconnectComplete(err); + return; + } + + iRequestQueue.AddLast(*newRequest); + + LOG( NetConLog::Printf(_L("\tAdded request [0x%08x] to queue"), newRequest); ) + + // start to process request if not already processing + if(!iCurrentRequest) + { + iProcessRequestCb->CallBack(); + } + } + +TInt CNetworkController::CancelRequest(MNetworkControllerObserver* aObserver) +/** +Cancel the request made by aObserver. +If this request is currently being processed then stop processing immediately. + +@param aObserver pointer to the object that initiated the request +@return KErrNone if the request was found and cancelled ok otherwise KErrNotFound + */ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::CancelRequest()")); ) + + TInt retval(KErrNotFound); + CNetConRequestBase* request = NULL; + + // find the request to cancel + if (iCurrentRequest && iCurrentRequest->Observer() == aObserver) + { + LOG( NetConLog::Printf(_L("\tCancelled request [0x%08x]"), iCurrentRequest); ) + + // cancel the active request - this will cancel all bearer checking and any dialog box activity + iCurrentRequest->CancelRequest(); + + // delete the request + delete iCurrentRequest; + iCurrentRequest = NULL; + + // trigger callback to process next request in the queue + iProcessRequestCb->CallBack(); + + retval = KErrNone; + } + else + { + TSglQueIter iter(iRequestQueue); + + while ((request = iter++) != NULL) + { + if (request->Observer() == aObserver) + { + // remove request from queue + iRequestQueue.Remove(*request); + + LOG( NetConLog::Printf(_L("\tCancelled request [0x%08x]"), request); ) + + // note: don't call Cancel() on this request as it is not active + + // delete the request + delete request; + request = NULL; + + retval = KErrNone; + break; + } + } + } + + return retval; + } + +void CNetworkController::AgentConnectionFailure(CNifAgentBase* aAgent, TInt aError) +/** +A connection has failed. + +@param aAgent the agent who's connection failed +@param aError the reason for the failure +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::AgentConnectionFailure()")); ) + + if(!aAgent) + { + return; + } + + // retrieve agent name + TNifAgentInfo info; + aAgent->Info(info); + + LOG( NetConLog::Printf(_L("\tAgent '%S' has disconnected with error %d"), &info.iName, aError); ) + + // remove warning - the error code is not used in all builds + (void)aError; + + // if the agent was the one for implicit connections + // then remove the stored name + if(iImplicitConnectionAgentName && info.iName == *iImplicitConnectionAgentName) + { + delete iImplicitConnectionAgentName; + iImplicitConnectionAgentName = NULL; + + (void)GetConnectionInfo(aAgent, iImplicitNotifyInfo); + iImplicitNotifyEvent = MImplicitConnectionNotify::EImplicitConnectionDown; + iImplicitNotificationCb->CallBack(); + } + + TInt i(0); + // remove this agent from any bearers + for (i=0; iRemoveAgentL(aAgent)); + if (KErrNone != err) + { + LOG( NetConLog::Printf(_L("\tERROR: Agent has disconnected from bearer with error %d"), err); ) + } + } + + // remove this agent from its network + for (i=0; iRemoveAgentL(aAgent)); + if (KErrNone != err) + { + LOG( NetConLog::Printf(_L("\tERROR: Agent has disconnected from network with error %d"), err); ) + } + } + } + +TInt CNetworkController::GetConnectionInfo(CNifAgentBase* aAgent, TDes8& aConnectionInfo) + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::GetConnectionInfo()")); ) + + _LIT(KIapId, "IAP\\Id"); + _LIT(KNetId, "IAP\\IAPNetwork"); + + TSoIfConnectionInfo info; + TInt err = aAgent->ReadInt(KIapId(), info.iIAPId); + if(err!=KErrNone) + { + return err; + } + + err = aAgent->ReadInt(KNetId(), info.iNetworkId); + if(err!=KErrNone) + { + return err; + } + + + aConnectionInfo = TPckg(info); + return KErrNone; + } + +TInt CNetworkController::ProcessRequestCb(TAny* aThisPtr) +/** +ProcessRequestCb + +@param aThisPtr the pointer to the object that initiated the callback +@return KErrNone always +*/ + { + CNetworkController* self = static_cast(aThisPtr); + self->ProcessRequest(); + return KErrNone; + } + +void CNetworkController::ProcessRequest() +/** +ProcessRequest +Deque a request and start to process it. +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::ProcessRequest()")); ) + LOG ( + if (iCurrentRequest) + NetConLog::Printf(_L("\tCurrently processing request [0x%08x]"), iCurrentRequest); + else + NetConLog::Printf(_L("\tNot currently processing any request")); + + if (!iRequestQueue.IsEmpty()) + NetConLog::Printf(_L("\tSome requests are queued")); + else + NetConLog::Printf(_L("\tRequest queue is empty")); + ) + + if (iCurrentRequest) + { + return; // we are already processing a request + } + + if (!iRequestQueue.IsEmpty()) + { + iCurrentRequest = iRequestQueue.First(); + iRequestQueue.Remove(*iCurrentRequest); + LOG( NetConLog::Printf(_L("--------------- Starting to process request [0x%08x] ---------------"), iCurrentRequest); ) + iCurrentRequest->StartRequest(); + } + } + +void CNetworkController::RequestComplete(const CSelectionRequest* aRequest, TInt aError) +/** +A selection request has been processed - queue another one. + +@param aRequest pointer to the actual selection request +@param aError contains the reason for failure of processing the request or KErrNone +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::RequestComplete()")); ) + __ASSERT_ALWAYS((CNetConRequestBase*)aRequest == iCurrentRequest, NetConPanic(NetworkController::ENetConBadRequestCallback)); + + LOG( NetConLog::Printf(_L("--------------- Finished processing request [0x%08x] ---------------"), iCurrentRequest); ) + + // Trigger callback to process next request in the queue + iProcessRequestCb->CallBack(); + + // if this was an implicit request then store the name of the agent for other implicit requests + if (aError == KErrNone && aRequest->ConnectionStartType() == EConnStartImplicit) + { + if(!iImplicitConnectionAgentName) + { + TRAPD(err, iImplicitConnectionAgentName = (aRequest->AgentName()).AllocL()); + if (err != KErrNone) + { + aError = err; + } + else + { + iImplicitConnectionPrefs = aRequest->ConnPrefs(); + iImplicitNotifyInfo = aRequest->AgentConnectionInfo(); + iImplicitNotifyEvent = MImplicitConnectionNotify::EImplicitConnectionUp; + iImplicitNotificationCb->CallBack(); + } + } + else + { + ASSERT(*iImplicitConnectionAgentName == aRequest->AgentName()); + } + } + + ASSERT(aRequest->Observer()); + + // signal the observer that the selection is complete + if(aError==KErrNone) + { + aRequest->Observer()->SelectComplete(aRequest->AgentName()); + } + else + { + aRequest->Observer()->SelectComplete(aError); + } + + delete iCurrentRequest; + iCurrentRequest = NULL; + + CancelBearerAvailabilityCheck(); + } + +void CNetworkController::RequestComplete(const CReconnectRequest* aRequest, TInt aError) +/** +RequestComplete + +A reconnect request has been processed - queue another one. + +@param aRequest pointer to the actual reconnect request +@param aError contains the reason for failure of processing the request or KErrNone +*/ + { + __ASSERT_ALWAYS( (CReconnectRequest*)aRequest == iCurrentRequest, NetConPanic(NetworkController::ENetConBadRequestCallback)); + + LOG_DETAILED ( NetConLog::Printf(_L("CNetworkController::RequestComplete(CReconnectRequest aRequest = 0x%08x, aError = %d)"), aRequest, aError); ) + LOG( NetConLog::Printf(_L("--------------- Finished processing request [0x%08x] ---------------"), iCurrentRequest); ) + + // Trigger callback to process next request in the queue + iProcessRequestCb->CallBack(); + + // signal the observer that the selection is complete + aRequest->Observer()->ReconnectComplete(aError); + + delete iCurrentRequest; + iCurrentRequest = NULL; + } + +TInt CNetworkController::RequestImplicitConnectionNotification(MImplicitConnectionNotify* aObserver) +/** +Register for implicit connection event notification +Implicit Connection Notification + +@param aObserver to notify of event changes +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::RequestImplicitConnectionNotification()")); ) + + if(iImplicitConnectionAgentName) + { + aObserver->ImplicitConnectionEvent(iImplicitNotifyInfo, MImplicitConnectionNotify::EImplicitConnectionUp); + } + + return iImplicitNotifyList.Append(aObserver); + } + +void CNetworkController::CancelImplicitConnectionNotification(MImplicitConnectionNotify* aObserver) +/** +Deregister for implicit connection event notification + +@param aObserver to notify of event changes +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::CancelImplicitConnectionNotification()")); ) + + TInt index = iImplicitNotifyList.Find(aObserver); + if(index>=0) + { + iImplicitNotifyList.Remove(index); + } + } + +TInt CNetworkController::ImplicitNotificationCb(TAny* aThisPtr) +/** +Static callback function + +@param aThisPtr the pointer to the instance of this class that triggered the callback +*/ + { + CNetworkController* self = STATIC_CAST(CNetworkController*, aThisPtr); + self->SendImplicitConnectionNotification(self->iImplicitNotifyInfo, self->iImplicitNotifyEvent); + return KErrNone; + } + +void CNetworkController::SendImplicitConnectionNotification(const TDesC8& aConnectionInfo, MImplicitConnectionNotify::TEvent aEvent) +/** +Notify all registered observers about the implicit connection event + +@param aConnectionInfo a TSoIfConnectionInfo describing the implicit connection IapId and NetId +@param aEvent either Up or Down +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::SendImplicitConnectionNotification()")); ) + + for(TInt i=0; iImplicitConnectionEvent(aConnectionInfo, aEvent); + } + } + +// +// // +// Bearer Availability Checking // +// // +// + +void CNetworkController::CheckBearerAvailability(TBool aIsReconnect) +/** +Check Bearer Availability + +@param aIsReconnect if this is a reconnection then any asynchronous requests are skipped in order to speed things up +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::CheckBearerAvailability()")); ) + + // ensure that the telephony bearer is in the array + __ASSERT_DEBUG(iBearers[KTelBearerPosition], NetConPanic(NetworkController::ENetConTelBearerMissing)); + + // ask the telephony bearer to start checking for availability + TBool ret = iBearers[KTelBearerPosition]->StartChecking(aIsReconnect); + __ASSERT_DEBUG(ret, NetConPanic(NetworkController::ENetConTelBearerAlreadyChecking)); + (void)ret; // remove warning in release builds + } + +void CNetworkController::CancelBearerAvailabilityCheck() +/** +CancelBearerAvailabilityCheck +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::CancelBearerAvailabilityCheck()")); ) + + // ensure that the telephony bearer is in the array + __ASSERT_DEBUG(iBearers[KTelBearerPosition], NetConPanic(NetworkController::ENetConTelBearerMissing)); + + iBearers[KTelBearerPosition]->StopChecking(); + } + +/** + Construct a new database accessor + @returns the new database accessor +*/ +CCommsDbAccess* CNetworkController::NewDatabaseL() + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::NewDatabaseL()")); ) + + CCommsDbAccess *database = CCommsDbAccess::NewL(ETrue); + ASSERT( database ); + return database; + } + + +/** + Construct a new dialog processor + @returns the new dialog processor +*/ +CNetConDlgProcessor* CNetworkController::NewDialogProcessorL() + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::NewDialogProcessorL()")); ) + + return CNetConDlgProcessor::NewL(); + } + + +TInt CNetworkController::RequestSecondPhaseAvailability() +/** +Check Second Phase Bearer Availability - e.g. signal strength + +@returns KErrNone if the bearer availability is above the threshold stored in CommDB, otherwise KErrNetConInadequateSignalStrengh +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::RequestSecondPhaseAvailability()")); ) + + CBearerBase* const telBearer = iBearers[KTelBearerPosition]; + + // ensure that the telephony bearer is in the array + __ASSERT_DEBUG(telBearer, NetConPanic(NetworkController::ENetConTelBearerMissing)); + + // ask the telephony bearer to start checking for availability + TInt availability = telBearer->SecondPhaseAvailability(); + + // we have to tell the bearer to stop checking for availability here, otherwise + // subsequent availability requests will fail + // the logic is that every selection request triggers a *new* bearer availabilty + // check - in a one box device this could be optimised to a single check. + telBearer->StopChecking(); + return availability; + } + +void CNetworkController::BearerStateChange(CBearerBase* aBearer) +/** +The bearer set available has changed - update the current +request + + +Implementation of MBearerObserver Interface + +@param aBearer the bearer who's availability has changed +@note that this is quite a simple implementation +of bearer availability checking because we only +have a single bearer. If further bearers are +implemented then a 'bearer manager' class may +be used to take the responsibility of retrieveing +the availability of all bearers and then returing +to the network controller +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::BearerStateChange()")); ) + + __ASSERT_DEBUG(iCurrentRequest, NetConPanic(NetworkController::ENetConNoCurrentRequest)); + + // fetch the available bearer set from the telephony bearer + TUint32 availableBearerSet(aBearer->AvailableBearerSet()); + + // the LAN bearer is assumed to be always available so mask it in + availableBearerSet |= (KCommDbBearerLAN|KCommDbBearerVirtual); + + // update the current request + iCurrentRequest->SetAvailableBearers(availableBearerSet); + } + +CCommsDbAccess* CNetworkController::DbAccess() +/** Provide a pointer to the CCommsDbAccess class to facilitate access to commdb +@return CCommsDbAccess +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::DbAccess()")); ) + + ASSERT(iCurrentRequest); + ASSERT(iCurrentRequest->DbAccess()); + return iCurrentRequest->DbAccess(); + } + +// +// // +// MNetConEnv Interface // +// // +// + +const HBufC* CNetworkController::ImplicitConnectionAgentName() const +/** +Retrieve the name of the Agent that is used for implicit connection +requests - i.e. connection startup from RSocket SendTo()/Connect() or +RHostResolver GetByName() + +@returns an Agent name +*/ + { + LOG_DETAILED( + if (iImplicitConnectionAgentName) + NetConLog::Printf(_L("CNetworkController::ImplicitConnectionAgentName() %S"), iImplicitConnectionAgentName); + else + NetConLog::Printf(_L("CNetworkController::ImplicitConnectionAgentName() returns NULL")); + ) + + return iImplicitConnectionAgentName; + } + +const TConnPref& CNetworkController::ImplicitConnectionPrefs() const +/** +Retrieve the connection preferences associated with the current +implicit connection + +@returns a TConnPref reference +*/ + { + + return iImplicitConnectionPrefs; + } + +void CNetworkController::AddAgentToNetworkL(CNifAgentBase* aAgent, TUint32 aNetworkId) +/** +Create an association between an Agent and a Network ID. + +@param aAgent pointer to the Agent +@param aNetworkId the CommDb ID of the Network +*/ + { + LOG_DETAILED( NetConLog::Printf(_L("CNetworkController::AddAgentToNetworkL()")); ) + + // Is the network already available? + CNetwork* network = NULL; + TInt findErr = FindNetworkById(aNetworkId, network); + + // ...if not create a new network + if(findErr!=KErrNone) + { + network=CNetwork::NewLC(aNetworkId, this); + AddNetworkL(network); + CleanupStack::Pop(); // network + } + + // add this agent to the network. + network->AddAgentL(aAgent); + + LOG( NetConLog::Printf(_L("\tAdded agent [0x%08x] to Network %d [0x%08x]"), aAgent, aNetworkId, network); ) + } +