Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


How to use the CDMA SMS MTM

[Top]


Overview

The Short Messaging Service (SMS) provides short text messaging between mobile phones. Messages can be written and read by phone users, and can also be used as a medium for communicating between applications.

Symbian OS until v8.0 supplied functionality for SMS over GSM networks. v8.1 continues to support GSM, and adds support for SMS on CDMA2000 networks. The CDMA SMS standard, defined by the 3GPP2, in standard C.S0015-A, derived from the TIA/EIA standard, TIA/EIA-637-B, defines broadly similiar functionality to GSM, but has differences in architecture and in data structures.

This document concentrates on using SMS through messaging APIs in a CDMA context. It contains the following sections:

Further information

For information on related areas of Symbian OS, see:

For SMS standards, see:

[Top]


CDMA SMS overview

A CDMA SMS message belongs to one of three message definitions:

A point-to-point message can have a teleservice identifier to specify the application that should handle it. The standard defines the operation of six teleservices.

The Wireless Messaging Teleservice (WMT) is for short text messaging between users. The Wireless Enhanced Messaging Teleservice (WEMT) extends this to include EMS elements such as pictures. Outgoing messages of these two teleservices can be created. Incoming messages of these teleservices are stored in the message store.

Other teleservices defined are: IS-91 Extended Protocol Enhanced Services, Wireless Paging Teleservice (WPT), Voice Mail Notification (VMN), and Service Category Programming Teleservice (SCPT). Incoming WPT and VMN messages are stored in the message store.

The fields in a message depend on the teleservice being used, and the message type. The most important types are the Deliver type, which is used for a message sent to a phone, and the Submit type, which is used for a message sent from a phone. There are also the following types:

Incoming acknowledgement messages are handled automatically by messaging. The SMS MTM makes available APIs, described in Acknowledgements, that allow you to find what acknowledgements have been received in response to an outgoing message.

Not all teleservices use all message types: for example, WPT does not support message cancellation, so does not use the Cancellation message type.

Finally, you should be aware that fields are often optional, so even if a field is appropriate to the teleservice and the message type, it may not be present in a message. The CDMA SMS 3GPP2 standard supplies tables of which fields apply to which teleservices and message types.

[Top]


Architecture overview

The messaging SMS plug-in (MTM) integrates SMS into the messaging architecture, so that SMS can be used by a messaging client program in a similar way to other message types such as email and fax. The following diagram shows the key components and their relationships:

SMS MTM component     relationships


SMS MTM component relationships

Components supplied by SMS messaging are in blue; other significant components are in grey.

The SMS client MTM implements the messaging architecture's client MTM API to provide the interface for applications to handle SMS messages. It provides:

Note that UI functionality, such as SMS message viewing and editing, is not provided by Symbian OS, but the platform user interface.

The SMS server-side MTM implements the server-side MTM interface, and primarily provides functionality to handle requests from the client MTM to send SMS messages.

Incoming SMS messages are handled by a group of components called SMS watchers. For CDMA, each watcher handles a particular teleservice, respectively WMT, WPT, WEMT, and VMN. The watchers handle the four possible types of incoming SMS, i.e. the Deliver type, and the three possible acknowledgement types, Read, User, and Delivery. When a deliver type SMS is received for one of these teleservices, the watcher creates a new message entry in the Inbox. When an acknowledgement type SMS is found, the watcher finds the message that is being acknowledged, and updates its relevant acknowledgement fields to record that an acknowledgement has been received. The acknowledgement message itself is not stored in the message store.

These messaging components provide a layer over the SMS support provided in the narrow band protocols stack subsystem. This has SMS stacks for GSM and for CDMA, which offer an encapsulation of an SMS message, together with the ability to send and receive messages. At the lowest level, below the SMS stacks, is the ETel multimode API, which provides low-level access to the phone drivers.

So, for an incoming message, the usual route is:

For an outgoing message, the route is:

Configurability

The MTM source code has been designed to conditionally include or exclude functionality for GSM/CDMA according to whether certain macros are defined. The macros are:

Classes

The following diagram shows the key classes in the SMS client MTM:

SMS MTM class relationships


SMS MTM class relationships

Classes in the client MTM are in blue; significant classes from components other than the MTM are in grey.

The following table summarises the classes:

Class

Purpose

CSmsClientMtm

Implements the messaging architecture client MTM interface for SMS. It allows messages to be created, replied to, and forwarded, and MTM-specific commands to be given.

It provides an accessor function SmsHeader() to get the CSmsHeader for a message.

CSmsHeader

Encapsulates an SMS message in a message store.

It provides information about message recipients as an array of CSmsNumber objects, and access to the family of classes derived from TMsvMessageBio, which allow fields of a message to be set and accessed.

For compatibility with the API of the v8 (GSM only) SMS MTM, it also provides access to the GSM SMS stack's message class CSmsMessage.

TMsvMessageBio

Base class for a family of classes that provide access to message fields.

TMsvMessageSms

Provides access to message fields that are compatible with both GSM and CDMA.

TMsvMessageGsm

Provides access to GSM-specific fields.

TMsvMessageCdma

Provides access to CDMA-specific fields.

TMsvSmsEntry

Provides a specialisation of the message server index class TMsvEntry for SMS message entries.

Putting selected SMS-specific fields in the index entry allows message clients to quickly get important message properties without having to create a message object.

CSmsNumber

Encapsulates recipient information for an SMS message.

CSmsSettings

Defines settings for the SMS service.

It contains some GSM-specific functions to maintain compability with the GSM SMS MTM.

It also provides access to CSmsMessageSettingsProxy for outgoing message defaults.

CSmsMessageSettings

This is now deprecated and kept for backward compatibility.

CSmsMessageSettingsProxy

Provides defaults for outgoing messages, both GSM and CDMA.

It also provides access to an additional object for CDMA-specific settings, TSmsMessageSettingsCdma.

TSmsMessageSettingsCdma

Defines CDMA-specific settings for outgoing messages.

[Top]


Project files

Clients of the API should specify the following in their project files:

[Top]


Client MTM operations

The SMS client MTM provides an API that allows applications to create and send SMS messages, and to access the properties and fields of a message. This section discusses these tasks:

See Using Messaging for general background information on the messaging APIs if you are not already familiar with them.


Getting a client MTM object

The messaging framework is based around a server program, to which a connection (a session) must be made before anything else with messaging can be done. The session class is called CMsvSession, and message client applications typically create an instance of this class upon start-up.

// Create message server session
iMsvSession = CMsvSession::OpenSyncL(*this);

The OpenSyncL() method takes a parameter of type MMsvSessionObserver, so, for this code to work, the containing class must implement this observer interface. It enables the server to call the client to inform it of significant events, such as new MTMs being registered.

An application should then get an CSmsClientMtm object. This cannot be created directly: instead, an application must ask the message server to create the object for it. A record of all the MTM components installed on a machine is held in a dedicated registry file managed by the message server. Registry classes use this registration data to allow MTM components to be identified and instantiated.

To get a SMS client MTM object, use CClientMtmRegistry as follows:

// Create client registry object
iClientMtmRegistry = CClientMtmRegistry::NewL(*iMsvSession);
// Request SMS client MTM object
iSmsClientMtm = (CSmsClientMtm *)iClientMtmRegistry->NewMtmL(KUidMsgTypeSMS);

The registry NewMtmL() function returns a pointer to the client MTM base class, CBaseMtm, so it needs to be cast to the SMS client class, CSmsClientMtm.

Each MTM type is identified by a UID, which is used to specify the MTM in the NewMtmL() call. For SMS, this UID is KUidMsgTypeSMS.


Message creation

There are several ways to create new messages:

These are explained in more detail below.

Creation with CreateMessageL()

A client MTM has the concept of a current entry, or context, on which operations, such as message creation, take place. A new outgoing message should be created in the Outbox folder, so this current entry needs to be set to that folder. The identifier for the Outbox folder is published in the API, and is KMsvGlobalOutBoxIndexEntryId. The following call sets the current entry to this folder, and then creates a new SMS message:

// Set context to Outbox folder
iSmsClientMtm->SwitchCurrentEntryL(KMsvGlobalOutBoxIndexEntryId);
// Create new message entry
iSmsClientMtm->CreateMessageL(0);

CreateMessageL() is a virtual function that is specified by the base class CBaseMtm to take a parameter for the message ID of the service that should own the entry. However, this parameter is not used in the SMS MTM implementation: instead, the MTM assumes that a single SMS service exists and that this service should be used.

The teleservice to which outgoing message belong is set at the service level (CSmsSettings::DefaultTeleservice()).

Creation using CMsvEntry

To create a message other than the Submit type, or for a teleservice other than the default, you need to create and initalise a message entry using CMsvEntry. Typical steps are:

  1. Set up an TMsvEntry index entry for the new entry. The entry is made invisible and in preparation.

        // set up index entry
     TMsvEntry newEntry;
        newEntry.iType = KUidMsvMessageEntry;
        newEntry.iServiceId = KMsvLocalServiceIndexEntryId;
        newEntry.iMtm = KUidMsgTypeSMS;
        newEntry.SetVisible(EFalse);
        newEntry.SetInPreparation(ETrue);           
  2. Create a new empty message. The following creates an entry in the outbox:

        // create empty message in outbox
        CMsvEntry* entry = iMsvSession->GetEntryL(KMsvGlobalOutBoxIndexEntryId);
        CleanupStack::PushL(entry);
        entry->CreateL(newEntry);
        iMsvSession->CleanupEntryPushL(newEntry.Id());
        // switch to created entry
        entry->SetEntryL(newEntry.Id());
  3. Create a CSmsHeader object, configure it, and store it in the entry's message store. There are a number of overloads for CSmsHeader::NewL(). For outgoing CDMA messages, use:

    static CSmsHeader* NewL(TSmsMessageType aType, CEditableText& aText);

    or

    static CSmsHeader* NewL(TSmsMessageType aType, CEditableText& aText, tia637::TTeleserviceId aTeleservice);

    aType specifies the type: e.g. KSmsTypeCdmaUserACK for a user acknowledgement; aText is the message text; and aTeleservice specifies the teleservice identifier, defined in the CDMA SMS stack header tia637.h. The following example:

    • creates a rich text object for the message text

    • creates a CSmsHeader object for a Submit message for the WEMT teleservice. It calls SetDefaultMessageSettingsL() to apply the default settings stored by the SMS service.

    • opens the entry's message store, and commits the header object to it.

        // create a rich text body
        CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL();
        CleanupStack::PushL(paraFormatLayer);
        CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL();
        CleanupStack::PushL(charFormatLayer);
        CRichText* richText = CRichText::NewL(paraFormatLayer,charFormatLayer);
        CleanupStack::PushL(richText);  
        // ... can set message text in richText now

        // create the header object
        CSmsHeader* smsHeader = CSmsHeader::NewL(KSmsTypeSubmit, *richText, tia637::KTeleserviceWEMT);
        CleanupStack::PushL(smsHeader);
        smsHeader->SetDefaultMessageSettingsL(aServiceSettings);
        // .. configure further as required

        // set the message header in the entry's store
        CMsvStore* store = entry->EditStoreL();
        CleanupStack::PushL(store);
        smsHeader->StoreL(*store);
        store->StoreBodyTextL(*richText);            
        store->CommitL();
        CleanupStack::PopAndDestroy(5);

The next two sections describe what more needs to be done to create acknowledgement and cancellation messages.

Creating read and user acknowledgement messages

Incoming CDMA SMS messages can request that user or read acknowledgement messages are sent in response. A messaging application may need to create such messages, for example, when a message is read for the first time. Note that these acknowledgements are specific to CDMA, and are not supported in GSM SMS.

To create an acknowledgement message:

  1. Test if the received message requests a user or read acknowledgement (the third type of acknowledgement, delivery acknowledgement, is handled by the service center.)

    To do this, load the received message, and get its CSmsHeader object.

    mtm->LoadMessageL();
    CSmsHeader& smsHdrRecv = static_cast<CSmsClientMtm*>(iMtm)->SmsHeader();

    You can then test if the received message requests an acknowledgement using CSmsHeader::AcknowledgementRequested(), i.e.:

    TBool ackRequest = smsHdrRecv.AcknowledgementRequested(ESmsAckTypeUser);

    or

    TBool ackRequest = smsHdrRecv.AcknowledgementRequested(ESmsAckTypeRead);
  2. If an acknowledgement is requested, the next step is to get information from the received message that will be needed to create the acknowledgement message.

    First, get the received message's teleservice. This can be read from the message's properties accessible through TMsvMessageCdma:

    TMsvMessageCdma& msgCdma = smsHdrRecv.CdmaMessage();
    tia637::TTeleserviceId tid = msgCdma.TeleserviceId();

    Second, get the received message's originating address:

    TPtrC originatingAddress = msgCdma.OriginatingAddress();

    (OriginatingAddress() is from TMsvMessageBio, which is a base class for TMsvMessageCdma).

    Third, get the received message's message identifier. This identifier is a CDMA SMS message property that allows a sent message to be referred to. An acknowledgement message uses the same identifier to indicate which message is being acknowledged. The identifier is stored in the message entry fields that are accessible through TMsvSmsEntry:

    TMsvSmsEntry entryRecv = (TMsvSmsEntry)(iMtm->Entry().Entry());
    TInt32 incomingId = 0;
    entryRecv.MessageId(incomingId);
  3. An acknowledgement message can now be created with CMsvEntry using the procedure described above, with the following adjustments:

    • The CSmsHeader for the new message should have the message type set to either KSmsTypeCdmaUserACK or KSmsTypeCdmaReadACK depending on the acknowledgement requested, and the teleservice be set to that of the received message:

          // create the header object
          CSmsHeader* smsHeader = CSmsHeader::NewL(KSmsTypeCdmaReadACK, *richText, tid);
    • The destination address of the message should be set to the orginating address of the received message, and its message identifier to that of the received message:

          //  Set destination address
          CSmsNumber* smsNumber = CSmsNumber::NewL();
          CleanupStack::PushL(smsNumber);
          smsNumber->SetAddressL(originatingAddress, EMsvAddressTypeISDN);

          //  Set message identifier
          TSmsMessageIdentifier outgoingId = incomingId;
          smsNumber->SetMessageId(outgoingId);

          // Add recipient
          smsHdr->Recipients().AppendL(smsNumber);
          CleanupStack::Pop(smsNumber); // deleted by CSmsHeader

Creating cancellation messages

A cancellation message is used to cancel a message that has been sent. A cancellation message can be created with CMsvEntry using the procedure described above, with the following adjustments:

    // Get the recipients of the message to cancel
    // where messageToCancelId is the TMsvID of that message
    iMtm->SwitchCurrentEntryL(messageToCancelId);
    CMsvStore* currStore = iMtm->Entry().ReadStoreL();
    CleanupStack::PushL(currStore);
    CSmsHeader* currMsg = CSmsHeader::RestoreL(*currStore, rtBody->RichText());
    CleanupStack::PopAndDestroy(currStore);
    CleanupStack::PushL(currMsg);
    CArrayPtrFlat<CSmsNumber>& currNumbers = currMsg->Recipients();
    // Get the message's teleservice
    tia637::TTeleserviceId teleservice = currMsg->CdmaMessage().TeleserviceId();
    
    // create the new message
    CSmsHeader* smsHdr = CSmsHeader::NewL(KSmsTypeCdmaCancellation, *richText, teleservice);
    CleanupStack::PushL(smsHdr);
    // set its recipients
    for (TInt i = 0; i < currNumbers.Count(); i++)
        {
        CSmsNumber* smsNumber = CSmsNumber::NewL(*(currNumbers[i]));
        CleanupStack::PushL(smsNumber);
        smsHdr->Recipients().AppendL(smsNumber);
        CleanupStack::Pop(smsNumber); // CSmsHeader will delete it
        }
    CleanupStack::Pop(smsHdr);
    CleanupStack::PopAndDestroy(currMsg);

    CleanupStack::PushL(smsHdr);
    // set anything further in CSmsHeader...
    CleanupStack::PopAndDestroy(smsHdr);

Forward/reply messages

You can also create new messages by forwarding or replying to an existing SMS message, through CSmsClientMtm::ForwardL() and CSmsClientMtm::ReplyL() respectively. In these cases, the new message is created for you, with the appropriate content copied into it from the original message.


Message body

The message text can be set and accessed as a rich text object (CRichText) through Body(). For example, the following sets the body text to be "some message text":

_LIT(KText,"some message text");
CRichText& body = iMtm->Body();
body.InsertL(0,KText);

Note that:


Message addressing

Every outgoing message must be addressed to a recipient. Although the SMS protocol does not allow a message to be addressed to more than one recipient, the SMS MTM does allow this. When a SMS message entry with more than one recipient is sent, the server MTM creates and sends a separate SMS message for each recipient.

The simplest way to add an address is to use CBaseMtm::AddAddresseeL().

iMtm->AddAddresseeL(address);

An array of recipients for the current message can be obtained from the SMS header object, CSmsHeader. Each object in the array is a CSmsNumber. In addition to the address, this class holds:

The following code shows creating an address using CSmsNumber, and adding it to the recipient array:

_LIT(KAddress,"0123456789");
CSmsHeader& header = iMtm->SmsHeader();
CArrayPtrFlat<CSmsNumber>& recips = header.Recipients();
CSmsNumber* newRecip = CSmsNumber::NewL();
CleanupStack::PushL(newRecip);
newRecip->SetAddressL(KAddress, EMsvAddressTypeISDN);
recips.AppendL(newRecip);
CleanupStack::Pop(newRecip); //CSmsHeader will delete it    

ISDN addresses both have maximum lengths that are set as part of the phone's provisioned settings (see Over-The-Air settings). If the maximum length is exceeded, the error behaviour differs depending on whether the MTM was compiled with GSM_COMPATIBILITY MODE: if it was, ISDN addresses gets trimmed down to the maximum length; if not, the function leaves with KErrTooBig.


Message fields

In addition to a message body and address, a message can have various other fields, such as priority level, privacy setting, and delivery time information. Fields can typically be set on outgoing messages, and read from incoming messages.

Which fields are available depends on whether GSM or CDMA is being used. Fields common to both are accessible through TMsvMessageBio and its derived class TMsvMessageSms. This can be got as follows:

TMsvMessageSms& fields = iMtm->SmsHeader().SmsMessage();

Common GSM/CDMA message fields describes these fields in detail.

CDMA specific fields are accessible through TMsvMessageCdma, which derives from TMsvMessageSms. It can be got as follows:

TMsvMessageCdma& CDMAFields = iMtm->SmsHeader().CdmaMessage();

CDMA-specific message fields describes these message fields in detail.

Be careful about the lifetime of the returned references to TMsvMessageSms or TMsvMessageCdma objects. If a message's CSmsHeader object is deleted, then these references will become invalid, and using them will cause an undefined error (such as a KERN-EXEC 3 panic).

Various fields are set to default values when a new message is created. The defaults are set in the service settings.


Message sending

Once a message has been set up, it can be sent by copying the message to the SMS service. This can be done using CMsvEntry::CopyL(). The following copies the MTM's current entry, whose ID is obtained using iSmsClientMtm->Entry().EntryId(), to the service, whose ID can be got from the MTM using ServiceId().

iSendOperation = ent->CopyL(iSmsClientMtm->Entry().EntryId(), iSmsClientMtm->ServiceId(), iStatus);

The function is asynchronous, and so takes a TRequestStatus parameter, usually of an active object in your program whose RunL() is called when the operation is complete.

The function returns a CMsvOperation object, which can be used to monitor the sending progress (TSmsProgress) and to obtain any error information.

Progress information includes fields for the total number of messages being handled by the operation, and the number of messages processed so far; as each message is processed, it also updates fields for the total number of recipients of the message, and the number of recipients processed so far.

Final progess information can be obtained when an operation has completed. For example, the following gets the final progress information after a send operation, and displays the number of messages sent out of the total attempted, and the error if any was reported.

    // get progress information after send operation completes
    TSmsProgressBuf progressBuf;
    progressBuf.Copy(iSendOperation -> FinalProgress());
    TSmsProgress progress = progressBuf();

    TBuf<40> msg1;
    TBuf<20> msg2;
    msg1.Format(_L("\nSent %d of %d messages"),progress.iMsgDone, progress.iMsgCount);
    if (progress.iError) msg2.Format(_L("Error: %d"), progress.iError);
    CEikonEnv::Static()->AlertWin(msg1, msg2);

Scheduled sending and resending

The SMS MTM has the ability to:

The sections below describe each of these.

Sending at a specified later time

To set a message to be sent at a specified later time:

  1. set the time to send in the message's TMsvEntry::iDate

  2. create a selection (CMsvEntrySelection) with the message(s) to send. Every message in the selection must have the same scheduled time.

  3. call CSmsClientMtm::InvokeAsyncFunctionL() with command ID ESmsMtmCommandScheduleCopy

The following schedules a message with ID aID:

    CMsvEntrySelection* smsEntries = new (ELeave) CMsvEntrySelection;
    CleanupStack::PushL(smsEntries);
    smsEntries->AppendL(aId);
    TBuf8<1> p;
    CMsvOperation* op = iMtm->InvokeAsyncFunctionL(ESmsMtmCommandScheduleCopy,
        *smsEntries, p, status);
    CleanupStack::PopAndDestroy(); //smsEntries

Note that:

Messages can be removed from the scheduler with the asynchronous function ID ESmsMtmCommandDeleteSchedule.

Specifying sending conditions

When preparing to start sending SMS messages. the SMS server MTM checks that any specified send conditions are met. The send conditions are defined using a set of conditions (TMsvSysAgentConditionAction objects). The conditions are held in a CMsvSysAgentActions object, which is stored in the SMS service entry. By default, there are no send conditions specified. If none have been specified, then the conditions are considered to have been met.

A TMsvSysAgentConditionAction contains:

The following example shows a condition being set. The condition is met if the KUidNetworkStatus variable is equal to ESANetworkAvailable. If the condition is not met, the action is to retry the send after a long interval, and to keep trying until the send is successful.

CMsvSysAgentActions* actions = new (ELeave) CMsvSysAgentActions();
CleanupStack::PushL(actions);
actions->iDefault.iAction = ESendActionRetryLater;
actions->iDefault.iRetries = ESendRetriesInfinite;

TMsvSysAgentConditionAction action;
action.iCondition.iVariable = KUidNetworkStatus;
action.iCondition.iState = ESANetworkAvailable;
action.iCondition.iType = TMsvCondition::EMsvSchSendEquals;
actions->AppendL(action);

// Store the actions in the SMS service entry
CMsvEntry* service = Session().GetEntryL(aServiceId);
CleanupStack::PushL(service);
CMsvStore* msvstore = service->EditStoreL();
CleanupStack::PushL(msvstore);
actions->StoreL(*msvstore);
msvstore->CommitL();

CleanupStack::PopAndDestroy(3, actions);

Resend on errors or failed conditions

A message can be rescheduled at two stages of sending:

Note that there are two addtional factors that can prevent rescheduling occurring:


R-UIM/phone store commands

The SMS MTM provides InvokeAsyncFunctionL() commands to copy and move messages between the message server store and either the phone's R-UIM (Removable User Identity Module), or built-in memory (referred to as the phone store).

Getting messages from a R-UIM/phone store is a two stage process. First, you need to use the command ESmsMtmCommandEnumeratePhoneStores. This reads the SMS messages on the R-UIM or phone store, and creates a copy of those messages in an invisible folder in the message store. You can specify whether to read from the R-UIM or phone store (the enum TMsvSmsStorage gives flags for each), and the target folder in the message store. These parameters are passed to InvokeAsyncFunctionL() in a packaged TMsvSmsSimOperationParams object.

Once enumeration has taken place, further InvokeAsyncFunctionL() commands can be used to:

Copying or moving messages in the other direction is simpler: to do this, use the InvokeAsyncFunctionL() commands ESmsMtmCommandCopyToPhoneStore or ESmsMtmCommandMoveToPhoneStore.

[Top]


TMsvEntry settings

Each SMS message has an message store index entry that can be accessed through TMsvEntry. The index entry allows an application quick access to important properties of the message.

The table below describe the functions and member variables for TMsvEntry that are set by the SMS MTM for an SMS message:

TMsvEntry member

Description

Attachment()

Not used by SMS MTM

Complete()

Not used by SMS MTM

Connected()

Normally set to EFalse.

This flag is set to ETrue while the message is being sent to indicate to clients that the message is currently in transit and hence should not be opened at this time. The flag is set to EFalse once the attempt to send the message has been completed. Any changes made to the message while the Connected() flag is set to ETrue will be ignored by the SMS MTM, i.e. the original message will be sent even if the contents of the message have subsequently been altered by a client.

Description()

For normal (i.e. non-BIO) SMS text messages, this is the beginning of the text message, discarding any leading white space characters. The maximum length of the description can be got from CSmsSettings::DescriptionLength().

For BIO message (iBioUid has been set), a human-readable description of the BIO message type contained within the message (e.g. “VCard”).

Details()

The full telephone “address” of the first name in the list of recipients.

This may either be a telephone number, or it may be the contact name of the recipient, if that recipient appears in the Symbian OS contact database.

Failed()

If the MTM is unable to send a message, then the Failed() flag is set on that message.

If there is more than one recipient of the message, the flag will be set if the message fails to be sent to any of the recipients.

The Failed() flag will be set only if the message has not been rescheduled for another attempt to send that message.

If the flag has been set, the iError member variable of the message entry contains the error code that describes that failure.

Note that successfully sending an SMS message to the message/service centre does not mean that the message is guaranteed to be delivered to the recipient(s).

iBioUid

Specifies or identifies the type of the BIO message.

If iBioUid==0, then the message will be treated as a normal SMS text message.

When iBioUid>0, the UID identifies what type of BIO message the SMS message contains. The mapping between the BIO UID and the BIO message type is made using the BIO message database.

In outgoing SMS messages, if iBioUid>0, then the preferred transport method specified in the BIO database will be used to send that message.

iDate

The time and date the message was originally created.

After an attempt has been made to send the message, iDate will be set to the home time to indicate when that attempt was made. If the message is to be scheduled, then iDate is the time the message should be sent.

iError

Any error code which occurred when an attempt was made to send the message (normally KErrNone), and Delivery Acknowledgement errors.

iMtm

The MTM type, which is always KUidMsgTypeSMS.

iMtmData1

Reserved.

iMtmData2

Reserved

iMtmData3

Reserved

InPreparation()

This is set to true when a new outgoing message is created. The application should set the flag to false when it has finished creating the message.

This is also set to true when a watcher creates a new incoming message; it is set to false when creation is complete.

iRelatedId

Not used by SMS MTM.

iServiceId

Identifies the SMS service that created the message.

There is normally only one SMS service in the message store.

iSize

Size, in bytes, of the message.

iType

Set to KUidMsvMessageEntry.

MultipleRecipients()

Not used by SMS MTM.

New()

Not used by SMS MTM.

OffPeak()

Not used by SMS MTM.

Operation()

Not used by SMS MTM.

PcSyncCount()

Not used by SMS MTM.

Priority()

Not used by SMS MTM.

ReadOnly()

This is set to true by the watcher for incoming SMS messages.

Scheduled()

Set to ETrue by the server MTM if the message has been added to the task scheduler for automated scheduled sending.

SendingState()

The sending status of the message.

The value of this status will depend upon whether the message has been scheduled to be sent using the task scheduler. The states are defined by TMsvSendState.

StandardFolder()

Not used by SMS MTM.

Unread()

When new SMS messages have been received by the SMS watcher, the Unread() flag on that message is set to ETrue.

It is the responsibility of the reading client to reset the flag once it has been read/processed.

Visible()

This is set to false when a new outgoing message is created. The application should set the flag to true when it has finished creating the message.

The TMsvSmsEntry class provides a specialisation of the message server index class for SMS message entries. Acknowledgements below discusses how this can be used to retrieve acknowledgement summaries.

[Top]


SMS services

An SMS service entry holds two types of information:

A SMS service is stored as a message entry with the following characteristics:

The following code shows how a service that meets the above criteria would be created:

CMsvEntry* entry = iMsvSession->GetEntryL(KMsvRootIndexEntryId);          
CleanupStack::PushL(entry);
// set message index entry
TMsvEntry s;
s.iMtm = KUidMsgTypeSMS;
s.iType = KUidMsvServiceEntry;
s.SetVisible(EFalse);
// create new message entry 
entry->CreateL(s);
entry->SetEntryL(s.Id());
// open store for entry
CMsvStore* store = entry->EditStoreL();
CleanupStack::PushL(store);
// create new settings object
CSmsSettings* set = CSmsSettings::NewL();
CleanupStack::PushL(set);       
// .. make settings as needed here
// save settings in store, and commit store
set -> StoreL(*store);
store -> CommitL();
CleanupStack::PopAndDestroy(3);

Typically, a phone will have just one SMS service defined. When an SMS client MTM object is created, it finds this service and loads the settings from it.

A client can then access the CSmsSettings object using CSmsClientMtm::ServiceSettings().

The ID of the service entry being used can be got with CSmsClientMtm::ServiceId().


Service settings

General settings for sending and retrieving SMS messages can be manipulated using the member functions of CSmsSettings. These are as follows:

GSM specific settings

The following service settings are kept for compatibility with the GSM MTM, but have no use in CDMA:


Message settings

Default settings applied to new outgoing messages can be obtained through CSmsSettings:

Common message settings

The common message settings accessible through CSmsMessageSettingsProxy are as follows:

CDMA-specific message settings

The CDMA-specific message settings in TSmsMessageSettingsCdma are as follows:

The IsMessageSettingActive()/ActivateMessageSetting() functions controls whether a particular message setting is applied or not when a new message is created.

[Top]


Over-The-Air settings

Each phone on a CDMA network has OTA (Over-The-Air) settings that control the phone's behaviour. They are called OTA because the CDMA network can transmit new values for each setting at any time. You can think of them as the network's rules that govern how your phone should act.

Symbian OS's CDMA implementation monitors these settings and makes sure that your phone does not break any rules. Hence it is not essential that your code reads these settings. However, you may read them if you wish.

A number of these settings are relevant to the SMS client MTM. They are:

Reading settings from your code explains how to read these settings. This is part of the Over-The-Air Settings Guide for CDMA Networks. You should never change any settings - only the network is allowed to do this.

[Top]


Acknowledgements

The sender of an CDMA SMS message can request acknowledgement of the message. There are three acknowledgement types:

The default reply options for new messages are set from the current message settings (CSmsMessageSettingsProxy::SetReplyOptions()). Per message settings can be made using CSmsHeader::SetAcknowledgementRequest().

When an acknowledgement is received, the relevant watcher processes it, and updates acknowledgement fields on the sent message.

After the message has been sent, you can query the message to find what acknowledgements have been received. You can get details of the acknowledgements for each message recipient, and a summary of the acknowledgements received for all recipients.

Getting recipient acknowledgement information

Per recipient information is available through the CSmsNumber object for the recipient. The following code starts a loop through a message's recipients and gets the status of the delivery acknowledgement by calling CSmsNumber::AckStatus(ESmsAckTypeDelivery):

const CArrayPtrFlat <CSmsNumber> & recipArray = iMtm->SmsHeader().Recipients();
for (TInt i=0; i<recipArray.Count(); i++)
    {
    TPtrC address = recipArray[i]->Address();
    CSmsNumber::TSmsAckStatus ackStatus = recipArray[i]->AckStatus(ESmsAckTypeDelivery);
    // do something with ackStatus
    }

The returned CSmsNumber::TSmsAckStatus indicates whether the acknowledgement has been received (indicating a success or failure) or not. The following prints a message for each of the possible values:

switch (ackStatus)
    {
case CSmsNumber::EPendingAck:
    iConsole.Printf(_L("The delivery status for this recipient has been requested, but the status report has not yet been received."));
    break; 
case CSmsNumber::EAckSuccessful:
    iConsole.Printf(_L("A successful acknowledgement for this recipient has been received."));
    break;
case CSmsNumber::EAckError:
    iConsole.Printf(_L("A failed acknowledgement for this recipient has been received."));
    break;
case CSmsNumber::ENoAckRequested:
    iConsole.Printf(_L("An acknowledgement for this recipient has not been requested."));
    break;
default:
    break;
    };

The status of the user acknowledgement can also be got by using AckStatus(ESmsAckTypeUser). A user acknowledgement contains a response code [C.S0015-A 4.5.3] that can be got using UserAck():

ackStatus = recipArray[i]->AckStatus(ESmsAckTypeUser);
if (ackStatus == CSmsNumber::EAckSuccessful)
    {
    TUint8 userAck = recipArray[i]->UserAck();
    iConsole.Printf(_L("\n\tResponse code: %u"), userAck);      
    }

The status of the read acknowledgement can be got using AckStatus(ESmsAckTypeRead). There is no further information relating to read acknowledgements.

Getting summary acknowledgement information

A summary of the acknowledgements received can be got from the index entry for the sent message, using TMsvSmsEntry::AckSummary(). The returned TMsvSmsEntry::TMsvSmsEntryAckSummary indicates if the message is expecting acknowledgments, has received all expected acknowledgements, or has no acknowledgement information.

For example, the following code tests if the message has been delivered successfully to all recipients:

TMsvSmsEntry entry = static_cast<TMsvSmsEntry>(iMtm->Entry().Entry());
TMsvSmsEntry::TMsvSmsEntryAckSummary summary = entry.AckSummary(ESmsAckTypeDelivery);
if (summary == TMsvSmsEntry::EAllSuccessful)
    iConsole.Printf(_L("\nMessage was successfully delivered to all recipients"));

[Top]


Incoming messages

Messaging receives SMS messages via a number of watcher components that listen to the CDMA stack for incoming messages that belong to particular teleservices (WMT, WEMT, VMN, WPT). When an incoming message belonging to one of these teleservices is received, its contents are read, and a new entry for the message is created in the message server's store (in the global inbox folder). The usual case is that these messages will then be read by the user through the email application, but other messaging clients can receive notifications when a new message is created in the store, and process the message if appropriate.

To receive such notifications, a class must implement the session observer interface MMsvSessionObserver. The interface has just one function:

void HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3)=0;

When a new message is created in the store, the framework calls this function with aEvent set to EMsvEntriesCreated, and aArg1 is set to a CMsvEntrySelection* that specifies the IDs of the entries that have been created. The following checks the event type, and gets the entry ID selection:

void CClientApp::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* , TAny* )
    {
    CMsvEntrySelection* entries = NULL;

    switch (aEvent)
        {
        case EMsvEntriesCreated:
            entries = static_cast<CMsvEntrySelection*>(aArg1);
            break;
        default:
            break;
        }

The observer will receive notifications for all types of entry, not just SMS, so it's necessary to read the message properties to check that the entry is appropriate to process.

The following code does the first stage in this checking. It:

if (entries)
    {
    TInt count = entries->Count();

    // check each entry to see if we want to process it
    while (count--)
        {
        // get the index entry
        TMsvId serviceId;
        TMsvEntry entry;
        iMtm->Session().GetEntry((*entries)[count], serviceId, entry);
        // if the entry is an SMS message
        if (entry.iMtm == KUidMsgTypeSMS && entry.iType == KUidMsvMessageEntry
            // and if it's an incoming message (as its in the inbox)
            && entry.Parent() == KMsvGlobalInBoxIndexEntryId)

An application can now perform further checks, e.g. for particular message content. For example, the following code:

iMtm->SwitchCurrentEntryL((*entries)[count]);
iMtm->LoadMessageL();
TBool match = ETrue;
// Check the message body against any specified match text     
if (iMatchText.Length())
    {
    CRichText& body = iMtm->Body();
    TPtrC text(body.Read(0, iMatchText.Length()));
    match = (text.Compare(iMatchText) == 0); 
    }

// Check the message teleservice against the match teleservice
if (iMatchTeleservice)
    {
    match &= (iMtm->SmsHeader().CdmaMessage().TeleserviceId() == iMatchTeleservice);
    }

If you determine that your application should process the message, you can prevent the user from seeing the message in the Inbox of the standard messaging application. To do this, you can set the message entry's visible flag to false, using TMsvEntry::SetVisible(EFalse). You should delete the message (as the user will not be able to do so) once its processing is complete.

[Top]


Common GSM/CDMA message fields

Common GSM and CDMA message fields are accessed through the TMsvMessageSms class and its base class TMsvMessageBio.

Use CSmsHeader::SmsMessage() to get a TMsvMessageSms object:

TMsvMessageSms& fields = iMtm->SmsHeader().SmsMessage();

The fields include:

Functions to manipulate the EMS Information Elements in a message are also provided by this class: see EMS.


Originating address

The Originating Address is a mandatory parameter on all point-to-point SMS messages.

It does not need to be set on outgoing messages, as the address of the originating phone is set by default.

For incoming messages, the parameter can be got as follows:

TPtrC originatingAddress = fields.OriginatingAddress();

When a reply message is created using CSmsClientMtm::ReplyL(), the reply address is set to this value unless a CDMA call-back number (see below) has been specified.


Message Service Center Time Stamp

Delivered messages can include a Message Center Time Stamp that gives the time that the message was accepted by the destination message center.

The following gets the time stamp. The time is expressed as the message center's local time plus the difference between the message center's time zone and Coordinated Universal Time (UTC) in quarter of hours.

TDateTime timeStamp;
TInt quarterHourUTCOffset;
User::LeaveIfError(iFields->GetMessageServiceCenterTimeStamp(timeStamp,quarterHourUTCOffset));

Validity period

The message validity period sets a time after which the message center should discard the message if it has not been delivered to the destination. The time can be expressed either as an absolute value or relative to the time the message is received by the message center.

An absolute time is represented using the standard Symbian OS type TDateTime. The following sets the message validity period to 10:30am on 2004/01/01:

TDateTime time(2004,EJanuary,01,10,30,0,0);
iFields->SetValidityPeriodAbsoluteL(time);

A relative time can be expressed in one of a number of units [C.S0015-A Table 4.5.6-1], such as days or weeks. Flags for these unit types are given in the enum TSmsRelativeTimeUnit. The following sets a relativity validity period of 1 day:

TSmsRelativeTimeUnit timeUnit=ETimeUnitDays;
TUint32 relativeTime=1;
iFields->SetValidityPeriodRelativeL(timeUnit, relativeTime);

The validity period can be got and set only on outgoing messages (as incoming messages must either be valid or will have been discarded by the message center).

[Top]


CDMA-specific message fields

CDMA-specific message fields are held in a TMsvMessageCdma object, which can be obtained using CSmsHeader::CdmaMessage().

In the following example, CDMAFields is an TMsvMessageCdma reference.

TMsvMessageCdma& CDMAFields = iMtm->SmsHeader().CdmaMessage();

The fields are:


Teleservice

SMS messages received in the messaging inbox belong to one of the teleservices WMT, WEMT, VMN, or WPT. You can find which one using TeleserviceId():

tia637::TTeleserviceId teleserviceId = CDMAFields.TeleserviceId();

tia637::TTeleserviceId is an integer type; constants to identify each teleservice are defined in the tia637 namespace.

There is no corresponding function to set the teleservice.


Originating Subaddress

As well as an originating address, a message can have an originating subaddress. The originating subaddress can be got for incoming messages as follows:

HBufC* originatingSubAddress = fields.GetOriginatingSubAddressL();

Note that ownership of the returned HBufC* is passed to the caller.


Deferred Delivery Time

The deferred delivery time sets a time at which the message center should deliver the message. Similiarly to the validity period field, this can be got and set on outgoing messages, and can be specified either as an absolute time or relative to when the message is received by the message center.

The setter functions are SetDeferredDeliveryTimeAbsoluteL() and SetValidityPeriodRelativeL(). The following sets the desired delivery time to be 09:30 am on 2004/03/02:

TDateTime time(2004,EMarch,02,09,30,0,0);
CDMAFields.SetDeferredDeliveryTimeAbsoluteL(time);

The getter functions are GetDeferredDeliveryTimeAbsoluteL() and GetDeferredDeliveryTimeRelativeL(). The following tests if the format is relative, and if so, gets the relative time:

    TSmsTimePeriodFormat deliveryTimeFormat = CDMAFields.DeliveryTimeFormat();
    if (deliveryTimeFormat == ESmsTimePeriodRelative)
        {
        // Relative format
        TSmsRelativeTimeUnit timeUnit;
        TUint32 relativeTime;
        CDMAFields.GetDeferredDeliveryTimeRelativeL(timeUnit, relativeTime);

Note the difference with the scheduled sending functionality, which controls when the message is sent from the phone to the message center.


Number of Messages

The Number of Messages is a decimal number with range (0 to 99) representing the number of messages stored at the Voice Mail System.

To get the number of messages, use GetNumberOfMessages(). It is set only by the Voice Mail Notification service.


Priority

A message can have one of four priority levels, from Normal to Emergency [C.S0015-A 4.5.9-1].

The priority level does not alter the phone's handling of the message, but can be used at application level, for example to highlight urgent messages for the user's attention.

The level can be got and set on outgoing messages, and got on incoming messages. The priority levels are specified by constants in the tia637 namespace. The following sets the priority level to urgent.

tia637::TPriorityIndicator priority = tia637::KBdUrgent;
CDMAFields.SetPriorityIndicatorL(priority);

A default priority level for new messages is set from the current default message settings.


Privacy

A message can have one of four privacy levels: Unrestricted, Restricted, Confidential, and Secret.

The privacy level does not alter the phone's handling of the message, and can be used at application level for any suitable purpose.

The level can be got and set on outgoing messages, and got on incoming messages. The privacy levels are specified by constants in the tia637 namespace. The following sets the privacy level to confidential.

tia637::TPrivacy privacy = tia637::KBdConfidential;
CDMAFields.SetPrivacyIndicatorL(privacy);

A default privacy level for new messages is set from the current default message settings.


Callback Number

The callback number sets the number to be dialled in reply to a received SMS message. This does not need to be set by the application unless the number is different from the number of the sending phone.

The callback number can be got and set on outgoing messages, and got on incoming messages. It is passed as a descriptor.

CDMAFields.SetCallbackNumberL(iInput);

A default callback number for new messages is set from the current default message settings.

When a reply message is created using CSmsClientMtm::ReplyL(), the reply address is set to this value if it is specified (or to the originator address if it is not).


Message Display Mode

A delivered message can specify a flag setting to indicate to the phone when to display the received message: the options are to display immediately, or according to a default or user configured setting.

The modes are defined by constants in the tia637 namespace, which belong to the tia637::TBdMode integer type. The following gets the mode:

tia637::TBdMode display = 0;
err = CDMAFields.GetMessageDisplayModeL(display);

The message display mode for new outgoing messages is set from the current service settings.


Message Deposit Index

A delivered message can have a Message Deposit Index field that provides a unique reference to the message's user data. This allows a phone, when replying to a received message, to include the Message Deposit Index of the received message to indicate to the message center that the original contents of the message are to be included in the reply.

The MTM sets the index field in this way when a reply message is created, so an application does not normally need to access this field.

Index values belong to the tia637::TMessageDepositIndex integer type. The following gets the index:

tia637::TMessageDepositIndex index;
err = CDMAFields.GetMessageDepositIndexL(index);

User Response Code

The User Response Code is used in SMS User Acknowledgement Messages to respond to previously received short messages. The GetUserResponseCodeL() and SetUserResponseCodeL() functions allow this to be retrieved and set. The code is message centre-specific and identifies a predefined response.


Alert On Message Delivery

The Alert on Message Delivery subparameter indicates that alerting is requested. Such methods as vibrating and sound may be used (e.g. by a UI MTM). The possible values are defined by tia637::TAlertPriority.

The subparameter can be retrieved from deliver messages, and set on submit messages. The following sets the alert to high:

CDMAFields.SetAlertOnDeliveryL(tia637::KBdUseHighPriorityAlert);

Language Indicator

The Language Indicator subparameter indicates the language of the message so that the receiving mobile station can discard those messages that are not in the user’s preferred language. The possible language values are defined by tia637::TLanguageIndicator.

The subparameter can be retrieved from deliver messages, and set on submit messages. The following sets the language indicator value to Spanish:

CDMAFields.SetLanguageIndicatorL(tia637::KLanguageSpanish);

[Top]


EMS

CDMA2000 provides a teleservice, the Wireless Enhanced Messaging Teleservice (WEMT), which can carry Enhanced Messaging Service (EMS) over SMS. The EMS standard, defined by the 3GPP [3G TS 23.040, http://www.3gpp.org/ftp/Specs/archive/23_series/23.040/], is based upon the standard SMS, but with formatting added to the text. The formatting allows the message to contain animations, pictures, melodies, formatted text, and vCard and vCalendar objects.

Classes for the various types of EMS element are provided by the gsmu.lib library.

Header

Class

Description

emsanimationie.h

CEmsPreDefAnimationIE

predefined animation

emsformatie.h

CEmsFormatIE

text formatting

emspictureie.h

CEmsPictureIE

large, small, and variably-sized pictures

emssoundie.h

CEmsPreDefSoundIE

predefined sounds

emsuserpromptie.h

CEmsUserPrompt

user prompt indicator

emsobjectdistributionie.h

CEmsObjectDistribution

object distribution indicator

Outgoing WEMT messages

To construct an outgoing WEMT message:

  1. create a new outgoing message, as described in Message creation.

  2. get the TMsvMessageSms for the message

  3. create EMS element objects, and add them to the message using TMsvMessageSms::AddEMSInformationElementL()

The following code adds a pre-defined "winking" animation, and a predefined "drum" sound to a message:

TMsvMessageSms& smsFields = smsHeader -> SmsMessage();
// if simulating an EMS message, add a couple of ems elements
CEmsPreDefAnimationIE* ani = CEmsPreDefAnimationIE::NewL(CEmsPreDefAnimationIE::EWinking);
CleanupStack::PushL(ani);           
smsFields.AddEMSInformationElementL(*ani);
CleanupStack::PopAndDestroy(ani);
CEmsPreDefSoundIE* soundIE = CEmsPreDefSoundIE::NewL(CEmsPreDefSoundIE::EDrum);
CleanupStack::PushL(soundIE);           
smsFields.AddEMSInformationElementL(*soundIE);
CleanupStack::PopAndDestroy(soundIE);

Particular elements and types of element can be removed using TMsvMessageSms::RemoveEMSInformationElementL(). All elements can be removed with TMsvMessageSms::ResetEMSL().

Incoming WEMT messages

Incoming WEMT messages can be detected using the approach described in Incoming messages. You will need to check the message's teleservice ID to test that the message is a WEMT message. Once your application has decided to process the message, you can get a reference to an array of the message's EMS elements using TMsvMessageSms::GetEMSInformationElementsL().

The following code gets the EMS element array, and prints out the type of each element.

const RPointerArray<const CEmsInformationElement>& ems = CDMAFields.GetEMSInformationElementsL();
TInt numEles = ems.Count();
if (numEles) iConsole.Printf(_L("\nContains %d EMS elements:"),numEles);
for (TInt i=0; i < numEles; i++) 
    {
    CSmsInformationElement::TSmsInformationElementIdentifier eleId = ems[i]->Identifier();
    switch (eleId)
        {
    case CSmsInformationElement::ESmsEnhancedTextFormatting:  
        iConsole.Printf(_L("\n\tText Formatting"));
        break;
    case CSmsInformationElement::ESmsEnhancedPredefinedSound:     
        iConsole.Printf(_L("\n\tPredefined Sound"));
        break;
    case CSmsInformationElement::ESmsEnhancedUserDefinedSound:    
        iConsole.Printf(_L("\n\tUser-defined Sound"));
        break;
    case CSmsInformationElement::ESmsEnhancedPredefinedAnimation:     
        iConsole.Printf(_L("\n\tPredefined Animation"));
        break;
    case CSmsInformationElement::ESmsEnhancedLargeAnimation:  
        iConsole.Printf(_L("\n\tLarge Animation"));
        break;
    case CSmsInformationElement::ESmsEnhancedSmallAnimation:  
        iConsole.Printf(_L("\n\tSmall Animation"));
        break;
    case CSmsInformationElement::ESmsEnhancedLargePicture:    
        iConsole.Printf(_L("\n\tLarge Picture"));
        break;
    case CSmsInformationElement::ESmsEnhancedSmallPicture:    
        iConsole.Printf(_L("\n\tSmall Picture"));
        break;
    case CSmsInformationElement::ESmsEnhancedVariablePicture:     
        iConsole.Printf(_L("\n\tVariable Picture"));
        break;
    case CSmsInformationElement::ESmsEnhancedUserPromptIndicator:     
        iConsole.Printf(_L("\n\tUser Prompt Indicator"));
        break;
    case CSmsInformationElement::ESmsEnhancedODI:     
        iConsole.Printf(_L("\n\tODI"));
        break;
    default:
        break;              
        };
    }   
}

[Top]


Send-As support

Messaging provides the Send As API, whose principal class is CSendAs, as a simple-to-use interface that allows applications to create outgoing messages. The SMS MTM supports this API.

The teleservice to which outgoing Send-As SMS messages belong is set at the service level (CSmsSettings::DefaultTeleservice()).

Additional settings such as privacy indicator, reply options, alert on delivery, language indicator, and callback number, are set on the new message from the message settings defaults specified in the SMS service.

[Top]


Example

Overview

The cdmasms_eg example, in the Examples\Messaging\ directory, demonstrates many of the messaging SMS CDMA APIs. It is a simple console-driven application. The main menu offers the following options:

  1. Create WMT

    This creates a new outgoing message belonging to the WMT teleservice. On choosing this, you will be prompted to enter the message text, address, and a number of other message fields. Either enter a value in the suggested range for the field, or just press ENTER to not set the field. On completion, the new message will be saved to the outbox.

  2. Create WEMT

    This is similar to the above, but creates a new WEMT message. In addition to the WMT fields, you are prompted to select an animation element, and a message sound element, to insert into the message.

  3. Send SMS messages

    This initiates sending of any SMS messages that are waiting in the outbox. On completion of the send, it displays an info message saying how many messages were sent, and any error that occurred.

  4. Get incoming messages

    This sets the application to listen for selected new incoming SMS messages, and displays any that arrive. It prompts for:

    • Teleservice to get: WMT, or WEMT

      This instructs the application what type of message should be listened for.

    • Text to match

      The application filters incoming messages, and only handles those in which the beginning of the messgage body is equal to the entered match text (maximum of 5 characters).

    At this point, listening is started. If a new message that meets the entered criteria is detected, the application will display its contents and various of its fields. A sub-menu is displayed that offers further options:

    1. Simulate incoming WMT message:

      This is to simplify experimentation and testing. It artificially creates a new "incoming" SMS message in the inbox that the application will detect and handle as if a genuine new incoming message had arrived. The message has the body text "simulated incoming message".

      Note that the function to do this (CSMSSession::SimulateIncomingL()) uses lower-level CDMA SMS stack APIs, which would not normally be used by a messaging application.

    2. Simulate incoming WEMT message:

      This is similar to the above, but creates a WEMT message with an animation and sound elements.

    3. 3. Cancel waiting for incoming messages

      This stops listening, and returns to the main menu.

    4. Quit

      This exits the example application.

  5. Quit

    This exits the example application.

Classes and files

The application has the following classes:

Class

Purpose

CSmsEgApplication

Standard minimal application class.

CSmsEgDocument

Standard minimal document class.

CSmsEgAppUi

Standard minimal app UI class.

CConsoleControl

Console-type control for input and output.

CSendOp

An active object that initiates sending of SMS messages in the outbox. On completion, it displays the final progress information for the operation.

CSMSSession

Encapsulates a session to the message server and an instance of the SMS client MTM object.

CMenuHandler

Main UI class to write menus to the console and get user input.

It also monitors session events for new incoming SMS messages.

The application has the following files:

File

Purpose

Bld.inf

Component build file

cdmasmsui.cpp, cdmasmsui.h

Defines the standard application framework classes, and CConsoleControl.

cdmasms_eg.cpp, cdmasms_eg.h

This contains the SMS specific part of the example. It defines the CSMSSession and CMenuHandler classes.

cdmasms_eg.mmp

Component project file

cdmasms_eg.rss

Defines standard minimal application resources

Building and running

The application can be built in the standard way using the bldmake and abld commands, or from an IDE.

Note that when running in the emulator, the emulator should be set to CDMA mode, as described in Selecting CDMA or GSM SMS.

The application is started in the same way as other GUI applications. It is called cdmasms_eg.