|
1 // Copyright (c) 2007-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 // Name : sipapnconfigurationhandler.cpp |
|
15 // Part of : SIP Profile Server |
|
16 // implementation |
|
17 // Version : 1.0 |
|
18 // |
|
19 #include <commsdattypesv1_1.h> |
|
20 #include <commdb.h> |
|
21 #include <commsdat.h> |
|
22 #include "sipapnconfigurationhandler.h" |
|
23 #include "SipProfileLog.h" |
|
24 |
|
25 // ----------------------------------------------------------------------------- |
|
26 // CSIPApnConfigurationHandler::NewL |
|
27 // ----------------------------------------------------------------------------- |
|
28 // |
|
29 CSIPApnConfigurationHandler* CSIPApnConfigurationHandler::NewL( |
|
30 MSIPApnChangeObserver& aObserver, TUint32 aIapId) |
|
31 { |
|
32 CSIPApnConfigurationHandler* self = |
|
33 CSIPApnConfigurationHandler::NewLC( aObserver, aIapId ); |
|
34 CleanupStack::Pop( self ); |
|
35 return self; |
|
36 } |
|
37 |
|
38 // ----------------------------------------------------------------------------- |
|
39 // CSIPApnConfigurationHandler::NewLC |
|
40 // ----------------------------------------------------------------------------- |
|
41 // |
|
42 CSIPApnConfigurationHandler* CSIPApnConfigurationHandler::NewLC( |
|
43 MSIPApnChangeObserver& aObserver, TUint32 aIapId) |
|
44 { |
|
45 CSIPApnConfigurationHandler* self = |
|
46 new ( ELeave ) CSIPApnConfigurationHandler( aObserver, aIapId ); |
|
47 CleanupStack::PushL( self ); |
|
48 self->ConstructL(); |
|
49 return self; |
|
50 } |
|
51 |
|
52 |
|
53 // ----------------------------------------------------------------------------- |
|
54 // CSIPApnConfigurationHandler::~CSIPApnConfigurationHandler |
|
55 // ----------------------------------------------------------------------------- |
|
56 // |
|
57 CSIPApnConfigurationHandler::~CSIPApnConfigurationHandler() |
|
58 { |
|
59 PROFILE_DEBUG1( |
|
60 "CSIPApnConfigurationHandler::~CSIPApnConfigurationHandler()" ) |
|
61 |
|
62 Cancel(); |
|
63 iConnection.Close(); |
|
64 iSocketSrv.Close(); |
|
65 |
|
66 delete iApnProposal; |
|
67 delete iCurrentApn; |
|
68 |
|
69 delete iPrimaryApn; |
|
70 delete iSecondaryApn; |
|
71 |
|
72 delete iCommsDatabase; |
|
73 |
|
74 PROFILE_DEBUG1( |
|
75 "CSIPApnConfigurationHandler::~CSIPApnConfigurationHandler() exit" ) |
|
76 } |
|
77 |
|
78 // ----------------------------------------------------------------------------- |
|
79 // CSIPApnConfigurationHandler::SetApnL |
|
80 // ----------------------------------------------------------------------------- |
|
81 // |
|
82 void CSIPApnConfigurationHandler::SetApnL( |
|
83 const TDesC8& aApn, |
|
84 TBool aUseSecureAuthentication, |
|
85 TBool aAllowAsync ) |
|
86 { |
|
87 PROFILE_DEBUG6( |
|
88 "CSIPApnConfigurationHandler::SetApnL() apn", aApn ) |
|
89 |
|
90 // Cancel if waiting for connection closure, will be re-issued if needed |
|
91 Cancel(); |
|
92 |
|
93 // Store current apn setting |
|
94 HBufC8* apn = aApn.AllocL(); |
|
95 delete iApnProposal; |
|
96 iApnProposal = apn; |
|
97 iApnUseSecureAuthProposal = aUseSecureAuthentication; |
|
98 |
|
99 if ( !ApnChangeNeededL( *iApnProposal ) ) |
|
100 { |
|
101 PROFILE_DEBUG1( |
|
102 "CSIPApnConfigurationHandler::SetApnL() apn already correct" ) |
|
103 |
|
104 SendApnChangedNotificationL( *iApnProposal ); |
|
105 return; |
|
106 } |
|
107 |
|
108 iMonitoringRetryCount = 0; |
|
109 |
|
110 ChangeApnIfNotInUseL( aAllowAsync ); |
|
111 |
|
112 PROFILE_DEBUG1( |
|
113 "CSIPApnConfigurationHandler::SetApnL() exit" ) |
|
114 } |
|
115 |
|
116 // ----------------------------------------------------------------------------- |
|
117 // CSIPApnConfigurationHandler::IsPrimaryApnUsed |
|
118 // ----------------------------------------------------------------------------- |
|
119 // |
|
120 TBool CSIPApnConfigurationHandler::IsPrimaryApnUsed() |
|
121 { |
|
122 return ( iCurrentApn && iCurrentApn->Compare( PrimaryApn() ) == 0 ); |
|
123 } |
|
124 |
|
125 // ----------------------------------------------------------------------------- |
|
126 // CSIPApnConfigurationHandler::ReadCurrentApnL |
|
127 // ----------------------------------------------------------------------------- |
|
128 // |
|
129 HBufC8* CSIPApnConfigurationHandler::ReadCurrentApnL() |
|
130 { |
|
131 HBufC8* apn(NULL); |
|
132 |
|
133 using namespace CommsDat; |
|
134 |
|
135 CMDBSession* db = CMDBSession::NewL( CMDBSession::LatestVersion() ); |
|
136 CleanupStack::PushL( db ); |
|
137 // Set any attributes if any |
|
138 db->SetAttributeMask( ECDHidden ); |
|
139 |
|
140 // Create an iap record |
|
141 CCDIAPRecord* iapRecord = |
|
142 static_cast<CCDIAPRecord*>( |
|
143 CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) ); |
|
144 CleanupStack::PushL( iapRecord ); |
|
145 |
|
146 iapRecord->SetRecordId( iIapId ); |
|
147 |
|
148 iapRecord->LoadL( *db ); |
|
149 |
|
150 // serviceType identifies the servicing table to use |
|
151 CMDBField<TDesC>* serviceType = |
|
152 ( CMDBField<TDesC>* )iapRecord->GetFieldByIdL( KCDTIdIAPServiceType ); |
|
153 |
|
154 __ASSERT_ALWAYS( serviceType && !serviceType->IsNull(), |
|
155 User::Leave( KErrNotFound ) ); |
|
156 // Only this service type has APN in the service record |
|
157 if ( TPtrC( KCDTypeNameOutgoingWCDMA ).Compare( *serviceType ) == 0 ) |
|
158 { |
|
159 PROFILE_DEBUG1( |
|
160 "CSIPApnConfigurationHandler::ReadCurrentApnL(), wcdma service" ) |
|
161 |
|
162 // iapRecord->iService field is a link to the servicing table. It tells |
|
163 // which record to use from the table. |
|
164 iapRecord->iService.LoadL( *db ); |
|
165 |
|
166 if ( !iapRecord->iService.iLinkedRecord ) |
|
167 { |
|
168 PROFILE_DEBUG1( |
|
169 "CSIPApnConfigurationHandler::ReadCurrentApnL(), creating linked" ) |
|
170 |
|
171 // Ownership of created record is transferred |
|
172 iapRecord->iService.iLinkedRecord = |
|
173 static_cast<CCDOutgoingGprsRecord*>( |
|
174 CCDRecordBase::RecordFactoryL( KCDTIdOutgoingGprsRecord ) ); |
|
175 iapRecord->iService.iLinkedRecord->SetRecordId( iapRecord->iService ); |
|
176 |
|
177 iapRecord->iService.iLinkedRecord->LoadL( *db ); |
|
178 } |
|
179 |
|
180 PROFILE_DEBUG1( |
|
181 "CSIPApnConfigurationHandler::ReadCurrentApnL(), linked service loaded" ) |
|
182 |
|
183 CCDOutgoingGprsRecord* serviceRecord = |
|
184 static_cast<CCDOutgoingGprsRecord*>( iapRecord->iService.iLinkedRecord ); |
|
185 |
|
186 TDesC& currApn = serviceRecord->iGPRSAPN.GetL(); |
|
187 PROFILE_DEBUG6( |
|
188 "CSIPApnConfigurationHandler::ReadCurrentApnL(), current apn", |
|
189 currApn ); |
|
190 |
|
191 apn = HBufC8::NewL( currApn.Length() ); |
|
192 apn->Des().Copy( currApn ); |
|
193 |
|
194 delete iCurrentApn; |
|
195 iCurrentApn = NULL; |
|
196 iCurrentApn = apn->AllocL(); |
|
197 } |
|
198 |
|
199 db->ClearAttributeMask( ECDHidden ); |
|
200 |
|
201 CleanupStack::PopAndDestroy( iapRecord ); |
|
202 CleanupStack::PopAndDestroy( db ); |
|
203 |
|
204 return apn; |
|
205 } |
|
206 |
|
207 // ----------------------------------------------------------------------------- |
|
208 // CSIPApnConfigurationHandler::HasPendingTasks |
|
209 // ----------------------------------------------------------------------------- |
|
210 // |
|
211 TBool CSIPApnConfigurationHandler::HasPendingTasks() const |
|
212 { |
|
213 return MonitoringState() != EMonitoringIdle; |
|
214 } |
|
215 |
|
216 // ----------------------------------------------------------------------------- |
|
217 // CSIPApnConfigurationHandler::DoCancel |
|
218 // ----------------------------------------------------------------------------- |
|
219 // |
|
220 void CSIPApnConfigurationHandler::DoCancel() |
|
221 { |
|
222 TSipApnMonitoringState currentState = MonitoringState(); |
|
223 |
|
224 PROFILE_DEBUG3( |
|
225 "CSIPApnConfigurationHandler::DoCancel() state", currentState ); |
|
226 |
|
227 if ( currentState == EMonitoringConnection ) |
|
228 { |
|
229 iConnection.CancelProgressNotification(); |
|
230 } |
|
231 else if ( currentState == EMonitoringDatabase ) |
|
232 { |
|
233 if ( iCommsDatabase ) |
|
234 { |
|
235 iCommsDatabase->CancelRequestNotification(); |
|
236 } |
|
237 } |
|
238 else |
|
239 { |
|
240 // NOP |
|
241 } |
|
242 |
|
243 SetMonitoringState( EMonitoringIdle ); |
|
244 |
|
245 PROFILE_DEBUG1( |
|
246 "CSIPApnConfigurationHandler::DoCancel() exit" ) |
|
247 } |
|
248 |
|
249 // ----------------------------------------------------------------------------- |
|
250 // CSIPApnConfigurationHandler::RunL |
|
251 // ----------------------------------------------------------------------------- |
|
252 // |
|
253 void CSIPApnConfigurationHandler::RunL() |
|
254 { |
|
255 TInt error = iStatus.Int(); |
|
256 |
|
257 TSipApnMonitoringState currentState = MonitoringState(); |
|
258 |
|
259 PROFILE_DEBUG3( |
|
260 "CSIPApnConfigurationHandler::RunL() err", error ); |
|
261 PROFILE_DEBUG3( |
|
262 "CSIPApnConfigurationHandler::RunL() state", currentState ); |
|
263 |
|
264 SetMonitoringState( EMonitoringIdle ); // Clear current state |
|
265 |
|
266 if ( currentState == EMonitoringConnection ) |
|
267 { |
|
268 ConnectionMonitoringCompletedL( error ); |
|
269 } |
|
270 else if ( currentState == EMonitoringDatabase ) |
|
271 { |
|
272 DatabaseMonitoringCompletedL( error ); |
|
273 } |
|
274 |
|
275 PROFILE_DEBUG1( |
|
276 "CSIPApnConfigurationHandler::RunL() exit" ) |
|
277 } |
|
278 |
|
279 // ----------------------------------------------------------------------------- |
|
280 // CSIPApnConfigurationHandler::RunError |
|
281 // ----------------------------------------------------------------------------- |
|
282 // |
|
283 TInt CSIPApnConfigurationHandler::RunError( TInt aError ) |
|
284 { |
|
285 PROFILE_DEBUG3( |
|
286 "CSIPApnConfigurationHandler::RunError() err", aError ); |
|
287 |
|
288 if ( aError != KErrNoMemory && aError != KErrNone ) |
|
289 { |
|
290 iObserver.ApnChanged( *iApnProposal, iIapId, aError ); |
|
291 aError = KErrNone; |
|
292 } |
|
293 |
|
294 return aError; |
|
295 } |
|
296 |
|
297 // ----------------------------------------------------------------------------- |
|
298 // CSIPApnConfigurationHandler::CSIPApnConfigurationHandler |
|
299 // ----------------------------------------------------------------------------- |
|
300 // |
|
301 CSIPApnConfigurationHandler::CSIPApnConfigurationHandler( |
|
302 MSIPApnChangeObserver& aObserver, TUint32 aIapId ) : |
|
303 CActive( CActive::EPriorityStandard ), |
|
304 iObserver( aObserver ), |
|
305 iMonitoringState( EMonitoringIdle ) |
|
306 { |
|
307 CActiveScheduler::Add( this ); |
|
308 iIapId = aIapId; |
|
309 } |
|
310 |
|
311 // ----------------------------------------------------------------------------- |
|
312 // CSIPApnConfigurationHandler::ConstructL |
|
313 // ----------------------------------------------------------------------------- |
|
314 // |
|
315 void CSIPApnConfigurationHandler::ConstructL() |
|
316 { |
|
317 PROFILE_DEBUG1( |
|
318 "CSIPApnConfigurationHandler::ConstructL()" ) |
|
319 |
|
320 User::LeaveIfError( iSocketSrv.Connect() ); |
|
321 |
|
322 PROFILE_DEBUG1( |
|
323 "CSIPApnConfigurationHandler::ConstructL() exit" ) |
|
324 } |
|
325 |
|
326 // ----------------------------------------------------------------------------- |
|
327 // CSIPApnConfigurationHandler::IsInUseL |
|
328 // ----------------------------------------------------------------------------- |
|
329 // |
|
330 TBool CSIPApnConfigurationHandler::IsInUseL( TConnectionInfo& aConnectionInfo ) |
|
331 { |
|
332 PROFILE_DEBUG1( |
|
333 "CSIPApnConfigurationHandler::IsInUseL()" ) |
|
334 |
|
335 TBool inUse( EFalse ); |
|
336 RConnection rcon; |
|
337 User::LeaveIfError( rcon.Open( iSocketSrv ) ); |
|
338 CleanupClosePushL( rcon ); |
|
339 |
|
340 TUint activeCount( 0 ); |
|
341 User::LeaveIfError( rcon.EnumerateConnections( activeCount ) ); |
|
342 |
|
343 if ( activeCount > 0 ) |
|
344 { |
|
345 // Indexing is unordinary |
|
346 for( TUint i = 1; i <= activeCount && !inUse; i++ ) |
|
347 { |
|
348 TPckgBuf<TConnectionInfoV2> connectionInfo; |
|
349 User::LeaveIfError( rcon.GetConnectionInfo( i, connectionInfo ) ); |
|
350 |
|
351 if ( connectionInfo().iIapId == iIapId ) |
|
352 { |
|
353 inUse = ETrue; |
|
354 aConnectionInfo = connectionInfo(); |
|
355 } |
|
356 } |
|
357 } |
|
358 |
|
359 CleanupStack::PopAndDestroy( &rcon ); |
|
360 |
|
361 PROFILE_DEBUG3( |
|
362 "CSIPApnConfigurationHandler::IsInUseL() inuse", inUse ) |
|
363 |
|
364 return inUse; |
|
365 } |
|
366 |
|
367 // ----------------------------------------------------------------------------- |
|
368 // CSIPApnConfigurationHandler::StartMonitoringConnectionL |
|
369 // ----------------------------------------------------------------------------- |
|
370 // |
|
371 void CSIPApnConfigurationHandler::StartMonitoringConnectionL( |
|
372 TConnectionInfo& aConnectionInfo ) |
|
373 { |
|
374 PROFILE_DEBUG1( |
|
375 "CSIPApnConfigurationHandler::StartMonitoringConnectionL()" ) |
|
376 |
|
377 __ASSERT_ALWAYS( !IsActive(), User::Leave( KErrInUse ) ); |
|
378 |
|
379 if ( iConnection.SubSessionHandle() ) |
|
380 { |
|
381 PROFILE_DEBUG1( |
|
382 "CSIPApnConfigurationHandler:: close existing connection" ) |
|
383 |
|
384 iConnection.Close(); |
|
385 } |
|
386 |
|
387 iConnectionInfo = aConnectionInfo; |
|
388 |
|
389 User::LeaveIfError( iConnection.Open( iSocketSrv ) ); |
|
390 |
|
391 PROFILE_DEBUG1( |
|
392 "CSIPApnConfigurationHandler:: attaching" ) |
|
393 |
|
394 User::LeaveIfError( |
|
395 iConnection.Attach( iConnectionInfo, RConnection::EAttachTypeMonitor ) ); |
|
396 |
|
397 WatchConnectionStatusChange(); |
|
398 |
|
399 PROFILE_DEBUG1( |
|
400 "CSIPApnConfigurationHandler::StartMonitoringConnectionL() exit" ) |
|
401 } |
|
402 |
|
403 // ----------------------------------------------------------------------------- |
|
404 // CSIPApnConfigurationHandler::WatchConnectionStatusChange |
|
405 // ----------------------------------------------------------------------------- |
|
406 // |
|
407 void CSIPApnConfigurationHandler::WatchConnectionStatusChange() |
|
408 { |
|
409 PROFILE_DEBUG1( |
|
410 "CSIPApnConfigurationHandler::WatchConnectionStatusChange()" ) |
|
411 |
|
412 Cancel(); |
|
413 |
|
414 iConnection.ProgressNotification( iProgress, iStatus, KConnectionClosed ); |
|
415 SetActive(); |
|
416 |
|
417 SetMonitoringState( EMonitoringConnection ); |
|
418 |
|
419 PROFILE_DEBUG1( |
|
420 "CSIPApnConfigurationHandler::WatchConnectionStatusChange(), exit" ) |
|
421 } |
|
422 |
|
423 // ----------------------------------------------------------------------------- |
|
424 // CSIPApnConfigurationHandler::WatchDatabaseStatusChangeL |
|
425 // ----------------------------------------------------------------------------- |
|
426 // |
|
427 void CSIPApnConfigurationHandler::WatchDatabaseStatusChangeL( TUint32 aIapId ) |
|
428 { |
|
429 PROFILE_DEBUG1( |
|
430 "CSIPApnConfigurationHandler::WatchDatabaseStatusChangeL()" ) |
|
431 |
|
432 Cancel(); |
|
433 |
|
434 if ( !iCommsDatabase ) |
|
435 { |
|
436 PROFILE_DEBUG1( |
|
437 "CSIPApnConfigurationHandler:: create commsdb" ) |
|
438 iCommsDatabase = CCommsDatabase::NewL(); |
|
439 } |
|
440 |
|
441 PROFILE_DEBUG1( |
|
442 "CSIPApnConfigurationHandler:: request notification" ) |
|
443 |
|
444 // Start monitoring for db events, there will be lots of them pouring in |
|
445 // as there's no filtering feature. We are interested only in |
|
446 // unlocked events. |
|
447 User::LeaveIfError( iCommsDatabase->RequestNotification( iStatus ) ); |
|
448 |
|
449 SetActive(); |
|
450 |
|
451 iIapId = aIapId; |
|
452 |
|
453 SetMonitoringState( EMonitoringDatabase ); |
|
454 |
|
455 PROFILE_DEBUG1( |
|
456 "CSIPApnConfigurationHandler::WatchDatabaseStatusChangeL(), exit" ) |
|
457 } |
|
458 |
|
459 // ----------------------------------------------------------------------------- |
|
460 // CSIPApnConfigurationHandler::ApnChangeNeededL |
|
461 // ----------------------------------------------------------------------------- |
|
462 // |
|
463 TBool CSIPApnConfigurationHandler::ApnChangeNeededL( const TDesC8& aApn ) |
|
464 { |
|
465 PROFILE_DEBUG1( |
|
466 "CSIPApnConfigurationHandler::ApnChangeNeededL()" ) |
|
467 |
|
468 TBool apnChangeNeeded( EFalse ); |
|
469 HBufC8* currentApn = ReadCurrentApnL(); |
|
470 |
|
471 if ( currentApn && currentApn->Compare( aApn ) != 0 ) |
|
472 { |
|
473 // Apn is not the same as wanted |
|
474 apnChangeNeeded = ETrue; |
|
475 } |
|
476 |
|
477 delete currentApn; |
|
478 |
|
479 PROFILE_DEBUG3( |
|
480 "CSIPApnConfigurationHandler::ApnChangeNeededL(), apnChangeNeeded", |
|
481 apnChangeNeeded ) |
|
482 return apnChangeNeeded; |
|
483 } |
|
484 |
|
485 // ----------------------------------------------------------------------------- |
|
486 // CSIPApnConfigurationHandler::ChangeApnIfNotInUseL |
|
487 // ----------------------------------------------------------------------------- |
|
488 // |
|
489 TBool CSIPApnConfigurationHandler::ChangeApnIfNotInUseL( TBool aAllowAsync ) |
|
490 { |
|
491 PROFILE_DEBUG1( |
|
492 "CSIPApnConfigurationHandler::ChangeApnIfNotInUseL()" ) |
|
493 |
|
494 TBool apnChanged( EFalse ); |
|
495 |
|
496 TConnectionInfo connectionInfo; |
|
497 if ( IsInUseL( connectionInfo ) ) |
|
498 { |
|
499 // If iap is in use, apn cannot be changed until everyone has stopped |
|
500 // using it |
|
501 __ASSERT_ALWAYS( aAllowAsync, User::Leave( KErrInUse ) ); |
|
502 |
|
503 StartMonitoringConnectionL( connectionInfo ); |
|
504 } |
|
505 else |
|
506 { |
|
507 apnChanged = IssueApnChangeL( |
|
508 iIapId, *iApnProposal, iApnUseSecureAuthProposal, aAllowAsync ); |
|
509 } |
|
510 |
|
511 PROFILE_DEBUG3( |
|
512 "CSIPApnConfigurationHandler::ChangeApnIfNotInUseL(), apnChanged", |
|
513 apnChanged ) |
|
514 return apnChanged; |
|
515 } |
|
516 |
|
517 // ----------------------------------------------------------------------------- |
|
518 // CSIPApnConfigurationHandler::IssueApnChangeL |
|
519 // ----------------------------------------------------------------------------- |
|
520 // |
|
521 TBool CSIPApnConfigurationHandler::IssueApnChangeL( |
|
522 TUint32 aIapId, |
|
523 const TDesC8& aApn, |
|
524 TBool aUseSecureAuthentication, |
|
525 TBool aAllowAsync ) |
|
526 { |
|
527 PROFILE_DEBUG1( |
|
528 "CSIPApnConfigurationHandler::IssueApnChangeL()" ) |
|
529 |
|
530 TBool apnChanged( EFalse ); |
|
531 if(aIapId == iIapId) |
|
532 { |
|
533 TRAPD( err, ChangeApnL( aApn, aUseSecureAuthentication ) ); |
|
534 if ( err == KErrLocked || err == KErrAccessDenied ) |
|
535 { |
|
536 // Database transaction lock may cause errors if some other client is |
|
537 // accessing the same record at the same time. In such case, start |
|
538 // monitoring for database events and retry apn changing at each |
|
539 // unlock/rollback event. |
|
540 |
|
541 __ASSERT_ALWAYS( aAllowAsync, User::Leave( KErrInUse ) ); |
|
542 |
|
543 WatchDatabaseStatusChangeL( iIapId ); |
|
544 } |
|
545 else |
|
546 { |
|
547 User::LeaveIfError( err ); |
|
548 apnChanged = ETrue; |
|
549 } |
|
550 } |
|
551 |
|
552 PROFILE_DEBUG3( |
|
553 "CSIPApnConfigurationHandler::IssueApnChangeL(), apnChanged", |
|
554 apnChanged ) |
|
555 return apnChanged; |
|
556 } |
|
557 |
|
558 // ----------------------------------------------------------------------------- |
|
559 // CSIPApnConfigurationHandler::ChangeApnL |
|
560 // ----------------------------------------------------------------------------- |
|
561 // |
|
562 void CSIPApnConfigurationHandler::ChangeApnL( |
|
563 const TDesC8& aApn, |
|
564 TBool aUseSecureAuthentication ) |
|
565 { |
|
566 PROFILE_DEBUG1( |
|
567 "CSIPApnConfigurationHandler::ChangeApnL()" ) |
|
568 |
|
569 using namespace CommsDat; |
|
570 |
|
571 CMDBSession* db = CMDBSession::NewL( CMDBSession::LatestVersion() ); |
|
572 CleanupStack::PushL( db ); |
|
573 // Set attributes so that also protected iaps can be accessed |
|
574 db->SetAttributeMask( ECDHidden | ECDProtectedWrite ); |
|
575 |
|
576 // Create an iap record |
|
577 CCDIAPRecord* iapRecord = |
|
578 static_cast<CCDIAPRecord*>( |
|
579 CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) ); |
|
580 CleanupStack::PushL( iapRecord ); |
|
581 |
|
582 iapRecord->SetRecordId( iIapId ); |
|
583 |
|
584 TBool clearedProtectedIap = ClearProtectedRecord( *iapRecord ); |
|
585 |
|
586 iapRecord->LoadL( *db ); |
|
587 |
|
588 iapRecord->iService.LoadL( *db ); |
|
589 |
|
590 if ( !iapRecord->iService.iLinkedRecord ) |
|
591 { |
|
592 // Ownership of created record is transferred |
|
593 iapRecord->iService.iLinkedRecord = |
|
594 static_cast<CCDOutgoingGprsRecord*>( |
|
595 CCDRecordBase::RecordFactoryL( KCDTIdOutgoingGprsRecord ) ); |
|
596 |
|
597 iapRecord->iService.iLinkedRecord->SetRecordId( iapRecord->iService ); |
|
598 iapRecord->iService.iLinkedRecord->LoadL( *db ); |
|
599 } |
|
600 |
|
601 PROFILE_DEBUG1( |
|
602 "CSIPApnConfigurationHandler::ChangeApnL linked service loaded" ) |
|
603 |
|
604 CCDOutgoingGprsRecord* serviceRecord = |
|
605 static_cast<CCDOutgoingGprsRecord*>( iapRecord->iService.iLinkedRecord ); |
|
606 |
|
607 TBool clearedProtectedService = ClearProtectedRecord( *serviceRecord ); |
|
608 |
|
609 PROFILE_DEBUG6( |
|
610 "CSIPApnConfigurationHandler::ChangeApnL() curr apn", |
|
611 serviceRecord->iGPRSAPN.GetL() ); |
|
612 |
|
613 HBufC* apn = HBufC::NewLC( aApn.Length() ); |
|
614 apn->Des().Copy( aApn ); |
|
615 serviceRecord->iGPRSAPN.SetL( *apn ); |
|
616 CleanupStack::PopAndDestroy( apn ); |
|
617 |
|
618 PROFILE_DEBUG3( |
|
619 "CSIPApnConfigurationHandler::ChangeApnL() curr security", |
|
620 serviceRecord->iGPRSDisablePlainTextAuth ); |
|
621 |
|
622 // Set CHAP/PAP (CHAP is enabled if plain text auth is disabled) |
|
623 serviceRecord->iGPRSDisablePlainTextAuth = aUseSecureAuthentication; |
|
624 |
|
625 PROFILE_DEBUG3( |
|
626 "CSIPApnConfigurationHandler::ChangeApnL() new security", |
|
627 aUseSecureAuthentication ) |
|
628 |
|
629 serviceRecord->ModifyL( *db ); |
|
630 |
|
631 if ( clearedProtectedIap ) |
|
632 { |
|
633 // Set protection back |
|
634 iapRecord->SetAttributes( ECDProtectedWrite ); |
|
635 iapRecord->ModifyL( *db ); |
|
636 } |
|
637 |
|
638 if ( clearedProtectedService ) |
|
639 { |
|
640 // Set protection back |
|
641 serviceRecord->SetAttributes( ECDProtectedWrite ); |
|
642 serviceRecord->ModifyL( *db ); |
|
643 } |
|
644 |
|
645 db->ClearAttributeMask( ECDHidden | ECDProtectedWrite ); |
|
646 |
|
647 CleanupStack::PopAndDestroy( iapRecord ); |
|
648 CleanupStack::PopAndDestroy( db ); |
|
649 |
|
650 SendApnChangedNotificationL( aApn ); |
|
651 |
|
652 PROFILE_DEBUG1( |
|
653 "CSIPApnConfigurationHandler::ChangeApnL(), exit" ) |
|
654 } |
|
655 |
|
656 // ----------------------------------------------------------------------------- |
|
657 // CSIPApnConfigurationHandler::ClearProtectedRecord |
|
658 // ----------------------------------------------------------------------------- |
|
659 // |
|
660 TBool CSIPApnConfigurationHandler::ClearProtectedRecord( |
|
661 CommsDat::CCDRecordBase& aRecord ) |
|
662 { |
|
663 TBool cleared( EFalse ); |
|
664 if ( aRecord.IsSetAttribute( CommsDat::ECDProtectedWrite ) ) |
|
665 { |
|
666 aRecord.ClearAttributes( CommsDat::ECDProtectedWrite ); |
|
667 cleared = ETrue; |
|
668 } |
|
669 return cleared; |
|
670 } |
|
671 |
|
672 // ----------------------------------------------------------------------------- |
|
673 // CSIPApnConfigurationHandler::SetMonitoringState |
|
674 // ----------------------------------------------------------------------------- |
|
675 // |
|
676 void CSIPApnConfigurationHandler::SetMonitoringState( |
|
677 TSipApnMonitoringState aMonitoringState ) |
|
678 { |
|
679 PROFILE_DEBUG3( |
|
680 "CSIPApnConfigurationHandler::SetMonitoringState, state", |
|
681 aMonitoringState ); |
|
682 iMonitoringState = aMonitoringState; |
|
683 } |
|
684 |
|
685 // ----------------------------------------------------------------------------- |
|
686 // CSIPApnConfigurationHandler::MonitoringState |
|
687 // ----------------------------------------------------------------------------- |
|
688 // |
|
689 CSIPApnConfigurationHandler::TSipApnMonitoringState |
|
690 CSIPApnConfigurationHandler::MonitoringState() const |
|
691 { |
|
692 return iMonitoringState; |
|
693 } |
|
694 |
|
695 // ----------------------------------------------------------------------------- |
|
696 // CSIPApnConfigurationHandler::ConnectionMonitoringCompletedL |
|
697 // ----------------------------------------------------------------------------- |
|
698 // |
|
699 void CSIPApnConfigurationHandler::ConnectionMonitoringCompletedL( TInt aError ) |
|
700 { |
|
701 PROFILE_DEBUG3( |
|
702 "CSIPApnConfigurationHandler:: progress.err", |
|
703 iProgress().iError ); |
|
704 PROFILE_DEBUG3( |
|
705 "CSIPApnConfigurationHandler:: progress.stage", |
|
706 iProgress().iStage ); |
|
707 |
|
708 if ( !aError ) |
|
709 { |
|
710 if ( iProgress().iStage == KConnectionClosed || |
|
711 iProgress().iStage == KLinkLayerClosed || |
|
712 iProgress().iStage == KConnectionFailure ) |
|
713 { |
|
714 // Changing is now possible |
|
715 IssueApnChangeL( |
|
716 iConnectionInfo().iIapId, *iApnProposal, iApnUseSecureAuthProposal ); |
|
717 } |
|
718 else if ( !iProgress().iError ) |
|
719 { |
|
720 // Changing not yet possible. Request further notifications |
|
721 // from RConnection only if possible |
|
722 WatchConnectionStatusChange(); |
|
723 } |
|
724 } |
|
725 } |
|
726 |
|
727 // ----------------------------------------------------------------------------- |
|
728 // CSIPApnConfigurationHandler::DatabaseMonitoringCompletedL |
|
729 // Only interested about unlock and rollback events. When such occur, it might |
|
730 // be possible that other client has released transaction lock and we can |
|
731 // finally modify apn. Note: cancelling notifications may complete with |
|
732 // KErrCancel, in that case we don't want to reissue notifications. |
|
733 // ----------------------------------------------------------------------------- |
|
734 // |
|
735 void CSIPApnConfigurationHandler::DatabaseMonitoringCompletedL( TInt aError ) |
|
736 { |
|
737 TBool apnChanged( EFalse ); |
|
738 if ( aError == KErrCancel ) |
|
739 { |
|
740 return; |
|
741 } |
|
742 |
|
743 if ( aError == RDbNotifier::EUnlock || |
|
744 aError == RDbNotifier::ERollback || |
|
745 aError == RDbNotifier::EClose ) |
|
746 { |
|
747 // Changing may be now possible, if not, db notifications or connection |
|
748 // monitoring is re-enabled inside following method |
|
749 apnChanged = ChangeApnIfNotInUseL(); |
|
750 } |
|
751 else |
|
752 { |
|
753 WatchDatabaseStatusChangeL( iIapId ); |
|
754 } |
|
755 |
|
756 // Have some safety limit for monitoring as it's not guaranteed that |
|
757 // db lock is ever released -> avoid unnecessary battery consumption |
|
758 if ( !apnChanged ) |
|
759 { |
|
760 iMonitoringRetryCount++; |
|
761 PROFILE_DEBUG3( |
|
762 "DatabaseMonitoringCompletedL:: retrycount", |
|
763 iMonitoringRetryCount ); |
|
764 |
|
765 if ( iMonitoringRetryCount > KSecondaryApnMaxRetryCount ) |
|
766 { |
|
767 PROFILE_DEBUG1( |
|
768 "CSIPApnConfigurationHandler:: max retries reached!" ) |
|
769 Cancel(); |
|
770 |
|
771 User::Leave( KErrAbort ); |
|
772 } |
|
773 } |
|
774 } |
|
775 |
|
776 // ----------------------------------------------------------------------------- |
|
777 // CSIPApnConfigurationHandler::SendApnChangedNotificationL |
|
778 // ----------------------------------------------------------------------------- |
|
779 // |
|
780 void CSIPApnConfigurationHandler::SendApnChangedNotificationL( |
|
781 const TDesC8& aNewApn, |
|
782 TInt aError ) |
|
783 { |
|
784 if ( !IsPrimaryApnUsed() ) |
|
785 { |
|
786 HBufC8* currentApn = aNewApn.AllocL(); |
|
787 delete iCurrentApn; |
|
788 iCurrentApn = NULL; |
|
789 iCurrentApn = currentApn; |
|
790 |
|
791 iObserver.ApnChanged( *iCurrentApn, iIapId, aError ); |
|
792 } |
|
793 } |
|
794 |
|
795 // ----------------------------------------------------------------------------- |
|
796 // CSIPApnConfigurationHandler::IsFailed |
|
797 // ----------------------------------------------------------------------------- |
|
798 // |
|
799 TBool CSIPApnConfigurationHandler::IsFailed() const |
|
800 { |
|
801 return iIsFailed; |
|
802 } |
|
803 |
|
804 // ----------------------------------------------------------------------------- |
|
805 // CSIPApnConfigurationHandler::IsFailed |
|
806 // ----------------------------------------------------------------------------- |
|
807 // |
|
808 void CSIPApnConfigurationHandler::SetFailed( TBool aIsFailed, TBool aIsFatalFailure ) |
|
809 { |
|
810 PROFILE_DEBUG4( |
|
811 "CSIPApnConfigurationHandler::SetFailed() (failed, fatal)", |
|
812 aIsFailed, aIsFatalFailure ) |
|
813 PROFILE_DEBUG4( |
|
814 "CSIPApnConfigurationHandler::SetFailed() (curr failed, curr fatal)", |
|
815 iIsFailed, iIsFatalFailure ) |
|
816 |
|
817 if ( iIsFailed != aIsFailed ) |
|
818 { |
|
819 TInt err( KErrNone ); |
|
820 if ( aIsFailed ) |
|
821 { |
|
822 TRAP( err, SetApnL( |
|
823 SecondaryApn(), ETrue, ETrue) ); |
|
824 } |
|
825 else if ( !iIsFatalFailure ) |
|
826 { |
|
827 TRAP( err, SetApnL( |
|
828 PrimaryApn(), EFalse, ETrue) ); |
|
829 } |
|
830 else |
|
831 { |
|
832 PROFILE_DEBUG1( |
|
833 "CSIPApnConfigurationHandler::SetFailed(), ignored" ) |
|
834 |
|
835 // State change is ignored as state change to "not-failed" was |
|
836 // attempted while fatal error had occured earlier |
|
837 aIsFailed = iIsFailed; |
|
838 aIsFatalFailure = iIsFatalFailure; |
|
839 } |
|
840 |
|
841 if ( err ) |
|
842 { |
|
843 PROFILE_DEBUG3( |
|
844 "CSIPApnConfigurationHandler::SetFailed(), Setting apn failed, err", err ) |
|
845 } |
|
846 } |
|
847 |
|
848 iIsFailed = aIsFailed; |
|
849 iIsFatalFailure = aIsFatalFailure; |
|
850 } |
|
851 |
|
852 // ---------------------------------------------------------------------------- |
|
853 // CSIPApnConfigurationHandler::PrimaryApn |
|
854 // ---------------------------------------------------------------------------- |
|
855 // |
|
856 TDesC8& CSIPApnConfigurationHandler::PrimaryApn() |
|
857 { |
|
858 return *iPrimaryApn; |
|
859 } |
|
860 |
|
861 // ---------------------------------------------------------------------------- |
|
862 // CSIPApnConfigurationHandler::SecondaryApn |
|
863 // ---------------------------------------------------------------------------- |
|
864 // |
|
865 TDesC8& CSIPApnConfigurationHandler::SecondaryApn() |
|
866 { |
|
867 return *iSecondaryApn; |
|
868 } |
|
869 |
|
870 // ----------------------------------------------------------------------------- |
|
871 // CSIPApnConfigurationHandler::HandlerIapId |
|
872 // ----------------------------------------------------------------------------- |
|
873 // |
|
874 TUint32 CSIPApnConfigurationHandler::HandlerIapId() const |
|
875 { |
|
876 return iIapId; |
|
877 } |
|
878 |
|
879 // ----------------------------------------------------------------------------- |
|
880 // CSIPApnConfigurationHandler::UpdateApnL |
|
881 // ----------------------------------------------------------------------------- |
|
882 // |
|
883 void CSIPApnConfigurationHandler::UpdateApnL( TBool aIsPrimaryApn, const TDesC8& aApn ) |
|
884 { |
|
885 PROFILE_DEBUG3( |
|
886 "CSIPApnConfigurationHandler::UpdateApnL isPrimary", aIsPrimaryApn ) |
|
887 PROFILE_DEBUG6( |
|
888 "CSIPApnConfigurationHandler::UpdateApnL apn", aApn ) |
|
889 |
|
890 HBufC8* newApn = aApn.AllocL(); |
|
891 if ( aIsPrimaryApn ) |
|
892 { |
|
893 delete iPrimaryApn; |
|
894 iPrimaryApn = newApn; |
|
895 } |
|
896 else |
|
897 { |
|
898 delete iSecondaryApn; |
|
899 iSecondaryApn = newApn; |
|
900 } |
|
901 } |
|
902 |
|
903 // End of file |