|
1 /* |
|
2 * Copyright (c) 2010 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 * A class which takes care of reading the possible new |
|
16 * service centres from SIM and adds them to pda-side Sms Settings. |
|
17 * |
|
18 */ |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <mtuireg.h> |
|
22 #include <mmlist.h> |
|
23 #include <smutset.h> |
|
24 #include <csmsaccount.h> |
|
25 #include <centralrepository.h> |
|
26 #include <MessagingVariant.hrh> |
|
27 #include <MessagingInternalCRKeys.h> |
|
28 #include <startupdomainpskeys.h> |
|
29 #include <rcustomerserviceprofilecache.h> |
|
30 |
|
31 #include "simscnumberdetector.h" |
|
32 #include "startupmonitor.h" |
|
33 |
|
34 #include "debugtraces.h" |
|
35 |
|
36 |
|
37 |
|
38 // ================= MEMBER FUNCTIONS ======================= |
|
39 |
|
40 EXPORT_C CMsgSimOperation* CMsgSimOperation::NewL( |
|
41 MSimOperationObserver& aObserver ) |
|
42 { |
|
43 QDEBUG_WRITE("CMsgSimOperation::NewL enter") |
|
44 |
|
45 CMsgSimOperation* self = new (ELeave) CMsgSimOperation(aObserver); |
|
46 CleanupStack::PushL(self); |
|
47 self->ConstructL(); |
|
48 CleanupStack::Pop(self); |
|
49 |
|
50 QDEBUG_WRITE("CMsgSimOperation::NewL End") |
|
51 return self; |
|
52 |
|
53 |
|
54 } |
|
55 |
|
56 |
|
57 CMsgSimOperation::CMsgSimOperation(MSimOperationObserver& aObserver) : |
|
58 iRetryCount(0), iObserver(aObserver) |
|
59 { |
|
60 } |
|
61 |
|
62 void CMsgSimOperation::ConstructL() |
|
63 { |
|
64 QDEBUG_WRITE("CMsgSimOperation::ConstructL enter") |
|
65 |
|
66 iCenRepSession = CRepository::NewL(KCRUidSmum); |
|
67 |
|
68 // initialise |
|
69 iMsvSession = CMsvSession::OpenSyncL(*this); |
|
70 |
|
71 // Create the SMS Service |
|
72 TMsvId serviceId = CreateSmsServiceL(); |
|
73 |
|
74 // Update the SMS cenrep with the default settings. |
|
75 CreateDefaultSettingsL(serviceId); |
|
76 |
|
77 iClientRegistry = CClientMtmRegistry::NewL(*iMsvSession); |
|
78 iSmsClientMtm = |
|
79 STATIC_CAST( CSmsClientMtm*, iClientRegistry->NewMtmL( KUidMsgTypeSMS )); |
|
80 |
|
81 // Start the System state monitor |
|
82 iStartupMonitor = CStartUpMonitor::NewL(this); |
|
83 |
|
84 QDEBUG_WRITE("CMsgSimOperation::ConstructL exit") |
|
85 } |
|
86 |
|
87 TMsvId CMsgSimOperation::CreateSmsServiceL() |
|
88 { |
|
89 TMsvId serviceEntryId = KMsvNullIndexEntryId; |
|
90 TInt err = KErrNone; |
|
91 TRAP( err, serviceEntryId = ServiceIdL()); |
|
92 |
|
93 // If no service, create one |
|
94 if (err == KErrNotFound) |
|
95 { |
|
96 TMsvEntry entry; |
|
97 entry.iMtm = KUidMsgTypeSMS; |
|
98 entry.iType = KUidMsvServiceEntry; |
|
99 entry.SetReadOnly(EFalse); |
|
100 entry.SetVisible(EFalse); |
|
101 entry.iDate.HomeTime(); |
|
102 entry.iDetails.Set(KSmsService); |
|
103 CMsvEntry* root = iMsvSession->GetEntryL(KMsvRootIndexEntryId); |
|
104 CleanupStack::PushL(root); |
|
105 |
|
106 // In case no root store, create one... |
|
107 if (!root->HasStoreL()) |
|
108 { |
|
109 // --- The entry does not have a store. EditStoreL() will create one --- |
|
110 CMsvStore* store = root->EditStoreL(); |
|
111 CleanupStack::PushL(store); |
|
112 store->CommitL(); |
|
113 CleanupStack::PopAndDestroy(); // store |
|
114 store = NULL; // destroyed |
|
115 } |
|
116 root->CreateL(entry); |
|
117 CleanupStack::PopAndDestroy(); // root |
|
118 serviceEntryId = entry.Id(); |
|
119 |
|
120 } |
|
121 return serviceEntryId; |
|
122 } |
|
123 |
|
124 |
|
125 TMsvId CMsgSimOperation::ServiceIdL() |
|
126 { |
|
127 TMsvId id = KMsvNullIndexEntryId; |
|
128 CMsvEntry* root = iMsvSession->GetEntryL(KMsvRootIndexEntryId); |
|
129 CleanupStack::PushL(root); |
|
130 TSmsUtilities::ServiceIdL(*root, id); |
|
131 CleanupStack::PopAndDestroy(root); |
|
132 return id; |
|
133 } |
|
134 |
|
135 |
|
136 void CMsgSimOperation::CreateDefaultSettingsL(TMsvId aServiceId) |
|
137 { |
|
138 QDEBUG_WRITE("CMsgSimOperation::CreateDefaultSettingsL enter") |
|
139 |
|
140 CSmsSettings* serviceSettings = CSmsSettings::NewL(); |
|
141 CleanupStack::PushL(serviceSettings); |
|
142 CSmsAccount* smsAccount = CSmsAccount::NewLC(); |
|
143 |
|
144 // Read the RFS related settings from shared data. |
|
145 TInt originalCount = 0; |
|
146 smsAccount->LoadSettingsL(*serviceSettings); |
|
147 originalCount = serviceSettings->ServiceCenterCount(); |
|
148 |
|
149 if (!originalCount) |
|
150 { |
|
151 QDEBUG_WRITE("Original count = 0") |
|
152 |
|
153 ReadDefaultSettingsFromSharedDataL(serviceSettings); |
|
154 |
|
155 // Rest of the sms settings, which are fixed. |
|
156 serviceSettings->SetValidityPeriodFormat(TSmsFirstOctet::ESmsVPFInteger); //relative |
|
157 serviceSettings->SetDelivery(ESmsDeliveryImmediately); |
|
158 serviceSettings->SetCanConcatenate(ETrue); |
|
159 serviceSettings->SetStatusReportHandling(CSmsSettings::EMoveReportToInboxInvisible); |
|
160 serviceSettings->SetSpecialMessageHandling(CSmsSettings::EMoveReportToInboxVisible); |
|
161 serviceSettings->SetRejectDuplicate(ETrue); |
|
162 TInt descriptionLength = KSmsDescriptionLength; |
|
163 |
|
164 // Read the value for description length |
|
165 CRepository* repository = CRepository::NewLC(KCRUidMuiuSettings); |
|
166 if (KErrNone == repository->Get(KMuiuDescriptionLength, |
|
167 descriptionLength)) |
|
168 { |
|
169 //Make sure value is not zero |
|
170 descriptionLength = Max(descriptionLength, KSmsDescriptionLength); |
|
171 } |
|
172 CleanupStack::PopAndDestroy(); // repository |
|
173 serviceSettings->SetDescriptionLength(descriptionLength); |
|
174 |
|
175 // Set saving to commsdb |
|
176 serviceSettings->SetCommDbAction(CSmsSettings::EStoreToCommDb); |
|
177 serviceSettings->SetSmsBearerAction(CSmsSettings::EStoreToCommDb); |
|
178 |
|
179 } |
|
180 |
|
181 // Save settings |
|
182 CMsvEntry* service = iMsvSession->GetEntryL(aServiceId); |
|
183 CleanupStack::PushL(service); |
|
184 CMsvStore* msvstore = service->EditStoreL(); |
|
185 CleanupStack::PushL(msvstore); |
|
186 |
|
187 TInt maxTries(5); |
|
188 TBool done(EFalse); |
|
189 while (maxTries && !done) |
|
190 { |
|
191 TRAPD( err, smsAccount->SaveSettingsL( *serviceSettings ) ); |
|
192 if (err == KErrNone) |
|
193 { |
|
194 QDEBUG_WRITE("CMsgSimOperation::CreateDefaultSettingsL settings saved") |
|
195 |
|
196 done = ETrue; |
|
197 } |
|
198 else if (err == KErrLocked) |
|
199 { |
|
200 QDEBUG_WRITE("CMsgSimOperation::CreateDefaultSettingsL KErrLocked") |
|
201 |
|
202 // Wait a while and retry. |
|
203 User::After(100000); // 0.1 seconds |
|
204 maxTries--; |
|
205 } |
|
206 else |
|
207 { |
|
208 User::Leave(err); |
|
209 } |
|
210 } |
|
211 |
|
212 msvstore->CommitL(); |
|
213 CleanupStack::PopAndDestroy(2); // msvstore, service |
|
214 CleanupStack::PopAndDestroy(2); // serviceSettings, smsAccount |
|
215 |
|
216 QDEBUG_WRITE("CMsgSimOperation::CreateDefaultSettingsL Exit") |
|
217 } |
|
218 |
|
219 |
|
220 void CMsgSimOperation:: |
|
221 ReadDefaultSettingsFromSharedDataL(CSmsSettings* aServiceSettings) |
|
222 { |
|
223 QDEBUG_WRITE("CMsgSimOperation::ReadDefaultSettingsFromSharedDataL Enter") |
|
224 |
|
225 if ( iCenRepSession ) |
|
226 { |
|
227 TInt readedSetting; |
|
228 |
|
229 // Delivery report |
|
230 if (iCenRepSession->Get(KSmumDeliveryReport, readedSetting) != KErrNone) |
|
231 { |
|
232 readedSetting = KDefDeliveryReport; |
|
233 } |
|
234 aServiceSettings->SetDeliveryReport(readedSetting); |
|
235 |
|
236 // Validity period |
|
237 if (iCenRepSession->Get(KSmumValidityPeriod, readedSetting) != KErrNone) |
|
238 { |
|
239 readedSetting = KDefValidityPeriod; |
|
240 } |
|
241 aServiceSettings->SetValidityPeriod(readedSetting); |
|
242 |
|
243 // Message conversion |
|
244 if (iCenRepSession->Get(KSmumMessageConversion, readedSetting) |
|
245 != KErrNone) |
|
246 { |
|
247 readedSetting = KDefMessageConversion; |
|
248 } |
|
249 aServiceSettings->SetMessageConversion((TSmsPIDConversion) readedSetting); |
|
250 |
|
251 // Preferred connection |
|
252 if (iCenRepSession->Get(KSmumPreferredConnection, readedSetting) |
|
253 != KErrNone) |
|
254 { |
|
255 readedSetting = KDefPreferredConnection; |
|
256 } |
|
257 aServiceSettings->SetSmsBearer((CSmsSettings::TMobileSmsBearer) readedSetting); |
|
258 |
|
259 // Reply via same centre |
|
260 if (iCenRepSession->Get(KSmumRemoveReplyViaSameCentre, readedSetting) |
|
261 != KErrNone) |
|
262 { |
|
263 if (iCenRepSession->Get(KSmumReplyViaSameCentre, readedSetting) |
|
264 != KErrNone) |
|
265 { |
|
266 readedSetting = KDefReplyViaSameCentre; |
|
267 } |
|
268 } |
|
269 else |
|
270 { |
|
271 if (!readedSetting) |
|
272 { |
|
273 if (iCenRepSession->Get(KSmumReplyViaSameCentre, readedSetting) |
|
274 != KErrNone) |
|
275 { |
|
276 readedSetting = KDefReplyViaSameCentre; |
|
277 } |
|
278 } |
|
279 } |
|
280 aServiceSettings->SetReplyPath(readedSetting); |
|
281 } |
|
282 |
|
283 QDEBUG_WRITE("CMsgSimOperation::ReadDefaultSettingsFromSharedDataL Exit") |
|
284 |
|
285 } |
|
286 |
|
287 CMsgSimOperation::~CMsgSimOperation() |
|
288 { |
|
289 QDEBUG_WRITE("CMsgSimOperation::~CMsgSimOperation Enter") |
|
290 delete iSimOperation; |
|
291 delete iSmsClientMtm; |
|
292 delete iClientRegistry; |
|
293 delete iMsvSession; |
|
294 delete iStartupMonitor; |
|
295 iStartupMonitor = NULL; |
|
296 QDEBUG_WRITE("CMsgSimOperation::~CMsgSimOperation Exit") |
|
297 } |
|
298 |
|
299 void CMsgSimOperation::StartL() |
|
300 { |
|
301 |
|
302 QDEBUG_WRITE("CMsgSimOperation::StartL Enter") |
|
303 |
|
304 // Retry is used to define the times ReadSimParamsL() is called |
|
305 iRetryCount++; |
|
306 |
|
307 if ( IsSIMPresent() ) |
|
308 { |
|
309 if ( HasSIMChanged() || HasNoSmscSettings() ) |
|
310 { |
|
311 QDEBUG_WRITE("CMsgSimOperation::StartL Reading sim settings") |
|
312 |
|
313 CMsvOperationWait* wait = CMsvOperationWait::NewLC(); |
|
314 iSimOperation = iSmsClientMtm->ReadSimParamsL(wait->iStatus); |
|
315 wait->Start(); |
|
316 |
|
317 QDEBUG_WRITE("CMsgSimOperation::StartL Before CActiveScheduler::Start") |
|
318 |
|
319 CActiveScheduler::Start(); |
|
320 |
|
321 QDEBUG_WRITE("CMsgSimOperation::StartL After CActiveScheduler::Start") |
|
322 |
|
323 TInt err = wait->iStatus.Int(); |
|
324 StartRunL(err); |
|
325 CleanupStack::PopAndDestroy(); |
|
326 |
|
327 } |
|
328 } |
|
329 CompleteClientRequest(0); |
|
330 |
|
331 QDEBUG_WRITE("CMsgSimOperation::StartL Exit") |
|
332 } |
|
333 |
|
334 void CMsgSimOperation::CompleteClientRequest(TInt /*aValue*/) |
|
335 { |
|
336 iObserver.CompleteOperation(); |
|
337 } |
|
338 |
|
339 void CMsgSimOperation::Panic(TSimOperationPanic aPanic) |
|
340 { |
|
341 _LIT(KSimOpPanicCategory, "SIMOP"); |
|
342 User::Panic(KSimOpPanicCategory, aPanic); |
|
343 } |
|
344 |
|
345 void CMsgSimOperation::StartRunL(TInt aErr) |
|
346 { |
|
347 QDEBUG_WRITE("CMsgSimOperation::StartRunL Enter") |
|
348 |
|
349 TInt error = aErr; |
|
350 |
|
351 if (error == KErrNone) |
|
352 { |
|
353 TRAP( error, DoStartRunL()); |
|
354 } |
|
355 |
|
356 // if problems with above; retry |
|
357 TInt maxRetryCount = KSmumRetryCount; |
|
358 if (error == KErrTimedOut) |
|
359 { |
|
360 QDEBUG_WRITE("CMsgSimOperation::StartRunL ErrorTimed Out") |
|
361 // no use to retry many times if timed out already |
|
362 maxRetryCount = KSmumRetryCount / 10; |
|
363 } |
|
364 if (error != KErrNone && iRetryCount <= maxRetryCount) |
|
365 { |
|
366 // first cancel the current simOp if still ongoing |
|
367 if (iSimOperation) |
|
368 { |
|
369 iSimOperation->Cancel(); |
|
370 delete iSimOperation; |
|
371 iSimOperation = NULL; |
|
372 } |
|
373 |
|
374 // wait a bit and actual retry |
|
375 User::After(KSmumRetryDelay); |
|
376 StartL(); |
|
377 return; |
|
378 } |
|
379 |
|
380 QDEBUG_WRITE("CMsgSimOperation::StartRunL Exit") |
|
381 } |
|
382 |
|
383 // ---------------------------------------------------- |
|
384 // CCMsgSimOperation::DoRunL |
|
385 // |
|
386 // ---------------------------------------------------- |
|
387 void CMsgSimOperation::DoStartRunL() |
|
388 { |
|
389 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL Enter") |
|
390 |
|
391 TIntBuf progressBuf; |
|
392 progressBuf.Copy(iSimOperation->ProgressL()); |
|
393 TInt error = progressBuf(); |
|
394 |
|
395 if (error != KErrNone) |
|
396 { |
|
397 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL " |
|
398 "iSimOperation->ProgressL() error ") |
|
399 return; |
|
400 } |
|
401 |
|
402 |
|
403 // Load current settings |
|
404 CSmsSettings* smsSettings = CSmsSettings::NewLC(); |
|
405 CSmsAccount* smsAccount = CSmsAccount::NewLC(); |
|
406 smsAccount->LoadSettingsL(*smsSettings); |
|
407 |
|
408 // Remove all old SMSC's configured |
|
409 TInt numSCAddresses = smsSettings->ServiceCenterCount(); |
|
410 |
|
411 QDEBUG_WRITE_FORMAT("CMsgSimOperation::DoStartRunL numSCAddresses =",numSCAddresses) |
|
412 |
|
413 for (TInt j = numSCAddresses; j > 0; j--) |
|
414 { |
|
415 smsSettings->RemoveServiceCenter(j - 1); |
|
416 } |
|
417 |
|
418 // Add all SMSC's from SIM |
|
419 CMobilePhoneSmspList* centersList = iSimOperation->ServiceCentersLC(); |
|
420 TInt count = centersList->Enumerate(); |
|
421 |
|
422 QDEBUG_WRITE_FORMAT("CMsgSimOperation::DoStartRunL count from sim operation =",count) |
|
423 |
|
424 for ( TInt i = 0; i < count; i++ ) |
|
425 { |
|
426 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL inside for loop") |
|
427 |
|
428 RMobileSmsMessaging::TMobileSmspEntryV1 entry; |
|
429 entry = centersList->GetEntryL(i); |
|
430 |
|
431 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL Mobile sms entry read") |
|
432 |
|
433 // If empty tel number field, don't add |
|
434 if (entry.iServiceCentre.iTelNumber == KNullDesC) |
|
435 { |
|
436 continue; |
|
437 } |
|
438 |
|
439 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL create name") |
|
440 |
|
441 TBuf<100> name(KSmscSimDefaultName); |
|
442 name.AppendNum(i); |
|
443 |
|
444 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL name created") |
|
445 |
|
446 smsSettings->AddServiceCenterL(name, entry.iServiceCentre.iTelNumber); |
|
447 |
|
448 |
|
449 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL AddServiceCenterL completed") |
|
450 |
|
451 if ( i == 0 ) |
|
452 { |
|
453 smsSettings->SetDefaultServiceCenter(i); |
|
454 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL SetDefaultServiceCenter completed") |
|
455 } |
|
456 } |
|
457 |
|
458 // save settings |
|
459 smsAccount->SaveSettingsL(*smsSettings); |
|
460 |
|
461 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL SaveSettingsL completed") |
|
462 |
|
463 CleanupStack::PopAndDestroy(3, smsSettings); // centersList, smsAccount, smsSettings |
|
464 |
|
465 QDEBUG_WRITE("CMsgSimOperation::DoStartRunL Exit") |
|
466 |
|
467 } |
|
468 |
|
469 void CMsgSimOperation::HandleSessionEventL(TMsvSessionEvent aEvent, |
|
470 TAny* /*aArg1*/, TAny* /*aArg2*/, |
|
471 TAny* /*aArg3*/) |
|
472 { |
|
473 // problem case handling |
|
474 if (aEvent == EMsvServerFailedToStart) |
|
475 { |
|
476 // Nothing to do here |
|
477 CompleteClientRequest(0); |
|
478 } |
|
479 |
|
480 else if ( (aEvent == EMsvServerTerminated) || (aEvent == EMsvCloseSession)) |
|
481 { |
|
482 delete iSimOperation; // These objects must be deleted first |
|
483 iSimOperation = NULL; // as they can't exist without a MsvSession |
|
484 |
|
485 delete iSmsClientMtm; |
|
486 iSmsClientMtm = NULL; |
|
487 |
|
488 delete iClientRegistry; |
|
489 iClientRegistry = NULL; |
|
490 |
|
491 delete iMsvSession; |
|
492 iMsvSession = NULL; |
|
493 |
|
494 CompleteClientRequest(0); |
|
495 } |
|
496 } |
|
497 |
|
498 void CMsgSimOperation::HandleStartupReadyL() |
|
499 { |
|
500 QDEBUG_WRITE("CMsgSimOperation::HandleStartupReadyL Enter") |
|
501 // Boot ready, start the real SimOperation |
|
502 StartL(); |
|
503 |
|
504 QDEBUG_WRITE("CMsgSimOperation::HandleStartupReadyL Exit") |
|
505 } |
|
506 |
|
507 TBool CMsgSimOperation::IsSIMPresent() |
|
508 { |
|
509 QDEBUG_WRITE("CMsgSimOperation::IsSIMPresent Enter") |
|
510 |
|
511 TInt status = KErrNone; |
|
512 TInt value = 0; |
|
513 |
|
514 status = RProperty::Get(KPSUidStartup, KPSSimStatus, value); |
|
515 |
|
516 if (status == KErrNone && value != ESimNotPresent) |
|
517 { |
|
518 QDEBUG_WRITE("CMsgSimOperation::IsSIMPresent returned True") |
|
519 |
|
520 return ETrue; |
|
521 } |
|
522 else |
|
523 { |
|
524 QDEBUG_WRITE("CMsgSimOperation::IsSIMPresent returned False") |
|
525 |
|
526 return EFalse; |
|
527 } |
|
528 |
|
529 |
|
530 } |
|
531 |
|
532 TBool CMsgSimOperation::HasSIMChanged() |
|
533 { |
|
534 QDEBUG_WRITE("CMsgSimOperation::HasSIMChanged Enter") |
|
535 |
|
536 TInt simValue = 0; |
|
537 TInt status = RProperty::Get(KPSUidStartup, KPSSimChanged, simValue); |
|
538 if (status == KErrNone && simValue == ESimChanged) |
|
539 { |
|
540 QDEBUG_WRITE("CMsgSimOperation::HasSIMChanged returned True") |
|
541 return ETrue; |
|
542 } |
|
543 |
|
544 QDEBUG_WRITE("CMsgSimOperation::HasSIMChanged returned False") |
|
545 return EFalse; |
|
546 } |
|
547 |
|
548 |
|
549 TBool CMsgSimOperation::HasNoSmscSettings() |
|
550 { |
|
551 QDEBUG_WRITE("CMsgSimOperation::HasNoSmscSettings Enter") |
|
552 |
|
553 CSmsSettings &settings = iSmsClientMtm->ServiceSettings(); |
|
554 if (settings.ServiceCenterCount() > 0) |
|
555 { |
|
556 QDEBUG_WRITE("CMsgSimOperation::HasNoSmscSettings returned False") |
|
557 |
|
558 return EFalse; |
|
559 } |
|
560 |
|
561 QDEBUG_WRITE("CMsgSimOperation::HasNoSmscSettings returned True") |
|
562 return ETrue; |
|
563 } |
|
564 |
|
565 // End of File |