datacommsserver/networkcontroller/src/CSelectionRequest.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file CSelectionRequest.cpp
       
    18 */
       
    19 
       
    20 #include <nifman.h>
       
    21 #include <comms-infras/nifagt.h>
       
    22 #include <es_connpref.h>
       
    23 #include "CSelectionRequest.h"
       
    24 #include "CNetworkController.h"
       
    25 #include "NetConPanic.h"
       
    26 #include "NetConLog.h"
       
    27 #include "NetConError.h"
       
    28 
       
    29 CSelectionRequest* CSelectionRequest::NewL(MNetConEnv* aController, MNetworkControllerObserver* aObserver, TConnStartType aStartType, const TConnPref& aPrefs, TInt aConnectionAttempt, TInt aLastConnectionError)
       
    30 /**
       
    31 Factory function
       
    32 
       
    33 Creates a new CSelectionRequest object
       
    34 
       
    35 @param aController pointer to the Network Controller
       
    36 @param aObserver the object that initiated this request
       
    37 @param aStartType how this request was initiated either Implicit(due to RSocket/RHostResolver calls) or Explicit(due to an RConnection call)
       
    38 @param aPrefs connection preferences to be used when selecting an appropriate Agent
       
    39 @param aConnectionAttempt indicates the current connection attempt
       
    40 @param aLastConnectionError if this is not the first connection attempt then the error of the last attempt
       
    41 @exception leaves if object cannot be constructed
       
    42 @return the new CSelectionRequest object
       
    43 */
       
    44  	{
       
    45 
       
    46 	CSelectionRequest* self = new(ELeave) CSelectionRequest(aController, aObserver, aStartType, aPrefs, aConnectionAttempt, aLastConnectionError);
       
    47 	CleanupStack::PushL(self);
       
    48 	self->ConstructL();
       
    49 	CleanupStack::Pop(); // self
       
    50 	return self;
       
    51 	}
       
    52 
       
    53 CSelectionRequest::~CSelectionRequest()
       
    54 /**
       
    55 Destructor
       
    56 */
       
    57 	{
       
    58 
       
    59 	if(iOverrides)
       
    60 		delete iOverrides;
       
    61 
       
    62 	if(iAgentName)
       
    63 		delete iAgentName;
       
    64 	}
       
    65 
       
    66 CSelectionRequest::CSelectionRequest(MNetConEnv* aController, MNetworkControllerObserver* aObserver, TConnStartType aStartType, const TConnPref& aPrefs, TInt aConnectionAttempt, TInt aLastConnectionError)
       
    67 : CNetConRequestBase(aController, aObserver, NULL), iConnStartType(aStartType), iConnPrefs(aPrefs), iConnectionAttempt(aConnectionAttempt), iLastConnectionError(aLastConnectionError)
       
    68 /**
       
    69 Constructor
       
    70 
       
    71 @param aDatabase pointer to the object used to access CommDb
       
    72 @param aDialogPrc pointer to the object used to access the dialog processor
       
    73 @param aController pointer to the Network Controller
       
    74 @param aObserver the object that initiated this request
       
    75 @param aStartType how this request was initiated either Implicit(due to RSocket/RHostResolver calls) or Explicit(due to an RConnection call)
       
    76 @param aPrefs connection preferences to be used when selecting an appropriate Agent
       
    77 @param aConnectionAttempt indicates the current connection attempt
       
    78 @param aLastConnectionError if this is not the first connection attempt then the error of the last attempt
       
    79 */
       
    80 	{ }
       
    81 
       
    82 void CSelectionRequest::ConstructL()
       
    83 /**
       
    84 2nd phase of construction
       
    85 
       
    86 @exception leaves if 2nd phase construction leaves
       
    87 */
       
    88 	{
       
    89 	CNetConRequestBase::ConstructL();
       
    90 
       
    91 	// construct a HBufC in which to store the name of the agent
       
    92 	const TUint8 KInitialAgentNameLength = 20;
       
    93 	iAgentName = HBufC::NewL(KInitialAgentNameLength);
       
    94 	_LIT(KUndefined, "Undefined");
       
    95 	SetAgentNameL(KUndefined());
       
    96 	}
       
    97 
       
    98 void CSelectionRequest::SetAgentNameL(const TDesC& aName)
       
    99 /**
       
   100 Replace the value of iAgentName allocating more memory if needed
       
   101 
       
   102 @param aName the new name of the Agent
       
   103 @exception leaves with KErrNoMemory if allocation fails
       
   104 */
       
   105 	{
       
   106 	ASSERT(iAgentName);
       
   107 
       
   108 	// see if we need to allocate more memory for the agent name
       
   109 	if (aName.Length() > iAgentName->Length())
       
   110 		{
       
   111 		iAgentName = iAgentName->ReAllocL(aName.Length());
       
   112 		}
       
   113 
       
   114 	// replace agent name
       
   115 	*iAgentName = aName;
       
   116 	}
       
   117 
       
   118 void CSelectionRequest::StartRequest()
       
   119 /**
       
   120 Start processing this request
       
   121 */
       
   122 	{
       
   123 	LOG (
       
   124 		NetConLog::Printf(_L("\tRequest type = Selection"));
       
   125 		NetConLog::Printf(_L("\tConnection attempt = %d"), iConnectionAttempt);
       
   126 		NetConLog::Printf(_L("\tConnection type = %d"), iConnStartType);
       
   127 		)
       
   128 
       
   129 	// set overrides for this request in the databse
       
   130 	TRAPD(err, iDatabase->SetOverridesL(iOverrides);
       
   131                iDatabase->RequestNotificationOfServiceChangeL(ipServiceChangeObserver));
       
   132 
       
   133 	if(err!=KErrNone)
       
   134 		{
       
   135 		LOG( NetConLog::Printf(_L("\tError %d encountered during start of IAP selection routine - is CommDb setup correctly?"), err); )
       
   136 		RequestComplete(err);
       
   137 		return;
       
   138 		}
       
   139 
       
   140 	TRAP(err, StartSelectL());
       
   141 	if(err!=KErrNone)
       
   142 		{
       
   143 		LOG( NetConLog::Printf(_L("\tError %d encountered during start of IAP selection routine - is CommDb setup correctly?"), err); )
       
   144 		RequestComplete(err);
       
   145 		}
       
   146 	}
       
   147 
       
   148 void CSelectionRequest::RequestComplete(TInt aError)
       
   149 /**
       
   150 Complete this request with a given error
       
   151  
       
   152 @param aError the error with which to complete the request
       
   153 */
       
   154 	{
       
   155 
       
   156 	LOG( NetConLog::Printf(_L("\tRequest Complete with error %d"), aError); )
       
   157 
       
   158 	iController->RequestComplete(this, aError);
       
   159 	}
       
   160 
       
   161 const TDesC& CSelectionRequest::AgentName() const
       
   162 /**
       
   163 Retrieves the name of the agent that was selected
       
   164 */
       
   165 	{
       
   166 	if(!iAgentName)
       
   167 		{
       
   168 		return KNullDesC();
       
   169 		}
       
   170 	else
       
   171 		{
       
   172 		return *iAgentName;
       
   173 		}
       
   174 	}
       
   175 
       
   176 const TPckgBuf<TSoIfConnectionInfo>& CSelectionRequest::AgentConnectionInfo() const
       
   177 /**
       
   178 Retrieves the connection information of the agent that was selected
       
   179 */
       
   180 	{
       
   181 	return iAgentConnInfo;
       
   182 	}
       
   183 
       
   184 const TConnStartType& CSelectionRequest::ConnectionStartType() const
       
   185 /**
       
   186 @return the connection start type - i.e. either implicit or explicit
       
   187 */
       
   188 	{
       
   189 	
       
   190 	return iConnStartType;
       
   191 	}
       
   192 
       
   193 const TConnPref& CSelectionRequest::ConnPrefs() const
       
   194 /**
       
   195 @return the connection preferences associated with this request
       
   196 */
       
   197 	{
       
   198 
       
   199 	return iConnPrefs;
       
   200 	}
       
   201 
       
   202 void CSelectionRequest::StartSelectL()
       
   203 /**
       
   204 Start the selection process
       
   205 
       
   206 Read current connection preferences and settings from the database then start the selection process. 
       
   207 
       
   208 @exception leaves if database access leaves
       
   209 */
       
   210  	{
       
   211 
       
   212 	// clear any existing overrides in the database
       
   213 	iDatabase->SetOverridesL(NULL);
       
   214 
       
   215 	// check that we are within the maximum number of connection attempts specified by CommDb
       
   216 	TInt maxConnectionAttempts = iDatabase->GetConnectionAttempts();
       
   217 	
       
   218 	User::LeaveIfError(maxConnectionAttempts);
       
   219 
       
   220 	// allow the connection preferences to override the max number of connection attempts in CommDb
       
   221 	if(iConnPrefs.ExtensionId() == TConnPref::EConnPrefCommDbMulti)
       
   222 		{
       
   223 		TInt preferences = TCommDbMultiConnPref::Cast(iConnPrefs).ConnectionAttempts();
       
   224 		maxConnectionAttempts = preferences; 
       
   225 		}
       
   226 
       
   227 	if(iConnectionAttempt > maxConnectionAttempts)
       
   228 		{
       
   229 		LOG( NetConLog::Printf(_L("\tError - maximum number of connection attempts (%d) reached"), maxConnectionAttempts); )
       
   230 		RequestComplete(KErrOverflow);
       
   231 		return;
       
   232 		}
       
   233 
       
   234 	// extract a TCommDbConnPref from iConnPrefs
       
   235 	TCommDbConnPref commDbPref;
       
   236 	User::LeaveIfError(ExtractCommDbConnPref(iConnPrefs, commDbPref));
       
   237 
       
   238 	// set connection attempt
       
   239 	iSettings.iRank = iConnectionAttempt;
       
   240 
       
   241 	// if direction is not specified then default to outgoing
       
   242 	if(commDbPref.Direction() == ECommDbConnectionDirectionUnknown)
       
   243 		{
       
   244 		commDbPref.SetDirection(ECommDbConnectionDirectionOutgoing);
       
   245 		}
       
   246 
       
   247 	// extract connection direction
       
   248 	iSettings.iDirection = commDbPref.Direction();
       
   249 
       
   250 	TUint32 overidenIap = commDbPref.IapId();
       
   251 
       
   252 	// Wnsure that a valid IAP exists in the 
       
   253 	TUint32 preferredIap(overidenIap);
       
   254 	LOG( NetConLog::Printf(_L("\tpreferredIap=%d"), preferredIap); )
       
   255 
       
   256 	if (overidenIap == 0)
       
   257 		{
       
   258 		iDatabase->GetPreferedIapL(preferredIap, iSettings.iDirection, iSettings.iRank);
       
   259 		LOG( NetConLog::Printf(_L("\tnew preferredIap=%d"), preferredIap); )
       
   260 		}
       
   261 
       
   262 	// If this IAP doesn't exist, we must prompt the user
       
   263 	if((preferredIap == 0) || !iDatabase->DoesIapExistL(preferredIap))
       
   264 		{
       
   265 		LOG( NetConLog::Printf(_L("\tActive settings for IAP have been set to prompt, since the IAP doesn't exist"));)
       
   266 		commDbPref.SetDialogPreference(ECommDbDialogPrefPrompt);
       
   267 
       
   268 		// IAP is invalid, override it in the active settings to allow prompt to continue
       
   269 		iDatabase->GetFirstValidIapL(preferredIap);
       
   270 		commDbPref.SetIapId(preferredIap);
       
   271 		}
       
   272 
       
   273 	// convert the connection preferences into some appropriate override settings
       
   274 	iOverrides = MapPrefsToOverridesL(commDbPref, iSettings);
       
   275 
       
   276 	if(iOverrides)
       
   277 		{
       
   278 		//set these overrides in the database
       
   279 		iDatabase->SetOverridesL(iOverrides);
       
   280 		}
       
   281 
       
   282 	iDatabase->GetCurrentSettingsL(iSettings, iSettings.iDirection, iSettings.iRank);
       
   283 
       
   284 	if((iConnStartType == EConnStartImplicit) && iController->ImplicitConnectionAgentName())
       
   285 		{
       
   286 		// there is already an implicit connection - try to match the preferences
       
   287 		TCommDbConnPref implicitPref;
       
   288 		User::LeaveIfError(ExtractCommDbConnPref(iController->ImplicitConnectionPrefs(), implicitPref));
       
   289 		if(commDbPref == implicitPref)
       
   290 			{
       
   291 			// This is an implicit request for an outgoing connection and there
       
   292 			// has already been another implicit request - just return the name
       
   293 			// of the existing agent
       
   294 			LOG( NetConLog::Printf(_L("\tReturning existing agent for implicit connection: '%S'"), iController->ImplicitConnectionAgentName()); )
       
   295 			SetAgentNameL(*iController->ImplicitConnectionAgentName());
       
   296 			RequestComplete(KErrNone);
       
   297 			}
       
   298 		else
       
   299 			{
       
   300 			LOG( NetConLog::Printf(_L("\tImplicit connection already exists - cannot start a new one with conflicting preferences!")); )
       
   301 			RequestComplete(KErrInUse);
       
   302 			}
       
   303 		return;
       
   304 		}
       
   305 
       
   306 	// store the completed preferences as iConnPrefs
       
   307 	// this is so that if the CNetworkController asks for the prefs used for the
       
   308 	// selected connection we will return the accurate prefs (with the default
       
   309 	// values filled in)
       
   310 	iConnPrefs = commDbPref;
       
   311 
       
   312 	// for some reason we have to write these settings back to the database, otherwise
       
   313 	// when dialog prompt is set to warn we get an error - why?
       
   314 	iDatabase->SetCurrentSettingsL(iSettings);
       
   315 
       
   316 	// note that we no-longer display the "Select Modem & Location" dialog boxes
       
   317 	// since the IAP points to the modem and location
       
   318 
       
   319 	// read service settings from database
       
   320 	iDatabase->GetServiceSettingsL(iSettings);
       
   321 
       
   322 	LOG (
       
   323 		NetConLog::Printf(_L("\tPreferred Service Type = '%S'"), &iSettings.iServiceType);
       
   324 		NetConLog::Printf(_L("\tPreferred Service Id = %d"), iSettings.iServiceId);
       
   325 		NetConLog::Printf(_L("\tPreferred Bearer Set = %d"), iSettings.iBearerSet);
       
   326 		)
       
   327 
       
   328 	// check for bearer availability
       
   329 	iDoBearerAvailability = !(iSettings.iDialogPref==ECommDbDialogPrefWarn || iSettings.iDialogPref==ECommDbDialogPrefDoNotPrompt);
       
   330 	if (iDoBearerAvailability)
       
   331 		{
       
   332 		// Bearer availability check is only performed if prompting
       
   333 		// It is only used to help populate the dialogue with available bearers
       
   334 		//
       
   335 		// Warning: that the results of the CheckBearerAvailability are 
       
   336 		// only used in the case of ECommDbDialogPrefPromptIfWrongMode
       
   337 		// so it might be possible to remove this check and speed things up
       
   338 		// 
       
   339 		LOG( NetConLog::Printf(_L("\tRequesting bearer availability")); )
       
   340 		iController->CheckBearerAvailability(EFalse);  // EFalse indicates that this is not a reconnection
       
   341 		}
       
   342 	else
       
   343 		{
       
   344 		// Not prompting so do best effort and allow all bearers
       
   345 		// Allow all bearers if bearer availability check is not done
       
   346 		LOG( NetConLog::Printf(_L("\tSkipping bearer availability check")); )
       
   347 		SetAvailableBearers(KCommDbBearerCSD | KCommDbBearerLAN | KCommDbBearerVirtual);
       
   348 		}
       
   349 	}
       
   350 
       
   351 TInt CSelectionRequest::ExtractCommDbConnPref(const TConnPref& aBasePref, TCommDbConnPref& aCommDbPref)
       
   352 /**
       
   353 Extract a single TCommDbConnPref from the given TConnPref
       
   354 
       
   355 @param aBasePref the TConnPref
       
   356 @param aCommDbPref on return contains the TCommDbConnPref extracted from the TConnPref
       
   357 @return KErrNone if the TCommDbConnPref could be extracted, otherwise KErrArgument
       
   358 */
       
   359 	{
       
   360 	TInt err(KErrNone);
       
   361 
       
   362 	// if the TConnPref argument is a valid CommDb connection preference then cast it to one
       
   363 	switch(aBasePref.ExtensionId())
       
   364 		{
       
   365 		case TConnPref::EConnPrefCommDb:
       
   366 			// cast down to a TCommDbConnPref
       
   367 			aCommDbPref = TCommDbConnPref::Cast(aBasePref);
       
   368 			break;
       
   369 
       
   370 		case TConnPref::EConnPrefCommDbMulti:
       
   371 			{
       
   372 			// cast down to a TCommDbMultiConnPref
       
   373 			TCommDbMultiConnPref multiPrefs = TCommDbMultiConnPref::Cast(aBasePref);
       
   374 
       
   375 			// check the number of connection attempts
       
   376 			if(iConnectionAttempt > multiPrefs.ConnectionAttempts())
       
   377 				{
       
   378 				LOG( NetConLog::Printf(_L("\tError - maximum number of connection attempts (%d) reached"), multiPrefs.ConnectionAttempts()); )
       
   379 				err = KErrOverflow;
       
   380 				}
       
   381 			else
       
   382 				{
       
   383 				// connection attempt is ok, try to retrieve the connection preference for this attempt
       
   384 				err = multiPrefs.GetPreference(iConnectionAttempt, aCommDbPref);
       
   385 				}
       
   386 			
       
   387 			break;
       
   388 			}
       
   389 
       
   390 		case TConnPref::EConnPrefSnap:
       
   391 			err = KErrNotSupported;
       
   392 			break;
       
   393 			
       
   394 		case TConnPref::EConnPrefIdList:
       
   395 			{
       
   396 			const TCommIdList& pref = static_cast<const TCommIdList&>(aBasePref);
       
   397 			// check the number of connection attempts
       
   398 			if(iConnectionAttempt > pref.Count())
       
   399 				{
       
   400 				LOG( NetConLog::Printf(_L("\tError - the last AP (%d) reached"), pref.Count()); )
       
   401 				err = KErrOverflow;
       
   402 				}
       
   403 			else
       
   404 				{
       
   405 				// connection attempt is ok, try to retrieve the connection preference for this attempt
       
   406 				TInt iap = pref.Get(iConnectionAttempt-1);
       
   407 				aCommDbPref.SetIapId(iap);
       
   408 				aCommDbPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
       
   409 				//otherwise keep the default TCommDbConnPref class settings
       
   410 				}
       
   411 			break;
       
   412 			}
       
   413 			
       
   414 		case TConnPref::EConnPrefUnknown:
       
   415 			// a TConnPref - just ignore and use the default values from the connection preferences table
       
   416 			break;
       
   417 
       
   418 		default:
       
   419 			// some sort of unrecognised connection preference type - error the caller
       
   420 			err = KErrArgument;
       
   421 
       
   422 		}
       
   423 
       
   424 	return err;
       
   425 	}
       
   426 
       
   427 CStoreableOverrideSettings* CSelectionRequest::MapPrefsToOverridesL(TCommDbConnPref& aPrefs, const TConnectionSettings& aSettings)
       
   428 /**
       
   429 Convert user's connection preferences into an override setting
       
   430 
       
   431 @param aPrefs a set of connection preferences passed in by the user
       
   432 @param aSettings the current default connection preference settings
       
   433 @return override settings matching the supplied connection preferences or NULL if the TCommDbConnPref is empty
       
   434 @exception leaves if OOM or database access fails
       
   435 */
       
   436 	{
       
   437 	CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref iapPref;
       
   438 
       
   439 	// set rank to this connection attempt
       
   440 	iapPref.iRanking = aSettings.iRank;
       
   441 
       
   442 	// always use direction given in prefs
       
   443 	iapPref.iDirection = aSettings.iDirection;
       
   444 
       
   445 	// if specified, use the settings given in the connection
       
   446 	// preferences - otherwise read the default values from CommDb
       
   447 	TBool useOverrides(EFalse);
       
   448 
       
   449 	if(aPrefs.DialogPreference() != ECommDbDialogPrefUnknown)
       
   450 		{
       
   451 		LOG( NetConLog::Printf(_L("\tDialog Preference overriden to %d"), aPrefs.DialogPreference()); )
       
   452 
       
   453 		iapPref.iDialogPref = aPrefs.DialogPreference();
       
   454 		useOverrides = ETrue;
       
   455 		}
       
   456 	else
       
   457 		{
       
   458 		// use current connection preference dialog setting from database
       
   459 		iapPref.iDialogPref = aSettings.iDialogPref;
       
   460 		aPrefs.SetDialogPreference(aSettings.iDialogPref);
       
   461 		}
       
   462 
       
   463 	if(aPrefs.BearerSet() != KCommDbBearerUnknown)
       
   464 		{
       
   465 		LOG( NetConLog::Printf(_L("\tBearer Set overriden to %d"), aPrefs.BearerSet()); )
       
   466 
       
   467 		iapPref.iBearer.iBearerSet = aPrefs.BearerSet();
       
   468 		useOverrides = ETrue;
       
   469 		}
       
   470 	else
       
   471 		{
       
   472 		// use current connection preference BearerSet setting from database
       
   473 		iapPref.iBearer.iBearerSet = aSettings.iBearerSet;
       
   474 		aPrefs.SetBearerSet(aSettings.iBearerSet);
       
   475 		}
       
   476 	
       
   477 	if(aPrefs.IapId() != 0)
       
   478 		{
       
   479 		LOG( NetConLog::Printf(_L("\tIAP ID overriden to %d"), aPrefs.IapId()); )
       
   480 		
       
   481 		iapPref.iBearer.iIapId = aPrefs.IapId();
       
   482 		useOverrides = ETrue;
       
   483 
       
   484 		}
       
   485 	else
       
   486 		{
       
   487 		// use current connection preference IAP setting from database
       
   488 		iapPref.iBearer.iIapId = aSettings.iIAPId;
       
   489 		aPrefs.SetIapId(aSettings.iIAPId);
       
   490 		}
       
   491 
       
   492 	CStoreableOverrideSettings* overrides = NULL;
       
   493 	if (useOverrides)
       
   494 		{
       
   495 		overrides = CStoreableOverrideSettings::NewL(CCommDbOverrideSettings::EParamListPartial);
       
   496 		CleanupStack::PushL(overrides);
       
   497 		User::LeaveIfError(overrides->SetConnectionPreferenceOverride(iapPref));
       
   498 		CleanupStack::Pop(); // overrides
       
   499 		}
       
   500 
       
   501 	return overrides;
       
   502 	}
       
   503 
       
   504 void CSelectionRequest::SetAvailableBearers(TUint32 aBearerSet)
       
   505 /**
       
   506 Callback from the Network Controller when the bearer availability check is complete
       
   507 
       
   508 @param aBearerSet the set of available bearers
       
   509 */
       
   510 	{
       
   511 	LOG( NetConLog::Printf(_L("\tAvailable Bearer Set = %d"), aBearerSet); )
       
   512 
       
   513 	// is the selected service available?
       
   514 	TBool available;
       
   515 	if( (iSettings.iDialogPref == ECommDbDialogPrefPrompt) || 
       
   516 	    (iSettings.iDialogPref == ECommDbDialogPrefPromptIfWrongMode))
       
   517 		{
       
   518 		/* The ServiceAvailable check is not necessary in prompt mode, since the user hasn't had a chance yet
       
   519 		   to select the IAP. */
       
   520 		available = ETrue;
       
   521 		}
       
   522 	else
       
   523 		{
       
   524 		available = SelectedServiceAvailable(aBearerSet);
       
   525 		}
       
   526 
       
   527 	TRAPD(err, SelectIapL(available, aBearerSet));
       
   528 	if(err!=KErrNone)
       
   529 		{
       
   530 		LOG_DETAILED( NetConLog::Printf(_L("SelectionRequest %x\tSelectIapL left with %d"), this, err); )
       
   531 		RequestComplete(err);
       
   532 		}
       
   533 	}
       
   534 
       
   535 TBool CSelectionRequest::ServiceAvailableInAlternateMode(TUint32& aBearerSet, const TUint32 aAvailableBearerSet)
       
   536 /**
       
   537 The selected service is not available in this network mode - see if it is available in an alternate mode
       
   538 
       
   539 If the selected service is GPRS but the network mode is CDMA (or vice versa) then prompt the user
       
   540 to select an appropriate IAP.
       
   541 
       
   542 @param aBearerSet on entry the set of selected bearers, on exit the set of bearers to pass to the dialog box
       
   543 @param aAvailableBearerSet the set of available bearers
       
   544 @return ETrue if an alternate bearer is available in another network mode, otherwise EFalse
       
   545 */
       
   546 	{
       
   547 
       
   548 	// read network mode from database
       
   549 	RMobilePhone::TMobilePhoneNetworkMode networkMode(RMobilePhone::ENetworkModeUnknown);
       
   550 	networkMode = iDatabase->NetworkMode();
       
   551 
       
   552 	switch (networkMode)
       
   553 		{
       
   554 		case RMobilePhone::ENetworkModeGsm:
       
   555 		default:
       
   556 			LOG( NetConLog::Printf(_L("\tPacket data network mode is unknown")); )
       
   557 			break;
       
   558 		}
       
   559 
       
   560 	// we couldn't switch from GPRS to CDMA or
       
   561 	// vice-versa so see if CSD is available
       
   562 	if(aAvailableBearerSet & KCommDbBearerCSD)
       
   563 		{
       
   564 		LOG( NetConLog::Printf(_L("\tPSD selected but only CSD available")); )
       
   565 		aBearerSet = KCommDbBearerCSD;
       
   566 		return ETrue;
       
   567 		}
       
   568 	else
       
   569 		{
       
   570 		return EFalse;
       
   571 		}
       
   572 	}
       
   573 
       
   574 void CSelectionRequest::SelectIapL(const TBool aSelectedServiceAvailable, const TUint32 aAvailableBearerSet)
       
   575 /**
       
   576 Select which Internet Access Point to connect to
       
   577 
       
   578 @param aSelectedServiceAvailable whether the bearer required by the service is available
       
   579 @param aAvailableBearerSet the set of available bearers
       
   580 @exception leaves if database access leaves or if no service is available
       
   581 */
       
   582 	{
       
   583 
       
   584 	// set up connection preferences
       
   585 	TConnectionPrefs prefs;
       
   586 	prefs.iRank = iSettings.iRank;
       
   587 	prefs.iDirection = iSettings.iDirection;
       
   588 	prefs.iBearerSet = iSettings.iBearerSet;
       
   589 
       
   590 	TBool serviceAvailable(aSelectedServiceAvailable);
       
   591 	TInt error(KErrNotFound);
       
   592 
       
   593 	switch (iSettings.iDialogPref)
       
   594 		{
       
   595 		case ECommDbDialogPrefWarn:
       
   596 			LOG( NetConLog::Printf(_L("\tDialog box preference set to Warn")); )
       
   597 				
       
   598 			if(serviceAvailable)
       
   599 				{
       
   600 				// display IAP warning dialog box
       
   601 				// will call back to MDPOWarnComplete() when finished
       
   602 				TBuf<KCommsDbSvrMaxFieldLength> iapName;
       
   603 				iDatabase->GetDesL(TPtrC(IAP),TPtrC(COMMDB_NAME), iapName);
       
   604 				WarnNewConnection(prefs, &iapName, NULL, 0);
       
   605 				}
       
   606 			break;
       
   607 		case ECommDbDialogPrefDoNotPrompt:
       
   608 			LOG( NetConLog::Printf(_L("\tDialog box preference set to Do Not Prompt")); )
       
   609 			
       
   610 			if(serviceAvailable)
       
   611 				{
       
   612 				SelectIAPCompleteL(iSettings);
       
   613 				}
       
   614 			break;
       
   615 		case ECommDbDialogPrefPromptIfWrongMode:
       
   616 			LOG( NetConLog::Printf(_L("\tDialog box preference set to Prompt If Wrong Mode")); )
       
   617 		
       
   618 			if(serviceAvailable)
       
   619 				{
       
   620 				SelectIAPCompleteL(iSettings);
       
   621 				}
       
   622 			else
       
   623 				{
       
   624 				serviceAvailable = ServiceAvailableInAlternateMode(prefs.iBearerSet, aAvailableBearerSet);
       
   625 				if(serviceAvailable)
       
   626 					{
       
   627 					// display IAP selection dialog box
       
   628 					// will call back to MDPOSelectComplete() when finished
       
   629 					// Warning:  prefs does not contain the aAvailableBearerSet
       
   630 					// so the dialogue may be presented with unavailable Bearers
       
   631 					SelectConnection(prefs, iLastConnectionError);
       
   632 					}
       
   633 				else
       
   634 					{
       
   635 					error = KErrNetConNoGPRSNetwork;
       
   636 					}
       
   637 				}
       
   638 			break;
       
   639 		case ECommDbDialogPrefPrompt:
       
   640 		case ECommDbDialogPrefUnknown:
       
   641 		default:
       
   642 			LOG ( 
       
   643 				if(iSettings.iDialogPref == ECommDbDialogPrefPrompt)
       
   644 					NetConLog::Printf(_L("\tDialog box preference set to Prompt"));
       
   645 				else
       
   646 					{
       
   647 					if (iSettings.iDialogPref == ECommDbDialogPrefUnknown)
       
   648 						NetConLog::Printf(_L("\tDialog box preference set to Unknown"));
       
   649 					else
       
   650 						NetConLog::Printf(_L("\tDialog box preference not set"));
       
   651 					}
       
   652 				)
       
   653 
       
   654 			if(serviceAvailable)
       
   655 				{
       
   656 				// display IAP selection dialog box
       
   657 				// will call back to MDPOSelectComplete() when finished
       
   658 				// Warning:  prefs does not contain the aAvailableBearerSet
       
   659 				// so the dialogue may be presented with unavailable Bearers
       
   660 				SelectConnection(prefs);
       
   661 				}
       
   662 			break;
       
   663 		}
       
   664 
       
   665 	if (!serviceAvailable)
       
   666 		{
       
   667 		if(iDoBearerAvailability)
       
   668 			{
       
   669 			iController->CancelBearerAvailabilityCheck();
       
   670 			}
       
   671 		User::Leave(error);
       
   672 		}
       
   673 	}
       
   674 
       
   675 void CSelectionRequest::SelectAgentL()
       
   676 /**
       
   677 Decide whether to create a new agent or return an existing one
       
   678 
       
   679 Check to see if there is already a connection to the
       
   680 selected IAP and if so use the existing CNifAgentBase
       
   681 Otherwise start a new Agent to the IAP
       
   682 
       
   683 @exception leaves if database access or memory allocation
       
   684 leaves or if signal strength is not sufficient
       
   685 */
       
   686 	{
       
   687 	if(iDoBearerAvailability)
       
   688 		{
       
   689 		if (iSettings.iBearerType.Compare(TPtrC(MODEM_BEARER))==0)
       
   690 			{
       
   691 			// connection is not NTRAS so check that the received signal strength is still ok
       
   692 			User::LeaveIfError(iController->RequestSecondPhaseAvailability());
       
   693 			}
       
   694 		else
       
   695 			{
       
   696 			iController->CancelBearerAvailabilityCheck();
       
   697 			}
       
   698 		}
       
   699 
       
   700 	CNifAgentBase* agent=NULL;
       
   701 
       
   702 	TInt findErr = iController->FindExistingAgentForSelection(agent, iDatabase);
       
   703 
       
   704 	if(findErr==KErrNone)
       
   705 		{
       
   706 		// found an Agent already connected to this IAP
       
   707 		// retrieve the unique name of the agent and 
       
   708 		// complete the request
       
   709 		TNifAgentInfo info;
       
   710 		agent->Info(info);
       
   711 		LOG( NetConLog::Printf(_L("\tFound existing agent '%S' already connected to IAP %d"), &(info.iName), iSettings.iIAPId); )
       
   712 		SetAgentNameL(info.iName);
       
   713 		RequestComplete(KErrNone);
       
   714 		return;
       
   715 		}
       
   716 
       
   717 	// otherwise - no existing connection to IAP - try to load a new agent
       
   718 	LOG( NetConLog::Printf(_L("\tNo existing agent connected to IAP %d"), iSettings.iIAPId); )
       
   719 
       
   720 	// read name of Agent from the bearer table
       
   721 	TFileName agentName;
       
   722 	iDatabase->GetDesL(iSettings.iBearerType, TPtrC(AGENT_NAME), agentName);
       
   723 
       
   724 	// ask Nifman to create a new Agent, instantiating a new instance of an
       
   725 	// existing agent if needed (note that Nifman maintains ownership of the agent)
       
   726 	LOG( NetConLog::Printf(_L("\tCreating a new instance of agent '%S' for connection to IAP %d"), &agentName, iSettings.iIAPId); )
       
   727 	agent = Nif::CreateAgentL(agentName, ETrue);
       
   728 
       
   729 	// read the Agent's name
       
   730 	TNifAgentInfo info;
       
   731 	agent->Info(info);
       
   732 	SetAgentNameL(info.iName);
       
   733 	LOG( NetConLog::Printf(_L("\tAgent '%S' created for connection to IAP %d"), iAgentName, iSettings.iIAPId); )
       
   734 
       
   735 	if(iOverrides)
       
   736 		{
       
   737 		// set overrides in the Agent's database - ownership of the overrides is transferred to the agent
       
   738 		agent->SetOverridesL(iOverrides);
       
   739 		iOverrides = NULL;
       
   740 		}
       
   741 
       
   742 	// set connection settings in Agent's database
       
   743 	agent->SetConnectionSettingsL(iSettings);
       
   744 
       
   745 	// read the Network ID of the IAP
       
   746 	TUint32 networkId(0);
       
   747 	iDatabase->GetIntL(TPtrC(IAP), TPtrC(IAP_NETWORK), networkId);
       
   748 
       
   749 	// add the agent to the corresponding CNetwork object
       
   750 	iController->AddAgentToNetworkL(agent, networkId);
       
   751 
       
   752 	// store Agent Connection Info (IAP ID and Network ID)
       
   753 	iAgentConnInfo().iIAPId = iSettings.iIAPId;
       
   754 	iAgentConnInfo().iNetworkId = networkId;
       
   755 
       
   756 	// If this is the implicit connection and it has a commdb connection preference 
       
   757 	if ((iConnStartType == EConnStartImplicit) &&
       
   758 		(iConnPrefs.ExtensionId() == TConnPref::EConnPrefCommDb))
       
   759 		{
       
   760 		TCommDbConnPref* commdbPref = (TCommDbConnPref*) &iConnPrefs; // cast down to a TCommDbConnPref
       
   761 
       
   762 		if (commdbPref->IapId() == 0)
       
   763 			{
       
   764 			commdbPref->SetIapId(iSettings.iIAPId);
       
   765 			}
       
   766 		}
       
   767 
       
   768 	RequestComplete(KErrNone);
       
   769 	}
       
   770 
       
   771 void CSelectionRequest::SelectIAPCompleteL(const TConnectionSettings& aSettings)
       
   772 /**
       
   773 IAP Selection is complete
       
   774 
       
   775 At this point the selection is complete.  The Modem, Location and IAP have
       
   776 been selected so load the appropriate Agent and set these settings in the
       
   777 Agent.
       
   778 
       
   779 @param aSettings The set of (now complete) connection settings
       
   780 @exception leaves if database access or loading the Agent leaves
       
   781 */
       
   782  	{
       
   783  	 	
       
   784 	if((iSettings.iDialogPref == ECommDbDialogPrefPrompt ||
       
   785 		iSettings.iDialogPref == ECommDbDialogPrefPromptIfWrongMode)
       
   786 		&& iSettings.iIAPId != aSettings.iIAPId)
       
   787 		{
       
   788 		// update stored connection preferences to reflect user's choice
       
   789 		TCommDbConnPref commDbPref(TCommDbConnPref::Cast(iConnPrefs));
       
   790 		commDbPref.SetIapId(aSettings.iIAPId);
       
   791 		commDbPref.SetBearerSet(aSettings.iBearerSet);
       
   792 		iConnPrefs = commDbPref;
       
   793 		iSettings.iIAPId = aSettings.iIAPId;
       
   794 
       
   795 		// Convert the new connection preferences into some appropriate override settings
       
   796 		CStoreableOverrideSettings* overrides;
       
   797 		overrides = MapPrefsToOverridesL(commDbPref, iSettings);
       
   798 		if (overrides)
       
   799 			{
       
   800 			CleanupStack::PushL(overrides);
       
   801 			iDatabase->SetOverridesL(overrides);
       
   802 			CleanupStack::Pop();		// overrides
       
   803 			}
       
   804 		else
       
   805 			{
       
   806 			iDatabase->SetOverridesL(overrides);
       
   807 			}
       
   808 
       
   809 		if (iOverrides)
       
   810 			{
       
   811 			delete iOverrides;
       
   812 			}
       
   813 
       
   814 		iOverrides = overrides;
       
   815 		}
       
   816 	else
       
   817 		{
       
   818 		// Store selected IAP
       
   819 		iSettings.iIAPId = aSettings.iIAPId;
       
   820 		}
       
   821 
       
   822 	// write the selected settings to the DbAccess object and refresh the service settings
       
   823 	iDatabase->SetCurrentSettingsL(iSettings);
       
   824 	iDatabase->GetCurrentSettingsL(iSettings, iSettings.iDirection, iSettings.iRank);
       
   825 	iDatabase->GetServiceSettingsL(iSettings);
       
   826 
       
   827 	LOG (
       
   828 		NetConLog::Printf(_L("\tSelected IAP Id = %d"), iSettings.iIAPId);
       
   829 		NetConLog::Printf(_L("\tSelected Location Id = %d"), iSettings.iLocationId);
       
   830 		NetConLog::Printf(_L("\tSelected Bearer Type = '%S'"), &iSettings.iBearerType);
       
   831 		NetConLog::Printf(_L("\tSelected Bearer Id = %d"), iSettings.iBearerId);
       
   832 		NetConLog::Printf(_L("\tSelected Service Type = '%S'"), &iSettings.iServiceType);
       
   833 		NetConLog::Printf(_L("\tSelected Service Id = %d"), iSettings.iServiceId);
       
   834 		NetConLog::Printf(_L("\tSelected Bearer Set = %d"), iSettings.iBearerSet);
       
   835 		)
       
   836 
       
   837 	SelectAgentL();
       
   838 	}
       
   839 
       
   840 void CSelectionRequest::MDPOWarnComplete(TInt aError, TBool aResponse)
       
   841 /**
       
   842 Callback from the dialog processor when the "Warn about New Connection" dialog box has completed
       
   843 
       
   844 @param aError KErrCancel if the user selected "Cancel", otherwise KErrNone
       
   845 @param aReponse ETrue if the user selected "OK" otherwise EFalse
       
   846 */
       
   847 	{
       
   848 
       
   849 	if (aError == KErrNone)
       
   850 		{
       
   851 		if (aResponse)
       
   852 			{
       
   853 			// User did not cancel the connection
       
   854 			// Find or Load an Agent based on selection
       
   855 			TRAPD(err, SelectIAPCompleteL(iSettings));
       
   856 			if(err!=KErrNone)
       
   857 				{
       
   858 				LOG_DETAILED( NetConLog::Printf(_L("\tError %d loading agent"), err); )
       
   859 				RequestComplete(err);
       
   860 				}
       
   861 			}
       
   862 		else
       
   863 			{
       
   864 			// User cancelled the connection
       
   865 			aError = KErrCancel;
       
   866 			}
       
   867 		}
       
   868 
       
   869 	if(aError!=KErrNone)
       
   870 		{
       
   871 		iController->CancelBearerAvailabilityCheck();
       
   872 		RequestComplete(aError);
       
   873 		return;
       
   874 		}
       
   875 
       
   876 	}
       
   877 
       
   878 void CSelectionRequest::MDPOSelectComplete(TInt aError, const TConnectionSettings& aSettings)
       
   879 /**
       
   880 Callback from the dialog processor when the "Select IAP" dialog box has completed
       
   881 
       
   882 @param aError KErrNone if the dialog box complete ok, otherwise KErrCancel
       
   883 @param aSettings if there was no error will contain the CommDb ID of the selected IAP
       
   884 */
       
   885 	{
       
   886 
       
   887 	if(aError!=KErrNone)
       
   888 		{
       
   889 		iController->CancelBearerAvailabilityCheck();
       
   890 		RequestComplete(aError);
       
   891 		return;
       
   892 		}
       
   893 
       
   894 	// Find or Load an Agent based on user selection
       
   895 	// Assume that the selected bearer is available its an edge case when
       
   896 	// the selected bearer is not available or has now failed 
       
   897 	TRAPD(err, SelectIAPCompleteL(aSettings));
       
   898 	if(err!=KErrNone)
       
   899 		{
       
   900 		LOG_DETAILED( NetConLog::Printf(_L("SelectionRequest %x\tSelectIAPCompleteL left with error %d"), this, err); )
       
   901 		RequestComplete(err);
       
   902 		}
       
   903 	}
       
   904