msg_plat/mms_codec_client_api/inc/mmscodecclient.h
author William Roberts <williamr@symbian.org>
Thu, 22 Jul 2010 16:32:06 +0100
branchGCC_SURGE
changeset 47 5b14749788d7
parent 23 238255e8b033
parent 31 ebfee66fde93
permissions -rw-r--r--
Catchup to latest Symbian^4

/*
* Copyright (c) 2005 - 2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:   MMS Codec Client offers API to multimedia message handling
*
*/




#ifndef MMSCODECCLIENT_H
#define MMSCODECCLIENT_H

//  INCLUDES
#include <e32base.h>        // CActive
#include <msvstd.h>         // TMsvId


// CONSTANTS
 

// MACROS


// DATA TYPES
 

// DATA TYPES
 


// FUNCTION PROTOTYPES
//
// FORWARD DECLARATIONS
class CClientMtmRegistry;
class CMsvOperation;
class CMsvSession;
class CMmsSettings;
class CMmsClientEntry;
class CMmsClientMtm;
class CMmsHeaders;
class CMmsDecode;
class CMmsEncode;

// CLASS DECLARATION
/**
*  This is a class declaration of CMmsCodecClient. It is a part of MMS Engine
*  and it used for adding, fetching and sending multimedia messages from and into
*  the message store in binary format. Also move, replace and some flag modifications
*  provided.
*  
*  The exported functions may be called in any order EXCEPT 
*  CreateNewMessageEntryL() MUST be called BEFORE AddMML().
*  If this rule is violated the operation may not be continued.
*  The chunked transfer also must be done in order as described below.
*  One message must be complete before another one is transferred.
*
*  Chunked transfer added to version 3.2.
*  To support synchronizing large messages without the need of large linear
*  buffer, chunked mode of data transfer has been added to the API
*
*  Chunked transfer from phone to PC:
*
*  1) Initialize retrieve (InitializeChunkedRetrievingL)
*  2) get a data chunk    (GetNextDataPart)
*  3) release data chunk  (ReleaseData)
*  repeat steps 2 and 3 until all data has been processed
*
*  Chunked transfer from PC to phone:
*  The same procedure can be used both for creating new entries
*  or replacing existing entries.
*
*  1) Create an entry or specify an entry to be replaced
*     (InitializeChunkedAddingL or InitializeChunkedReplacingL)
*  2) Give next data chunk until last one has been reached (NextDataPart)
*
*  If a chunked transfer to either direction is not totally completed 
*  before a new operation starts, the new operation will reset the state
*  of the previous operation and delete possible incomplete entry.
*  The next operation will proceed normally.
*    
*  Setting the flags:
*  Some information is not transferred inside the binary data in message headers.
*  That's why some data is transferred in flags. The flag info is moved
*  to the codec client in AddMML, ReplaceMML and SetFlags functions. To the caller
*  the info is transferred in RetrieveMML function.
*  The unread flag is starightforward, it is just a boolean which tells if the 
*  message has been read or not. 
*  The other flags (TUint32) is just like TMsvEntry.iMtmData1 (See mmsconst.h). 
*  but only the following bits are used, others are zero:
*  EMmsDrmCorruptedAttachment  , if the corrupted DRM attachments has been removed
*  KMmsMessageMobileTerminated , modbile terminated message
*  KMmsMessageEditorOriented   , mobile originated message
*  The last two must be set exclusive e.g the may not be set at the same time
*  
*  Folders: 
*  User of this class may only access messages in the standard folders:
*  KMsvGlobalInBoxIndexEntryId = 0x1002
*  KMsvGlobalOutBoxIndexEntryId=0x1003
*  KMsvDraftEntryId= 0x1004
*  KMsvSentEntryId=0x1005
*
*  @lib mmscodecclient.lib
*/
class CMmsCodecClient : public CActive
    {
    public:  // Constructors and destructor
        
        /**
        * Two-phased constructor.
        * 
        * @param aMsvSession    Message Server Session handle   
        */
        IMPORT_C static CMmsCodecClient* NewL( CMsvSession& aMsvSession );

                
        /**
        * Destructor.
        */
        virtual ~CMmsCodecClient();

    public: // New functions
        
        /**
        * Add a multimedia message. The given multimedia message is stored to
        * the target folder.  The flags are set correctly.
        * CreateNewMessageEntryL must be called before this function.
        * 
        * 
        * @param aMm       the MM in binary format, which will be added to 
        *                  the messaging store
        * @param aFolder   the folder in which the MM will be stored 
        * @param aFlags    the flags of the MM, which go to iMtmData1
        * @param aUnread   if the MM is unread or not
        * @param aMmId     the index, which was created for the added MM by 
        *                  the caller.
        * @param aStatus   request status of the calling active object 
        * 
        * Return values: 
        * @return KErrNone, if everything proceeds fine
        * @return KErrArgument, if aMm or aFolder is invalid.
        */
        IMPORT_C void AddMML( 
            CBufFlat& aMm,
            TMsvId aFolder,
            TUint32 aFlags,                                                                                                                           
            TBool aUnread,                                                                                   
            TMsvId& aMmId,
            TRequestStatus& aStatus );

        /**
        * Delete a multimedia message. 
        * 
        * @param aMmId      The index to the MM, which will be deleted
        * @return KErrNone, if everything proceeds fine or if the multimedia is
        *                   not found.
        * @return Error value in exceptional cases                     
        * 
        */
        IMPORT_C TInt DeleteMM( TMsvId aMmId );

        /**
        * Retrieves a multimedia message. This function provides an MM in the 
        * binary format, the folder where the MM is stored and its flags.
        *
        * 
        * @param aMm       The MM
        * @param aFolder   The folder, in which the message is stored.
        * @param aFlags    the flags of the MM, from the iMtmData1
        * @param aUnread   if the MM is unread or not
        * @param aMmId     Index to the MM, which will be retrieved            
        * @param aStatus   request status of the calling active object 
        *
        * @return KErrNone, if everything proceeds fine.
        * @return Error value in exceptional cases  
        */
        IMPORT_C void RetrieveMML(
            TMsvId aMmId,
            CBufFlat& aMM,
            TMsvId& aFolder,
            TUint32& aFlags,                   
            TBool& aUnread,
            TRequestStatus& aStatus );

        /**
        * Sends the specified MM.The message is moved to the Outbox before 
        * sending. The caller of the method should not delete CMsvOperation, 
        * which is returned from the function until aStatus has completed. 
        * If CMsvOperation is destroyed too early, the sending is canceled.
        *  
        * 
        * @param aMmId     Index to the MM, which will be sent.           
        * @param aStatus   request status of the calling active object 

        * @return   pointer to CMsvOperation object. Caller must take care of
        *           deleting the pointer after the operation completes.
        */
        IMPORT_C CMsvOperation* SendMML( 
            TMsvId aMmId, 
            TRequestStatus& aStatus );

        /**
        * A multimedia message is replaced. 
        * First the attachments of the original message is destroyed. 
        * Then the new message is stored to the same entry. Flags are set as 
        * defined. If the message is in the Outbox, it is not allowed to be 
        * replaced.
        * 
        * @param aMmId     the index to the replaceable MM  
        * @param aMm       The new MMS
        * @param aFlags    the flags of the MM, which go to iMtmData1
        * @param aUnread   if the MM is unread or not         
        * @param aStatus   request status of the calling active object 
        * 
        */
        IMPORT_C void ReplaceMML (
            TMsvId& aMmId, 
            CBufFlat& aMm,
            TUint32 aFlags,
            TBool aUnread,
            TRequestStatus& aStatus );
        
        
        /**
        * A multimedia message is moved from a standard folder to another.
        * Moving to outbox is not allowed.
        * @since 3.0
        * 
        * @param aMmId     the id to the moved MM  
        * @param aParentId New folder
        * 
        */
        IMPORT_C void MoveMML( 
                      TMsvId aMmId, 
                      TMsvId aParentId, 
                      TRequestStatus& aStatus );
        
        
        /**
        * This function sets flags of the MM.
        * Note that it is not allowed to change the flags,
        * if the MM is in outbox.
        * 
        * @param aMmId     Index to the MM          
        * @param aFlags    the flags of the MM, which go to iMtmData1
        * @param aUnread   if the MM is unread or not
        *     
        * @return KErrNone, if everything proceeds fine.
        * @return KErrNotSupported, if the message is in Outbox. 
        *
        */
        IMPORT_C TInt SetFlags( 
                TMsvId aMmId,
                TUint32 aFlags,
                TBool aUnread );
            
        /*
        * Create a message entry into the target folder. This function must be
        * called
        * before the AddMML function.
        * 
        * @since 3.0
        * @param aFolder    the folder under which the entry is created. 
        * @param aCreatedId The new creared entry ID.
        *
        * @return KErrNone the function succeeded.
        * @return Error values in exceptional cases. 
        */
        IMPORT_C TInt CreateNewMessageEntryL( 
                TMsvId aFolder, 
                TMsvId& aCreatedId );


        /**
        * Check if disk space is below critical level when storing data.
        * This is a wrapper function.
        * @since 3.0
        *
        * @param aDataSize amount of data to be added. If aDataSize == 0,
        *     returns info if disk space is already below critical level.
        * @return error code KErrDiskFull if data does not fit,
        *     KErrNone if data fits.
        *     May return some other error code if appropriate.
        *     KErrNone always means it is all right to save the data.
        */
        IMPORT_C TInt  DiskSpaceBelowCriticalLevelL( TInt aSize );
        
    // New methods to support chunked transfer.
        
        /**
         * Initialize retrieving a message in chunked mode.
         * Data will be obtained by repeatedly calling GetNextDataPart()
         * and ReleaseData().
         * Function encodes the first data part into its internal buffer
         * ready to be fetched by calling GetNextDataPart()
         *
         * @since S60 v3.1
         * @param aMessageId Id of the message to be retrieved
         * @param aFolder The folder where the message is stored
         * @param aFlags  The flags of the message, from the iMtmData1
         * @param aUnread If the message is unread or not
         * @param aOverallDataSize The total size of the encoded data
         *    if the size can be determined. -1 means the size could not be
         *    determined, and the return value of GetNextDataPart() function
         *    should be used to determine when the last data part has been
         *    reached. The buffer will be smaller than the total data size
         *    except in the case of small messages that may fit in the buffer
         *    in one chunk.
         * @param aStatus   request status of the calling active object 
         * Leaves with some system wide error code or completes with error
         *     if something goes wrong. If the function leaves, the caller
         *     must not set itself active as it was not set pending and will
         *     not be completed.
         */
         
        IMPORT_C void InitializeChunkedRetrievingL(
            TMsvId aMessageId,
            TMsvId& aFolder,
            TUint32& aFlags,
            TBool& aUnread,
            TInt& aOverallDataSize,
            TRequestStatus& aStatus );

        /**
         * Obtain a data part from the supplier.
         * The data is guaranteed to survive until a call is made to ReleaseData().
         * If the component that is receiving the data cannot receive all data
         * in one chunk, data can be given forward in smaller chunks. The data will
         * will remain in the internal buffer of CodecClient until it has been
         * released by calling ReleaseData().
         *
         * @since S60 v3.1
         * @param aDataPart Pointer to the data that has been encoded into internal buffer
         *     The length of the pointer is set to reflect the amount of data.
         * @param aLastDataChunk 
         *     ETrue if this is the last data chunk
         *     EFalse if this is not the last data chunk
         * @return error code, KErrNone if all is well.
         *     If returns some other error, transaction should be ended.
         */
        IMPORT_C TInt GetNextDataPart( TPtrC8& aDataPart, TBool& aLastDataChunk );
            
        /**
         * Release the current data part being held at the data supplier.
         * This call indicates to the supplier that the part
         * is no longer needed, and another one can be provided.
         * When this function is called, the next data part will be encoded
         * into the buffer. When this function returns, a new data part
         * can be fetched with GetNextDataPart.
         * This function must always be called after the data obtained by
         * GetNextDataPart() call has been processed.
         * This function must also be called after last data chunk has 
         * been processed so that the state of the data supplier can be reset.
         *
         * @since S60 v3.1
         * @return error code, KErrNone if all is well.
         *     If returns some other error, transaction must be ended.
         */
        IMPORT_C TInt ReleaseData();

        /** 
         * Initialize adding a message in chunked mode.
         * An empty invisible message entry is created into the folder specified.
         *
         * @since S60 v3.1
         * @param aFolder The folder where the message will be added
         * @param aMessageId The ID of the message that has been created
         * @param aFlags The flags of the MM to be stored in iMtmData1
         * @param aUnread Specifies if the message is unread or not 
         * Leaves with KErrArgument if aFolder is invalid or if called 
         *    in the middle of some other operation
         * Leaves with some system wide error code if something goes wrong.
         */
        IMPORT_C void InitializeChunkedAddingL(
            TMsvId aFolder,
            TMsvId& aMessageId,
            TUint32 aFlags,
            TBool aUnread );

        /** 
         * Initialize replacing a message in chunked mode.
         * The present content of the message entry is deleted.
         * The data is added by calling NextDataPart()
         *
         * @since S60 v3.1
         * @param aMessageId The ID of the message that will be replaced
         * @param aFlags The flags of the MM to be stored in iMtmData1
         * @param aUnread Specifies if the message is unread or not 
         * Leaves with KErrArgument if aFolder is invalid or if called 
         *    in the middle of some other operation.
         * Leaves with some system wide error code if something goes wrong.
         */
        IMPORT_C void InitializeChunkedReplacingL(
            TMsvId aMessageId,
            TUint32 aFlags,
            TBool aUnread );

        /**
         * Gives the next data part to be decoded.
         * Decoding is synchronous. When the code returns, data can be released.
         * MMS Decode may not be able to handle incomplete headers. MMS Codec Client
         * will take care of buffering the incoming data and saving possible
         * uncoded data in a flat buffer the same way CMmsTransaction does.
         * The data should be provided in chunks that are small enough to be
         * copied to an internal buffer without fear of running out of memory.
         * HTTP stack provides data in chunks that are less than 10 kB.
         * A similar size would be recommended but there is no absolute 
         * requirement as to the size of the data chunk. A compromise between
         * performance and memory consumption may be used to determine an appropriate
         * buffer size.
         *
         * @since S60 v3.1
         * @param aDataPart the data to be decoded.
         * @param aLastChunk ETrue if the data chunk in the buffer is the last one.
         *     When the last chunk has been decoded, the message entry is finalized.
         *     The flags are put into the entry, and the entry is made visible.
         * @return error code, KErrNone if decoding succeeds
         *     If returns some other error, the entry that was created in InitializeChunkedAddingL
         *     will be deleted.
         */
        IMPORT_C TInt NextDataPart(
            TPtrC8& aDataPart,
            TBool aLastDataChunk );
        


    public: // Functions from base classes


        
    protected:  // New functions
        

    protected:  // Functions from base classes
        
        
        /**
        * From CActive         
        */
        virtual void DoCancel();


        /**
        * From CActive.
        */
        virtual void RunL();
        
        /**
        * From CActive.
        */
        TInt RunError(TInt aError);

    private:

        /**
        * C++ default constructor.
        * C++ default constructor can NOT contain any code, that
        * might leave.
        */
        CMmsCodecClient();

        /**
        * By default Symbian 2nd phase constructor is private.
        */
        void ConstructL( CMsvSession& aMsvSession );
        
        /*
        * This function finalizes an entry, which has a decoded MM.
        */
        void FinalizeDecodedMML( );

        /*
        * This function generates iDetails for TMsvEntry::iMtmData1
        * in case of outgoing messages 
        */
        void GenerateRecipientsL( TDes& aDetails );
       
        /*
        * This function generates iDetails for TMsvEntry::iMtmData1
        * in case of incoming messages 
        */
        void GenerateSenderL ( TDes& aDetails );
        
        /*
        * Retrieve flags of the MM
        *
        * @param aEntry    The entry, which flags are given.          
        * @param aFlags    the flags, from the iMtmData1
        * @param aUnread   if the MM is unread or not
        */
        void RetrieveFlags( 
            TMsvEntry aEntry,
            TUint32 &aFlags,
            TBool &aUnread );

        /*
        * Set flags to the TMsvEntry
        *
        * @param aEntry    The entry, which flags are set.          
        *
        */

        void SetFlagsToTMsvEntry(
            TMsvEntry& aEntry );

        /*
        * Check if the entry's parent is Outbox.
        *
        * @param aMmId     Index to the MM
        *
        * @return ETrue when the parent is Outbox.
        * @return EFalse when the parent is Outbox.
        */

        TBool ParentOutbox(
            TMsvId aMmId );
            
        /*
        * Deletes the current entry.
        */
        void DeleteCurrentEntryL();
        
        /*
        * If a chunked operation has not completed properly, reset the state
        */
        void ResetChunkedMode();    

        /*
        * After last chunk has been fetched, an error encountered during
        * retrieve or if caller starts a new operation without completing
        * previous fetch, the entry being handled is put back to read only
        * state if needed.
        */
        void ReleaseRetrievedEntry();

    public:     // Data
        
    
    protected:  // Data
        

    private:    // Data
        
        CMsvSession* iMsvSession; 
        CMsvEntry* iClientEntry;
        
        RFs iFs;  // file system
        CMmsClientMtm* iMmsClient;
        CMmsClientEntry* iClientEntryWrapper;
        CClientMtmRegistry* iClientMtmRegistry;

        CMmsHeaders* iMmsHeaders;
        CMmsDecode* iDecoder;
        CMmsEncode* iEncoder;
        TMsvId iEntryBeingHandled;

        TMsvId iFolder;
        
        TUint32 iFlags;                                                                                                                           
        TBool iUnread;    

        TRequestStatus*  iClientStatus;     // status of the client
        
        // Private encode buffer for copying incoming data as partial headers
        // cannot be decoded, and it is possible that partial data will be left
        // in the buffer and more data appended to the end.
        // The procedure is the same as in CMmsTransaction.
        CBufFlat*           iEncodeBuffer;
        // Position where the data will be written into buffer. There may be some old
        // unhandled data left.
        TInt                iPosition;
        // keep track if we already got last chunk
        TBool               iLastChunk;
        
        // MMS encapsulation versio to be used if the version is not defined
        // in the messages
        TInt16 iMmsVersion;
        
        
        enum TState
            {
            EIdle = 0,
            EFinalizeDecodedMM,
            EFinalizeEncodedMM,
            ESendMM,
            EEntryCreated,
            EChunkedRetrieve, // not an active state
            EChunkedAdd,      // not an active state
            EChunkedReplace   // not an active state
            }; 
        TState iState;    // The state of the active object
        
    };

#endif      // MMSCODECCLIENT_H   
            
// End of File