diff -r 238255e8b033 -r 84d9eb65b26f messagingappbase/smsmtm/clientmtm/src/SMUTHDR.CPP --- a/messagingappbase/smsmtm/clientmtm/src/SMUTHDR.CPP Fri Apr 16 14:56:15 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1075 +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: -// - -#include -#include -#include - -#include -#include -#include -#include -#include -#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS -#include -#endif - -#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) -#include -#endif - -const TUid KUidMsvSMSHeaderStream = {0x10001834}; -const TInt16 KMsvSmsHeaderVersion = 1; -const TInt KSmcmRecipientsGranularity = 8; -#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) -_LIT16(KComma, ","); -_LIT16(KDelimiter, ";"); -#endif - -/** -Allocates and constructs a new CSmsHeader object. - -Use this function to create a new SMS-SUBMIT, SMS-COMMAND, SMS-DELIVER or -SMS-STATUS-REPORT type message. - -@param aType -The Protocol Data Unit (PDU) type for the SMS message. - -@param aText -The message text. - -@return -A new CSmsHeader object. -*/ -EXPORT_C CSmsHeader* CSmsHeader::NewL(CSmsPDU::TSmsPDUType aType, CEditableText& aText) - { - CSmsHeader* self = new(ELeave) CSmsHeader(); - CleanupStack::PushL(self); - self->ConstructL(aType, aText); - CleanupStack::Pop(self); - return self; - } - -/** -Allocates and constructs a new CSmsHeader object. - -Use this function to create a new SMS-SUBMIT, SMS-COMMAND, SMS-DELIVER or -SMS-STATUS-REPORT type message. This version uses a previously connected -file server session handle. - -@param aType -The Protocol Data Unit (PDU) type for the SMS message. - -@param aText -The message text. - -@param aFs -Handle to an open file server session. CSmsHeader will not close the file session. - -@return -A new CSmsHeader object. -*/ -EXPORT_C CSmsHeader* CSmsHeader::NewL(CSmsPDU::TSmsPDUType aType, CEditableText& aText, RFs& aFs) - { - CSmsHeader* self = new(ELeave) CSmsHeader(); - CleanupStack::PushL(self); - self->ConstructL(aType, aText, aFs); - CleanupStack::Pop(self); - return self; - } - -/** -Allocates and constructs a new CSmsHeader object. - -Use this function to create a new SMS-DELIVER type message. - -@param aMessage -The SMS message encapsulation from the SMS stack. - -@return -A new CSmsHeader object. -*/ -EXPORT_C CSmsHeader* CSmsHeader::NewL(CSmsMessage* aMessage) - { - CSmsHeader* self = new(ELeave) CSmsHeader(aMessage); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - -/** -Destructor. -*/ -EXPORT_C CSmsHeader::~CSmsHeader() - { - iRecipients.ResetAndDestroy(); - delete iMessage; - delete iEmailFields; - if(iCloseFs) - { - iFs.Close(); - } - } - -/** -Sets the SMS message settings for the message. - -This can only be used on SMS-SUBMIT, SMS-COMMAND, SMS-DELIVER or SMS-STATUS-REPORT -type messages. - -NOTE - if this is an Email over SMS message then the PID of is not changed. The -PID would have been set correctly when the email fields were set. - -@param aSmsSettings -The SMS message settings for the message - -@leave KErrNotSupported -The message PDU type was not supported, or the message conversion value was not -supported. - -@panic SMCM 0 -The message PDU is not supported (debug only). -*/ -EXPORT_C void CSmsHeader::SetSmsSettingsL(const CSmsMessageSettings& aSmsSettings) - { - __ASSERT_DEBUG( (Type()==CSmsPDU::ESmsSubmit) || (Type()==CSmsPDU::ESmsDeliver) || (Type()==CSmsPDU::ESmsStatusReport) || (Type()==CSmsPDU::ESmsCommand), Panic(ESmutPanicUnsupportedMsgType)); - - switch(Type()) - { - case(CSmsPDU::ESmsSubmit): - { - Submit().SetRejectDuplicates(aSmsSettings.RejectDuplicate()); - Submit().SetReplyPath(aSmsSettings.ReplyPath()); - - //Check if delivery report for the last segment only is required . - if(aSmsSettings.LastSegmentDeliveryReport()) - { - CSmsTPSRROperations& tpSRROperations = static_cast(iMessage->GetOperationsForNonIEL(ESmsTPSRRParameter)); - tpSRROperations.SetSchemeL(); - tpSRROperations.SetLastSegmentStatusReportL(ETrue); - } - else - { - Submit().SetStatusReportRequest(aSmsSettings.DeliveryReport()); - } - Submit().SetValidityPeriod(aSmsSettings.ValidityPeriod()); - Submit().SetValidityPeriodFormat(aSmsSettings.ValidityPeriodFormat()); - break; - } - case(CSmsPDU::ESmsCommand): - { - Command().SetStatusReportRequest(aSmsSettings.DeliveryReport()); - break; - } - case(CSmsPDU::ESmsDeliver): - case(CSmsPDU::ESmsStatusReport): - break; - default: - { - User::Leave(KErrNotSupported); - break; - } - }; - - if (Message().TextPresent()) - SetCanConcatenate(aSmsSettings.CanConcatenate()); - - CSmsPDU& pdu=Message().SmsPDU(); - if (pdu.DataCodingSchemePresent()) - pdu.SetAlphabet(aSmsSettings.CharacterSet()); - if (pdu.ProtocolIdentifierPresent() && iEmailFields->Length() == 0 ) - { - // The email fields object for this message is empty - therefore the - // PID can be set. With a non-empty email fields object the PID would - // have been set for interworking with email and MUST not be changed. - pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking); - - // MessageConversion - switch(aSmsSettings.MessageConversion()) - { - case(ESmsConvPIDNone): - { - pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsNoTelematicDevice); - break; - } - case ESmsConvFax: - case ESmsConvX400: - case ESmsConvPaging: - case ESmsConvMail: - case ESmsConvErmes: - case ESmsConvSpeech: - { - pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice); - pdu.SetTelematicDeviceType((TSmsProtocolIdentifier::TSmsTelematicDeviceType) aSmsSettings.MessageConversion()); - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - }; - } - } - -/** -Gets the SMS message settings for the message. - -This can only be used on SMS-SUBMIT type messages. - -@param aSmsSettings -The output argument with the SMS message settings. - -@leave KErrNotSupoprted -The Telematic Device type is not supported. - -@panic SMCM 0 -The message PDU is not supported (debug only). -*/ -EXPORT_C void CSmsHeader::GetSmsSettingsL(CSmsMessageSettings& aSmsSettings) const - { - __ASSERT_DEBUG( Type()==CSmsPDU::ESmsSubmit, Panic(ESmutPanicUnsupportedMsgType)); - switch(Type()) - { - case(CSmsPDU::ESmsSubmit): - { - aSmsSettings.SetRejectDuplicate(Submit().RejectDuplicates()); - aSmsSettings.SetReplyPath(Submit().ReplyPath()); - TSmsStatusReportScheme scheme = iMessage->Scheme(); - if (scheme == ETPSRRScheme) - { - aSmsSettings.SetLastSegmentDeliveryReport(ETrue); - } - else - { - aSmsSettings.SetDeliveryReport(Submit().StatusReportRequest()); - } - aSmsSettings.SetValidityPeriod(Submit().ValidityPeriod()); - aSmsSettings.SetValidityPeriodFormat(Submit().ValidityPeriodFormat()); - aSmsSettings.SetCharacterSet(Submit().Alphabet()); - - if (iMessage->SmsPDU().PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking) - { - if (iMessage->SmsPDU().TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsNoTelematicDevice) - { - aSmsSettings.SetMessageConversion(ESmsConvPIDNone); - } - else //if (iMessage->SmsPDU().TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice) - { - switch (iMessage->SmsPDU().TelematicDeviceType()) - { - case TSmsProtocolIdentifier::ESmsGroup3TeleFax: - case TSmsProtocolIdentifier::ESmsX400MessageHandlingSystem: - case TSmsProtocolIdentifier::ESmsNationalPagingSystem: - case TSmsProtocolIdentifier::ESmsInternetElectronicMail: - case TSmsProtocolIdentifier::ESmsERMES: - case TSmsProtocolIdentifier::ESmsVoiceTelephone: - aSmsSettings.SetMessageConversion((TSmsPIDConversion) iMessage->SmsPDU().TelematicDeviceType()); - break; - default: - User::Leave(KErrNotSupported); - break; - } - } - } - - aSmsSettings.SetCanConcatenate(CanConcatenate()); - break; - } - default: - { - break; - } - } - } - -/** -Sets the email fields for the message. - -If the supplied email fields is not empty then the PID of the PDU of the message -is set for interworking with email. - -If the supplied email fields is empty and the PID of the PDU of the message is -set for interworking with email then the PID is set to the default value that -indicates no telematic device. If the PID was not set for interworking with -email then it is left unchanged. - -@param aEmailFields -The email fields object. A copy is made of this object. -*/ -EXPORT_C void CSmsHeader::SetEmailFieldsL(const CSmsEmailFields& aEmailFields) - { - __ASSERT_DEBUG( Type()==CSmsPDU::ESmsSubmit, Panic(ESmutPanicUnsupportedMsgType)); - - CSmsEmailFields* temp = CSmsEmailFields::NewL(aEmailFields); - delete iEmailFields; - iEmailFields = temp; - - CSmsPDU& pdu = Message().SmsPDU(); - if( pdu.ProtocolIdentifierPresent() ) - { - if( iEmailFields->Length() > 0 ) - { - // Set the PID for interworking with email. - pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking); - pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice); - pdu.SetTelematicDeviceType(TSmsProtocolIdentifier::ESmsInternetElectronicMail); - } - else - { - // The email fields are empty - if the PID is set for interworking - // with email, set to indicate no telematic device. - if( pdu.PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking && - pdu.TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice && - pdu.TelematicDeviceType() == TSmsProtocolIdentifier::ESmsInternetElectronicMail ) - { - pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsNoTelematicDevice); - } - } - } - } - -/** -Sets the email fields for a reply message. - -The address field is copied from the specified email fields. The subject field -is formatted according to the specified subject format using the subject from -the specified email fields. - -The PID of the PDU of the message is set for interworking with email. - -@param aEmailFields -The email fields object. - -@param aReplySubjectFormat -The format of the subject field. - -@internalComponent -*/ -void CSmsHeader::SetReplyEmailFieldsL(const CSmsEmailFields& aEmailFields, const TDesC& aReplySubjectFormat) - { - // Create the reply email fields - copy address and then format the subject, - // if one exists according to the reply prefix. - CSmsEmailFields* temp = CSmsEmailFields::NewL(); - CleanupStack::PushL(temp); - temp->AddAddressL(aEmailFields.Addresses().MdcaPoint(0)); - - SetEmailReplyForwardSubjectL(temp, aEmailFields.Subject(), aReplySubjectFormat); - - CleanupStack::Pop(temp); - delete iEmailFields; - iEmailFields = temp; - - // Set the PID for interworking with email. - CSmsPDU& pdu = Message().SmsPDU(); - if( pdu.ProtocolIdentifierPresent() ) - { - pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking); - pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice); - pdu.SetTelematicDeviceType(TSmsProtocolIdentifier::ESmsInternetElectronicMail); - } - } - -/** -Sets the email fields for a forward message. - -The address field is left empty. The subject field is formatted according to the -specified subject format using the subject from the specified email fields. - -The PID of the PDU of the message is set for interworking with email. - -@param aEmailFields -The email fields object. - -@param aForwardSubjectFormat -The format of the subject field. - -@internalComponent -*/ -void CSmsHeader::SetForwardEmailFieldsL(const CSmsEmailFields& aEmailFields, const TDesC& aForwardSubjectFormat) - { - // Create the reply email fields - copy address and then format the subject, - // if one exists according to the reply prefix. - CSmsEmailFields* temp = CSmsEmailFields::NewL(); - CleanupStack::PushL(temp); - - SetEmailReplyForwardSubjectL(temp, aEmailFields.Subject(), aForwardSubjectFormat); - - CleanupStack::Pop(temp); - delete iEmailFields; - iEmailFields = temp; - - // Set the PID for interworking with email. - CSmsPDU& pdu = Message().SmsPDU(); - if( pdu.ProtocolIdentifierPresent() ) - { - pdu.SetPIDType(TSmsProtocolIdentifier::ESmsPIDTelematicInterworking); - pdu.SetTelematicDeviceIndicator(TSmsProtocolIdentifier::ESmsTelematicDevice); - pdu.SetTelematicDeviceType(TSmsProtocolIdentifier::ESmsInternetElectronicMail); - } - } - -void CSmsHeader::SetEmailReplyForwardSubjectL(CSmsEmailFields* aEmailFields, const TDesC& aSubject, const TDesC& aSubjectFormat) - { - TInt length = aSubject.Length(); - if( length > 0 ) - { - // Prevent a chain of the format string appearing in the subject - check - // to see if the format string is already the prefix of the subject. - TInt formatPosInSubject = KErrNotFound; - - _LIT(KFormatStringSpecifier, "%S"); - TInt formatPos = aSubjectFormat.Find(KFormatStringSpecifier); - if( formatPos > 0 ) - { - // Look in current subject for the format string - avoid the '%'. - formatPosInSubject = aSubject.FindF(aSubjectFormat.Left(formatPos - 1)); - } - - // Need to format the string if the format string is not at the start of - // the current subject. - if( formatPosInSubject != 0 ) - { - // Create a buffer large enough to hold re-formated subject - need - // to subtract two from the prefix length (the %S). - length += aSubjectFormat.Length() - 2; - HBufC* buf = HBufC::NewLC(length); - TPtr ptr(buf->Des()); - - // Format the reply subject and set in the email fields. - ptr.Format(aSubjectFormat, &aSubject); - aEmailFields->SetSubjectL(*buf); - - CleanupStack::PopAndDestroy(buf); - } - else - { - // Subject already contains the format string - use it. - aEmailFields->SetSubjectL(aSubject); - } - } - } - -/** -The email fields object for this message. - -@return -The email fields object for this message. -*/ -EXPORT_C const CSmsEmailFields& CSmsHeader::EmailFields() const - { - return *iEmailFields; - } - -/** -Internalises the object from the specified stream. - -@param aStream -The stream to be read from. -*/ -EXPORT_C void CSmsHeader::InternalizeL(RMsvReadStream& aStream) - { -#if (!defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) - - aStream.ReadInt16L(); //version. Not used yet - - iRecipients.ResetAndDestroy(); - TInt count=aStream.ReadInt32L(); - while(count--) - { - CSmsNumber* recipient=CSmsNumber::NewL(); - CleanupStack::PushL(recipient); - recipient->InternalizeL(aStream); - iRecipients.AppendL(recipient); - CleanupStack::Pop(recipient); - } - - iFlags = aStream.ReadUint32L(); - iBioMsgIdType = (TBioMsgIdType) aStream.ReadInt8L(); - iMessage->InternalizeWithoutBufferL(aStream); -#else - iMessage->InternalizeWithoutBufferL(aStream); -#endif - } - -/** -Externalises the object to the specified stream. - -@param aStream -The stream to be writen to. -*/ -EXPORT_C void CSmsHeader::ExternalizeL(RMsvWriteStream& aStream) const - { -#if (!defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) - - aStream.WriteInt16L(KMsvSmsHeaderVersion); - - TInt count=iRecipients.Count(); - aStream.WriteInt32L(count); - - for (TInt i=0; iExternalizeL(aStream); - - aStream.WriteUint32L(iFlags); - aStream.WriteInt8L(iBioMsgIdType); - iMessage->ExternalizeWithoutBufferL(aStream); -#else - iMessage->ExternalizeWithoutBufferL(aStream); -#endif - } - -/** -Restores the object from the message entry store. - -The SMS object is restored from the KUidMsvSMSHeaderStream in the supplied store. - -@param aStore -The store from which the object is restored. - -@leave KErrNotFound -The stream KUidMsvSMSHeaderStream does not exist in aStore. -*/ -EXPORT_C void CSmsHeader::RestoreL(CMsvStore& aStore) - { -#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) - ReStoreDBL(aStore); - RMsvReadStream in; - in.OpenLC(aStore,KUidMsvSMSHeaderStream); - InternalizeL(in); - CleanupStack::PopAndDestroy(&in); -#else - - RMsvReadStream in; - in.OpenLC(aStore,KUidMsvSMSHeaderStream); - InternalizeL(in); - CleanupStack::PopAndDestroy(&in); - - iEmailFields->RestoreL(aStore); - -#endif - } - - -/** -Stores the object in the message entry store. - -The object is written to the KUidMsvSMSHeaderStream stream. Any previous content -is overwritten. - -@param aStore -The store to hold the stream into which the object is written. -*/ -EXPORT_C void CSmsHeader::StoreL(CMsvStore& aStore) const - { -#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) - StoreDbL(aStore); - RMsvWriteStream out; - out.AssignLC(aStore,KUidMsvSMSHeaderStream); - ExternalizeL(out); - out.CommitL(); - CleanupStack::PopAndDestroy(&out); - -#else - RMsvWriteStream out; - out.AssignLC(aStore,KUidMsvSMSHeaderStream); - ExternalizeL(out); - out.CommitL(); - CleanupStack::PopAndDestroy(&out); - - iEmailFields->StoreL(aStore); -#endif - } - - -/** -Check whether a CMsvStore contains an SMS header stream. - -@param aStore The store. -@return ETrue if there is a SMS header -*/ -EXPORT_C TBool CSmsHeader::ContainsSmsHeaderL(const CMsvStore& aStore) - { - return aStore.IsPresentL(KUidMsvSMSHeaderStream); - } - -CSmsHeader::CSmsHeader(CSmsMessage* aSmsMessage) -: iRecipients(KSmcmRecipientsGranularity), - iMessage(aSmsMessage), - iFlags(ESmsHeaderNoFlags), - iBioMsgIdType(EBioMsgIdNbs), - iCloseFs(ETrue) - { - } - -void CSmsHeader::ConstructL(CSmsPDU::TSmsPDUType aType, CEditableText& aText) - { - User::LeaveIfError(iFs.Connect()); - iMessage=CSmsMessage::NewL(iFs, aType, CSmsEditorBuffer::NewL(aText), EFalse); - iEmailFields = CSmsEmailFields::NewL(); - } - -void CSmsHeader::ConstructL(CSmsPDU::TSmsPDUType aType, CEditableText& aText, RFs& aFs) - { - iFs=aFs; - iCloseFs = EFalse; - iMessage=CSmsMessage::NewL(iFs, aType, CSmsEditorBuffer::NewL(aText), EFalse); - iEmailFields = CSmsEmailFields::NewL(); - } - -void CSmsHeader::ConstructL() - { - iEmailFields = CSmsEmailFields::NewL(); - - // Check the PID of the SMS PDU to see if set for interworking with email. - CSmsPDU& pdu = Message().SmsPDU(); - if( pdu.ProtocolIdentifierPresent() && - pdu.PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking && - pdu.TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice && - pdu.TelematicDeviceType() == TSmsProtocolIdentifier::ESmsInternetElectronicMail ) - { - __ASSERT_DEBUG( pdu.Type() == CSmsPDU::ESmsDeliver, User::Invariant() ); - - // Ok, this is an email SMS - parse out the address and the optional - // subject fields. - CSmsBufferBase& message = Message().Buffer(); - TInt length = message.Length(); - HBufC* buf = HBufC::NewLC(length); - TPtr bufPtr(buf->Des()); - message.Extract(bufPtr, 0, length); - - TInt end = iEmailFields->ParseL(*buf); - - if( end > 0 ) - { - TPtrC body((*buf).Mid(end)); - message.Reset(); - message.InsertL(0, body); - } - CleanupStack::PopAndDestroy(buf); - } - } - -void CSmsHeader::SetCanConcatenate(TBool aCanConcatenate) - { - iFlags = (iFlags & ~ESmsHeaderCanConcatenate) | (aCanConcatenate ? ESmsHeaderCanConcatenate : ESmsHeaderNoFlags); - } - -TBool CSmsHeader::CanConcatenate() const - { - return iFlags & ESmsHeaderCanConcatenate; - } - -/** -Gets the summary information for the specified acknowledgement. - -If the specified acknowledgement is not recognised, then this function returns -the default value of TMsvSmsEntryAckSummary::ENoAckSummary. -nothing. - -@param -aAckType The requested acknowledgement summary. - -@return -The acknowledgement summary information. - -@see -TMsvSmsEntry::TMsvSmsEntryAckSummary -*/ -EXPORT_C TMsvSmsEntry::TMsvSmsEntryAckSummary TMsvSmsEntry::AckSummary(TSmsAckType aAckType) const - { - TMsvSmsEntryAckSummary summary = ENoAckSummary; - switch( aAckType ) - { - case ESmsAckTypeDelivery: - summary = static_cast((iMtmData2 & EMsvSmsEntryDeliveryAckSummary) >> EMsvSmsEntryDeliveryAckSummaryShift); - break; - default: - // Use default summary - fail gracefully. - break; - } - return summary; - } - -/** -Sets the summary information for the specified acknowlwdgement. - -If the specified acknowledgement is not recognised, then this function does -nothing. - -@param -aAckType The acknowledgement summary to be set. - -@param -aAckSummary The summary information. - -@see -TMsvSmsEntry::TMsvSmsEntryAckSummary -*/ -EXPORT_C void TMsvSmsEntry::SetAckSummary(TSmsAckType aAckType, TMsvSmsEntryAckSummary aAckSummary) - { - switch( aAckType ) - { - case ESmsAckTypeDelivery: - iMtmData2 = (iMtmData2 & ~EMsvSmsEntryDeliveryAckSummary) | ((aAckSummary << EMsvSmsEntryDeliveryAckSummaryShift) & EMsvSmsEntryDeliveryAckSummary); - break; - default: - // Do nothing - fail gracefully. - break; - } - } - -/** -Gets the message log ID and a flag indicating if it is valid. - -The returned flag indicates whether the message log ID is valid. If it is valid -then the message has only a single recipient that is pending a status report. In -this case the returned message log ID refers to the recipient that is pending. - -If it is not valid then the message has more than one recipient that is pending -a status report. The message log ID should is not valid and should not be used. - -@param -aMessageId An output argument for the message log ID. - -@return -A flag indicating whether the message log ID aMessageId is valid or not. -*/ -EXPORT_C TBool TMsvSmsEntry::MessageId(TInt32& aMessageId) const - { - aMessageId = iMtmData3; - return iMtmData2 & EMsvSmsMessageValid; - } - -/** -Sets the message log ID and a flag indicating if it is valid. - -If the message has only a single recipient that is pending a status report then -the message log ID for that recipient can be set in the index. The flag must be -set to true. - -If the message has more than one recipient that is pending a status report then -the message log ID must not be used. The flag must be set to false. - -This functionality cannot be used with bio-messages. This function will panic if -used with a bio-message. - -@param -aMessageId The message log ID. Should only be used if aIsValid is true. It has - a default value of zero. - -@param -aIsValid A flag indicating if the message log ID is valid. This should have - a value or true if the message has only a single recipient pending - a status report. - -@panic USER 0 -This message is a bio-message and therefore the message ID field cannot be used. -*/ -EXPORT_C void TMsvSmsEntry::SetMessageId(TInt32 aMessageId, TBool aIsValid) - { - __ASSERT_ALWAYS( iBioType == 0, User::Invariant() ); - - aIsValid ? (iMtmData2 |= EMsvSmsMessageValid) : (iMtmData2 &= ~EMsvSmsMessageValid); - iMtmData3 = aMessageId; - } - -/** -Gets the reply to address if it exists, otherwise calls FromAddress(). - -Only valid for SMS-DELIVER type messages. -@return -The reply to address if it exists, otherwise the originator address as returned by FromAddress(). -*/ -TPtrC CSmsHeader::ReplyAddressL() const - { - - if(Type()==CSmsPDU::ESmsDeliver) - { - //Check for a reply address field - CSmsReplyAddressOperations& operations = STATIC_CAST(CSmsReplyAddressOperations&,Message().GetOperationsForIEL(CSmsInformationElement::ESmsReplyAddressFormat)); - if(!operations.ContainsReplyAddressIEL()) - { - //if there is no reply to field call FromAddress() - return FromAddress(); - } - //return the reply to address - HBufC* replyAddressHBuf=operations.GetReplyAddressL(); - return replyAddressHBuf->Des(); - } - else - { - return FromAddress(); - } - } - -#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) - -/** -Stores the object in the message entry store in SQL DB. - -The object is written to the KUidMsvSMSHeaderStream stream. Any previous content -is overwritten. - -@param aStore -The store to hold the stream into which the object is written. -*/ - -void CSmsHeader::StoreDbL(CMsvStore& aStore) const - { - _LIT(KDetails,""); - - CHeaderFields* smsHeaderFields = new(ELeave) CHeaderFields(); - CleanupStack::PushL(smsHeaderFields); - smsHeaderFields->iUid = KUidMsvSMSHeaderStream; - - // 1. Header version field. - CFieldPair* smsHeaderVersionfield = new(ELeave) CFieldPair(); - CleanupStack::PushL(smsHeaderVersionfield); - smsHeaderVersionfield->iFieldNumValue = KMsvSmsHeaderVersion; - smsHeaderFields->iFieldPairList.AppendL(smsHeaderVersionfield); - CleanupStack::Pop(smsHeaderVersionfield); - - // 2. Recipient count field. - CFieldPair* smsRecipientCountField = new(ELeave) CFieldPair(); - CleanupStack::PushL(smsRecipientCountField); - smsRecipientCountField->iFieldNumValue = iRecipients.Count(); - smsHeaderFields->iFieldPairList.AppendL(smsRecipientCountField); - CleanupStack::Pop(smsRecipientCountField); - - // 3. Recipients field. - TInt size = 0; - for (TInt i=0; i < iRecipients.Count(); i++) - { - size += sizeof(CMsvRecipient::TRecipientStatus); - size += 16; // CMsvRecipient::iError (4), iRetries(4) and iTime (8) - size += Align4(iRecipients[i]->Address().Size()); // CSmsNumber::iNumber - size += Align4(iRecipients[i]->Name().Size()); // CSmsNumber::iName - size += sizeof(TLogId); // CSmsNumber::iLogId - size += sizeof(CSmsNumber::TSmsAckStatus); // CSmsNumber::iDeliveryStatus - size += 10; // For delimiters - } - - RBuf recipients; - CleanupClosePushL(recipients); - recipients.CreateL(size); - - for (TInt i=0; iStatus()); //0 - recipients.Append(KComma); - recipients.AppendNum(iRecipients[i]->Error()); //1 - recipients.Append(KComma); - recipients.AppendNum(iRecipients[i]->Retries()); //2 - recipients.Append(KComma); - recipients.AppendNum(iRecipients[i]->Time().Int64()); //3 - recipients.Append(KComma); - - recipients.Append(iRecipients[i]->Address()); //4 - recipients.Append(KComma); - recipients.Append(iRecipients[i]->Name()); //5 - recipients.Append(KComma); - recipients.AppendNum(iRecipients[i]->LogId()); //6 - recipients.Append(KComma); - recipients.AppendNum(iRecipients[i]->AckStatus(ESmsAckTypeDelivery)); //7 - recipients.Append(KDelimiter); - } - - CFieldPair* smsRecipientsField = new(ELeave) CFieldPair(); - CleanupStack::PushL(smsRecipientsField); - smsRecipientsField->iFieldTextValue = recipients.AllocL(); - smsHeaderFields->iFieldPairList.AppendL(smsRecipientsField); - - CleanupStack::Pop(smsRecipientsField); // smsRecipientsField - CleanupStack::PopAndDestroy(); // recipients - - // 4. SMS Flag - CFieldPair* smsSmsFlags = new(ELeave) CFieldPair(); - CleanupStack::PushL(smsSmsFlags); - smsSmsFlags->iFieldNumValue = iFlags; - smsHeaderFields->iFieldPairList.AppendL(smsSmsFlags); - CleanupStack::Pop(smsSmsFlags); - - // 5. BIO Msg Id - CFieldPair* smsBioMsgIdType = new(ELeave) CFieldPair(); - CleanupStack::PushL(smsBioMsgIdType); - smsBioMsgIdType->iFieldNumValue = iBioMsgIdType; - smsHeaderFields->iFieldPairList.AppendL(smsBioMsgIdType); - CleanupStack::Pop(smsBioMsgIdType); - - - CFieldPair* smsdetailField = new (ELeave)CFieldPair(); - CleanupStack::PushL(smsdetailField); - smsdetailField->iFieldName = KDetails().AllocL(); - smsdetailField->iFieldType = ETextField; - smsdetailField->iFieldTextValue = KNullDesC().AllocL(); - smsHeaderFields->iFieldPairList.AppendL(smsdetailField); - CleanupStack::Pop(smsdetailField); - - TMsvWriteStore storeWriter(aStore); - storeWriter.AssignL(smsHeaderFields); - storeWriter.CommitL(); - - CleanupStack::Pop(smsHeaderFields); - - // 6. SMS-Email UID - // 7. SMS-EMail HeaderVersion - // 8. Subject - // 9. AddressCount - // 10. Addresses - - iEmailFields->StoreDBL(aStore); - - } - -/** -Restores the object from the message entry store in SQL DB. - -The SMS object is restored from the KUidMsvSMSHeaderStream in the supplied store. - -@param aStore -The store from which the object is restored. - -@leave KErrNotFound -The stream KUidMsvSMSHeaderStream does not exist in aStore. -*/ - -void CSmsHeader::ReStoreDBL(CMsvStore& aStore) - { - - CHeaderFields* rcvHeaderRow = NULL; - TMsvReadStore storeReader(aStore, KUidMsvSMSHeaderStream); - storeReader.LoadL(rcvHeaderRow); - - - iRecipients.ResetAndDestroy(); - - TInt i = 0; - CFieldPair* rcvHeader = rcvHeaderRow->iFieldPairList[i]; - - TInt16 headerversion = rcvHeaderRow->iFieldPairList[i++]->iFieldNumValue; // header version. - TInt count = rcvHeaderRow->iFieldPairList[i++]->iFieldNumValue; - - HBufC* receipientList = rcvHeaderRow->iFieldPairList[i++]->iFieldTextValue->Des().AllocL(); - CleanupStack::PushL(receipientList); - - TPtrC receipientListPtr = receipientList->Des(); - GetRecipientL(receipientListPtr); - - iFlags = rcvHeaderRow->iFieldPairList[i++]->iFieldNumValue; - iBioMsgIdType = (TBioMsgIdType)rcvHeaderRow->iFieldPairList[i++]->iFieldNumValue ; - - CleanupStack::PopAndDestroy(receipientList); - - iEmailFields->ReStoreDBL(aStore); - - } - -/** -Get the recipient strring and Create the recipient. - -@param : aRecipientStr A TPtrC16. -@return None. -*/ -void CSmsHeader::GetRecipientL(TDesC16& aRecipientStrList) - { - TPtrC16 aRecipientStr = aRecipientStrList.Left(aRecipientStrList.Length()); - - if(aRecipientStr.Length()>0) - { - RArray smsNumberData; - TInt startPos = 0; - TInt firstSemiColonPos = aRecipientStr.Locate(';'); - TInt lastSemiColonPos = aRecipientStr.LocateReverse(';'); - - do - { - CSmsNumber* recipientNumber=CSmsNumber::NewL(); - TPtrC16 str1 = aRecipientStr.Left(firstSemiColonPos+1); // First recipient - startPos = str1.Locate(',') ; - - while(startPos != KErrNotFound ) - { - TPtrC16 str2 = str1.Left(startPos); - smsNumberData.Append(str2); - - startPos++; - str1.Set(str1.Mid(startPos, str1.Length()- startPos)); - - startPos = str1.Locate(','); - if(startPos == KErrNotFound) - { - TPtrC16 str3; - str3.Set(str1.Mid(0,str1.Length()-1)); - smsNumberData.Append(str3); - break; - } - - } - - recipientNumber->SetStatus((CMsvRecipient::TRecipientStatus)ConvertToTInt(smsNumberData[0])); - recipientNumber->SetError(ConvertToTInt(smsNumberData[1])); - recipientNumber->SetRetries(ConvertToTInt(smsNumberData[2])); - TInt64 time = ConvertToTInt(smsNumberData[3]); - recipientNumber->SetTimeValue(time); - - //CSmsNumber - recipientNumber->SetAddressL(smsNumberData[4]); - recipientNumber->SetNameL(smsNumberData[5]); - - TLex logId(smsNumberData[6]); - TInt32 logIdNum; - logId.Val(logIdNum); - recipientNumber->SetLogId(logIdNum); - - TLex ackStatus(smsNumberData[7]); - TInt32 ackStatusNum; - recipientNumber->SetAckStatus( (TSmsAckType) ackStatus.Val(ackStatusNum), CSmsNumber::ENoAckRequested); - - iRecipients.AppendL(recipientNumber); - smsNumberData.Reset(); - - if(firstSemiColonPos != lastSemiColonPos) - { - aRecipientStr.Set(aRecipientStr.Mid(firstSemiColonPos+1,aRecipientStr.Length()-firstSemiColonPos-1)); - firstSemiColonPos = aRecipientStr.Locate(';'); - lastSemiColonPos = aRecipientStr.LocateReverse(';'); - } - else - { - break; - } - - }while(1); - - smsNumberData.Close(); - } - } - - -/** - * Convert a String to an Integer. - * @param aStr A string to make Integer. - * @return TInt A integer value - */ - TInt CSmsHeader::ConvertToTInt(TDesC16& aStr) - { - TLex str(aStr); - TInt32 string; - str.Val(string); - return string; - } - -#endif