mmsengine/mmsserver/src/mmsforwardoperation.cpp
changeset 0 72b543305e3a
child 26 ebe688cedc25
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *     State machine for sending a forward request
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    <apparc.h>
       
    23 #include    <msventry.h>
       
    24 #include    <msvids.h>
       
    25 #include    <logcli.h>
       
    26 #include    <commdb.h>
       
    27 #include    <in_sock.h>
       
    28 #include    <commdbconnpref.h>
       
    29 #include    <featmgr.h>
       
    30 #include    <AknGlobalNote.h>
       
    31 
       
    32 // the rest are local includes, needed always
       
    33 #include    "mmsconst.h"
       
    34 #include    "mmsforwardoperation.h"
       
    35 #include    "mmssession.h"
       
    36 #include    "mmssettings.h"
       
    37 #include    "mmsservercommon.h"
       
    38 #include    "mmsheaders.h"
       
    39 #include    "mmsencode.h"
       
    40 #include    "mmsdecode.h"
       
    41 #include    "mmsscheduledentry.h"
       
    42 #include    "mmsgenutils.h"
       
    43 #include    "mmslog.h"
       
    44 #include    "mmserrors.h"
       
    45 #include    "mmsserverentry.h"
       
    46 #include    "mmsconninit.h"
       
    47 
       
    48 // EXTERNAL DATA STRUCTURES
       
    49 
       
    50 // EXTERNAL FUNCTION PROTOTYPES  
       
    51 extern void gPanic( TMmsPanic aPanic );
       
    52 
       
    53 // CONSTANTS
       
    54 
       
    55 // MACROS
       
    56 // LOCAL CONSTANTS AND MACROS
       
    57 // MODULE DATA STRUCTURES
       
    58 // LOCAL FUNCTION PROTOTYPES
       
    59 // ==================== LOCAL FUNCTIONS ====================
       
    60 // ================= MEMBER FUNCTIONS =======================
       
    61 
       
    62 // ---------------------------------------------------------
       
    63 // CMmsForwardOperation::CMmsForwardOperation
       
    64 //
       
    65 // ---------------------------------------------------------
       
    66 //
       
    67 CMmsForwardOperation::CMmsForwardOperation( RFs& aFs ):
       
    68     CMmsBaseOperation( aFs )
       
    69     {
       
    70     //
       
    71     // members that get initial value 0, need not be intialized here
       
    72     //
       
    73     }
       
    74 
       
    75 // ---------------------------------------------------------
       
    76 // CMmsForwardOperation::ConstructL
       
    77 //
       
    78 // ---------------------------------------------------------
       
    79 //
       
    80 void CMmsForwardOperation::ConstructL( CMmsSettings* aMmsSettings )
       
    81     {
       
    82     CMmsBaseOperation::ConstructL( aMmsSettings );
       
    83     iMmsRequestHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
       
    84     CActiveScheduler::Add( this );
       
    85     }
       
    86 
       
    87 // ---------------------------------------------------------
       
    88 // CMmsForwardOperation::NewL
       
    89 //
       
    90 // ---------------------------------------------------------
       
    91 //
       
    92 CMmsForwardOperation* CMmsForwardOperation::NewL( RFs& aFs, CMmsSettings* aMmsSettings )
       
    93     {
       
    94     CMmsForwardOperation* self = new ( ELeave ) CMmsForwardOperation( aFs );
       
    95     CleanupStack::PushL( self );
       
    96     self->ConstructL( aMmsSettings );
       
    97     CleanupStack::Pop( self );
       
    98     return self;
       
    99     }
       
   100 
       
   101     
       
   102 // ---------------------------------------------------------
       
   103 // CMmsForwardOperation::~CMmsForwardOperation
       
   104 //
       
   105 // ---------------------------------------------------------
       
   106 //
       
   107 CMmsForwardOperation::~CMmsForwardOperation()
       
   108     {
       
   109     Cancel();
       
   110     delete iMmsRequestHeaders;
       
   111     }
       
   112 
       
   113 // ---------------------------------------------------------
       
   114 // CMmsForwardOperation::Failed
       
   115 //
       
   116 // ---------------------------------------------------------
       
   117 //
       
   118 CMsvEntrySelection& CMmsForwardOperation::Failed() const
       
   119     {
       
   120     return *iFailed;
       
   121     }
       
   122 
       
   123 // ---------------------------------------------------------
       
   124 // CMmsForwardOperation::EncodePDUL
       
   125 //
       
   126 // ---------------------------------------------------------
       
   127 //
       
   128 void CMmsForwardOperation::EncodePDUL()
       
   129     {
       
   130     #ifndef _NO_MMSS_LOGGING_
       
   131     TMmsLogger::Log( _L("CMmsForwardOperation EncodePDU") );
       
   132     #endif
       
   133 
       
   134     if( iError != KErrNone )
       
   135         {
       
   136         FallThrough();
       
   137         return;
       
   138         }
       
   139     //
       
   140     // Set entry's context to next message in the selection
       
   141     //
       
   142     iError = iServerEntry->SetEntry( iSelection->At( iCurrentMessageNo - 1 ) );
       
   143     if( iError != KErrNone )
       
   144         {
       
   145         #ifndef _NO_MMSS_LOGGING_
       
   146         TMmsLogger::Log( _L("- ERROR: SetEntry: %d"), iError );
       
   147         #endif
       
   148         FallThrough();
       
   149         return;
       
   150         }
       
   151 
       
   152     //
       
   153     // Getting write access to message's store because headers have to be
       
   154     // altered.
       
   155     //
       
   156     CMsvStore* store = NULL;
       
   157     TRAP( iError, store = iServerEntry->EditStoreL(); )
       
   158     if ( iError != KErrNone )
       
   159         {
       
   160         #ifndef _NO_MMSS_LOGGING_
       
   161         TMmsLogger::Log( _L("- ERROR: EditStoreL: %d"), iError );
       
   162         #endif
       
   163         FallThrough();
       
   164         return;
       
   165         }
       
   166     CleanupStack::PushL( store ); // ***
       
   167 
       
   168     //
       
   169     // Filling headers object from the data in the MessageStore
       
   170     //
       
   171     iMmsRequestHeaders->RestoreL( *store );
       
   172 
       
   173     //
       
   174     // Forward request headers that are not filled by application,
       
   175     // are added below
       
   176     //
       
   177 
       
   178     //
       
   179     // TransactionId
       
   180     //
       
   181     TBufC8<KMMSMAXTIDLENGTH> tid;
       
   182     tid.Des().NumUC( AllocateTID(), EHex );
       
   183     iMmsRequestHeaders->SetTidL( tid );
       
   184 
       
   185     //
       
   186     // Set messagetype
       
   187     //
       
   188     iMmsRequestHeaders->SetMessageType( KMmsMessageTypeForwardReq );
       
   189 
       
   190     //
       
   191     // Saving headers back to Message Store
       
   192     // No diskspace check done here, because the size of the data has not
       
   193     // really changed that much (headers already are on the disk).
       
   194     //
       
   195     iMmsRequestHeaders->StoreL( *store );
       
   196     store->CommitL();
       
   197     CleanupStack::PopAndDestroy( store );
       
   198     store = NULL;
       
   199 
       
   200     //
       
   201     // Encode the message
       
   202     //
       
   203     iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   204     iError = iEntryWrapper->SetCurrentEntry( iSelection->At( iCurrentMessageNo - 1 ) );
       
   205     if ( iError != KErrNone )
       
   206         {
       
   207         FallThrough();
       
   208         }
       
   209     else
       
   210         {
       
   211         iEncoder->EncodeHeadersL( *iMmsRequestHeaders, *iEncodeBuffer );
       
   212         FallThrough();
       
   213         }
       
   214     }
       
   215 
       
   216 // ---------------------------------------------------------
       
   217 // CMmsForwardOperation::UpdateEntryStatusL
       
   218 //
       
   219 // ---------------------------------------------------------
       
   220 //
       
   221 void CMmsForwardOperation::UpdateEntryStatusL()
       
   222     {
       
   223     #ifndef _NO_MMSS_LOGGING_
       
   224     TMmsLogger::Log( _L( "CMmsForwardOperation UpdateEntryStatusL()" ) );
       
   225     TMmsLogger::Log( _L( "- Updating notification flags" ) );
       
   226     #endif
       
   227 
       
   228     TInt error = KErrNone;
       
   229     TMsvEntry tEntry;
       
   230     
       
   231     // Fix for a case where the server is sending no response to forward request.
       
   232     // If we have got a response and already set iError to something, we don't
       
   233     // override it.
       
   234     if ( iResponse->MessageType() != KMmsMessageTypeForwardConf && iError == KErrNone )
       
   235         {
       
   236     #ifndef _NO_MMSS_LOGGING_
       
   237         TMmsLogger::Log( _L( "- Incorrect PDU type received: %d" ), iResponse->MessageType() );
       
   238     #endif
       
   239         iError = KMmsErrorStatusUnsupportedMessage;
       
   240         }
       
   241 
       
   242     //
       
   243     // Update the status of the notification entry
       
   244     //
       
   245     TMsvId notifId = iMmsRequestHeaders->RelatedEntry();
       
   246     error = iServerEntry->SetEntry( notifId );
       
   247     if ( error == KErrNone )
       
   248         {
       
   249         tEntry = iServerEntry->Entry();
       
   250 
       
   251         if( iError == KErrNone )
       
   252             {
       
   253             //
       
   254             // OK
       
   255             //
       
   256             tEntry.iMtmData2 &= ~KMmsOperationOngoing;      // not ongoing
       
   257             tEntry.iMtmData2 |= KMmsOperationFinished;      // finished
       
   258             tEntry.iMtmData2 &= ~KMmsOperationResult;       // OK
       
   259             tEntry.iMtmData2 &= ~KMmsNewOperationForbidden; // not forbidden
       
   260             // KMmsStoredInMMBox is left untouched
       
   261             }
       
   262         else if( iError == KMmsErrorOfflineMode )
       
   263             {
       
   264             // Leaving flags as they are
       
   265             }
       
   266         else // iError not equal to KErrNone/KMmsErrorOfflineMode
       
   267             {
       
   268             //
       
   269             // NOK
       
   270             //
       
   271             tEntry.iMtmData2 &= ~KMmsNewOperationForbidden; // not forbidden
       
   272             tEntry.iMtmData2 &= ~KMmsOperationOngoing;      // not ongoing
       
   273             tEntry.iMtmData2 |= KMmsOperationFinished;      // finished
       
   274             tEntry.iMtmData2 |= KMmsOperationResult;        // NOK
       
   275             // KMmsStoredInMMBox is left untouched
       
   276             }
       
   277         tEntry.SetReadOnly( ETrue );
       
   278         error = iServerEntry->ChangeEntry( tEntry );
       
   279         }
       
   280         
       
   281     #ifndef _NO_MMSS_LOGGING_
       
   282     if( error != KErrNone )
       
   283         {
       
   284         TMmsLogger::Log( _L( "- ERROR: could not change notification entry's flags!" ) );
       
   285         }
       
   286     #endif
       
   287 
       
   288     #ifndef _NO_MMSS_LOGGING_
       
   289     TMmsLogger::Log( _L( "- Updating forward entry state" ) );
       
   290     #endif
       
   291     //
       
   292     // Set context to forward entry
       
   293     //
       
   294     error = iServerEntry->SetEntry( iSelection->At( iCurrentMessageNo - 1 ) );
       
   295     if( error != KErrNone )
       
   296         {
       
   297         #ifndef _NO_MMSS_LOGGING_
       
   298         TMmsLogger::Log( _L( "- ERROR: could not get forward entry" ) );
       
   299         #endif
       
   300         if( iError == KErrNone )
       
   301             {
       
   302             iError = error;
       
   303             }
       
   304         FallThrough();
       
   305         return;
       
   306         }
       
   307 
       
   308     //
       
   309     // If notification has been succesfully updated, clear the relatedId link
       
   310     //
       
   311     #ifndef _NO_MMSS_LOGGING_
       
   312     TMmsLogger::Log( _L( "0" ) );
       
   313     #endif
       
   314     if( iError != KMmsErrorOfflineMode )
       
   315         {
       
   316         #ifndef _NO_MMSS_LOGGING_
       
   317         TMmsLogger::Log( _L( "- clearing link to original notification" ) );
       
   318         #endif
       
   319         CMsvStore* store = iServerEntry->EditStoreL();
       
   320         CleanupStack::PushL( store ); // ***
       
   321         iMmsRequestHeaders->SetRelatedEntry( KMsvNullIndexEntryId );
       
   322         iMmsRequestHeaders->StoreL( *store );
       
   323         store->CommitL();
       
   324         CleanupStack::PopAndDestroy( store );
       
   325         }
       
   326 
       
   327     //
       
   328     // Update the status of the forward entry
       
   329     //
       
   330     tEntry = iServerEntry->Entry();
       
   331     if( iError == KErrNone )
       
   332         {
       
   333         #ifndef _NO_MMSS_LOGGING_
       
   334         TMmsLogger::Log( _L( "- forward succeeded" ) );
       
   335         #endif
       
   336         tEntry.SetFailed( EFalse );
       
   337         tEntry.SetSendingState( KMsvSendStateSent );
       
   338         // Take the entry out of failed list
       
   339         // (only offline cases should get rescheduled)
       
   340         iFailed->Delete( iCurrentMessageNo - 1 );
       
   341         }
       
   342     else if( iError == KMmsErrorOfflineMode )
       
   343         {
       
   344         #ifndef _NO_MMSS_LOGGING_
       
   345         TMmsLogger::Log( _L( "- forward failed due to Offline mode" ) );
       
   346         #endif
       
   347         tEntry.SetFailed( EFalse );
       
   348         tEntry.SetSendingState( KMmsOffLineState );        
       
   349         }
       
   350     else
       
   351         {
       
   352         #ifndef _NO_MMSS_LOGGING_
       
   353         TMmsLogger::Log( _L( "- forward failed" ) );
       
   354         #endif
       
   355         tEntry.SetFailed( ETrue );
       
   356         tEntry.SetSendingState( KMsvSendStateFailed );
       
   357         // Take the entry out of failed list in order not to get it rescheduled
       
   358         // (only offline cases should get rescheduled)
       
   359         iFailed->Delete( iCurrentMessageNo - 1 );
       
   360         }
       
   361     tEntry.SetConnected( EFalse );
       
   362     tEntry.iError = iError;
       
   363     tEntry.SetReadOnly( ETrue );
       
   364     error = iServerEntry->ChangeEntry( tEntry );
       
   365     #ifndef _NO_MMSS_LOGGING_
       
   366     if( error != KErrNone )
       
   367         {
       
   368         TMmsLogger::Log( _L( "- ERROR: could not change forward entry's flags!" ) );
       
   369         }
       
   370     #endif
       
   371 
       
   372     // Clear up
       
   373     iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   374     FallThrough();
       
   375     }
       
   376 
       
   377 // ---------------------------------------------------------
       
   378 // CMmsForwardOperation::MoveEntryL
       
   379 //
       
   380 // ---------------------------------------------------------
       
   381 //
       
   382 void CMmsForwardOperation::MoveEntryL()
       
   383     {
       
   384     #ifndef _NO_MMSS_LOGGING_
       
   385     TMmsLogger::Log( _L("CMmsForwardOperation MoveEntryL") );
       
   386     #endif
       
   387 
       
   388     //
       
   389     // If something has gone wrong, just falling through
       
   390     //
       
   391     if( iError != KErrNone )
       
   392         {
       
   393         FallThrough();
       
   394         return;
       
   395         }
       
   396     
       
   397     //
       
   398     // If all is well, the forwarded entry is moved to Sent folder,
       
   399     // or deleted, depending on the settings
       
   400     //
       
   401     TInt error = KErrNone;
       
   402     error = iServerEntry->SetEntry( iSelection->At( iCurrentMessageNo - 1 ) );
       
   403     if ( error == KErrNone )
       
   404         {
       
   405         TMsvEntry entry = iServerEntry->Entry();
       
   406         error = iServerEntry->SetEntry( entry.Parent() );
       
   407         
       
   408         if ( error == KErrNone )
       
   409             {
       
   410             if ( iMmsSettings->MoveToSent() )
       
   411                 {
       
   412                 // Move entry from Outbox to Sent Folder
       
   413                 iServerEntry->MoveEntryWithinService( entry.Id(), KMsvSentEntryIdValue );
       
   414                 }
       
   415             else
       
   416                 {
       
   417                 // Delete entry
       
   418                 iServerEntry->DeleteEntry( entry.Id() );
       
   419                 }
       
   420             }
       
   421         }
       
   422     iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   423     FallThrough();
       
   424     }
       
   425 
       
   426 // ---------------------------------------------------------
       
   427 // CMmsForwardOperation::LogL
       
   428 //
       
   429 // ---------------------------------------------------------
       
   430 //
       
   431 void CMmsForwardOperation::LogL()
       
   432     {
       
   433     #ifndef _NO_MMSS_LOGGING_
       
   434     TMmsLogger::Log( _L("CMmsForwardOperation LogL") );
       
   435     #endif
       
   436 
       
   437     TInt error = iServerEntry->SetEntry( iSelection->At( iCurrentMessageNo - 1 ) );
       
   438     if ( error != KErrNone || iError != KErrNone ||
       
   439         iMmsRequestHeaders->DeliveryReport() != EMmsYes )
       
   440         {
       
   441         // Can't access the entry or do not want logging, can't update log
       
   442         FallThrough();
       
   443         return;
       
   444         }
       
   445         
       
   446     TBool isActive = EFalse;    
       
   447     TRAP( error,
       
   448         {
       
   449         InitializeLoggingL();
       
   450         
       
   451         TMsvEntry entry = iServerEntry->Entry();
       
   452         // set event type and recipients to log event
       
   453         CommonLogEventInitializationL( *iMmsRequestHeaders, entry );
       
   454         iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   455         
       
   456         // if MMSC has accepted our message for fowarding, the message id is present
       
   457         // If the entry was not accepted, iError reflects the error   
       
   458         iLogEvent->SetDataL( iResponse->MessageId() );
       
   459         // CMmsLog will set our status to KRequestPending
       
   460         iMmsLog->StartL( *iLogEvent, *iRemoteParties, iStatus );
       
   461         SetActive();
       
   462         isActive = ETrue;
       
   463         });
       
   464         
       
   465     // If logging has been successfully initialized, iMmsLog will complete us.
       
   466     // If something has gone wrong, we complete ourselves because we want to
       
   467     // continue finalization of the operation. We free our entry in any case
       
   468     
       
   469     iServerEntry->SetEntry( KMsvNullIndexEntryId );
       
   470     if ( !isActive )
       
   471         {
       
   472         FallThrough();
       
   473         return;
       
   474         }
       
   475     }
       
   476 
       
   477 // ================= OTHER EXPORTED FUNCTIONS ==============
       
   478 
       
   479 //  End of File