MMS Client MTM API Specification


1 Overview

The MMS Client MTM API provides functions to create, send multimedia messages, and retrieve and manipulate multimedia message entries in Message Server.

API categorypublic
API typec++
API librariesmmscli.lib

1.1 Description

MMS Client MTM API is used to access Message Server and message entries. MMS Client MTM forms part of the MMS MTM module (a plug-in to the messaging architecture). It implements a class derived from CBaseMtm and provides functionality to create and send MMS messages, retrieve messages from the message store and view or change their attributes, forward or reply to messages and so on.

Note that MTMs are often platform-specific. So, while the base class, CBaseMtm , is common to all Symbian platforms, MMS Client MTM described here is Symbian-specific.

Before using MMS Client MTM API, it is recommeded to check if the lightweight APIs, Send As ( RSendAs and RSendAsMessage ) or Send UI ( CSendUI ), are suitable.

1.1.1 MMS messages

MMS messaging provide a means of sending multimedia objects (such as images, sounds and videos) between devices. The multimedia objects are sent as attachments to a message and the required presentation of the message (in a message viewer) is defined by SMIL. (SMIL is a markup language. More information can be found at

1.1.2 MTMs

Messaging architecture from the Symbian platform is a powerful and extensible multi-protocol messaging framework. It allows the creation of plug-in modules to support individual messaging protocols such as SMS, email, and MMS. The set of components that make up such a plug-in module is called a Message Type Module (MTM). All interaction with lower-level communication protocols is performed by MTM. The components that comprise a module are Client MTM, UI MTM, UI Data MTM and Server MTM. The following diagram illustrates the MTM architecture:

Messaging architecture
Messaging architecture

Different devices on Symbian platform may support different protocols and the support for any given protocol may differ between Symbian platforms. The plug-in architecture makes the support mechanisum easy in Messaging.

1.2 Use Cases

The following are the most important use cases of MMS Client API:

1.3 Class Structure

Summary of API classes and header files
CMmsClientMtm /epoc32/include/app/mmsclient.h, /epoc32/include/app/mmsclient.inl No classes/epoc32/include/app/mmsconst.h, /epoc32/include/app/mmserrors.h

MMS Client MTM is one module of MMS MTM. The main class of MMS Client MTM API is CMmsClientMtm . It is derived from CBaseMtm and is the MMS MTM's implementation of Client MTM.

An overview of the MTM architecture is given in the [MMS_Client_MTM_API_Specification.topic1 MTMs] section of this document. Further information can be found in the SDK documentation.

The following class diagram shows the MMS Client MTM API:

MMS Client MTM class diagram
MMS Client MTM class diagram

2 Using The API

The messaging architecture relies on the client-server framework. This means that a session (an instance of CMsvSession ) is required as a channel of communication between the client thread (Client MTM) and the Message Server thread. This session must exist before Client MTM can be constructed and its functionality used.

The most important use cases are described in the sections below. Note that these use cases do not constitute an exhaustive list of the MMS Client MTM's functionality. CMmsClientMtm contains numerous functions documented in the header file mmsclient.h.

Capabilities required to use MMS Client MTM API are ReadUserData, ReadDeviceData and NetworkServices.

A prerequisite of using MMS Client MTM is a good understanding of the key messaging concepts.

2.1 Constructing MMS Client MTM

The first step for using MMS Client MTM API is creating a session with Message Server. To do this, a class which implements the mixin MMsvSessionObserver is required. An example of such a class is shown below.

class CMtmExample : public CActive, public MMsvSessionObserver
private: // from MMsvSessionObserver
    void HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);
    CMsvOperation*      iOp;
    CMsvSession*        iSession; // Session to the messaging server
    CClientMtmRegistry* iMtmReg;
    CMmsClientMtm*      iMmsMtm;
    TMsvId              iNewMessageId;

A session with the Message Server can be created either synchronously (using CMsvSession::OpenSyncL ) or asynchronously (using CMsvSession::OpenAsyncL() ). In each case, an instance of the MMSvSessionObserver derived class is passed, by reference to the function. It is recommended to use the asynchronous implementation to ensure responsiveness of the device.

void CMtmExample::ConstructL()
    // Create CMsvSession
    // New session is opened asynchronously
    iSession = CMsvSession::OpenAsyncL(*this);

For asynchronous connections, notification of success is through a call to the implemented HandleSessionEventL() function, with the argument aEvent = EMsvServerReady being passed through. Once this notification has been received (or the synchronous function has returned), other messaging objects can be created.

void CMtmExample::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
    switch (aEvent)
        // This event tells us that the session has been opened
        case EMsvServerReady:

Accessing MMS Client MTM is done through the Client MTM registry ( CClientMtmRegistry ). This holds details of all registered client MTMs available on the device. The registry is constructed with a handle to the session. MMS Client MTM can then be created through a call to CClientMtmRegistry::NewMtmL() , passing through KUidMsgTypeMultiMedia (defined in mmsconst.h) as the MTM UID. NewMtmL() returns a CBaseMtm pointer which needs to be cast into the correct type, that is CMmsClientMtm .

void CMtmsExampleEngine::CompleteConstructL()
    // Construct the Client MTM registry
    iMtmReg = CClientMtmRegistry::NewL(*iSession);
    // Obtain MMS Client MTM from the MTM registry
    iMmsMtm = static_cast<CMmsClientMtm*>(iMtmReg->NewMtmL(KUidMsgTypeMultimedia));

MMS Client MTM can now be used to access Message Server and create, manipulate, and send multimedia messages.

2.2 Creating an MMS message entry

Once the MMS Client MTM instance has been constructed (see Constructing MMS Client MTM), it can be used to create an MMS entry in Message Server. There is more than one way to create an MMS message entry but the most obvious way is to use CMmsClientMtm::CreateMessageL() . This function creates an empty message entry as the child of the current context. (The context is the entry on which the MTM actions are performed.) The entry is created with its visible flag set to false and its in-preparation flag set to true since at this stage it is empty.

As the entry is created as a child to the current context, it is important to first set the context appropriately before CreateMessageL() is called. It is usual to create new messages in the drafts folder. To set the context, SwitchCurrentEntryL() is called with the parent folder ID (KMsvDraftEntryId) passed through. CMmsClientMtm::CreateMessageL() is then called with the required service ID as a parameter. The service ID can be retrieved by calling DefaultServiceL() on the MTM. After successfully creating the new message entry, CreateMessageL() then sets the new entry as the current context.

TBool CMtmsExampleEngine::CreateNewMessageL()
    // Set context to the parent folder (Drafts folder)

At this stage, the created message is empty. To be useful, the intended message recipient(s) of the message must be set. For MMS entries, it is also useful to give the message a subject attribute.

CMmsClientMtm::AddAddresseeL() has a number of overloads that can be used to set the To, Cc, and Bcc fields of an MMS entry. CMMsClientMtmL::SetSubjectL() takes a descriptor (TDesC&) and is used to set the subject.

    // Set the recipients (_LIT used only for demonstration purposes)
    // "To" recipient.
    _LIT(KSamsNumber, "07738123456");
    _LIT(KSamsAlias, "Sam");
    // Cc recipient
    _LIT(KPetesNumber, "07812654321");
    iMmsMtm->AddAddresseeL(EMsvRecipientTo, KSamsNumber, KSamsAlias); // To field, alias set
    iMmsMtm->AddAddresseeL(EMsvRecipientCc, KPetesNumber); // Cc field, no alias
    // Set a message subject
    _LIT(KMessageSubject, "MMS Example");

The next step is to add some text and multimedia object to the message. How this is done is shown in Adding an attachment to an MMS message.

Here, the message is just saved to the drafts folder. To indicate that the message entry is no longer being amended, TMsvEntry::SetInPreparation() can be set to |EFalse while TMsvEntry::SetVisible() is set to ETrue to ensure the message is displayed in the Messaging application. Changes to the entry should be committed using CMsvEntry::ChangeL() and the message saved using CMmsClientMtm::SaveMessageL() .

SetInPreparation() and SetVisible() need to be called on the TMsvEntry that represents the message in Message Server. To access this, Entry() is called on Client MTM and then Entry() is called on the returned CMsvEntry .

    TMsvEntry ent = iMmsMtm->Entry().Entry();
    // Set InPreparation to false
    ent.SetVisible(ETrue);            // Mark as visible, so this the message can be seen in Drafts
    iMmsMtm->Entry().ChangeL(ent);    // Commit changes
    //Save the changes

2.3 Adding and amending attributes of an MMS message

There are a number of attributes on a message entry than can be set or amended. These attributes are properties of the message header but can be set through Client MTM and include the expiry date on the message, the delivery time, and priority. As long as the context of the MTM is set to the appropriate message, setting the values for the properties is simply a case of calling the correct function. The functions are detailed in the Client MTM header file (mmsclient.h) and enumeration values required by some of the functions can be found in mmsconst.h.

An example showing the message priority being set to high is shown below.

//Save the changes

2.4 Adding body text to an MMS message

Although CMmsClientMtm has a Body() function defined, it should not be used. Body text for an MMS message is treated as a message attachment and therefore should be set using CMmsClientMtm::CreateTextAttachmentL() . See Adding attachments to an MMS message for further information.

2.5 Adding attachments to an MMS message

All MMS message data (text, images, sounds, and so on) should be sent as attachments to the message with the required presentation being defined by a SMIL file (also sent as an attachment). Note, although CMmsClientMtm has a Body() function defined, it should not be used - the message body text is treated as an attachment. Therefore, text should be added using CMmsClientMtm::CreateTextAttachmentL() .

virtual void CMmsClientMtm::CreateTextAttachmentL(
    CMsvStore&  aStore,
    TMsvAttachmentId &  aAttachmentId,
    const TDesC&  aText,
    const TDesC&  aFile,
    TBool  aConvertParagraphSeparator = ETrue);

The function requires that the message store for the message entry has been opened ready for editing. A pointer to the open store is then passed as a parameter. The text required for the message is passed as a descriptor ( aText) and a suggestion for a suitable file name is also needed (SMIL references this filename). If required, the unicode paragraph separator (character 0x2029) can be replaced with a line feed (character 0x000a). On completion, aAttachmentId is set.

To use CreateTextAttachmentL(), the message entry's store must first be opened.

// Open the entry's store - assume message context set correctly
CMsvStore* store = iMmsMtm->Entry().EditStoreL();
// Add the text attachment. _LIT used for demonstration purposes
_LIT(KMMSText, "Thought you'd like to see where I'm staying");
_LIT(KMMSTextFilename, "hello.txt");
iMmsMtm->CreateTextAttachmentL(*store, attachId, KMMSText, KMMSTextFilename);
// Add more attachments or save the message
// Remember to do the appropriate clean up at the end

For multimedia attachments, CMmsClientMtm::CreateAttachment2L() is used.

virtual void CreateAttachment2L(
    CMsvStore& aStore,
    RFile& aFile,
    TDesC8& aMimeType,
    CMsvMimeHeaders& aMimeHeaders,
    CMsvAttachment* aAttachmentInfo,
    TMsvAttachmentId& aAttaId);

The function creates an attachment entry and copies the file specified as a parameter ( aFile to an open message store (aStore). The attachment should be passed as a handle to an open file. The MIME type, for example image/jpeg for a JPEG image, is passed as a descriptor. A MIME header ( CMsvMimeHeaders ) for the attachment is created. A reference to the header is passed to the function so it can be updated. A CMsvAttachment object is created with the parameter CMsvAttachment::EMsvFile to represent the attachment. This is also updated by the CreateAttachment2L() function.

// Continuation of code above which set a text attachment
// Add an image attachment
// Set the filename for the image
#define KDirPictures	PathInfo::ImagesPath()
#define KPhoneRootPath	PathInfo::PhoneMemoryRootPath()
_LIT(KFileName, "mmsexample.jpg");
TFileName attachmentFile(KPhoneRootPath);
// Open the attachment file
RFile attachment;
TInt error = attachment.Open(CCoeEnv::Static()->FsSession(), attachmentFile, EFileShareReadersOnly | EFileRead);
// Check that the attachment file exists.
if(error != KErrNone)
    _LIT(KFileNotFound, "Attachment file not found!");
    return EFalse;
    // Mime header
    CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL();
    // Represents a single attachment and information about the attachment
    CMsvAttachment* attaInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
    // Mime Type
    _LIT8(KMimeType, "image/jpeg");
    TBufC8<10> mimeType(KMimeType);
    // Attachment file must be in a public folder (e.g. c:\Data\images)
        attachId );
    CleanupStack::Pop(attaInfo); // attaInfo
    CleanupStack::PopAndDestroy(mimeHeaders); // mimeHeaders
    // If a SMIL file is attached for presentation layout purposes
    // then it should be done here before the
    // the changes are committed
    // Commit the changes and perform the appropriate cleanup
    // Save the changes

This example shows how to attach some text and an image to an MMS message. However, the layout of the message is left to the receiving device. To dictate how the message should be presented to the recipient, a SMIL file is needed. An example file is shown below.

<smil xmlns="">
             <root-layout width="160" height="140"/>
             <region id="Image" width="160" height="120" left="0" top="0"/>
             <region id = "Text" width="160" height="20" left="100" top="120"/>
         <par dur="10s">
             <img src="mmsexample.jpg" region="Image" />
             <text src="hello.txt" region="Text" />

This file indicates that the image should be displayed before the text in the message.

The SMIL file should be added as an attachment in the same way that the image was added, that is using CMmsClientMtm::CreateAttachment2L() . In this case, the MIME type should be set to KMmsApplicationSmil(defined in mmsconst.h). The SMIL attachment should then be set as the root attachment using CMmsClientMtm::SetMessageRootL() and passing through the ID ( TMsvAttachmentId ) of the SMIL attachment set by the Createattachment2L() function.


Note that after setting the root, the changes to the store should be committed and the message saved.

2.6 Validating an MMS message

Before sending an MMS message, it is advisable to validate it to ensure the added data is compliant with the message type. The base class ( CBaseMtm ) defines the function ValidateMessage() and this is implemented by each MTM to provide type-specific validation. The function takes a TMsvPartList parameter which is a bit-set (flags for this bit-set are defined in Mmtdef.h) indicating the parts to be checked. Not all flags are supported by MMS MTM. Supported flags are KMsvMessagePartRecipient, KMsvMessagePartOriginator and KMsvMessagePartAttachments. The return value of ValidateMessage() is also a TMsvPartList bit-set that indicates which parts of the message were invalid.

TBool CMtmsExampleEngine::ValidateMMS()
    // Context should be set to appropriate message
    TMsvPartList msgCheckParts = KMsvMessagePartRecipient | KMsvMessagePartOriginator | KMsvMessagePartAttachments;
    TMsvPartList msgFailParts = iMmsMtm->ValidateMessage(msgCheckParts);
    return msgFailParts == KMsvMessagePartNone;

2.7 Sending an MMS message

Assuming that the MMS message has been created and validated, sending a message using MMS Client MTM is using its SendL() function. The important point to realize is that the ID of the message entry that should be sent must be set as the context of the MTM. If required, a time can be set for the sending of the message. The SendL() function is asynchronous and returns a CMsvOperation pointer. This can be used to obtain progress information about the operation before the active object completes (that is, before the RunL() method is called).

void CMtmsExampleEngine::SendMMSL()
    iOp = iMmsMtm->SendL(iStatus);

There is also an overload of CMmsClientMtm::SendL() that enables the sending of multiple messages with one operation. An array of message IDs ( TMsvId s) is created as a CMsvEntrySelection object and this is passed as a parameter to the SendL() function. The function is asynchronous and returns a CMsvOperation pointer to allow progress monitoring.

2.8 Querying a received MMS message

MMS Client MTM can be used to retrieve information from received MMS messages. Functions, such as Sender(), MessageReceiveTime(), NumberOfPreviousSenders() are available to use. In each case, the important point is that the context of the MTM is set correctly using the ID of the message.

The example below shows an incoming message, caught by MMsvSessionObserver::HandleSessionEventL() . The message ID ( TmsvId iNewMessageId) is stored as the entry is created in Inbox and then, once the message has been stored ( aEvent == EMsvEntriesChanged), the MTM context is set and the message loaded. Information about the message can then be queried, for example the sender.

void CMtmsExampleEngine::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3)
    switch (aEvent)
        case EMsvEntriesCreated:
            if(*(static_cast<TMsvId*>(aArg2)) == KMsvGlobalInBoxIndexEntryId)
                CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1);
                iNewMessageId = entries->At(0);
        case EMsvEntriesChanged:
            if(*(static_cast<TMsvId*>(aArg2)) == KMsvGlobalInBoxIndexEntryId)
                CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1);
                if(iNewMessageId == entries->At(0))
                    TPtrC sender = iMmsMtm->Sender();
                    // Use the sender information

Further information about the general messaging concepts that are needed to understand this example can be found in the SDK documentation and at Forum Nokia.

It is important to note that an MMS entry does not have a message body as the message text is sent as an attachment and therefore the Client MTM's Body() function should not be used. However, further information about the message text and attachments can be obtained through the message entry's store. The general procedure is to use CMsvStore::AttachmentManagerL() . The example below shows how the message text could be retrieved.

CMsvEntry* entry = iSession->GetEntryL(iNewMessageId);
CMsvStore* store = entry->ReadStoreL();
if(store!= NULL)
    MMsvAttachmentManager& attManager = store->AttachmentManagerL();
    _LIT8(KMimeBuf, "text/plain");
    // Cycle through the attachments
    for(TInt i=0; i<attManager.AttachmentCount(); i++)
        CMsvAttachment* attachment = attManager.GetAttachmentInfoL(i);
        // Test to see if we have a text file
        if(mimeBuf.CompareF(attachment->MimeType())== 0)
            RFile file = attManager.GetAttachmentFileL(i);
            // The file can then be read using the normal file functionality
            // After reading, the file should be closed

This aspect of message querying falls outside the scope of MMS Client MTM and therefore is not covered in detail here but is included for completeness.

2.9 Responding to (replying/forwarding) a received message

An obvious requirement of a messaging client is to be able to reply to or forward received messages. MMS Client MTM provides CMmsClientMtm::ReplyL() and CMmsClientMtm::ForwardL() for this purpose. Both functions are asynchronous and return a CMsvOperation pointer to allow the monitoring of the progress of the function and ultimately to provide the ID (TMsvId) of the newly created message.

To use the functions, the message to be replied to or forwarded must be set as the context. The functions take as parameters the ID ( TMsvId ) of the folder in which the new message should be created, a list ( TMsvPartList ) of the elements of the original message that should be copied to the new message, and a TRequestStatus reference. Note that not all elements of TMsvPartList are supported, see mmsclient.h for further information. An example of using CClientMtm::ReplyL() is shown here but CMmsClientMtm::ForwardL() can be used similarly.

void CMtmsExampleEngine::ReplyL()
    // Add the description of the received message to the new (reply) message
    // Note the Recipient address is automatically set to the sender
    // KMsvMessagePartRecipient is only needed for reply to all
    TMsvPartList msgCheckParts = KMsvMessagePartDescription;
    iOp = iMmsMtm->ReplyL(KMsvDraftEntryId,msgCheckParts,iStatus);

On completion ( RunL() being called), the ID of the newly created message is retrieved using CMsvOperation::Progress() . A package buffer is used to transfer this information. If the creation of the reply or forward message was not successful, the ID will be set to KMsvNullIndexEntryId . Once the operation has completed, the message can be modified and saved, or sent, using the usual functions.

void CMtmsExampleEngine::RunL()
    if(iStatus.Int() == KErrNone)
        // Retrieve the id of the created message
        // Id is returned in a package buffer
        TPckgBuf<TMsvId> pkg;
        pkg.Copy( iOp->ProgressL());
        TMsvId indexEntry = pkg();
        if(indexEntry != KMsvNullIndexEntryId)
            // Set the context to the new message
            // Here add further recipients, subject, attachments
            // to the message
            // Commit the changes and save the Message
            TMsvEntry ent = iMmsMtm->Entry().Entry();
            // Set InPreparation to false
            ent.SetVisible(ETrue);            // mark as visible
            iMmsMtm->Entry().ChangeL(ent);    // Commit changes
            //Save the changes

2.10 Cleaning up of resources

Once all of the required operations have been carried out, the appropriate destruction of resources should be carried out. Obviously the resources used are application specific, but in general at least Client MTM, the MTM registry and the session are required. They should be deleted in the reverse order in which they were created.

    // For this particular example cleanup
    Cancel();         // Active Object
    delete iOp;
    // For general use of the MMS Client MTM
    delete iMmsMtm;   // CMmsClientMtm
    delete iMtmReg;   // CClientMtmRegistry
    delete iSession;  // CMsvSession

2.11 Error handling

The leave mechanism of the Symbian platform is used to handle error conditions on method calls. In addition, messaging defines a series of panics; these are explained in Symbian OS reference » System panic reference » MSGS.

3 Glossary

3.1 Abbreviations

MMS Client MTM API abbreviations
ID Identifier
API Application Programming Interface.
MIME Multipurpose Internet Mail Extensions.
MMS Multimedia Messaging Service. Protocol defined by 3GPP. Messaging for

text, images, audio.

MTM Message Type Module. A group of components that together provide message

handling for a particular protocol.

SDK Software Development Kit.
SMIL Synchronized Multimedia Integration Language. A markup language designed

to present multiple media files together.

SMS Short Message System. A protocol, defined within the GSM standard,

which allows point-to-point transmission of short messages. 'Short' means 140 bytes, or 160 characters with the special 7-bit SMS character set. Can also be used to transmit up to 31k of binary or text data by concatenating messages.

UI User Interface.

4 References

Name Location
Synchronized Media Integration Language (SMIL) SDK documentation Forum Nokia