|
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 |