--- a/messagingappbase/smsmtm/clientmtm/src/smut.cpp Fri Apr 16 14:56:15 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,951 +0,0 @@
-// Copyright (c) 1999-2009 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:
-// smut.cpp
-//
-#include <smut.h>
-#include <gsmuieoperations.h>
-
-#include <e32std.h>
-#include <gsmumsg.h>
-#include <msvstd.h>
-#include <cntdb.h>
-#include <cntfield.h>
-#include <cntitem.h>
-#include <cntfldst.h>
-#include <msventry.h>
-#include <msvuids.h>
-#include <msvapi.h>
-#include <txtetext.h>
-#include <gsmubuf.h>
-#include <bautils.h>
-#include <barsc.h>
-#include <SMSS.rsg>
-#include <smss.hrh>
-#include <msvutils.h>
-#include "SMCMMAIN.H"
-#include "SMUTSET.H"
-
-// Used by ValidGsmNumber(). The characters that may appear at the start of a
-// valid GSM number
-_LIT(KSmsValidGsmNumberFirstChar, "+");
-
-// Used by ValidGsmNumber(). The characters that may appear after the first
-// character of a valid GSM number
-_LIT(KSmsValidGsmNumberOtherChar, "#*");
-
-const TInt KSmsValidGsmNumberMinLength = 2;
-
-/**
-Finds and returns all the Service IDs for the specified MTM.
-
-A Service ID is the entry ID for an service-type entry. The first Service ID
-for the specified MTM is returned.
-
-If the complete set of Service IDs for the MTM is required then the caller
-should provide a valid CMsvEntrySelection object in aServiceIds. The Service
-Ids are appended to this object. If the complete set is not required then the
-input/output argument aServiceIds should be set to NULL.
-
-@param aEntry
-A server message entry that can be used by this function.
-
-@param aFirstId
-An output argument with the first Service ID.
-
-@param aMtm
-The specified MTM. This has a default value of KUidMsgTypeSMS.
-
-@param aServiceIds
-An input/output argument with the complete selection of Service IDs. This has
-a default value of NULL.
-
-@leave KErrNotFound
-A service entry could not be found for the specified MTM.
-*/
-EXPORT_C void TSmsUtilities::ServiceIdL(CMsvServerEntry& aEntry, TMsvId& aFirstId, TUid aMtm, CMsvEntrySelection* aServiceIds)
- {
- aFirstId = KMsvNullIndexEntryId;
-
- CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection();
- CleanupStack::PushL(selection);
-
- User::LeaveIfError(aEntry.SetEntry(KMsvRootIndexEntryId));
-
- TMsvSelectionOrdering order;
- order.SetShowInvisibleEntries(ETrue);
- aEntry.SetSort(order);
-
- // Get the children on the Root Index Entry
- User::LeaveIfError(aEntry.GetChildrenWithType(KUidMsvServiceEntry, *selection));
-
- TInt count = selection->Count();
-
- // Find an entry for MTM aMtm
- for (TInt curChild = 0; curChild < count && (aFirstId == KMsvNullIndexEntryId || aServiceIds); ++curChild)
- {
- User::LeaveIfError(aEntry.SetEntry(selection->At(curChild)));
- CompareEntryL(aEntry.Entry(), aMtm, aFirstId, aServiceIds);
- }
-
- // Leave if no Service Entry found for MTM aMtm
- if (aFirstId == KMsvNullIndexEntryId)
- User::Leave(KErrNotFound);
-
- CleanupStack::PopAndDestroy(selection);
- }
-
-/**
-Finds and returns all the Service IDs for the specified MTM.
-
-A Service ID is the entry ID for an service-type entry. The first Service ID
-for the specified MTM is returned.
-
-If the complete set of Service IDs for the MTM is required then the caller
-should provide a valid CMsvEntrySelection object in aServiceIds. The Service
-Ids are appended to this object. If the complete set is not required then the
-input/output argument aServiceIds should be set to NULL.
-
-@param aSession
-A message server session.
-
-@param aFirstId
-An output argument with the first Service ID.
-
-@param aMtm
-The specified MTM. This has a default value of KUidMsgTypeSMS.
-
-@param aServiceIds
-An input/output argument with the complete selection of Service IDs. This has
-a default value of NULL.
-
-@leave KErrNotFound
-A service entry could not be found for the specified MTM.
-*/
-EXPORT_C void TSmsUtilities::ServiceIdL(CMsvSession& aSession, TMsvId& aFirstId, TUid aMtm, CMsvEntrySelection* aServiceIds)
- {
- TMsvSelectionOrdering order;
- order.SetShowInvisibleEntries(ETrue);
-
- CMsvEntry* root = CMsvEntry::NewL(aSession, KMsvRootIndexEntryId, order);
- CleanupStack::PushL(root);
-
- ServiceIdL(*root, aFirstId, aMtm, aServiceIds);
-
- CleanupStack::PopAndDestroy(root);
- }
-
-/**
-Finds and returns all the Service IDs for the specified MTM.
-
-A Service ID is the entry ID for an service-type entry. The first Service ID
-for the specified MTM is returned.
-
-If the complete set of Service IDs for the MTM is required then the caller
-should provide a valid CMsvEntrySelection object in aServiceIds. The Service
-Ids are appended to this object. If the complete set is not required then the
-input/output argument aServiceIds should be set to NULL.
-
-@param aEntry
-A message entry that can be used by this function.
-
-@param aFirstId
-An output argument with the first Service ID.
-
-@param aMtm
-The specified MTM. This has a default value of KUidMsgTypeSMS.
-
-@param aServiceIds
-An input/output argument with the complete selection of Service IDs. This has
-a default value of NULL.
-
-@leave KErrNotFound
-A service entry could not be found for the specified MTM.
-*/
-EXPORT_C void TSmsUtilities::ServiceIdL(CMsvEntry& aEntry, TMsvId& aFirstId, TUid aMtm, CMsvEntrySelection* aServiceIds)
- {
- aFirstId = KMsvNullIndexEntryId;
-
- TMsvSelectionOrdering order(aEntry.SortType());
- if (!order.ShowInvisibleEntries())
- {
- order.SetShowInvisibleEntries(ETrue);
- aEntry.SetSortTypeL(order);
- }
-
- aEntry.SetEntryL(KMsvRootIndexEntryId);
- const TInt count = aEntry.Count();
-
- // Find an entry for MTM aMtm
- for (TInt curChild = 0; curChild < count && (aFirstId == KMsvNullIndexEntryId || aServiceIds != NULL); ++curChild)
- {
- CompareEntryL(aEntry[curChild], aMtm, aFirstId, aServiceIds);
- }
-
- // Leave if no Service Entry found for MTM aMtm
- if (aFirstId == KMsvNullIndexEntryId)
- User::Leave(KErrNotFound);
- }
-
-/**
-Populates a message index.
-
-The input data is used to set the fields in supplied message index. The affected
-fields are the entry type, MTM, entry date, Service ID and error fields. The
-date field is set from the time information in the aMessage argument.
-
-This function can be used as part of the process when creating SMS messages in
-the message store.
-
-@param aEntry
-An input/output argument with the index entry to populate.
-
-@param aMessage
-The SMS message object for the index entry.
-
-@param aServiceId
-The Service ID for the message.
-
-@param aMtm
-The specified MTM. This has a default value of KUidMsgTypeSMS.
-*/
-EXPORT_C void TSmsUtilities::PopulateMsgEntry(TMsvEntry& aEntry, const CSmsMessage& aMessage, TMsvId aServiceId, TUid aMtm)
- {
- aEntry.iType = KUidMsvMessageEntry;
- aEntry.iMtm = aMtm;
- aEntry.iDate = aMessage.Time();
- aEntry.iServiceId = aServiceId;
- aEntry.iError = KErrNone;
- }
-
-/**
-Populates a message index.
-
-The input data is used to set the fields in supplied message index. The affected
-fields are the entry type, MTM, entry date, Service ID and error fields. The
-date field is either set from the time information in the aMessage argument or from
-the service center timestamp in the PDU depending on the associated SMS setting.
-
-This function can be used as part of the process when creating SMS messages in
-the message store.
-
-@param aEntry
-An input/output argument with the index entry to populate.
-
-@param aMessage
-The SMS message object for the index entry.
-
-@param aServiceId
-The Service ID for the message.
-
-@param aSettings
-The settings for the SMS account.
-
-@param aMtm
-The specified MTM. This has a default value of KUidMsgTypeSMS.
-*/
-EXPORT_C void TSmsUtilities::PopulateMsgEntry(TMsvEntry& aEntry, const CSmsMessage& aMessage, TMsvId aServiceId, const CSmsSettings& aSettings, TUid aMtm)
- {
- TSmsUtilities::PopulateMsgEntry(aEntry, aMessage, aServiceId, aMtm);
-
- if (aSettings.UseServiceCenterTimeStampForDate())
- {
- const CSmsPDU& pdu = aMessage.SmsPDU();
-
- TTime time = 0;
- TInt gmtOffset = 0;
-
- if (pdu.Type() == CSmsPDU::ESmsDeliver)
- {
- CSmsDeliver& smsDeliver =
- const_cast<CSmsDeliver&>(static_cast<const CSmsDeliver&>(pdu));
- smsDeliver.ServiceCenterTimeStamp(time, gmtOffset);
- }
- else if (pdu.Type() == CSmsPDU::ESmsStatusReport)
- {
- CSmsStatusReport& smsStatusReport =
- const_cast<CSmsStatusReport&>(static_cast<const CSmsStatusReport&>(pdu));
- smsStatusReport.ServiceCenterTimeStamp(time, gmtOffset);
- }
-
- if (time > 0)
- {
- aEntry.iDate = time;
- }
- }
- }
-
-/**
-Get the SMS message recipient/sender details.
-
-The recipient/sender telephone number is extracted from the supplied message
-object. If the recipient/sender telephone number appears uniquely in the contacts
-database then the family name and given name contact details are set into the
-output argument aDetails in the format specified by the resource item
-R_SENDER_NAME_FORMAT. The buffer limit specified by aMaxLength is observed.
-
-If there is not a unique contact entry for the recipient/sender telephone number
-then aDetails will contain the orginally telephone number.
-
-@param aFs
-A connected file server session.
-
-@param aMessage
-The message object with the recipient/sender telephone number.
-
-@param aDetails
-The output argument to contain the message details.
-
-@param aMaxLength
-The maximum length of the supplied buffer in aDetails.
-
-@return
-KErrNotSupported if the message is not of type SMS-SUBMIT, SMS-DELIVER or SMS-STATUS-REPORT.
-KErrArgument if the telephone number is invalid.
-KErrNotFound if a contact could not be found.
-KErrAlreadyExists if more than one contact entry found.
-KErrNone if details is obtained successfully.
-*/
-EXPORT_C TInt TSmsUtilities::GetDetails(RFs& aFs, const CSmsMessage& aMessage, TDes& aDetails, TInt aMaxLength)
- {
- __ASSERT_DEBUG( aMaxLength <= aDetails.MaxLength(), User::Invariant() );
-
- if (aMaxLength > aDetails.MaxLength())
- {
- aMaxLength = aDetails.MaxLength();
- }
-
- aDetails.Zero();
-
- TPtrC fromAddress;
-
- switch (aMessage.SmsPDU().Type())
- {
- case CSmsPDU::ESmsSubmit:
- case CSmsPDU::ESmsDeliver:
- case CSmsPDU::ESmsStatusReport:
- fromAddress.Set(aMessage.SmsPDU().ToFromAddress());
- break;
- default:
- return KErrNotSupported;
- }
-
- return GetDetails(aFs, fromAddress, aDetails, aMaxLength);
- }
-
-/**
-Get the SMS message recipient/sender details.
-
-The recipient/sender telephone number is searched for in the contacts database.
-If a unique match is found then the family name and given name contact details
-are set into the output argument aDetails in the format specified by the
-resource item R_SENDER_NAME_FORMAT. The buffer limit specified by aMaxLength is
-observed.
-
-If a unique match is not found or the supplied telephone number is invalid, then
-aDetails will contain the orginally telephone number.
-
-@param aFs
-A connected file server session.
-
-@param aFromAddress
-The recipient/sender telephone number.
-
-@param aDetails
-The output argument to contain the message details.
-
-@param aMaxLength
-The maximum length of the supplied buffer in aDetails.
-
-@return
-KErrArgument if aFromAddress is not a valid GSM number.
-KErrNotFound if a contact could not be found.
-KErrAlreadyExists if more than one contact entry found.
-KErrNone if details is obtained successfully.
-*/
-EXPORT_C TInt TSmsUtilities::GetDetails(RFs& aFs, const TDesC& aFromAddress, TDes& aDetails, TInt aMaxLength)
- {
- __ASSERT_DEBUG( aMaxLength <= aDetails.MaxLength(), User::Invariant() );
-
- if (aMaxLength > aDetails.MaxLength())
- {
- aMaxLength = aDetails.MaxLength();
- }
-
- TRAPD(err, DoGetDetailsL(aFs, aFromAddress, aDetails, aMaxLength));
-
- if ( (err != KErrNone) || (aDetails.Length() == 0) )
- {
- if (aFromAddress.Length() <= aMaxLength)
- {
- aDetails = aFromAddress;
- aDetails.Trim();
- }
- else
- {
- // Truncate aFromAddress so that it fits into aDetails.
- aDetails = aFromAddress.Left(aMaxLength);
- aDetails.Trim();
- }
- }
-
- return KErrNone;
- }
-
-/**
-Get the SMS message description.
-
-If the message is Special Message Indication SMS then the description will
-contain the appropriate localised text for the indication.
-
-If the message is a Status Report then the description will contain the
-appropriate localised text for a Status Report.
-
-If the message is a standard text message the description will contain the
-beginning section of the SMS message text itself.
-
-In all cases the buffer limit specified by aMaxLength is observered.
-
-@param aMessage
-The SMS message object.
-
-@param aDescription
-The output argument for the description.
-
-@param aMaxLength
-The maximum length of the supplied buffer in aDescription.
-
-@return
-An error code if the localised text for a SMS-STATUS-REPORT message could not be
-obtained. Otherwise KErrNone is returned.
-*/
-EXPORT_C TInt TSmsUtilities::GetDescription(const CSmsMessage& aMessage, TDes& aDescription, TInt aMaxLength)
- {
- __ASSERT_DEBUG( aMaxLength <= aDescription.MaxLength(), User::Invariant() );
-
- if (aMaxLength > aDescription.MaxLength())
- {
- aMaxLength = aDescription.MaxLength();
- }
-
- aDescription.Zero();
-
- TBool gotDescription = EFalse;
- TRAPD(err, gotDescription = DoGetDescriptionL(aMessage, aDescription, aMaxLength));
- if(err != KErrNone || !gotDescription)
- ExtractDescriptionFromMessage(aMessage, aDescription, aMaxLength);
-
- return KErrNone;
- }
-
-/**
-Opens and returns the SMS client MTM resource file.
-
-It is the responsibility of the caller to ensure that the resource file is
-closed once it is no longer required.
-
-@param aFs
-A connected file server session.
-
-@return
-The opened resource file.
-*/
-EXPORT_C RResourceFile TSmsUtilities::OpenResourceFileL(RFs& aFs)
- {
- TFileName fileName(KSmsResourceFile);
- MsvUtils::AddPathAndExtensionToResFileL(fileName);
- BaflUtils::NearestLanguageFile(aFs, fileName);
-
- RResourceFile resFile;
- resFile.OpenL(aFs, fileName);
- return resFile;
- }
-
-/**
-Reads the resource specified by aResourceId from the supplied resource file.
-
-The resource is returned in the output argument aString. The supplied resource
-file must be open or this function will leave.
-
-@param aResourceFile
-The opened resource file to read the resource from.
-
-@param aResourceId
-The ID of the resource that is required.
-
-@param aString
-An output buffer into which the read resource is placed.
-
-@leave KErrOverflow
-The length of the resource string is greater than the maximum allowed.
-*/
-EXPORT_C void TSmsUtilities::ReadResourceStringL(RResourceFile aResourceFile, TInt aResourceId, TDes& aString)
-
- {
- HBufC8* buf = aResourceFile.AllocReadLC(aResourceId);
- TResourceReader reader;
- reader.SetBuffer(buf);
-
- TPtrC resString = reader.ReadTPtrC();
-
- if (resString.Length() <= aString.MaxLength())
- {
- aString.Copy(resString);
- }
- else
- {
- User::Leave(KErrOverflow);
- }
-
- CleanupStack::PopAndDestroy(buf);
- }
-
-void TSmsUtilities::CompareEntryL(const TMsvEntry& aEntry, TUid aMtm, TMsvId& aFirstId, CMsvEntrySelection* aServiceIds)
- {
- if (aEntry.iType == KUidMsvServiceEntry && aEntry.iMtm == aMtm)
- {
- const TMsvId id = aEntry.Id();
-
- if (aFirstId == KMsvNullIndexEntryId)
- aFirstId = id;
-
- if (aServiceIds)
- aServiceIds->AppendL(id);
- }
- }
-
-void TSmsUtilities::DoGetDetailsL(RFs& aFs, const TDesC& aFromAddress, TDes& aDetails, TInt aMaxLength)
- {
- __UHEAP_MARK;
-
- // Check that aFromAddress is a valid GSM telephone number
- if (!ValidGsmNumber(aFromAddress))
- User::Leave(KErrArgument);
-
- aDetails.Zero();
-
- CContactDatabase* db = CContactDatabase::OpenL();
- CleanupStack::PushL(db);
-
- // Lookup the telephone number (aFromAddress) in the contact database
- CContactIdArray* contactId = db->MatchPhoneNumberL(aFromAddress, KLowerSevenDigits);
- CleanupStack::PushL(contactId);
-
- // Add the name if there is one and only one match in contacts. If there's more than
- // one then wouldn't know which one to choose
- if (contactId->Count() <= 0)
- {
- //The telephone number (aFromAddress) was not found in the contact database.
- User::Leave(KErrNotFound);
- }
- else if (contactId->Count() > 1)
- {
- //There's more than one telephone number match in contacts.
- User::Leave(KErrAlreadyExists);
- }
-
- CContactItem* newContact = db->ReadMinimalContactL((*contactId)[0]);
- CleanupStack::PushL(newContact);
-
- CContactItemFieldSet& fieldSet = newContact->CardFields();
-
- TInt count = fieldSet.Count();
-
- HBufC* family = HBufC::NewLC(aMaxLength);
- HBufC* given = HBufC::NewLC(aMaxLength);
- TPtr familyPtr(family->Des());
- TPtr givenPtr(given->Des());
-
- // Find the Given and First Name of the contact
- // Order important
- for (TInt curField = 0; curField < count && !(familyPtr.Length() && givenPtr.Length()); curField++)
- {
- CContactItemField& field = fieldSet[curField];
-
- if (!familyPtr.Length())
- GetName(field, KUidContactFieldFamilyName, familyPtr);
-
- if (!givenPtr.Length())
- GetName(field, KUidContactFieldGivenName, givenPtr);
- }
-
- familyPtr.Trim();
- givenPtr.Trim();
-
- TInt familyLen = familyPtr.Length();
- TInt givenLen = givenPtr.Length();
-
- if (!familyLen && !givenLen)
- {
- //Leave if no family nor given name found
- User::Leave(KErrNotFound);
- }
- else if (givenLen == 0)
- {
- // The maximum length of familyPtr may be greater than
- // aMaxLength, so need to check its length before copying.
- if (familyPtr.Length() > aMaxLength)
- {
- familyPtr.Set(familyPtr.LeftTPtr(aMaxLength));
- }
-
- aDetails = familyPtr;
- }
- else if (familyLen == 0)
- {
- // The maximum length of givenPtr may be greater than
- // aMaxLength, so need to check its length before copying.
- if (givenPtr.Length() > aMaxLength)
- {
- givenPtr.Set(givenPtr.LeftTPtr(aMaxLength));
- }
-
- aDetails = givenPtr;
- }
- else
- {
- RResourceFile resFile = OpenResourceFileL(aFs);
- CleanupClosePushL(resFile);
- ReadResourceStringL(resFile, R_SENDER_NAME_FORMAT, aDetails);
- CleanupStack::PopAndDestroy(&resFile);
-
- TBuf<8> givenPlaceHolder = L_SMS_GIVEN_NAME;
- TBuf<8> familyPlaceHolder = L_SMS_FAMILY_NAME;
- TInt minLength = aDetails.Length() - givenPlaceHolder.Length() - familyPlaceHolder.Length();
-
- if ((familyLen + givenLen + minLength) > aMaxLength)
- {
- // The maximum length of familyPtr may be greater than
- // aMaxLength, so need to check its length before copying.
- if (familyPtr.Length() > aMaxLength)
- {
- familyPtr.Set(familyPtr.LeftTPtr(aMaxLength));
- }
- aDetails = familyPtr;
- }
- else
- {
- Replace(givenPlaceHolder, givenPtr, aDetails);
- Replace(familyPlaceHolder, familyPtr, aDetails);
- }
- }
-
- //Remove leading and trailing spaces
- aDetails.Trim();
- CleanupStack::PopAndDestroy(5, db);
-
- __UHEAP_MARKEND;
- }
-
- TBool TSmsUtilities::ValidGsmNumber(const TDesC& aTelephone)
- {
- // Returns ETrue if
- // aTelephone is not zero length; and
- // aTelephone[0] is a digit or "+"; and
- // aTelephone[1..] is a digit or "*" or "#".
- // aTelephone has at least 2 valid characters
- //Note: Returns EFalse if aTelephone contains any alpha character
- // All spaces are ignored
- const TInt length = aTelephone.Length();
-
- if (length < KSmsValidGsmNumberMinLength)
- return EFalse;
-
- TPtrC KFirstChar(KSmsValidGsmNumberFirstChar);
- TPtrC KOtherChar(KSmsValidGsmNumberOtherChar);
- TBool validTel = ETrue;
- TInt validCharsFound = 0; //must be >= KSmsValidGsmNumberMinLength by the end
-
- const TText* first = aTelephone.Ptr(); //Points to the first character in aTelephone
- const TText* last = first + length - 1; //Points to the last character in aTelephone
-
- //Check each character in the telephone number
- while (validTel && first <= last)
- {
- TChar ch(*first);
- if (!ch.IsSpace()) //ignore whitespace
- {
- if (!ch.IsDigit())
- {
- //Need to create TPtrC because TDesC::Find() does not take a TChar
- TPtrC telCharacter(first, 1);
-
- if (validCharsFound)
- {
- //Check the remaining characters of the telephone number
- validTel = (KOtherChar.Find(telCharacter) != KErrNotFound);
- }
- else //validCharsFound == 0
- {
- //Check the first character of the telephone number
- validTel = (KFirstChar.Find(telCharacter) != KErrNotFound);
- }
- }
- validCharsFound++;
- }
-
- first++; //move to the next character
- }
-
- return validTel && validCharsFound >= KSmsValidGsmNumberMinLength;
- }
-
- void TSmsUtilities::GetName(CContactItemField& aField, TUid aFieldType, TDes& aName)
- {
- __UHEAP_MARK;
- if (aField.ContentType().ContainsFieldType(aFieldType))
- {
- TPtrC name = aField.TextStorage()->Text();
- aName = name.Left(Min(aName.MaxLength(), name.Length()));
- }
- __UHEAP_MARKEND;
-
- }
-
-TBool TSmsUtilities::DoGetDescriptionL(const CSmsMessage& aMessage, TDes& aDescription, TInt aMaxLength)
-// this function returns EFalse if aMessage has no special message indication data and is not an SMS_STATUS_REPORT,
-// i.e. more needs to be done to extract the description from the message
-// otherwise returns ETrue
- {
- TInt resourceId = 0;
- TBuf<KSmsDescriptionLength> format;
- TSmsMessageIndicationType messageIndicationType;
- TExtendedSmsIndicationType extendedType;
- TSmsMessageProfileType messageProfileType;
- TBool toStore=EFalse;
- TUint totalIndicationCount=0;
- TUint totalMessageCount=0;
-
- //check if the messae contains an enhanced voice mail indication
- CSmsEnhancedVoiceMailOperations& enhancedVoiceMailOperations = STATIC_CAST(CSmsEnhancedVoiceMailOperations&,aMessage.GetOperationsForIEL(CSmsInformationElement::ESmsEnhanceVoiceMailInformation));
-
- if(enhancedVoiceMailOperations.ContainsEnhancedVoiceMailIEL())
- {
- //get a copy of the indication
- CEnhancedVoiceMailBoxInformation* retrievedNotification=enhancedVoiceMailOperations.CopyEnhancedVoiceMailIEL();
- TVoiceMailInfoType typeInfo=retrievedNotification->Type();
- //check its type
- if(typeInfo==EGsmSmsVoiceMailNotification)
- {
- //increment the indication count
- ++totalIndicationCount;
- resourceId = R_MESSAGE_INDICATION_ENHANCED_VOICEMAIL_ONE;
- }
-
- TUint8 messageCount=retrievedNotification->NumberOfVoiceMessages();
- //add the message count to the running total
- totalMessageCount+=messageCount;
- //if there is more that one message of this type then set the resouce id to 'many'
- if(messageCount!=1)
- {
- ++resourceId;
- }
-
- delete retrievedNotification;
- }
-
- //check for special message waiting indications
- CSmsSpecialSMSMessageOperations& operations = STATIC_CAST(CSmsSpecialSMSMessageOperations&,aMessage.GetOperationsForIEL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication));
- TUint specialMessageIndicationCount=operations.GetCountOfSpecialMessageIndicationsL();
-
- if(specialMessageIndicationCount!=0)
- {
- //add special message indications to out indication count
- totalIndicationCount+=specialMessageIndicationCount;
-
- if(totalIndicationCount>1)
- {
- //set the resource id to R_MESSAGE_INDICATION_OTHER_ONE
- resourceId = R_MESSAGE_INDICATION_OTHER_ONE;
- //get the total number of messages from the indicatations
- TUint8 messageCount=0;
- for(TInt loopCount=0;loopCount<specialMessageIndicationCount;loopCount++)
- {
- operations.GetMessageIndicationIEL(loopCount,toStore,messageIndicationType,extendedType,messageProfileType,messageCount);
- totalMessageCount+=messageCount;
- }
- }
- else
- {
- //there is only one indication, get it's type and the number of messages it holds.
- TUint8 messageCount=0;
- operations.GetMessageIndicationIEL(0,toStore,messageIndicationType,
- extendedType,messageProfileType,messageCount);
-
- //add the message count to the running total
- totalMessageCount+=messageCount;
-
- switch (messageIndicationType)
- {
- case EGsmSmsVoiceMessageWaiting:
- resourceId = R_MESSAGE_INDICATION_VOICEMAIL_ONE;
- break;
-
- case EGsmSmsFaxMessageWaiting:
- resourceId = R_MESSAGE_INDICATION_FAX_ONE;
- break;
-
- case EGsmSmsElectronicMailMessageWaiting:
- resourceId = R_MESSAGE_INDICATION_EMAIL_ONE;
- break;
-
- case EGsmSmsExtendedMessageTypeWaiting:
- //get the extended indications type
- if(extendedType==EGsmSmsVideoMessageWaiting)
- {
- resourceId = R_MESSAGE_INDICATION_VIDEOMESSAGE_ONE;
- }
- else
- {
- resourceId = R_MESSAGE_INDICATION_OTHER_ONE;
- }
- break;
-
- default:
- resourceId = R_MESSAGE_INDICATION_OTHER_ONE;
- break;
- }
- }
- //if there is more that one message waiting append 'many' to the id.
- if(totalMessageCount!=1)
- {
- resourceId++;
- }
- }
-
- const CSmsPDU& smsPDU= aMessage.SmsPDU();
- // If no Special Msg Indication found in the User Data,
- // then check the DataCodingScheme.
- if (totalIndicationCount==0 && smsPDU.DataCodingSchemePresent())
- {
- TInt bits7to4 = smsPDU.Bits7To4();
-
- switch (bits7to4)
- {
- case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndication7Bit:
- case TSmsDataCodingScheme::ESmsDCSMessageWaitingIndicationUCS2:
- {
- if (smsPDU.IndicationState() == TSmsDataCodingScheme::ESmsIndicationActive)
- {
- totalIndicationCount = 1;
-
- switch (smsPDU.IndicationType())
- {
- case TSmsDataCodingScheme::ESmsVoicemailMessageWaiting:
- resourceId = R_MESSAGE_INDICATION_VOICEMAIL_ONE;
- break;
- case TSmsDataCodingScheme::ESmsFaxMessageWaiting:
- resourceId = R_MESSAGE_INDICATION_FAX_ONE;
- break;
- case TSmsDataCodingScheme::ESmsElectronicMailMessageWaiting:
- resourceId = R_MESSAGE_INDICATION_EMAIL_ONE;
- break;
- case TSmsDataCodingScheme::ESmsFaxOtherMessageWaiting:
- default:
- resourceId = R_MESSAGE_INDICATION_OTHER_ONE;
- break;
- } //end switch
- } //end if
- } //end case
- default:
- {
- break; //do nothing
- }
- }
- }
-
- if (totalIndicationCount!=0)
- {
- //Special message found.
- //Look up the resourceID in the SMSS resource file
-
- RFs fs;
- User::LeaveIfError(fs.Connect());
- CleanupClosePushL(fs);
- RResourceFile resFile = OpenResourceFileL(fs);
- CleanupClosePushL(resFile);
- ReadResourceStringL(resFile, resourceId, format);
- CleanupStack::PopAndDestroy(2, &fs);
-
- if (totalMessageCount == 1)
- {
- if (format.Length() <= aMaxLength)
- {
- aDescription = format;
- }
- else
- {
- // Truncate format so that it fits into aDescription.
- aDescription = format.Left(aMaxLength);
- }
- }
- else if (format.Length() < aMaxLength)
- {
- aDescription.Zero();
- aDescription.AppendFormat(format, totalMessageCount);
- }
- return ETrue;
- }
- else
- {
- if(aMessage.Type() == CSmsPDU::ESmsStatusReport)
- {
- // for SMS_STATUS_REPORT messages, if we cannot read the string in, then
- // we do not attempt to extract the description from the message: return EFalse
- RFs fs;
- User::LeaveIfError(fs.Connect());
- CleanupClosePushL(fs);
- RResourceFile resFile = OpenResourceFileL(fs);
- CleanupClosePushL(resFile);
- ReadResourceStringL(resFile, R_TYPE_STATUS_REPORT, aDescription);
- CleanupStack::PopAndDestroy(2, &fs);
- return ETrue;
- }
- else
- {
- return EFalse;
- }
- }
- }
-
-
-void TSmsUtilities::ExtractDescriptionFromMessage(const CSmsMessage& aMessage, TDes& aDescription, TInt aMaxLength)
- {
- if(aMessage.Type() != CSmsPDU::ESmsStatusReport)
- {
- aMessage.Buffer().Extract(aDescription, 0, Min(aMaxLength, aMessage.Buffer().Length()));
-
- TInt length = aDescription.Length();
-
- //replace paragraphs with spaces.
- while(length--)
- {
- TText& text = aDescription[length];
- const TChar ch(text);
- if (ch.IsSpace() || text == CEditableText::EParagraphDelimiter)
- text = ' ';
- }
-
- aDescription.TrimAll(); //removes leading trailing and multiple internal whitespace (spaces, line feeds etc)
- }
- }
-
-void TSmsUtilities::Replace(const TDesC& aOld, const TDesC& aNew, TDes& aString)
- {
- TInt find = aString.Find(aOld);
-
- if (find != KErrNotFound)
- {
- aString.Replace(find, aOld.Length(), aNew);
- }
- }