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