messagingapp/msgappfw/plugins/msgplugin/src/ccsmsghandler.cpp
branchRCL_3
changeset 57 ebe688cedc25
equal deleted inserted replaced
54:fa1df4b99609 57:ebe688cedc25
       
     1 /*
       
     2 * Copyright (c) 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:  CS Message Handler, This class caches the conversation server
       
    15  *                with the message data and also sends run-time updates to the
       
    16  *                server with the message data
       
    17  *
       
    18 */
       
    19 
       
    20 
       
    21 // USER INCLUDES
       
    22 #include "ccsmsghandler.h"
       
    23 #include "msgbiouids.h"
       
    24 #include "ccsdefs.h"
       
    25 
       
    26 // SYSTEM INCLUDES
       
    27 #include <smsclnt.h>                   
       
    28 #include <mmsclient.h>
       
    29 #include <mtclreg.h>
       
    30 #include <csmsemailfields.h>
       
    31 #include <txtrich.h>
       
    32 #include <msvids.h>
       
    33 #include <e32const.h>
       
    34 #include <SendUiConsts.h>
       
    35 #include <pushentry.h> // For services messages
       
    36 #include <e32cmn.h>
       
    37 
       
    38 
       
    39 //CONSTANTS
       
    40 const TInt KMessageArrayGranularity = 50;
       
    41 
       
    42 // NOTE:- DRAFT ENTRIES ARE NOT HANDLED IN THE PLUGIN
       
    43 
       
    44 // ============================== MEMBER FUNCTIONS ============================
       
    45 // ----------------------------------------------------------------------------
       
    46 // CCsMsgHandler::NewL
       
    47 // Two Phase Construction
       
    48 // ----------------------------------------------------------------------------
       
    49 //
       
    50 CCsMsgHandler* CCsMsgHandler::NewL(MCsMsgObserver *aMsgObserver)
       
    51     {
       
    52     PRINT ( _L("Enter CCsMsgHandler::NewL") );
       
    53 
       
    54     CCsMsgHandler* self = new ( ELeave ) CCsMsgHandler();
       
    55     CleanupStack::PushL( self );
       
    56     self->ConstructL(aMsgObserver);
       
    57     CleanupStack::Pop( self );
       
    58 
       
    59     PRINT ( _L("End CCsMsgHandler::NewL") );
       
    60 
       
    61     return self;
       
    62     }
       
    63 
       
    64 // ----------------------------------------------------------------------------
       
    65 // CCsMsgHandler::~CCsMsgHandler
       
    66 // Destructor
       
    67 // ----------------------------------------------------------------------------
       
    68 //
       
    69 CCsMsgHandler::~CCsMsgHandler()
       
    70     {
       
    71     PRINT ( _L("Enter CCsMsgHandler::~CCsMsgHandler") );
       
    72     if(iIdle)
       
    73         {
       
    74         iIdle->Cancel();
       
    75         delete iIdle;
       
    76         iIdle=NULL;
       
    77         }
       
    78     if(iMsgPluginUtility)
       
    79         {
       
    80         delete iMsgPluginUtility;
       
    81         iMsgPluginUtility = NULL;
       
    82         }
       
    83 
       
    84     if(iConverstationEntryList)
       
    85         {
       
    86         iConverstationEntryList->ResetAndDestroy();
       
    87         iConverstationEntryList->Close();
       
    88         delete iConverstationEntryList;
       
    89         iConverstationEntryList = NULL;
       
    90         }
       
    91 
       
    92     if(iSmsMtm)
       
    93         {
       
    94         delete iSmsMtm;
       
    95         iSmsMtm = NULL;
       
    96         }
       
    97 
       
    98     if(iMmsMtm)
       
    99         {
       
   100         delete iMmsMtm;
       
   101         iMmsMtm = NULL;
       
   102         }
       
   103 
       
   104     if(iMtmRegistry)
       
   105         {
       
   106         delete iMtmRegistry;
       
   107         iMtmRegistry = NULL;
       
   108         }
       
   109 
       
   110     if(iSession)
       
   111         {
       
   112         delete iSession;
       
   113         iSession = NULL;
       
   114         }
       
   115 
       
   116     if(iMessageArray)
       
   117     {
       
   118         iMessageArray->Reset();
       
   119         iMessageArray->Close();
       
   120         delete iMessageArray;
       
   121         iMessageArray = NULL;
       
   122     }
       
   123 
       
   124     PRINT ( _L("End CCsMsgHandler::~CCsMsgHandler") );
       
   125     }
       
   126 
       
   127 // ----------------------------------------------------------------------------
       
   128 // CCsMsgHandler::ConstructL
       
   129 // Two Phase Construction
       
   130 // ----------------------------------------------------------------------------
       
   131 //
       
   132 void CCsMsgHandler::ConstructL(MCsMsgObserver *aMsgObserver)
       
   133     {
       
   134     PRINT ( _L("Enter CCsMsgHandler::ConstructL") );
       
   135 
       
   136     iMsgObserver = aMsgObserver;
       
   137 
       
   138     iSession = CMsvSession::OpenSyncL(*this);
       
   139 
       
   140     iMsgPluginUtility = CCsMsgPluginUtility::NewL();
       
   141 
       
   142     iConverstationEntryList = new(ELeave) RPointerArray<CCsConversationEntry>(1);
       
   143 
       
   144     iMtmRegistry = CClientMtmRegistry::NewL( *iSession );
       
   145 
       
   146     iSmsMtm = static_cast<CSmsClientMtm*>( iMtmRegistry->
       
   147             NewMtmL( KSenduiMtmSmsUid ) );
       
   148 
       
   149     iMmsMtm = static_cast<CMmsClientMtm*>( iMtmRegistry->
       
   150             NewMtmL( KSenduiMtmMmsUid ) );
       
   151 
       
   152     iState = EReadInbox;
       
   153 
       
   154     iMessageArray = new (ELeave)RArray <TMsvId>(KMessageArrayGranularity);
       
   155 
       
   156     PRINT ( _L("End CCsMsgHandler::ConstructL") );
       
   157     }
       
   158 
       
   159 // ----------------------------------------------------------------------------
       
   160 // CCsMsgHandler::CCsMsgHandler
       
   161 // Two Phase Construction
       
   162 // ----------------------------------------------------------------------------
       
   163 //
       
   164 CCsMsgHandler::CCsMsgHandler()
       
   165     {
       
   166     }
       
   167 
       
   168 // -----------------------------------------------------------------------------
       
   169 // CCsMsgHandler::ProcessResultsL()
       
   170 // ProcessResultsL fetches results for the searchsort query and
       
   171 // updates the CCsServer with the fetched data
       
   172 // -----------------------------------------------------------------------------
       
   173 //
       
   174 void CCsMsgHandler::ProcessResultsL(TMsvEntry entry)
       
   175     {
       
   176     PRINT ( _L("Enter CCsMsgHandler::ProcessResultsL"));
       
   177 
       
   178     // Cleanup the conversationEntry List initially.
       
   179     // So that the previous entries not cleaned up in
       
   180     // the event of Leave have been clean up.
       
   181     iConverstationEntryList->ResetAndDestroy();
       
   182 
       
   183     RPointerArray<HBufC> addressList;
       
   184 
       
   185     // Ignore hidden items during upload
       
   186     if ( entry.Visible() == EFalse )
       
   187         {
       
   188         return;
       
   189         }
       
   190     
       
   191     if ( entry.Parent() == KMsvGlobalInBoxIndexEntryIdValue ||
       
   192          entry.Parent() == KMsvSentEntryIdValue ||
       
   193          entry.Parent() == KMsvGlobalOutBoxIndexEntryIdValue )
       
   194         {
       
   195         CleanupResetAndDestroyPushL(addressList);
       
   196         
       
   197         iMsgPluginUtility->CreateContactL(iSession, entry, addressList);
       
   198 
       
   199         //process entry
       
   200         ExtractAddressesL(entry, ERead, addressList);
       
   201         
       
   202         // Cleanup addressList
       
   203         CleanupStack::PopAndDestroy(&addressList);
       
   204         }
       
   205 
       
   206     PRINT ( _L("Exit CCsMsgHandler::ProcessResultsL") );
       
   207     }
       
   208 
       
   209 // ----------------------------------------------------------------------------
       
   210 // CCsMsgHandler::HandleSessionEventL
       
   211 // Implemented for MMsvSessionObserver
       
   212 // ----------------------------------------------------------------------------
       
   213 //
       
   214 void CCsMsgHandler::HandleSessionEventL( TMsvSessionEvent aEvent,
       
   215         TAny* aArg1,
       
   216         TAny* aArg2,
       
   217         TAny* /*aArg3*/)
       
   218     {
       
   219     PRINT1 ( _L("Enter CCsMsgHandler::HandleSessionEventL aEvent=%d"),aEvent );
       
   220 
       
   221     CMsvEntrySelection* selection=NULL;
       
   222     TMsvId parent;
       
   223 
       
   224     //args
       
   225     if(aArg1 == NULL || aArg2 == NULL)
       
   226         {
       
   227         PRINT ( _L("Enter CCsMsgHandler::HandleSessionEventL arguments invalid"));
       
   228         return;
       
   229         }
       
   230 
       
   231     //start, processing the event
       
   232     selection= (CMsvEntrySelection*)aArg1;
       
   233     parent = *(TMsvId*)aArg2;
       
   234 
       
   235     // Cleanup the conversationEntry List initially.
       
   236     iConverstationEntryList->ResetAndDestroy();
       
   237 
       
   238     switch( aEvent )
       
   239         {
       
   240         case EMsvEntriesChanged:
       
   241         case EMsvEntriesMoved:
       
   242             {
       
   243             HandleEventL(selection,parent);
       
   244             }
       
   245             break;
       
   246             
       
   247         case EMsvEntriesDeleted:
       
   248             {
       
   249             if ( parent == KMsvGlobalInBoxIndexEntryIdValue || 
       
   250                  parent == KMsvSentEntryIdValue ||
       
   251                  parent == KMsvGlobalOutBoxIndexEntryIdValue)
       
   252                 {
       
   253                 for( TInt i=0 ; i < selection->Count() ; i++ )
       
   254                     {
       
   255                     TMsvId id = selection->At( i );
       
   256 
       
   257                     //use utility to create conversation entry
       
   258                     CCsConversationEntry *conversationEntry = 
       
   259                     iMsgPluginUtility->CreateConversationEntryL(
       
   260                             NULL,
       
   261                             id,
       
   262                             0,
       
   263                             parent,
       
   264                             NULL,
       
   265                             ECsSendStateUnknown,
       
   266                             ECsAttributeNone,
       
   267                             0);
       
   268                     CleanupStack::PushL(conversationEntry);
       
   269                     iConverstationEntryList->AppendL( conversationEntry );
       
   270                     CleanupStack::Pop(conversationEntry);
       
   271 
       
   272                     // call observer interface for each entry
       
   273                     iMsgObserver->HandleDeleteCompleteL(iConverstationEntryList);
       
   274 
       
   275                     //cleanup before next iteration
       
   276                     iConverstationEntryList->ResetAndDestroy();
       
   277                     }
       
   278                 }
       
   279             }
       
   280             break;
       
   281             
       
   282         case EMsvMediaChanged:
       
   283             iMsgObserver->HandleRefreshCompleteL();
       
   284             break;
       
   285         }
       
   286 
       
   287     // Cleanup the conversationEntry List before function exits.
       
   288     iConverstationEntryList->ResetAndDestroy();
       
   289     PRINT ( _L("Exit CCsMsgHandler::HandleSessionEventL") );
       
   290     }
       
   291 
       
   292 // ---------------------------------------------------------------------
       
   293 // CCsMsgHandler::HandleEvent
       
   294 // Handle events
       
   295 // ---------------------------------------------------------------------
       
   296 //
       
   297 void CCsMsgHandler::HandleEventL(CMsvEntrySelection* aSelection, TMsvId aParent)
       
   298     {
       
   299     PRINT ( _L("Enter CCsMsgHandler::HandleEvent") );
       
   300     TMsvEntry entry;
       
   301     TMsvId service;
       
   302     TInt error= KErrNone;
       
   303     RPointerArray<HBufC> addressList;
       
   304 
       
   305     for( TInt i=0 ; i < aSelection->Count() ; i++ )
       
   306         {
       
   307         error = iSession->GetEntry(aSelection->At(i),service,entry);
       
   308         
       
   309         if (aParent == KMsvGlobalInBoxIndexEntryIdValue && KSenduiMtmSmsUidValue == entry.iMtm.iUid) 
       
   310 						{
       
   311             iSmsMtm->SwitchCurrentEntryL(entry.Id());
       
   312             iSmsMtm->LoadMessageL();
       
   313 
       
   314             CSmsHeader& header = static_cast<CSmsClientMtm*> (iSmsMtm)->SmsHeader();
       
   315             CSmsPDU& pdu = header.Message().SmsPDU();
       
   316             TSmsDataCodingScheme::TSmsClass smsClass;
       
   317 
       
   318             if (pdu.Class(smsClass) && smsClass == TSmsDataCodingScheme::ESmsClass0
       
   319                 && entry.ReadOnly()) 
       
   320 							{
       
   321                 iSmsMtm->SwitchCurrentEntryL(entry.iServiceId);
       
   322                 // for class 0 sms dont create conversation entry.. 
       
   323                 continue;
       
   324             	}
       
   325 
       
   326         	 }
       
   327         if (entry.Visible() == EFalse) 
       
   328 						{
       
   329             // Do a delete if entry becomes invisible.
       
   330             // e.g) My Nokia registration messages.
       
   331             RPointerArray<CCsConversationEntry>* hiddenEntries =  
       
   332                     new (ELeave) RPointerArray<CCsConversationEntry>();
       
   333             
       
   334             CCsConversationEntry *conversationEntry = 
       
   335                     iMsgPluginUtility->CreateConversationEntryL ( 
       
   336                             NULL,
       
   337                             entry.Id(),
       
   338                             0,
       
   339                             aParent,
       
   340                             NULL,
       
   341                             ECsSendStateUnknown,
       
   342                             ECsAttributeNone,
       
   343                             0 );  
       
   344             CleanupStack::PushL(conversationEntry);
       
   345             hiddenEntries->AppendL( conversationEntry );
       
   346             CleanupStack::Pop(conversationEntry);
       
   347             
       
   348             // Delete at server
       
   349             iMsgObserver->HandleDeleteCompleteL(hiddenEntries);
       
   350             hiddenEntries->ResetAndDestroy();
       
   351             hiddenEntries->Close();
       
   352             delete hiddenEntries;
       
   353             
       
   354             break;
       
   355             }
       
   356         
       
   357         if ( (KErrNone == error) && (IsMtmSupported(entry.iMtm.iUid) ) )
       
   358             {
       
   359             // sent/inbox/Outbox entry
       
   360             if ( aParent == KMsvSentEntryIdValue ||
       
   361                  aParent == KMsvGlobalInBoxIndexEntryIdValue )
       
   362                 {
       
   363                 CleanupResetAndDestroyPushL(addressList);
       
   364                 // currently server needs number, so getting it from header
       
   365                 iMsgPluginUtility->CreateContactL(iSession, entry,
       
   366                         addressList);
       
   367 
       
   368                 //process entry
       
   369                 // entry created in sent already exists, hence an update
       
   370                 ExtractAddressesL(entry, EUpdate, addressList);
       
   371 
       
   372                 CleanupStack::PopAndDestroy(&addressList);
       
   373                 }  
       
   374                 
       
   375             //for drafts and outbox, the entry changes multiple times,
       
   376             // so making a check if entry has changed
       
   377             else if(aParent == KMsvGlobalOutBoxIndexEntryIdValue)
       
   378                 {
       
   379                 //outbox
       
   380                 if(!(iMsgPluginUtility->CompareEntry(iPrevEntry,entry,aParent)))
       
   381                     {
       
   382                     TUint sendState = entry.SendingState();
       
   383                     
       
   384                     // if the entry state is sent, we dont need to process it
       
   385                     // as it is going to appear in sent items
       
   386                     if( ECsSendStateSent != iMsgPluginUtility->GetSendState(entry) )
       
   387                         {
       
   388                          CleanupResetAndDestroyPushL(addressList);
       
   389                         // currently server needs number, so getting it from header
       
   390                         iMsgPluginUtility->CreateContactL(iSession, entry,
       
   391                                 addressList);
       
   392                         
       
   393                         //process entry
       
   394                         // entry created in sent already exists, hence an update
       
   395                         ExtractAddressesL(entry, EUpdate, addressList);
       
   396                         
       
   397                         iPrevEntry = entry;
       
   398                         
       
   399                         CleanupStack::PopAndDestroy(&addressList);
       
   400                         }
       
   401                     }//end check changed entry
       
   402                 }
       
   403             }
       
   404         }//end for loop
       
   405 
       
   406     PRINT ( _L("Exit CCsMsgHandler::HandleEvent") );
       
   407     }
       
   408 
       
   409 // ----------------------------------------------------------------------------
       
   410 // CCsMsgHandler::CreateAndAddEntryL
       
   411 // Creates CCsConversationEntry and adds to the list
       
   412 // ----------------------------------------------------------------------------
       
   413 //
       
   414 void CCsMsgHandler::CreateAndAddEntryL(const TDesC& aContact, 
       
   415         const TDesC& aDescription, 
       
   416         const TMsvEntry& aEntry)
       
   417     {
       
   418     PRINT ( _L("Enter CCsMsgHandler::CreateAndAddEntryL") );
       
   419 
       
   420     HBufC* contact = NULL;
       
   421     HBufC* sDescription = NULL;
       
   422 
       
   423     if (aContact.Length()>0)
       
   424         {
       
   425         contact = aContact.AllocLC();
       
   426         }
       
   427     if (aDescription.Length()>0)
       
   428         {
       
   429         sDescription = aDescription.AllocLC();
       
   430         }
       
   431 
       
   432     //use utility to create conversation entry
       
   433     CCsConversationEntry *conversationEntry = iMsgPluginUtility->CreateConversationEntryL(
       
   434             contact,
       
   435             aEntry.Id(),
       
   436             aEntry.iDate.Int64(),
       
   437             aEntry.Parent(),
       
   438             sDescription,
       
   439             iMsgPluginUtility->GetSendState(aEntry),
       
   440             iMsgPluginUtility->GetMsgAttributes(aEntry),
       
   441             ExtractCsType(aEntry));
       
   442     CleanupStack::PushL(conversationEntry);
       
   443 
       
   444     //add to the list
       
   445     iConverstationEntryList->AppendL( conversationEntry );
       
   446     CleanupStack::Pop(conversationEntry);
       
   447 
       
   448     // cleanup
       
   449     if (sDescription)
       
   450         {
       
   451         CleanupStack::PopAndDestroy(sDescription);
       
   452         }
       
   453     if (contact)
       
   454         {
       
   455         CleanupStack::PopAndDestroy(contact);
       
   456         }
       
   457 
       
   458     PRINT ( _L("Exit CCsMsgHandler::CreateAndAddEntryL") );
       
   459     }
       
   460 
       
   461 // ----------------------------------------------------------------------------
       
   462 // CCsMsgHandler::ProcessEntryL
       
   463 // Creates CCsConversationEntry and adds to the list
       
   464 // ----------------------------------------------------------------------------
       
   465 //
       
   466 void CCsMsgHandler::ProcessEntryL( TEventType aEvent, const TDesC& aContact, 
       
   467         const TDesC& aDescription, const TMsvEntry& aEntry)
       
   468     {
       
   469     PRINT ( _L("Enter CCsMsgHandler::ProcessEntryL") );
       
   470 
       
   471     // create and add entry to the list
       
   472     CreateAndAddEntryL(aContact,aDescription,aEntry);
       
   473 
       
   474     // call cs observer interface for each entry
       
   475     switch(aEvent)
       
   476         {
       
   477         case ERead:
       
   478             {
       
   479             iMsgObserver->HandleReadCompleteL(iConverstationEntryList);
       
   480             }
       
   481             break;
       
   482         case EUpdate:
       
   483             {
       
   484             iMsgObserver->HandleUpdateCompleteL(iConverstationEntryList);
       
   485             }
       
   486             break;
       
   487         }
       
   488 
       
   489     // Cleanup the conversationEntry List, as we are just sending one entry at a time
       
   490     iConverstationEntryList->ResetAndDestroy();
       
   491 
       
   492     PRINT ( _L("Exit CCsMsgHandler::ProcessEntryL") );
       
   493     }
       
   494 
       
   495 // ----------------------------------------------------------------------------
       
   496 // CCsMsgHandler::ExtractAddressL
       
   497 // Extracts the addresses in the to field and updates them to server
       
   498 // ----------------------------------------------------------------------------
       
   499 //
       
   500 void CCsMsgHandler::ExtractAddressesL( 
       
   501         TMsvEntry aEntry, 
       
   502         TEventType aEvent, 
       
   503         RPointerArray<HBufC>& addressList )
       
   504     {
       
   505     PRINT ( _L("Enter CCsMsgHandler::ExtractAddressesL") );
       
   506 
       
   507     // For SMS read the whole body.
       
   508     // For bio type SMS read the iDescription
       
   509     // For other message types read the iDescription
       
   510     // Note: After the LoadMessageL() the iDescription is getting 
       
   511     // deleted so need to make a copy before that.
       
   512     TPtrC description;
       
   513     HBufC* tmpBuffer = NULL;
       
   514 
       
   515     if ( (aEntry.iBioType && 
       
   516 	      aEntry.iBioType != KUidMsgSubTypeMmsAudioMsg.iUid ) || 
       
   517 		  aEntry.iMtm == KSenduiMtmBtUid ) 
       
   518         {
       
   519         tmpBuffer = aEntry.iDescription.AllocLC();
       
   520         description.Set( tmpBuffer->Des() );         
       
   521         }    
       
   522     else if ( aEntry.iMtm == KSenduiMtmSmsUid )  
       
   523         {
       
   524         iSmsMtm->SwitchCurrentEntryL( aEntry.Id() );
       
   525         iSmsMtm->LoadMessageL();
       
   526             
       
   527         CRichText& body = iSmsMtm->Body();
       
   528         TInt smsLength = body.DocumentLength();      
       
   529         tmpBuffer = HBufC::NewLC(smsLength);
       
   530         TPtr ptr(tmpBuffer->Des());
       
   531         body.Extract(ptr, 0);
       
   532         description.Set( tmpBuffer->Des() );  
       
   533         }
       
   534     else if ( aEntry.iMtm == KSenduiMtmMmsUid  || 
       
   535 	          aEntry.iMtm == KSenduiMMSNotificationUid)  
       
   536         {
       
   537         tmpBuffer = aEntry.iDescription.AllocLC();
       
   538         description.Set( tmpBuffer->Des() );         
       
   539 
       
   540         iMmsMtm->SwitchCurrentEntryL( aEntry.Id() );
       
   541         iMmsMtm->LoadMessageL();
       
   542 
       
   543         // Handle addresses
       
   544         if ( aEntry.Parent() == KMsvGlobalInBoxIndexEntryIdValue )
       
   545             {
       
   546             HBufC* address = iMmsMtm->Sender().AllocL();
       
   547             addressList.Append(address);
       
   548             }
       
   549         else if ( aEntry.Parent() == KMsvSentEntryIdValue ||
       
   550                   aEntry.Parent() == KMsvGlobalOutBoxIndexEntryIdValue )
       
   551             {
       
   552             const CMsvRecipientList& addresses = iMmsMtm->AddresseeList();
       
   553             TInt count = addresses.Count();
       
   554 
       
   555             for( TInt i = 0; i < count; i++)
       
   556                 {
       
   557                 HBufC* address = addresses[i].AllocL();
       
   558                 TPtrC pureAddress = iMsgPluginUtility->PureAddress(*address);
       
   559                 HBufC* address1 = pureAddress.AllocL();
       
   560                 addressList.Append(address1);
       
   561                 delete address;
       
   562                 }
       
   563             }
       
   564         }
       
   565     else
       
   566         {
       
   567         return;
       
   568         }
       
   569 
       
   570     if ( addressList.Count() > 0 )
       
   571         {
       
   572         for ( int i = 0; i < addressList.Count(); i++ )
       
   573             {
       
   574             HBufC* address = addressList[i];
       
   575             ProcessEntryL(aEvent, *address, description, aEntry);
       
   576             }
       
   577         }
       
   578     else
       
   579         {
       
   580         // Unknown
       
   581         ProcessEntryL(aEvent, KNullDesC, description, aEntry);       
       
   582         }
       
   583     
       
   584     //Cleanup tmpBuffer
       
   585     if ( tmpBuffer )
       
   586         {
       
   587 		 CleanupStack::PopAndDestroy();
       
   588         }
       
   589 
       
   590     PRINT ( _L("Exit CCsMsgHandler::ExtractAddressesL") );
       
   591     }
       
   592 
       
   593 // -----------------------------------------------------------------------------
       
   594 // CCsMsgHandler::CompareOrder()
       
   595 // Method for determining the sorting behaviour of RArray of TMsvId's  
       
   596 // -----------------------------------------------------------------------------
       
   597 //
       
   598 static TInt CompareOrder(const TMsvId& aFirst, const TMsvId& aSecond)
       
   599     {
       
   600     return aSecond - aFirst;
       
   601     }
       
   602 // -----------------------------------------------------------------------------
       
   603 // CCsMsgHandler::UploadMsgL()
       
   604 // State machine to upload all messages 
       
   605 // -----------------------------------------------------------------------------
       
   606 //
       
   607 TInt CCsMsgHandler::UploadMsgL() 
       
   608     {
       
   609     //Release scheduler for scheduling.    
       
   610     User::After(1);
       
   611     
       
   612     switch ( iState ) 
       
   613         {
       
   614         case EReadInbox:
       
   615             {
       
   616             UpdateMessageArrayL(KMsvGlobalInBoxIndexEntryId);
       
   617             iState = EReadSent;
       
   618             return 1;
       
   619             }
       
   620 
       
   621         case EReadSent:
       
   622             {
       
   623             UpdateMessageArrayL(KMsvSentEntryId);
       
   624             iState = EReadOutbox;
       
   625             return 1;
       
   626             }
       
   627 
       
   628         case EReadOutbox:
       
   629             {
       
   630             UpdateMessageArrayL(KMsvGlobalOutBoxIndexEntryId);
       
   631             iState = ESortEntries;            
       
   632             return 1;
       
   633             }
       
   634         case ESortEntries:
       
   635             {
       
   636             //Sort the elements in the array by descending order of TMsvId's
       
   637             TLinearOrder<TMsvId> order(CompareOrder);
       
   638             iMessageArray->Sort(order);
       
   639             iState = EProcessEntries;
       
   640             return 1;
       
   641             }            
       
   642         case EProcessEntries:
       
   643             { 
       
   644             //Process one entry at a time in sequence
       
   645             //Process the first element in the array on each call, till the end
       
   646             if(iMessageArray->Count())
       
   647                 {
       
   648                 CMsvEntry* msvEntry= iSession->
       
   649                         GetEntryL(iMessageArray->operator[](0));
       
   650                 CleanupStack::PushL(msvEntry);
       
   651             TBool isNotClass0 = ETrue;
       
   652 
       
   653             if (msvEntry->Entry().iMtm.iUid == KSenduiMtmSmsUidValue && msvEntry->Entry().Parent()
       
   654                 == KMsvGlobalInBoxIndexEntryIdValue) 
       
   655 								{
       
   656                 iSmsMtm->SwitchCurrentEntryL(msvEntry->Entry().Id());
       
   657                 iSmsMtm->LoadMessageL();
       
   658 
       
   659                 CSmsHeader& header = static_cast<CSmsClientMtm*> (iSmsMtm)->SmsHeader();
       
   660                 CSmsPDU& pdu = header.Message().SmsPDU();
       
   661                 TSmsDataCodingScheme::TSmsClass smsClass;
       
   662 
       
   663                 if (pdu.Class(smsClass) && smsClass == TSmsDataCodingScheme::ESmsClass0)
       
   664 									{
       
   665                     isNotClass0 = EFalse;                  
       
   666                 	}
       
   667             	}
       
   668             if (isNotClass0) 
       
   669 							{
       
   670                 ProcessResultsL(msvEntry->Entry());
       
   671             	}
       
   672                 CleanupStack::PopAndDestroy(msvEntry);
       
   673                 iMessageArray->Remove(0);
       
   674                 }
       
   675             else
       
   676                 {
       
   677                 iMessageArray->Reset();
       
   678                 iMsgObserver->HandleCachingCompleted();
       
   679                 return 0; //DONE 
       
   680                 }            
       
   681             iState = EProcessEntries;
       
   682             return 1; 
       
   683         }
       
   684     }
       
   685     return 0;    
       
   686 }
       
   687 
       
   688 // -----------------------------------------------------------------------------
       
   689 // CCsMsgHandler::UploadMsg()
       
   690 // CIdle callback 
       
   691 // -----------------------------------------------------------------------------
       
   692 //
       
   693 TInt CCsMsgHandler::UploadMsg(TAny* aArg)
       
   694     {
       
   695     CCsMsgHandler* handler = (CCsMsgHandler*) aArg; 
       
   696     TInt ok = 0;
       
   697     TRAPD(err, ok = handler->UploadMsgL());
       
   698     return ((err == KErrNone) && ok);
       
   699     }
       
   700 
       
   701 // -----------------------------------------------------------------------------
       
   702 // CCsMsgHandler::StartL()
       
   703 // This function starts the state machine to fetch sms data from msvserver
       
   704 // -----------------------------------------------------------------------------
       
   705 //
       
   706 void CCsMsgHandler::StartL()
       
   707     {
       
   708     PRINT ( _L("Enter CCsMsgHandler::Start") );
       
   709 
       
   710     iState = EReadInbox;
       
   711     TCallBack callback = TCallBack(UploadMsg, (TAny*) this);
       
   712     
       
   713     if(iIdle)
       
   714         {
       
   715         delete iIdle;
       
   716         iIdle = NULL;
       
   717         }
       
   718     iIdle = CIdle::NewL(CActive::EPriorityIdle);
       
   719     iIdle->Start(callback);
       
   720 
       
   721     PRINT ( _L("End CCsMsgHandler::Start") );
       
   722     }
       
   723 
       
   724 // -----------------------------------------------------------------------------
       
   725 // CCsMsgHandler::IsMtmSupported()
       
   726 // 
       
   727 // -----------------------------------------------------------------------------
       
   728 //
       
   729 TBool CCsMsgHandler::IsMtmSupported(long uid)	
       
   730     {
       
   731     if ( KSenduiMtmSmsUidValue == uid || \
       
   732          KSenduiMtmBtUidValue == uid || \
       
   733          KSenduiMtmMmsUidValue == uid || \
       
   734          KSenduiMtmBioUidValue == uid  || \
       
   735          KSenduiMMSNotificationUidValue == uid || \
       
   736          KUidMtmWapPush ==  TUid::Uid(uid) )
       
   737         {
       
   738         return ETrue;
       
   739         }	
       
   740     return EFalse;
       
   741     }
       
   742 
       
   743 // -----------------------------------------------------------------------------
       
   744 // CCsMsgHandler::ExtractCsType()
       
   745 // Extracts the Message type based on the MTM Uid 
       
   746 // -----------------------------------------------------------------------------
       
   747 //
       
   748 TCsType CCsMsgHandler::ExtractCsType( const TMsvEntry& aEntry)
       
   749     {
       
   750     TCsType type = ECsUnknown;
       
   751     switch(aEntry.iMtm.iUid)
       
   752         {
       
   753         case KSenduiMtmSmsUidValue:            
       
   754             type = ECsSMS;
       
   755             if (aEntry.iBioType == KMsgBioUidVCard.iUid)
       
   756                 {
       
   757                 type = ECsBioMsg_VCard;
       
   758                 }
       
   759             break;
       
   760         case KSenduiMtmBtUidValue:
       
   761             type = ECsBlueTooth;
       
   762             break;
       
   763         case KSenduiMtmMmsUidValue:        
       
   764            if(aEntry.iBioType == KUidMsgSubTypeMmsAudioMsg.iUid)
       
   765                 {
       
   766                 type = ECsAudio;
       
   767                 }
       
   768             else
       
   769                 {
       
   770                 type = ECsMMS;
       
   771                 }
       
   772             break;
       
   773         case KSenduiMMSNotificationUidValue:            
       
   774             type = ECsMmsNotification;
       
   775             break;
       
   776         case KSenduiMtmBioUidValue:
       
   777             { 
       
   778 			if (aEntry.iMtmData1 == KSenduiMtmBtUidValue) 
       
   779 			{
       
   780            	 	if (aEntry.iBioType == KMsgBioUidVCard.iUid) 
       
   781 				{
       
   782                 	type = ECsBlueTooth_VCard;
       
   783             	}
       
   784             	else if (aEntry.iBioType == KMsgBioUidVCalendar.iUid)
       
   785 				{
       
   786                		type = ECsBlueTooth_VCal;
       
   787             	}
       
   788            		 break;
       
   789         	}
       
   790             type = ECsBioMsg; 
       
   791             
       
   792             // based on the biotype uid set message type
       
   793             if(aEntry.iBioType == KMsgBioUidRingingTone.iUid)
       
   794                 {
       
   795                 type = ECsRingingTone;
       
   796                 }
       
   797             else if(aEntry.iBioType == KMsgBioProvisioningMessage.iUid)
       
   798                 {
       
   799                 type = ECsProvisioning;
       
   800                 }
       
   801 		    else if (aEntry.iBioType == KMsgBioUidVCard.iUid)
       
   802                 {
       
   803                 type = ECsBioMsg_VCard;
       
   804                 }
       
   805             else if (aEntry.iBioType == KMsgBioUidVCalendar.iUid)
       
   806                 {
       
   807                 type = ECsBioMsg_VCal;
       
   808        		 }
       
   809        		 else if (aEntry.iBioType == KMsgBioNokiaServiceMessage.iUid) {
       
   810             	type = ECsBioMgs_NokiaService;
       
   811         }
       
   812     }
       
   813         break;
       
   814     default:
       
   815         type = ECsUnknown;
       
   816         break;
       
   817     }
       
   818     return (type);
       
   819 }
       
   820 // -----------------------------------------------------------------------------
       
   821 // void CCsMsgHandler::UpdateMessageArrayL(const TMsvId& aFolderId)
       
   822 // Update iMessageArray with the message ID before upload message to csserver. 
       
   823 // -----------------------------------------------------------------------------
       
   824 //
       
   825 void CCsMsgHandler::UpdateMessageArrayL(const TMsvId& aFolderId)
       
   826     {
       
   827     CMsvEntry* msvEntry = iSession->GetEntryL(aFolderId);
       
   828     CleanupStack::PushL(msvEntry);
       
   829     // Set sort order
       
   830     TMsvSelectionOrdering order;
       
   831     order.SetSorting(EMsvSortById);
       
   832     msvEntry->SetSortTypeL(order);
       
   833 
       
   834     CMsvEntrySelection* messages = msvEntry->ChildrenL();  
       
   835     // Cleanup msvEntry
       
   836     CleanupStack::PopAndDestroy(msvEntry);
       
   837     CleanupStack::PushL(messages);
       
   838 
       
   839     TInt messageCount = messages->Count();
       
   840     
       
   841     // In case of large number of message caching
       
   842     // to avoid multiple reallocation alloc memory
       
   843     // one shot.
       
   844     if( messageCount > KMessageArrayGranularity)
       
   845         iMessageArray->Reserve(messageCount);
       
   846     
       
   847     for(int i = 0; i < messageCount; i ++)
       
   848         {
       
   849         TMsvId msgId=messages->At(i);
       
   850         iMessageArray->Append(msgId);
       
   851         }
       
   852     // Cleanup messages
       
   853     CleanupStack::PopAndDestroy(messages); 
       
   854     }
       
   855 // End of file
       
   856