|
1 /* |
|
2 * Copyright (c) 2004-2007 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 * State machine for mmbox list |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDE FILES |
|
22 #include <logcli.h> |
|
23 #include <msvids.h> |
|
24 #include <msventry.h> |
|
25 #include <msvstd.h> |
|
26 #include <e32std.h> // TTime |
|
27 |
|
28 // the rest are local includes |
|
29 #include "mmsmmboxlist.h" |
|
30 #include "mmsconst.h" |
|
31 #include "mmsencode.h" |
|
32 #include "mmsdecode.h" |
|
33 #include "mmsheaders.h" |
|
34 #include "mmsmmboxviewheaders.h" |
|
35 #include "mmsserverentry.h" |
|
36 #include "mmssettings.h" |
|
37 #include "mmssession.h" |
|
38 #include "mmserrors.h" |
|
39 #include "MmsServerDebugLogging.h" |
|
40 |
|
41 // EXTERNAL DATA STRUCTURES |
|
42 |
|
43 // EXTERNAL FUNCTION PROTOTYPES |
|
44 |
|
45 |
|
46 // CONSTANTS |
|
47 _LIT( K1970, "19700000:000000.000000" ); // 1-Jan 1970 0:00:00 |
|
48 // MACROS |
|
49 |
|
50 // LOCAL CONSTANTS AND MACROS |
|
51 |
|
52 // MODULE DATA STRUCTURES |
|
53 |
|
54 // LOCAL FUNCTION PROTOTYPES |
|
55 |
|
56 // ==================== LOCAL FUNCTIONS ==================== |
|
57 |
|
58 // ================= MEMBER FUNCTIONS ======================= |
|
59 |
|
60 // --------------------------------------------------------- |
|
61 // CMmsMmboxList::CMmsMmboxList |
|
62 // |
|
63 // --------------------------------------------------------- |
|
64 // |
|
65 CMmsMmboxList::CMmsMmboxList( RFs& aFs ): |
|
66 CMmsBaseOperation( aFs ) |
|
67 { |
|
68 } |
|
69 |
|
70 // --------------------------------------------------------- |
|
71 // CMmsMmboxList::ConstructL |
|
72 // |
|
73 // --------------------------------------------------------- |
|
74 // |
|
75 void CMmsMmboxList::ConstructL( CMmsSettings* aMmsSettings ) |
|
76 { |
|
77 CMmsBaseOperation::ConstructL( aMmsSettings ); |
|
78 iMmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() ); |
|
79 iOldNotifications = new ( ELeave ) CMsvEntrySelection; |
|
80 CActiveScheduler::Add( this ); |
|
81 } |
|
82 |
|
83 // --------------------------------------------------------- |
|
84 // CMmsMmboxList::NewL |
|
85 // |
|
86 // --------------------------------------------------------- |
|
87 // |
|
88 CMmsMmboxList* CMmsMmboxList::NewL( RFs& aFs, CMmsSettings* aMmsSettings ) |
|
89 { |
|
90 CMmsMmboxList* self = new ( ELeave ) CMmsMmboxList( aFs ); |
|
91 CleanupStack::PushL( self ); |
|
92 self->ConstructL( aMmsSettings ); |
|
93 CleanupStack::Pop( self ); |
|
94 return self; |
|
95 } |
|
96 |
|
97 // --------------------------------------------------------- |
|
98 // CMmsMmboxList::~CMmsMmboxList |
|
99 // |
|
100 // --------------------------------------------------------- |
|
101 // |
|
102 CMmsMmboxList::~CMmsMmboxList() |
|
103 { |
|
104 Cancel(); // has to be called first |
|
105 delete iOldNotifications; |
|
106 delete iMmsHeaders; |
|
107 } |
|
108 |
|
109 // --------------------------------------------------------- |
|
110 // CMmsMmboxList::StartL |
|
111 // |
|
112 // --------------------------------------------------------- |
|
113 // |
|
114 void CMmsMmboxList::StartL( |
|
115 CMsvEntrySelection& aSelection, |
|
116 CMsvServerEntry& aServerEntry, |
|
117 TMsvId aService, |
|
118 TRequestStatus& aStatus ) |
|
119 { |
|
120 LOG( _L("CMmsMmboxList::StartL") ); |
|
121 |
|
122 // Make sure that the aSelection is empty |
|
123 aSelection.Reset(); |
|
124 CMmsBaseOperation::InitializeL( aSelection, aServerEntry, aService ); |
|
125 iMmsHeaders->Reset(); |
|
126 |
|
127 iOldNotifications->Reset(); |
|
128 // get current notifications from mmbox folder |
|
129 iMmboxFolder = iMmsSettings->MMBoxFolder(); |
|
130 if ( iError == KErrNone ) |
|
131 { |
|
132 iError = iServerEntry->SetEntry( iMmboxFolder ); |
|
133 } |
|
134 // If cannot access MMBoxFolder, we are in trouble |
|
135 // When iError not equal to KErrNone, the operation will complete after running through RunL |
|
136 if ( iError == KErrNone ) |
|
137 { |
|
138 TInt err; |
|
139 err = iServerEntry->GetChildrenWithMtm( KUidMsgMMSNotification, *iOldNotifications ); |
|
140 if (err != KErrNone) |
|
141 { |
|
142 return; |
|
143 } |
|
144 iOldQuotaEntryId = OldQuotaEntryL(); |
|
145 } |
|
146 else |
|
147 { |
|
148 iOldQuotaEntryId = KMsvNullIndexEntryId; |
|
149 } |
|
150 iServerEntry->SetEntry( KMsvNullIndexEntryId ); |
|
151 |
|
152 Queue( aStatus ); |
|
153 FallThrough(); |
|
154 } |
|
155 |
|
156 // --------------------------------------------------------- |
|
157 // CMmsMmboxList::DoCancel |
|
158 // |
|
159 // --------------------------------------------------------- |
|
160 // |
|
161 void CMmsMmboxList::DoCancel() |
|
162 { |
|
163 LOG( _L("CMmsMmboxList::DoCancel") ); |
|
164 CMmsBaseOperation::DoCancel(); |
|
165 } |
|
166 |
|
167 // --------------------------------------------------------- |
|
168 // CMmsMmboxList::EncodePDUL |
|
169 // |
|
170 // --------------------------------------------------------- |
|
171 // |
|
172 void CMmsMmboxList::EncodePDUL() |
|
173 { |
|
174 LOG( _L("CMmsMmboxList::EncodePDU") ); |
|
175 |
|
176 // As no entry exists to be encoded, mmsheaders are not restored and stored. |
|
177 |
|
178 // Set message type |
|
179 iMmsHeaders->SetMessageType( KMmsMessageTypeMboxViewReq ); |
|
180 |
|
181 // Request mmbox total and quota information |
|
182 CMmsMMBoxViewHeaders& viewHeaders = iMmsHeaders->MMBoxViewHeadersL(); |
|
183 viewHeaders.SetMmsTotals( KMmsYes ); |
|
184 viewHeaders.SetMmsQuotas( KMmsYes ); |
|
185 |
|
186 // Set TransactionId |
|
187 TBufC8<KMMSMAXTIDLENGTH> tid; |
|
188 tid.Des().NumUC( AllocateTID(), EHex ); |
|
189 iMmsHeaders->SetTidL( tid ); |
|
190 |
|
191 // Encode the mmboxview request |
|
192 iEncoder->EncodeHeadersL( *iMmsHeaders, *iEncodeBuffer ); |
|
193 |
|
194 FallThrough(); |
|
195 } |
|
196 |
|
197 // --------------------------------------------------------- |
|
198 // CMmsMmboxList::SubmitTransactionL |
|
199 // |
|
200 // --------------------------------------------------------- |
|
201 // |
|
202 void CMmsMmboxList::SubmitTransactionL() |
|
203 { |
|
204 LOG( _L("CMmsMmboxList::SubmitTransaction")); |
|
205 |
|
206 if ( !iConnected ) |
|
207 { |
|
208 if ( iError == KErrNone ) |
|
209 { |
|
210 iError = KErrCouldNotConnect; |
|
211 } |
|
212 } |
|
213 |
|
214 // This check is needed only when running tests in global mode |
|
215 // if length of URI is 0, Symbian code will panic |
|
216 if ( !iUri ) |
|
217 { |
|
218 if ( !iMmsSettings->LocalMode() ) |
|
219 { |
|
220 iError = KMmsErrorNoURI1; |
|
221 } |
|
222 } |
|
223 else if ( iUri->Des().Length() == 0 && !iMmsSettings->LocalMode() ) |
|
224 { |
|
225 iError = KMmsErrorNoURI1; |
|
226 } |
|
227 |
|
228 if ( iError != KErrNone ) |
|
229 { |
|
230 FallThrough(); |
|
231 return; |
|
232 } |
|
233 |
|
234 if ( !iMmsSettings->LocalMode() ) |
|
235 { |
|
236 // Send |
|
237 iMmsSession->SendMessageL( |
|
238 iUri->Des(), |
|
239 *iEncodeBuffer, |
|
240 *iEncoder, |
|
241 *iDecoder, |
|
242 iStatus ); |
|
243 SetActive(); |
|
244 } |
|
245 else |
|
246 { |
|
247 LocalModeFetchL(); |
|
248 } |
|
249 } |
|
250 |
|
251 // --------------------------------------------------------- |
|
252 // CMmsMmboxList::CreateEntryL |
|
253 // |
|
254 // --------------------------------------------------------- |
|
255 // |
|
256 void CMmsMmboxList::CreateEntryL() |
|
257 { |
|
258 LOG( _L("CMmsMmboxList CreateEntry")); |
|
259 // Create an mms entry under mmbox folder |
|
260 if ( iOldQuotaEntryId != KMsvNullIndexEntryId ) |
|
261 { |
|
262 // Reuse old quota |
|
263 iEntryUnderConstruction = iOldQuotaEntryId; |
|
264 } |
|
265 else |
|
266 { |
|
267 // If no old quota entry exists, we create a new one |
|
268 iError = iServerEntry->SetEntry( iMmboxFolder ); |
|
269 if ( iError == KErrNone ) |
|
270 { |
|
271 // set all relevant flags in tMsvEntry |
|
272 TMsvEntry tEntry; |
|
273 tEntry.iMtm = KUidMsgTypeMultimedia; |
|
274 tEntry.iDate.UniversalTime(); |
|
275 SetFirstFlagsToNewEntry( tEntry ); |
|
276 |
|
277 iError = iServerEntry->CreateEntry( tEntry ); |
|
278 if ( iError == KErrNone ) |
|
279 { |
|
280 iEntryUnderConstruction = tEntry.Id(); |
|
281 } |
|
282 } |
|
283 iServerEntry->SetEntry( KMsvNullIndexEntryId ); |
|
284 } |
|
285 FallThrough(); |
|
286 } |
|
287 |
|
288 // --------------------------------------------------------- |
|
289 // CMmsMmboxList::DecodeResponseL |
|
290 // |
|
291 // --------------------------------------------------------- |
|
292 // |
|
293 void CMmsMmboxList::DecodeResponseL() |
|
294 { |
|
295 LOG( _L("CMmsMmboxList::DecodeResponseL")); |
|
296 if( iEncodeBuffer->Size() < 1 ) |
|
297 { |
|
298 iError = KErrCorrupt; |
|
299 } |
|
300 if( iError != KErrNone ) |
|
301 { |
|
302 FallThrough(); |
|
303 return; |
|
304 } |
|
305 |
|
306 iMmsHeaders->Reset(); |
|
307 // Decode mmbox view confirmation |
|
308 TInt numAtt = 0; |
|
309 TInt dataStart = 0; |
|
310 TInt startInBuffer = 0; |
|
311 TInt length = iEncodeBuffer->Size(); |
|
312 iDecoder->DecodeHeadersL( *iEntryWrapper, |
|
313 *iMmsHeaders, |
|
314 *iEncodeBuffer, |
|
315 startInBuffer, |
|
316 length, |
|
317 &numAtt, |
|
318 &dataStart ); |
|
319 |
|
320 // The content type have to be mmbox view conf. |
|
321 if ( iMmsHeaders->MessageType() != KMmsMessageTypeMboxViewConf ) |
|
322 { |
|
323 // the content type is not correct. Don't save the headers |
|
324 if ( iMmsHeaders->MessageType() == KMmsMessageTypeMSendConf && |
|
325 iMmsHeaders->ResponseStatus() == KMmsErrorUnsupportedMessage ) |
|
326 { |
|
327 iError = KErrNotSupported; |
|
328 } |
|
329 else |
|
330 { |
|
331 iError = KErrCorrupt; |
|
332 } |
|
333 } |
|
334 |
|
335 if ( iError == KErrNone ) |
|
336 { |
|
337 if ( iOldQuotaEntryId != KMsvNullIndexEntryId ) |
|
338 { |
|
339 // We must make the entry read only again |
|
340 iError = iServerEntry->SetEntry( iOldQuotaEntryId ); |
|
341 if ( iError == KErrNone ) |
|
342 { |
|
343 TMsvEntry tEntry = iServerEntry->Entry(); |
|
344 tEntry.SetReadOnly( EFalse ); |
|
345 iServerEntry->ChangeEntry( tEntry ); |
|
346 } |
|
347 iServerEntry->SetEntry( KMsvNullIndexEntryId ); |
|
348 } |
|
349 iError = iEntryWrapper->SetCurrentEntry( iEntryUnderConstruction ); |
|
350 } |
|
351 |
|
352 // save the mmbox view confirmation headers, |
|
353 // as the decode does not save them |
|
354 if ( iError == KErrNone ) |
|
355 { |
|
356 iError = iEntryWrapper->StoreMmsHeadersL( *iMmsHeaders, NULL ); |
|
357 } |
|
358 |
|
359 // decode rest of the PDUs if we have any. |
|
360 TInt start = dataStart; // start of multipart data. |
|
361 for ( TInt i = 0; i < numAtt && iError == KErrNone; i++ ) |
|
362 { |
|
363 length = iEncodeBuffer->Size() - start; |
|
364 // We extract next data part, but we don't use the mime headers that would be returned |
|
365 iDecoder->ExtractNextDataPartL( *iEncodeBuffer, |
|
366 start, // start of next data part |
|
367 dataStart, // start of actual data |
|
368 length ); // length of data |
|
369 |
|
370 // Create a new entry for the mmbox description PDU |
|
371 iError = iServerEntry->SetEntry( iMmboxFolder ); |
|
372 TMsvEntry descEntry; |
|
373 if ( iError == KErrNone ) |
|
374 { |
|
375 // set all relevant flags in tMsvEntry |
|
376 descEntry.iMtm = KUidMsgMMSNotification; |
|
377 SetFirstFlagsToNewEntry( descEntry ); |
|
378 iError = iServerEntry->CreateEntry( descEntry ); |
|
379 } |
|
380 |
|
381 if ( iError == KErrNone ) |
|
382 { |
|
383 // Decode description PDU |
|
384 iMmsHeaders->Reset(); |
|
385 TInt attaNum = 0; |
|
386 TInt attaDataStart = 0; |
|
387 iDecoder->DecodeHeadersL( *iEntryWrapper, |
|
388 *iMmsHeaders, |
|
389 *iEncodeBuffer, |
|
390 dataStart, |
|
391 length, |
|
392 &attaNum, |
|
393 &attaDataStart ); |
|
394 |
|
395 iError = iEntryWrapper->SetCurrentEntry( descEntry.Id() ); |
|
396 } |
|
397 |
|
398 // Checking the content type |
|
399 if( iError == KErrNone ) |
|
400 { |
|
401 // The content type has to be mmbox view description. |
|
402 if( iMmsHeaders->MessageType() != KMmsMessageTypeMBoxDescr ) |
|
403 { |
|
404 // Content type is not correct. |
|
405 iError = KErrCorrupt; |
|
406 LOG( _L("ERROR: Wrong content type")); |
|
407 } |
|
408 else |
|
409 { |
|
410 // Mark mmbox notification specific flags |
|
411 // Mark as notification. This information is important for UI. |
|
412 descEntry.iMtmData1 = KMmsMessageMNotificationInd; |
|
413 descEntry.iMtmData2 = KMmsStoredInMMBox; |
|
414 descEntry.iMtmData2 |= KMmsNotifyResponseSent; |
|
415 } |
|
416 } |
|
417 if( iError == KErrNone ) |
|
418 { |
|
419 // Set subject etc. to the notification entry |
|
420 iError = StoreContentToNotificationEntryL( descEntry ); |
|
421 } |
|
422 if ( iError == KErrNone ) |
|
423 { |
|
424 // Save the headers as the decoder does not save them |
|
425 iError = iEntryWrapper->StoreMmsHeadersL( *iMmsHeaders, NULL ); |
|
426 } |
|
427 if ( iError == KErrNone ) |
|
428 { |
|
429 // add new notification to iSelection list |
|
430 iSelection->AppendL( descEntry.Id() ); |
|
431 } |
|
432 } // for loop |
|
433 |
|
434 iServerEntry->SetEntry( KMsvNullIndexEntryId ); |
|
435 FallThrough(); |
|
436 } |
|
437 |
|
438 // --------------------------------------------------------- |
|
439 // CMmsMmboxList::MoveEntryL |
|
440 // |
|
441 // --------------------------------------------------------- |
|
442 // |
|
443 void CMmsMmboxList::MoveEntryL() |
|
444 { |
|
445 LOG( _L("CMmsMmboxList::MoveEntryL")); |
|
446 if ( iError != KErrNone ) |
|
447 { |
|
448 FallThrough(); |
|
449 return; |
|
450 } |
|
451 |
|
452 // Delete old notifications |
|
453 iError = RemoveOldNotifications(); |
|
454 |
|
455 // make new notifications visible |
|
456 if ( iError == KErrNone ) |
|
457 { |
|
458 iError = MakeNewNotificationsVisible(); |
|
459 } |
|
460 |
|
461 // Finalize the new quota entry - if we created a new one and did not |
|
462 // just reuse the old entry |
|
463 |
|
464 TMsvEntry tEntry; |
|
465 |
|
466 if ( iError == KErrNone || iOldQuotaEntryId == KMsvNullIndexEntryId ) |
|
467 { |
|
468 iError = iServerEntry->SetEntry( iEntryUnderConstruction ); |
|
469 if ( iError == KErrNone ) |
|
470 { |
|
471 tEntry = iServerEntry->Entry(); |
|
472 SetFlagsToEntryBeingFinalized( tEntry ); |
|
473 // update the time the quota entry was updated |
|
474 tEntry.iDate.UniversalTime(); |
|
475 tEntry.iError = KErrNone; // clear possible old error |
|
476 |
|
477 // Quota entry must not be visible. |
|
478 // Otherwise the shows the number of notifications in mmboxfolder wrong. |
|
479 tEntry.SetVisible( EFalse ); |
|
480 iError = iServerEntry->ChangeEntry( tEntry ); |
|
481 if ( iError == KErrNone ) |
|
482 { |
|
483 iEntryUnderConstruction = KMsvNullIndexEntryId; |
|
484 } |
|
485 } |
|
486 iServerEntry->SetEntry( KMsvNullIndexEntryId ); |
|
487 } |
|
488 |
|
489 FallThrough(); |
|
490 } |
|
491 |
|
492 // --------------------------------------------------------- |
|
493 // CMmsMmboxList::FinalizeL() |
|
494 // |
|
495 // --------------------------------------------------------- |
|
496 // |
|
497 void CMmsMmboxList::FinalizeL() |
|
498 { |
|
499 LOG( _L("CMmsMmboxList::FinalizeL")); |
|
500 |
|
501 TInt error; |
|
502 |
|
503 // In case something has failed. Delete the new quota entry |
|
504 // - but only in case it was just created |
|
505 if ( iError != KErrNone ) |
|
506 { |
|
507 error = iServerEntry->SetEntry( iMmboxFolder ); |
|
508 if ( error == KErrNone ) |
|
509 { |
|
510 // we can only delete, if we can set context to parent |
|
511 if ( iOldQuotaEntryId == KMsvNullIndexEntryId ) |
|
512 { |
|
513 iServerEntry->DeleteEntry( iEntryUnderConstruction ); |
|
514 } |
|
515 |
|
516 // if iSelection contains now notifications, the notifications |
|
517 // are not ready yet. They can be destroyed. |
|
518 if ( iSelection->Count() > 0 ) |
|
519 { |
|
520 iServerEntry->DeleteEntries( *iSelection ); |
|
521 } |
|
522 } |
|
523 iEntryUnderConstruction = KMsvNullIndexEntryId; |
|
524 |
|
525 iSelection->Reset(); |
|
526 |
|
527 // we don't care if the iOldNotifications is empty or not. |
|
528 // If the old notifications are not deleted, they can stay |
|
529 // in the mmbox folder. The array is reseted anyway. |
|
530 iOldNotifications->Reset(); |
|
531 |
|
532 // set iError to old quota entry, if the entry exists |
|
533 if ( iOldQuotaEntryId != KMsvNullIndexEntryId ) |
|
534 { |
|
535 |
|
536 LOG( _L("- old quota entry exists")); |
|
537 |
|
538 error = iServerEntry->SetEntry( iOldQuotaEntryId ); |
|
539 if ( error == KErrNone ) |
|
540 { |
|
541 TMsvEntry tEntry = iServerEntry->Entry(); |
|
542 tEntry.iError = iError; |
|
543 |
|
544 error = iServerEntry->ChangeEntry( tEntry ); |
|
545 if ( error == KErrNone ) |
|
546 { |
|
547 LOG( _L("- iError saved to old quota entry.")); |
|
548 } |
|
549 } |
|
550 } |
|
551 |
|
552 iServerEntry->SetEntry( KMsvNullIndexEntryId ); |
|
553 } |
|
554 |
|
555 CMmsBaseOperation::FinalizeL(); |
|
556 } |
|
557 |
|
558 // --------------------------------------------------------- |
|
559 // CMmsMmboxList::SetFirstFlagsToNewEntry |
|
560 // |
|
561 // --------------------------------------------------------- |
|
562 // |
|
563 void CMmsMmboxList::SetFirstFlagsToNewEntry( TMsvEntry& aEntry ) |
|
564 { |
|
565 aEntry.iType = KUidMsvMessageEntry; |
|
566 aEntry.iServiceId = iService; |
|
567 aEntry.SetVisible( EFalse ); |
|
568 aEntry.SetComplete( EFalse ); |
|
569 aEntry.SetInPreparation( ETrue ); |
|
570 aEntry.SetReadOnly( EFalse ); |
|
571 aEntry.SetNew( ETrue ); |
|
572 aEntry.SetUnread( ETrue ); |
|
573 } |
|
574 |
|
575 // --------------------------------------------------------- |
|
576 // CMmsMmboxList::SetFlagsToEntryBeingFinalized |
|
577 // |
|
578 // --------------------------------------------------------- |
|
579 // |
|
580 void CMmsMmboxList::SetFlagsToEntryBeingFinalized( TMsvEntry& aEntry ) |
|
581 { |
|
582 aEntry.iMtmData1 |= KMmsMessageMobileTerminated; |
|
583 aEntry.SetReadOnly( ETrue ); |
|
584 aEntry.SetVisible( ETrue ); |
|
585 aEntry.SetInPreparation( EFalse ); |
|
586 aEntry.SetComplete( ETrue ); |
|
587 } |
|
588 |
|
589 // --------------------------------------------------------- |
|
590 // CMmsMmboxList::RemoveOldNotifications |
|
591 // |
|
592 // --------------------------------------------------------- |
|
593 // |
|
594 TInt CMmsMmboxList::RemoveOldNotifications() |
|
595 { |
|
596 LOG( _L("CMmsMmboxList::RemoveOldNotifications")); |
|
597 |
|
598 TInt error = iServerEntry->SetEntry( iMmboxFolder ); |
|
599 if ( error == KErrNone && iOldNotifications->Count() > 0 ) |
|
600 { |
|
601 error = iServerEntry->DeleteEntries( *iOldNotifications ); |
|
602 if ( error == KErrNone ) |
|
603 { |
|
604 iOldNotifications->Reset(); |
|
605 } |
|
606 } |
|
607 |
|
608 iServerEntry->SetEntry( KMsvNullIndexEntryId ); |
|
609 return error; |
|
610 } |
|
611 |
|
612 // --------------------------------------------------------- |
|
613 // CMmsMmboxList::MakeNewNotificationsVisible |
|
614 // |
|
615 // --------------------------------------------------------- |
|
616 // |
|
617 TInt CMmsMmboxList::MakeNewNotificationsVisible() |
|
618 { |
|
619 LOG( _L("CMmsMmboxList::MakeNewNotificationsVisible")); |
|
620 TInt count = iSelection->Count(); |
|
621 TInt error = KErrNone; |
|
622 for ( TInt i = count - 1; i >=0 && error == KErrNone; i-- ) |
|
623 { |
|
624 error = iServerEntry->SetEntry( iSelection->At( i ) ); |
|
625 if ( error == KErrNone ) |
|
626 { |
|
627 TMsvEntry tEntry = iServerEntry->Entry(); |
|
628 SetFlagsToEntryBeingFinalized( tEntry ); |
|
629 error = iServerEntry->ChangeEntry( tEntry ); |
|
630 if ( error == KErrNone ) |
|
631 { |
|
632 iSelection->Delete( i ); |
|
633 } |
|
634 } |
|
635 } |
|
636 iServerEntry->SetEntry( KMsvNullIndexEntryId ); |
|
637 return error; |
|
638 } |
|
639 |
|
640 // --------------------------------------------------------- |
|
641 // CMmsMmboxList::StoreContentToNotificationEntryL |
|
642 // |
|
643 // --------------------------------------------------------- |
|
644 // |
|
645 TInt CMmsMmboxList::StoreContentToNotificationEntryL( TMsvEntry aEntry ) |
|
646 { |
|
647 LOG( _L("CMmsMmboxList::SetContentToNotificationL")); |
|
648 |
|
649 // Expiry interval must be changed to absolute time, |
|
650 // otherwise it makes no sense. |
|
651 if ( iMmsHeaders->ExpiryDate() == 0 ) |
|
652 { |
|
653 TTime time; |
|
654 // handle expiry in universal time |
|
655 time.UniversalTime(); |
|
656 time += TTimeIntervalSeconds( iMmsHeaders->ExpiryInterval() ); |
|
657 iMmsHeaders->SetExpiryDate( |
|
658 ( time.MicroSecondsFrom( TTime( KMmsYear1970String ) ).Int64() ) / KMmsMillion ); |
|
659 } |
|
660 |
|
661 // If the notifications does not contains the date value from the server, |
|
662 // arrival time is set to notification. |
|
663 // Otherwise the date from the server. |
|
664 |
|
665 LOG( _L("Mark time")); |
|
666 |
|
667 if ( iMmsHeaders->Date() == 0 ) |
|
668 { |
|
669 aEntry.iDate.UniversalTime(); |
|
670 } |
|
671 else |
|
672 { |
|
673 aEntry.iDate = ServerDate(); |
|
674 } |
|
675 |
|
676 // Mark subject |
|
677 if ( iMmsHeaders->Subject().Length() > 0 ) |
|
678 { |
|
679 aEntry.iDescription.Set( iMmsHeaders->Subject() ); |
|
680 } |
|
681 |
|
682 // Mark size of the notification |
|
683 aEntry.iSize = iMmsHeaders->Size(); |
|
684 |
|
685 // Mark message class. |
|
686 // Default is personal |
|
687 if ( iMmsHeaders->MessageClass() == EMmsClassAdvertisement ) |
|
688 { |
|
689 aEntry.iMtmData1 |= KMmsMessageAdvertisement; |
|
690 } |
|
691 else if (iMmsHeaders->MessageClass() == EMmsClassInformational ) |
|
692 { |
|
693 aEntry.iMtmData1 |= KMmsMessageInformational; |
|
694 } |
|
695 else |
|
696 { |
|
697 // keep LINT happy |
|
698 } |
|
699 |
|
700 switch ( iMmsHeaders->MessagePriority() ) |
|
701 { |
|
702 case KMmsPriorityNormal: |
|
703 aEntry.SetPriority( EMsvMediumPriority ); |
|
704 break; |
|
705 case KMmsPriorityLow: |
|
706 aEntry.SetPriority( EMsvLowPriority ); |
|
707 break; |
|
708 case KMmsPriorityHigh: |
|
709 aEntry.SetPriority( EMsvHighPriority ); |
|
710 break; |
|
711 default: |
|
712 // if not defined default is normal |
|
713 aEntry.SetPriority( EMsvMediumPriority ); |
|
714 break; |
|
715 } |
|
716 |
|
717 // mark sender |
|
718 // If the sender is a phone number, add alias. |
|
719 HBufC* buffer = HBufC::NewL( KMmsMaxDescription ); |
|
720 TPtr pBuffer = buffer->Des(); |
|
721 |
|
722 if ( TMmsGenUtils::GenerateDetails( iMmsHeaders->Sender(), |
|
723 pBuffer, KMmsMaxDescription, iFs ) == KErrNone ) |
|
724 { |
|
725 aEntry.iDetails.Set( pBuffer ); |
|
726 } |
|
727 else |
|
728 { |
|
729 // We come here only if there was an fatal error in GenerateDetails. |
|
730 // Even if we don't find the alias, we have something in the string |
|
731 aEntry.iDetails.Set( iMmsHeaders->Sender() ); |
|
732 } |
|
733 |
|
734 TInt error = iServerEntry->ChangeEntry( aEntry ); |
|
735 delete buffer; |
|
736 buffer = NULL; |
|
737 // iServerEntry is not set to KMsvNullIndexEntryId, |
|
738 // as the next function demands that the iServerEntry is set to aEntry. |
|
739 return error; |
|
740 } |
|
741 |
|
742 // --------------------------------------------------------- |
|
743 // CMmsMmboxList::OldQuotaEntryL |
|
744 // |
|
745 // --------------------------------------------------------- |
|
746 // |
|
747 TMsvId CMmsMmboxList::OldQuotaEntryL() |
|
748 { |
|
749 LOG( _L("CMmsMmboxList::OldQuotaEntryL")); |
|
750 |
|
751 // iServerEntry context must be set to iMmboxFolder |
|
752 // before calling this function |
|
753 TMsvId oldQuotaEntryId = KMsvNullIndexEntryId; |
|
754 |
|
755 // show invisible entries. |
|
756 TMsvSelectionOrdering ordering = |
|
757 TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue ); |
|
758 iServerEntry->SetSort( ordering ); |
|
759 |
|
760 CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; |
|
761 CleanupStack::PushL( selection ); |
|
762 TInt error = iServerEntry->GetChildrenWithMtm( KUidMsgTypeMultimedia, *selection ); |
|
763 TInt count = selection->Count(); |
|
764 |
|
765 LOG2( _L("- %d mms entries"), count ); |
|
766 |
|
767 if( error == KErrNone && count > 0 ) |
|
768 { |
|
769 for( TInt i = selection->Count() - 1 ; i >= 0; i-- ) |
|
770 { |
|
771 |
|
772 LOG2( _L("- processing at selection[%d]"), i ); |
|
773 |
|
774 TMsvId entryId = selection->At( i ); |
|
775 error = iServerEntry->SetEntry( entryId ); |
|
776 if ( error == KErrNone ) |
|
777 { |
|
778 TMsvEntry entry = iServerEntry->Entry(); |
|
779 // old quota entry is complete, but not visible |
|
780 if ( ( !entry.Visible() ) && entry.Complete() ) |
|
781 { |
|
782 oldQuotaEntryId = entryId; |
|
783 i = -1; |
|
784 |
|
785 LOG( _L("- Old quota found")); |
|
786 |
|
787 } |
|
788 } |
|
789 } |
|
790 } |
|
791 CleanupStack::PopAndDestroy( selection ); |
|
792 |
|
793 return oldQuotaEntryId; |
|
794 } |
|
795 |
|
796 // --------------------------------------------------------- |
|
797 // CMmsMmboxList::ServerDate |
|
798 // |
|
799 // --------------------------------------------------------- |
|
800 // |
|
801 TTime CMmsMmboxList::ServerDate() |
|
802 { |
|
803 |
|
804 LOG( _L("CMmsMmboxList::ServerDate")); |
|
805 |
|
806 TInt64 inSeconds = iMmsHeaders->Date(); |
|
807 |
|
808 TTime y1970( K1970 ); |
|
809 |
|
810 // 1970 presented as microseconds after January 1st, 0 AD nominal Gregorian. |
|
811 TInt64 ms1970 = y1970.Int64(); |
|
812 |
|
813 // If not defined in message headers return 0 |
|
814 if ( inSeconds == 0 ) |
|
815 { |
|
816 return TTime(0); |
|
817 } |
|
818 |
|
819 // microseconds after 1.1. 1970 |
|
820 TInt64 msAfter1970; |
|
821 msAfter1970 = KMmsMillion * inSeconds; |
|
822 |
|
823 return TTime( ms1970 + msAfter1970 ); |
|
824 } |
|
825 |
|
826 // --------------------------------------------------------- |
|
827 // |
|
828 // --------------------------------------------------------- |
|
829 // |
|
830 void CMmsMmboxList::LocalModeFetchL() |
|
831 { |
|
832 // This functionality has no meaning in hardware |
|
833 // It is available in WINS to help module testing |
|
834 |
|
835 #ifdef __WINS__ |
|
836 RFs fs; // We need a separate session to be able to set the session path |
|
837 RFile file; // local mode message |
|
838 iError = fs.Connect(); |
|
839 if ( iError != KErrNone ) |
|
840 { |
|
841 FallThrough(); |
|
842 } |
|
843 |
|
844 CleanupClosePushL( fs ); |
|
845 |
|
846 CDir* fileList = NULL; |
|
847 |
|
848 TEntry* entry = new( ELeave ) TEntry; // allocated from heap to save stack space |
|
849 CleanupStack::PushL( entry ); |
|
850 HBufC* filename = HBufC::NewL( KMaxFileName ); |
|
851 CleanupStack::PushL( filename ); |
|
852 TPtr fileNamePtr = filename->Des(); |
|
853 // use different directory in order to be able to simulate |
|
854 // both mmbox view and fetching the corresponding messages |
|
855 fileNamePtr.Copy( KMmsMMBoxDirectory ); |
|
856 TInt err = fs.SetSessionPath( fileNamePtr ); |
|
857 err = fs.Entry( fileNamePtr, *entry ); |
|
858 TInt count = 0; |
|
859 if ( err == KErrNone ) |
|
860 { |
|
861 TFindFile* finder = new( ELeave ) TFindFile( fs ); // allocated from heap to save stack space |
|
862 CleanupStack::PushL( finder ); |
|
863 _LIT( KWild, "*" ); |
|
864 |
|
865 err = finder->FindWildByPath( KWild, &fileNamePtr, fileList ); |
|
866 CleanupStack::PopAndDestroy( finder ); |
|
867 |
|
868 if ( fileList ) |
|
869 { |
|
870 CleanupStack::PushL( fileList ); |
|
871 count = fileList->Count(); |
|
872 } |
|
873 } |
|
874 |
|
875 |
|
876 if ( count > 0 ) |
|
877 { |
|
878 TParse parse; |
|
879 parse.Set( ( ( *fileList )[0] ).iName, &fileNamePtr, NULL ); |
|
880 fileNamePtr.Copy( parse.FullName() ); |
|
881 TInt size = fs.Entry( parse.FullName(), *entry ); |
|
882 size = entry->iSize; |
|
883 |
|
884 iError = file.Open( fs, fileNamePtr, EFileShareExclusive ); |
|
885 if ( iError == KErrNone ) |
|
886 { |
|
887 iEncodeBuffer->Reset(); |
|
888 TRAP(iError, iEncodeBuffer->ResizeL( size )); |
|
889 if ( iError == KErrNone ) |
|
890 { |
|
891 TPtr8 pos = iEncodeBuffer->Ptr( 0 ); |
|
892 file.Read( 0, pos, size ); |
|
893 } |
|
894 file.Close(); |
|
895 // delete the file after the view has been fetched |
|
896 fs.Delete( fileNamePtr ); |
|
897 } |
|
898 } |
|
899 |
|
900 if ( fileList ) |
|
901 { |
|
902 CleanupStack::PopAndDestroy( fileList ); |
|
903 } |
|
904 |
|
905 CleanupStack::PopAndDestroy( filename ); |
|
906 CleanupStack::PopAndDestroy( entry ); |
|
907 CleanupStack::PopAndDestroy( &fs ); // close fs |
|
908 #endif |
|
909 |
|
910 FallThrough(); |
|
911 } |
|
912 |
|
913 |
|
914 // ================= OTHER EXPORTED FUNCTIONS ============== |
|
915 |
|
916 // End of File |