htiui/HtiServicePlugins/HtiMessagesServicePlugin/src/MessageMgmntHandler.cpp
changeset 0 d6fe6244b863
child 3 2703485a934c
equal deleted inserted replaced
-1:000000000000 0:d6fe6244b863
       
     1 /*
       
     2 * Copyright (c) 2009 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:  Functional implementation of HtiMessagesServicePlugin service
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "HtiMessagesServicePlugin.h"
       
    21 #include "MessageMgmntHandler.h"
       
    22 
       
    23 #include <HtiDispatcherInterface.h>
       
    24 #include <HTILogging.h>
       
    25 #include <mtclreg.h>
       
    26 #include <smscmds.h>
       
    27 #include <smtcmtm.h>
       
    28 #include <smuthdr.h>
       
    29 #include <smsclnt.h>
       
    30 #include <utf.h>
       
    31 #include <mmsclient.h>
       
    32 #include <mmsconst.h>
       
    33 #include <miutset.h>
       
    34 #include <irmsgtypeuid.h>
       
    35 #include <btmsgtypeuid.h>
       
    36 #include <biouids.h>
       
    37 #include <apgcli.h>
       
    38 #include <apmstd.h>
       
    39 #include <bautils.h>
       
    40 #include <obexclientmtm.h>
       
    41 #include <cmsvmimeheaders.h>
       
    42 #include <mmsvattachmentmanager.h>
       
    43 
       
    44 // CONSTANTS
       
    45 _LIT8( KErrorMissingCommand,        "Command was not given - message was empty" );
       
    46 _LIT8( KErrorUnrecognizedCommand,   "Unrecognized command" );
       
    47 _LIT8( KErrorInvalidParameters,     "Invalid command parameters");
       
    48 _LIT8( KErrorTooLongSmsBody,        "Too long SMS body" );
       
    49 _LIT8( KErrorInvalidId,             "Invalid SMS id parameter" );
       
    50 _LIT8( KErrorInvalidFolder,         "Invalid folder parameter" );
       
    51 _LIT8( KErrorItemNotFound,          "Item not found" );
       
    52 _LIT8( KErrorFailedDelete,          "Failed to delete item" );
       
    53 _LIT8( KErrorNotSupported,          "Not supported" );
       
    54 _LIT8( KErrorSmsSettingNotDefined,  "SMS settings not defined" );
       
    55 _LIT8( KErrorMmsSettingNotDefined,  "MMS settings not defined" );
       
    56 _LIT8( KErrorMailboxNotDefined,     "Mailbox not defined" );
       
    57 _LIT8( KErrorMsgTypeNotFound,       "Message type module not found" );
       
    58 _LIT8( KErrorMsgStoreOpenFailed,    "Could not open message store" );
       
    59 _LIT8( KErrorRfsConnectFailed,      "Could not connect to file server session" );
       
    60 _LIT8( KErrorAttachmentNotFound,    "Attachment not found" );
       
    61 _LIT8( KErrorInvalidFolderForSmartMsg, "Only inbox allowed for smart messages" );
       
    62 
       
    63 const static TInt KAddSmsCmdMinLength        = 7;
       
    64 const static TInt KAddMmsOrEmailCmdMinLength = 8;
       
    65 const static TInt KAddObexMsgCmdMinLength    = 6;
       
    66 const static TInt KAddSmartMsgCmdMinLength   = 11;
       
    67 const static TInt KAddAudioCmdMinLength      = 10;
       
    68 
       
    69 // ----------------------------------------------------------------------------
       
    70 CMessageMgmntHandler* CMessageMgmntHandler::NewL()
       
    71     {
       
    72     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::NewL" );
       
    73     CMessageMgmntHandler* self = new (ELeave) CMessageMgmntHandler();
       
    74     CleanupStack::PushL ( self );
       
    75     self->ConstructL();
       
    76     CleanupStack::Pop();
       
    77     HTI_LOG_FUNC_OUT( "CMessageMgmntHandler::NewL: Done" );
       
    78     return self;
       
    79     }
       
    80 
       
    81 // ----------------------------------------------------------------------------
       
    82 CMessageMgmntHandler::CMessageMgmntHandler()
       
    83     {
       
    84     }
       
    85 
       
    86 // ----------------------------------------------------------------------------
       
    87 CMessageMgmntHandler::~CMessageMgmntHandler()
       
    88     {
       
    89     delete iMtmReg;
       
    90     delete iSession;
       
    91     }
       
    92 
       
    93 // ----------------------------------------------------------------------------
       
    94 void CMessageMgmntHandler::ConstructL()
       
    95     {
       
    96     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::ConstructL" );
       
    97     iSession = CMsvSession::OpenSyncL( *this );
       
    98     iMtmReg = CClientMtmRegistry::NewL( *iSession );
       
    99     HTI_LOG_FUNC_OUT( "CMessageMgmntHandler::ConstructL: Done" );
       
   100     }
       
   101 
       
   102 // ----------------------------------------------------------------------------
       
   103 void CMessageMgmntHandler::SetDispatcher( MHtiDispatcher* aDispatcher )
       
   104     {
       
   105     iDispatcher = aDispatcher;
       
   106     }
       
   107 
       
   108 // ----------------------------------------------------------------------------
       
   109 void CMessageMgmntHandler::ProcessMessageL( const TDesC8& aMessage,
       
   110                                             THtiMessagePriority /*aPriority*/ )
       
   111     {
       
   112     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::ProcessMessageL" );
       
   113     HTI_LOG_FORMAT( "Msg length: %d", aMessage.Length() );
       
   114 
       
   115     if ( aMessage.Length() == 0 )
       
   116         {
       
   117         SendErrorMessageL( KErrArgument, KErrorMissingCommand );
       
   118         return;
       
   119         }
       
   120 
       
   121     switch ( aMessage[0] )
       
   122         {
       
   123         case CHtiMessagesServicePlugin::EAddSms:
       
   124             HTI_LOG_TEXT( "Add SMS" );
       
   125             HandleCreateSmsL( aMessage.Right( aMessage.Length() - 1 ) );
       
   126             break;
       
   127 
       
   128         case CHtiMessagesServicePlugin::EAddMms:
       
   129         case CHtiMessagesServicePlugin::EAddAudioMsg: // special MMS sub type
       
   130             HTI_LOG_TEXT( "Add MMS" );
       
   131             HandleCreateMmsL( aMessage );
       
   132             break;
       
   133 
       
   134         case CHtiMessagesServicePlugin::EAddEmail:
       
   135             HTI_LOG_TEXT( "Add Email" );
       
   136             HandleCreateEmailL( aMessage );
       
   137             break;
       
   138 
       
   139         case CHtiMessagesServicePlugin::EAddIrMsg:
       
   140             HTI_LOG_TEXT( "Add IR msg" );
       
   141             HandleCreateObexMsgL( aMessage.Right( aMessage.Length() - 1 ),
       
   142                                   TUid::Uid( KUidMsgTypeIrTInt32 ),
       
   143                                   KUidMsgTypeIrUID );
       
   144             break;
       
   145 
       
   146         case CHtiMessagesServicePlugin::EAddBtMsg:
       
   147             HTI_LOG_TEXT( "Add BT msg" );
       
   148             HandleCreateObexMsgL( aMessage.Right( aMessage.Length() - 1 ),
       
   149                                   TUid::Uid( KUidMsgTypeBtTInt32 ),
       
   150                                   KUidMsgTypeBt );
       
   151             break;
       
   152 
       
   153         case CHtiMessagesServicePlugin::EAddSmartMsg:
       
   154             HTI_LOG_TEXT( "Add smart msg" );
       
   155             HandleCreateSmartMsgL( aMessage.Right( aMessage.Length() - 1 ) );
       
   156             break;
       
   157 
       
   158         case CHtiMessagesServicePlugin::EDeleteMessage:
       
   159             HTI_LOG_TEXT( "Delete message" );
       
   160             HandleDeleteMessageL( aMessage.Right( aMessage.Length() - 1 ) );
       
   161             break;
       
   162 
       
   163         case CHtiMessagesServicePlugin::EDeleteFolderContent:
       
   164             HTI_LOG_TEXT( "Delete messages" );
       
   165             HandleDeleteMessagesL( aMessage.Right( aMessage.Length() - 1 ) );
       
   166             break;
       
   167 
       
   168         default:
       
   169             HTI_LOG_TEXT( "Unknown command" );
       
   170             SendErrorMessageL( KErrUnknown, KErrorUnrecognizedCommand );
       
   171             break;
       
   172         }
       
   173 
       
   174     HTI_LOG_FUNC_OUT( "CMessageMgmntHandler::ProcessMessageL: Done" );
       
   175     }
       
   176 
       
   177 // ----------------------------------------------------------------------------
       
   178 void CMessageMgmntHandler::HandleCreateSmsL( const TDesC8& aData )
       
   179     {
       
   180     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleSmsImportFuncL" );
       
   181 
       
   182     if ( ValidateAddSmsCommand( aData ) )
       
   183         {
       
   184         TInt position( 0 );
       
   185         HBufC16* fromTo = ExtractDesLC( aData, position, 1 );
       
   186         HBufC16* description = ExtractDesLC( aData, position, 1 );
       
   187         HBufC16* body = ExtractDesLC( aData, position, 2 );
       
   188         TBool isNew = (TBool)aData[position];
       
   189         TBool isUnread = (TBool)aData[position+1];
       
   190         TFolder folder = (TFolder)aData[position+2];
       
   191 
       
   192         CSmsClientMtm* smsMtm = NULL;
       
   193         TRAPD( err, smsMtm = ( CSmsClientMtm* )iMtmReg->NewMtmL(
       
   194                 KUidMsgTypeSMS ) );
       
   195         if ( err || !smsMtm )
       
   196             {
       
   197             HTI_LOG_TEXT( "SMS message type module not found" );
       
   198             SendErrorMessageL( KErrNotFound, KErrorMsgTypeNotFound );
       
   199             CleanupStack::PopAndDestroy( body );
       
   200             CleanupStack::PopAndDestroy( description );
       
   201             CleanupStack::PopAndDestroy( fromTo );
       
   202             return;
       
   203             }
       
   204         CleanupStack::PushL( smsMtm );
       
   205 
       
   206         CMsvEntry* entry = CMsvEntry::NewL( *iSession,
       
   207                                             KMsvGlobalInBoxIndexEntryId,
       
   208                                             TMsvSelectionOrdering() );
       
   209         CleanupStack::PushL( entry );
       
   210 
       
   211         // get the default service
       
   212         TMsvId defaultServiceId = 0;
       
   213         TRAP( err, defaultServiceId = smsMtm->DefaultServiceL() );
       
   214         if ( err )
       
   215             {
       
   216             HTI_LOG_FORMAT( "Could not get default service, err: %d", err );
       
   217             SendErrorMessageL( err, KErrorSmsSettingNotDefined );
       
   218             CleanupStack::PopAndDestroy( entry );
       
   219             CleanupStack::PopAndDestroy( smsMtm );
       
   220             CleanupStack::PopAndDestroy( body );
       
   221             CleanupStack::PopAndDestroy( description );
       
   222             CleanupStack::PopAndDestroy( fromTo );
       
   223             return;
       
   224             }
       
   225 
       
   226         // map the folder parameter to folder id
       
   227         TMsvId folderId = KMsvGlobalInBoxIndexEntryId;
       
   228         TRAP( err, folderId = MapFolderToIdL( folder ) );
       
   229         if ( err )
       
   230             {
       
   231             HTI_LOG_FORMAT( "Invalid folder: %d", folder );
       
   232             SendErrorMessageL( err, KErrorInvalidFolder );
       
   233             CleanupStack::PopAndDestroy( entry );
       
   234             CleanupStack::PopAndDestroy( smsMtm );
       
   235             CleanupStack::PopAndDestroy( body );
       
   236             CleanupStack::PopAndDestroy( description );
       
   237             CleanupStack::PopAndDestroy( fromTo );
       
   238             return;
       
   239             }
       
   240         entry->SetEntryL( folderId );
       
   241 
       
   242         // mtm takes ownership of entry context
       
   243         smsMtm->SetCurrentEntryL( entry );
       
   244         CleanupStack::Pop( entry );
       
   245 
       
   246         // create a new message
       
   247         smsMtm->CreateMessageL( defaultServiceId );
       
   248 
       
   249         if ( folder == EInbox )
       
   250             {
       
   251             CSmsHeader* smsHeader = &( smsMtm->SmsHeader() );
       
   252             delete smsHeader;
       
   253             smsHeader = NULL;
       
   254             smsHeader = CSmsHeader::NewL( CSmsPDU::ESmsDeliver, smsMtm->Body() );
       
   255             smsHeader->SetFromAddressL( fromTo->Des() );
       
   256             }
       
   257         else
       
   258             {
       
   259             smsMtm->AddAddresseeL( fromTo->Des() );
       
   260 
       
   261             // set delivery settings
       
   262             CSmsSettings* sendOptions = CSmsSettings::NewL();
       
   263             CleanupStack::PushL( sendOptions );
       
   264             sendOptions->CopyL( smsMtm->ServiceSettings() );
       
   265             sendOptions->SetDelivery( ESmsDeliveryImmediately );
       
   266 
       
   267             CSmsHeader* smsHeader = &( smsMtm->SmsHeader() );
       
   268             smsHeader->SetSmsSettingsL( *sendOptions );
       
   269             CleanupStack::PopAndDestroy( sendOptions );
       
   270             }
       
   271 
       
   272 
       
   273 
       
   274         // set body
       
   275         smsMtm->Body().Reset();
       
   276         smsMtm->Body().InsertL( 0, *body );
       
   277 
       
   278         // save the message
       
   279         smsMtm->SaveMessageL();
       
   280 
       
   281         // get the entry of the message
       
   282         TMsvEntry tentry = smsMtm->Entry().Entry();
       
   283 
       
   284         // set the details field
       
   285         tentry.iDetails.Set( fromTo->Des() );
       
   286 
       
   287         // set the description field if it is given.
       
   288         // (with no description the beginning of the message body
       
   289         //  is used as a description)
       
   290         if ( description->Length() > 0 )
       
   291             {
       
   292             tentry.iDescription.Set( description->Des() );
       
   293             }
       
   294 
       
   295         // final fine tuning
       
   296         tentry.SetAttachment( EFalse );
       
   297         tentry.iDate.UniversalTime();
       
   298         tentry.SetVisible( ETrue );
       
   299         tentry.SetInPreparation( EFalse );
       
   300         tentry.SetUnread( isUnread );
       
   301         tentry.SetNew( isNew );
       
   302         tentry.SetComplete( ETrue );
       
   303         tentry.SetSendingState( KMsvSendStateWaiting );
       
   304         tentry.iServiceId = defaultServiceId;
       
   305         tentry.iRelatedId = 0;
       
   306         if ( folder == EInbox )
       
   307             {
       
   308             tentry.SetReadOnly( ETrue );
       
   309             }
       
   310 
       
   311         smsMtm->Entry().ChangeL( tentry );
       
   312 
       
   313         // send the message, if it is in outbox
       
   314         if ( folder == EOutbox )
       
   315             {
       
   316             CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
   317             CleanupStack::PushL( selection );
       
   318             selection->AppendL( tentry.Id() );
       
   319 
       
   320             TBuf8<1> dummyParameter;
       
   321             CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
       
   322             CMsvOperation* op = smsMtm->InvokeAsyncFunctionL(
       
   323                     ESmsMtmCommandScheduleCopy, *selection,
       
   324                     dummyParameter, waiter->iStatus );
       
   325             CleanupStack::PushL( op );
       
   326             waiter->Start();
       
   327             CActiveScheduler::Start();
       
   328             CleanupStack::PopAndDestroy( op );
       
   329             CleanupStack::PopAndDestroy( waiter );
       
   330             CleanupStack::PopAndDestroy( selection );
       
   331             }
       
   332 
       
   333         CleanupStack::PopAndDestroy( smsMtm );
       
   334         CleanupStack::PopAndDestroy( body );
       
   335         CleanupStack::PopAndDestroy( description );
       
   336         CleanupStack::PopAndDestroy( fromTo );
       
   337 
       
   338         TInt32 id = tentry.Id();
       
   339         TBuf8<8> idStr;
       
   340         idStr.Copy( ( TUint8* )( &id ), sizeof( id ) );
       
   341         SendOkMsgL( idStr );
       
   342         }
       
   343 
       
   344     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleSmsImportFuncL: Done");
       
   345     }
       
   346 
       
   347 // ----------------------------------------------------------------------------
       
   348 void CMessageMgmntHandler::HandleCreateMmsL( const TDesC8& aData )
       
   349     {
       
   350     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleCreateMmsL" );
       
   351 
       
   352     if ( !ValidateAddMmsOrAddEmailCommand( aData ) )
       
   353         {
       
   354         // Error message has been sent from validation method.
       
   355         return;
       
   356         }
       
   357 
       
   358     // parse the parameters
       
   359     TInt position( 0 );
       
   360     TInt cmdCode = aData[position];
       
   361     position++;
       
   362     HBufC16* fromTo = ExtractDesLC( aData, position, 1 );
       
   363     HBufC16* description = ExtractDesLC( aData, position, 1 );
       
   364     HBufC8* body = NULL;
       
   365     if ( cmdCode == CHtiMessagesServicePlugin::EAddMms )
       
   366         {
       
   367         body = ExtractDes8LC( aData, position, 2 );
       
   368         }
       
   369     else // Audio msg does not have body text
       
   370         {
       
   371         body = HBufC8::NewLC( 0 );
       
   372         }
       
   373     HBufC16* attPath = ExtractDesLC( aData, position, 1 );
       
   374     TBool isNew = (TBool)aData[position];
       
   375     TBool isUnread = (TBool)aData[position+1];
       
   376     TFolder folder = (TFolder)aData[position+2];
       
   377 
       
   378     HTI_LOG_TEXT( "Creating MMS Client MTM" );
       
   379     CMmsClientMtm* mmsMtm = NULL;
       
   380     TRAPD( err , mmsMtm = ( CMmsClientMtm* )iMtmReg->NewMtmL(
       
   381             KUidMsgTypeMultimedia ) );
       
   382     if ( err || !mmsMtm )
       
   383         {
       
   384         HTI_LOG_TEXT( "MMS message type module not found" );
       
   385         SendErrorMessageL( KErrNotFound, KErrorMsgTypeNotFound );
       
   386         CleanupStack::PopAndDestroy( attPath );
       
   387         CleanupStack::PopAndDestroy( body );
       
   388         CleanupStack::PopAndDestroy( description );
       
   389         CleanupStack::PopAndDestroy( fromTo );
       
   390         return;
       
   391         }
       
   392     CleanupStack::PushL( mmsMtm );
       
   393 
       
   394     HTI_LOG_TEXT( "Creating MMS Client MTM" );
       
   395     CMsvEntry* entry = CMsvEntry::NewL( *iSession,
       
   396                                         KMsvGlobalInBoxIndexEntryId,
       
   397                                         TMsvSelectionOrdering() );
       
   398     CleanupStack::PushL( entry );
       
   399 
       
   400     // get the default service
       
   401     TMsvId defaultServiceId = 0;
       
   402     TRAP( err, defaultServiceId = mmsMtm->DefaultServiceL() );
       
   403     if ( err )
       
   404         {
       
   405         HTI_LOG_FORMAT( "Could not get default service, err: %d", err );
       
   406         SendErrorMessageL( err, KErrorMmsSettingNotDefined );
       
   407         CleanupStack::PopAndDestroy( entry );
       
   408         CleanupStack::PopAndDestroy( mmsMtm );
       
   409         CleanupStack::PopAndDestroy( attPath );
       
   410         CleanupStack::PopAndDestroy( body );
       
   411         CleanupStack::PopAndDestroy( description );
       
   412         CleanupStack::PopAndDestroy( fromTo );
       
   413         return;
       
   414         }
       
   415 
       
   416     // map the folder parameter to folder id
       
   417     TMsvId folderId = KMsvGlobalInBoxIndexEntryId;
       
   418     TRAP( err, folderId = MapFolderToIdL( folder ) );
       
   419     if ( err )
       
   420         {
       
   421         HTI_LOG_FORMAT( "Invalid folder: %d", folder );
       
   422         SendErrorMessageL( err, KErrorInvalidFolder );
       
   423         CleanupStack::PopAndDestroy( entry );
       
   424         CleanupStack::PopAndDestroy( mmsMtm );
       
   425         CleanupStack::PopAndDestroy( attPath );
       
   426         CleanupStack::PopAndDestroy( body );
       
   427         CleanupStack::PopAndDestroy( description );
       
   428         CleanupStack::PopAndDestroy( fromTo );
       
   429         return;
       
   430         }
       
   431     entry->SetEntryL( folderId );
       
   432 
       
   433     // mtm takes ownership of entry context
       
   434     mmsMtm->SetCurrentEntryL( entry );
       
   435     CleanupStack::Pop( entry );
       
   436 
       
   437     HTI_LOG_TEXT( "Creating MMS..." );
       
   438     mmsMtm->CreateMessageL( defaultServiceId );
       
   439     mmsMtm->SetMessageClass( EMmsClassPersonal );
       
   440     mmsMtm->SetExpiryInterval( 86400 );
       
   441     mmsMtm->SetDeliveryTimeInterval( 0 );
       
   442     mmsMtm->SetMessagePriority( EMmsPriorityNormal );
       
   443     mmsMtm->SetSenderVisibility( EMmsMaximumSenderVisibility );
       
   444     mmsMtm->SetDeliveryReport( EMmsDeliveryReportNo );
       
   445     mmsMtm->SetReadReply( EMmsReadReplyYes );
       
   446 
       
   447     if ( description->Length() > 0 )
       
   448         {
       
   449         mmsMtm->SetSubjectL( description->Des() );
       
   450         }
       
   451 
       
   452     if ( folder == EInbox )
       
   453         {
       
   454         mmsMtm->SetSenderL( fromTo->Des() );
       
   455         }
       
   456     else
       
   457         {
       
   458         mmsMtm->AddAddresseeL( fromTo->Des() );
       
   459         }
       
   460 
       
   461     // get an access to the message store
       
   462     HTI_LOG_TEXT( "Getting message store..." );
       
   463     CMsvStore* store = NULL;
       
   464     TRAP( err, store = entry->EditStoreL() );
       
   465     if ( err )
       
   466         {
       
   467         HTI_LOG_FORMAT( "Could not get access to message store, err: %d", err );
       
   468         SendErrorMessageL( err, KErrorMsgStoreOpenFailed );
       
   469         CleanupStack::PopAndDestroy( mmsMtm );
       
   470         CleanupStack::PopAndDestroy( attPath );
       
   471         CleanupStack::PopAndDestroy( body );
       
   472         CleanupStack::PopAndDestroy( description );
       
   473         CleanupStack::PopAndDestroy( fromTo );
       
   474         return;
       
   475         }
       
   476     CleanupStack::PushL( store );
       
   477 
       
   478     MMsvAttachmentManager& attachMan = store->AttachmentManagerL();
       
   479     // set body attachment only for normal MMS - audio message doesn't have body
       
   480     if ( cmdCode == CHtiMessagesServicePlugin::EAddMms )
       
   481         {
       
   482         // Set the message body as attachment
       
   483         // Use UTF-8 as charset because MMS created with MMS editor seems to
       
   484         // save text attachments also as UTF-8.
       
   485         HTI_LOG_TEXT( "Setting body..." );
       
   486         CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL();
       
   487         CleanupStack::PushL( mimeHeaders );
       
   488         mimeHeaders->SetContentTypeL( _L8( "text" ) );
       
   489         mimeHeaders->SetContentSubTypeL( _L8( "plain" ) );
       
   490         mimeHeaders->SetMimeCharset( KMmsUtf8 );
       
   491         mimeHeaders->SetSuggestedFilenameL( _L( "body.txt" ) );
       
   492 
       
   493         // ownership of bodyAttachment will be transferred
       
   494         CMsvAttachment* bodyAttachment = CMsvAttachment::NewL(
       
   495                 CMsvAttachment::EMsvFile );
       
   496         CleanupStack::PushL( bodyAttachment );
       
   497         bodyAttachment->SetAttachmentNameL( _L( "body.txt" ) );
       
   498         bodyAttachment->SetMimeTypeL( _L8( "text/plain" ) );
       
   499         mimeHeaders->StoreL( *bodyAttachment );
       
   500 
       
   501         RFile textFile;
       
   502         CleanupClosePushL( textFile );
       
   503         CWaiter* waiter = CWaiter::NewLC();
       
   504         attachMan.CreateAttachmentL( _L( "body.txt" ), textFile,
       
   505                 bodyAttachment, waiter->iStatus );
       
   506         waiter->StartAndWait();
       
   507         CleanupStack::PopAndDestroy( waiter );
       
   508 
       
   509         // write the UTF-8 body data to attachment file
       
   510         textFile.Write( *body );
       
   511         CleanupStack::PopAndDestroy(); // textFile
       
   512         CleanupStack::Pop( bodyAttachment ); // ownership transfered
       
   513         CleanupStack::PopAndDestroy( mimeHeaders );
       
   514         }
       
   515 
       
   516     // get the entry of the message
       
   517     TMsvEntry tentry = mmsMtm->Entry().Entry();
       
   518 
       
   519     // set the details field
       
   520     tentry.iDetails.Set( *fromTo );
       
   521 
       
   522     // set the description field
       
   523     if ( description->Length() > 0 )
       
   524         {
       
   525         tentry.iDescription.Set( description->Left( KMmsMaxDescription ) );
       
   526         }
       
   527     else
       
   528         {
       
   529         TBuf<KMmsMaxDescription> descr;
       
   530         CnvUtfConverter::ConvertToUnicodeFromUtf8( descr, *body );
       
   531         tentry.iDescription.Set( descr );
       
   532         }
       
   533 
       
   534     // if this is audio message, set the bio type uid
       
   535     if ( cmdCode == CHtiMessagesServicePlugin::EAddAudioMsg )
       
   536         {
       
   537         tentry.iBioType = KUidMsgSubTypeMmsAudioMsg.iUid;
       
   538         }
       
   539 
       
   540     // handle attachment
       
   541     TBool attachmentsExist = EFalse;
       
   542     if ( attPath->Length() > 0 )
       
   543         {
       
   544         HTI_LOG_TEXT( "Handling attachment..." );
       
   545         // check that attachment exists
       
   546         RFs fsSession;
       
   547         if ( fsSession.Connect() != KErrNone )
       
   548             {
       
   549             HTI_LOG_FORMAT( "Error in connecting to file server session: %d", err );
       
   550             SendErrorMessageL( KErrCouldNotConnect, KErrorRfsConnectFailed );
       
   551             CleanupStack::PopAndDestroy( store );
       
   552             CleanupStack::PopAndDestroy( mmsMtm );
       
   553             CleanupStack::PopAndDestroy( attPath );
       
   554             CleanupStack::PopAndDestroy( body );
       
   555             CleanupStack::PopAndDestroy( description );
       
   556             CleanupStack::PopAndDestroy( fromTo );
       
   557             return;
       
   558             }
       
   559 
       
   560         TBool fileExists = BaflUtils::FileExists( fsSession, attPath->Des() );
       
   561         fsSession.Close();
       
   562         if ( !fileExists )
       
   563             {
       
   564             HTI_LOG_TEXT( "Attachment file not found" );
       
   565             SendErrorMessageL( KErrPathNotFound, KErrorAttachmentNotFound );
       
   566             store->RevertL();
       
   567             CleanupStack::PopAndDestroy( store );
       
   568             CleanupStack::PopAndDestroy( mmsMtm );
       
   569             CleanupStack::PopAndDestroy( attPath );
       
   570             CleanupStack::PopAndDestroy( body );
       
   571             CleanupStack::PopAndDestroy( description );
       
   572             CleanupStack::PopAndDestroy( fromTo );
       
   573             return;
       
   574             }
       
   575         else
       
   576             {
       
   577             // save the attachment
       
   578             TParse parser;
       
   579             parser.Set( *attPath, NULL, NULL);
       
   580             TFileName shortFileName = parser.NameAndExt();
       
   581 
       
   582             // get the mime type
       
   583             RApaLsSession ls;
       
   584             User::LeaveIfError( ls.Connect() );
       
   585             CleanupClosePushL( ls );
       
   586             TUid appUid;
       
   587             TDataType dataType;
       
   588             ls.AppForDocument( *attPath, appUid, dataType );
       
   589             CleanupStack::PopAndDestroy(); // ls
       
   590             TPtrC8 mimeType = dataType.Des8();
       
   591 
       
   592             // attachment settings
       
   593             // ownership of attachment will be transferred
       
   594             CMsvAttachment* attachment = CMsvAttachment::NewL(
       
   595                     CMsvAttachment::EMsvFile );
       
   596             attachment->SetAttachmentNameL( shortFileName );
       
   597             attachment->SetMimeTypeL( mimeType );
       
   598 
       
   599             // save
       
   600             CWaiter* waiter = CWaiter::NewLC();
       
   601             attachMan.AddAttachmentL( *attPath, attachment, waiter->iStatus );
       
   602             waiter->StartAndWait();
       
   603             CleanupStack::PopAndDestroy( waiter );
       
   604             attachmentsExist = ETrue;
       
   605             }
       
   606         }
       
   607 
       
   608     // save the changes made to the message store
       
   609     store->CommitL();
       
   610     CleanupStack::PopAndDestroy( store );
       
   611 
       
   612     // save the message
       
   613     mmsMtm->SaveMessageL();
       
   614 
       
   615     // final fine tuning
       
   616     tentry.SetAttachment( attachmentsExist );
       
   617     tentry.iDate.UniversalTime();
       
   618     tentry.SetVisible( ETrue );
       
   619     tentry.SetInPreparation( EFalse );
       
   620     if ( folder == EDrafts )
       
   621         {
       
   622         tentry.SetReadOnly( EFalse );
       
   623         }
       
   624     else
       
   625         {
       
   626         tentry.SetReadOnly( ETrue );
       
   627         }
       
   628     tentry.SetUnread( isUnread );
       
   629     tentry.SetNew( isNew );
       
   630     tentry.SetComplete( ETrue );
       
   631     tentry.SetSendingState( KMsvSendStateWaiting );
       
   632     tentry.iServiceId = defaultServiceId;
       
   633     tentry.iRelatedId = 0;
       
   634     tentry.iMtmData1 = KMmsMessageMRetrieveConf | KMmsMessageMobileTerminated;
       
   635 
       
   636     mmsMtm->Entry().ChangeL( tentry );
       
   637 
       
   638     HTI_LOG_TEXT( "MMS created and ready" );
       
   639 
       
   640     // send the message, if it is in outbox
       
   641     if ( folder == EOutbox )
       
   642         {
       
   643         HTI_LOG_TEXT( "MMS is in Outbox, sending it..." );
       
   644 
       
   645         CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
   646         CleanupStack::PushL( selection );
       
   647         selection->AppendL( tentry.Id() );
       
   648 
       
   649         CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
       
   650         CMsvOperation* op = mmsMtm->SendL( *selection,
       
   651                                            waiter->iStatus,
       
   652                                            tentry.iDate );
       
   653         CleanupStack::PushL( op );
       
   654         waiter->Start();
       
   655         CActiveScheduler::Start();
       
   656         CleanupStack::PopAndDestroy( op );
       
   657         CleanupStack::PopAndDestroy( waiter );
       
   658         CleanupStack::PopAndDestroy( selection );
       
   659         }
       
   660 
       
   661     HTI_LOG_TEXT( "Cleaning up" );
       
   662     CleanupStack::PopAndDestroy( mmsMtm );
       
   663     CleanupStack::PopAndDestroy( attPath );
       
   664     CleanupStack::PopAndDestroy( body );
       
   665     CleanupStack::PopAndDestroy( description );
       
   666     CleanupStack::PopAndDestroy( fromTo );
       
   667 
       
   668     // send the message id back
       
   669     TInt32 id = tentry.Id();
       
   670     TBuf8<8> idStr;
       
   671     idStr.Copy( ( TUint8* )( &id ), sizeof( id ) );
       
   672     SendOkMsgL( idStr );
       
   673 
       
   674     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleCreateMmsL: Done");
       
   675     }
       
   676 
       
   677 
       
   678 // ----------------------------------------------------------------------------
       
   679 void CMessageMgmntHandler::HandleCreateEmailL( const TDesC8& aData )
       
   680     {
       
   681     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleCreateEmailL" );
       
   682 
       
   683     if ( ValidateAddMmsOrAddEmailCommand( aData ) )
       
   684         {
       
   685         // parse the parameters
       
   686         TInt position( 1 ); // position 0 is command code
       
   687         HBufC16* fromTo = ExtractDesLC( aData, position, 1 );
       
   688         HBufC16* description = ExtractDesLC( aData, position, 1 );
       
   689         HBufC16* body = ExtractDesLC( aData, position, 2 );
       
   690         HBufC16* attPath = ExtractDesLC( aData, position, 1 );
       
   691         TBool isNew = (TBool)aData[position];
       
   692         TBool isUnread = (TBool)aData[position+1];
       
   693         TFolder folder = (TFolder)aData[position+2];
       
   694 
       
   695         HTI_LOG_TEXT( "Creating SMTP Client MTM" );
       
   696         CSmtpClientMtm* smtpMtm = NULL;
       
   697         TRAPD( err, smtpMtm = ( CSmtpClientMtm* )iMtmReg->NewMtmL(
       
   698                 KUidMsgTypeSMTP ) );
       
   699         if ( err || !smtpMtm )
       
   700             {
       
   701             HTI_LOG_TEXT( "SMTP message type module not found" );
       
   702             SendErrorMessageL( KErrNotFound, KErrorMsgTypeNotFound );
       
   703             CleanupStack::PopAndDestroy( attPath );
       
   704             CleanupStack::PopAndDestroy( body );
       
   705             CleanupStack::PopAndDestroy( description );
       
   706             CleanupStack::PopAndDestroy( fromTo );
       
   707             return;
       
   708             }
       
   709         CleanupStack::PushL( smtpMtm );
       
   710 
       
   711         HTI_LOG_TEXT( "Creating a new CMsvEntry" );
       
   712         CMsvEntry* entry = CMsvEntry::NewL( *iSession,
       
   713                                             KMsvGlobalInBoxIndexEntryId,
       
   714                                             TMsvSelectionOrdering() );
       
   715         CleanupStack::PushL( entry );
       
   716 
       
   717         // get the default service
       
   718         HTI_LOG_TEXT( "Getting the default service" );
       
   719         TMsvId defaultServiceId = 0;
       
   720         TRAP( err, defaultServiceId = smtpMtm->DefaultServiceL() );
       
   721         if ( err )
       
   722             {
       
   723             HTI_LOG_FORMAT( "Could not get default service, err: %d", err );
       
   724             SendErrorMessageL( err, KErrorMailboxNotDefined );
       
   725             CleanupStack::PopAndDestroy( entry );
       
   726             CleanupStack::PopAndDestroy( smtpMtm );
       
   727             CleanupStack::PopAndDestroy( attPath );
       
   728             CleanupStack::PopAndDestroy( body );
       
   729             CleanupStack::PopAndDestroy( description );
       
   730             CleanupStack::PopAndDestroy( fromTo );
       
   731             return;
       
   732             }
       
   733 
       
   734         // map the folder parameter to folder id
       
   735         HTI_LOG_TEXT( "Mapping the folder parameter to folder id" );
       
   736         TMsvId folderId = KMsvGlobalInBoxIndexEntryId;
       
   737         TRAP( err, folderId = MapFolderToIdL( folder ) );
       
   738         if ( err )
       
   739             {
       
   740             HTI_LOG_FORMAT( "Invalid folder: %d", folder );
       
   741             SendErrorMessageL( err, KErrorInvalidFolder );
       
   742             CleanupStack::PopAndDestroy( entry );
       
   743             CleanupStack::PopAndDestroy( smtpMtm );
       
   744             CleanupStack::PopAndDestroy( attPath );
       
   745             CleanupStack::PopAndDestroy( body );
       
   746             CleanupStack::PopAndDestroy( description );
       
   747             CleanupStack::PopAndDestroy( fromTo );
       
   748             return;
       
   749             }
       
   750         entry->SetEntryL( folderId );
       
   751 
       
   752         // mtm takes ownership of entry context
       
   753         smtpMtm->SetCurrentEntryL( entry );
       
   754         CleanupStack::Pop( entry );
       
   755 
       
   756         // create a message and set subject and body
       
   757         smtpMtm->CreateMessageL( defaultServiceId );
       
   758         smtpMtm->SetSubjectL( description->Des() );
       
   759         smtpMtm->Body().Reset();
       
   760         smtpMtm->Body().InsertL( 0, body->Des() );
       
   761 
       
   762         // get the entry of the message
       
   763         TMsvEntry tentry = smtpMtm->Entry().Entry();
       
   764 
       
   765         // add addressee
       
   766         smtpMtm->AddAddresseeL( fromTo->Des() );
       
   767         tentry.iDetails.Set( fromTo->Des() );
       
   768 
       
   769         // If creating to Inbox use other than KUidMsgTypeSMTP so that the
       
   770         // mail displays "from" field and not "to" field.
       
   771         if ( folder == EInbox )
       
   772             {
       
   773             tentry.iMtm = KUidMsgTypeIMAP4;
       
   774             }
       
   775 
       
   776         // set the description field same as the message subject
       
   777         tentry.iDescription.Set( description->Des() );
       
   778 
       
   779         // save the changes done above
       
   780         smtpMtm->Entry().ChangeL( tentry );
       
   781 
       
   782         // get an access to the message store
       
   783         CMsvStore* store = entry->EditStoreL();
       
   784         CleanupStack::PushL( store );
       
   785         CImHeader* header = CImHeader::NewLC();
       
   786         header->RestoreL( *store );
       
   787         TUint charset = header->Charset();
       
   788         CleanupStack::PopAndDestroy( header );
       
   789         CleanupStack::PopAndDestroy( store );
       
   790 
       
   791         // handle attachment
       
   792         TBool attachmentsExist = EFalse;
       
   793         if ( attPath->Length() > 0 )
       
   794             {
       
   795             // check that attachment exists
       
   796             RFs fsSession;
       
   797             if ( fsSession.Connect() != KErrNone )
       
   798                 {
       
   799                 HTI_LOG_FORMAT( "Error in connecting to file server session: %d", err );
       
   800                 SendErrorMessageL( KErrCouldNotConnect, KErrorRfsConnectFailed );
       
   801                 CleanupStack::PopAndDestroy( smtpMtm );
       
   802                 CleanupStack::PopAndDestroy( attPath );
       
   803                 CleanupStack::PopAndDestroy( body );
       
   804                 CleanupStack::PopAndDestroy( description );
       
   805                 CleanupStack::PopAndDestroy( fromTo );
       
   806                 return;
       
   807                 }
       
   808             CleanupClosePushL( fsSession );
       
   809 
       
   810             TBool fileExists = BaflUtils::FileExists( fsSession, attPath->Des() );
       
   811             if ( !fileExists )
       
   812                 {
       
   813                 HTI_LOG_TEXT( "Attachment file not found" );
       
   814                 SendErrorMessageL( KErrPathNotFound, KErrorAttachmentNotFound );
       
   815                 CleanupStack::PopAndDestroy(); // fsSession
       
   816                 CleanupStack::PopAndDestroy( smtpMtm );
       
   817                 CleanupStack::PopAndDestroy( attPath );
       
   818                 CleanupStack::PopAndDestroy( body );
       
   819                 CleanupStack::PopAndDestroy( description );
       
   820                 CleanupStack::PopAndDestroy( fromTo );
       
   821                 return;
       
   822                 }
       
   823             else
       
   824                 {
       
   825                 // get the mime type
       
   826                 HTI_LOG_TEXT( "Getting the attachment's mime type" );
       
   827                 RApaLsSession ls;
       
   828                 User::LeaveIfError( ls.Connect() );
       
   829                 TUid appUid;
       
   830                 TDataType dataType;
       
   831                 ls.AppForDocument( *attPath, appUid, dataType );
       
   832                 TPtrC8 mimeType = dataType.Des8();
       
   833 
       
   834                 HTI_LOG_TEXT( "Adding the attachment" );
       
   835                 CWaiter* waiter = CWaiter::NewLC();
       
   836                 smtpMtm->AddAttachmentL( attPath->Des(), mimeType, charset,
       
   837                         waiter->iStatus );
       
   838                 waiter->StartAndWait();
       
   839                 CleanupStack::PopAndDestroy( waiter );
       
   840                 HTI_LOG_TEXT( "Attachment added succesfully" );
       
   841 
       
   842                 attachmentsExist = ETrue;
       
   843                 }
       
   844 
       
   845             CleanupStack::PopAndDestroy(); // fsSession
       
   846             }
       
   847 
       
   848         // save the message
       
   849         smtpMtm->SaveMessageL();
       
   850 
       
   851         // final fine tuning
       
   852         TMsvEmailEntry temailEntry = static_cast<TMsvEmailEntry>( tentry );
       
   853         temailEntry.SetMessageFolderType( EFolderTypeUnknown );
       
   854         temailEntry.SetDisconnectedOperation( ENoDisconnectedOperations );
       
   855         temailEntry.SetEncrypted( EFalse );
       
   856         temailEntry.SetSigned( EFalse );
       
   857         temailEntry.SetVCard( EFalse );
       
   858         temailEntry.SetVCalendar( EFalse );
       
   859         temailEntry.SetReceipt( EFalse );
       
   860         temailEntry.SetMHTMLEmail( EFalse );
       
   861         temailEntry.SetBodyTextComplete( ETrue );
       
   862         temailEntry.SetAttachment( attachmentsExist );
       
   863         temailEntry.iDate.UniversalTime();
       
   864         temailEntry.SetVisible( ETrue );
       
   865         temailEntry.SetInPreparation( EFalse );
       
   866         temailEntry.SetSendingState( KMsvSendStateWaiting );
       
   867         temailEntry.SetUnread( isUnread );
       
   868         temailEntry.SetNew( isNew );
       
   869         temailEntry.SetComplete( ETrue );
       
   870         temailEntry.iServiceId = defaultServiceId;
       
   871         temailEntry.iRelatedId = 0;
       
   872 
       
   873         smtpMtm->Entry().ChangeL( temailEntry );
       
   874 
       
   875         // get an access to the message store
       
   876         store = entry->EditStoreL();
       
   877         CleanupStack::PushL( store );
       
   878 
       
   879         // set email header info
       
   880         header = CImHeader::NewLC();
       
   881         header->RestoreL( *store );
       
   882         header->SetSubjectL( description->Des() );
       
   883         header->SetFromL( fromTo->Des() );
       
   884         header->SetReceiptAddressL( fromTo->Des() );
       
   885         header->StoreL( *store );
       
   886         store->CommitL();
       
   887         CleanupStack::PopAndDestroy( header );
       
   888         CleanupStack::PopAndDestroy( store );
       
   889 
       
   890         // send the message, if it is in outbox
       
   891         if ( folder == EOutbox )
       
   892             {
       
   893             HTI_LOG_TEXT( "E-Mail was created in outbox, marking it to be sent on next connection" );
       
   894 
       
   895             CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
   896             CleanupStack::PushL( selection );
       
   897             selection->AppendL( temailEntry.Id() );
       
   898 
       
   899             TBuf8<1> dummyParameter;
       
   900             CMsvOperationActiveSchedulerWait* waiter =
       
   901                     CMsvOperationActiveSchedulerWait::NewLC();
       
   902             CMsvOperation* op = smtpMtm->InvokeAsyncFunctionL(
       
   903                     KSMTPMTMSendOnNextConnection, *selection,
       
   904                     dummyParameter, waiter->iStatus );
       
   905             CleanupStack::PushL( op );
       
   906             waiter->Start();
       
   907             CleanupStack::PopAndDestroy( op );
       
   908             CleanupStack::PopAndDestroy( waiter );
       
   909             CleanupStack::PopAndDestroy( selection );
       
   910             }
       
   911 
       
   912         HTI_LOG_TEXT( "Cleaning up" );
       
   913         CleanupStack::PopAndDestroy( smtpMtm );
       
   914         CleanupStack::PopAndDestroy( attPath );
       
   915         CleanupStack::PopAndDestroy( body );
       
   916         CleanupStack::PopAndDestroy( description );
       
   917         CleanupStack::PopAndDestroy( fromTo );
       
   918 
       
   919         // send the message id back
       
   920         TInt32 id = tentry.Id();
       
   921         TBuf8<8> idStr;
       
   922         idStr.Copy( ( TUint8* )( &id ), sizeof( id ) );
       
   923         SendOkMsgL( idStr );
       
   924         }
       
   925 
       
   926     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleCreateEmailL: Done");
       
   927     }
       
   928 
       
   929 // ----------------------------------------------------------------------------
       
   930 void CMessageMgmntHandler::HandleCreateObexMsgL( const TDesC8& aData,
       
   931                                                  TUid aMtmUid,
       
   932                                                  TUid aMsgTypeUid )
       
   933     {
       
   934     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleCreateObexMsgL" );
       
   935 
       
   936     if ( ValidateAddObexMsgCommand( aData ) )
       
   937         {
       
   938         // parse the parameters
       
   939         TInt position( 0 );
       
   940         HBufC16* fromTo = ExtractDesLC( aData, position, 1 );
       
   941         HBufC16* description = ExtractDesLC( aData, position, 1 );
       
   942         HBufC16* attPath = ExtractDesLC( aData, position, 1 );
       
   943         TBool isNew = (TBool)aData[position];
       
   944         TBool isUnread = (TBool)aData[position+1];
       
   945         TFolder folder = (TFolder)aData[position+2];
       
   946 
       
   947         // Adding Obex messages to the outbox is not allowed
       
   948         if ( folder == EOutbox )
       
   949             {
       
   950             HTI_LOG_TEXT( "Outbox not supported with Obex messages" );
       
   951             SendErrorMessageL( KErrNotSupported, KErrorNotSupported );
       
   952             CleanupStack::PopAndDestroy( attPath );
       
   953             CleanupStack::PopAndDestroy( description );
       
   954             CleanupStack::PopAndDestroy( fromTo );
       
   955             return;
       
   956             }
       
   957 
       
   958         CObexClientMtm* obexMtm = NULL;
       
   959         TRAPD( err, obexMtm = ( CObexClientMtm* )iMtmReg->NewMtmL( aMtmUid ) );
       
   960         if ( err || !obexMtm )
       
   961             {
       
   962             HTI_LOG_TEXT( "Obex message type module not found" );
       
   963             SendErrorMessageL( KErrNotFound, KErrorMsgTypeNotFound );
       
   964             CleanupStack::PopAndDestroy( attPath );
       
   965             CleanupStack::PopAndDestroy( description );
       
   966             CleanupStack::PopAndDestroy( fromTo );
       
   967             return;
       
   968             }
       
   969         CleanupStack::PushL( obexMtm );
       
   970 
       
   971         CMsvEntry* entry = CMsvEntry::NewL( *iSession,
       
   972                                             KMsvGlobalInBoxIndexEntryId,
       
   973                                             TMsvSelectionOrdering() );
       
   974         CleanupStack::PushL( entry );
       
   975 
       
   976         TMsvId defaultServiceId = 0;
       
   977 
       
   978         // map the folder parameter to folder id
       
   979         TMsvId folderId = KMsvGlobalInBoxIndexEntryId;
       
   980         TRAP( err, folderId = MapFolderToIdL( folder ) );
       
   981         if ( err )
       
   982             {
       
   983             HTI_LOG_FORMAT( "Invalid folder: %d", folder );
       
   984             SendErrorMessageL( err, KErrorInvalidFolder );
       
   985             CleanupStack::PopAndDestroy( entry );
       
   986             CleanupStack::PopAndDestroy( obexMtm );
       
   987             CleanupStack::PopAndDestroy( attPath );
       
   988             CleanupStack::PopAndDestroy( description );
       
   989             CleanupStack::PopAndDestroy( fromTo );
       
   990             return;
       
   991             }
       
   992         entry->SetEntryL( folderId );
       
   993 
       
   994         // mtm takes ownership of entry context
       
   995         obexMtm->SetCurrentEntryL( entry );
       
   996         CleanupStack::Pop( entry );
       
   997 
       
   998         // create a new message
       
   999         obexMtm->CreateMessageL( defaultServiceId );
       
  1000 
       
  1001         // get the entry of the message
       
  1002         TMsvEntry tentry = obexMtm->Entry().Entry();
       
  1003 
       
  1004         // set subject
       
  1005         obexMtm->SetSubjectL( description->Des() );
       
  1006         tentry.iDescription.Set( description->Des() );
       
  1007 
       
  1008         // set body, must be empty for obex messages
       
  1009         obexMtm->Body().Reset();
       
  1010 
       
  1011         // set the details field and
       
  1012         tentry.iDetails.Set( fromTo->Des() );
       
  1013 
       
  1014         // set mtm
       
  1015         tentry.iMtm = aMtmUid;
       
  1016         tentry.iType = KUidMsvMessageEntry;
       
  1017         tentry.iServiceId = KMsvUnknownServiceIndexEntryId;
       
  1018 
       
  1019         // save the changes done above
       
  1020         obexMtm->Entry().ChangeL( tentry );
       
  1021 
       
  1022         // save the message
       
  1023         obexMtm->SaveMessageL();
       
  1024 
       
  1025         // final fine tuning
       
  1026         tentry.iDate.HomeTime();
       
  1027         tentry.SetVisible( ETrue );
       
  1028         tentry.SetInPreparation( EFalse );
       
  1029         tentry.SetUnread( isUnread );
       
  1030         tentry.SetNew( isNew );
       
  1031         tentry.SetComplete( ETrue );
       
  1032         obexMtm->Entry().ChangeL( tentry );
       
  1033 
       
  1034         // handle attachment
       
  1035         if ( attPath->Length() > 0 )
       
  1036             {
       
  1037             // check that attachment exists
       
  1038             RFs fsSession;
       
  1039             if ( fsSession.Connect() != KErrNone )
       
  1040                 {
       
  1041                 HTI_LOG_FORMAT( "Error in connecting to file server session: %d", err );
       
  1042                 SendErrorMessageL( KErrCouldNotConnect, KErrorRfsConnectFailed );
       
  1043                 CleanupStack::PopAndDestroy( obexMtm );
       
  1044                 CleanupStack::PopAndDestroy( attPath );
       
  1045                 CleanupStack::PopAndDestroy( description );
       
  1046                 CleanupStack::PopAndDestroy( fromTo );
       
  1047                 return;
       
  1048                 }
       
  1049 
       
  1050             TBool fileExists = BaflUtils::FileExists( fsSession, attPath->Des() );
       
  1051             fsSession.Close();
       
  1052             if ( !fileExists )
       
  1053                 {
       
  1054                 HTI_LOG_TEXT( "Attachment file not found" );
       
  1055                 SendErrorMessageL( KErrPathNotFound, KErrorAttachmentNotFound );
       
  1056                 CleanupStack::PopAndDestroy( obexMtm );
       
  1057                 CleanupStack::PopAndDestroy( attPath );
       
  1058                 CleanupStack::PopAndDestroy( description );
       
  1059                 CleanupStack::PopAndDestroy( fromTo );
       
  1060                 return;
       
  1061                 }
       
  1062             else
       
  1063                 {
       
  1064                 // create a new entry for the attachment
       
  1065                 TMsvEntry attachTEntry;
       
  1066                 attachTEntry.iType = KUidMsvAttachmentEntry;
       
  1067                 attachTEntry.iServiceId = KMsvUnknownServiceIndexEntryId;
       
  1068                 attachTEntry.iMtm = aMsgTypeUid; //save as bt message
       
  1069 
       
  1070                 entry->CreateL( attachTEntry );
       
  1071 
       
  1072                 CMsvEntry* attachEntry = iSession->GetEntryL( attachTEntry.Id() );
       
  1073                 obexMtm->SetCurrentEntryL( attachEntry );
       
  1074 
       
  1075                 // get source file
       
  1076                 TFileName sourceFileName = attPath->Des();
       
  1077 
       
  1078                 // get the mime type
       
  1079                 RApaLsSession ls;
       
  1080                 User::LeaveIfError( ls.Connect() );
       
  1081                 CleanupClosePushL<RApaLsSession>(ls);
       
  1082                 TUid appUid;
       
  1083                 TDataType mimeType;
       
  1084                 ls.AppForDocument( sourceFileName, appUid, mimeType );
       
  1085                 CleanupStack::PopAndDestroy(); //ls
       
  1086 
       
  1087                 CWaiter* waiter = CWaiter::NewLC();
       
  1088 
       
  1089                 // add an attachment to the current message entry
       
  1090                 obexMtm->AddAttachmentL( sourceFileName, mimeType.Des8(), 0,
       
  1091                         waiter->iStatus );
       
  1092                 waiter->StartAndWait();
       
  1093                 CleanupStack::PopAndDestroy( waiter );
       
  1094                 }
       
  1095             }
       
  1096 
       
  1097         CleanupStack::PopAndDestroy( obexMtm );
       
  1098         CleanupStack::PopAndDestroy( attPath );
       
  1099         CleanupStack::PopAndDestroy( description );
       
  1100         CleanupStack::PopAndDestroy( fromTo );
       
  1101 
       
  1102         // send the message id back
       
  1103         TInt32 id = tentry.Id();
       
  1104         TBuf8<8> idStr;
       
  1105         idStr.Copy( ( TUint8* )( &id ), sizeof( id ) );
       
  1106         SendOkMsgL( idStr );
       
  1107         }
       
  1108 
       
  1109     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleCreateObexMsgL: Done");
       
  1110     }
       
  1111 
       
  1112 
       
  1113 // ----------------------------------------------------------------------------
       
  1114 void CMessageMgmntHandler::HandleCreateSmartMsgL( const TDesC8& aData )
       
  1115     {
       
  1116     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleCreateSmartMsgL" );
       
  1117 
       
  1118     if ( ValidateAddSmartMsgCommand( aData ) )
       
  1119         {
       
  1120         TInt position( 0 );
       
  1121         HBufC16* fromTo = ExtractDesLC( aData, position, 1 );
       
  1122         HBufC16* description = ExtractDesLC( aData, position, 1 );
       
  1123         HBufC16* body = ExtractDesLC( aData, position, 2 );
       
  1124         TBool isNew = (TBool)aData[position];
       
  1125         TBool isUnread = (TBool)aData[position+1];
       
  1126         TFolder folder = (TFolder)aData[position+2];
       
  1127         TInt bioUidValue =   aData[position+3] +
       
  1128                            ( aData[position+4] << 8 ) +
       
  1129                            ( aData[position+5] << 16 ) +
       
  1130                            ( aData[position+6] << 24 );
       
  1131 
       
  1132 
       
  1133         // Smart messages can be created only to inbox.
       
  1134         // For sending smart messages, create a normal SMS with smart message
       
  1135         // content as a body and send it.
       
  1136         if ( folder != EInbox )
       
  1137             {
       
  1138             HTI_LOG_TEXT( "Invalid folder specified for smart message" );
       
  1139             SendErrorMessageL( KErrArgument, KErrorInvalidFolderForSmartMsg );
       
  1140             CleanupStack::PopAndDestroy( body );
       
  1141             CleanupStack::PopAndDestroy( description );
       
  1142             CleanupStack::PopAndDestroy( fromTo );
       
  1143             return;
       
  1144 
       
  1145             }
       
  1146 
       
  1147         CSmsClientMtm* smsMtm = NULL;
       
  1148         TRAPD( err, smsMtm = ( CSmsClientMtm* )iMtmReg->NewMtmL( KUidMsgTypeSMS ) );
       
  1149         if ( err || !smsMtm )
       
  1150             {
       
  1151             HTI_LOG_TEXT( "SMS message type module not found" );
       
  1152             SendErrorMessageL( KErrNotFound, KErrorMsgTypeNotFound );
       
  1153             CleanupStack::PopAndDestroy( body );
       
  1154             CleanupStack::PopAndDestroy( description );
       
  1155             CleanupStack::PopAndDestroy( fromTo );
       
  1156             return;
       
  1157             }
       
  1158         CleanupStack::PushL( smsMtm );
       
  1159 
       
  1160         CMsvEntry* entry = CMsvEntry::NewL( *iSession,
       
  1161                 KMsvGlobalInBoxIndexEntryId, TMsvSelectionOrdering() );
       
  1162         CleanupStack::PushL( entry );
       
  1163 
       
  1164         // get the default service
       
  1165         TMsvId defaultServiceId = 0;
       
  1166         TRAP( err, defaultServiceId = smsMtm->DefaultServiceL() );
       
  1167         if ( err )
       
  1168             {
       
  1169             HTI_LOG_FORMAT( "Could not get default service, err: %d", err );
       
  1170             SendErrorMessageL( err, KErrorSmsSettingNotDefined );
       
  1171             CleanupStack::PopAndDestroy( entry );
       
  1172             CleanupStack::PopAndDestroy( smsMtm );
       
  1173             CleanupStack::PopAndDestroy( body );
       
  1174             CleanupStack::PopAndDestroy( description );
       
  1175             CleanupStack::PopAndDestroy( fromTo );
       
  1176             return;
       
  1177             }
       
  1178 
       
  1179         // no need for folder mapping, since only inbox allowed for smart messages
       
  1180         TMsvId folderId = KMsvGlobalInBoxIndexEntryId;
       
  1181         entry->SetEntryL( folderId );
       
  1182 
       
  1183         // mtm takes ownership of entry context
       
  1184         smsMtm->SetCurrentEntryL( entry );
       
  1185         CleanupStack::Pop( entry );
       
  1186 
       
  1187         // create a new message
       
  1188         smsMtm->CreateMessageL( defaultServiceId );
       
  1189 
       
  1190         // update the message header
       
  1191         CSmsHeader* smsHeader = &( smsMtm->SmsHeader() );
       
  1192         delete smsHeader;
       
  1193         smsHeader = NULL;
       
  1194         smsHeader = CSmsHeader::NewL( CSmsPDU::ESmsDeliver, smsMtm->Body() );
       
  1195         smsHeader->SetFromAddressL( fromTo->Des() );
       
  1196 
       
  1197         // set body, the actual BIO message content
       
  1198         smsMtm->Body().Reset();
       
  1199         smsMtm->Body().InsertL( 0, body->Des() );
       
  1200 
       
  1201         // get the entry of the message
       
  1202         TMsvEntry tentry = smsMtm->Entry().Entry();
       
  1203 
       
  1204         // set BIO message type specific data
       
  1205         tentry.iBioType = bioUidValue;
       
  1206         smsMtm->BioTypeChangedL( TUid::Uid( bioUidValue ) );
       
  1207 
       
  1208         // set details field
       
  1209         tentry.iDetails.Set( fromTo->Des() );
       
  1210 
       
  1211         // set the description field
       
  1212         tentry.iDescription.Set( description->Des() );
       
  1213 
       
  1214         // set correct MTM type
       
  1215         tentry.iMtm= KUidBIOMessageTypeMtm;
       
  1216 
       
  1217         // final fine tuning
       
  1218         tentry.SetAttachment( EFalse );
       
  1219         tentry.iDate.UniversalTime();
       
  1220         tentry.SetVisible( ETrue );
       
  1221         tentry.SetInPreparation( EFalse );
       
  1222         tentry.SetUnread( isUnread );
       
  1223         tentry.SetNew( isNew );
       
  1224         tentry.SetComplete( ETrue );
       
  1225         tentry.SetSendingState( KMsvSendStateWaiting );
       
  1226         tentry.iServiceId = defaultServiceId;
       
  1227         tentry.iRelatedId = 0;
       
  1228 
       
  1229         // save the changes done above
       
  1230         smsMtm->Entry().ChangeL( tentry );
       
  1231 
       
  1232         // save the message
       
  1233         smsMtm->SaveMessageL();
       
  1234 
       
  1235         CleanupStack::PopAndDestroy( smsMtm );
       
  1236         CleanupStack::PopAndDestroy( body );
       
  1237         CleanupStack::PopAndDestroy( description );
       
  1238         CleanupStack::PopAndDestroy( fromTo );
       
  1239 
       
  1240         TInt32 id = tentry.Id();
       
  1241         TBuf8<8> idStr;
       
  1242         idStr.Copy( ( TUint8* )( &id ), sizeof( id ) );
       
  1243         SendOkMsgL( idStr );
       
  1244         }
       
  1245 
       
  1246     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleCreateSmartMsgL: Done");
       
  1247     }
       
  1248 
       
  1249 
       
  1250 // ----------------------------------------------------------------------------
       
  1251 void CMessageMgmntHandler::HandleDeleteMessageL( const TDesC8& aData )
       
  1252     {
       
  1253     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleDeleteMessageL" );
       
  1254 
       
  1255     if ( aData.Length() != 4 )
       
  1256         {
       
  1257         HTI_LOG_TEXT( "CMessageMgmntHandler: Error: wrong length of data" );
       
  1258         SendErrorMessageL( KErrArgument, KErrorInvalidId );
       
  1259         return;
       
  1260         }
       
  1261 
       
  1262     TMsvId entryId =   aData[0] +
       
  1263                      ( aData[1] << 8 ) +
       
  1264                      ( aData[2] << 16 ) +
       
  1265                      ( aData[3] << 24 );
       
  1266     HTI_LOG_FORMAT( "CMessageMgmntHandler: Deleting one message, id: %d", entryId );
       
  1267     TMsvEntry entry;
       
  1268     TMsvId service;
       
  1269     User::LeaveIfError( iSession->GetEntry( entryId, service, entry ) );
       
  1270 
       
  1271     CMsvEntry* parentCEntry = iSession->GetEntryL( entry.Parent() );
       
  1272     CleanupStack::PushL( parentCEntry );
       
  1273     TRAPD( err, parentCEntry->DeleteL( entry.Id() ) );
       
  1274     CleanupStack::PopAndDestroy( parentCEntry );
       
  1275 
       
  1276     if ( err == KErrNone )
       
  1277         {
       
  1278         SendOkMsgL( KNullDesC8 );
       
  1279         }
       
  1280     else if ( err == KErrNotFound )
       
  1281         {
       
  1282         SendErrorMessageL( err, KErrorItemNotFound );
       
  1283         }
       
  1284     else
       
  1285         {
       
  1286         SendErrorMessageL( err, KErrorFailedDelete );
       
  1287         }
       
  1288 
       
  1289     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleDeleteMessageL: Done");
       
  1290     }
       
  1291 
       
  1292 // ----------------------------------------------------------------------------
       
  1293 void CMessageMgmntHandler::HandleDeleteMessagesL( const TDesC8& aData )
       
  1294     {
       
  1295     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleDeleteMessagesFuncL" );
       
  1296 
       
  1297     if ( aData.Length() != 2 )
       
  1298         {
       
  1299         HTI_LOG_TEXT( "CMessageMgmntHandler: Error: wrong length of data" );
       
  1300         SendErrorMessageL( KErrArgument, KErrorInvalidFolder );
       
  1301         return;
       
  1302         }
       
  1303 
       
  1304     if ( aData[0] == EAllFolders )
       
  1305         {
       
  1306         HandleDeleteFromAllFoldersL( (TMessageType)aData[1] );
       
  1307         }
       
  1308     else if ( aData[1] == EAllMessageTypes )
       
  1309         {
       
  1310         HandleDeleteAllMessageTypesL( (TFolder)aData[0] );
       
  1311         }
       
  1312     else
       
  1313         {
       
  1314         HandleDeleteFromFolderByTypeL( (TFolder)aData[0],
       
  1315                                        (TMessageType)aData[1] );
       
  1316         }
       
  1317 
       
  1318     SendOkMsgL( KNullDesC8 );
       
  1319     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleDeleteMessagesFuncL: Done");
       
  1320     }
       
  1321 
       
  1322 // ----------------------------------------------------------------------------
       
  1323 void CMessageMgmntHandler::HandleDeleteFromAllFoldersL( TMessageType aType )
       
  1324     {
       
  1325     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleDeleteFromAllFoldersL" );
       
  1326 
       
  1327     if ( aType == EAllMessageTypes )
       
  1328         {
       
  1329         for ( TInt i = 1; i < ENumberOfFolders; i++ )
       
  1330             {
       
  1331             HandleDeleteAllMessageTypesL( (TFolder)i );
       
  1332             }
       
  1333         }
       
  1334     else
       
  1335         {
       
  1336         for ( TInt i = 1; i < ENumberOfFolders; i++ )
       
  1337             {
       
  1338             HandleDeleteFromFolderByTypeL( (TFolder)i, aType );
       
  1339             }
       
  1340         }
       
  1341 
       
  1342     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleDeleteFromAllFoldersL: Done");
       
  1343     }
       
  1344 
       
  1345 // ----------------------------------------------------------------------------
       
  1346 void CMessageMgmntHandler::HandleDeleteAllMessageTypesL( TFolder aFolder )
       
  1347     {
       
  1348     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleDeleteAllMessageTypesL" );
       
  1349 
       
  1350     if ( aFolder == EAllFolders )
       
  1351         {
       
  1352         for ( TInt i = 1; i < ENumberOfMessageTypes; i++ )
       
  1353             {
       
  1354             HandleDeleteFromAllFoldersL( (TMessageType)i );
       
  1355             }
       
  1356         }
       
  1357     else
       
  1358         {
       
  1359         for ( TInt i = 1; i < ENumberOfMessageTypes; i++ )
       
  1360             {
       
  1361             HandleDeleteFromFolderByTypeL( aFolder, (TMessageType)i );
       
  1362             }
       
  1363         }
       
  1364 
       
  1365     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleDeleteAllMessageTypesL: Done");
       
  1366     }
       
  1367 
       
  1368 // ----------------------------------------------------------------------------
       
  1369 void CMessageMgmntHandler::HandleDeleteFromFolderByTypeL( TFolder aFolder,
       
  1370                                                           TMessageType aType )
       
  1371     {
       
  1372     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::HandleDeleteFromFolderByTypeL" );
       
  1373 
       
  1374     TMsvId folderId = MapFolderToIdL( aFolder );
       
  1375     TUid msgTypeUid = MapMessageTypeToUidL( aType );
       
  1376 
       
  1377     HTI_LOG_TEXT( "Deleting messages..." );
       
  1378     HTI_LOG_FORMAT( "Folder: %d", aFolder );
       
  1379     HTI_LOG_FORMAT( "Message type: %d", aType );
       
  1380 
       
  1381     CMsvEntry* folder = CMsvEntry::NewL( *iSession,
       
  1382                                          folderId,
       
  1383                                          TMsvSelectionOrdering() );
       
  1384     CleanupStack::PushL( folder );
       
  1385     CMsvEntrySelection* sel = folder->ChildrenWithMtmL( msgTypeUid );
       
  1386 
       
  1387     CleanupStack::PushL( sel );
       
  1388     HTI_LOG_FORMAT( "Found %d matching items", sel->Count() );
       
  1389 
       
  1390     for ( TInt i = 0; i < sel->Count(); i++ )
       
  1391         {
       
  1392         TMsvId entryId = sel->At( i );
       
  1393         TMsvEntry entry;
       
  1394         TMsvId service;
       
  1395         User::LeaveIfError( iSession->GetEntry( entryId, service, entry ) );
       
  1396         if ( ( aType == EAudioMessage && entry.iBioType != KUidMsgSubTypeMmsAudioMsg.iUid ) ||
       
  1397                 ( aType == EMMS && entry.iBioType == KUidMsgSubTypeMmsAudioMsg.iUid ) )
       
  1398             {
       
  1399             // do not delete audio messages when MMS deletion
       
  1400             // requested and vice versa
       
  1401             continue;
       
  1402             }
       
  1403         CMsvEntry* parentCEntry = iSession->GetEntryL( entry.Parent() );
       
  1404         CleanupStack::PushL( parentCEntry );
       
  1405         parentCEntry->DeleteL( entry.Id() );
       
  1406         CleanupStack::PopAndDestroy( parentCEntry );
       
  1407         }
       
  1408 
       
  1409     CleanupStack::PopAndDestroy( sel );
       
  1410     CleanupStack::PopAndDestroy( folder );
       
  1411 
       
  1412     if ( aType == EEmail )
       
  1413         {
       
  1414         HandleDeleteFromFolderByTypeL( aFolder, EEmailPOP3 );
       
  1415         HandleDeleteFromFolderByTypeL( aFolder, EEmailIMAP4 );
       
  1416         }
       
  1417 
       
  1418     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::HandleDeleteFromFolderByTypeL: Done");
       
  1419     }
       
  1420 
       
  1421 // ----------------------------------------------------------------------------
       
  1422 void CMessageMgmntHandler::SendOkMsgL( const TDesC8& aData )
       
  1423     {
       
  1424     HTI_LOG_FUNC_IN("CMessageMgmntHandler::SendOkMsgL: Starting");
       
  1425 
       
  1426     User::LeaveIfNull( iDispatcher );
       
  1427 
       
  1428     HBufC8* temp = HBufC8::NewL( aData.Length() + 1 );
       
  1429     TPtr8 response = temp->Des();
       
  1430     response.Append( (TChar) CHtiMessagesServicePlugin::EResultOk );
       
  1431     response.Append( aData );
       
  1432     User::LeaveIfError( iDispatcher->DispatchOutgoingMessage(
       
  1433         temp, KHtiMessagesServiceUid ) );
       
  1434 
       
  1435     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::SendOkMsgL: Done");
       
  1436     }
       
  1437 
       
  1438 // ----------------------------------------------------------------------------
       
  1439 void CMessageMgmntHandler::SendErrorMessageL( TInt aError,
       
  1440                                               const TDesC8& aDescription )
       
  1441     {
       
  1442     HTI_LOG_FUNC_IN("CMessageMgmntHandler::SendErrorMessageL: Starting");
       
  1443     User::LeaveIfNull( iDispatcher );
       
  1444     User::LeaveIfError( iDispatcher->DispatchOutgoingErrorMessage(
       
  1445         aError, aDescription, KHtiMessagesServiceUid ) );
       
  1446     HTI_LOG_FUNC_OUT("CMessageMgmntHandler::SendErrorMessageL: Done");
       
  1447     }
       
  1448 
       
  1449 // ----------------------------------------------------------------------------
       
  1450 TBool CMessageMgmntHandler::ValidateAddSmsCommand( const TDesC8& aData )
       
  1451     {
       
  1452     if ( aData.Length() < KAddSmsCmdMinLength )
       
  1453         {
       
  1454         HTI_LOG_TEXT( "ValidateAddSmsCommand: Error: missing data" );
       
  1455         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1456         return EFalse;
       
  1457         }
       
  1458 
       
  1459     TInt offset = 0;
       
  1460     TInt fromLength = aData[offset];
       
  1461 
       
  1462     offset = 1 + fromLength;
       
  1463     if ( offset > aData.Length() - 1 )
       
  1464         {
       
  1465         HTI_LOG_TEXT( "ValidateAddSmsCommand: Error: wrong length of data" );
       
  1466         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1467         return EFalse;
       
  1468         }
       
  1469     TInt descrLength = aData[offset];
       
  1470 
       
  1471     offset = offset + 1 + descrLength;
       
  1472     if ( offset > aData.Length() - 2 ) // body length in two bytes
       
  1473         {
       
  1474         HTI_LOG_TEXT( "ValidateAddSmsCommand: Error: wrong length of data" );
       
  1475         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1476         return EFalse;
       
  1477         }
       
  1478     TInt bodyLength = aData[offset] + ( aData[offset+1] << 8 );
       
  1479 
       
  1480     TInt wholeLength = 1 + fromLength +
       
  1481                        1 + descrLength +
       
  1482                        2 + bodyLength +
       
  1483                        1 + // is new
       
  1484                        1 + // is unread
       
  1485                        1;  // folder
       
  1486 
       
  1487     if ( wholeLength != aData.Length() )
       
  1488         {
       
  1489         HTI_LOG_TEXT( "ValidateAddSmsCommand: Error: wrong length of data" );
       
  1490         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1491         return EFalse;
       
  1492         }
       
  1493 
       
  1494     if ( bodyLength > 160 )
       
  1495         {
       
  1496         HTI_LOG_TEXT( "ValidateAddSmsCommand: Error: too long SMS body" );
       
  1497         SendErrorMessageL( KErrOverflow, KErrorTooLongSmsBody );
       
  1498         return EFalse;
       
  1499         }
       
  1500 
       
  1501     return ETrue;
       
  1502     }
       
  1503 
       
  1504 
       
  1505 // ----------------------------------------------------------------------------
       
  1506 TBool CMessageMgmntHandler::ValidateAddMmsOrAddEmailCommand( const TDesC8& aData )
       
  1507     {
       
  1508     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::ValidateAddMmsOrAddEmailCommand" );
       
  1509     if ( aData.Length() < KAddMmsOrEmailCmdMinLength + 1 ) // +1 = cmd code
       
  1510         {
       
  1511         HTI_LOG_TEXT( "Error: missing data" );
       
  1512         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1513         return EFalse;
       
  1514         }
       
  1515 
       
  1516     if ( aData[0] == CHtiMessagesServicePlugin::EAddAudioMsg &&
       
  1517             aData.Length() < KAddAudioCmdMinLength + 1 ) // +1 = cmd code
       
  1518         {
       
  1519         HTI_LOG_TEXT( "ValidateAddMmsOrAddEmailCommand: Error: missing data" );
       
  1520         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1521         return EFalse;
       
  1522         }
       
  1523 
       
  1524     TInt offset = 0;
       
  1525     TInt cmdCode = aData[offset];
       
  1526     offset++;
       
  1527     TInt fromToLength = aData[offset];
       
  1528     fromToLength++; // the length byte
       
  1529 
       
  1530     offset = offset + fromToLength;
       
  1531     if ( offset > aData.Length() - 1 )
       
  1532         {
       
  1533         HTI_LOG_TEXT( "Error: wrong length of data" );
       
  1534         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1535         return EFalse;
       
  1536         }
       
  1537     TInt descrLength = aData[offset];
       
  1538     descrLength++; // the length byte
       
  1539 
       
  1540     offset = offset + descrLength;
       
  1541     TInt bodyLength = 0;
       
  1542     if ( cmdCode != CHtiMessagesServicePlugin::EAddAudioMsg )
       
  1543         {
       
  1544         if ( offset > aData.Length() - 2 ) // body length in two bytes
       
  1545             {
       
  1546             HTI_LOG_TEXT( "Error: wrong length of data" );
       
  1547             SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1548             return EFalse;
       
  1549             }
       
  1550         bodyLength = aData[offset] + ( aData[offset+1] << 8 );
       
  1551         bodyLength += 2; // the body length bytes
       
  1552         }
       
  1553 
       
  1554     offset = offset + bodyLength;
       
  1555     if ( offset > aData.Length() - 1 )
       
  1556         {
       
  1557         HTI_LOG_TEXT( ": wrong length of data" );
       
  1558         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1559         return EFalse;
       
  1560         }
       
  1561     TInt attPathLength = aData[offset];
       
  1562     if ( attPathLength == 0 && cmdCode == CHtiMessagesServicePlugin::EAddAudioMsg )
       
  1563         {
       
  1564         // attachment (the audio) is mandatory for audio message
       
  1565         HTI_LOG_TEXT( "Error: missing attachment" );
       
  1566         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1567         return EFalse;
       
  1568         }
       
  1569     attPathLength++; // the length byte
       
  1570 
       
  1571     TInt wholeLength = 1 + // command code
       
  1572                        fromToLength + descrLength +  bodyLength + attPathLength +
       
  1573                        1 + // is new
       
  1574                        1 + // is unread
       
  1575                        1;  // folder
       
  1576 
       
  1577     if ( wholeLength != aData.Length() )
       
  1578         {
       
  1579         HTI_LOG_TEXT( "Error: wrong length of data (wholeLength)" );
       
  1580         HTI_LOG_FORMAT( "Expected: %d", wholeLength );
       
  1581         HTI_LOG_FORMAT( "Was:      %d", aData.Length() );
       
  1582         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1583         return EFalse;
       
  1584         }
       
  1585 
       
  1586     return ETrue;
       
  1587     }
       
  1588 
       
  1589 
       
  1590 // ----------------------------------------------------------------------------
       
  1591 TBool CMessageMgmntHandler::ValidateAddObexMsgCommand( const TDesC8& aData )
       
  1592     {
       
  1593     if ( aData.Length() < KAddObexMsgCmdMinLength )
       
  1594         {
       
  1595         HTI_LOG_TEXT( "ValidateAddObexMsgCommand: Error: missing data" );
       
  1596         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1597         return EFalse;
       
  1598         }
       
  1599 
       
  1600     TInt offset = 0;
       
  1601     TInt fromToLength = aData[offset];
       
  1602 
       
  1603     offset = 1 + fromToLength;
       
  1604     if ( offset > aData.Length() - 1 )
       
  1605         {
       
  1606         HTI_LOG_TEXT( "ValidateAddObexMsgCommand: Error: wrong length of data" );
       
  1607         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1608         return EFalse;
       
  1609         }
       
  1610     TInt descrLength = aData[offset];
       
  1611 
       
  1612     offset = offset + 1 + descrLength;
       
  1613     if ( offset > aData.Length() - 1 )
       
  1614         {
       
  1615         HTI_LOG_TEXT( "ValidateAddObexMsgCommand: Error: wrong length of data" );
       
  1616         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1617         return EFalse;
       
  1618         }
       
  1619     TInt attPathLength = aData[offset];
       
  1620 
       
  1621     TInt wholeLength = 1 + fromToLength +
       
  1622                        1 + descrLength +
       
  1623                        1 + attPathLength +
       
  1624                        1 + // is new
       
  1625                        1 + // is unread
       
  1626                        1;  // folder
       
  1627 
       
  1628     if ( wholeLength != aData.Length() )
       
  1629         {
       
  1630         HTI_LOG_TEXT( "ValidateAddObexMsgCommand: Error: wrong length of data" );
       
  1631         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1632         return EFalse;
       
  1633         }
       
  1634 
       
  1635     return ETrue;
       
  1636     }
       
  1637 
       
  1638 // ----------------------------------------------------------------------------
       
  1639 TBool CMessageMgmntHandler::ValidateAddSmartMsgCommand( const TDesC8& aData )
       
  1640     {
       
  1641     if ( aData.Length() < KAddSmartMsgCmdMinLength )
       
  1642         {
       
  1643         HTI_LOG_TEXT( "ValidateAddSmartMsgCommand: Error: missing data" );
       
  1644         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1645         return EFalse;
       
  1646         }
       
  1647 
       
  1648     TInt offset = 0;
       
  1649     TInt fromToLength = aData[offset];
       
  1650 
       
  1651     offset = 1 + fromToLength;
       
  1652     if ( offset > aData.Length() - 1 )
       
  1653         {
       
  1654         HTI_LOG_TEXT( "ValidateAddSmartMsgCommand: Error: wrong length of data" );
       
  1655         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1656         return EFalse;
       
  1657         }
       
  1658     TInt descrLength = aData[offset];
       
  1659 
       
  1660     offset = offset + 1 + descrLength;
       
  1661     if ( offset > aData.Length() - 2 ) // body length in two bytes
       
  1662         {
       
  1663         HTI_LOG_TEXT( "ValidateAddSmartMsgCommand: Error: wrong length of data" );
       
  1664         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1665         return EFalse;
       
  1666         }
       
  1667     TInt bodyLength = aData[offset] + ( aData[offset+1] << 8 );
       
  1668 
       
  1669     TInt wholeLength = 1 + fromToLength +
       
  1670                        1 + descrLength +
       
  1671                        2 + bodyLength +
       
  1672                        1 + // is new
       
  1673                        1 + // is unread
       
  1674                        1 + // folder
       
  1675                        4;  // biomessage uid
       
  1676 
       
  1677     if ( wholeLength != aData.Length() )
       
  1678         {
       
  1679         HTI_LOG_TEXT( "ValidateAddSmartMsgCommand: Error: wrong length of data" );
       
  1680         SendErrorMessageL( KErrArgument, KErrorInvalidParameters );
       
  1681         return EFalse;
       
  1682         }
       
  1683 
       
  1684     return ETrue;
       
  1685     }
       
  1686 
       
  1687 
       
  1688 // ----------------------------------------------------------------------------
       
  1689 // Extracts UTF-8 data, converts it to Unicode and returns as 16-bit descriptor.
       
  1690 // Within aData, read descriptor from aPosition:
       
  1691 //  - first bytes tell the size of data for UTF8 formatted data
       
  1692 //  - next bytes are the data as indicated by the size
       
  1693 //  - position is finally set to the end of UTF8 data area
       
  1694 // ----------------------------------------------------------------------------
       
  1695 HBufC16* CMessageMgmntHandler::ExtractDesLC( const TDesC8& aUtf8Data,
       
  1696                                              TInt& aPosition,
       
  1697                                              TInt aSizeBytes )
       
  1698     {
       
  1699     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::ExtractDesLC" );
       
  1700     TInt length = 0;
       
  1701     for ( TInt i = 0; i < aSizeBytes; i++ )
       
  1702         {
       
  1703         length += ( aUtf8Data[aPosition+i] << ( i * 8 ) );
       
  1704         }
       
  1705 
       
  1706     if ( length < 0 ||
       
  1707          length > aUtf8Data.Mid( aPosition ).Length() )
       
  1708         {
       
  1709         User::Leave( KErrBadDescriptor );
       
  1710         }
       
  1711 
       
  1712     HBufC16* result = NULL;
       
  1713 
       
  1714     if ( length > 0 )
       
  1715         {
       
  1716         result = CnvUtfConverter::ConvertToUnicodeFromUtf8L(
       
  1717             aUtf8Data.Mid( aPosition + aSizeBytes, length ) );
       
  1718         HTI_LOG_TEXT( "ExtractDesLC: Conversion to Unicode done" );
       
  1719         CleanupStack::PushL( result );
       
  1720         }
       
  1721 
       
  1722     else
       
  1723         {
       
  1724         result = HBufC16::NewLC( 0 );
       
  1725         }
       
  1726 
       
  1727     aPosition += ( aSizeBytes + length );
       
  1728 
       
  1729     HTI_LOG_FUNC_OUT( "CMessageMgmntHandler::ExtractDesLC" );
       
  1730     return result;
       
  1731     }
       
  1732 
       
  1733 
       
  1734 // ----------------------------------------------------------------------------
       
  1735 // Extracts UTF-8 data to 8-bit descriptor without doing any conversions.
       
  1736 // ----------------------------------------------------------------------------
       
  1737 HBufC8* CMessageMgmntHandler::ExtractDes8LC( const TDesC8& aUtf8Data,
       
  1738                                              TInt& aPosition,
       
  1739                                              TInt aSizeBytes )
       
  1740     {
       
  1741     HTI_LOG_FUNC_IN( "CMessageMgmntHandler::ExtractDes8LC" );
       
  1742     TInt length = 0;
       
  1743     for ( TInt i = 0; i < aSizeBytes; i++ )
       
  1744         {
       
  1745         length += ( aUtf8Data[aPosition+i] << ( i * 8 ) );
       
  1746         }
       
  1747 
       
  1748     if ( length < 0 ||
       
  1749          length > aUtf8Data.Mid( aPosition ).Length() )
       
  1750         {
       
  1751         User::Leave( KErrBadDescriptor );
       
  1752         }
       
  1753 
       
  1754     HBufC8* result = HBufC8::NewLC( length );
       
  1755 
       
  1756     if ( length > 0 )
       
  1757         {
       
  1758         result->Des().Copy( aUtf8Data.Mid( aPosition + aSizeBytes, length ) );
       
  1759         }
       
  1760 
       
  1761     aPosition += ( aSizeBytes + length );
       
  1762 
       
  1763     HTI_LOG_FUNC_OUT( "CMessageMgmntHandler::ExtractDes8LC" );
       
  1764     return result;
       
  1765     }
       
  1766 
       
  1767 
       
  1768 // ----------------------------------------------------------------------------
       
  1769 TMsvId CMessageMgmntHandler::MapFolderToIdL( TFolder aFolder )
       
  1770     {
       
  1771     TMsvId id = 0;
       
  1772 
       
  1773     switch ( aFolder )
       
  1774         {
       
  1775         case EInbox:  { id = KMsvGlobalInBoxIndexEntryId;   break; }
       
  1776         case EDrafts: { id = KMsvDraftEntryId;              break; }
       
  1777         case ESent:   { id = KMsvSentEntryId;               break; }
       
  1778         case EOutbox: { id = KMsvGlobalOutBoxIndexEntryId;  break; }
       
  1779         default:      { User::Leave( KErrArgument );        break; }
       
  1780         }
       
  1781 
       
  1782     return id;
       
  1783     }
       
  1784 
       
  1785 // ----------------------------------------------------------------------------
       
  1786 TUid CMessageMgmntHandler::MapMessageTypeToUidL( TMessageType aType )
       
  1787     {
       
  1788     TUid uid = { 0 };
       
  1789 
       
  1790     switch ( aType )
       
  1791         {
       
  1792         case ESMS:          { uid = KUidMsgTypeSMS;            break; }
       
  1793         case EAudioMessage: // fall through - audio msg is MMS sub type
       
  1794         case EMMS:          { uid = KUidMsgTypeMultimedia;     break; }
       
  1795         case ESmartMessage: { uid = KUidBIOMessageTypeMtm;     break; }
       
  1796         case EEmail:        { uid = KUidMsgTypeSMTP;           break; }
       
  1797         case EEmailPOP3:    { uid = KUidMsgTypePOP3;           break; }
       
  1798         case EEmailIMAP4:   { uid = KUidMsgTypeIMAP4;          break; }
       
  1799         case EIrMessage:    { uid = KUidMsgTypeIrUID;          break; }
       
  1800         case EBtMessage:    { uid = KUidMsgTypeBt;             break; }
       
  1801         default:            { User::Leave( KErrArgument );     break; }
       
  1802         }
       
  1803 
       
  1804     return uid;
       
  1805     }
       
  1806 
       
  1807 // ----------------------------------------------------------------------------
       
  1808 void CMessageMgmntHandler::HandleSessionEventL( TMsvSessionEvent /*aEvent*/,
       
  1809                                                 TAny* /*aArg1*/,
       
  1810                                                 TAny* /*aArg2*/,
       
  1811                                                 TAny* /*aArg3*/ )
       
  1812     {
       
  1813     }
       
  1814 
       
  1815 
       
  1816 
       
  1817 // ----------------------------------------------------------------------------
       
  1818 CWaiter* CWaiter::NewL( TInt aPriority )
       
  1819     {
       
  1820     CWaiter* self = new(ELeave) CWaiter( aPriority );
       
  1821     return self;
       
  1822     }
       
  1823 
       
  1824 // ----------------------------------------------------------------------------
       
  1825 CWaiter* CWaiter::NewLC( TInt aPriority )
       
  1826     {
       
  1827     CWaiter* self = new(ELeave) CWaiter( aPriority );
       
  1828     CleanupStack::PushL( self );
       
  1829     return self;
       
  1830     }
       
  1831 
       
  1832 // ----------------------------------------------------------------------------
       
  1833 CWaiter::CWaiter( TInt aPriority ) : CActive( aPriority )
       
  1834     {
       
  1835     CActiveScheduler::Add( this );
       
  1836     }
       
  1837 
       
  1838 // ----------------------------------------------------------------------------
       
  1839 CWaiter::~CWaiter()
       
  1840     {
       
  1841     Cancel();
       
  1842     }
       
  1843 
       
  1844 // ----------------------------------------------------------------------------
       
  1845 void CWaiter::StartAndWait()
       
  1846     {
       
  1847     iStatus = KRequestPending;
       
  1848     SetActive();
       
  1849     iWait.Start();
       
  1850     }
       
  1851 
       
  1852 // ----------------------------------------------------------------------------
       
  1853 TInt CWaiter::Result() const
       
  1854     {
       
  1855     return iResult;
       
  1856     }
       
  1857 
       
  1858 // ----------------------------------------------------------------------------
       
  1859 void CWaiter::RunL()
       
  1860     {
       
  1861     iResult = iStatus.Int();
       
  1862     iWait.AsyncStop();
       
  1863     }
       
  1864 
       
  1865 // ----------------------------------------------------------------------------
       
  1866 void CWaiter::DoCancel()
       
  1867     {
       
  1868     iResult = KErrCancel;
       
  1869     if ( iStatus == KRequestPending )
       
  1870         {
       
  1871         TRequestStatus* status = &iStatus;
       
  1872         User::RequestComplete( status, KErrCancel );
       
  1873         }
       
  1874 
       
  1875     iWait.AsyncStop();
       
  1876     }
       
  1877 
       
  1878 
       
  1879 // End of file