javaextensions/wma/mms/src.s60/cmmsplatformservices60impl.cpp
branchRCL_3
changeset 19 04becd199f91
child 78 71ad690e91f5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/wma/mms/src.s60/cmmsplatformservices60impl.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,1322 @@
+/*
+* Copyright (c) 2008 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:  ?Description
+ *
+*/
+
+
+// INCLUDE FILES
+#include <cmsvattachment.h>
+#include <cmsvmimeheaders.h>
+#include <mmsvattachmentmanager.h>
+
+#include "logger.h"
+#include "fs_methodcall.h"
+#include "s60commonutils.h"
+#include "cmmsmessageattachment.h"
+#include "cmmsplatformservices60impl.h"
+
+//constants
+const TInt KMaxAppIDLength = 34;
+
+using namespace java::push;
+using namespace java::util;
+
+namespace java
+{
+namespace wma
+{
+/* ================= MEMBER FUNCTIONS =======================
+ * constructor
+ *------------------------------------------------------------------------------
+ * private CMMSPlatformServiceS60Impl
+ *
+ *------------------------------------------------------------------------------
+ */
+CMMSPlatformServiceS60Impl::CMMSPlatformServiceS60Impl(
+    const bool aServerConnection,
+    HBufC* aServerApplicationId,
+    ConnectionListener* aListener)
+        :CActive(EPriorityNormal), java::util::FunctionServer("CMMSPlatformService"),
+        mIsSending(false), mServerConnection(aServerConnection), mNewMessages(0),
+        mServerApplicationId(aServerApplicationId)
+{
+    JELOG2(EWMA);
+    //Creates a new thread and starts active scheduler
+    //This results in call to doServerSideInit()
+    createServerToNewThread();
+    mSendMsgArray = NULL;
+    mMessageListener = aListener;
+}
+/**
+ * Gets the instance of OS Specific class which implements the interface
+ * CMMSPlatformService.
+ * @param aJni - jni interface pointer
+ * @param aPeer - java side peer reference.
+ * @param aServerConnection - boolean value to identify client/server
+ *                            connection.
+ * @param aUri - uri on which the connection to be opened.
+ * @param aListener - listener to be notified about incoming messages.
+ */
+MMSPlatformService* MMSPlatformService::getInstance(JNIEnv& aJni,
+        jobject aPeer,const bool aServerConnection,const std::wstring& aUri,
+        ConnectionListener* aListener)
+{
+    return CMMSPlatformServiceS60Impl::New(aJni,aPeer,aServerConnection,aUri,
+                                           aListener);
+}
+
+
+CMMSPlatformServiceS60Impl* CMMSPlatformServiceS60Impl::New(JNIEnv& aJni,
+        jobject aPeer,const bool aServerConnection,const std::wstring& aUri,
+        ConnectionListener* aListener)
+{
+    JELOG2(EWMA);
+    HBufC* serverApplicationId = NULL;
+    int error = KErrNone;
+    if (aServerConnection)
+    {
+        serverApplicationId = S60CommonUtils::wstringToDes(
+                                  (aUri.substr(7)).c_str());
+    }
+    CMMSPlatformServiceS60Impl * self = new CMMSPlatformServiceS60Impl(
+        aServerConnection, serverApplicationId, aListener);
+    error = self->getError();
+    if (KErrNone == error)
+    {
+        //Attaches the function server thread to VM, to make callbacks to java
+        //This results in call to vmAttached()
+        self->attachToVm(aJni, aPeer);
+        LOG(EWMA, EInfo, "CMMSPlatformServiceS60Impl Successfully attached to VM");
+        TRAP(error, self->ConstructL());
+    }
+    if (error != KErrNone)
+    {
+        ELOG1(EWMA, "CMMSPlatformServiceS60Impl : Error while opening %d", error);
+        // If there is any error while opening close the connection
+        self->closeConnection(aJni,aPeer);
+        delete self;
+        throw error;
+    }
+    return self;
+}
+
+/**------------------------------------------------------------------------------
+ * EPOC default constructor can leave.
+ * private ConstructL
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::ConstructL()
+{
+    JELOG2(EWMA);
+    User::LeaveIfError(mRFs.Connect());
+    User::LeaveIfError(mRFs.ShareProtected());
+    CreateSendMessageArrayL(); // create send array
+    mMessageDeliveryDate = TTime(0);
+    mMmsMessagePriority = EMmsPriorityHigh;
+    mMessageHandler = CJavaMMSMessageHandler::NewL(mRFs);
+    // If server connection then check for messages already available in MMS
+    // message store.
+    if (mServerConnection)
+    {
+        LOG(EWMA, EInfo , "CMMSPlatformServiceS60Impl::ConstructL() Check for"
+            "any messages availble in message store");
+        CallMethodL(this, &CMMSPlatformServiceS60Impl::NotifyReceivedMessageL,
+                    this);
+    }
+}
+
+
+void CMMSPlatformServiceS60Impl::vmAttached()
+{
+    JELOG2(EWMA);
+    jclass sessionClass = mJniEnv->FindClass(
+                              "com/nokia/mj/impl/mms/MMSConnectionImpl");
+    mSendCallBackMethodId = mJniEnv->GetMethodID(sessionClass,
+                            "messageSentCallback", "(I)V");
+
+}
+/**
+ * Returns total number of messages that are arrived
+ * from opening the connection
+ */
+int CMMSPlatformServiceS60Impl::getNumberOfMessages()
+{
+    JELOG2(EWMA);
+    return mNewMessages;
+}
+/**
+ * Does the MMS Engine side initializations .Registers with MMS Engine
+ * for notification about incoming message in case of server connection.
+ */
+void CMMSPlatformServiceS60Impl::doServerSideInit()
+{
+    JELOG2(EWMA);
+    FunctionServer::doServerSideInit();
+    CActiveScheduler::Add(this);
+    TRAPD(error,
+    {
+        mSession = CMsvSession::OpenSyncL(*this);
+        mClientMtmRegistry = CClientMtmRegistry::NewL(*mSession);
+        mMmsClient = (CMmsClientMtm *) mClientMtmRegistry->NewMtmL(
+                         KUidMsgTypeMultimedia);
+        mSendTMsvIdArray = RArray<TMsvId>(KArrayGranularity);
+        mMmsApplicationAdapter = CMmsApplicationAdapter::NewL();
+        if (mServerConnection)
+        {
+            mServerMmsMtm = (CMmsClientMtm *) mClientMtmRegistry->NewMtmL(
+                                KUidMsgTypeMultimedia);
+            mReceivedMsgArray = new(ELeave) CArrayPtrSeg
+            <CMMSMessageInformation>(KArrayGranularity);
+            TBool isRegister = EFalse;
+            // If launched by push the application would have already registered
+            // with mms engine . check before registering.
+            LOG(EWMA, EInfo , "Checking whether application is already"
+                "registered or not");
+            isRegister = mMmsApplicationAdapter->RegisteredL
+                         (*mServerApplicationId);
+            // If not registered , register now.
+            if (!isRegister)
+            {
+                TMsvId folderId;
+                LOG(EWMA, EInfo , "Registering the AppId with MMS engine");
+                mMmsApplicationAdapter->RegisterL(*mServerApplicationId,folderId);
+                isRegister = true;
+            }
+
+            TMsvId tmsvId = mMmsApplicationAdapter->FolderIdL(
+                                *mServerApplicationId);
+            if (0 != tmsvId)
+            {
+                mRegisterCMsvEntry = mSession->GetEntryL(tmsvId);
+                // Add listener to the created entry for that application Id
+                mRegisterCMsvEntry->AddObserverL(*this);
+            }
+
+        }
+    });
+    mError = error;
+}
+
+/* -----------------------------------------------------------------------------
+ * CMMSPlatformServiceS60Impl::Send
+ * Sends a multimedia message to its recipients.
+ * -----------------------------------------------------------------------------
+ */
+int CMMSPlatformServiceS60Impl::send(JNIEnv& aJniEnv,
+                                     jbyteArray aBytes, int aOffset, int aLength, jstring /*aDestination*/)
+{
+    JELOG2(EWMA);
+    // put the jbyteArray into the mSendBuffer
+    delete mSendBuf; // avoid the memory leak
+    mSendBuf = NULL;
+    TRAPD(error,
+    {
+        mSendBuf = CBufFlat::NewL(aLength);
+
+        // Extends the size of the buffer by the required size
+        mSendBuf->ExpandL(aOffset, aLength);
+
+        // Transfer the data from java
+        TPtr8 sendBufPtr = mSendBuf->Ptr(0);
+        S60CommonUtils::CopyToNative(aJniEnv, aBytes, aOffset, aLength,sendBufPtr);
+        // If the object is active then it is currently sending a message
+        // it will also send the newly added message.
+        iStatus = KRequestPending;
+        SetActive();
+        CallMethodL(this, &CMMSPlatformServiceS60Impl::mmsRequestComplete,
+                    KErrNone,this);
+    });
+    ELOG1(EWMA, "CMMSPlatformServiceS60Impl : status of send %d",error);
+    return error;
+}
+
+/*------------------------------------------------------------------------------
+ * protected SetObjectActive locally
+ * .
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::mmsRequestComplete(int result)
+{
+    JELOG2(EWMA);
+    TRequestStatus *status = &iStatus;
+    User::RequestComplete(status, result);
+}
+
+/*------------------------------------------------------------------------------
+ * Notifies java side about success or failure of sending MMS message
+ * .
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::NotifySend(JNIEnv& aJni,jobject aPeer,
+        int aError)
+{
+    JELOG2(EWMA);
+    aJni.CallVoidMethod(aPeer, mSendCallBackMethodId, aError);
+    mIsSending = false;
+}
+
+/*------------------------------------------------------------------------------
+ * RunL from CActive
+ * .
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::RunL()
+{
+    JELOG2(EWMA);
+    if (iStatus.Int() ==KErrNone)
+    {
+        mIsSending = true;
+        SendMultiPartMessageL();
+    }
+}
+
+/*------------------------------------------------------------------------------
+ * protected DoCancel
+ * Cancel the sending of the message. If the message is in the creation phase
+ * we can cancel the sending of the message. If the deviec is actually sending
+ * the message we cannot cancel it.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::DoCancel()
+{
+    // clean up the entry
+    JELOG2(EWMA);
+}
+/*------------------------------------------------------------------------------
+ * protected RunError
+ * .
+ *------------------------------------------------------------------------------
+ */
+TInt CMMSPlatformServiceS60Impl::RunError(TInt aError)
+{
+    JELOG2(EWMA);
+    ELOG1(EWMA, "+ In runerror %d this %d", aError);
+    NotifySend(*mJniEnv, mJavaPeerObject, aError);
+    return KErrNone;
+}
+/* -----------------------------------------------------------------------------
+ * CMMSPlatformServiceS60Impl::RetrieveMessageL
+ * Retrieves the first received message from the queue. After delivering the
+ * message to the caller, the message is removed from the queue.
+ * -----------------------------------------------------------------------------
+ */
+jbyteArray CMMSPlatformServiceS60Impl::retrieveMessage(JNIEnv& aJni)
+{
+    JELOG2(EWMA);
+    // check if there is something in the queue
+    if (mReceivedMMSIDs.Count() <= 0)
+    {
+        return NULL;
+    }
+    // retrieve the first message whose ID is in the queue
+    TMsvId id = mReceivedMMSIDs[0];
+    mReceivedMMSIDs.Remove(0);
+
+    CMMSMessageInformation* mms = ReceivedMessage(id);
+    if (!mms)
+    {
+        return NULL;
+    }
+    CleanupStack::PushL(mms);
+
+    // serialize the received MMS
+    LOG(EWMA, EInfo , "Serializing the message before giving to java");
+    CBufFlat& receiveBuffer = mMessageHandler->SerializeLC(*mms);
+    // receiveBuffer is on the cleanup stack
+    TPtr8 receiveBufferPtr = receiveBuffer.Ptr(0);
+    //get the jbyteArray
+    TInt dataLength = receiveBuffer.Capacity();
+    jbyteArray array = aJni.NewByteArray(dataLength);
+    S60CommonUtils::CopyToJava(aJni, receiveBufferPtr, array, 0,dataLength);
+    CleanupStack::PopAndDestroy(&receiveBuffer); // receiveBuffer
+    CleanupStack::PopAndDestroy(mms);
+    return array;
+}
+
+/*------------------------------------------------------------------------------
+ * public CreateMessageL
+ * create an empty messsage in draft folder. Later we will add the information
+ * (attachments addresses, subject etc)
+ *------------------------------------------------------------------------------
+ */
+TMsvId CMMSPlatformServiceS60Impl::CreateMessageL()
+{
+    JELOG2(EWMA);
+    TMsvId serviceId = mMmsClient->DefaultServiceL();
+    // Context must be set to parent folder for CreateMessageL
+    mMmsClient->SwitchCurrentEntryL(KMsvDraftEntryId);
+    mMmsClient->CreateMessageL(serviceId);
+    CMsvEntry& cmsvEntry = mMmsClient->Entry();
+    TMsvId msvId = cmsvEntry.EntryId();
+    return msvId;
+}
+
+/*------------------------------------------------------------------------------
+ * private DeleteSentMessage
+ * When the message is gone from the device. Delete the message from
+ * the sent folder.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::DeleteSentMessageL(TMsvId aMsvId)
+{
+    JELOG2(EWMA);
+    TInt index = mSendTMsvIdArray.Find(aMsvId);
+    if (KErrNotFound == index)
+    {
+        return;
+    }
+    mSendTMsvIdArray.Remove(index);
+    DeleteMmsMessageL(aMsvId);
+}
+
+/*------------------------------------------------------------------------------
+ * public DeleteMessage
+ * Delete the message from message store. We are deleting two type of
+ * multimedia messages.Messages that we send from Java side. When they
+ * are gone from the device. We delete the message from the sent folder.
+ * Second is when we receive the message we delete it after
+ * reading it from Java side.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::DeleteMmsMessageL(TMsvId aMsvId)
+{
+    JELOG2(EWMA);
+    LoadMessageL(aMsvId);
+    CMsvEntry& cmsvEntry = mMmsClient->Entry();
+    TMsvEntry tmsvEntry(cmsvEntry.Entry());
+
+    if ((tmsvEntry.iMtm != KUidMsgTypeMultimedia)||(tmsvEntry.InPreparation()))
+    {
+        // It is not MMS  or the entry is not ready
+        return;
+    }
+    //Taking a handle to the Sent folder...
+    TMsvSelectionOrdering sort = cmsvEntry.SortType();
+    sort.SetShowInvisibleEntries(ETrue);
+    // we want to handle also the invisible entries
+    // Take a handle to the parent entry
+    CMsvEntry* parentEntry = CMsvEntry::NewL(mMmsClient->Session(),
+                             tmsvEntry.Parent(), sort);
+    CleanupStack::PushL(parentEntry); //
+    TRAPD(err, parentEntry->DeleteL(aMsvId));
+    if (err != KErrNone)
+    {
+        mSession->RemoveEntry(aMsvId);
+    }
+    CleanupStack::PopAndDestroy(parentEntry);
+}
+/*------------------------------------------------------------------------------
+ * public LoadMessage
+ * laod the message  from the given TMsvId,
+ * After this call message will be current message
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::LoadMessageL(TMsvId aMessageEntry)
+{
+    JELOG2(EWMA);
+    mMmsClient->SwitchCurrentEntryL(aMessageEntry);
+    mMmsClient->LoadMessageL();
+}
+/*------------------------------------------------------------------------------
+ * AddAttachments
+ * add attachment, location, contentId, and set the message root here
+ *
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::AddAttachmentsL(
+    CMMSMessageInformation* aMidMessageInformation)
+{
+    JELOG2(EWMA);
+    // Add attachments also set the started ID
+    CMsvStore* store = mMmsClient->Entry().EditStoreL();
+    CleanupStack::PushL(store);
+    TInt count = aMidMessageInformation->AttachmentCount();
+    for (int i = 0; i < count; i++)
+    {
+        CMMSMessageAttachment& messageAttachment =
+            aMidMessageInformation->Attachment(i);
+        TDesC& fileName = messageAttachment.AttachmentName();
+        TDesC8& mimeType8 = messageAttachment.AttachmentType();
+        TDesC8& contentLocation8 = messageAttachment.ContentLocationL();
+        TDesC8& contentId8 = messageAttachment.ContentIdL();
+        TInt charEncoding = messageAttachment.Encoding();
+        TDesC* contentLocation = NULL;
+        S60CommonUtils::ConvertNarrowToWiderLC(contentLocation8,contentLocation);
+
+        CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewLC();
+        // set the attachment mime type in the CMsvMimeHeaders
+        if (&mimeType8)
+        {
+            TInt position = mimeType8.Find(KSlash);
+            if (position > 0 && position < mimeType8.Length() - 1)
+            {
+                mimeHeaders->SetContentTypeL(mimeType8.Left(position));
+                mimeHeaders->SetContentSubTypeL(mimeType8.Mid(position + 1));
+            }
+            else
+            {
+                mimeHeaders->SetContentTypeL(mimeType8);
+            }
+        }
+        CMsvAttachment* attachment = CMsvAttachment::NewL(
+                                         CMsvAttachment::EMsvFile);
+        if (contentLocation)
+        {
+            mimeHeaders->SetContentLocationL(*contentLocation);
+        }
+        // contentId8 can be NULL
+        if (&contentId8)
+        {
+            mimeHeaders->SetContentIdL(contentId8);
+        }
+        // set Charset in attachment
+        if (charEncoding >= 0)
+        {
+            mimeHeaders->SetMimeCharset(charEncoding);
+        }
+        RFile attaFile;
+        User::LeaveIfError(attaFile.Open(mRFs, fileName,
+                                         EFileShareReadersOnly | EFileRead));
+        CleanupClosePushL(attaFile);
+        TMsvAttachmentId attaId = 0;
+        // attachment ownerhip will be transferred to Attachment Manager
+        // It must not be pushed onto the cleanupStack before calling
+        // CreateAttachment2L
+        HBufC8* emptyMime = NULL;
+        if (&mimeType8)
+        {
+            mMmsClient->CreateAttachment2L(*store, // edit store
+                                           attaFile, // open file handle
+                                           mimeType8,
+                                           // combination type like image/jpeg
+                                           *mimeHeaders, attachment, attaId);
+        }
+        else
+        {
+            emptyMime = HBufC8::NewLC(0);
+            mMmsClient->CreateAttachment2L(*store, // edit store
+                                           attaFile, // open file handle
+                                           *emptyMime,
+                                           // combination type like image/jpeg
+                                           *mimeHeaders, attachment, attaId);
+        }
+        // Now Attachment Manager owns the attachment object, so assign it NULL.
+        attachment = NULL;
+        // check also isStarted Id
+        if (messageAttachment.IsStarterContentId())
+        {
+            mMmsClient->SetMessageRootL(attaId);
+        }
+        if (emptyMime)
+        {
+            CleanupStack::PopAndDestroy(emptyMime);
+        }
+        CleanupStack::PopAndDestroy(&attaFile); // attaFile.Close()
+        CleanupStack::PopAndDestroy(mimeHeaders); // mimeHeaders
+        CleanupStack::PopAndDestroy(contentLocation); // contentLocation
+    } // end of add attachment for loop
+
+    store->CommitL();
+    CleanupStack::PopAndDestroy(store); // store
+}
+/*------------------------------------------------------------------------------
+ * public SetSubject
+ * LoadMessage is called before this method call other wise subject can be set
+ * to wrong TMsvId
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::SetSubjectL(const TDesC& aSubject)
+{
+    JELOG2(EWMA);
+    mMmsClient->SetSubjectL(aSubject);
+}
+/*------------------------------------------------------------------------------
+ * public AddRecipient
+ * LoadMessage is called before this method call other wise address can be set
+ * to wrong TMsvId
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::AddRecipientL(const TDesC& aAddress,
+        TMmsRecipients aAddressType)
+{
+    JELOG2(EWMA);
+    mMmsClient->AddAddresseeL(aAddressType, aAddress);
+}
+/*------------------------------------------------------------------------------
+ * public SetApplicationId
+ * LoadMessage is called before this method call, other wise applicationId can
+ * be set to wrong TMsvId.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::SetApplicationIdL(const TDesC& aApplicationId)
+{
+    JELOG2(EWMA);
+    if (aApplicationId.Length() > 0)
+    {
+        TMsvId mvsEntry = mMmsClient->Entry().EntryId();
+        mMmsApplicationAdapter->SetApplicationIdL(mvsEntry,aApplicationId);
+    }
+}
+/*------------------------------------------------------------------------------
+ * SetReplyToApplicationId
+ * LoadMessage is called before this method call, other wise
+ * ReplyToApplicationId can be set to wrong TMsvId.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::SetReplyToApplicationIdL(
+    const TDesC& aReplyToApplicationId)
+{
+    JELOG2(EWMA);
+    if (aReplyToApplicationId.Length() > 0)
+    {
+        TMsvId mvsEntry = mMmsClient->Entry().EntryId();
+        mMmsApplicationAdapter->SetReplyToApplicationIdL(mvsEntry,
+                aReplyToApplicationId);
+    }
+}
+/*------------------------------------------------------------------------------
+ * public SendMultiPartMessageL
+ * ASyn method call to send the message.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::SendMultiPartMessageL()
+{
+    JELOG2(EWMA);
+    // convert the byte array into a native multimedia message representation
+    LOG(EWMA, EInfo , "Converting the byte array into a native multimedia"
+        "message representation");
+    CMMSMessageInformation& mms = mMessageHandler->DeSerializeL(*mSendBuf);
+    // send it towards the MMS engine
+    mSendMsgArray->AppendL(&mms);
+    while (mSendMsgArray->Count() > 0)
+    {
+        CMMSMessageInformation* midMessageInformation =
+            mSendMsgArray->At(0);
+        CleanupStack::PushL(midMessageInformation);
+        SendMmsMessageL(midMessageInformation);
+        mSendMsgArray->Delete(0);
+        CleanupStack::Pop(midMessageInformation); // midMessageInformation
+        delete midMessageInformation;
+        midMessageInformation = NULL;
+    }
+}
+/*------------------------------------------------------------------------------
+ * public SendMultiMediaMessageL
+ * Message is send in the following steps
+ * 1) Create an empty message in the draft folder
+ * 2) Get the multimeida messsage information from the CMMSMessageInformation
+ *    object and set that information to the newly created multimedia message
+ *    in the following order
+ *        i) Set the subject of the message (Optional)
+ *        ii)Add the destination addresses (to, cc, bcc)
+ *        iii)Add attachments to the message. Attachments are saved in the
+ *          message store.
+ *        vi)Set message setting (Date, time, expiry time, priority, visibility
+ *         of the sender)
+ * 3) Save the formed message in the message store
+ * 4) Send the message by using mmsMTMClient.
+ * 5) When the message is gone from the device delete the message from the sent
+ *    folder.
+ *-----------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::SendMmsMessageL(
+    CMMSMessageInformation* aMidMessageInformation)
+{
+    JELOG2(EWMA);
+    TMsvId msvId = CreateMessageL();
+    // Add subject
+    TDesC8& str8 = aMidMessageInformation->MessageSubjectL();
+    TDesC* str = NULL;
+    if (NULL != &str8)
+    {
+        S60CommonUtils::ConvertNarrowToWiderL(str8, str);
+        SetSubjectL(*str);
+        delete str;
+        str = NULL;
+    }
+    // Add EMsvRecipientTo addresses
+    TInt i = 0;
+    TInt count = aMidMessageInformation->AddressesCount(EMsvRecipientTo);
+    for (i = 0; i < count; i++)
+    {
+        AddRecipientL(aMidMessageInformation->MessageAddressL(
+                          EMsvRecipientTo, i), EMsvRecipientTo);
+    }
+    // Add EMsvRecipientCc addresses
+    count = aMidMessageInformation->AddressesCount(EMsvRecipientCc);
+    for (i = 0; i < count; i++)
+    {
+        AddRecipientL(aMidMessageInformation->MessageAddressL(
+                          EMsvRecipientCc, i), EMsvRecipientCc);
+    }
+    // Add EMsvRecipientBcc addresses
+    count = aMidMessageInformation->AddressesCount(EMsvRecipientBcc);
+    for (i = 0; i < count; i++)
+    {
+        AddRecipientL(aMidMessageInformation->MessageAddressL(
+                          EMsvRecipientBcc, i), EMsvRecipientBcc);
+    }
+    // Add attachments also set the started ID
+    AddAttachmentsL(aMidMessageInformation);
+    // set date and time
+    TInt64 time = aMidMessageInformation->MessageTime();
+    SetMessageSendDate(time);
+    mMmsMessagePriority = aMidMessageInformation->MessagePriority();
+    // set priorty, delivery time, message class, ExpiryInterval,
+    // sender visibility and delivery report
+    SetMessageSettingL();
+
+    // set application-id and reply-to-application-id
+    TDesC8& id8 = aMidMessageInformation->ApplicationIdL();
+    TDesC* id = NULL;
+    if (NULL != &id8)
+    {
+        S60CommonUtils::ConvertNarrowToWiderL(id8, id);
+        SetApplicationIdL(*id);
+        delete id;
+        id = NULL;
+    }
+    // Set reply-to-application-Id
+    TDesC8& rId8 = aMidMessageInformation->ReplyToApplicationIdL();
+    if (NULL != &rId8)
+    { // add reply-to-application-id to currently loaded message
+        S60CommonUtils::ConvertNarrowToWiderL(rId8, id);
+        SetReplyToApplicationIdL(*id);
+        delete id;
+        id = NULL;
+    }
+    SendMmsMessageL(msvId); // send it now
+    LOG(EWMA, EInfo, "CMMSPlatformServiceS60Impl::SendMmsMessageL Notifying"
+        "java about the message send status");
+    NotifySend(*mJniEnv, mJavaPeerObject, KErrNone);
+}
+/*-----------------------------------------------------------------------------
+ * private SendMmsMessageL
+ * Send the message from the device. This method is called when the
+ * message is ready to send. All the necessary fields are filled.
+ * message is send by using mmsClient mtm.
+ *-----------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::SendMmsMessageL(TMsvId aSendMmsMsgId)
+{
+    JELOG2(EWMA);
+    TMsvEntry tmvsEntry = mMmsClient->Entry().Entry();
+    tmvsEntry.SetInPreparation(EFalse);
+    tmvsEntry.SetVisible(ETrue);
+    mMmsClient->Entry().ChangeL(tmvsEntry);
+    // Save the message here to save the last changes made above.
+    mMmsClient->SaveMessageL();
+    // left on CleanupStack
+    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
+    wait->iStatus = KRequestPending;
+    CMsvOperation* op = NULL;
+    op = mMmsClient->SendL(wait->iStatus);
+    wait->Start();
+    CleanupStack::PushL(op);
+    CActiveScheduler::Start();
+    mSendTMsvIdArray.AppendL(aSendMmsMsgId);
+    // The following is to ignore the completion of other active objects.
+    // It is not needed if the app has a command absorbing control.
+    while (wait->iStatus.Int() == KRequestPending)
+    {
+        CActiveScheduler::Start();
+    }
+    CleanupStack::PopAndDestroy(op);
+    CleanupStack::PopAndDestroy(wait);
+}
+/*------------------------------------------------------------------------------
+ * protected Set Message Setting
+ * Set the class, ExpiryInterval, delivery time interval, priority and
+ * visibility of the sender.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::SetMessageSettingL()
+{
+    JELOG2(EWMA);
+    mMmsClient->RestoreSettingsL();
+
+    mMmsClient->SetMessageClass(EMmsClassPersonal);
+    // X-Mms-Delivery-Time
+    mMmsClient->SetDeliveryDate(mMessageDeliveryDate);
+
+    // X-Mms-Priority
+    mMmsClient->SetMessagePriority(mMmsMessagePriority);
+    mMmsClient->SetSenderVisibility(EMmsSenderVisibilityShow);
+    mMmsClient->SetDeliveryReport(EMmsDeliveryReportYes);
+}
+/*------------------------------------------------------------------------------
+ * public SetMessageSendDate
+ * Set message time in Java format
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::SetMessageSendDate(TInt64& aLong)
+{
+    JELOG2(EWMA);
+    if (aLong != 0)
+    {
+        mMessageDeliveryDate = S60CommonUtils::JavaTimeToTTime(aLong);
+    }
+    else
+    {
+        mMessageDeliveryDate = TTime(0);
+    }
+}
+/*------------------------------------------------------------------------------
+ * public HandleSessionEventL
+ * EMsvEntriesMoved,
+ *
+ *    One or more entries have been moved.
+ *
+ *    aArg1 is a CMsvEntrySelection containing the IDs of the moved entries.
+ *    aArg2 is the TMsvId of the new parent.
+ *    aArg3 is the TMsvId of the old parent entry.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::HandleSessionEventL(
+    TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/)
+{
+    JELOG2(EWMA);
+    switch (aEvent)
+    {
+    case EMsvEntriesMoved:
+    {
+        TMsvId parentId = KMsvNullIndexEntryId;
+        parentId = *(TMsvId*) aArg2;
+
+        if (parentId == KMsvSentEntryId)
+        {
+            // We take the created entries into a selection
+            CMsvEntrySelection* entries =
+                static_cast<CMsvEntrySelection*>(aArg1);
+            TInt count = entries->Count();
+            LOG1(EWMA, EInfo, "CMMSPlatformServiceS60Impl::HandleSessionEventL"
+                 "Count = %d ", count);
+            for (TInt i = 0; i < count; i++)
+            {
+                LOG1(EWMA, EInfo, "CMMSPlatformServiceS60Impl::"
+                     "HandleSessionEventL number = %d ", i);
+                TRAP_IGNORE(DeleteSentMessageL(entries->At(i)));
+            }// end of for loop
+        } // end of parentid if
+        break;
+    }
+    default:
+        break;
+    }
+}
+/*------------------------------------------------------------------------------
+ * private CreateSendMessageArray
+ * Create the send message TMsvId array. It will be later used to delete the
+ * messages. We should NOT be deleting the messages send by other application.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::CreateSendMessageArrayL()
+{
+    JELOG2(EWMA);
+    ClearAndDestroySendMessageArray();
+    mSendMsgArray = new(ELeave) CArrayPtrSeg<CMMSMessageInformation>
+    (KArrayGranularity);
+}
+/*------------------------------------------------------------------------------
+ * private ClearAndDestroySendMessageArray
+ *
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::ClearAndDestroySendMessageArray()
+{
+    JELOG2(EWMA);
+    if (mSendMsgArray)
+    {
+        mSendMsgArray->ResetAndDestroy();
+    }
+    delete mSendMsgArray;
+    mSendMsgArray = NULL;
+}
+
+/*------------------------------------------------------------------------------
+ * public ClearSendMessageArray
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::ClearSendMessageArray()
+{
+    JELOG2(EWMA);
+    if (mSendMsgArray)
+    {
+        mSendMsgArray->Reset();
+    }
+}
+
+/*------------------------------------------------------------------------------
+ * public NotifyReceivedMessage
+ * Message arrive in the device. User was prompted for the MMS message.
+ * But user do not want to start the midlet. Later (after some time)
+ * user start the midlet.
+ * MIDlet will receive all the messages. Following method will notify
+ * the listener for the received messages.
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::NotifyReceivedMessageL()
+{
+    JELOG2(EWMA);
+    TMsvId folderId = KMsvNullIndexEntryId;
+    folderId = mMmsApplicationAdapter->FolderIdL(*mServerApplicationId);
+
+    if (KMsvNullIndexEntryId != folderId)
+    {
+        CMsvEntry* cEntry = mSession->GetEntryL(folderId);
+        // Show invisible entries
+        // Sort the entries according to date;
+        cEntry->SetSortTypeL(TMsvSelectionOrdering(KMsvNoGrouping,
+                             EMsvSortByDate, ETrue));
+        //get the selection array of the messages in sorted order by date
+        CMsvEntrySelection* msvEntrySelection =
+            cEntry->ChildrenWithTypeL(KUidMsvMessageEntry);
+
+        //Process each entry, one at a time.
+        TInt count = msvEntrySelection->Count();
+        for (TInt i = 0; i < count; i++)
+        {
+            // this checks the entry and handles it if it is targeted
+            // to midp app we are in startup we do not want to leave here
+            TRAP_IGNORE(DoReceiveMessageL(msvEntrySelection->At(i)));
+        }// end of for loop
+        delete msvEntrySelection;
+        msvEntrySelection = NULL;
+        delete cEntry;
+        cEntry = NULL;
+    }
+} // end of the method NotifyReceivedMessageL
+
+/*------------------------------------------------------------------------------
+ * public HandleEntryEventL
+ * observer the entry for the specific application Id.
+ * if a new message is arrived in this folder notify the listener
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::HandleEntryEventL(
+    TMsvEntryEvent aEvent, TAny* aArg1, TAny*, TAny*)
+{
+    JELOG2(EWMA);
+    switch (aEvent)
+    {
+    case MMsvSessionObserver::EMsvEntriesChanged:
+    {
+        // We take the created entries into a selection
+        CMsvEntrySelection* entries =
+            static_cast<CMsvEntrySelection*>(aArg1);
+        //Process each created entry, one at a time.
+        for (TInt i = 0; i < entries->Count(); i++)
+        { // this checks the entry and handles it if it is targeted
+            // to midp app
+            TRAP_IGNORE(DoReceiveMessageL(entries->At(i)));
+        } // end of for loop
+    }
+    break;
+    }
+}
+
+/*------------------------------------------------------------------------------
+ * private DoReceiveMessageL
+ * ReceiveMessageL MUST be call from DoReceiveMessageL
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::DoReceiveMessageL(TMsvId aMsvId)
+{
+    JELOG2(EWMA);
+    ReceiveMessageL(aMsvId);
+}
+/*------------------------------------------------------------------------------
+ * protected ReceiveMessageL
+ *
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::ReceiveMessageL(TMsvId aMsvId)
+{
+    JELOG2(EWMA);
+    CMsvEntry* csvEntry = mSession->GetEntryL(aMsvId);
+    TMsvEntry msvEntry = csvEntry->Entry();
+
+    if (msvEntry.iMtm != KUidMsgTypeMultimedia)
+    { // It is not MMS, free up the memory of the CMsvEntry
+        delete csvEntry;
+        csvEntry = NULL;
+        return;
+    }
+
+    if (msvEntry.InPreparation() > 0)
+    { // message is not ready free up the memory of the CMsvEntry
+        delete csvEntry;
+        csvEntry = NULL;
+        return; // entry is not ready to read
+    }
+
+    mServerMmsMtm->SwitchCurrentEntryL(aMsvId);
+    mServerMmsMtm->LoadMessageL();
+
+    // Check application ID
+    TPtrC applicationId = mMmsApplicationAdapter->ApplicationIdL(aMsvId);
+    // Local Copy of the Application ID
+    TDesC *localCopy_AppId = NULL;
+    S60CommonUtils::CopyWiderL(applicationId, (TDesC16*&) localCopy_AppId);
+    // AppId and replyToAppId is not working yet so cannot be tested.
+    if (mServerApplicationId->Compare(*localCopy_AppId) != 0)
+    { // received message is not for this connector
+        delete csvEntry;
+        csvEntry = NULL; // free the memory
+        return;
+    }
+    TPtrC replyToappId = mMmsApplicationAdapter->ReplyToApplicationIdL(aMsvId);
+    // Local Copy of reply-to-Application-Id  //TDesC16*&
+    TDesC *localCopy_Reply_To_AppId = NULL;
+    S60CommonUtils::CopyWiderL(replyToappId,(TDesC16*&)localCopy_Reply_To_AppId);
+
+    // receive message date
+    TInt64 dateTime;
+    if (mServerMmsMtm->SendingDate() != TTime(0))
+    {
+        dateTime = S60CommonUtils::TTimeToJavaTime(
+                       mServerMmsMtm->SendingDate());
+    }
+    else
+    {
+        dateTime = S60CommonUtils::TTimeToJavaTime(msvEntry.iDate);
+    }
+    TDesC *localCopySender = NULL;
+    // only for emulator in local mode to pass the test on the emulator
+#if(defined (__WINS__) || defined(__WINSCW__))
+    {
+        const CMsvRecipientList& recipientList =mServerMmsMtm->AddresseeList();
+        TInt recipientCount = recipientList.Count();
+        for (TInt j=0; j < recipientCount; j++)
+        {
+            const TDesC& address = recipientList[j];
+            TMsvRecipientType addressType = recipientList.Type(j);
+            if (EMsvRecipientTo == addressType)
+            {
+                TInt len = S60CommonUtils::CopyWiderL(address,(TDesC16*&)
+                                                      localCopySender);
+                break;
+            }
+        }
+    }
+#else
+    {
+        const TPtrC sender = mServerMmsMtm->Sender();
+        S60CommonUtils::CopyWiderL(sender, (TDesC16*&) localCopySender);
+    }
+#endif
+
+    TInt size = mServerMmsMtm->MessageSize();
+    TDesC8* applicationId8 = NULL;
+    CMMSMessageInformation* receiveMsgInformation =
+        CMMSMessageInformation::NewL(*localCopySender, dateTime,
+                                     *applicationId8, aMsvId);
+    CleanupStack::PushL(receiveMsgInformation);
+
+    const CMsvRecipientList& recipientList = mServerMmsMtm->AddresseeList();
+    TInt recipientCount = recipientList.Count();
+    TDesC16* messageAddress;
+    for (TInt j = 0; j < recipientCount; j++)
+    {
+        messageAddress = NULL;
+        const TDesC& address = recipientList[j];
+        TMsvRecipientType addressType = recipientList.Type(j);
+        S60CommonUtils::CopyWiderL(address, messageAddress);
+        receiveMsgInformation->AddAddressL((TMsvRecipientTypeValues)addressType,
+                                           messageAddress);
+    }
+
+    receiveMsgInformation->SetApplicationIdL(*localCopy_AppId);
+    receiveMsgInformation->SetReplyToApplicationIdL(*localCopy_Reply_To_AppId);
+    receiveMsgInformation->SetMessageSize(size);
+    TPtrC subject = mServerMmsMtm->SubjectL();
+    receiveMsgInformation->SetMessageSubjectL(subject);
+    TMmsMessagePriority priority =
+        (TMmsMessagePriority) mServerMmsMtm->MessagePriority();
+    receiveMsgInformation->SetMessagePriority(priority);
+    ReadAttachmentsL(*receiveMsgInformation);
+
+    mReceivedMsgArray->AppendL(receiveMsgInformation);
+    CleanupStack::Pop(receiveMsgInformation);
+
+    delete csvEntry;
+    csvEntry = NULL;
+    delete localCopy_Reply_To_AppId;
+    localCopy_Reply_To_AppId = NULL;
+    delete localCopy_AppId;
+    localCopy_AppId = NULL;
+    delete localCopySender;
+    localCopySender = NULL;
+
+    HBufC* buf = HBufC::NewLC(KMaxAppIDLength);
+    TPtr ptr = buf->Des();
+    ptr.SetLength(0); // make sure that there is no garbage
+    ptr.AppendNum(aMsvId);
+    NotifyJava(*buf, 1);
+    CleanupStack::PopAndDestroy(buf); //buf
+    TRAP_IGNORE(DeleteMmsMessageL(aMsvId));
+}
+
+/*------------------------------------------------------------------------------
+ * Notifies the message listener about the incoming message
+ * .
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::NotifyJava(const TDesC& aDescription,
+        int aMessages)
+{
+    JELOG2(EWMA);
+    TLex lex(aDescription);
+    TMsvId ID;
+    lex.Val(ID);
+    TRAP_IGNORE(mReceivedMMSIDs.AppendL(ID));
+    mNewMessages += aMessages;
+    mMessageListener->msgArrived();
+}
+/*-------------------------------------------------------------------------------
+ * void ReadAttachmentsL(CMMSMessageInformation& aMidMessageInformation)
+ *
+ *-------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::ReadAttachmentsL(
+    CMMSMessageInformation& aMidMessageInformation)
+{
+    JELOG2(EWMA);
+    // Find root attachment
+    TMsvAttachmentId rootId = mServerMmsMtm->MessageRootAttachment();
+    CMsvStore* store = mServerMmsMtm->Entry().ReadStoreL();
+    CleanupStack::PushL(store);
+    MMsvAttachmentManager& attaMan = store->AttachmentManagerL();
+    CMsvAttachment* msvAttachment = NULL;
+    TInt attaCount = attaMan.AttachmentCount();
+
+    for (TInt i = 0; i < attaCount; i++)
+    {
+        msvAttachment = attaMan.GetAttachmentInfoL(i);
+        CleanupStack::PushL(msvAttachment);
+        // open other message part
+        // get mime header
+        CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewLC();
+        mimeHeaders->RestoreL(*msvAttachment);
+
+        TMsvAttachmentId attachmentId = msvAttachment->Id();
+        RFile attaFile = attaMan.GetAttachmentFileL(attachmentId);
+        TDesC8* dataArray8 = NULL;
+        ReadDataFromAttachFileL(attaFile, dataArray8);
+        CleanupStack::PushL(dataArray8);
+        attaFile.Close();
+        // mimetype and encoding from mime header
+        const TDesC8& attachmentType8 = mimeHeaders->ContentType();
+        const TDesC8& attachmentSubType8 = mimeHeaders->ContentSubType();
+        HBufC8* attachmentTypeBuf8 = HBufC8::NewLC(attachmentType8.Length() +
+                                     attachmentSubType8.Length()
+                                     + KSlashLength +
+                                     KSlashLength);
+        TPtr8 ptr = attachmentTypeBuf8->Des();
+        ptr.SetLength(0);
+        ptr.Append(attachmentType8);
+        ptr.Append(KSlash);
+        ptr.Append(attachmentSubType8);
+        // Get the values of content-id, content-location
+        const TDesC8& contentId8 = mimeHeaders->ContentId();
+        const TDesC& location = mimeHeaders->ContentLocation();
+        TDesC8* location8 = NULL;
+        // Check for the content location if we have the same string that
+        // we use for sending remove the content location.
+        if ((&location) && location.Find(KTempMmsAttachmentName)== KErrNotFound)
+        {
+            S60CommonUtils::ConvertWiderToNarrowL(location, location8);
+        }
+        TInt size = msvAttachment->Size();
+
+        CMMSMessageAttachment* midAttachment =
+            CMMSMessageAttachment::NewL(mRFs, *dataArray8,
+                                        *attachmentTypeBuf8, contentId8, *location8,
+                                        false);
+
+        CleanupStack::PushL(midAttachment);
+
+        TUint charEncoding = mimeHeaders->MimeCharset();
+        midAttachment->SetEncoding(charEncoding);
+
+        if (attachmentId == rootId)
+        {
+            midAttachment->SetStarterContentId(true);
+        }
+        aMidMessageInformation.InsertAttachmentL(midAttachment);
+        CleanupStack::Pop(midAttachment); // midAttachment
+
+        delete location8;
+        location8 = NULL; // location8
+        // attachmentTypeBuf8
+        CleanupStack::PopAndDestroy(attachmentTypeBuf8);
+        CleanupStack::Pop(dataArray8); // dataArray8
+        // mimeHeaders, attaInfo
+        CleanupStack::PopAndDestroy(mimeHeaders);
+        // mimeHeaders, attaInfo
+        CleanupStack::PopAndDestroy(msvAttachment);
+    }
+    CleanupStack::PopAndDestroy(store); // store
+}
+/*-------------------------------------------------------------------------------
+ *
+ *-------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::ReadDataFromAttachFileL(RFile& aRFile,
+        TDesC8*& aDataArray)
+{
+    JELOG2(EWMA);
+    TInt size = 0;
+    TInt error = KErrNotFound;
+    error = aRFile.Size(size);
+    if (error == KErrNone)
+    {
+        HBufC8* buffer = HBufC8::NewL(size);
+        if (buffer)
+        {
+            TPtr8 ptr = buffer->Des();
+            error = aRFile.Read(ptr, size); //read the data in the file
+        }
+        aDataArray = buffer;
+    }
+}
+
+/*------------------------------------------------------------------------------
+ * public ReceivedMessage(TMsvId aMessageId)
+ *
+ *------------------------------------------------------------------------------
+ */
+CMMSMessageInformation* CMMSPlatformServiceS60Impl::ReceivedMessage(
+    TMsvId aMessageId)
+{
+    JELOG2(EWMA);
+    CMMSMessageInformation* msgInfo = NULL;
+    TInt count = mReceivedMsgArray->Count();
+    for (TInt i = 0; i < count; i++)
+    {
+        CMMSMessageInformation* mi =(CMMSMessageInformation*)
+                                    mReceivedMsgArray->At(i);
+        if (aMessageId == mi->MessageMsvId()) //check for the message Id
+        {
+            msgInfo = mi; // that is the message we are looking for.
+            mReceivedMsgArray->Delete(i);
+            break;
+        }
+    }
+    return msgInfo;
+}
+
+/*------------------------------------------------------------------------------
+ * public destructor
+ *
+ *------------------------------------------------------------------------------
+ */
+CMMSPlatformServiceS60Impl::~CMMSPlatformServiceS60Impl()
+{
+    JELOG2(EWMA);
+    detachFromVm();
+    stopServer();
+}
+void CMMSPlatformServiceS60Impl::closeConnection(JNIEnv& aJni, jobject aPeer)
+{
+    JELOG2(EWMA);
+    // If sending of a message is being carried out unblock the java side with
+    // KErrCancel.
+    if (mIsSending)
+    {
+        NotifySend(aJni, aPeer, KErrCancel);
+    }
+    // Close() Needs to be called in function server thread
+    TRAP_IGNORE(CallMethodL(this, &CMMSPlatformServiceS60Impl::Close, this));
+}
+/*------------------------------------------------------------------------------
+ * private close
+ *
+ *------------------------------------------------------------------------------
+ */
+void CMMSPlatformServiceS60Impl::Close()
+{
+    JELOG2(EWMA);
+    if (mServerConnection)
+    {
+        mReceivedMMSIDs.Close();
+        if (mRegisterCMsvEntry)
+        {
+            mRegisterCMsvEntry->RemoveObserver(*this);
+            delete mRegisterCMsvEntry;
+            mRegisterCMsvEntry = NULL;
+        }
+        if (mServerMmsMtm)
+        {
+            delete mServerMmsMtm;
+            mServerMmsMtm = NULL;
+        }
+        if (mReceivedMsgArray)
+        {
+            mReceivedMsgArray->ResetAndDestroy();
+            delete mReceivedMsgArray;
+            mReceivedMsgArray = NULL;
+        }
+        // Unregistering from MMS Engine.
+        LOG(EWMA, EInfo , "CMMSPlatformServiceS60Impl::Close() Unregistering"
+            "from MMS Engine");
+        mMmsApplicationAdapter->UnregisterL(*mServerApplicationId);
+        if (mServerApplicationId)
+        {
+            delete mServerApplicationId;
+            mServerApplicationId = NULL;
+        }
+    }
+    if (mMmsClient)
+    {
+        delete mMmsClient;
+        mMmsClient = NULL;
+    }
+
+    if (mClientMtmRegistry)
+    {
+        delete mClientMtmRegistry;
+        mClientMtmRegistry = NULL;
+    }
+
+    if (mSession)
+    {
+        delete mSession;
+        mSession = NULL;
+    }
+
+    if (mMmsApplicationAdapter)
+    {
+        delete mMmsApplicationAdapter;
+        mMmsApplicationAdapter = NULL;
+    }
+    mSendTMsvIdArray.Close();
+
+    if (mSendMsgArray)
+    {
+        mSendMsgArray->ResetAndDestroy();
+        delete mSendMsgArray;
+        mSendMsgArray = NULL;
+    }
+    if (mMessageHandler)
+    {
+        delete mMessageHandler;
+        mMessageHandler = NULL;
+    }
+}
+// End of File
+} //namespace wma
+} //namespace java
+