|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * Implements CRfsHandles class. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 |
|
22 #include <e32std.h> |
|
23 #include <bautils.h> // BaflUtils |
|
24 #include <eikenv.h> // CEikonEnv |
|
25 #include <rfs.rsg> // rfs resource file |
|
26 #include <etelmm.h> |
|
27 #include <mmtsy_names.h> |
|
28 |
|
29 #include <featmgr.h> |
|
30 #include <e32property.h> |
|
31 #include <PSVariables.h> |
|
32 #include <ctsydomainpskeys.h> |
|
33 #include <ir_sock.h> |
|
34 #include <bt_subscribe.h> |
|
35 #include <wlaninternalpskeys.h> |
|
36 |
|
37 #include <starterclient.h> |
|
38 #include <syslangutil.h> // default language |
|
39 |
|
40 #include <secui.h> // security UI |
|
41 #include <secuisecurityhandler.h> |
|
42 |
|
43 #include <aknnotewrappers.h> |
|
44 #include <AknQueryDialog.h> |
|
45 |
|
46 #include <hal.h> |
|
47 #include <centralrepository.h> |
|
48 #include <CommonEngineDomainCRKeys.h> |
|
49 |
|
50 #include <data_caging_path_literals.hrh> |
|
51 |
|
52 #include "CleanupResetPointer.h" |
|
53 #include <AknWaitDialog.h> |
|
54 #include <pdpcontextmanagerpskeys.h> |
|
55 #include <pdpcontextmanagerinternalcrkeys.h> |
|
56 #include "rfsConnectionObserver.h" |
|
57 #include "rfsHandler.h" |
|
58 #include "rfsClient.h" |
|
59 #include "RfsTraces.h" |
|
60 |
|
61 |
|
62 _LIT( KRfsResourceFileName, "Z:rfs.rsc"); |
|
63 |
|
64 // CONSTANTS |
|
65 const TInt KPhoneIndex = 0; |
|
66 const TInt KRfsHandlerActivated = 0x0001; |
|
67 const TInt KRfsHandlerPhoneModuleLoaded = 0x0002; |
|
68 const TInt KRfsHandlerSecUiInitialized = 0x0004; |
|
69 const TInt KRfsHandlerInitDone = 0x0008; |
|
70 |
|
71 |
|
72 EXPORT_C CRfsHandler::CRfsHandler() |
|
73 { |
|
74 } |
|
75 |
|
76 EXPORT_C CRfsHandler::~CRfsHandler() |
|
77 { |
|
78 if ( iDestroyedPtr ) |
|
79 { |
|
80 *iDestroyedPtr = ETrue; |
|
81 iDestroyedPtr = NULL; |
|
82 } |
|
83 Cancel(); |
|
84 } |
|
85 |
|
86 // ----------------------------------------------------------------------------- |
|
87 // CRfsHandler::ActivateRfsL() |
|
88 // ----------------------------------------------------------------------------- |
|
89 EXPORT_C void CRfsHandler::ActivateRfsL( TRfsType aType, TBool aAskSecurityCodeFirst ) |
|
90 { |
|
91 TRACES("CRfsHandler::ActivateRfsL()"); |
|
92 |
|
93 // if already activated, do nothing |
|
94 if ( iFlags & KRfsHandlerActivated ) |
|
95 { |
|
96 TRACES("CRfsHandler::ActivateRfsL(): return"); |
|
97 return; |
|
98 } |
|
99 |
|
100 // load the resource file |
|
101 if ( !iResourceFileOffset ) |
|
102 { |
|
103 LoadResourceL(); |
|
104 } |
|
105 |
|
106 // Create a generic connection observer for closing all the active connections |
|
107 // if they exist. Currently there are only 2 types i.e. SIP and PDP |
|
108 CRfsConnectionObserver* connectionObserver = CRfsConnectionObserver::NewLC(); |
|
109 |
|
110 // This wil return a boolean: |
|
111 // ETrue: if all the active connections are closed i.e. both SIP and PDP |
|
112 // EFalse: if the user pressed 'Cancel' button in between any of the connection closing process |
|
113 iAlwaysOnlineConnectionClosed = connectionObserver->CloseAlwaysOnConnectionL(); |
|
114 |
|
115 // Ensure there aren't any active calls or data sessions |
|
116 if ( CheckConnectionsL() ) |
|
117 { |
|
118 // If there are some connections active, then we publish that the RFS has failed/stoped |
|
119 connectionObserver->ReOpenPDPConnection(); |
|
120 connectionObserver->ReportRfsFailureToSip(); |
|
121 CleanupStack::PopAndDestroy(connectionObserver); |
|
122 return; |
|
123 } |
|
124 |
|
125 // Puts 'this' in the cleanup stack so that Cancel() is called on leave |
|
126 CleanupStack::PushL( TCleanupItem( DoCleanup, this ) ); |
|
127 |
|
128 // Do other initialisations if not already done |
|
129 if ( !(iFlags & KRfsHandlerInitDone) ) |
|
130 { |
|
131 // create or open the needed resources |
|
132 User::LeaveIfError( iTelServer.Connect() ); |
|
133 iTelServer.LoadPhoneModule( KMmTsyModuleName ); |
|
134 iFlags |= KRfsHandlerPhoneModuleLoaded; |
|
135 iTelServer.SetExtendedErrorGranularity( RTelServer::EErrorExtended ); |
|
136 |
|
137 RTelServer::TPhoneInfo info; |
|
138 // get info about default phone (KPhoneIndex) |
|
139 User::LeaveIfError( iTelServer.GetPhoneInfo( KPhoneIndex, info ) ); |
|
140 User::LeaveIfError( iPhone.Open( iTelServer, info.iName ) ); |
|
141 TSecUi::InitializeLibL(); |
|
142 iFlags |= KRfsHandlerSecUiInitialized; |
|
143 iSecurityHandler = new( ELeave ) CSecurityHandler( iPhone ); |
|
144 } |
|
145 |
|
146 iFlags |= ( KRfsHandlerActivated | KRfsHandlerInitDone ); |
|
147 TBool proceed( ETrue ); |
|
148 |
|
149 // Setup information of whether the CRfsHandler instance has been |
|
150 // destroyed while one of the queries was on the screen. |
|
151 TBool thisDestroyed( EFalse ); |
|
152 iDestroyedPtr = &thisDestroyed; |
|
153 CleanupResetPointerPushL( iDestroyedPtr ); |
|
154 |
|
155 // Ask first query. |
|
156 if ( aAskSecurityCodeFirst ) |
|
157 { |
|
158 proceed = iSecurityHandler->AskSecCodeL(); |
|
159 } |
|
160 else |
|
161 { |
|
162 proceed = AskConfirmationL( thisDestroyed, aType ); |
|
163 } |
|
164 |
|
165 // If OK, ask second query. |
|
166 if ( proceed ) |
|
167 { |
|
168 if ( aAskSecurityCodeFirst ) |
|
169 { |
|
170 proceed = AskConfirmationL( thisDestroyed, aType ); |
|
171 } |
|
172 else |
|
173 { |
|
174 proceed = iSecurityHandler->AskSecCodeL(); |
|
175 } |
|
176 } |
|
177 |
|
178 // If all OK, then perform RFS. |
|
179 if ( proceed && !CheckConnectionsL() ) |
|
180 { |
|
181 // In case of deep level RFS, set the default language code here, before RFS reboot. |
|
182 if ( aType == ERfsDeep ) |
|
183 { |
|
184 SetDefaultLanguage(); |
|
185 } |
|
186 RStarterSession startersession; |
|
187 if( startersession.Connect() == KErrNone ) |
|
188 { |
|
189 // Displays information note to the user telling that the device will restart |
|
190 HBufC* prompt = iEnv->AllocReadResourceLC( R_DEVICE_RESTART ); |
|
191 CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue ); |
|
192 note->ExecuteLD( *prompt ); |
|
193 CleanupStack::PopAndDestroy( prompt ); |
|
194 |
|
195 if (aType == ERfsNormal ) startersession.Reset( RStarterSession::ENormalRFSReset ); |
|
196 else if (aType == ERfsDeep ) startersession.Reset( RStarterSession::EDeepRFSReset ); |
|
197 else startersession.Reset( RStarterSession::EUnknownReset ); |
|
198 startersession.Close(); |
|
199 } |
|
200 } |
|
201 // Inform SIP and PDP that the RFS has completed its operation. |
|
202 // The method is used for two purposes |
|
203 // 1. When we reopen the connection due to RFS failure. |
|
204 // 2. when we have successfully completed the RFS operation. |
|
205 // In both of the above cases the RFS has completed either successfully or not |
|
206 connectionObserver->ReOpenPDPConnection(); |
|
207 |
|
208 if(!proceed) |
|
209 { |
|
210 // Inform SIP that user has either selected not to perform the RFS |
|
211 // or has failed to provide the right security code due to which |
|
212 // RFS operation is not performed. So in this case the SIP should reopen |
|
213 // its connection. |
|
214 connectionObserver->ReportRfsFailureToSip(); |
|
215 } |
|
216 else |
|
217 { |
|
218 connectionObserver->ReportRfsCompletionToSip(); |
|
219 } |
|
220 |
|
221 if ( thisDestroyed ) // this object has already been destroyed |
|
222 { |
|
223 // remove cleanup items |
|
224 CleanupStack::Pop( 2 ); // this, iDestroyedPtr |
|
225 } |
|
226 else |
|
227 { |
|
228 // NULLs iDestroyedPtr and calls DoCleanup() |
|
229 CleanupStack::PopAndDestroy( 2 ); // this, iDestroyedPtr |
|
230 } |
|
231 |
|
232 CleanupStack::PopAndDestroy(connectionObserver); |
|
233 } |
|
234 |
|
235 // ----------------------------------------------------------------------------- |
|
236 // CRfsHandler::Cancel() |
|
237 // ----------------------------------------------------------------------------- |
|
238 EXPORT_C void CRfsHandler::Cancel() |
|
239 { |
|
240 TRACES("CRfsHandler::Cancel()"); |
|
241 |
|
242 // delete confirmation query |
|
243 delete iQuery; |
|
244 iQuery = NULL; |
|
245 |
|
246 // delete security handler |
|
247 if ( iSecurityHandler ) |
|
248 { |
|
249 iSecurityHandler->CancelSecCodeQuery(); |
|
250 |
|
251 delete iSecurityHandler; |
|
252 iSecurityHandler = NULL; |
|
253 } |
|
254 |
|
255 // uninitialize security UI |
|
256 if ( iFlags & KRfsHandlerSecUiInitialized ) |
|
257 { |
|
258 TSecUi::UnInitializeLib(); |
|
259 } |
|
260 |
|
261 // close ETel connection |
|
262 iPhone.Close(); |
|
263 |
|
264 if ( iFlags & KRfsHandlerPhoneModuleLoaded ) |
|
265 { |
|
266 iTelServer.UnloadPhoneModule( KMmTsyModuleName ); |
|
267 } |
|
268 |
|
269 iTelServer.Close(); |
|
270 |
|
271 // close the resource file |
|
272 if ( iResourceFileOffset ) |
|
273 { |
|
274 iEnv->DeleteResourceFile( iResourceFileOffset ); |
|
275 iResourceFileOffset = 0; |
|
276 } |
|
277 |
|
278 // finally, reset the flags |
|
279 iFlags = 0; |
|
280 } |
|
281 |
|
282 // ----------------------------------------------------------------------------- |
|
283 // CRfsHandler::LoadResourceL() |
|
284 // ----------------------------------------------------------------------------- |
|
285 void CRfsHandler::LoadResourceL() |
|
286 { |
|
287 TRACES("CRfsHandler::LoadResourceL()"); |
|
288 iEnv = CEikonEnv::Static(); |
|
289 |
|
290 // eikon environment is needed |
|
291 __ASSERT_DEBUG( iEnv, User::Invariant() ); |
|
292 |
|
293 TParse* fp = new(ELeave) TParse(); |
|
294 fp->Set(KRfsResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL); |
|
295 TFileName fileName( fp->FullName() ); |
|
296 delete fp; |
|
297 |
|
298 BaflUtils::NearestLanguageFile( iEnv->FsSession(), fileName ); |
|
299 iResourceFileOffset = iEnv->AddResourceFileL( fileName ); |
|
300 } |
|
301 |
|
302 // ----------------------------------------------------------------------------- |
|
303 // CRfsHandler::SetDefaultLanguage() |
|
304 // ----------------------------------------------------------------------------- |
|
305 void CRfsHandler::SetDefaultLanguage() const |
|
306 { |
|
307 TRACES("CRfsHandler::SetDefaultLanguage()"); |
|
308 |
|
309 CRepository* repository = NULL; |
|
310 TRAPD( err, repository = CRepository::NewL( KCRUidCommonEngineKeys ) ); |
|
311 if ( err == KErrNone ) |
|
312 { |
|
313 err = repository->Reset( KGSDisplayTxtLang ); |
|
314 TRACE_IF_ERROR_1("CRfsHandler::SetDefaultLanguage(): Failed to write language code: %d",err) |
|
315 delete repository; |
|
316 } |
|
317 else |
|
318 { |
|
319 TRACES1("CRfsHandler::SetDefaultLanguage(): Failed to open repository: %d", err); |
|
320 } |
|
321 } |
|
322 |
|
323 // ----------------------------------------------------------------------------- |
|
324 // CRfsHandler::AskConfirmationL() |
|
325 // ----------------------------------------------------------------------------- |
|
326 TBool CRfsHandler::AskConfirmationL( const TBool& aThisDestroyed, TRfsType aType ) |
|
327 { |
|
328 TRACES("CRfsHandler::AskConfirmationL()"); |
|
329 CleanupResetPointerPushL( iQuery ); |
|
330 |
|
331 // Show the confirmation query. |
|
332 |
|
333 iQuery = CAknQueryDialog::NewL(); // no tone as default |
|
334 |
|
335 TInt resourceId = ( aType == ERfsNormal ) ? R_CONFIRM_RFS : R_CONFIRM_DEEP_RFS; |
|
336 //iQuery->SetSize(); |
|
337 //iQuery->pref |
|
338 |
|
339 TBool ret = iQuery->ExecuteLD( resourceId ); |
|
340 |
|
341 if ( aThisDestroyed ) |
|
342 { |
|
343 // this object was destroyed |
|
344 ret = EFalse; |
|
345 // remove cleanup item |
|
346 CleanupStack::Pop(); |
|
347 } |
|
348 else |
|
349 { |
|
350 // NULLs iQuery |
|
351 CleanupStack::PopAndDestroy(); |
|
352 } |
|
353 |
|
354 return ret; |
|
355 } |
|
356 |
|
357 // ----------------------------------------------------------------------------- |
|
358 // CRfsHandler::DoCleanup() |
|
359 // ----------------------------------------------------------------------------- |
|
360 void CRfsHandler::DoCleanup( TAny* aAny ) |
|
361 { |
|
362 TRACES("CRfsHandler::DoCleanup()"); |
|
363 REINTERPRET_CAST( CRfsHandler*, aAny )->Cancel(); |
|
364 } |
|
365 |
|
366 // ----------------------------------------------------------------------------- |
|
367 // CRfsHandler::CheckConnectionsL() |
|
368 // ----------------------------------------------------------------------------- |
|
369 TBool CRfsHandler::CheckConnectionsL() |
|
370 { |
|
371 TInt callState( 0 ); |
|
372 TInt gprsState( 0 ); |
|
373 TInt wcdmaState( 0 ); |
|
374 TInt btState( 0 ); |
|
375 TInt irdaState( 0 ); |
|
376 TInt wlanState( 0 ); |
|
377 |
|
378 RProperty property; |
|
379 |
|
380 property.Attach( KPSUidCtsyCallInformation, KCTsyCallState ); |
|
381 property.Get( callState ); |
|
382 |
|
383 property.Attach( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothGetPHYCount ); |
|
384 property.Get( btState ); |
|
385 |
|
386 property.Attach( KIrdaPropertyCategory, KIrdaStatus ); |
|
387 property.Get( irdaState ); |
|
388 |
|
389 TUid categoryUid = { KUidSystemCategoryValue }; |
|
390 property.Attach( categoryUid, KPSUidGprsStatusValue ); |
|
391 property.Get( gprsState ); |
|
392 |
|
393 property.Attach( categoryUid, KPSUidWcdmaStatusValue ); |
|
394 property.Get( wcdmaState ); |
|
395 |
|
396 property.Attach( KPSUidWlan, KPSWlanIndicator ); |
|
397 property.Get( wlanState ); |
|
398 |
|
399 property.Close(); |
|
400 |
|
401 if (IsGprs()) |
|
402 { |
|
403 wcdmaState = EPSWcdmaUnattached; |
|
404 } |
|
405 else |
|
406 { |
|
407 gprsState = EPSGprsUnattached; |
|
408 } |
|
409 |
|
410 TRACES1("CRfsHandler::ActivateRfsL(): Call state: %d", callState); |
|
411 TRACES1("CRfsHandler::ActivateRfsL(): Gprs state: %d", gprsState); |
|
412 TRACES1("CRfsHandler::ActivateRfsL(): Wcdma state: %d", wcdmaState); |
|
413 TRACES1("CRfsHandler::ActivateRfsL(): BT state: %d", btState); |
|
414 TRACES1("CRfsHandler::ActivateRfsL(): IrDa State: %d", irdaState); |
|
415 TRACES1("CRfsHandler::ActivateRfsL(): WLan State: %d", wlanState); |
|
416 |
|
417 if( FeatureManager::FeatureSupported( KFeatureIdAlwaysOnlinePDPContext2 ) ) |
|
418 { |
|
419 if (iAlwaysOnlineConnectionClosed) |
|
420 { |
|
421 gprsState = KErrUnknown; |
|
422 wcdmaState = KErrUnknown; |
|
423 } |
|
424 } |
|
425 |
|
426 #ifndef __WINS__ //Do not allow RFS in emulator |
|
427 if (( callState != KErrUnknown && |
|
428 callState != EPSCTsyCallStateNone ) || |
|
429 ( gprsState != KErrUnknown && |
|
430 gprsState != EPSGprsUnattached && |
|
431 gprsState != EPSGprsAttach && |
|
432 gprsState != EPSGprsSuspend) || |
|
433 ( wcdmaState != KErrUnknown && |
|
434 wcdmaState != EPSWcdmaUnattached && |
|
435 wcdmaState != EPSWcdmaAttach && |
|
436 wcdmaState != EPSWcdmaSuspend) || |
|
437 ( btState ) || |
|
438 ( irdaState == TIrdaStatusCodes::EIrConnected ) || |
|
439 ( wlanState == EPSWlanIndicatorActive || wlanState == EPSWlanIndicatorActiveSecure )) |
|
440 #endif //__WINS__ |
|
441 { |
|
442 HBufC* prompt = iEnv->AllocReadResourceLC( R_ACTIVE_CALLS ); |
|
443 |
|
444 CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue ); |
|
445 |
|
446 note->ExecuteLD( *prompt ); |
|
447 |
|
448 CleanupStack::PopAndDestroy( prompt ); |
|
449 return ETrue; |
|
450 } |
|
451 |
|
452 return EFalse; |
|
453 } |
|
454 |
|
455 // ----------------------------------------------------------------------------- |
|
456 // CRfsHandler::IsGprs() |
|
457 // ----------------------------------------------------------------------------- |
|
458 TBool CRfsHandler::IsGprs() const |
|
459 { |
|
460 TRACES("CRfsHandler::IsGprs()"); |
|
461 RTelServer telServer; |
|
462 RMobilePhone mobilePhone; |
|
463 TInt error = telServer.Connect(); |
|
464 if ( error != KErrNone ) |
|
465 { |
|
466 TRACES("CRfsHandler::IsGprs(): Connect to RTelServer failed"); |
|
467 return ETrue; |
|
468 } |
|
469 error = telServer.LoadPhoneModule( KMmTsyModuleName ); |
|
470 if ( error != KErrNone ) |
|
471 { |
|
472 TRACES("CRfsHandler::IsGprs(): Loading phone module failed"); |
|
473 telServer.Close(); |
|
474 return ETrue; |
|
475 } |
|
476 RTelServer::TPhoneInfo phoneInfo; |
|
477 error = telServer.GetPhoneInfo( KPhoneIndex, phoneInfo ); |
|
478 if ( error != KErrNone ) |
|
479 { |
|
480 TRACES("CRfsHandler::IsGprs(): Getting phone info failed"); |
|
481 telServer.Close(); |
|
482 return ETrue; |
|
483 } |
|
484 error = mobilePhone.Open( telServer, phoneInfo.iName ); |
|
485 if ( error != KErrNone ) |
|
486 { |
|
487 TRACES("CRfsHandler::IsGprs(): Opening RMobilePhone failed"); |
|
488 telServer.Close(); |
|
489 return ETrue; |
|
490 } |
|
491 RMobilePhone::TMobilePhoneNetworkMode networkMode = RMobilePhone::ENetworkModeGsm; |
|
492 error = mobilePhone.GetCurrentMode( networkMode ); |
|
493 |
|
494 mobilePhone.Close(); |
|
495 telServer.Close(); |
|
496 |
|
497 if ( error == KErrNone && networkMode == RMobilePhone::ENetworkModeWcdma ) |
|
498 { |
|
499 TRACES("CRfsHandler::IsGprs(): Currently in 3G network"); |
|
500 return EFalse; |
|
501 } |
|
502 else |
|
503 { |
|
504 TRACES("CRfsHandler::IsGprs(): Currently in 2G network"); |
|
505 return ETrue; |
|
506 } |
|
507 } |
|
508 |
|
509 // End of File |