diff -r 6b1d113cdff3 -r 6638e7f4bd8f smsprotocols/smsstack/gsmu/src/Gsmuelem.cpp --- a/smsprotocols/smsstack/gsmu/src/Gsmuelem.cpp Mon May 03 13:37:20 2010 +0300 +++ b/smsprotocols/smsstack/gsmu/src/Gsmuelem.cpp Thu May 06 15:10:38 2010 +0100 @@ -1,6436 +1,6436 @@ -// 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: -// This file implements the different PDU elements -// -// - -/** - @file -*/ - -#include -#include -#include "Gsmumain.h" -#include -#include "gsmupriv.h" -#include -#include -#include -#include -#include -#include -#include - -/** - * Question Mark character. - */ -const TInt KReplacementCharacter = 0x003f; - - -/** - * Constructs the object with a descriptor. The extraction mark and next character members are initialised to point to the start of the string. - * - * @param aSource Descriptor to be assigned by reference - */ -TGsmuLex8::TGsmuLex8(const TDesC8& aSource): TLex8(aSource) - { - //NOP - } // TGsmuLex8::TGsmuLex8 - - -/** - * Gets the next character in the string and increments the next character position. - * - * @return The next character in the string - * @leave Leaves with KErrGsmuDecoding if at end of string - */ -TUint8 TGsmuLex8::GetL() - { - if (Eos()) - LeaveL(); - - return static_cast(Get()); - } // TGsmuLex8::GetL - - -/** - * Increments the next character position by aNumber - * - * @param aNumber The number of characters to increment the next character position by. - * @leave If the increment puts the next character position before the start or beyond the end of the string, the function leaves with KErrGsmuDecoding. - */ -void TGsmuLex8::IncL(TInt aNumber) - { - if (aNumber != 0) - { - if (aNumber < 0 || Eos() || Remainder().Length() < aNumber) - LeaveL(); - else - Inc(aNumber); - } - } // TGsmuLex8::IncL - - -/** - * Checks there are enough remaining characters, then returns a TPtrC containing the next aLength characters. Does not increment the current position. - * - * @param aLength Number of characters to return - * @return Remainder().Left(aLength) - * @leave Leaves with KErrGsmuDecoding if there are insufficient characters remaining - */ -TPtrC8 TGsmuLex8::NextWithNoIncL(TInt aLength) const - { - return NextWithNoIncL(aLength, EFalse); - } - -/** - * Checks there are enough remaining characters, then returns a TPtrC containing the next aLength characters. Does not increment the current position. - * - * @param aLength Number of characters to return - * @param aAcceptTruncation ETrue if a mismatch between length indicator and actual length is acceptable. EFalse otherwise. - * @return Remainder().Left(aLength) if aAcceptTruncation is EFalse. Remainder() otherwise. - * @leave Leaves with KErrGsmuDecoding if there are insufficient characters remaining, unless aAcceptTruncation is ETrue. - */ -TPtrC8 TGsmuLex8::NextWithNoIncL(TInt aLength, TBool aAcceptTruncation) const - { - const TPtrC8 remainder(Remainder()); - - if ( (aLength < 0) || (remainder.Length()< aLength && !aAcceptTruncation) ) - { - LeaveL(); - } - - if (!aAcceptTruncation) - { - return Remainder().Left(aLength); - } - // aAcceptTruncation is ETrue - else if (remainder.Length() < aLength) - { - return Remainder(); - } - // otherwise, no need for truncation: - - return Remainder().Left(aLength); - } - - -/** - * Calls TGsmuLeax8::NextWithNoIncL then increments the next character position by aLength - * - * @param aLength Number of characters to return and increment the next character position - * @return Remainder().Left(aLength) - * @leave If the increment puts the next character position before the start or beyond the end of the string, the function leaves with KErrGsmuDecoding. - */ -TPtrC8 TGsmuLex8::NextAndIncL(TInt aLength) - { - const TPtrC8 next(NextWithNoIncL(aLength)); - IncL(aLength); - return next; - } // TGsmuLeax8::NextWithNoIncL - - -const TSmsOctet& TSmsOctet::operator = (TInt aValue) - { - iValue = static_cast(aValue); - return *this; - } // TSmsOctet::operator - - -TUint8* TSmsOctet::EncodeL(TUint8* aPtr) const - { - *aPtr=iValue; - return aPtr+1; - } // TSmsOctet::EncodeL - - -TSmsFirstOctet::TSmsFirstOctet(TInt aValue): - TSmsOctet(aValue) - { - } // TSmsFirstOctet::TSmsFirstOctet - - -const TSmsFirstOctet& TSmsFirstOctet::operator = (TInt aValue) - { - TSmsOctet::operator = (aValue); - return *this; - } // TSmsFirstOctet::operator - - -TSmsFailureCause::TSmsFailureCause(): - TSmsOctet(ESmsErrorUnspecified) - { - } // TSmsFailureCause::TSmsFailureCause - - -TSmsStatus::TSmsStatus(): - TSmsOctet(ESmsShortMessageReceivedBySME) - { - } // TSmsStatus::TSmsStatus - - -CSmsCommandData* CSmsCommandData::NewL(TSmsFirstOctet& aFirstOctet) - { - LOGGSMU1("CSmsCommandData::NewL()"); - - CSmsCommandData* commanddata=new(ELeave) CSmsCommandData(aFirstOctet); - CleanupStack::PushL(commanddata); - TPtrC8 ptr; - commanddata->SetDataL(ptr); - CleanupStack::Pop(); - return commanddata; - } // CSmsCommandData::NewL - - -CSmsCommandData::~CSmsCommandData() - { - iInformationElementArray.ResetAndDestroy(); - delete iBuffer; - } // CSmsCommandData::NewL - - -/** - * Duplicates this CSmsCommandData object. - * - * @return Pointer to the newly created CSmsCommandData object. - */ -CSmsCommandData* CSmsCommandData::DuplicateL() const - { - LOGGSMU1("CSmsCommandData::DuplicateL()"); - - CSmsCommandData* smsCommandData = CSmsCommandData::NewL(iFirstOctet); - CleanupStack::PushL(smsCommandData); - - smsCommandData->SetDataL(Data()); - - for (TInt ie = 0; ie < iInformationElementArray.Count(); ie++) - { - smsCommandData->AddInformationElementL(iInformationElementArray[ie]->Identifier(), - iInformationElementArray[ie]->Data()); - } - - CleanupStack::Pop(smsCommandData); - - return smsCommandData; - } // CSmsCommandData::DuplicateL - - -CSmsInformationElement& CSmsCommandData::InformationElement(TInt aIndex) const - { - LOGGSMU1("CSmsCommandData::InformationElement()"); - - CSmsInformationElement* ie=iInformationElementArray[aIndex]; - return *ie; - } // CSmsCommandData::InformationElement - - -CSmsInformationElement*& CSmsCommandData::InformationElementPtr(TInt aIndex) - { - // Ignore in code coverage - not used in SMS stack and not exported - // but cannot be removed as impacts public header. - BULLSEYE_OFF - LOGGSMU1("CSmsCommandData::InformationElementPtr()"); - return iInformationElementArray[aIndex]; - BULLSEYE_RESTORE - } - -TBool CSmsCommandData::InformationElementIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier, - TInt& aIndex) const - { - LOGGSMU1("CSmsCommandData::InformationElementIndex()"); - - TBool found=EFalse; - TInt count=NumInformationElements(); - for (TInt i=0; (!found) && (i=1) - SetHeaderPresent(ETrue); - } // CSmsCommandData::AddInformationElementL - - -void CSmsCommandData::RemoveInformationElement(TInt aIndex) - { - LOGGSMU1("CSmsCommandData::RemoveInformationElement()"); - // Since iInformationElementArray[aIndex] is removed from iInformationElementArray, no double free issue. - // coverity[double_free] - delete iInformationElementArray[aIndex]; - iInformationElementArray[aIndex] = NULL; - iInformationElementArray.Delete(aIndex); - - if (NumInformationElements()==0) - { - SetHeaderPresent(EFalse); - } - } // CSmsCommandData::RemoveInformationElement - - -TPtrC8 CSmsCommandData::Data() const - { - LOGGSMU1("CSmsCommandData::Data()"); - - TPtrC8 ptr; - ptr.Set(iBuffer->Des()); - return ptr; - } // CSmsCommandData::Data - - -void CSmsCommandData::SetDataL(const TDesC8& aData) - { - LOGGSMU1("CSmsCommandData::SetDataL()"); - - TInt length=aData.Length(); - __ASSERT_DEBUG(length<=KSmsMaxDataSize,Panic(KGsmuPanicCommandDataLengthTooLong)); - HBufC8* buffer=HBufC8::NewL(length); - delete iBuffer; - iBuffer=buffer; - iBuffer->Des().SetLength(length); - iBuffer->Des().Copy(aData); - } // CSmsCommandData::SetDataL - - -TUint8* CSmsCommandData::EncodeL(TUint8* aPtr) const - { - LOGGSMU1("CSmsCommandData::EncodeL()"); - - __ASSERT_DEBUG(iBuffer->Length()<=MaxDataLength(),Panic(KGsmuPanicCommandDataBufferTooLong)); - TSmsOctet datalength=iBuffer->Length()+TSmsOctet(TotalHeaderLengthInUDLUnits()); - aPtr=datalength.EncodeL(aPtr); - TPtr8 ptr((TUint8*) aPtr,datalength); - - if (HeaderPresent()) - { - TSmsOctet headerLength(HeaderLength()); - aPtr=headerLength.EncodeL(aPtr); - for (TInt i=0; iEncodeL(aPtr); - } - } - - ptr.Copy(iBuffer->Des()); - aPtr+=TInt(iBuffer->Length()); - return aPtr; - } // CSmsCommandData::EncodeL - - -void CSmsCommandData::DecodeL(TGsmuLex8& aPdu) - { - LOGGSMU1("CSmsCommandData::DecodeL()"); - - iInformationElementArray.ResetAndDestroy(); - const TBool headerPresent=HeaderPresent(); - TSmsOctet dataLength; - dataLength.DecodeL(aPdu); - - if (headerPresent) - { - TSmsOctet headerLength; - headerLength.DecodeL(aPdu); - if ((1+headerLength)>KSmsMaxDataSize) - User::Leave(KErrGsmSMSTpduNotSupported); - while (HeaderLength()DecodeL(aPdu); - iInformationElementArray.AppendL(informationElement); - CleanupStack::Pop(informationElement); - } - if (HeaderLength()!=headerLength) - User::Leave(KErrGsmSMSTpduNotSupported); - } - const TInt totalHeaderLength=TotalHeaderLengthInUDLUnits(); - const TInt totalDataLength=dataLength-totalHeaderLength; - const TPtrC8 next(aPdu.NextAndIncL(totalDataLength)); - SetDataL(next); - } // CSmsCommandData::DecodeL - - -void CSmsCommandData::InternalizeL(RReadStream& aStream) - { - iInformationElementArray.ResetAndDestroy(); - TInt numInformationElements=aStream.ReadInt32L(); - for (TInt i=0; i> *informationElement; - iInformationElementArray.AppendL(informationElement); - CleanupStack::Pop(); - } - HBufC8* buffer=HBufC8::NewL(aStream,KSmsMaxDataSize); - delete iBuffer; - iBuffer=buffer; - } // CSmsCommandData::InternalizeL - - -void CSmsCommandData::ExternalizeL(RWriteStream& aStream) const - { - TInt numInformationElements=iInformationElementArray.Count(); - aStream.WriteInt32L(numInformationElements); - for (TInt i=0; iLength(); - return headerLength; - } // CSmsCommandData::HeaderLength - - -TInt CSmsCommandData::TotalHeaderLengthInUDLUnits() const - { - LOGGSMU1("CSmsCommandData::TotalHeaderLengthInUDLUnits()"); - - if (iInformationElementArray.Count()==0) - return 0; - else - return (HeaderLength()+1); // +1 stands for UDHL - } // CSmsCommandData::TotalHeaderLengthInUDLUnits - - -TBool CSmsCommandData::HeaderPresent() const - { - LOGGSMU1("CSmsCommandData::HeaderPresent()"); - - return (iFirstOctet&TSmsFirstOctet::ESmsUDHIMask)==TSmsFirstOctet::ESmsUDHIHeaderPresent; - } // CSmsCommandData::HeaderPresent - - -void CSmsCommandData::SetHeaderPresent(TBool aHeaderPresent) - { - LOGGSMU1("CSmsCommandData::SetHeaderPresent()"); - - iFirstOctet=aHeaderPresent? (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderPresent: (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderNotPresent; - } // CSmsCommandData::SetHeaderPresent - - -TSmsParameterIndicator::TSmsParameterIndicator(): - TSmsOctet(ESmsPIDProtocolIdentifierPresent|ESmsPIDUserDataPresent|ESmsPIDDataCodingSchemePresent) - { - } // TSmsParameterIndicator::TSmsParameterIndicator - - -TSmsCommandType::TSmsCommandType(): - TSmsOctet(ESmsCommandTypeEnquiry) - { - } // TSmsCommandType::TSmsCommandType - - -TSmsProtocolIdentifier::TSmsProtocolIdentifier(): - TSmsOctet((TInt)ESmsPIDTelematicInterworking|(TInt)ESmsNoTelematicDevice) - { - } // TSmsProtocolIdentifier::TSmsProtocolIdentifier - - -TSmsProtocolIdentifier::TSmsTelematicDeviceIndicator TSmsProtocolIdentifier::TelematicDeviceIndicator() const - { - __ASSERT_DEBUG(PIDType()==ESmsPIDTelematicInterworking,Panic(KGsmuPanicNoTelematicInterworking)); - return (TSmsTelematicDeviceIndicator) (iValue&EPIDTelematicDeviceIndicatorMask); - } // TSmsProtocolIdentifier::TSmsTelematicDeviceIndicator - - -void TSmsProtocolIdentifier::SetTelematicDeviceIndicator(TSmsTelematicDeviceIndicator aIndicator) - { - LOGGSMU1("TSmsProtocolIdentifier::SetTelematicDeviceIndicator()"); - - __ASSERT_DEBUG(PIDType()==ESmsPIDTelematicInterworking,Panic(KGsmuPanicNoTelematicInterworking)); - - //iValue=(TUint8) ((iValue&ESmsPIDTypeMask)|aIndicator); - iValue=(TUint8) ((iValue&(~EPIDTelematicDeviceIndicatorMask))|aIndicator); - } // TSmsProtocolIdentifier::SetTelematicDeviceIndicator - - -TSmsProtocolIdentifier::TSmsTelematicDeviceType TSmsProtocolIdentifier::TelematicDeviceType() const - { - __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsTelematicDevice,Panic(KGsmuPanicNoTelematicDevice)); - return (TSmsTelematicDeviceType) (iValue&ESmsTelematicDeviceTypeMask); - } // TSmsProtocolIdentifier::TSmsTelematicDeviceType - - -void TSmsProtocolIdentifier::SetTelematicDeviceType(TSmsTelematicDeviceType aDeviceType) - { - LOGGSMU1("TSmsProtocolIdentifier::SetTelematicDeviceType()"); - - __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsTelematicDevice,Panic(KGsmuPanicNoTelematicDevice)); - iValue=(TUint8) ((iValue&(~ESmsTelematicDeviceTypeMask))|aDeviceType); - } // TSmsProtocolIdentifier::SetTelematicDeviceType - - -TInt TSmsProtocolIdentifier::ShortMessageALProtocol() const - { - // Ignore in code coverage - not used in SMS stack and not exported - // but cannot be removed as impacts public header. - BULLSEYE_OFF - LOGGSMU1("TSmsProtocolIdentifier::ShortMessageALProtocol()"); - - __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsNoTelematicDevice,Panic(KGsmuPanicNoTelematicDevice)); - return (TSmsShortMessageALProtocol) (iValue&ESmsShortMessageALProtocolMask); - BULLSEYE_RESTORE - } - -void TSmsProtocolIdentifier::SetShortMessageALProtocol(TSmsShortMessageALProtocol aProtocol) - { - // Ignore in code coverage - not used in SMS stack and not exported - // but cannot be removed as impacts public header. - BULLSEYE_OFF - LOGGSMU1("TSmsProtocolIdentifier::SetShortMessageALProtocol()"); - - __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsNoTelematicDevice,Panic(KGsmuPanicNoTelematicDevice)); - iValue=(TUint8) ((iValue&(~ESmsShortMessageALProtocolMask))|aProtocol); - BULLSEYE_RESTORE - } - -TInt TSmsProtocolIdentifier::ShortMessageType() const - { - LOGGSMU1("TSmsProtocolIdentifier::ShortMessageType()"); - - __ASSERT_DEBUG(PIDType()==ESmsPIDShortMessageType,Panic(KGsmuPanicNoShortMessageType)); - return (TSmsShortMessageType) (iValue&ESmsShortMessageTypeMask); - } // TSmsProtocolIdentifier::ShortMessageType - - -void TSmsProtocolIdentifier::SetShortMessageType(TSmsShortMessageType aShortMessageType) - { - LOGGSMU1("TSmsProtocolIdentifier::SetShortMessageType()"); - - __ASSERT_DEBUG(PIDType()==ESmsPIDShortMessageType,Panic(KGsmuPanicNoShortMessageType)); - //iValue=(TUint8) ((iValue&(~ESmsPIDTypeMask))|aShortMessageType); - iValue=(TUint8) ((iValue&(~ESmsShortMessageTypeMask))|aShortMessageType); - } // TSmsProtocolIdentifier::SetShortMessageType - - -TSmsDataCodingScheme::TSmsDataCodingScheme(): - TSmsOctet((TInt)ESmsDCSTextUncompressedWithNoClassInfo|(TInt)ESmsAlphabet7Bit|(TInt)ESmsClass0) - // Constructor is expected to set the octet = 0, This is needed by - // CSmsDeliverReport::DecodeL, CSmsSubmitReport::DecodeL and CSmsStatusReport::DecodeL, per - // 23.040 v6.5.0 section 9.2.3.27. - { - } // CSmsDeliverReport::DecodeL - - -TBool TSmsDataCodingScheme::TextCompressed() const - { - LOGGSMU1("TSmsDataCodingScheme::TextCompressed()"); - - TInt bits7to4=Bits7To4(); - return (bits7to4==ESmsDCSTextCompressedWithNoClassInfo) || (bits7to4==ESmsDCSTextCompressedWithClassInfo) || - (bits7to4==ESmsDCSAutoDelNoClassInfoCompressedText) || (bits7to4==ESmsDCSAutoDelClassInfoTextCompressedText); - } // TSmsDataCodingScheme::TextCompressed - - -void TSmsDataCodingScheme::SetTextCompressed(TBool aCompressed) - { - LOGGSMU1("TSmsDataCodingScheme::SetTextCompressed()"); - - TInt bits7to4=Bits7To4(); - if (aCompressed) - { - switch (bits7to4) - { - case (ESmsDCSTextUncompressedWithNoClassInfo): - { - iValue=(TUint8) (ESmsDCSTextCompressedWithNoClassInfo|(iValue&(~ESmsDCSBits7To4Mask))); - break; - } - case (ESmsDCSAutoDelNoClassInfoUncompressedText): - { - iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoCompressedText|(iValue&(~ESmsDCSBits7To4Mask))); - break; - } - case (ESmsDCSAutoDelClassInfoUncompressedText): - { - iValue=(TUint8) (ESmsDCSAutoDelClassInfoTextCompressedText|(iValue&(~ESmsDCSBits7To4Mask))); - break; - } - case (ESmsDCSTextUncompressedWithClassInfo): - case (ESmsDCSTextUncompressed7BitOr8Bit): - { - iValue=(TUint8) (ESmsDCSTextCompressedWithClassInfo|(iValue&(~ESmsDCSBits7To4Mask))); - break; - } - case (ESmsDCSTextCompressedWithNoClassInfo): - case (ESmsDCSTextCompressedWithClassInfo): - case (ESmsDCSAutoDelNoClassInfoCompressedText): - case (ESmsDCSAutoDelClassInfoTextCompressedText): - break; - default: - break; - // has to be tested, what happens in this default case - //Panic(KGsmuPanicNotSupportedWithDCSBits7To4); - } - } - else - { - switch (bits7to4) - { - case (ESmsDCSTextCompressedWithNoClassInfo): - { - iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&(~ESmsDCSBits7To4Mask))); - break; - } - case (ESmsDCSTextCompressedWithClassInfo): - { - iValue=(TUint8) (ESmsDCSTextUncompressedWithClassInfo|(iValue&(~ESmsDCSBits7To4Mask))); - break; - } - case (ESmsDCSAutoDelNoClassInfoCompressedText): - { - iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoUncompressedText|(iValue&(~ESmsDCSBits7To4Mask))); - break; - } - case (ESmsDCSAutoDelClassInfoTextCompressedText): - { - iValue=(TUint8) ( ESmsDCSAutoDelClassInfoUncompressedText|(iValue&(~ESmsDCSBits7To4Mask))); - break; - } - case (ESmsDCSTextUncompressedWithNoClassInfo): - case (ESmsDCSTextUncompressedWithClassInfo): - case (ESmsDCSAutoDelClassInfoUncompressedText): - case (ESmsDCSAutoDelNoClassInfoUncompressedText): - case (ESmsDCSTextUncompressed7BitOr8Bit): - default: - { - } - } - } - } // TSmsDataCodingScheme::SetTextCompressed - - -TSmsDataCodingScheme::TSmsAlphabet TSmsDataCodingScheme::Alphabet() const - { - LOGGSMU1("TSmsDataCodingScheme::TSmsAlphabet()"); - - TInt bits7to4=Bits7To4(); - TInt alphabet=ESmsAlphabet7Bit; - switch (bits7to4) - { - case (ESmsDCSTextUncompressedWithNoClassInfo): - case (ESmsDCSTextUncompressedWithClassInfo): - case (ESmsDCSTextCompressedWithNoClassInfo): // Alphabet not used in these cases - case (ESmsDCSTextCompressedWithClassInfo): - case (ESmsDCSAutoDelNoClassInfoUncompressedText): - case (ESmsDCSAutoDelClassInfoUncompressedText): - case (ESmsDCSAutoDelNoClassInfoCompressedText): - case (ESmsDCSAutoDelClassInfoTextCompressedText): - { - alphabet=iValue&ESmsAlphabetMask; - break; - } - case (ESmsDCSTextUncompressed7BitOr8Bit): - { - alphabet=iValue&ESmsAlphabet8Bit; // N.B. only one bit used to code alphabet - break; - } - case (ESmsDCSMessageWaitingIndicationDiscardMessage): - case (ESmsDCSMessageWaitingIndication7Bit): - { - alphabet=ESmsAlphabet7Bit; - break; - } - case (ESmsDCSMessageWaitingIndicationUCS2): - { - alphabet=ESmsAlphabetUCS2; - break; - } - default: - LOGGSMU1("TSmsDataCodingScheme::Alphabet() WARNING! default case has been reached"); - break; - } - return (TSmsAlphabet) alphabet; - } // TSmsDataCodingScheme::TSmsAlphabet - -void TSmsDataCodingScheme::SetAlphabet(TSmsAlphabet aAlphabet) - { - LOGGSMU1("TSmsDataCodingScheme::SetAlphabet()"); - - TInt bits7to4=Bits7To4(); - switch (bits7to4) - { - case (ESmsDCSTextUncompressedWithNoClassInfo): - case (ESmsDCSTextUncompressedWithClassInfo): - case (ESmsDCSTextCompressedWithNoClassInfo): // Alphabet not used in these cases - case (ESmsDCSTextCompressedWithClassInfo): - case (ESmsDCSAutoDelNoClassInfoUncompressedText): - case (ESmsDCSAutoDelClassInfoUncompressedText): - case (ESmsDCSAutoDelNoClassInfoCompressedText): - case (ESmsDCSAutoDelClassInfoTextCompressedText): - { - iValue=(TUint8) ((iValue&(~ESmsAlphabetMask))|aAlphabet); - break; - } - case (ESmsDCSTextUncompressed7BitOr8Bit): - { - if ((aAlphabet==ESmsAlphabet7Bit) || (aAlphabet==ESmsAlphabet8Bit)) - { - iValue=(TUint8) ((iValue&(~ESmsAlphabet8Bit))|aAlphabet); // N.B. only one bit used to code alphabet - } - break; - } - case (ESmsDCSMessageWaitingIndicationDiscardMessage): - { - if (aAlphabet!=ESmsAlphabet7Bit) - { - LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet); - } - break; - } - case (ESmsDCSMessageWaitingIndication7Bit): - { - if (aAlphabet==ESmsAlphabetUCS2) - { - iValue=(TUint8) (ESmsDCSMessageWaitingIndicationUCS2|(iValue&(~ESmsDCSBits7To4Mask))); - } - else - { - LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet); - } - break; - } - case (ESmsDCSMessageWaitingIndicationUCS2): - { - if (aAlphabet==ESmsAlphabet7Bit) - { - iValue=(TUint8) (ESmsDCSMessageWaitingIndication7Bit|(iValue&(~ESmsDCSBits7To4Mask))); - } - else - { - LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet); - } - break; - } - default: - LOGGSMU1("TSmsDataCodingScheme::SetAlphabet() WARNING! default case has been reached"); - break; - } - } // TSmsDataCodingScheme::SetAlphabet - - -TBool TSmsDataCodingScheme::Class(TSmsClass& aClass) const - { - LOGGSMU1("TSmsDataCodingScheme::Class()"); - - switch (Bits7To4()) - { - case (ESmsDCSTextUncompressedWithClassInfo): - case (ESmsDCSTextCompressedWithClassInfo): - case (ESmsDCSAutoDelClassInfoUncompressedText): - case (ESmsDCSAutoDelClassInfoTextCompressedText): - case (ESmsDCSTextUncompressed7BitOr8Bit): - aClass=(TSmsClass) (iValue&ESmsClassMask); - return ETrue; - default: - return EFalse; - } - } // TSmsDataCodingScheme::Class - - -void TSmsDataCodingScheme::SetClass(TBool aClassDefined,TSmsDataCodingScheme::TSmsClass aClass) - { - LOGGSMU1("TSmsDataCodingScheme::SetClass()"); - - TInt bits7to4=Bits7To4(); - if (aClassDefined) - { - switch (bits7to4) - { - case (ESmsDCSTextUncompressedWithNoClassInfo): - { - iValue=(TUint8) (ESmsDCSTextUncompressedWithClassInfo|(iValue&ESmsAlphabetMask|aClass)); - break; - } - case (ESmsDCSTextCompressedWithNoClassInfo): - { - iValue=(TUint8) (ESmsDCSTextCompressedWithClassInfo|(iValue&ESmsAlphabetMask|aClass)); - break; - } - case (ESmsDCSAutoDelNoClassInfoUncompressedText): - { - iValue=(TUint8) (ESmsDCSAutoDelClassInfoUncompressedText|(iValue&ESmsAlphabetMask|aClass)); - break; - } - case (ESmsDCSAutoDelNoClassInfoCompressedText): - { - iValue=(TUint8) (ESmsDCSAutoDelClassInfoTextCompressedText|(iValue&ESmsAlphabetMask|aClass)); - break; - } - case (ESmsDCSTextUncompressedWithClassInfo): - case (ESmsDCSTextCompressedWithClassInfo): - case (ESmsDCSAutoDelClassInfoUncompressedText): - case (ESmsDCSAutoDelClassInfoTextCompressedText): - case (ESmsDCSTextUncompressed7BitOr8Bit): - - { - iValue=(TUint8) (iValue&(~ESmsClassMask)|aClass); - break; - } - default: - LOGGSMU1("WARNING! default case has been reached"); - break; - } - } - else - { - switch (bits7to4) - { - case (ESmsDCSTextUncompressedWithClassInfo): - { - iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass); - break; - } - case (ESmsDCSTextCompressedWithClassInfo): - { - iValue=(TUint8) (ESmsDCSTextCompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass); - break; - } - case (ESmsDCSAutoDelClassInfoUncompressedText): - { - iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoUncompressedText|(iValue&ESmsAlphabetMask)|aClass); - break; - } - case (ESmsDCSAutoDelClassInfoTextCompressedText): - { - iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoCompressedText|(iValue&ESmsAlphabetMask)|aClass); - break; - } - case (ESmsDCSTextUncompressed7BitOr8Bit): - { - iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass); - break; - } - case (ESmsDCSTextUncompressedWithNoClassInfo): - case (ESmsDCSTextCompressedWithNoClassInfo): - case (ESmsDCSAutoDelNoClassInfoUncompressedText): - case (ESmsDCSAutoDelNoClassInfoCompressedText): - case (ESmsDCSMessageWaitingIndicationDiscardMessage): - case (ESmsDCSMessageWaitingIndication7Bit): - case (ESmsDCSMessageWaitingIndicationUCS2): - default: - { - } - } - } - } // TSmsDataCodingScheme::SetClass - - -TSmsDataCodingScheme::TSmsIndicationState TSmsDataCodingScheme::IndicationState() const - { - LOGGSMU1("TSmsDataCodingScheme::IndicationState()"); - - TInt bits7to4=Bits7To4(); - TSmsIndicationState state=ESmsIndicationInactive; - switch (bits7to4) - { - case (ESmsDCSMessageWaitingIndicationDiscardMessage): - case (ESmsDCSMessageWaitingIndication7Bit): - case (ESmsDCSMessageWaitingIndicationUCS2): - { - state=(TSmsIndicationState) (iValue&ESmsIndicationStateMask); - break; - } - default: - LOGGSMU1("WARNING! default case has been reached"); - break; - } - return state; - } // TSmsDataCodingScheme::TSmsIndicationState - - -void TSmsDataCodingScheme::SetIndicationState(TSmsIndicationState aState) - { - LOGGSMU1("TSmsDataCodingScheme::SetIndicationState()"); - - TInt bits7to4=Bits7To4(); - switch (bits7to4) - { - case (ESmsDCSMessageWaitingIndicationDiscardMessage): - case (ESmsDCSMessageWaitingIndication7Bit): - case (ESmsDCSMessageWaitingIndicationUCS2): - { - iValue=(TUint8) (aState | (iValue&(~ESmsIndicationStateMask))); - break; - } - default: - LOGGSMU1("TSmsDataCodingScheme::SetIndicationState() WARNING! default case has been reached"); - break; - } - } // TSmsDataCodingScheme::SetIndicationState - - -TSmsDataCodingScheme::TSmsIndicationType TSmsDataCodingScheme::IndicationType() const - { - LOGGSMU1("TSmsDataCodingScheme::IndicationType()"); - - TInt bits7to4=Bits7To4(); - TSmsIndicationType type=ESmsVoicemailMessageWaiting; - switch (bits7to4) - { - case (ESmsDCSMessageWaitingIndicationDiscardMessage): - case (ESmsDCSMessageWaitingIndication7Bit): - case (ESmsDCSMessageWaitingIndicationUCS2): - { - type=(TSmsIndicationType) (iValue&ESmsIndicationTypeMask); - break; - } - default: - LOGGSMU1("TSmsDataCodingScheme::IndicationType() WARNING default case has been reached"); - break; - } - return type; - } // TSmsDataCodingScheme::TSmsIndicationType - - -void TSmsDataCodingScheme::SetIndicationType(TSmsIndicationType aType) - { - LOGGSMU1("TSmsDataCodingScheme::SetIndicationType()"); - - TInt bits7to4=Bits7To4(); - switch (bits7to4) - { - case (ESmsDCSMessageWaitingIndicationDiscardMessage): - case (ESmsDCSMessageWaitingIndication7Bit): - case (ESmsDCSMessageWaitingIndicationUCS2): - { - iValue=(TUint8) (aType | (iValue&(~ESmsIndicationTypeMask))); - break; - } - default: - LOGGSMU1("TSmsDataCodingScheme::SetIndicationType() WARNING! default case has been reached"); - break; - } - } // TSmsDataCodingScheme::SetIndicationType - - -/** - * Allocates and creates a CSmsAlphabetConverter object, specifying an Alphabet - * Coding scheme and a Binary flag. - * - * @param aCharacterSetConverter Pre-initialised character set converter - * @param aFs File system handle - * @param aSmsAlphabet Data coding scheme alphabet - * @param aIsBinary Set to true for WAP or compressed data - * @return New CSmsAlphabetConverter object - * @capability None - */ -EXPORT_C CSmsAlphabetConverter* CSmsAlphabetConverter::NewLC(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsDataCodingScheme::TSmsAlphabet aSmsAlphabet,TBool aIsBinary) - { - LOGGSMU1("CSmsAlphabetConverter::NewLC()"); - - CSmsAlphabetConverter* converter=new (ELeave)CSmsAlphabetConverter(aCharacterSetConverter,aFs,aSmsAlphabet,aIsBinary); - CleanupStack::PushL(converter); - converter->ConstructL(); - return converter; - } // CSmsAlphabetConverter::NewLC - - -/** - * Destructor. - * @capability None - */ -EXPORT_C CSmsAlphabetConverter::~CSmsAlphabetConverter() - { - delete iConvertedNativeCharacters; - delete iConvertedUDElements; - delete iUnconvertedNativeCharacters; - delete iUnconvertedUDElements; - } // CSmsAlphabetConverter::NewLC - - -// -// C'tor - standard stuff -// -CSmsAlphabetConverter::CSmsAlphabetConverter(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsDataCodingScheme::TSmsAlphabet aSmsAlphabet,TBool aIsBinary) - : iCharacterSetConverter(aCharacterSetConverter), - iFs(aFs), - iSmsAlphabet(aSmsAlphabet), - iIsBinary(aIsBinary), - iUnconvertedNativeCharactersPtr(NULL,0), - iUnconvertedUDElementsPtr(NULL,0) - { - } // CSmsAlphabetConverter::CSmsAlphabetConverter - - -// -// Ensures this is a supported character set if not binary conversion -// -void CSmsAlphabetConverter::ConstructL() - { - LOGGSMU1("CSmsAlphabetConverter::ConstructL()"); - - - if (!iIsBinary) - { - switch (iSmsAlphabet) - { - case TSmsDataCodingScheme::ESmsAlphabet7Bit: - case TSmsDataCodingScheme::ESmsAlphabet8Bit: - case TSmsDataCodingScheme::ESmsAlphabetUCS2: - { - // Supported - break; - } - default: - { - // Not supported - User::Leave(KErrGsmSMSDataCodingSchemeNotSupported); - break; - } - } - } - } // CSmsAlphabetConverter::ConstructL - - -// -// Returns whether the character set converter is invoked. Provided to allow -// clients to provided efficient converted length calculation where no -// conversion is required. -// -void CSmsAlphabetConverter::ConversionPropertiesL(TSmsAlphabetConversionProperties& aConversionProperties) const - { - LOGGSMU1("CSmsAlphabetConverter::ConversionPropertiesL()"); - - - // Set defaults - aConversionProperties.iWidthConversion=ESmsAlphabetWidthConversionFixed; - aConversionProperties.iUDElementsPerNativeCharacter=1; - // Modify if different - if (iIsBinary) - return; - switch (iSmsAlphabet) - { - case TSmsDataCodingScheme::ESmsAlphabet7Bit: - case TSmsDataCodingScheme::ESmsAlphabet8Bit: - { - aConversionProperties.iWidthConversion=ESmsAlphabetWidthConversionVariable; - break; - } - case TSmsDataCodingScheme::ESmsAlphabetUCS2: - { - aConversionProperties.iUDElementsPerNativeCharacter=sizeof(TText); - break; - } - default: - { - User::Leave(KErrGsmSMSDataCodingSchemeNotSupported); - } - } - } // CSmsAlphabetConverter::ConversionPropertiesL - - -/** - * Converts from the native character set to unpacked user data elements of the - * desired character set. - * - * The function stores the converted data internally. - * - * @param aNativeCharacters The native character set data (Unicode only) - * @return Converted characters - * @capability None - */ -EXPORT_C TPtrC8 CSmsAlphabetConverter::ConvertFromNativeL(const TDesC& aNativeCharacters) - { - LOGGSMU1("CSmsAlphabetConverter::ConvertFromNativeL()"); - - TInt numberOfUnconvertibleCharacters, numberOfDowngradedCharacters; - - return ConvertFromNativeL(aNativeCharacters, ESmsEncodingNone, - numberOfUnconvertibleCharacters, - numberOfDowngradedCharacters); - } // CSmsAlphabetConverter::ConvertFromNativeL - - -/** - * Converts from the native character set to unpacked user data elements of the - * desired character set. - * - * The function stores the converted data internally. - * - * @param aNativeCharacters The native character set data (Unicode only) - * @param aNumberOfUnconvertibleCharacters Number of characters unconverted - * @param aNumberOfDowngradedCharacters Number of characters downgraded - * @param aEncoding Alternative 7bit encoding to used (if needed) - * - * @return Converted characters - * - * @capability None - */ -EXPORT_C TPtrC8 CSmsAlphabetConverter::ConvertFromNativeL(const TDesC& aNativeCharacters, - TSmsEncoding aEncoding, - TInt& aNumberOfUnconvertibleCharacters, - TInt& aNumberOfDowngradedCharacters) - { - LOGGSMU2("CSmsAlphabetConverter::ConvertFromNativeL(): aEncoding=%d", aEncoding); - - aNumberOfUnconvertibleCharacters = 0; - aNumberOfDowngradedCharacters = 0; - - // Check for some shortcuts - if (iIsBinary || iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit) - { - // Binary data stored as padded unicode - TPtr8 outputPtr=CheckAllocBufferL(&iConvertedUDElements,aNativeCharacters.Length(),0); - outputPtr.Copy(aNativeCharacters); - iUnconvertedNativeCharactersPtr.Zero(); - return outputPtr; - } - else if (iSmsAlphabet==TSmsDataCodingScheme::ESmsAlphabetUCS2) - { - TInt nativeCharactersLength = aNativeCharacters.Length(); - // 16-bit copy with possible endianess correction - TInt elementCount=nativeCharactersLength*2; - TPtr8 outputPtr(CheckAllocBufferL(&iConvertedUDElements,elementCount,elementCount)); - for (TInt i=0;i>8); - outputPtr[2*i+1]=(TUint8)aNativeCharacters[i]; - } - iUnconvertedNativeCharactersPtr.Zero(); - return outputPtr; - } - else // No shortcuts, do proper conversion - { - PrepareForConversionFromNativeL(aEncoding); - - // Create input buffer - TInt newInputLength=iUnconvertedNativeCharactersPtr.Length()+aNativeCharacters.Length(); - iUnconvertedNativeCharactersPtr.Set(CheckAllocBufferL(&iUnconvertedNativeCharacters,newInputLength,iUnconvertedNativeCharactersPtr.Length())); - iUnconvertedNativeCharactersPtr.Append(aNativeCharacters); - - // Ensure buffer is at least the length of the input buffer - TPtr8 outputPtr=CheckAllocBufferL(&iConvertedUDElements,iUnconvertedNativeCharactersPtr.Length(),0); - - TInt retryCount=0; - TInt unconvertedCount=iUnconvertedNativeCharactersPtr.Length(); - while (unconvertedCount) - { - TInt tempNumberOfUnconvertibleCharacters = 0; - TInt tempNumberOfDowngradedCharacters = 0; - - // Get a pointer to unfilled area of output buffer - TPtr8 fillPtr((TUint8*)outputPtr.Ptr()+outputPtr.Length(),0,outputPtr.MaxLength()-outputPtr.Length()); - // Try the conversion & get number of unconverted characters - TInt newUnconvertedCount=iCharacterSetConverter.ConvertFromUnicode(fillPtr,iUnconvertedNativeCharactersPtr); - if (newUnconvertedCount<0) - break; - - // Compare what is converted with the original, to get downgrade count - TPtr tempBufPtr((TUint16*)iUnconvertedNativeCharactersPtr.Ptr(), 0, fillPtr.Length()); - TInt offset = aNativeCharacters.Length() - unconvertedCount; - TInt state = CCnvCharacterSetConverter::KStateDefault; - TInt notRestored = iCharacterSetConverter.ConvertToUnicode(tempBufPtr, fillPtr, state); - - if (notRestored > 0) - { - tempNumberOfUnconvertibleCharacters += notRestored; - } - - for (TInt pos = 0; pos < tempBufPtr.Length(); pos++) - { - if (tempBufPtr[pos] != aNativeCharacters[offset + pos]) - { - if (tempBufPtr[pos] != KReplacementCharacter) - { - tempNumberOfDowngradedCharacters++; - } - else - { - tempNumberOfUnconvertibleCharacters++; - } - } - } - - // - // If characters were downgraded or unconverted then replace them - // with downgrades from the PREQ2090 converter. - // - if (tempNumberOfUnconvertibleCharacters > 0 && - aEncoding != ESmsEncodingNone) - { - HBufC8* downgradesBuf = HBufC8::NewLC(iUnconvertedNativeCharactersPtr.Length()); - HBufC* nativeBuf = HBufC::NewLC(iUnconvertedNativeCharactersPtr.Length()); - TPtr8 downgradesPtr = downgradesBuf->Des(); - TPtr nativePtr = nativeBuf->Des(); - - PrepareForConversionFromNativeL(ESmsEncodingNone); - - // Attempt to convert the text - TInt ret = iCharacterSetConverter.ConvertFromUnicode(downgradesPtr, iUnconvertedNativeCharactersPtr); - if (ret >= 0) - { - // Compare what is converted with the original... - state = CCnvCharacterSetConverter::KStateDefault; - notRestored = iCharacterSetConverter.ConvertToUnicode(nativePtr, downgradesPtr, state); - - if (notRestored >= 0) - { - // Merge in the downgrades - TInt pos; - - for (pos = 0; pos < tempBufPtr.Length(); pos++) - { - if (tempBufPtr[pos] != aNativeCharacters[offset + pos]) - { - if (tempBufPtr[pos] != KReplacementCharacter) - { - tempBufPtr[pos] = nativePtr[pos]; - } - } - } - - // Reconvert... - PrepareForConversionFromNativeL(aEncoding); - - newUnconvertedCount=iCharacterSetConverter.ConvertFromUnicode(fillPtr,iUnconvertedNativeCharactersPtr); - if (newUnconvertedCount<0) - break; - - // Recount the changed characters... - tempNumberOfUnconvertibleCharacters = 0; - tempNumberOfDowngradedCharacters = 0; - - for (pos = 0; pos < tempBufPtr.Length(); pos++) - { - if (tempBufPtr[pos] != aNativeCharacters[offset + pos]) - { - if (tempBufPtr[pos] != KReplacementCharacter) - { - tempNumberOfDowngradedCharacters++; - } - else - { - tempNumberOfUnconvertibleCharacters++; - } - } - } - } - } - - CleanupStack::PopAndDestroy(2, downgradesBuf); - } - - // - // Store these downgraded/unconvertible character counts... - // - aNumberOfDowngradedCharacters += tempNumberOfDowngradedCharacters; - aNumberOfUnconvertibleCharacters += tempNumberOfUnconvertibleCharacters; - - // Update original buffer length, check retry count and realloc if req'd - outputPtr.SetLength(outputPtr.Length()+fillPtr.Length()); - if (newUnconvertedCount==unconvertedCount) - { - if (++retryCount>KMaxSmsAlphabetConversionRetries) - { - __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicConversionRetriedOut)); - break; - } - } - else - { - iUnconvertedNativeCharactersPtr.Delete(0,unconvertedCount-newUnconvertedCount); - retryCount=0; - } - unconvertedCount=newUnconvertedCount; - // Check for realloc - if (unconvertedCount) - outputPtr.Set(CheckAllocBufferL(&iConvertedUDElements,iConvertedUDElements->Length()+Max(unconvertedCount,KMinSmsAlphabetConversionAllocIncrement),outputPtr.Length())); - } - - return outputPtr; - } - } // CSmsAlphabetConverter::ConvertFromNativeL - - -/** - * Converts the user data elements of the specified character set to the native - * character set. - * - * @param aUDElements The converted character set data - * - * @return Native character set data (Unicode only) - * - * @capability None - */ -EXPORT_C TPtrC CSmsAlphabetConverter::ConvertToNativeL(const TDesC8& aUDElements) - { - LOGGSMU1("CSmsAlphabetConverter::ConvertToNativeL()"); - - return ConvertToNativeL(aUDElements, ESmsEncodingNone); - } // CSmsAlphabetConverter::ConvertToNativeL - - -/** - * Converts the user data elements of the specified character set to the native - * character set. - * - * @param aUDElements The converted character set data - * @param aEncoding Alternative 7bit encoding to used (if needed) - * - * @return Native character set data (Unicode only) - * - * @capability None - */ -EXPORT_C TPtrC CSmsAlphabetConverter::ConvertToNativeL(const TDesC8& aUDElements, - TSmsEncoding aEncoding) - { - LOGGSMU2("CSmsAlphabetConverter::ConvertToNativeL(): aEncoding=%d", aEncoding); - - // Check for some shortcuts - if (iIsBinary || iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit) - { - // Binary data stored as padded unicode - TPtr16 outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,aUDElements.Length(),0); - outputPtr.Copy(aUDElements); - iUnconvertedUDElementsPtr.Zero(); - return outputPtr; - } - else if (iSmsAlphabet==TSmsDataCodingScheme::ESmsAlphabetUCS2) - { - // 16-bit copy with possible endianess correction - TInt charCount=aUDElements.Length()/2; - TPtr16 outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,charCount,charCount); - for (TInt i=0; iKMaxSmsAlphabetConversionRetries) - { - __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicConversionRetriedOut)); - break; - } - } - else - { - iUnconvertedUDElementsPtr.Delete(0,unconvertedCount-newUnconvertedCount); - retryCount=0; - } - unconvertedCount=newUnconvertedCount; - // Check for realloc - if (unconvertedCount) - outputPtr.Set(CheckAllocBufferL(&iConvertedNativeCharacters,iConvertedNativeCharacters->Length()+Max(unconvertedCount,KMinSmsAlphabetConversionAllocIncrement),outputPtr.Length())); - } - return outputPtr; - } - } // CSmsAlphabetConverter::ConvertToNativeL - - -/** - * Tests if the character is supported by the current character set. - * This function can be used with 7bit and 8bit alphabets. - * - * @param aChar Character to investigate. - * - * @return ETrue if the character is supported. - * - * @note Since the function is based on the old behaviour (pre-PREQ2090) - * it does not accept a downgraded character or alternative encoding - * as being supported. - */ -TBool CSmsAlphabetConverter::IsSupportedL(TChar aChar) - { - LOGGSMU2("[1] CSmsAlphabetConverter::IsSupportedL(aChar=0x%04x)", (TUint) aChar); - - TBool isDowngrade, isRequiresAlternativeEncoding; - - TBool supported = IsSupportedL(aChar, ESmsEncodingNone, - isDowngrade, isRequiresAlternativeEncoding); - - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported); - - return supported; - } // CSmsAlphabetConverter::IsSupportedL - - -/** - * Tests if the descriptor text is supported by the current character set. - * This function can be used with 7bit and 8bit alphabets. - * - * @param aDes Text string to check. - * @param aNumberOfUnconvertibleCharacters Exit param for the number of - * characters unconvertible. - * @param aIndexOfFirstUnconvertibleCharacter Exit param for the first - * unconverted character. - * - * @return ETrue if the character is supported. - */ -TBool CSmsAlphabetConverter::IsSupportedL(const TDesC& aDes, TInt& aNumberOfUnconvertibleCharacters, - TInt& aIndexOfFirstUnconvertibleCharacter) - { - LOGGSMU2("[2] CSmsAlphabetConverter::IsSupportedL(aDes=\"%S\")", &aDes); - - TInt desLength = aDes.Length(); - // - // Initialise the exit params... - // - aNumberOfUnconvertibleCharacters = 0; - aIndexOfFirstUnconvertibleCharacter = desLength; - - // - // Create buffers for the input converted to 7Bit and a buffer for it once - // converted back again... - // - HBufC8* encodedBuf = HBufC8::NewLC(desLength*2); // worse case - HBufC* backToUnicodeAfterStdBuf = HBufC::NewLC(desLength); - TPtr8 encoded(encodedBuf->Des()); - TPtr backToUnicodeAfterStd(backToUnicodeAfterStdBuf->Des()); - - // - // Convert the input string to standard 7bit (with downgrades if needed)... - // - PrepareForConversionFromNativeL(ESmsEncodingNone); - - TInt notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes); - - if (notConverted > 0) - { - aNumberOfUnconvertibleCharacters += notConverted; - } - else if (notConverted < 0) - { - aNumberOfUnconvertibleCharacters = desLength; - } - - // - // Convert it back again to the native format... - // - TInt state = CCnvCharacterSetConverter::KStateDefault; - TInt notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterStd, encoded, state); - - if (notRestored > 0) - { - aNumberOfUnconvertibleCharacters += notRestored; - } - else if (notRestored < 0) - { - aNumberOfUnconvertibleCharacters = desLength; - } - - // - // Work out if the string is acceptable as it is (e.g. no unconvertible - // and no downgrades). We only need do this if the previous conversions were - // complete with no issues. - // - for (TInt pos = desLength-1; pos >= 0; --pos) - { - if (backToUnicodeAfterStd[pos] != aDes[pos]) - { - aNumberOfUnconvertibleCharacters++; - aIndexOfFirstUnconvertibleCharacter = pos; - } - } - - CleanupStack::PopAndDestroy(backToUnicodeAfterStdBuf); - CleanupStack::PopAndDestroy(encodedBuf); - - // - // Useful logging... - // - TBool supported = (aNumberOfUnconvertibleCharacters == 0); - - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfUnconvertibleCharacters=%d.", aNumberOfUnconvertibleCharacters); - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIndexOfFirstUnconvertibleCharacter=%d.", aIndexOfFirstUnconvertibleCharacter); - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported); - - return supported; - } // CSmsAlphabetConverter::IsSupportedL - - -/** - * Tests if the character is supported by the current character set. - * This function can be used with 7bit and 8bit alphabets. - * - * @param aChar Character to investigate. - * @param aEncoding Alternative 7bit encoding (if used). - * @param aIsDowngrade Exit param set to ETrue if the - * character has to be downgraded. - * @param aRequiresAlternativeEncoding Exit param set to ETrue if the - * alternative encoding has to be - * used to encode it. - * - * @return ETrue if the character is supported. - */ -TBool CSmsAlphabetConverter::IsSupportedL(TChar aChar, TSmsEncoding aEncoding, - TBool& aIsDowngrade, - TBool& aRequiresAlternativeEncoding) - { - LOGGSMU2("[3] CSmsAlphabetConverter::IsSupportedL(aChar=0x%04x)", (TUint) aChar); - - // - // Convert the character... - // - TInt numberOfUnconvertibleCharacters, numberOfDowngradedCharacters, - numberRequiringAlternativeEncoding, indexOfFirstUnconvertibleCharacter; - TBuf<4> toEncode; - - toEncode.SetLength(1); - toEncode[0]=(TText)aChar; - - TBool supported = IsSupportedL(toEncode, aEncoding, - numberOfUnconvertibleCharacters, - numberOfDowngradedCharacters, - numberRequiringAlternativeEncoding, - indexOfFirstUnconvertibleCharacter); - - // - // Calculate the exit params... - // - aIsDowngrade = (numberOfDowngradedCharacters > 0); - aRequiresAlternativeEncoding = (numberRequiringAlternativeEncoding > 0); - - // - // Useful logging... - // - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIsDowngrade=%d.", aIsDowngrade); - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aRequiresAlternativeEncoding=%d.", aRequiresAlternativeEncoding); - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported); - - return supported; - } // CSmsAlphabetConverter::IsSupportedL - - -/** - * Tests if the descriptor text is supported by the current character set. - * This function can be used with 7bit and 8bit alphabets. - * - * @param aDes Text string to check. - * @param aEncoding Alternative 7bit encoding (if used). - * @param aNumberOfUnconvertibleCharacters Exit param for the number of - * characters unconvertible. - * @param aNumberOfDowngradedCharacters Exit param for the number of - * downgraded characters. - * @param aNumberRequiringAlternativeEncoding Exit param for the number of - * characters requiring use of - * the alternative encoder. - * @param aIndexOfFirstUnconvertibleCharacter Exit param for the first - * unconverted character. - * - * @return ETrue if the character is supported. - */ -TBool CSmsAlphabetConverter::IsSupportedL(const TDesC& aDes, TSmsEncoding aEncoding, - TInt& aNumberOfUnconvertibleCharacters, - TInt& aNumberOfDowngradedCharacters, - TInt& aNumberRequiringAlternativeEncoding, - TInt& aIndexOfFirstUnconvertibleCharacter) - { - LOGGSMU2("[4] CSmsAlphabetConverter::IsSupportedL(aDes=\"%S\")", &aDes); - - TInt desLength = aDes.Length(); - // - // Initialise the exit params... - // - aNumberOfUnconvertibleCharacters = 0; - aNumberOfDowngradedCharacters = 0; - aNumberRequiringAlternativeEncoding = 0; - aIndexOfFirstUnconvertibleCharacter = desLength; - - // - // Create buffers for the input converted to 7Bit and a buffer for it once - // converted back again... - // - HBufC8* encodedBuf = HBufC8::NewLC(desLength*2); // worse case - HBufC* backToUnicodeAfterStdBuf = HBufC::NewLC(desLength); - TPtr8 encoded(encodedBuf->Des()); - TPtr backToUnicodeAfterStd(backToUnicodeAfterStdBuf->Des()); - - // - // Convert the input string to standard 7bit (with downgrades if needed)... - // - PrepareForConversionFromNativeL(ESmsEncodingNone); - - TInt notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes); - - if (notConverted > 0) - { - aNumberOfUnconvertibleCharacters += notConverted; - } - else if (notConverted < 0) - { - aNumberOfUnconvertibleCharacters = desLength; - } - - // - // Convert it back again to the native format... - // - TInt state = CCnvCharacterSetConverter::KStateDefault; - TInt notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterStd, encoded, state); - - if (notRestored > 0) - { - aNumberOfUnconvertibleCharacters += notRestored; - } - else if (notRestored < 0) - { - aNumberOfUnconvertibleCharacters = desLength; - } - - // - // Work out if the string is acceptable as it is (e.g. no unconvertible - // and no downgrades). - // - for (TInt pos = desLength-1; pos >= 0; --pos) - { - if (backToUnicodeAfterStd[pos] != aDes[pos]) - { - if (backToUnicodeAfterStd[pos] != KReplacementCharacter) - { - aNumberOfDowngradedCharacters++; - } - else - { - aNumberOfUnconvertibleCharacters++; - aIndexOfFirstUnconvertibleCharacter = pos; - } - } - } - - TInt totalCharFaultsSoFar = aNumberOfUnconvertibleCharacters + - aNumberOfDowngradedCharacters; - - // - // If the total unconvertible plus downgrades is zero, then there is nothing - // more to do as the string can be converted to 7bit with no issues and no - // other encoder is needed. - // - // Otherwise we have to look at the alternative encoder... - // - if (totalCharFaultsSoFar == 0) - { - // - // We are done (the return counts are already zero and therefore - // correct at this point too!). - // - } - else if (iSmsAlphabet != TSmsDataCodingScheme::ESmsAlphabet7Bit || - aEncoding == ESmsEncodingNone) - { - // - // The string was not perfectly converted, but there is no alternative - // encoder to try. We are done. - // - } - else - { - // - // Initialise the params... - // - TInt tmpDowngradedCharacters = 0; - TInt tmpUnconvertibleCharacters = 0; - TInt tmpIndexOfFirstUnconvertibleCharacter = desLength; - - // - // Convert the input string to the alternative encoding... - // - PrepareForConversionFromNativeL(aEncoding); - - notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes); - if (notConverted > 0) - { - tmpUnconvertibleCharacters = notConverted; - } - else if (notConverted < 0) - { - tmpUnconvertibleCharacters = desLength; - } - - // - // Convert it back again to the native format... - // - HBufC* backToUnicodeAfterAltBuf = HBufC::NewLC(desLength); - TPtr backToUnicodeAfterAlt(backToUnicodeAfterAltBuf->Des()); - TInt state = CCnvCharacterSetConverter::KStateDefault; - TInt notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterAlt, encoded, state); - - if (notRestored > 0) - { - tmpUnconvertibleCharacters += notRestored; - } - else if (notRestored < 0) - { - tmpUnconvertibleCharacters = desLength; - } - - // - // Now work out which characters are downgrades, require alternative encoding - // or are unsupported. - // - for (TInt pos = desLength-1; pos >= 0; --pos) - { - if (backToUnicodeAfterStd[pos] != aDes[pos]) - { - // Not supported by standard encoder... - if (backToUnicodeAfterAlt[pos] == aDes[pos]) - { - // Supported by alternative encoder... - aNumberRequiringAlternativeEncoding++; - } - else if (backToUnicodeAfterStd[pos] != KReplacementCharacter) - { - // Downgraded by standard encoder... - tmpDowngradedCharacters++; - } - else if (backToUnicodeAfterAlt[pos] != KReplacementCharacter) - { - // Downgraded by alternative encoder... - tmpDowngradedCharacters++; - aNumberRequiringAlternativeEncoding++; - } - else - { - // Unconvertible... - tmpUnconvertibleCharacters++; - tmpIndexOfFirstUnconvertibleCharacter = pos; - } - } - } - - // Is this better? - if ( totalCharFaultsSoFar >= (tmpUnconvertibleCharacters + tmpDowngradedCharacters) ) - { - // Best conversion is the alternative conversion - aNumberOfUnconvertibleCharacters = tmpUnconvertibleCharacters; - aNumberOfDowngradedCharacters = tmpDowngradedCharacters; - aIndexOfFirstUnconvertibleCharacter = tmpIndexOfFirstUnconvertibleCharacter; - } - else - { - // Best conversion is the standard conversion - aNumberRequiringAlternativeEncoding = 0; - } - - CleanupStack::PopAndDestroy(backToUnicodeAfterAltBuf); - } - - CleanupStack::PopAndDestroy(backToUnicodeAfterStdBuf); - CleanupStack::PopAndDestroy(encodedBuf); - - // - // Useful logging... - // - TBool supported = (aNumberOfUnconvertibleCharacters == 0); - - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfUnconvertibleCharacters=%d.", aNumberOfUnconvertibleCharacters); - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfDowngradedCharacters=%d.", aNumberOfDowngradedCharacters); - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberRequiringAlternativeEncoding=%d.", aNumberRequiringAlternativeEncoding); - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIndexOfFirstUnconvertibleCharacter=%d.", aIndexOfFirstUnconvertibleCharacter); - LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported); - - return supported; - } // CSmsAlphabetConverter::IsSupportedL - - -/** - * Given a piece of text and an alternative encoding, this function works out - * which encoding is best to use and returns the ID of that converter. - * - * @param aNativeCharacters Text to use as a sample. - * @param aEncoding Suggested alternative 7bit encoding method. - * - * @return Encoding that should be used. - */ -TSmsEncoding CSmsAlphabetConverter::FindBestAlternativeEncodingL(const TDesC& aNativeCharacters, - TSmsEncoding aSuggestedEncoding) - { - LOGGSMU2("CSmsAlphabetConverter::FindBestAlternativeEncodingL(): aSuggestedEncoding=%d", - aSuggestedEncoding); - - TSmsEncoding encodingToUse = ESmsEncodingNone; - - // - // If this is not 7bit or the alternative encoding is not set then do - // nothing... - // - if (aSuggestedEncoding != ESmsEncodingNone && - iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet7Bit) - { - TInt numberOfUnconvertibleCharacters, numberOfDowngradedCharacters; - TInt numberRequiringAlternativeEncoding, indexOfFirstUnconvertibleCharacter; - - // - // First try the default encoding (but in this case treat downgrades - // as unconverted, since later encoders might do better)... - // - IsSupportedL(aNativeCharacters, ESmsEncodingNone, - numberOfUnconvertibleCharacters, - numberOfDowngradedCharacters, - numberRequiringAlternativeEncoding, - indexOfFirstUnconvertibleCharacter); - - TInt leastUnconvertibleCharacters = numberOfUnconvertibleCharacters + numberOfDowngradedCharacters; - - // - // Create a list of alternative encodings to try... - // - TSmsEncoding encodingList[8]; - TInt encodingCount = 0; - - if (aSuggestedEncoding == ESmsEncodingTurkishLockingAndSingleShift) - { - encodingList[encodingCount++] = ESmsEncodingTurkishSingleShift; - encodingList[encodingCount++] = ESmsEncodingTurkishLockingShift; - } - else if (aSuggestedEncoding == ESmsEncodingPortugueseLockingAndSingleShift) - { - encodingList[encodingCount++] = ESmsEncodingPortugueseSingleShift; - encodingList[encodingCount++] = ESmsEncodingPortugueseLockingShift; - } - - encodingList[encodingCount++] = aSuggestedEncoding; - encodingList[encodingCount++] = ESmsEncodingNone; - - // - // Now try the all the alternatives... - // - for (TInt encoder = 0; encoder < encodingCount; encoder++) - { - IsSupportedL(aNativeCharacters, encodingList[encoder], - numberOfUnconvertibleCharacters, - numberOfDowngradedCharacters, - numberRequiringAlternativeEncoding, - indexOfFirstUnconvertibleCharacter); - if (numberOfUnconvertibleCharacters + numberOfDowngradedCharacters < leastUnconvertibleCharacters) - { - encodingToUse = encodingList[encoder]; - leastUnconvertibleCharacters = numberOfUnconvertibleCharacters + numberOfDowngradedCharacters; - } - } - } - - LOGGSMU2("CSmsAlphabetConverter::FindBestAlternativeEncodingL(): encodingToUse=%d", encodingToUse); - - return encodingToUse; - } // CSmsAlphabetConverter::FindBestAlternativeEncoding - - -/** - * Confirms that the requested encoding method is present (e.g. the converter - * plug-in can be loaded). - * - * @param aEncoding Alternative 7bit encoding method. - * - * @leave KErrNotSupported if the encoder is not available. - */ -void CSmsAlphabetConverter::ConfirmAlternativeEncoderL(TSmsEncoding aEncoding) const - { - // - // Check the ID for the encoder exists... - // - if (aEncoding != ESmsEncodingNone) - { - TUint encoderID; - - GetAlternativeEncoderIDL(aEncoding, encoderID); - - // - // Confirm it can be loaded... - // - if (iCharacterSetConverter.PrepareToConvertToOrFromL(encoderID, iFs) != CCnvCharacterSetConverter::EAvailable) - { - User::Leave(KErrNotSupported); - } - } - } // CSmsAlphabetConverter::ConfirmAlternativeEncoderL - - -/** - * Prepares the converted for conversion from native charset. - * Character set specific preparation is performed here. - * - * @param aEncoding Alternative 7bit encoding to use if required. - */ -void CSmsAlphabetConverter::PrepareForConversionFromNativeL(TSmsEncoding aEncoding) - { - LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): aEncoding=%d", - aEncoding); - - __ASSERT_DEBUG(iIsBinary==EFalse,Panic(KGsmuPanicUnsupportedAlphabet)); - switch (iSmsAlphabet) - { - case TSmsDataCodingScheme::ESmsAlphabet7Bit: - { - // - // If an alternative encoding has been specified then try and - // load that converter... - // - if (aEncoding != ESmsEncodingNone) - { - TUint alternativeEncoderID; - - GetAlternativeEncoderIDL(aEncoding, alternativeEncoderID); - if (alternativeEncoderID != 0) - { - CCnvCharacterSetConverter::TAvailability availability; - - LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): Converter 0x%08x", - alternativeEncoderID); - - availability = iCharacterSetConverter.PrepareToConvertToOrFromL(alternativeEncoderID, iFs); - if (availability == CCnvCharacterSetConverter::EAvailable) - { - // Force unicode line termination characters to simple line feed - iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters( - CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed); - - // Job done, return - return; - } - - // Plug-in could not be loaded, so drop through and load the default! - } - } - - // - // Check for the PREQ2090 7bit converter with Eastern European - // downgrade support first, otherwise if the plug-in is not found - // use the standard internal converter. - // - CCnvCharacterSetConverter::TAvailability availability; - - availability = iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierExtendedSms7Bit, iFs); - if (availability == CCnvCharacterSetConverter::ENotAvailable) - { - availability = iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierSms7Bit, iFs); - if (availability == CCnvCharacterSetConverter::ENotAvailable) - { - User::Leave(KErrNotFound); - } - } - - // Force unicode line termination characters to simple line feed - iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters( - CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed); - break; - } - case TSmsDataCodingScheme::ESmsAlphabet8Bit: - { - CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierCodePage1252,iFs); - if (availability==CCnvCharacterSetConverter::ENotAvailable) - { - User::Leave(KErrNotFound); - } - - // Force unicode line termination characters to simple line feed - iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters( - CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed); - break; - } - case TSmsDataCodingScheme::ESmsAlphabetUCS2: - default: - { - User::Leave(KErrNotSupported); - } - } - } // CSmsAlphabetConverter::PrepareForConversionFromNativeL - - -/** - * Prepares the converted for conversion to unicode. Character set - * specific preparation is performed here. - * - * @param aEncoding Alternative 7bit encoding to use if required. - */ -void CSmsAlphabetConverter::PrepareForConversionToNativeL(TSmsEncoding aEncoding) - { - LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionToNativeL(): aEncoding=%d", - aEncoding); - - switch (iSmsAlphabet) - { - case TSmsDataCodingScheme::ESmsAlphabet7Bit: - { - // - // If an alternative encoding has been specified then try and - // load that converter... - // - if (aEncoding != ESmsEncodingNone) - { - TUint alternativeEncoderID; - - GetAlternativeEncoderIDL(aEncoding, alternativeEncoderID); - if (alternativeEncoderID != 0) - { - CCnvCharacterSetConverter::TAvailability availability; - - LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): Converter 0x%08x", - alternativeEncoderID); - - availability = iCharacterSetConverter.PrepareToConvertToOrFromL(alternativeEncoderID, iFs); - if (availability == CCnvCharacterSetConverter::EAvailable) - { - // Job done, return - return; - } - - // Plug-in could not be loaded, so drop through and load the default! - } - } - - // - // Always use the internal converter, as it is quicker to prepare - // and the PREQ2090 7bit converter with Eastern European downgrade - // offers no benefit when converting to native. - // - CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierSms7Bit,iFs); - if (availability==CCnvCharacterSetConverter::ENotAvailable) - { - User::Leave(KErrNotFound); - } - break; - } - case TSmsDataCodingScheme::ESmsAlphabet8Bit: - { - CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierCodePage1252,iFs); - if (availability==CCnvCharacterSetConverter::ENotAvailable) - { - User::Leave(KErrNotFound); - } - break; - } - case TSmsDataCodingScheme::ESmsAlphabetUCS2: - default: - { - User::Leave(KErrNotSupported); - } - } - } // CSmsAlphabetConverter::PrepareForConversionToNativeL - - -/** - * This function returns the alternative encoding converters that are used - * incase the default GSM encoding cannot encode the message completely - * without data loss. - * - * @param aEncoding Encoding to obtain the converter for. - * @param aEncoderID Returned converter UID if present. - * - * @leave KErrArgument if the encoding enum is invalid or - */ -void CSmsAlphabetConverter::GetAlternativeEncoderIDL(TSmsEncoding aEncoding, TUint& aEncoderID) const - { - LOGGSMU2("CSmsAlphabetConverter::GetAlternativeEncoderIDL(%d)", aEncoding); - - aEncoderID = 0; - - // - // Decide on appropriate encoders. - // - switch (aEncoding) - { - case ESmsEncodingNone: - { - // Nothing to set. - } - break; - - case ESmsEncodingTurkishSingleShift: - { - aEncoderID = KCharacterSetIdentifierTurkishSingleSms7Bit; - } - break; - - case ESmsEncodingTurkishLockingShift: - { - aEncoderID = KCharacterSetIdentifierTurkishLockingSms7Bit; - } - break; - - case ESmsEncodingTurkishLockingAndSingleShift: - { - aEncoderID = KCharacterSetIdentifierTurkishLockingAndSingleSms7Bit; - } - break; - - case ESmsEncodingSpanishSingleShift: - { - aEncoderID = KCharacterSetIdentifierSpanishSingleSms7Bit; - } - break; - - case ESmsEncodingPortugueseSingleShift: - { - aEncoderID = KCharacterSetIdentifierPortugueseSingleSms7Bit; - } - break; - - case ESmsEncodingPortugueseLockingShift: - { - aEncoderID = KCharacterSetIdentifierPortugueseLockingSms7Bit; - } - break; - - case ESmsEncodingPortugueseLockingAndSingleShift: - { - aEncoderID = KCharacterSetIdentifierPortugueseLockingAndSingleSms7Bit; - } - break; - - default: - { - // - // Invalid encoder method! - // - User::Leave(KErrArgument); - } - }; - } // CSmsAlphabetConverter::GetAlternativeEncoderIDL - - -// -// Ensures the allocated 16 bit buffer is at least of the specified length -// -TPtr16 CSmsAlphabetConverter::CheckAllocBufferL(HBufC16** aBuffer,TInt aMaxLength,TInt aUsedLength) - { - LOGGSMU1("CSmsAlphabetConverter::CheckAllocBufferL()"); - - if (*aBuffer!=NULL) - { - if ((*aBuffer)->Length()ReAllocL(aMaxLength); - (*aBuffer)->Des().SetLength(aMaxLength); - } - } - else - { - *aBuffer=HBufC16::NewMaxL(aMaxLength); - } - return TPtr16((TUint16*)(*aBuffer)->Des().Ptr(),aUsedLength,(*aBuffer)->Length()); - } // CSmsAlphabetConverter::CheckAllocBufferL - - -// -// Ensures the allocated 8 bit buffer is at least of the specified length -// -TPtr8 CSmsAlphabetConverter::CheckAllocBufferL(HBufC8** aBuffer,TInt aMaxLength,TInt aUsedLength) - { - LOGGSMU1("CSmsAlphabetConverter::CheckAllocBufferL()"); - - if (*aBuffer!=NULL) - { - if ((*aBuffer)->Length()ReAllocL(aMaxLength); - (*aBuffer)->Des().SetLength(aMaxLength); - } - } - else - { - *aBuffer=HBufC8::NewMaxL(aMaxLength); - } - return TPtr8((TUint8*)(*aBuffer)->Des().Ptr(),aUsedLength,(*aBuffer)->Length()); - } // CSmsAlphabetConverter::CheckAllocBufferL - - -/** - * @internalComponent - * - * Determines whether the address format matches the specified type. - * - * @param aType Specifies an indicator type, as defined in the Common PCN Handset Specification - * @return returns ETrue if address is of specified type, EFalse otherwise - */ -EXPORT_C TBool TGsmSmsTelNumber::IsInstanceOf(TTypeOfIndicator aType) - { - LOGGSMU1("TGsmSmsTelNumber::IsInstanceOf()"); - - TBool rc = EFalse; - - (void) aType; - - if((aType == EVoiceMessageWaitingIndicator) - && ((iTypeOfAddress & TGsmSmsTypeOfAddress::EGsmSmsTONMask)==EGsmSmsTONAlphaNumeric) - && (iTelNumber.Length()==ECPHSSizeOfAddressField) - && ((iTelNumber[ECPHSAddressIndicatorType] & ECPSHIndicatorTypeBitMask) == ECPSHVoiceMailId) - && ((iTelNumber[ECPHSAddressIndicatorId] & ECPSHIndicatorIdBitMask) == ECPSHIndicatorId )) - rc = ETrue; - - return rc; - } // TGsmSmsTelNumber::IsInstanceOf - - -// -// CSmsAddress -// - -CSmsAddress* CSmsAddress::NewL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs) - { - LOGGSMU1("CSmsAddress::NewL()"); - - CSmsAddress* address=new(ELeave) CSmsAddress(aCharacterSetConverter,aFs); - CleanupStack::PushL(address); - TPtrC ptr; - address->SetAddressL(ptr); - CleanupStack::Pop(); - return address; - } // CSmsAddress::NewL - - -CSmsAddress::~CSmsAddress() - { - delete iBuffer; - } // CSmsAddress::NewL - - -/** - * Duplicates this CSmsAddress object. - * - * @return Pointer to the newly created CSmsAddress object. - */ -CSmsAddress* CSmsAddress::DuplicateL() const - { - LOGGSMU1("CSmsAddress::DuplicateL()"); - - CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter, iFs); - CleanupStack::PushL(address); - - address->SetRawAddressL(iTypeOfAddress, *iBuffer); - - CleanupStack::Pop(); - - return address; - } // CSmsAddress::DuplicateL - - -TPtrC CSmsAddress::Address() const - { - LOGGSMU1("CSmsAddress::Address()"); - - TPtrC ptr; - if (iBuffer) - ptr.Set(iBuffer->Des()); - return ptr; - } // CSmsAddress::Address - - -void CSmsAddress::SetRawAddressL(TGsmSmsTypeOfAddress aTypeOfAddress, TPtrC aBufferPtr) - { - LOGGSMU1("CSmsAddress::SetRawAddressL()"); - - iTypeOfAddress = aTypeOfAddress; - - NewBufferL(aBufferPtr.Length()); - - *iBuffer=aBufferPtr; - } // CSmsAddress::SetRawAddressL - - -TGsmSmsTypeOfAddress& CSmsAddress::TypeOfAddress() - { - LOGGSMU1("CSmsAddress::TypeOfAddress()"); - - return iTypeOfAddress; - } // CSmsAddress::TypeOfAddress - - -void CSmsAddress::SetAddressL(const TDesC& aAddress) - { - LOGGSMU1("CSmsAddress::SetAddressL()"); - - TInt length=aAddress.Length(); - NewBufferL(length); - iBuffer->Des().Copy(aAddress); - - const TGsmSmsTypeOfNumber typeofnumber=length && (iBuffer->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown; - iTypeOfAddress.SetTON(typeofnumber); - } // CSmsAddress::SetAddressL - - -void CSmsAddress::ParsedAddress(TGsmSmsTelNumber& aParsedAddress) const - { - aParsedAddress.iTypeOfAddress = iTypeOfAddress; - - TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength(); - - if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric) - { - TInt parsedlength=Address().Length(); - if (parsedlength>maxparsedlength) - parsedlength=maxparsedlength; - aParsedAddress.iTelNumber.Copy(Address().Mid(0,parsedlength)); - } - else - { - aParsedAddress.iTelNumber.SetLength(maxparsedlength); - - TInt length=iBuffer->Des().Length(); - TInt parsedlength=0; - for (TInt i=0; (iDes()[i]; - switch(ch) - { - case '*': - case '#': - case 'a': - case 'b': - case 'c': - aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch; - parsedlength++; - break; - default: - if ((ch>='0') && (ch<='9')) - { - aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch; - parsedlength++; - } - break; - } - } - - aParsedAddress.iTelNumber.SetLength(parsedlength); - } - } - - -void CSmsAddress::SetParsedAddressL(const TGsmSmsTelNumber& aParsedAddress) - { - LOGGSMU1("CSmsAddress::SetParsedAddressL()"); - - iTypeOfAddress=aParsedAddress.iTypeOfAddress; - DoSetParsedAddressL(aParsedAddress.iTelNumber); - } // CSmsAddress::SetParsedAddressL - - -TUint8 CSmsAddress::SizeL() - { - LOGGSMU1("CSmsAddress::SizeL()"); - - TUint8 size = 0; - - TBuf8 testBuffer; - testBuffer.SetLength(KSmsAddressMaxAddressLength); - TUint8* startPtr = &testBuffer[0]; - TUint8* endPtr = NULL; - - TRAPD(err,endPtr = EncodeL(startPtr)); - - if (err != KErrNone) - { - User::Leave(KErrArgument); - } - else - { - // handle architectures whose address space increments or whose address space decrements. - (endPtr > startPtr) ? (size = endPtr - startPtr) : (size = startPtr - endPtr); - } - - return size; - } // CSmsAddress::SizeL - - -TUint8* CSmsAddress::EncodeL(TUint8* aPtr) const - { - TGsmSmsTelNumber parsedaddress; - ParsedAddress(parsedaddress); - - switch (iTypeOfAddress.TON()) - { - case EGsmSmsTONAlphaNumeric: - { - // Mark buffer for length encoding after conversion - TUint8* lengthPtr=aPtr++; - // Encode type - aPtr=iTypeOfAddress.EncodeL(aPtr); - // 7-bit conversion - TPtrC address=Address(); - TInt convertedNumUDUnits=0; - TPtr8 packedPtr(aPtr,0,KSmsAddressMaxAddressValueLength); - TSmsAlphabetPacker packer(TSmsDataCodingScheme::ESmsAlphabet7Bit,EFalse,0); - aPtr+=packer.ConvertAndPackL(iCharacterSetConverter,iFs,packedPtr,address,convertedNumUDUnits); - // Now encode length - TSmsOctet length=(convertedNumUDUnits*7+3)/4; - length.EncodeL(lengthPtr); - break; - } - case EGsmSmsTONInternationalNumber: - default: - { - TSmsOctet length=parsedaddress.iTelNumber.Length(); - if (length > KSmsAddressMaxAddressValueLength * 2) - // each address value occupies one nibble. - { - User::Leave(KErrArgument); - } - aPtr=length.EncodeL(aPtr); - aPtr=iTypeOfAddress.EncodeL(aPtr); - TSmsOctet octet; - for (TInt i=0; iDes().Ptr(),0,iBuffer->Length()); - - if (remainder.Length() < KSmsAddressMaxAddressValueLength) - User::Leave(KErrGsmuDecoding); - - TPtrC8 packedPtr(remainder.Ptr(), KSmsAddressMaxAddressValueLength); - TSmsAlphabetPacker unpacker(TSmsDataCodingScheme::ESmsAlphabet7Bit,EFalse,0); - unpacker.UnpackAndConvertL(iCharacterSetConverter,iFs,packedPtr,unpackedPtr,numUDUnits); - aPdu.IncL(length / 2); - if ((length % 2) != 0) - aPdu.IncL(); - } - break; - } - case EGsmSmsTONInternationalNumber: - default: - { - TGsmSmsTelNumber parsedaddress; - if (length>parsedaddress.iTelNumber.MaxLength()) - User::Leave(KErrGsmuDecoding); - parsedaddress.iTelNumber.SetLength(length); - TSmsOctet octet; - for (TInt i=0; i>4; - - switch(tempOctet) - { - case 10: // 1010 - { - parsedaddress.iTelNumber[i] = '*'; - } - break; - - case 11: // 1011 - { - parsedaddress.iTelNumber[i] = '#'; - } - break; - - case 12: // 1100 - { - parsedaddress.iTelNumber[i] = 'a'; - } - break; - - case 13: // 1101 - { - parsedaddress.iTelNumber[i] = 'b'; - } - break; - - case 14: // 1110 - { - parsedaddress.iTelNumber[i] = 'c'; - } - break; - - case 15: - // Skip if 1111 is received - break; - - default: - parsedaddress.iTelNumber[i]=(TUint8) (tempOctet+'0'); - // unwanted bits zeroed in the beginning - - break; - } - } - } - DoSetParsedAddressL(parsedaddress.iTelNumber); - } - } - } - -void CSmsAddress::InternalizeL(RReadStream& aStream) - { - aStream >> iTypeOfAddress; - HBufC* buffer=HBufC::NewL(aStream,256); - delete iBuffer; - iBuffer=buffer; - } // CSmsAddress::InternalizeL - - -void CSmsAddress::ExternalizeL(RWriteStream& aStream) const - { - aStream << iTypeOfAddress; - aStream << *iBuffer; - } // CSmsAddress::ExternalizeL - - -CSmsAddress::CSmsAddress(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs): - iCharacterSetConverter(aCharacterSetConverter), - iFs(aFs), - iTypeOfAddress(EGsmSmsTONUnknown, EGsmSmsNPIISDNTelephoneNumberingPlan) - { - } // CSmsAddress::CSmsAddress - - -void CSmsAddress::NewBufferL(TInt aLength) - { - LOGGSMU1("CSmsAddress::NewBufferL()"); - - HBufC* buffer=HBufC::NewL(aLength); - delete iBuffer; - iBuffer=buffer; - iBuffer->Des().SetLength(aLength); - iBuffer->Des().FillZ(); - } - - -void CSmsAddress::DoSetParsedAddressL(const TDesC& aAddress) - { - LOGGSMU2("CSmsAddress::DoSetParsedAddressL() the length of the Address [Length = %d", aAddress.Length()); - - TInt length=aAddress.Length(); - if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) && - (length && (aAddress[0]!='+'))) - { - NewBufferL(length+1); - iBuffer->Des()[0]='+'; - TPtr ptr((TText*) (iBuffer->Des().Ptr()+1),length,length); - ptr.Copy(aAddress); - } - else - { - NewBufferL(length); - iBuffer->Des().Copy(aAddress); - } - } // CSmsAddress::DoSetParsedAddressL - - -TSmsServiceCenterTimeStamp::TSmsServiceCenterTimeStamp() - { - iTimeZoneNumQuarterHours = 0; - } // TSmsServiceCenterTimeStamp::TSmsServiceCenterTimeStamp - - -void TSmsServiceCenterTimeStamp::SetTimeOffset(TInt aNumQuarterHours) - { - __ASSERT_DEBUG((aNumQuarterHours>=-KSmsMaxTimeZoneNumQuarterHours) && (aNumQuarterHours<=KSmsMaxTimeZoneNumQuarterHours),Panic(KGsmuPanicNumQuarterHoursOutOfRange)); - iTimeZoneNumQuarterHours=aNumQuarterHours; - } // TSmsServiceCenterTimeStamp::SetTimeOffset - - -TUint8* TSmsServiceCenterTimeStamp::EncodeL(TUint8* aPtr) const - { - LOGGSMU1("TSmsServiceCenterTimeStamp::EncodeL()"); - - TInt numquarterhours=iTimeZoneNumQuarterHours; - - TInt timeZoneOffsetInSeconds = numquarterhours * CSmsMessage::E15MinutesRepresentedInSeconds; - TTimeIntervalSeconds offsetFromUTCToLocal(timeZoneOffsetInSeconds); - - TTime time = iTime; - time += offsetFromUTCToLocal; - - TDateTime datetime=time.DateTime(); - - TSmsOctet octet; - octet.FillSemiOctets(datetime.Year()%100); - aPtr=octet.EncodeL(aPtr); - octet.FillSemiOctets(datetime.Month()+1); - aPtr=octet.EncodeL(aPtr); - octet.FillSemiOctets(datetime.Day()+1); - aPtr=octet.EncodeL(aPtr); - octet.FillSemiOctets(datetime.Hour()); - aPtr=octet.EncodeL(aPtr); - octet.FillSemiOctets(datetime.Minute()); - aPtr=octet.EncodeL(aPtr); - octet.FillSemiOctets(datetime.Second()); - aPtr=octet.EncodeL(aPtr); - - TInt signbit=ESmsTimeZonePositive; - if (numquarterhours<0) - { - numquarterhours=-numquarterhours; - signbit=ESmsTimeZoneNegative; - } - - TSmsOctet timezone; - timezone.FillSemiOctets(numquarterhours); - timezone=timezone|signbit; - return timezone.EncodeL(aPtr); - } // TSmsServiceCenterTimeStamp::EncodeL - - -void TSmsServiceCenterTimeStamp::DecodeL(TGsmuLex8& aPdu, TInt& aTimeError) - { - LOGGSMU1("TSmsServiceCenterTimeStamp::DecodeL()"); - - TSmsOctet octet; - octet.DecodeL(aPdu); - TInt year=octet.SemiOctetsToNum(); - if (year>95) - year+=1900; - else - year+=2000; - octet.DecodeL(aPdu); - TInt month=octet.SemiOctetsToNum(); - octet.DecodeL(aPdu); - - TInt day=octet.SemiOctetsToNum(); - octet.DecodeL(aPdu); - TInt hour=octet.SemiOctetsToNum(); - octet.DecodeL(aPdu); - TInt minute=octet.SemiOctetsToNum(); - octet.DecodeL(aPdu); - TInt second=octet.SemiOctetsToNum(); - - TDateTime datetime; - aTimeError = datetime.Set(year,(TMonth) (month-1),day-1,hour,minute,second,0); - - TSmsOctet timezone; - timezone.DecodeL(aPdu); - - TInt signBit = (timezone&ESmsTimeZoneSignBitMask) ? ESmsTimeZoneNegative : ESmsTimeZonePositive; - timezone=timezone &(~ESmsTimeZoneSignBitMask); // clear sign bit - - TInt offsetToUTCInSeconds = 0; - if (timezone.SemiOctetsToNum() <= KSmsMaxTimeZoneNumQuarterHours) - { - offsetToUTCInSeconds = ((TInt) timezone.SemiOctetsToNum()) * CSmsMessage::E15MinutesRepresentedInSeconds; - if (signBit == ESmsTimeZoneNegative) - { - offsetToUTCInSeconds = -offsetToUTCInSeconds; - } - - TTimeIntervalSeconds offsetToUTC(offsetToUTCInSeconds) ; - - if (aTimeError == KErrNone) - { - TTime time = datetime; - time -= offsetToUTC; - iTime = time; - - iTimeZoneNumQuarterHours=(signBit == ESmsTimeZonePositive) ? timezone.SemiOctetsToNum(): -timezone.SemiOctetsToNum(); - } - - } - else // Time zone out of range, set to 0 per 23.040 4.4.0 Section 9.2.3.11 - { - if (aTimeError == KErrNone) - { - iTime = datetime; - iTimeZoneNumQuarterHours=0; - } - } - } // TSmsServiceCenterTimeStamp::DecodeL - - -void TSmsServiceCenterTimeStamp::InternalizeL(RReadStream& aStream) - { - TInt64 time; - aStream >> time; - iTime=time; - iTimeZoneNumQuarterHours=aStream.ReadInt32L(); - } // TSmsServiceCenterTimeStamp::InternalizeL - - -void TSmsServiceCenterTimeStamp::ExternalizeL(RWriteStream& aStream) const - { - aStream << iTime.Int64(); - aStream.WriteInt32L(iTimeZoneNumQuarterHours); - } // TSmsServiceCenterTimeStamp::ExternalizeL - - -TSmsValidityPeriod::TSmsValidityPeriod(TSmsFirstOctet& aFirstOctet): - iFirstOctet(aFirstOctet), - iTimeIntervalMinutes(EOneDayUnitInMinutes) - { - } // TSmsValidityPeriod::TSmsValidityPeriod - - -TTime TSmsValidityPeriod::Time() const - { - LOGGSMU1("TSmsValidityPeriod::Time()"); - - TTime time; - time.UniversalTime(); - time+=iTimeIntervalMinutes; - return time; - } // TSmsValidityPeriod::Time - - -TUint8* TSmsValidityPeriod::EncodeL(TUint8* aPtr) const - { - LOGGSMU1("TSmsValidityPeriod::EncodeL()"); - - TInt validityperiodformat=ValidityPeriodFormat(); - switch (validityperiodformat) - { - case (TSmsFirstOctet::ESmsVPFNone): - break; - case (TSmsFirstOctet::ESmsVPFInteger): - { - TInt timeintervalminutes=iTimeIntervalMinutes.Int(); - __ASSERT_DEBUG((timeintervalminutes>=EFiveMinuteUnitInMinutes) && (timeintervalminutes<=63*EOneWeekUnitLimitInMinutes),Panic(KGsmuPanicValidityPeriodOutOfRange)); - TSmsOctet octet; - if (timeintervalminutes<=EFiveMinuteUnitLimitInMinutes) - octet=((timeintervalminutes/EFiveMinuteUnitInMinutes)-1); - else if (timeintervalminutes<=EHalfHourUnitLimitInMinutes) - octet=(((timeintervalminutes-(EHalfHourUnitLimitInMinutes/2))/EHalfHourUnitInMinutes)+EFiveMinuteUnitLimit); - - else if (timeintervalminutes<=EOneDayUnitLimitInMinutes) - octet=((timeintervalminutes/EOneDayUnitInMinutes)+166); - else - octet=((timeintervalminutes/EOneWeekUnitInMinutes)+192); - - aPtr=octet.EncodeL(aPtr); - break; - } - case (TSmsFirstOctet::ESmsVPFSemiOctet): - { - TSmsServiceCenterTimeStamp timestamp; - timestamp.SetTime(Time()); - - TTimeIntervalSeconds timeIntervalInSeconds(User::UTCOffset()); - timestamp.SetTimeOffset(timeIntervalInSeconds.Int() / CSmsMessage::E15MinutesRepresentedInSeconds); - - aPtr=timestamp.EncodeL(aPtr); - break; - } - default: - __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat)); - User::Leave(KErrGsmSMSTPVPFNotSupported); - break; - }; - return aPtr; - } // TSmsValidityPeriod::EncodeL - -TUint8* TSmsValidityPeriod::EncodeL(TUint8* aPtr, const TEncodeParams* aEncodeParams) const - { - LOGGSMU1("TSmsValidityPeriod::EncodeL()"); - - TInt validityperiodformat=ValidityPeriodFormat(); - switch (validityperiodformat) - { - case (TSmsFirstOctet::ESmsVPFNone): - break; - case (TSmsFirstOctet::ESmsVPFInteger): - { - TInt timeintervalminutes=iTimeIntervalMinutes.Int(); - __ASSERT_DEBUG((timeintervalminutes>=EFiveMinuteUnitInMinutes) && (timeintervalminutes<=63*EOneWeekUnitLimitInMinutes),Panic(KGsmuPanicValidityPeriodOutOfRange)); - TSmsOctet octet; - if (timeintervalminutes<=EFiveMinuteUnitLimitInMinutes) - octet=((timeintervalminutes/EFiveMinuteUnitInMinutes)-1); - else if (timeintervalminutes<=EHalfHourUnitLimitInMinutes) - octet=(((timeintervalminutes-(EHalfHourUnitLimitInMinutes/2))/EHalfHourUnitInMinutes)+EFiveMinuteUnitLimit); - - else if (timeintervalminutes<=EOneDayUnitLimitInMinutes) - octet=((timeintervalminutes/EOneDayUnitInMinutes)+166); - else - octet=((timeintervalminutes/EOneWeekUnitInMinutes)+192); - - aPtr=octet.EncodeL(aPtr); - break; - } - case (TSmsFirstOctet::ESmsVPFSemiOctet): - { - //The reason TSmsValidityPeriod::EncodeL(TUint8* aPtr, const TEncodeParams* aEncodeParams) was - //created was to allow the CSmsMessage's time stamp to be used when generating the validity time. - //The CSmsMessage's time stamp is typically created when the message is constructed by the SMS Stack client. - //This means the validity time is based from the point the SMS Stack client actually sends the message, rather - //than the SMS Stack encodes it - - TSmsServiceCenterTimeStamp timestamp; - timestamp.SetTime( *aEncodeParams->iTimeStamp + iTimeIntervalMinutes ); - - TTimeIntervalSeconds timeIntervalInSeconds( *aEncodeParams->iTimeIntervalInSeconds ); - timestamp.SetTimeOffset(timeIntervalInSeconds.Int() / CSmsMessage::E15MinutesRepresentedInSeconds); - - aPtr=timestamp.EncodeL(aPtr); - break; - } - default: - __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat)); - User::Leave(KErrGsmSMSTPVPFNotSupported); - break; - }; - return aPtr; - } // TSmsValidityPeriod::EncodeL - -void TSmsValidityPeriod::DecodeL(TGsmuLex8& aPdu) - { - LOGGSMU1("TSmsValidityPeriod::DecodeL()"); - - TInt validityperiodformat=ValidityPeriodFormat(); - switch (validityperiodformat) - { - case (TSmsFirstOctet::ESmsVPFNone): - break; - case (TSmsFirstOctet::ESmsVPFInteger): - { - TSmsOctet octet; - octet.DecodeL(aPdu); - if (octet<=EFiveMinuteUnitLimit) - iTimeIntervalMinutes=(octet+1)*EFiveMinuteUnitInMinutes; - else if (octet<=EHalfHourUnitLimit) - iTimeIntervalMinutes=((EOneDayUnitInMinutes/2)+((octet-EFiveMinuteUnitLimit)*EHalfHourUnitInMinutes)); - else if (octet<=EOneDayUnitLimit) - iTimeIntervalMinutes=(octet-166)*EOneDayUnitInMinutes; - else - iTimeIntervalMinutes=(octet-192)*EOneWeekUnitInMinutes; - break; - } - case (TSmsFirstOctet::ESmsVPFSemiOctet): - { - TSmsServiceCenterTimeStamp timestamp; - TInt timeError; - timestamp.DecodeL(aPdu, timeError); - User::LeaveIfError(timeError); - TTime time; - time.UniversalTime(); - timestamp.Time().MinutesFrom(time,iTimeIntervalMinutes); - break; - } - default: - __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat)); - User::Leave(KErrGsmSMSTPVPFNotSupported); - break; - }; - } // TSmsValidityPeriod::DecodeL - - -void TSmsValidityPeriod::InternalizeL(RReadStream& aStream) - { - TInt timeintervalinminutes=aStream.ReadInt32L(); - iTimeIntervalMinutes=timeintervalinminutes; - } // TSmsValidityPeriod::InternalizeL - - -void TSmsValidityPeriod::ExternalizeL(RWriteStream& aStream) const - { - aStream.WriteInt32L(iTimeIntervalMinutes.Int()); - } // TSmsValidityPeriod::ExternalizeL - - -CSmsInformationElement* CSmsInformationElement::NewL(TSmsInformationElementIdentifier aIdentifier,const TDesC8& aData) - { - LOGGSMU1("CSmsInformationElement::NewL()"); - - CSmsInformationElement* informationelement=new(ELeave) CSmsInformationElement(aIdentifier); - CleanupStack::PushL(informationelement); - informationelement->ConstructL(aData); - CleanupStack::Pop(); - return informationelement; - } // CSmsInformationElement::NewL - - -CSmsInformationElement* CSmsInformationElement::NewL() - { - LOGGSMU1("CSmsInformationElement::NewL()"); - - CSmsInformationElement* informationelement=new(ELeave) CSmsInformationElement(ESmsIEIConcatenatedShortMessages8BitReference); - CleanupStack::PushL(informationelement); - TPtrC8 data; - informationelement->ConstructL(data); - CleanupStack::Pop(); - return informationelement; - } // CSmsInformationElement::NewL - - -/** - * Destructor. - */ -CSmsInformationElement::~CSmsInformationElement() - { - delete iData; - } // CSmsInformationElement::NewL - - -/** - * Gets the Information Element data. - * - * @return Information Element data - * @capability None - */ -EXPORT_C TPtr8 CSmsInformationElement::Data() - { - LOGGSMU1("CSmsInformationElement::Data()"); - - return iData->Des(); - } // CSmsInformationElement::Data - - -/** - * Gets the (const) Information Element data. - * - * @return Information Element data - * @capability None - */ -EXPORT_C const TDesC8& CSmsInformationElement::Data() const - { - LOGGSMU1("CSmsInformationElement::Data()"); - - return *iData; - } // CSmsInformationElement::Data - - -/** - * Gets the Information Element Identifier. - * - * @return Information Element Identifier - * @capability None - */ -EXPORT_C CSmsInformationElement::TSmsInformationElementIdentifier CSmsInformationElement::Identifier() const - { - return TSmsId(TInt(iIdentifier)); - } // CSmsInformationElement::TSmsInformationElementIdentifier - - -TUint8* CSmsInformationElement::EncodeL(TUint8* aPtr) const - { - LOGGSMU1("CSmsInformationElement::EncodeL()"); - - TSmsOctet id=iIdentifier; - aPtr=id.EncodeL(aPtr); - TSmsOctet informationelementlength=iData->Des().Length(); - aPtr=informationelementlength.EncodeL(aPtr); - Mem::Copy(aPtr,iData->Des().Ptr(),informationelementlength); - aPtr+=TInt(informationelementlength); - return aPtr; - } // CSmsInformationElement::EncodeL - - -void CSmsInformationElement::DecodeL(TGsmuLex8& aPdu) - { - LOGGSMU1("CSmsInformationElement::DecodeL()"); - - TSmsOctet id; - id.DecodeL(aPdu); - iIdentifier=static_cast((TInt)id); - - TSmsOctet informationelementlength; - informationelementlength.DecodeL(aPdu); - - switch(iIdentifier) - { - case (ESmsIEIConcatenatedShortMessages8BitReference): - if(informationelementlength !=3) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsIEISpecialSMSMessageIndication): - if(informationelementlength !=2) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsIEIApplicationPortAddressing8Bit): - if(informationelementlength !=2) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsIEIApplicationPortAddressing16Bit): - if(informationelementlength !=4) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsIEISMSCControlParameters): - if(informationelementlength !=1) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsIEIUDHSourceIndicator): - if(informationelementlength !=1) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsIEIConcatenatedShortMessages16BitReference): - if(informationelementlength !=4) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsIEIRFC822EmailHeader): - if(informationelementlength !=1) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsHyperLinkFormat): - if(informationelementlength !=4) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsNationalLanguageSingleShift): - if(informationelementlength != 1) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsNationalLanguageLockingShift): - if(informationelementlength != 1) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - case (ESmsIEISIMToolkitSecurityHeaders1): - case (ESmsIEISIMToolkitSecurityHeaders2): - case (ESmsIEISIMToolkitSecurityHeaders3): - case (ESmsIEISIMToolkitSecurityHeaders4): - case (ESmsIEISIMToolkitSecurityHeaders5): - case (ESmsIEISIMToolkitSecurityHeaders6): - case (ESmsIEISIMToolkitSecurityHeaders7): - case (ESmsIEISIMToolkitSecurityHeaders8): - case (ESmsIEISIMToolkitSecurityHeaders9): - case (ESmsIEISIMToolkitSecurityHeaders10): - case (ESmsIEISIMToolkitSecurityHeaders11): - case (ESmsIEISIMToolkitSecurityHeaders12): - case (ESmsIEISIMToolkitSecurityHeaders13): - case (ESmsIEISIMToolkitSecurityHeaders14): - case (ESmsIEISIMToolkitSecurityHeaders15): - case (ESmsIEISIMToolkitSecurityHeaders16): - if(informationelementlength !=0) - User::Leave(KErrGsmSMSTpduNotSupported); - break; - default: - break; - } - - const TPtrC8 data(aPdu.NextAndIncL(informationelementlength)); - NewDataL(informationelementlength); - TPtr8 ptr(iData->Des()); - ptr.Copy(data); - } // CSmsInformationElement::DecodeL - - -void CSmsInformationElement::InternalizeL(RReadStream& aStream) - { - TSmsOctet id; - aStream >> id; - iIdentifier=static_cast((TInt)id); - delete iData; - iData=NULL; - iData=HBufC8::NewL(aStream,CSmsUserData::KSmsMaxUserDataSize); - } // CSmsInformationElement::InternalizeL - - -void CSmsInformationElement::ExternalizeL(RWriteStream& aStream) const - { - TSmsOctet id; - id=(TInt)iIdentifier; - aStream << id; - aStream << *iData; - } // CSmsInformationElement::ExternalizeL - - -void CSmsInformationElement::ConstructL(const TDesC8& aData) - { - LOGGSMU1("CSmsInformationElement::ConstructL()"); - - NewDataL(aData.Length()); - iData->Des().Copy(aData); - } // CSmsInformationElement::ConstructL - - -void CSmsInformationElement::NewDataL(TInt aLength) - { - LOGGSMU1("CSmsInformationElement::NewDataL()"); - - HBufC8* data=HBufC8::NewL(aLength); - delete iData; - iData=data; - iData->Des().SetLength(aLength); - } // CSmsInformationElement::NewDataL - - -TUint CSmsInformationElement::Length()const - { - LOGGSMU1("CSmsInformationElement::Length()"); - - return 2+iData->Length(); // 2 stands for IEID and IEDL - } // CSmsInformationElement::Length - - -/** - * @internalComponent - * - * This method maps an information element to an index into an array of categories. - * - * @param aId - * The information Element Identifier. - * @param aIndex - * The index into the array of categories - * @return - * True if the information element can be mapped. - * False otherwise. - */ -TBool TSmsInformationElementCategories::TranslateCategoryToIndex(TInformationElementId aId, TInt& aIndex) - { - LOGGSMU1("CSmsMessage::TranslateCategoryToIndex"); - - TBool rc = ETrue; - - if (aId < CSmsInformationElement::ESmsIEMaximum) - { - switch (aId) - { - case CSmsInformationElement::ESmsIEIConcatenatedShortMessages8BitReference: - case CSmsInformationElement::ESmsIEIConcatenatedShortMessages16BitReference: - case CSmsInformationElement::ESmsIEISMSCControlParameters: - case CSmsInformationElement::ESmsIEIRFC822EmailHeader: - { - aIndex = EIndexCtrlMandatoryInEveryPDUButWithValueSpecificToPDU; - break; - } - case CSmsInformationElement::ESmsIEISpecialSMSMessageIndication: - { - aIndex = EIndexCtrlMandatoryInEveryPDUMultipleInstancesPerPDU; - break; - } - case CSmsInformationElement::ESmsHyperLinkFormat: - { - aIndex = EIndexCtrlMultipleInstancesAllowed; - break; - } - case CSmsInformationElement::ESmsNationalLanguageSingleShift: - case CSmsInformationElement::ESmsNationalLanguageLockingShift: - { - aIndex = EIndexCtrlOptionalInEveryPDUWithValueSpecificToPDU; - break; - } - case CSmsInformationElement::ESmsReplyAddressFormat: - { - aIndex = EIndexCtrlMandatoryIn1stPDUOnly; - break; - } - case CSmsInformationElement::ESmsEnhanceVoiceMailInformation: - { - aIndex = EIndexCtrlSingleInstanceOnly; - break; - } - case CSmsInformationElement::ESmsEnhancedTextFormatting: - case CSmsInformationElement::ESmsEnhancedPredefinedSound: - case CSmsInformationElement::ESmsEnhancedUserDefinedSound: - case CSmsInformationElement::ESmsEnhancedPredefinedAnimation: - case CSmsInformationElement::ESmsEnhancedLargeAnimation: - case CSmsInformationElement::ESmsEnhancedSmallAnimation: - case CSmsInformationElement::ESmsEnhancedLargePicture: - case CSmsInformationElement::ESmsEnhancedSmallPicture: - case CSmsInformationElement::ESmsEnhancedVariablePicture: - case CSmsInformationElement::ESmsEnhancedUserPromptIndicator: - case CSmsInformationElement::ESmsEnhancedExtendedObject: - case CSmsInformationElement::ESmsEnhancedReusedExtendedObject: - case CSmsInformationElement::ESmsEnhancedCompressionControl: - case CSmsInformationElement::ESmsEnhancedODI: - case CSmsInformationElement::ESmsEnhancedStandardWVG: - case CSmsInformationElement::ESmsEnhancedCharacterSizeWVG: - case CSmsInformationElement::ESmsEnhancedextendedObjectDataRequest: - { - aIndex = EIndexEmsInformationElement; - break; - } - case CSmsInformationElement::ESmsIEIReserved: - case CSmsInformationElement::ESmsIEIValueNotUsed: - { - rc = EFalse; - break; - } - default: - { - aIndex = EIndexCtrlMandatoryInEveryPDUAndWithIdenticalValues; - break; - } - } - } - else - { - rc = EFalse; - LOGGSMU3("CSmsMessage::TranslateCategoryToIndex id = %d, found = %d", aId, rc); - } - return rc; - } // TSmsInformationElementCategories::TranslateCategoryToIndex - - -/** - * @internalComponent - * - * This method gets an information element identifier's category. - * - * @param aId - * The information Element Identifier. - * @param aCategory - * The category of information element. - * @return - * ETrue if successful, EFalse if an information identifier is unknown or cannot - * be mapped. - */ -TBool TSmsInformationElementCategories::GetCategoryDefinition(TInformationElementId aId, TInformationElementCategory& aCategory) - { - LOGGSMU1("TSmsInformationElementCategories::GetCategoryDefinition"); - TInt index; - - if (TranslateCategoryToIndex(aId,index)) - { - aCategory = categories[index]; - } - else - { - LOGGSMU2("TSmsInformationElementCategories::GetCategoryDefinition, Failure, aId = %d", aId); - return EFalse; - } - - return ETrue; - } // TSmsInformationElementCategories::GetCategoryDefinition - - -const TSmsInformationElementCategories::TInformationElementCategory TSmsInformationElementCategories::categories[TSmsInformationElementCategories::ENumberOfIndices] = - { - TSmsInformationElementCategories::EEmsInformationElement, // EDefaultEMSIndex - TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUAndWithIdenticalValues, // EDefaultControlIndex - TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUMultipleInstancesPerPDU, // EIndexForSpecialSMSMessageIndication, Concatenated Short Messages - TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUButWithValueSpecificToPDU,// EIndexForIRFC822EmailHeader, Application Port Addresses - TSmsInformationElementCategories::ECtrlMandatoryIn1stPDUOnly, // EIndexReplyAddressFormat - TSmsInformationElementCategories::ECtrlSingleInstanceOnly, // EIndexEnhanceVoiceMailInformation - TSmsInformationElementCategories::ECtrlMultipleInstancesAllowed // EIndexForHyperLinkFormat - }; - - -CSmsUserData* CSmsUserData::NewL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsFirstOctet& aFirstOctet,const TSmsDataCodingScheme& aDataCodingScheme) - { - LOGGSMU1("CSmsUserData::NewL()"); - - CSmsUserData* userdata=new(ELeave) CSmsUserData(aCharacterSetConverter,aFs,aFirstOctet,aDataCodingScheme); - CleanupStack::PushL(userdata); - userdata->ConstructL(); - CleanupStack::Pop(); - return userdata; - } // CSmsUserData::NewL - - -/** - * Destructor. - */ -CSmsUserData::~CSmsUserData() - { - iInformationElementArray.ResetAndDestroy(); - delete iBody; - } // CSmsUserData::NewL - - -/** - * Gets an information element by index. - * - * @param aIndex Index of the information element within the User Data - * @return Information element - * @capability None - */ -EXPORT_C CSmsInformationElement& CSmsUserData::InformationElement(TInt aIndex) const - { - LOGGSMU1("CSmsUserData::InformationElement()"); - - return *iInformationElementArray[aIndex]; - } // CSmsUserData::InformationElement - - -CSmsInformationElement*& CSmsUserData::InformationElementPtr(TInt aIndex) - { - LOGGSMU1("CSmsUserData::InformationElementPtr()"); - - return iInformationElementArray[aIndex]; - } // CSmsUserData::InformationElementPtr - - -/** - * Gets the index of an information element. - * - * @param aIdentifier An information element Identifier to search for - * @param aIndex The index within the User Data of the information element (if - * found). If more than 1 instance of this information element exists, then - * the 1st instance will be returned. - * - * Use InformationELementIndexL to get all elements. - * @return True if aIdentifier is found in the User Data - * @capability None - */ -EXPORT_C TBool CSmsUserData::InformationElementIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,TInt& aIndex) const - { - LOGGSMU1("CSmsUserData::InformationElementIndex()"); - - TBool found=EFalse; - TInt count=NumInformationElements(); - for (TInt i=0; (!found) && (i=0); i--) - if (InformationElement(i).Identifier()==aIdentifier) - { - found=ETrue; - aIndex=i; - } - return found; - } // CSmsUserData::InformationElementLastIndex - - -/** - * @internalComponent - * - * Locates every information element of type aIdentifier and - * stores its location index in the output array aIndices. - * - * @param aIdentifer - * The information element Identifier to search for - * @param aIndices - * A collection containing the location index for each information element of this type. - */ -void CSmsUserData::InformationElementIndicesL(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier, CArrayFixFlat& aIndices) const - { - LOGGSMU1("CSmsUserData::InformationElementIndicesL()"); - - aIndices.Reset(); - - TInt count=NumInformationElements(); - for (TInt i=0; iEncodeInformationElementL(); - iInformationElementArray.AppendL(aIe); - - TInt sizeLeft=MaxPackedUDUnitsInBodyRemaining(); - iInformationElementArray.Delete(iInformationElementArray.Count()-1); - if(sizeLeft==0 && iBody && (iBody->Length() > 0) && (*iBody)[iBody->Length()-1] == KSms7BitAlphabetEscapeChar) - { - --aCharsAddedToCurrentPDU; - --aSeg.iElementsExtracted; - TPtr8 ptr(iBody->Des()); - ptr.Delete(iBody->Length()-1,1); - --sizeLeft; - } - return sizeLeft>=0; - } // CSmsUserData::EmsInformationElementWillFitL - - -/** - * Tests whether the control information element will fit in the current PDU. - * - * Note that whilst a pointer to the aIe is passed as an - * input argument, the information element is still owned - * by the calling function, regardless of the return code. - * - * @param aInformationElement A pointer to an information Element - * @capability None - */ -TBool CSmsUserData::ControlInformationElementWillFitL(CSmsInformationElement* aIe) - { - LOGGSMU1("CSmsUserData::ControlInformationElementWillFitL()"); - - if (aIe == NULL) - { - User::Leave(KErrGeneral); - } - - TSmsInformationElementCategories::TInformationElementCategory category; - - if (TSmsInformationElementCategories::GetCategoryDefinition(aIe->Identifier(), category) == EFalse || - category == TSmsInformationElementCategories::EEmsInformationElement) - { - User::Leave(KErrArgument); - } - - iInformationElementArray.AppendL(aIe); - - TInt sizeLeft=MaxPackedUDUnitsInBodyRemaining(); - iInformationElementArray.Delete(iInformationElementArray.Count()-1); - - // Not considering whether escape characters exist in the buffer - // as control information elements do not add text to the buffer. - - return sizeLeft>=0; - } // CSmsUserData::ControlInformationElementWillFitL - - -/** - * Adds an information element. - * This method can be used to create information elements in the range: - * 00 - 09 - i.e. Control Information Elements - * It can be used to create information elements in the following ranges - * (on the assumption that the information element is intended to be encoded into - * every PDU): - * 24 - 25 - i.e. National Language Encodings - * 70 - 7F - i.e. SIM Tool Kit Security Headers - * 80 - 9F - i.e SMS to SME specific use - * C0 - CF - i.e. SC specific use - * - * Information elements in the following ranges should not be - * added using this interface. Instead they should be added using - * the following identified interfaces: - * 0A-1F - Use the interfaces provided to support EMS Elements - * 20 - Use the interfaces provided for Email in CSmsMessage - * 21 - Use the interface provided by CSmsHyperLinkOperations - * 22 - Use the interface provided by CSmsReplyAddressOperations - * 23 - Use the interface provided by CSmsEnhancedVoiceMailOperations - * - * This interface should not be used for information element in the following - * ranges, these are reserved for future use in TS23.040 V6.5.0 and their - * characteristics and repeatability have not yet been defined. - * 26-6F - * A0-BF - * E0-FF - * - * @param aIdentifier An information element Identifier for aData - * @param aData The information element to add to the User Data - * @leave - * KErrNotSupported if the information element is not supported via this interface. - * @capability None - */ -EXPORT_C void CSmsUserData::AddInformationElementL(TSmsId aIdentifier,const TDesC8& aData) - { - LOGGSMU1("CSmsUserData::AddInformationElementL"); - - if ((aIdentifier >= 0x21) && (aIdentifier <= 0x23) || - (aIdentifier >= 0x26) && (aIdentifier <= 0x6F) || - (aIdentifier >= 0xA0) && (aIdentifier <= 0xBF) || - (aIdentifier >= 0xE0) && (aIdentifier <= 0xFF)) - { - User::Leave(KErrNotSupported); - } - UpdateInformationElementArrayL(aIdentifier, aData); - - } // CSmsUserData::AddInformationElementL - - -/** - * @internalComponent - * - * Either adds an information element to - * iInformationElementArray. - * - * @param aIdentifier An information element Identifier for aData - * @param aData The information element to add to the User Data - */ -void CSmsUserData::UpdateInformationElementArrayL(TSmsId aIdentifier,const TDesC8& aData) - { - LOGGSMU1("CSmsUserData::UpdateInformationElementsL"); - - TInt count=NumInformationElements(); - if(!CEmsFactory::Supported(aIdentifier)) - { - for (TInt i=0; i& aSmsPDUArray,CSmsBufferBase& aBuffer) - break; - } - default: - { - LOGGSMU3("CSmsUserData::AddInformationElementL8 category = %d, identifier = %d",category,aIdentifier); - User::Leave(KErrNotSupported); - break; - } - } - } - } - } - - CSmsInformationElement* informationElement=CSmsInformationElement::NewL(aIdentifier,aData); - CleanupStack::PushL(informationElement); - iInformationElementArray.AppendL(informationElement); - CleanupStack::Pop(); - SetHeaderPresent(ETrue); - } // CSmsUserData::UpdateInformationElementArrayL - - -void CSmsUserData::AddEmsInformationElementL(CEmsInformationElement* aIe) - { - LOGGSMU1("CSmsUserData::AddEmsInformationElementL()"); - - // Before using an EmsInformationElement polymorphically as an SmsIE, - // we need to make sure that the IE has been encoded - aIe->EncodeInformationElementL(); - iInformationElementArray.AppendL(aIe); - SetHeaderPresent(ETrue); - } // CSmsUserData::AddEmsInformationElementL - - -/** - * Removes an information element at the specified index. - * - * @param aIndex Information element index - * @capability None - */ -EXPORT_C void CSmsUserData::RemoveInformationElement(TInt aIndex) - { - LOGGSMU1("CSmsUserData::RemoveInformationElement()"); - // Since iInformationElementArray[aIndex] pointer is removed from iInformationElementArray, there is no double free issue. - // coverity[double_free] - delete iInformationElementArray[aIndex]; - iInformationElementArray[aIndex] = NULL; - iInformationElementArray.Delete(aIndex); - - if (NumInformationElements()==0) - { - SetHeaderPresent(EFalse); - } - } // CSmsUserData::RemoveInformationElement - - -TInt CSmsUserData::MaxPackedUDUnitsInBodyRemaining() const - { - LOGGSMU1("CSmsUserData::MaxPackedUDUnitsInBodyRemaining()"); - - TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits(); - TInt maxPackedUDUnitsInBody=0; - if (iDataCodingScheme.TextCompressed()||(iDataCodingScheme.Alphabet()!=TSmsDataCodingScheme::ESmsAlphabet7Bit)) - { - maxPackedUDUnitsInBody=KSmsMaxUserDataSize-totalHeaderLengthInUDLUnits; - if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabetUCS2) - { - // Cannot split unicode character across PDU boundary - maxPackedUDUnitsInBody&=~1; - } - } - else // 7-bit - { - maxPackedUDUnitsInBody=(8*KSmsMaxUserDataSize)/7-totalHeaderLengthInUDLUnits; - } - - if (iBody) - return maxPackedUDUnitsInBody-=iBody->Length(); - return maxPackedUDUnitsInBody; - } // CSmsUserData::MaxPackedUDUnitsInBodyRemaining - - -TInt CSmsUserData::MaxPackedUDUnitsInBodyRemaining(TUint aIELen) const - { - LOGGSMU1("CSmsUserData::MaxPackedUDUnitsInBodyRemaining()"); - - TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits(aIELen); - TInt maxPackedUDUnitsInBody=0; - if (iDataCodingScheme.TextCompressed()||(iDataCodingScheme.Alphabet()!=TSmsDataCodingScheme::ESmsAlphabet7Bit)) - { - maxPackedUDUnitsInBody=KSmsMaxUserDataSize-totalHeaderLengthInUDLUnits; - if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabetUCS2) - { - // Cannot split unicode character across PDU boundary - maxPackedUDUnitsInBody&=~1; - } - } - else // 7-bit - { - maxPackedUDUnitsInBody=(8*KSmsMaxUserDataSize)/7-totalHeaderLengthInUDLUnits; - } - - if (iBody) - return maxPackedUDUnitsInBody-=iBody->Length(); - return maxPackedUDUnitsInBody; - } // CSmsUserData::MaxPackedUDUnitsInBodyRemaining - - -/** - * @capability None - */ -EXPORT_C TInt CSmsUserData::MaxBodyLengthInChars() const - { - LOGGSMU1("CSmsUserData::MaxBodyLengthInChars()"); - - TInt totalheaderlengthinudlunits=TotalHeaderLengthInUDLUnits(); - TInt maxbodylengthinchars=0; - if (iDataCodingScheme.TextCompressed()) - { - maxbodylengthinchars=KSmsMaxUserDataSize-totalheaderlengthinudlunits; - } - else - { - switch (iDataCodingScheme.Alphabet()) - { - case (TSmsDataCodingScheme::ESmsAlphabet7Bit): - { - maxbodylengthinchars=(8*KSmsMaxUserDataSize)/7-totalheaderlengthinudlunits; - break; - } - case (TSmsDataCodingScheme::ESmsAlphabet8Bit): - { - maxbodylengthinchars=KSmsMaxUserDataSize-totalheaderlengthinudlunits; - break; - } - case (TSmsDataCodingScheme::ESmsAlphabetUCS2): - { - maxbodylengthinchars=(KSmsMaxUserDataSize-totalheaderlengthinudlunits)/2; - break; - } - default: - LOGGSMU1("CSmsUserData::MaxBodyLengthInChars() WARNING! default case has been reached"); - break; - } - } - return maxbodylengthinchars; - } // CSmsUserData::MaxBodyLengthInChars - - -/** - * Gets the unpacked User Data Elements. - * - * @return Unpacked User Data Elements - * @capability None - */ -EXPORT_C TPtrC8 CSmsUserData::Body() const - { - LOGGSMU1("CSmsUserData::Body()"); - - return iBody->Des(); - } // CSmsUserData::Body - - -/** - * Sets the User Data (unpacked). - * - * @param aBody Unpacked User Data Elements - * @capability None - */ -EXPORT_C void CSmsUserData::SetBodyL(const TDesC8& aBody) - { - LOGGSMU1("CSmsUserData::SetBodyL()"); - - //Some tests fail with this line in, despite it being a valid condition! - //__ASSERT_DEBUG(aBody.Length() <= MaxBodyLengthInChars(), User::Leave(KErrTooBig)); - - NewBodyL(aBody.Length()); - iBody->Des().Copy(aBody); - } // CSmsUserData::SetBodyL - - -void CSmsUserData::AppendBodyL(const TDesC8& aBody) - { - LOGGSMU1("CSmsUserData::AppendBodyL()"); - - if (iBody) - { - //Some tests fail with this line in, despite it being a valid condition! - //__ASSERT_DEBUG(aBody.Length() + iBody->Length() <= MaxBodyLengthInChars(), User::Leave(KErrTooBig)); - - iBody = iBody->ReAllocL(aBody.Length()+iBody->Length()); - iBody->Des().Append(aBody); - } - else - { - SetBodyL(aBody); - } - } // CSmsUserData::AppendBodyL - - -/** - * Tests if the character is supported by the current character set. - * This function can be used with 7bit and 8bit alphabets. - * - * @param aChar Character to investigate. - * - * @return ETrue if the character is supported. - * - * @note Since the function is based on the old behaviour (pre-PREQ2090) - * it does not accept a downgraded character or alternative encoding - * as being supported. - * - * @capability None - */ -EXPORT_C TBool CSmsUserData::IsSupportedL(TChar aChar) - { - LOGGSMU1("CSmsUserData::IsSupportedL()"); - - CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData()); - TBool result=converter->IsSupportedL(aChar); - CleanupStack::PopAndDestroy(); - - return result; - } // CSmsUserData::IsSupportedL - - -/** - * Tests if the descriptor text is supported by the current character set. - * This function can be used with 7bit and 8bit alphabets. - * - * @param aDes Text string to check. - * @param aNumberOfUnconvertibleCharacters Exit param for the number of - * characters unconvertible. - * @param aIndexOfFirstUnconvertibleCharacter Exit param for the first - * unconverted character. - * - * @return ETrue if the character is supported. - * - * @capability None - */ -EXPORT_C TBool CSmsUserData::IsSupportedL(const TDesC& aDes, TInt& aNumberOfUnconvertibleCharacters, - TInt& aIndexOfFirstUnconvertibleCharacter) const - { - LOGGSMU1("[1] CSmsUserData::IsSupportedL()"); - - CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData()); - TBool result=converter->IsSupportedL(aDes, aNumberOfUnconvertibleCharacters, - aIndexOfFirstUnconvertibleCharacter); - CleanupStack::PopAndDestroy(); - - return result; - } // CSmsUserData::IsSupportedL - - -/** - * Tests if the descriptor text is supported by the current character set. - * This function can be used with 7bit and 8bit alphabets. - * - * @param aDes Text string to check. - * @param aEncoding Alternative encoding method. - * @param aNumberOfUnconvertibleCharacters Exit param for the number of - * characters unconvertible. - * @param aNumberOfDowngradedCharacters Exit param for the number of - * downgraded characters. - * @param aNumberRequiringAlternativeEncoding Exit param for the number of - * characters requiring use of - * the alternative encoder. - * @param aIndexOfFirstUnconvertibleCharacter Exit param for the first - * unconverted character. - * - * @return ETrue if the character is supported. - * - * @capability None - */ -EXPORT_C TBool CSmsUserData::IsSupportedL(const TDesC& aDes, TSmsEncoding aEncoding, - TInt& aNumberOfUnconvertibleCharacters, - TInt& aNumberOfDowngradedCharacters, - TInt& aNumberRequiringAlternativeEncoding, - TInt& aIndexOfFirstUnconvertibleCharacter) const - { - LOGGSMU1("[2] CSmsUserData::IsSupportedL()"); - - CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData()); - TBool result=converter->IsSupportedL(aDes, aEncoding, - aNumberOfUnconvertibleCharacters, - aNumberOfDowngradedCharacters, - aNumberRequiringAlternativeEncoding, - aIndexOfFirstUnconvertibleCharacter); - CleanupStack::PopAndDestroy(); - - return result; - } // CSmsUserData::IsSupportedL - - -TUint8* CSmsUserData::EncodeL(TUint8* aPtr) const - { - LOGGSMU1("CSmsUserData::EncodeL()"); - - __ASSERT_DEBUG(0<=MaxPackedUDUnitsInBodyRemaining(),Panic(KGsmuPanicUserDataBodyTooLong)); - // Encode the user data length - TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits(); - TSmsOctet userDataLength=totalHeaderLengthInUDLUnits+TSmsOctet(BodyLengthInUDLUnits()); - aPtr=userDataLength.EncodeL(aPtr); - // Encode any user data header - if (HeaderPresent()) - { - TSmsOctet headerLength=HeaderLength(); - aPtr=headerLength.EncodeL(aPtr); - TInt numInformationElements=NumInformationElements(); - for (TInt i=0; iEncodeL(aPtr); - } - // Pack the user data body - TInt startBit=0; - if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit) - startBit=(totalHeaderLengthInUDLUnits*7)%8; - TSmsAlphabetPacker packer(iDataCodingScheme.Alphabet(),IsBinaryData(),startBit); - TPtr8 ptr((TUint8*)aPtr,0,packer.PackedOctetsRequiredL(Body().Length())); - aPtr+=packer.PackL(ptr,Body()); - return aPtr; - } // CSmsUserData::EncodeL - - -void CSmsUserData::DecodeL(TGsmuLex8& aPdu) - { - DecodeL(aPdu, EFalse); - } - -void CSmsUserData::DecodeL(TGsmuLex8& aPdu, TBool aAcceptTruncation) - { - LOGGSMU1("CSmsUserData::DecodeL()"); - - // Reset current data - iInformationElementArray.ResetAndDestroy(); - // Decode the user data - TSmsOctet userDataLength; - userDataLength.DecodeL(aPdu); - TSmsOctet headerLength; - // Decode any user data header - TBool headerPresent=HeaderPresent(); - /* - if (headerPresent || IsHeaderPresent(aPtr,dataLength)) - */ - if (headerPresent) - { - headerLength.DecodeL(aPdu); - if ((1+headerLength)>KSmsMaxUserDataSize) - User::Leave(KErrGsmSMSTpduNotSupported); - while (HeaderLength()DecodeL(aPdu); - iInformationElementArray.AppendL(informationelement); - CleanupStack::Pop(informationelement); - } - if (HeaderLength()!=headerLength) - User::Leave(KErrGsmSMSTpduNotSupported); - } - // Decode the body - make sure we have enough buffer - TInt headerLengthInUDLUnits=TotalHeaderLengthInUDLUnits(); - TInt bodyLengthInUDLUnits=userDataLength-headerLengthInUDLUnits; - - if(bodyLengthInUDLUnits <=0) - { - NewBodyL(0); - return; - } - - NewBodyL(bodyLengthInUDLUnits); - - // Unpack the body - TInt startBit=0; - if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit) - startBit=(headerLengthInUDLUnits*7)%8; - TSmsAlphabetPacker unpacker(iDataCodingScheme.Alphabet(),IsBinaryData(),startBit); - TInt bodyLengthInOctets=unpacker.PackedOctetsRequiredL(bodyLengthInUDLUnits); - TPtr8 destPtr((TUint8*)iBody->Des().Ptr(),0,bodyLengthInUDLUnits); - - const TPtrC8 sourcePtr(aPdu.NextWithNoIncL(bodyLengthInOctets,aAcceptTruncation)); - if ( aAcceptTruncation && sourcePtr.Length() < bodyLengthInOctets) - { - // field was truncated in an acceptable situation (User Data in Status Report PDU) - bodyLengthInUDLUnits = unpacker.NumUDUnitsL(sourcePtr.Length()); - } - unpacker.UnpackL(sourcePtr,destPtr,bodyLengthInUDLUnits); - - //@note No need to call aPdu.IncL() because CSmsUserData is always at the end of a PDU - } // CSmsUserData::DecodeL - - -void CSmsUserData::InternalizeL(RReadStream& aStream) - { - iInformationElementArray.ResetAndDestroy(); - TInt numiformationelements=aStream.ReadInt32L(); - // The "header present" flag must mirror whether information elements are present, and - // the parental iFirstOctet should already be set by its InternalizeL() - __ASSERT_DEBUG(((!HeaderPresent() && numiformationelements == 0) || (HeaderPresent() && numiformationelements > 0)), Panic(KGsmuPanicInformationElementIndexOutOfRange)); - for (TInt i=0; i> *informationelement; - iInformationElementArray.AppendL(informationelement); - CleanupStack::Pop(); - } - delete iBody; - iBody=NULL; - iBody=HBufC8::NewL(aStream,KSmsMaxUserDataLengthInChars); - } // CSmsUserData::InternalizeL - - -void CSmsUserData::ExternalizeL(RWriteStream& aStream) const - { - TInt numiformationelements=iInformationElementArray.Count(); - aStream.WriteInt32L(numiformationelements); - for (TInt i=0; iSetBodyL(Body()); - - for (TInt ie = 0; ie < iInformationElementArray.Count(); ie++) - { - CSmsInformationElement* oldIE = iInformationElementArray[ie]; - - if (CEmsFactory::Supported(oldIE->Identifier())) - { - CEmsInformationElement* newIE = static_cast(oldIE)->DuplicateL(); - - CleanupStack::PushL(newIE); - userdata->AddEmsInformationElementL(newIE); - CleanupStack::Pop(newIE); - } - else - { - userdata->UpdateInformationElementArrayL(oldIE->Identifier(), oldIE->Data()); - } - } - - CleanupStack::Pop(); - - return userdata; - } // CSmsUserData::DuplicateL - - -TInt CSmsUserData::HeaderLength() const - { - LOGGSMU1("CSmsUserData::HeaderLength()"); - - TInt numinformationelements=NumInformationElements(); - TInt headerlength=0; - for (TInt i=0; iLength(); - return headerlength; - } // CSmsUserData::HeaderLength - - -TInt CSmsUserData::TotalHeaderLengthInUDLUnits() const - { - LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits()"); - - TInt totalheaderlengthinudlunits=0; - if (iInformationElementArray.Count()>0) - { - TInt totalheaderlength=1+HeaderLength(); - if (iDataCodingScheme.TextCompressed()) - { - totalheaderlengthinudlunits=totalheaderlength; - } - else - { - switch(iDataCodingScheme.Alphabet()) - { - case (TSmsDataCodingScheme::ESmsAlphabet7Bit): - { - totalheaderlengthinudlunits=((8*totalheaderlength)+6)/7; // Rounds up - break; - } - case (TSmsDataCodingScheme::ESmsAlphabet8Bit): - case (TSmsDataCodingScheme::ESmsAlphabetUCS2): - { - totalheaderlengthinudlunits=totalheaderlength; - break; - } - default: - LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits() WARNING default case has been reached"); - break; - } - } - } - return totalheaderlengthinudlunits; - } // CSmsUserData::TotalHeaderLengthInUDLUnits - - -TInt CSmsUserData::TotalHeaderLengthInUDLUnits(TInt aIElen) const - { - LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits()"); - - TInt totalheaderlengthinudlunits=0; - TInt totalheaderlength=aIElen; - - if (iInformationElementArray.Count()>0) - totalheaderlength+=HeaderLength(); - - if(totalheaderlength)totalheaderlength+=1; //UDHL - - if (iDataCodingScheme.TextCompressed()) - { - totalheaderlengthinudlunits=totalheaderlength; - } - else - { - switch(iDataCodingScheme.Alphabet()) - { - case (TSmsDataCodingScheme::ESmsAlphabet7Bit): - { - totalheaderlengthinudlunits=((8*totalheaderlength)+6)/7; // Rounds up - break; - } - case (TSmsDataCodingScheme::ESmsAlphabet8Bit): - case (TSmsDataCodingScheme::ESmsAlphabetUCS2): - { - totalheaderlengthinudlunits=totalheaderlength; - break; - } - default: - break; - } - } - return totalheaderlengthinudlunits; - } // CSmsUserData::TotalHeaderLengthInUDLUnits - - -TInt CSmsUserData::BodyLengthInUDLUnits() const - { - LOGGSMU1("CSmsUserData::BodyLengthInUDLUnits()"); - - return iBody->Des().Length(); - } // CSmsUserData::BodyLengthInUDLUnits - - -void CSmsUserData::NewBodyL(TInt aLength) - { - LOGGSMU1("CSmsUserData::NewBodyL()"); - - - HBufC8* body=HBufC8::NewL(aLength); - delete iBody; - iBody=body; - iBody->Des().SetLength(aLength); - - } // CSmsUserData::NewBodyL - - -TBool CSmsUserData::HeaderPresent() const - { - LOGGSMU1("CSmsUserData::HeaderPresent()"); - - return (iFirstOctet&TSmsFirstOctet::ESmsUDHIMask)==TSmsFirstOctet::ESmsUDHIHeaderPresent; - } // CSmsUserData::HeaderPresent - - -void CSmsUserData::SetHeaderPresent(TBool aHeaderPresent) - { - LOGGSMU1("CSmsUserData::SetHeaderPresent()"); - - iFirstOctet=aHeaderPresent? (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderPresent: (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderNotPresent; - } // CSmsUserData::SetHeaderPresent - - -TBool CSmsUserData::IsBinaryData() const - { - LOGGSMU1("CSmsUserData::IsBinaryData()"); - - TInt index=0; - return (iDataCodingScheme.TextCompressed()) || - ((iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet8Bit) && - (InformationElementIndex(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit,index) || - InformationElementIndex(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit,index))); - } // CSmsUserData::IsBinaryData - - -/** - * Converts type of number and numbering plan identification information - * from the type of address parameter to the NMobilePhone::TMobileTON - * and NMobilePhone::TMobileNPI format. - * - * @return aTon The number type - * @return aNpi The numbering plan - * - * @capability None - */ -EXPORT_C void TGsmSmsTypeOfAddress::ConvertToETelMM(NMobilePhone::TMobileTON& aTon,NMobilePhone::TMobileNPI& aNpi) const - { - LOGGSMU1("TGsmSmsTypeOfAddress::ConvertToETelMM()"); - - switch (TON()) - { - case EGsmSmsTONInternationalNumber: - { - aTon = (NMobilePhone::EInternationalNumber); - break; - } - case EGsmSmsTONNationalNumber: - { - aTon = (NMobilePhone::ENationalNumber); - break; - } - case EGsmSmsTONNetworkSpecificNumber: - { - aTon = (NMobilePhone::ENetworkSpecificNumber); - break; - } - case EGsmSmsTONSubscriberNumber: - { - aTon = (NMobilePhone::ESubscriberNumber); - break; - } - case EGsmSmsTONAlphaNumeric: - { - aTon = (NMobilePhone::EAlphanumericNumber); - break; - } - case EGsmSmsTONAbbreviatedNumber: - { - aTon = (NMobilePhone::EAbbreviatedNumber); - break; - } - - default: - { - aTon = (NMobilePhone::EUnknownNumber); - break; - } - } - - switch (NPI()) - { - case EGsmSmsNPIISDNTelephoneNumberingPlan: - { - aNpi = (NMobilePhone::EIsdnNumberPlan); - break; - } - case EGsmSmsNPIDataNumberingPlan: - { - aNpi = (NMobilePhone::EDataNumberPlan); - break; - } - case EGsmSmsNPITelexNumberingPlan: - { - aNpi = (NMobilePhone::ETelexNumberPlan); - break; - } - case EGsmSmsNPINationalNumberingPlan: - { - aNpi = (NMobilePhone::ENationalNumberPlan); - break; - } - case EGsmSmsNPIPrivateNumberingPlan: - { - aNpi = (NMobilePhone::EPrivateNumberPlan); - break; - } - case EGsmSmsNPIERMESNumberingPlan: - { - aNpi = (NMobilePhone::EERMESNumberPlan); - break; - } - - default: - { - aNpi = (NMobilePhone::EUnknownNumberingPlan); - break; - } - } - } // NMobilePhone::TMobileNPI - - -/** - * Converts type of number and numbering plan identification information - * from the NMobilePhone::TMobileTON and NMobilePhone::TMobileNPI format - * to the type of address parameter. - * - * @param aTon The number type - * @param aNpi The numbering plan - * - * @capability None - */ -EXPORT_C void TGsmSmsTypeOfAddress::SetFromETelMM(NMobilePhone::TMobileTON aTon,NMobilePhone::TMobileNPI aNpi) - { - LOGGSMU1("TGsmSmsTypeOfAddress::SetFromETelMM()"); - - switch (aTon) - { - case NMobilePhone::EInternationalNumber: - { - SetTON( EGsmSmsTONInternationalNumber ); - break; - } - case NMobilePhone::ENationalNumber: - { - SetTON( EGsmSmsTONNationalNumber ); - break; - } - case NMobilePhone::ENetworkSpecificNumber: - { - SetTON( EGsmSmsTONNetworkSpecificNumber ); - break; - } - case NMobilePhone::ESubscriberNumber: - { - SetTON( EGsmSmsTONSubscriberNumber ); - break; - } - case NMobilePhone::EAlphanumericNumber: - { - SetTON( EGsmSmsTONAlphaNumeric ); - break; - } - case NMobilePhone::EAbbreviatedNumber: - { - SetTON( EGsmSmsTONAbbreviatedNumber ); - break; - } - - default: - { - SetTON( EGsmSmsTONUnknown ); - break; - } - } - - switch (aNpi) - { - case NMobilePhone::EIsdnNumberPlan: - { - SetNPI( EGsmSmsNPIISDNTelephoneNumberingPlan ); - break; - } - case NMobilePhone::EDataNumberPlan: - { - SetNPI( EGsmSmsNPIDataNumberingPlan ); - break; - } - case NMobilePhone::ETelexNumberPlan: - { - SetNPI( EGsmSmsNPITelexNumberingPlan ); - break; - } - case NMobilePhone::ENationalNumberPlan: - { - SetNPI( EGsmSmsNPINationalNumberingPlan ); - break; - } - case NMobilePhone::EPrivateNumberPlan: - { - SetNPI( EGsmSmsNPIPrivateNumberingPlan ); - break; - } - case NMobilePhone::EERMESNumberPlan: - { - SetNPI( EGsmSmsNPIERMESNumberingPlan ); - break; - } - - default: - { - SetNPI( EGsmSmsNPIUnknown ); - break; - } - } - } // NMobilePhone::TMobileTON - - -/** - * @publishedAll - * - * Indicates whether this message is a Voice Mail Notification - * or a Voice Mail Deletion Confirmation. - * - * @return - * TVoiceMailInfoType, indicating whether this message is a Voice Mail - * Notification or a Voice Mail Deletion Confirmation. - * - * @capability None - */ -EXPORT_C TVoiceMailInfoType CEnhancedVoiceMailBoxInformation::Type() const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::Type()"); - - return iType; - } // CEnhancedVoiceMailBoxInformation::Type - - -/** - * @publishedAll - * - * Sets the subscriber profile per 23.040 v6.5 Section 9.2.3.24.13.1. - * - * @param aProfile - * The required subscriber profile - * - * @capability None - */ -EXPORT_C void CEnhancedVoiceMailBoxInformation::SetProfile(TSmsMessageProfileType aProfile) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetProfile()"); - - iProfile = aProfile; - } // CEnhancedVoiceMailBoxInformation::SetProfile - - -/** - * @publishedAll - * - * Gets the subscriber profile per 23.040 v6.5 Section 9.2.3.24.13.1. - * - * @param aProfile - * The current subscriber profile - * - * @capability None - */ -EXPORT_C TSmsMessageProfileType CEnhancedVoiceMailBoxInformation::Profile() const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::Profile()"); - - return iProfile; - } // CEnhancedVoiceMailBoxInformation::Profile - - -/** - * @publishedAll - * - * Configures the storage directive - * - * @param aIsStored - * Set to True if the SM is to be stored in the ME or USIM, - * False is the SM is to be discarded. - * - * @capability None - */ -EXPORT_C void CEnhancedVoiceMailBoxInformation::SetStorage(TBool aIsStored) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetStorage()"); - - iStorage = aIsStored; - } // CEnhancedVoiceMailBoxInformation::SetStorage - - -/** - * @publishedAll - * - * Indicates whether the SM is to be stored or discarded - * - * @return - * True if the SM is to be stored in the ME or USIM, - * False is the SM is to be discarded. - * - * @capability None - */ -EXPORT_C TBool CEnhancedVoiceMailBoxInformation::Store() const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::Store()"); - - return iStorage; - } // CEnhancedVoiceMailBoxInformation::Store - - -/** - * @publishedAll - * - * Used to set or reset the voice mail status to almost full. - * - * @param aIsStored - * Set to True the voice mail system is almost full. - * Set to False otherwise. - * - * @capability None - */ -EXPORT_C void CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity(TBool aIsAlmostFull) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity()"); - - iAlmostFull = aIsAlmostFull; - } // CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity - - -/** - * @publishedAll - * - * Indicates whether the voice mail system is almost at full capacity. - * - * @return - * True, if the voice mail system is almost full. - * False otherwise. - * - * @capability None - */ -EXPORT_C TBool CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity() const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity()"); - - return iAlmostFull; - } // CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity - - -/** - * @publishedAll - * - * Used to set or reset the voice mail status to full. - * - * @param aIsStored - * Set to True the voice mail system is full. - * Set to False otherwise. - * - * @capability None - */ -EXPORT_C void CEnhancedVoiceMailBoxInformation::SetMaximumCapacity(TBool aIsFull) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetMaximumCapacity()"); - - iFull = aIsFull; - } // CEnhancedVoiceMailBoxInformation::SetMaximumCapacity - - -/** - * @publishedAll - * - * Indicates whether the voice mail status is full. - * - * @return - * True if the voice mail system is almost full. - * False otherwise. - * - * @capability None - */ -EXPORT_C TBool CEnhancedVoiceMailBoxInformation::MaximumCapacity() const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::MaximumCapacity()"); - - return iFull; - } // CEnhancedVoiceMailBoxInformation::MaximumCapacity - - -/** - * @publishedAll - * - * Indicates whether the message contains extension bytes - * - * @return - * True if the message contains extension bytes. - * False otherwise. - * - * @capability None - */ -EXPORT_C TBool CEnhancedVoiceMailBoxInformation::ExtensionIndicator() const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::ExtensionIndicator()"); - - return iExtensionIndicator; - } // CEnhancedVoiceMailBoxInformation::ExtensionIndicator - - -void CEnhancedVoiceMailBoxInformation::NewBufferL(TInt aLength) - { - LOGGSMU2("CEnhancedVoiceMailBoxInformation::NewBufferL, length = %d",aLength); - - HBufC* buffer=HBufC::NewL(aLength); - delete iAccessAddress; - iAccessAddress=buffer; - iAccessAddress->Des().SetLength(aLength); - iAccessAddress->Des().FillZ(); - } // CEnhancedVoiceMailBoxInformation::NewBufferL - - -/** - * @publishedAll - * - * Used to set the voice mail box number, overwriting any pre-existing number. - * - * @param aAddress - * The voice mail box address. - * - * @capability None - */ -EXPORT_C void CEnhancedVoiceMailBoxInformation::SetAccessAddressL(const TDesC& aAddress) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetAccessAddressL()"); - - TInt length=aAddress.Length(); - NewBufferL(length); - iAccessAddress->Des().Copy(aAddress); - - const TGsmSmsTypeOfNumber typeofnumber=length && (iAccessAddress->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown; - iTypeOfAddress.SetTON(typeofnumber); - } // CEnhancedVoiceMailBoxInformation::SetAccessAddressL - - -/** - * @publishedAll - * - * Retrieves the voice mail box number. - * - * @return - * A pointer to the voice mail box number. - * - * @capability None - */ -EXPORT_C TPtrC CEnhancedVoiceMailBoxInformation::AccessAddress() const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::AccessAddress()"); - - TPtrC ptr; - if (iAccessAddress) - ptr.Set(iAccessAddress->Des()); - return ptr; - } // CEnhancedVoiceMailBoxInformation::AccessAddress - - -/** - * @publishedAll - * - * Used to set the voice mail box number as a parsed address - * - * @param aParsedAddress - * The parsed address to be used as the voice mail box number. - * - * @capability None - */ -EXPORT_C void CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL(const TGsmSmsTelNumber& aParsedAddress) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL()"); - - iTypeOfAddress=aParsedAddress.iTypeOfAddress; - DoSetParsedAddressL(aParsedAddress.iTelNumber); - } // CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL - - -/** - * @publishedAll - * - * Used to get the voice mail box number as a parsed address. - * - * @param aParsedAddress - * An output parameter which is set to the parsed address. - * - * @capability None - */ -EXPORT_C void CEnhancedVoiceMailBoxInformation::ParsedAccessAddress(TGsmSmsTelNumber& aParsedAddress) const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::ParsedAccessAddress()"); - - aParsedAddress.iTypeOfAddress = iTypeOfAddress; - - TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength(); - - if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric) - { - TInt parsedlength=AccessAddress().Length(); - if (parsedlength>maxparsedlength) - parsedlength=maxparsedlength; - aParsedAddress.iTelNumber.Copy(AccessAddress().Mid(0,parsedlength)); - } - else - { - aParsedAddress.iTelNumber.SetLength(maxparsedlength); - - TInt length=iAccessAddress->Des().Length(); - TInt parsedlength=0; - for (TInt i=0; (iDes()[i]; - if ((ch>='0') && (ch<='9')) - { - aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch; - parsedlength++; - } - } - - aParsedAddress.iTelNumber.SetLength(parsedlength); - } - } // CEnhancedVoiceMailBoxInformation::ParsedAccessAddress - - -void CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL(const TDesC& aAddress) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL()"); - - TInt length=aAddress.Length(); - if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) && - (length && (aAddress[0]!='+'))) - { - NewBufferL(length+1); - iAccessAddress->Des()[0]='+'; - TPtr ptr((TText*) (iAccessAddress->Des().Ptr()+1),length,length); - ptr.Copy(aAddress); - } - else - { - NewBufferL(length); - iAccessAddress->Des().Copy(aAddress); - } - } // CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL - - -/** - * @publishedAll - * - * Sets the number of voice messages to a value in the range 0 to 255. - * - * @param aNumber - * The number of voice messages. - * - * @capability None - */ -EXPORT_C void CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages(TUint8 aNumber) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages()"); - - iNumberOfVoiceMessages=aNumber; - } // CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages - - -/** - * @publishedAll - * - * Retrieves the number of voice messages that are unread. - * - * @return - * The number of unread voice messages. - * - * @capability None - */ -EXPORT_C TUint8 CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages() const - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages()"); - - return iNumberOfVoiceMessages; - } // CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages - - -TUint8* CEnhancedVoiceMailBoxInformation::EncodeL(TUint8* aPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const - { - *aPtr = (((TUint8) iType) & EMask1Bit ) + - ((((TUint8) iProfile) & EMask2Bits) << 2) + - ((((TUint8) iStorage) & EMask1Bit ) << 4) + - ((((TUint8) iAlmostFull) & EMask1Bit ) << 5) + - ((((TUint8) iFull) & EMask1Bit ) << 6) + - (((TUint8) iExtensionIndicator ) << 7); - - LOGGSMU2("CEnhancedVoiceMailBoxInformation::EncodeL 1st byte = %d",*aPtr); - aPtr++; - - // Create an address object to encode the mail box access address into the - // format required by 23.040 v6.5.0 section 9.1.2.5. - CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs); - CleanupStack::PushL(address); - TPtrC accessAddressPtr; - if (iAccessAddress) - { - accessAddressPtr.Set(iAccessAddress->Des()); - } - address->SetRawAddressL(iTypeOfAddress,accessAddressPtr); - aPtr = address->EncodeL(aPtr); - CleanupStack::PopAndDestroy(address); - - *aPtr = (TUint8) iNumberOfVoiceMessages; - aPtr++; - - return aPtr; - } // CEnhancedVoiceMailBoxInformation::EncodeL - - -void CEnhancedVoiceMailBoxInformation::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) - { - TUint8 Byte1 = aVoiceMailInfo.GetL(); - - iType = (TVoiceMailInfoType) (Byte1 & EMask1Bit); - iProfile = (TSmsMessageProfileType ) ((Byte1 >> 2) & EMask2Bits); - iStorage = (TBool) ((Byte1 >> 4) & EMask1Bit); - iAlmostFull = (TBool) ((Byte1 >> 5) & EMask1Bit); - iFull = (TBool) ((Byte1 >> 6) & EMask1Bit); - iExtensionIndicator = (TBool) ((Byte1 >> 7) & EMask1Bit); - - LOGGSMU2("CEnhancedVoiceMailBoxInformation::DecodeL 1st byte = %d", Byte1); - - // Create an address object to deccode the mail box access address from the - // format required by 23.040 v6.5.0 section 9.1.2.5. - CSmsAddress* decodedAddress = CSmsAddress::NewL(aCharacterSetConverter,aFs); - CleanupStack::PushL(decodedAddress); - - // CSmsAddress::DecodeL is also used to decode source and destination addresses. - // CSmsAddress::DecodeL expects internally that alphanumeric addresses will be size - // CSmsAddress::KSmsAddressMaxAddressValueLength=10. - // Need to add padding bytes to bring the address field up to the maximum size. - const TPtrC8 remainder(aVoiceMailInfo.Remainder()); - - if (remainder.Length() < CSmsAddress::KSmsAddressMaxAddressLength) - { - TBuf8 data; - data = remainder; - TInt actualLength = data.Length(); - data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength); - - for (TUint8 j = actualLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++) - { - data[j] = 0; - } - - TGsmuLex8 encodedAddress(data); - decodedAddress->DecodeL(encodedAddress); - // might want to check that aVoiceMailInfo can be incremented - // by encodedAddress.Offset. - aVoiceMailInfo.Inc(encodedAddress.Offset()); - } - else - { - decodedAddress->DecodeL(aVoiceMailInfo); - } - - TInt length=(decodedAddress->Address()).Length(); - NewBufferL(length); - iAccessAddress->Des().Copy((decodedAddress->Address().Ptr()),length); - - iTypeOfAddress = decodedAddress->TypeOfAddress(); - - CleanupStack::PopAndDestroy(decodedAddress); - - iNumberOfVoiceMessages = aVoiceMailInfo.GetL(); - LOGGSMU2("CEnhancedVoiceMailBoxInformation::DecodeL iNumberOfVoiceMessages = %d", iNumberOfVoiceMessages); - } // CEnhancedVoiceMailBoxInformation::DecodeL - - -CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation() - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()"); - - // Consider changing this over to a Panic. - iType = EGsmSmsVoiceMailNotification; - iOctet1Bit1 = EFalse; - iProfile = EGsmSmsProfileId1; - iStorage = EFalse; - iAlmostFull = EFalse; - iFull = EFalse; - iExtensionIndicator = EFalse; - iTypeOfAddress = 0; - } // CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation - - -CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation(TVoiceMailInfoType aTVoiceMailInfoType) - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()"); - - iType = aTVoiceMailInfoType; - iOctet1Bit1 = EFalse; - iProfile = EGsmSmsProfileId1; - iStorage = EFalse; - iAlmostFull = EFalse; - iFull = EFalse; - iExtensionIndicator = EFalse; - iTypeOfAddress = 0; - } // CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation - - -/** - * @internalComponent - * - * Prevent clients from using the copy constructor by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation(const CEnhancedVoiceMailBoxInformation&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation"); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the equality operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -TBool CEnhancedVoiceMailBoxInformation::operator==(const CEnhancedVoiceMailBoxInformation&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailBoxInformation::operator=="); - Panic(KGsmuPanicMethodBodyNotImplemented); - return EFalse; - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the assignment operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -void CEnhancedVoiceMailBoxInformation::operator=(const CEnhancedVoiceMailBoxInformation&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailBoxInformation::operator="); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -void CEnhancedVoiceMailBoxInformation::ConstructL() - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::ConstructL()"); - - NewBufferL(0); - } // CEnhancedVoiceMailBoxInformation::ConstructL - - -CEnhancedVoiceMailBoxInformation::~CEnhancedVoiceMailBoxInformation() - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::~CEnhancedVoiceMailBoxInformation"); - delete iAccessAddress; - } // CEnhancedVoiceMailBoxInformation::ConstructL - - -CEnhancedVoiceMailBoxInformation* CEnhancedVoiceMailBoxInformation::NewL() - { - LOGGSMU1("CEnhancedVoiceMailBoxInformation::NewL()"); - - CEnhancedVoiceMailBoxInformation* aCEnhancedVoiceMailBoxInformation=new(ELeave) CEnhancedVoiceMailBoxInformation(); - CleanupStack::PushL(aCEnhancedVoiceMailBoxInformation); - aCEnhancedVoiceMailBoxInformation->ConstructL(); - CleanupStack::Pop(aCEnhancedVoiceMailBoxInformation); - return aCEnhancedVoiceMailBoxInformation; - } // CEnhancedVoiceMailBoxInformation::NewL - - -/** - * @publishedAll - * - * Sets the message id to a value between 0 and 65535. - * - * @param aNumber - * The message id - * - * @capability None - */ -EXPORT_C void CVoiceMailNotification::SetMessageId(TUint16 aMessageId) - { - LOGGSMU1("CVoiceMailNotification::SetMessageId()"); - - iMessageId = aMessageId; - } // CVoiceMailNotification::SetMessageId - - -/** - * @publishedAll - * - * Retrieves the message id, a value in the range 0 to 65535. - * - * @return - * The message id, - * - * @capability None - */ -EXPORT_C TUint16 CVoiceMailNotification::MessageId() const - { - LOGGSMU1("CVoiceMailNotification::MessageId()"); - - return iMessageId; - } // CVoiceMailNotification::MessageId - - -/** - * @publishedAll - * - * Sets the voice mail message length to a value between 0 and 255 - * - * @param aLength - * The voice mail message length. - * - * @capability None - */ -EXPORT_C void CVoiceMailNotification::SetMessageLength(TUint8 aLength) - { - LOGGSMU1("CVoiceMailNotification::SetMessageLength()"); - - iMessageLength=aLength; - } // CVoiceMailNotification::SetMessageLength - - -/** - * @publishedAll - * - * Retrieves the voice mail message length, a value in the range 0 to 255. - * - * @return - * The voice mail message length. - * - * @capability None - */ -EXPORT_C TUint8 CVoiceMailNotification::MessageLength() const - { - LOGGSMU1("CVoiceMailNotification::MessageLength()"); - - return iMessageLength; - } // CVoiceMailNotification::MessageLength - - -/** - * @publishedAll - * - * Sets the number of days that the voice message will be retained to - * a value between 0 and 31. Values in excess of 31 will be capped at - * 31. - * - * @param aDays - * The number of retention days. - * - * @capability None - */ -EXPORT_C void CVoiceMailNotification::SetRetentionDays(TUint8 aDays) - { - LOGGSMU1("CVoiceMailNotification::SetRetentionDays()"); - - if (aDays > 31) - { - iRetentionDays = 31; - } - else - { - iRetentionDays = aDays; - } - } // CVoiceMailNotification::SetRetentionDays - - -/** - * @publishedAll - * - * Retrieves the number of days the voice message will be retained. - * - * @return - * The number of days the voice message will be retained. - * - * @capability None - */ -EXPORT_C TUint8 CVoiceMailNotification::RetentionDays() const - { - LOGGSMU1("CVoiceMailNotification::RetentionDays()"); - - return iRetentionDays; - } // CVoiceMailNotification::RetentionDays - - -/** - * @publishedAll - * - * Sets the message priority to urgent - * - * @param aPriority - * Set to True if the priority is urgent, - * Otherwise set to False. - * - * @capability None - */ -EXPORT_C void CVoiceMailNotification::SetPriorityIndication(TBool aPriority) - { - LOGGSMU1("CVoiceMailNotification::SetPriorityIndication()"); - - iPriorityIndication=aPriority; - } // CVoiceMailNotification::SetPriorityIndication - - -/** - * @publishedAll - * - * Retrieves the priority indication. - * - * @return - * True if the priority is urgent, - * False otherwise. - * - * @capability None - */ -EXPORT_C TBool CVoiceMailNotification::PriorityIndication() const - { - LOGGSMU1("CVoiceMailNotification::PriorityIndication()"); - - return iPriorityIndication; - } // CVoiceMailNotification::PriorityIndication - - -/** - * @publishedAll - * - * Indicates whether the voice mail notification contains extension bytes. - * - * @return - * True if the voice mail notification contains extension bytes. - * False otherwise. - * - * @capability None - */ -EXPORT_C TBool CVoiceMailNotification::MessageExtensionIndication() const - { - LOGGSMU1("CVoiceMailNotification::MessageExtensionIndication()"); - - return iMessageExtensionIndicator; - } // CVoiceMailNotification::MessageExtensionIndication - - -void CVoiceMailNotification::NewBufferL(TInt aLength) - { - LOGGSMU1("CVoiceMailNotification::NewBufferL()"); - - HBufC* buffer=HBufC::NewL(aLength); - delete iCallingLineIdentity; - iCallingLineIdentity=buffer; - iCallingLineIdentity->Des().SetLength(aLength); - iCallingLineIdentity->Des().FillZ(); - } // CVoiceMailNotification::NewBufferL - - -/** - * @publishedAll - * - * Used to set the calling line idenity - * - * @param aLineIdentity - * - * @capability None - */ -EXPORT_C void CVoiceMailNotification::SetCallingLineIdentityL(TDesC& aLineIdentity) - { - LOGGSMU1("CVoiceMailNotification::SetCallingLineIdentityL()"); - - TInt length=aLineIdentity.Length(); - NewBufferL(length); - iCallingLineIdentity->Des().Copy(aLineIdentity); - - const TGsmSmsTypeOfNumber typeofnumber=length && (iCallingLineIdentity->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown; - iTypeOfAddress.SetTON(typeofnumber); - } // CVoiceMailNotification::SetCallingLineIdentityL - - -/** - * @publishedAll - * - * Retrieves the Calling Line Identity - * - * @return - * A pointer to the Calling Line Identity. - * - * @capability None - */ -EXPORT_C TPtrC CVoiceMailNotification::CallingLineIdentity() const - { - LOGGSMU1("CVoiceMailNotification::CallingLineIdentity()"); - - TPtrC ptr; - if (iCallingLineIdentity) - ptr.Set(iCallingLineIdentity->Des()); - return ptr; - } // CVoiceMailNotification::CallingLineIdentity - - -/** - * @publishedAll - * - * Set the Calling Line Id as a parsed address. - * - * @param aParsedAddress - * The Calling Line Id as a parsed address. - * - * @capability None - */ -EXPORT_C void CVoiceMailNotification::SetParsedCallingLineIdentityL(TGsmSmsTelNumber& aParsedAddress) - { - LOGGSMU1("CVoiceMailNotification::SetParsedCallingLineIdentityL()"); - - iTypeOfAddress=aParsedAddress.iTypeOfAddress; - DoSetParsedAddressL(aParsedAddress.iTelNumber); - } // CVoiceMailNotification::SetParsedCallingLineIdentityL - - -/** - * @publishedAll - * - * Gets the Calling Line Id as a parsed address. - * - * @param aParsedAddress - * An output parameter which is to be set to the parsed calling line ID. - * - * @capability None - */ -EXPORT_C void CVoiceMailNotification::ParsedCallingLineIdentity(TGsmSmsTelNumber& aParsedAddress) const - { - LOGGSMU1("CVoiceMailNotification::ParsedCallingLineIdentity()"); - - aParsedAddress.iTypeOfAddress = iTypeOfAddress; - - TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength(); - - if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric) - { - TInt parsedlength=CallingLineIdentity().Length(); - if (parsedlength>maxparsedlength) - parsedlength=maxparsedlength; - aParsedAddress.iTelNumber.Copy(CallingLineIdentity().Mid(0,parsedlength)); - } - else - { - aParsedAddress.iTelNumber.SetLength(maxparsedlength); - - TInt length=iCallingLineIdentity->Des().Length(); - TInt parsedlength=0; - for (TInt i=0; (iDes()[i]; - if ((ch>='0') && (ch<='9')) - { - aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch; - parsedlength++; - } - } - - aParsedAddress.iTelNumber.SetLength(parsedlength); - } - } // CVoiceMailNotification::ParsedCallingLineIdentity - - -void CVoiceMailNotification::NewExtensionL(TInt aLength) - { - LOGGSMU1("CVoiceMailNotification::NewExtensionL()"); - - HBufC* buffer=HBufC::NewL(aLength); - delete iExtension; - iExtension=buffer; - iExtension->Des().SetLength(aLength); - iExtension->Des().FillZ(); - } // CVoiceMailNotification::NewExtensionL - - -/*void CVoiceMailNotification::SetExtension(TDesC& aExtension) - { - LOGGSMU1("CVoiceMailNotification::SetExtension()"); - - TInt length=aExtension.Length(); - NewExtensionL(length); - iExtension->Des().Copy(aExtension); - } // CVoiceMailNotification::SetExtension - -TPtrC CVoiceMailNotification::Extension() const - { - LOGGSMU1("CVoiceMailNotification::Extension()"); - - TPtrC ptr; - if (iExtension) - ptr.Set(iExtension->Des()); - return ptr; - }*/ - - -/** - * @internalComponent - * - * Determines the size of the encoded Voice Mail Notification. - * - * @param aCharacterSetConverter A reference to a character set converter. - * @param aFs A reference to the file server. - * @return The size of the encoded Voice Mail Notification - * - * @capability None - */ -TUint8 CVoiceMailNotification::SizeL(CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) - { - LOGGSMU1("CVoiceMailNotification::SizeL()"); - - const TUint8 KTotalSizeOfFixedLengthAttributes = 4; - TUint8 size = KTotalSizeOfFixedLengthAttributes; - - // need to find the size of the calling line ID. - CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs); - CleanupStack::PushL(address); - - TPtrC callingLineIdentityPtr; - if (iCallingLineIdentity) - { - callingLineIdentityPtr.Set(iCallingLineIdentity->Des()); - } - - address->SetRawAddressL(iTypeOfAddress,callingLineIdentityPtr); - - size += address->SizeL(); - CleanupStack::PopAndDestroy(address); - - return size; - } // CVoiceMailNotification::SizeL - - -TUint8* CVoiceMailNotification::EncodeL(TUint8* aPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const - { - // When changes are made to this function that affect the - // number of bytes that are encoded, this should be reflected in - // CVoiceMailNotification::SizeL() - LOGGSMU1("CVoiceMailNotification::EncodeL"); - - - *aPtr = (TUint8) (iMessageId >> 8); // Message Id MSB - aPtr++; - *aPtr = (TUint8) iMessageId; // Message Id LSB - aPtr++; - *aPtr = (TUint8) iMessageLength; - aPtr++; - *aPtr = ((TUint8) (iRetentionDays & EMask5Bits)) + - (((TUint8) iPriorityIndication) << 6) + - (((TUint8) iMessageExtensionIndicator) << 7); - aPtr++; - - CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs); - CleanupStack::PushL(address); - - TPtrC callingLineIdentityPtr; - if (iCallingLineIdentity) - { - callingLineIdentityPtr.Set(iCallingLineIdentity->Des()); - } - - address->SetRawAddressL(iTypeOfAddress,callingLineIdentityPtr); - - aPtr = address->EncodeL(aPtr); - CleanupStack::PopAndDestroy(address); - - return aPtr; - } // CVoiceMailNotification::EncodeL - - -void CVoiceMailNotification::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) - { - LOGGSMU1("CVoiceMailNotification::DecodeL"); - - iMessageId = (((TUint16) aVoiceMailInfo.GetL()) << 8); - iMessageId += ((TUint16) aVoiceMailInfo.GetL()); - - iMessageLength=aVoiceMailInfo.GetL(); - - TUint8 currentByte = aVoiceMailInfo.GetL(); - - iRetentionDays = currentByte & EMask5Bits; - iPriorityIndication = ((currentByte >> 6) & EMask1Bit); - iMessageExtensionIndicator = ((currentByte >> 7) & EMask1Bit); - - CSmsAddress* decodedAddress = CSmsAddress::NewL(aCharacterSetConverter,aFs); - CleanupStack::PushL(decodedAddress); - - const TPtrC8 remainder(aVoiceMailInfo.Remainder()); - // The address information element makes an assumption that aVoiceMail must - // be of size CSmsAddress::KSmsAddressMaxAddressLength - // Provide padding to ensure that this is the case. - if (remainder.Length() < CSmsAddress::KSmsAddressMaxAddressLength) - { - TBuf8 data; - data = remainder; - TInt actualLength = data.Length(); - data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength); - - for (TUint8 j = actualLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++) - { - data[j] = 0; - } - - TGsmuLex8 encodedAddress(data); - decodedAddress->DecodeL(encodedAddress); - // Should be the last piece of data to be decoded - // The next line is included for completeness. - aVoiceMailInfo.Inc(encodedAddress.Offset()); - } - else - { - decodedAddress->DecodeL(aVoiceMailInfo); - } - - TInt length=(decodedAddress->Address()).Length(); - NewBufferL(length); - iCallingLineIdentity->Des().Copy((decodedAddress->Address().Ptr()),length); - - iTypeOfAddress = decodedAddress->TypeOfAddress(); - - CleanupStack::PopAndDestroy(decodedAddress); - - if (iMessageExtensionIndicator) - { - TUint8 extensionLength = aVoiceMailInfo.GetL(); - aVoiceMailInfo.Inc(extensionLength); - } - } // CVoiceMailNotification::DecodeL - - -/** - * @internalComponent - * - * Prevent clients from using the copy constructor by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -CVoiceMailNotification::CVoiceMailNotification(const CVoiceMailNotification&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CVoiceMailNotification::CVoiceMailNotification"); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the equality operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -TBool CVoiceMailNotification::operator==(const CVoiceMailNotification&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CVoiceMailNotification::operator=="); - Panic(KGsmuPanicMethodBodyNotImplemented); - return EFalse; - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the assignment operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -void CVoiceMailNotification::operator=(const CVoiceMailNotification&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CVoiceMailNotification::operator="); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -CVoiceMailNotification::CVoiceMailNotification() - { - LOGGSMU1("CVoiceMailNotification::CVoiceMailNotification()"); - - iMessageId = 0; - iMessageLength = 0; - iRetentionDays = 0; - iOctetN8Bit1 = EFalse; - iPriorityIndication = EFalse; - iMessageExtensionIndicator = EFalse; - iTypeOfAddress = 0; - } // CVoiceMailNotification::CVoiceMailNotification - - -/** - * @publishedAll - * - * Class Destructor - * - * @capability None - */ -EXPORT_C CVoiceMailNotification::~CVoiceMailNotification() - { - LOGGSMU1("CVoiceMailNotification::~CVoiceMailNotification"); - delete iCallingLineIdentity; - delete iExtension; - } // CVoiceMailNotification::CVoiceMailNotification - - -void CVoiceMailNotification::ConstructL() - { - LOGGSMU1("CVoiceMailNotification::ConstructL()"); - - NewBufferL(0); - NewExtensionL(0); - } // CVoiceMailNotification::ConstructL - - -/** - * @publishedAll - * - * Class construction method. - * - * @capability None - */ -EXPORT_C CVoiceMailNotification* CVoiceMailNotification::NewL() - { - LOGGSMU1("CVoiceMailNotification::NewL()"); - - CVoiceMailNotification* aCVoiceMailNotification=new(ELeave) CVoiceMailNotification(); - CleanupStack::PushL(aCVoiceMailNotification); - aCVoiceMailNotification->ConstructL(); - CleanupStack::Pop(aCVoiceMailNotification); - return aCVoiceMailNotification; - } // CVoiceMailNotification::NewL - - -void CVoiceMailNotification::DoSetParsedAddressL(const TDesC& aAddress) - { - LOGGSMU1("CVoiceMailNotification::DoSetParsedAddressL()"); - - TInt length=aAddress.Length(); - if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) && - (length && (aAddress[0]!='+'))) - { - NewBufferL(length+1); - iCallingLineIdentity->Des()[0]='+'; - TPtr ptr((TText*) (iCallingLineIdentity->Des().Ptr()+1),length,length); - ptr.Copy(aAddress); - } - else - { - NewBufferL(length); - iCallingLineIdentity->Des().Copy(aAddress); - } - } // CVoiceMailNotification::DoSetParsedAddressL - - -/** - * @publishedAll - * - * Retrieves the number of voice message notifications contained in - * this information. The range is 0 to 15. - * - * @return - * The number of voice message notifications in this information element. - * - * @capability None - */ -EXPORT_C TUint8 CEnhancedVoiceMailNotification::NumberOfVoiceMails() - { - LOGGSMU1("CEnhancedVoiceMailNotification::NumberOfVoiceMails()"); - - return (TUint8) iNotifications->Count(); - } // CEnhancedVoiceMailNotification::NumberOfVoiceMails - - -/*void CEnhancedVoiceMailNotification::SetExtension(TDesC& aExtension) - { - LOGGSMU1("CEnhancedVoiceMailNotification::SetExtension()"); - - TInt length=aExtension.Length(); - NewExtensionL(length); - iExtension->Des().Copy(aExtension); - } // CEnhancedVoiceMailNotification::SetExtension - -TPtrC CEnhancedVoiceMailNotification::Extension() const - { - LOGGSMU1("CEnhancedVoiceMailNotification::Extension()"); - - TPtrC ptr; - if (iExtension) - ptr.Set(iExtension->Des()); - return ptr; - }*/ - - -/** - * @publishedAll - * - * Provides a reference to the collection that is used to contain the Voice Mail Notifications. - * A maximum of 15 voice mail confirmations is supported. If more that 15 voice mails notifications are added - * the CEnhancedVoiceMailNotification will not be added to the CSmsMessage by the CSmsEnhancedVoiceMailOperations - * class. - * - * @return - * A reference to the collection that is used to contain the Voice Mail Notifications. - * - * @capability None - */ -EXPORT_C RPointerArray& CEnhancedVoiceMailNotification::GetVoiceMailNotifications() - { - LOGGSMU1("CEnhancedVoiceMailNotification::GetVoiceMailNotifications()"); - - return *iNotifications; - } // CEnhancedVoiceMailNotification::GetVoiceMailNotifications - - -void CEnhancedVoiceMailNotification::NewExtensionL(TInt aLength) - { - LOGGSMU1("CEnhancedVoiceMailNotification::NewExtensionL()"); - - HBufC* buffer=HBufC::NewL(aLength); - delete iExtension; - iExtension=buffer; - iExtension->Des().SetLength(aLength); - iExtension->Des().FillZ(); - } // CEnhancedVoiceMailNotification::NewExtensionL - - -/** - * @publishedAll - * - * Class construction method. - * - * @capability None - */ -EXPORT_C CEnhancedVoiceMailNotification* CEnhancedVoiceMailNotification::NewL() - { - LOGGSMU1("CEnhancedVoiceMailNotification::NewL()"); - - CEnhancedVoiceMailNotification* aCEnhancedVoiceMailNotification=new(ELeave) CEnhancedVoiceMailNotification(); - CleanupStack::PushL(aCEnhancedVoiceMailNotification); - aCEnhancedVoiceMailNotification->CEnhancedVoiceMailBoxInformation::ConstructL(); - aCEnhancedVoiceMailNotification->ConstructL(); - CleanupStack::Pop(aCEnhancedVoiceMailNotification); - return aCEnhancedVoiceMailNotification; - } // CEnhancedVoiceMailNotification::NewL - - -CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification() : CEnhancedVoiceMailBoxInformation(EGsmSmsVoiceMailNotification) - { - } // CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification - - -/** - * @internalComponent - * - * Prevent clients from using the copy constructor by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification(const CEnhancedVoiceMailNotification&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification"); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the equality operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -TBool CEnhancedVoiceMailNotification::operator==(const CEnhancedVoiceMailNotification&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailNotification::operator=="); - Panic(KGsmuPanicMethodBodyNotImplemented); - return EFalse; - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the assignment operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -void CEnhancedVoiceMailNotification::operator=(const CEnhancedVoiceMailNotification&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailNotification::operator="); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -/** - * @publishedAll - * - * Class destructor. - * - * @capability None - */ -EXPORT_C CEnhancedVoiceMailNotification::~CEnhancedVoiceMailNotification() - { - LOGGSMU1("CEnhancedVoiceMailNotification::~CEnhancedVoiceMailNotification"); - delete iExtension; - iNotifications->ResetAndDestroy(); - iNotifications->Close(); - delete iNotifications; - } // CEnhancedVoiceMailNotification::operator - - -void CEnhancedVoiceMailNotification::ConstructL() - { - LOGGSMU1("CEnhancedVoiceMailNotification::ConstructL()"); - - NewExtensionL(0); - iNotifications = new (ELeave) RPointerArray(KMaxNumberOfNotifications); - } // CEnhancedVoiceMailNotification::ConstructL - - -TUint8* CEnhancedVoiceMailNotification::EncodeL(TUint8* aCurrentPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const - { - LOGGSMU1("CEnhancedVoiceMailNotification::EncodeL"); - - TUint8* startPtr = aCurrentPtr; - - aCurrentPtr = CEnhancedVoiceMailBoxInformation::EncodeL(aCurrentPtr, aCharacterSetConverter, aFs); - - TUint8 count = (TUint8) iNotifications->Count(); - if (count > KMaxNumberOfNotifications) - { - User::Leave(KErrArgument); - } - - *aCurrentPtr = (count & KSmsNotificationBitMask); - aCurrentPtr++; - - TInt16 spaceAlreadyAllocated = 0; // handle architectures whose address space increments and whose address space decrements. - (aCurrentPtr > startPtr) ? (spaceAlreadyAllocated = aCurrentPtr - startPtr) : (spaceAlreadyAllocated = startPtr - aCurrentPtr); - - TInt16 remainingSize = (TInt16)(CEnhancedVoiceMailNotification::KSmsMaxEnhancedVoiceMailSize - spaceAlreadyAllocated); - for (TUint i = 0; i < count; i++) - { - remainingSize -= (TInt16)(*iNotifications)[i]->SizeL(aCharacterSetConverter,aFs); - if (remainingSize < 0) - { - User::Leave(KErrArgument); - } - - aCurrentPtr = (*iNotifications)[i]->EncodeL(aCurrentPtr, aCharacterSetConverter, aFs); - } - - return aCurrentPtr; - } // CEnhancedVoiceMailNotification::EncodeL - - -void CEnhancedVoiceMailNotification::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) - { - LOGGSMU1("CEnhancedVoiceMailNotification::DecodeL"); - - CEnhancedVoiceMailBoxInformation::DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs); - - TUint8 numberOfNotifications = (aVoiceMailInfo.GetL() & KSmsNotificationBitMask); - - if (iExtensionIndicator) - { - TUint8 extensionLength = aVoiceMailInfo.GetL(); - aVoiceMailInfo.Inc(extensionLength); - } - - for (TUint8 i = 0; i < numberOfNotifications; i++) - { - CVoiceMailNotification* voiceMailNotification = CVoiceMailNotification::NewL(); - CleanupStack::PushL(voiceMailNotification); - voiceMailNotification->DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs); - iNotifications->AppendL(voiceMailNotification); - CleanupStack::Pop(voiceMailNotification); - } - } // CEnhancedVoiceMailNotification::DecodeL - - -/** - * @publishedAll - * - * Sets the message ID of the specific Voice Mail message - * whose deletion is being confirmed. - * - * @param aMessageId - * The message ID of the specific voice mail message whose deletion - * is being confirmed. - * - * @capability None - */ -EXPORT_C void CVoiceMailDeletion::SetMessageId(TUint16 aMessageId) - { - LOGGSMU1("CVoiceMailDeletion::SetMessageId()"); - - iMessageId=aMessageId; - } // CVoiceMailDeletion::SetMessageId - - -/** - * @publishedAll - * - * Retrieves the message ID of the Voice Mail message - * whose deletion is being confirmed, range 0 to 65535. - * - * @return - * The message ID of the Voice Mail message whose deletion - * is being confirmed, range 0 to 65535. - * - * @capability None - */ -EXPORT_C TUint16 CVoiceMailDeletion::MessageId() const - { - LOGGSMU1("CVoiceMailDeletion::MessageId()"); - - return iMessageId; - } // CVoiceMailDeletion::MessageId - - -/** - * @publishedAll - * - * Indicates whether the voice mail deletion contains extension bytes. - * - * @return - * True if the voice mail deletion contains extension bytes. - * False otherwise. - * - * @capability None - */ -EXPORT_C TBool CVoiceMailDeletion::MessageExtensionIndication() const - { - LOGGSMU1("CVoiceMailDeletion::MessageExtensionIndication()"); - - return iExtensionIndicator; - } // CVoiceMailDeletion::MessageExtensionIndication - - -TUint8 CVoiceMailDeletion::SizeL() - { - LOGGSMU1("CVoiceMailDeletion::SizeL()"); - - const TUint8 KSizeOfVoiceMailDeletion = 3; - return KSizeOfVoiceMailDeletion; - } // CVoiceMailDeletion::SizeL - - -TUint8* CVoiceMailDeletion::EncodeL(TUint8* aPtr) const - { - // When changes are made which affect the - // number of bytes encoded, this should be - // reflected in VoiceMailDeletion::SizeL() - LOGGSMU1("CVoiceMailDeletion::EncodeL"); - - *aPtr = (TUint8) (iMessageId >> 8); - aPtr++; - *aPtr = (TUint8) iMessageId; - aPtr++; - *aPtr = ((TUint8) iExtensionIndicator) << 7; - aPtr++; - return aPtr; - } // CVoiceMailDeletion::EncodeL - - -void CVoiceMailDeletion::DecodeL(TGsmuLex8& aVoiceMailInfo) - { - LOGGSMU1("CVoiceMailDeletion::DecodeL"); - - iMessageId = (((TUint16) aVoiceMailInfo.GetL()) << 8) + - ((TUint16) aVoiceMailInfo.GetL()); - iExtensionIndicator = (aVoiceMailInfo.GetL() >> 7); - - if (iExtensionIndicator) - { - TUint8 extensionLength = aVoiceMailInfo.GetL(); - aVoiceMailInfo.Inc(extensionLength); - } - } // CVoiceMailDeletion::DecodeL - - -CVoiceMailDeletion::CVoiceMailDeletion() - { - iMessageId = 0; - iExtensionIndicator = EFalse; - } // CVoiceMailDeletion::CVoiceMailDeletion - - -/** - * @internalComponent - * - * Prevent clients from using the copy constructor by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -CVoiceMailDeletion::CVoiceMailDeletion(const CVoiceMailDeletion&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CVoiceMailDeletion::CVoiceMailDeletion"); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the equality operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -TBool CVoiceMailDeletion::operator==(const CVoiceMailDeletion&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CVoiceMailDeletion::operator=="); - Panic(KGsmuPanicMethodBodyNotImplemented); - return EFalse; - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the assignment operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -void CVoiceMailDeletion::operator=(const CVoiceMailDeletion&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CVoiceMailDeletion::operator="); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -/** - * @publishedAll - * - * Class destructor. - * - * @capability None - */ -EXPORT_C CVoiceMailDeletion::~CVoiceMailDeletion() - { - LOGGSMU1("CVoiceMailDeletion::~CVoiceMailDeletion"); - - delete iExtension; - } // CVoiceMailDeletion::operator - - -void CVoiceMailDeletion::ConstructL() - { - LOGGSMU1("CVoiceMailDeletion::ConstructL()"); - - NewBufferL(0); - } // CVoiceMailDeletion::ConstructL - - -void CVoiceMailDeletion::NewBufferL(TInt aLength) - { - LOGGSMU1("CVoiceMailDeletion::NewBufferL()"); - - HBufC* buffer=HBufC::NewL(aLength); - delete iExtension; - iExtension=buffer; - iExtension->Des().SetLength(aLength); - iExtension->Des().FillZ(); - } // CVoiceMailDeletion::NewBufferL - - -/** - * @publishedAll - * - * Class constructor - * - * @capability None - */ -EXPORT_C CVoiceMailDeletion* CVoiceMailDeletion::NewL() - { - LOGGSMU1("CVoiceMailDeletion::NewL()"); - - CVoiceMailDeletion* voiceMailDeletion=new(ELeave) CVoiceMailDeletion(); - CleanupStack::PushL(voiceMailDeletion); - voiceMailDeletion->ConstructL(); - CleanupStack::Pop(voiceMailDeletion); - return voiceMailDeletion; - } // CVoiceMailDeletion::NewL - - -/* -void CVoiceMailDeletion::SetExtension(TDesC& aExtension) - { - LOGGSMU1("CVoiceMailDeletion::SetExtension()"); - - TInt length=aExtension.Length(); - NewBufferL(length); - iExtension->Des().Copy(aExtension); - } // CVoiceMailDeletion::SetExtension - - -TPtrC CVoiceMailDeletion::Extension() const - { - LOGGSMU1("CVoiceMailDeletion::Extension()"); - - TPtrC ptr; - if (iExtension) - ptr.Set(iExtension->Des()); - return ptr; - }*/ - - -void CEnhancedVoiceMailDeleteConfirmations::NewExtensionL(TInt aLength) - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NewExtensionL()"); - - HBufC* buffer=HBufC::NewL(aLength); - delete iExtension; - iExtension=buffer; - iExtension->Des().SetLength(aLength); - iExtension->Des().FillZ(); - } // CEnhancedVoiceMailDeleteConfirmations::NewExtensionL - - -CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations() : CEnhancedVoiceMailBoxInformation(EGsmSmsVoiceMailDeleteConfirmation) - { - //NOP - } // CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations - - -/** - * @publishedAll - * - * Class destructor - * - * @capability None - */ -EXPORT_C CEnhancedVoiceMailDeleteConfirmations::~CEnhancedVoiceMailDeleteConfirmations() - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::~CEnhancedVoiceMailDeleteConfirmations"); - - delete iExtension; - iVoiceMailDeletions->ResetAndDestroy(); - iVoiceMailDeletions->Close(); - delete iVoiceMailDeletions; - } // CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations - - -/** - * @internalComponent - * - * Prevent clients from using the copy constructor by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations(const CEnhancedVoiceMailDeleteConfirmations&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations"); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the equality operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -TBool CEnhancedVoiceMailDeleteConfirmations::operator==(const CEnhancedVoiceMailDeleteConfirmations&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::operator=="); - Panic(KGsmuPanicMethodBodyNotImplemented); - return EFalse; - BULLSEYE_RESTORE - } - -/** - * @internalComponent - * - * Prevent clients from using the assignment operator by including it in the class definition - * but making it protected and not exporting it. - * - * @capability None - */ -void CEnhancedVoiceMailDeleteConfirmations::operator=(const CEnhancedVoiceMailDeleteConfirmations&) - { - // Ignore in code coverage - not intended to be used - BULLSEYE_OFF - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::operator="); - Panic(KGsmuPanicMethodBodyNotImplemented); - BULLSEYE_RESTORE - } - -void CEnhancedVoiceMailDeleteConfirmations::ConstructL() - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::ConstructL()"); - - NewExtensionL(0); - - iVoiceMailDeletions = new (ELeave) RPointerArray(15); - } // CEnhancedVoiceMailDeleteConfirmations::ConstructL - - -/** - * @publishedAll - * - * Class constructor - * - * @capability None - */ -EXPORT_C CEnhancedVoiceMailDeleteConfirmations* CEnhancedVoiceMailDeleteConfirmations::NewL() - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NewL()"); - - CEnhancedVoiceMailDeleteConfirmations* aCEnhancedVoiceMailDeleteConfirmations=new(ELeave) CEnhancedVoiceMailDeleteConfirmations(); - CleanupStack::PushL(aCEnhancedVoiceMailDeleteConfirmations); - aCEnhancedVoiceMailDeleteConfirmations->CEnhancedVoiceMailBoxInformation::ConstructL(); - aCEnhancedVoiceMailDeleteConfirmations->ConstructL(); - CleanupStack::Pop(aCEnhancedVoiceMailDeleteConfirmations); - return aCEnhancedVoiceMailDeleteConfirmations; - } // CEnhancedVoiceMailDeleteConfirmations::NewL - - -/** - * @publishedAll - * - * Indicates the number of message IDs that follow in this IE. - * - * @return - * The number of message IDs that follow. - * - * @capability None - */ -EXPORT_C TUint8 CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes() - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes()"); - - return iVoiceMailDeletions->Count(); - } // CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes - - -/** - * @publishedAll - * - * Provides a reference to the collection that is used to contain the Voice Mail Deletion - * notifications. Up to 31 instances of CVoiceMailDeletion can be stored. If more than - * 31 instances are added, the CEnhancedVoiceMailDeleteConfirmations will not be added to - * the CSmsMessage. - * - * @return - * A reference to the collection that is used to contain the Voice Mail Deletion - * notifications. - * - * @capability None - */ -EXPORT_C RPointerArray& CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions() - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions()"); - - return *iVoiceMailDeletions; - } // CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions - - -/* -void CEnhancedVoiceMailDeleteConfirmations::SetExtension(TDesC& aExtension) - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::SetExtension()"); - - TInt length=aExtension.Length(); - NewBufferL(length); - iExtension->Des().Copy(aExtension); - } // CEnhancedVoiceMailDeleteConfirmations::SetExtension - - -TPtrC CEnhancedVoiceMailDeleteConfirmations::Extension() const - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::Extension()"); - - TPtrC ptr; - if (iExtension) - { - ptr.Set(iExtension->Des()); - } - return ptr; - }*/ - - -TUint8* CEnhancedVoiceMailDeleteConfirmations::EncodeL(TUint8* aCurrentPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::EncodeL"); - - TUint8* startPtr = aCurrentPtr; - - aCurrentPtr = CEnhancedVoiceMailBoxInformation::EncodeL(aCurrentPtr, aCharacterSetConverter, aFs); - - TUint8 count = ((TUint8)iVoiceMailDeletions->Count()); - - if (count > KMaxNumberOfNotifications) - { - User::Leave(KErrArgument); - } - - *aCurrentPtr= (count & KSmsNotificationBitMask); - aCurrentPtr++; - - TInt16 spaceAlreadyAllocated; // handle architectures whose address space increments and whose address space decrements. - (aCurrentPtr > startPtr) ? (spaceAlreadyAllocated = aCurrentPtr - startPtr) : (spaceAlreadyAllocated = startPtr - aCurrentPtr); - - // allow space for id and length bytes - TInt16 remainingSize = (TInt16)(CEnhancedVoiceMailBoxInformation::KSmsMaxEnhancedVoiceMailSize - spaceAlreadyAllocated); - - for (TUint i = 0; i < count; i++) - { - remainingSize -= (TInt16)(*iVoiceMailDeletions)[i]->SizeL(); - if (remainingSize < 0) - { - User::Leave(KErrArgument); - } - - aCurrentPtr = (*iVoiceMailDeletions)[i]->EncodeL(aCurrentPtr); - } - - return aCurrentPtr; - } // CEnhancedVoiceMailDeleteConfirmations::EncodeL - - -void CEnhancedVoiceMailDeleteConfirmations::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) - { - LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::DecodeL"); - - CEnhancedVoiceMailBoxInformation::DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs); - - TUint numberOfVMDeletions = (aVoiceMailInfo.GetL() & KSmsNotificationBitMask); - - if (iExtensionIndicator) - { - TUint8 extensionLength = aVoiceMailInfo.GetL(); - aVoiceMailInfo.Inc(extensionLength); - } - - for (TUint8 i = 0; i < numberOfVMDeletions; i++) - { - // Create a Voice Mail Deletion - CVoiceMailDeletion* voiceMailDeletion = CVoiceMailDeletion::NewL(); - CleanupStack::PushL(voiceMailDeletion); - voiceMailDeletion->DecodeL(aVoiceMailInfo); - CleanupStack::Pop(voiceMailDeletion); - iVoiceMailDeletions->Append(voiceMailDeletion); - } - } // CEnhancedVoiceMailDeleteConfirmations::DecodeL +// 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: +// This file implements the different PDU elements +// +// + +/** + @file +*/ + +#include +#include +#include "Gsmumain.h" +#include +#include "gsmupriv.h" +#include +#include +#include +#include +#include +#include +#include + +/** + * Question Mark character. + */ +const TInt KReplacementCharacter = 0x003f; + + +/** + * Constructs the object with a descriptor. The extraction mark and next character members are initialised to point to the start of the string. + * + * @param aSource Descriptor to be assigned by reference + */ +TGsmuLex8::TGsmuLex8(const TDesC8& aSource): TLex8(aSource) + { + //NOP + } // TGsmuLex8::TGsmuLex8 + + +/** + * Gets the next character in the string and increments the next character position. + * + * @return The next character in the string + * @leave Leaves with KErrGsmuDecoding if at end of string + */ +TUint8 TGsmuLex8::GetL() + { + if (Eos()) + LeaveL(); + + return static_cast(Get()); + } // TGsmuLex8::GetL + + +/** + * Increments the next character position by aNumber + * + * @param aNumber The number of characters to increment the next character position by. + * @leave If the increment puts the next character position before the start or beyond the end of the string, the function leaves with KErrGsmuDecoding. + */ +void TGsmuLex8::IncL(TInt aNumber) + { + if (aNumber != 0) + { + if (aNumber < 0 || Eos() || Remainder().Length() < aNumber) + LeaveL(); + else + Inc(aNumber); + } + } // TGsmuLex8::IncL + + +/** + * Checks there are enough remaining characters, then returns a TPtrC containing the next aLength characters. Does not increment the current position. + * + * @param aLength Number of characters to return + * @return Remainder().Left(aLength) + * @leave Leaves with KErrGsmuDecoding if there are insufficient characters remaining + */ +TPtrC8 TGsmuLex8::NextWithNoIncL(TInt aLength) const + { + return NextWithNoIncL(aLength, EFalse); + } + +/** + * Checks there are enough remaining characters, then returns a TPtrC containing the next aLength characters. Does not increment the current position. + * + * @param aLength Number of characters to return + * @param aAcceptTruncation ETrue if a mismatch between length indicator and actual length is acceptable. EFalse otherwise. + * @return Remainder().Left(aLength) if aAcceptTruncation is EFalse. Remainder() otherwise. + * @leave Leaves with KErrGsmuDecoding if there are insufficient characters remaining, unless aAcceptTruncation is ETrue. + */ +TPtrC8 TGsmuLex8::NextWithNoIncL(TInt aLength, TBool aAcceptTruncation) const + { + const TPtrC8 remainder(Remainder()); + + if ( (aLength < 0) || (remainder.Length()< aLength && !aAcceptTruncation) ) + { + LeaveL(); + } + + if (!aAcceptTruncation) + { + return Remainder().Left(aLength); + } + // aAcceptTruncation is ETrue + else if (remainder.Length() < aLength) + { + return Remainder(); + } + // otherwise, no need for truncation: + + return Remainder().Left(aLength); + } + + +/** + * Calls TGsmuLeax8::NextWithNoIncL then increments the next character position by aLength + * + * @param aLength Number of characters to return and increment the next character position + * @return Remainder().Left(aLength) + * @leave If the increment puts the next character position before the start or beyond the end of the string, the function leaves with KErrGsmuDecoding. + */ +TPtrC8 TGsmuLex8::NextAndIncL(TInt aLength) + { + const TPtrC8 next(NextWithNoIncL(aLength)); + IncL(aLength); + return next; + } // TGsmuLeax8::NextWithNoIncL + + +const TSmsOctet& TSmsOctet::operator = (TInt aValue) + { + iValue = static_cast(aValue); + return *this; + } // TSmsOctet::operator + + +TUint8* TSmsOctet::EncodeL(TUint8* aPtr) const + { + *aPtr=iValue; + return aPtr+1; + } // TSmsOctet::EncodeL + + +TSmsFirstOctet::TSmsFirstOctet(TInt aValue): + TSmsOctet(aValue) + { + } // TSmsFirstOctet::TSmsFirstOctet + + +const TSmsFirstOctet& TSmsFirstOctet::operator = (TInt aValue) + { + TSmsOctet::operator = (aValue); + return *this; + } // TSmsFirstOctet::operator + + +TSmsFailureCause::TSmsFailureCause(): + TSmsOctet(ESmsErrorUnspecified) + { + } // TSmsFailureCause::TSmsFailureCause + + +TSmsStatus::TSmsStatus(): + TSmsOctet(ESmsShortMessageReceivedBySME) + { + } // TSmsStatus::TSmsStatus + + +CSmsCommandData* CSmsCommandData::NewL(TSmsFirstOctet& aFirstOctet) + { + LOGGSMU1("CSmsCommandData::NewL()"); + + CSmsCommandData* commanddata=new(ELeave) CSmsCommandData(aFirstOctet); + CleanupStack::PushL(commanddata); + TPtrC8 ptr; + commanddata->SetDataL(ptr); + CleanupStack::Pop(); + return commanddata; + } // CSmsCommandData::NewL + + +CSmsCommandData::~CSmsCommandData() + { + iInformationElementArray.ResetAndDestroy(); + delete iBuffer; + } // CSmsCommandData::NewL + + +/** + * Duplicates this CSmsCommandData object. + * + * @return Pointer to the newly created CSmsCommandData object. + */ +CSmsCommandData* CSmsCommandData::DuplicateL() const + { + LOGGSMU1("CSmsCommandData::DuplicateL()"); + + CSmsCommandData* smsCommandData = CSmsCommandData::NewL(iFirstOctet); + CleanupStack::PushL(smsCommandData); + + smsCommandData->SetDataL(Data()); + + for (TInt ie = 0; ie < iInformationElementArray.Count(); ie++) + { + smsCommandData->AddInformationElementL(iInformationElementArray[ie]->Identifier(), + iInformationElementArray[ie]->Data()); + } + + CleanupStack::Pop(smsCommandData); + + return smsCommandData; + } // CSmsCommandData::DuplicateL + + +CSmsInformationElement& CSmsCommandData::InformationElement(TInt aIndex) const + { + LOGGSMU1("CSmsCommandData::InformationElement()"); + + CSmsInformationElement* ie=iInformationElementArray[aIndex]; + return *ie; + } // CSmsCommandData::InformationElement + + +CSmsInformationElement*& CSmsCommandData::InformationElementPtr(TInt aIndex) + { + // Ignore in code coverage - not used in SMS stack and not exported + // but cannot be removed as impacts public header. + BULLSEYE_OFF + LOGGSMU1("CSmsCommandData::InformationElementPtr()"); + return iInformationElementArray[aIndex]; + BULLSEYE_RESTORE + } + +TBool CSmsCommandData::InformationElementIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier, + TInt& aIndex) const + { + LOGGSMU1("CSmsCommandData::InformationElementIndex()"); + + TBool found=EFalse; + TInt count=NumInformationElements(); + for (TInt i=0; (!found) && (i=1) + SetHeaderPresent(ETrue); + } // CSmsCommandData::AddInformationElementL + + +void CSmsCommandData::RemoveInformationElement(TInt aIndex) + { + LOGGSMU1("CSmsCommandData::RemoveInformationElement()"); + // Since iInformationElementArray[aIndex] is removed from iInformationElementArray, no double free issue. + // coverity[double_free] + delete iInformationElementArray[aIndex]; + iInformationElementArray[aIndex] = NULL; + iInformationElementArray.Delete(aIndex); + + if (NumInformationElements()==0) + { + SetHeaderPresent(EFalse); + } + } // CSmsCommandData::RemoveInformationElement + + +TPtrC8 CSmsCommandData::Data() const + { + LOGGSMU1("CSmsCommandData::Data()"); + + TPtrC8 ptr; + ptr.Set(iBuffer->Des()); + return ptr; + } // CSmsCommandData::Data + + +void CSmsCommandData::SetDataL(const TDesC8& aData) + { + LOGGSMU1("CSmsCommandData::SetDataL()"); + + TInt length=aData.Length(); + __ASSERT_DEBUG(length<=KSmsMaxDataSize,Panic(KGsmuPanicCommandDataLengthTooLong)); + HBufC8* buffer=HBufC8::NewL(length); + delete iBuffer; + iBuffer=buffer; + iBuffer->Des().SetLength(length); + iBuffer->Des().Copy(aData); + } // CSmsCommandData::SetDataL + + +TUint8* CSmsCommandData::EncodeL(TUint8* aPtr) const + { + LOGGSMU1("CSmsCommandData::EncodeL()"); + + __ASSERT_DEBUG(iBuffer->Length()<=MaxDataLength(),Panic(KGsmuPanicCommandDataBufferTooLong)); + TSmsOctet datalength=iBuffer->Length()+TSmsOctet(TotalHeaderLengthInUDLUnits()); + aPtr=datalength.EncodeL(aPtr); + TPtr8 ptr((TUint8*) aPtr,datalength); + + if (HeaderPresent()) + { + TSmsOctet headerLength(HeaderLength()); + aPtr=headerLength.EncodeL(aPtr); + for (TInt i=0; iEncodeL(aPtr); + } + } + + ptr.Copy(iBuffer->Des()); + aPtr+=TInt(iBuffer->Length()); + return aPtr; + } // CSmsCommandData::EncodeL + + +void CSmsCommandData::DecodeL(TGsmuLex8& aPdu) + { + LOGGSMU1("CSmsCommandData::DecodeL()"); + + iInformationElementArray.ResetAndDestroy(); + const TBool headerPresent=HeaderPresent(); + TSmsOctet dataLength; + dataLength.DecodeL(aPdu); + + if (headerPresent) + { + TSmsOctet headerLength; + headerLength.DecodeL(aPdu); + if ((1+headerLength)>KSmsMaxDataSize) + User::Leave(KErrGsmSMSTpduNotSupported); + while (HeaderLength()DecodeL(aPdu); + iInformationElementArray.AppendL(informationElement); + CleanupStack::Pop(informationElement); + } + if (HeaderLength()!=headerLength) + User::Leave(KErrGsmSMSTpduNotSupported); + } + const TInt totalHeaderLength=TotalHeaderLengthInUDLUnits(); + const TInt totalDataLength=dataLength-totalHeaderLength; + const TPtrC8 next(aPdu.NextAndIncL(totalDataLength)); + SetDataL(next); + } // CSmsCommandData::DecodeL + + +void CSmsCommandData::InternalizeL(RReadStream& aStream) + { + iInformationElementArray.ResetAndDestroy(); + TInt numInformationElements=aStream.ReadInt32L(); + for (TInt i=0; i> *informationElement; + iInformationElementArray.AppendL(informationElement); + CleanupStack::Pop(); + } + HBufC8* buffer=HBufC8::NewL(aStream,KSmsMaxDataSize); + delete iBuffer; + iBuffer=buffer; + } // CSmsCommandData::InternalizeL + + +void CSmsCommandData::ExternalizeL(RWriteStream& aStream) const + { + TInt numInformationElements=iInformationElementArray.Count(); + aStream.WriteInt32L(numInformationElements); + for (TInt i=0; iLength(); + return headerLength; + } // CSmsCommandData::HeaderLength + + +TInt CSmsCommandData::TotalHeaderLengthInUDLUnits() const + { + LOGGSMU1("CSmsCommandData::TotalHeaderLengthInUDLUnits()"); + + if (iInformationElementArray.Count()==0) + return 0; + else + return (HeaderLength()+1); // +1 stands for UDHL + } // CSmsCommandData::TotalHeaderLengthInUDLUnits + + +TBool CSmsCommandData::HeaderPresent() const + { + LOGGSMU1("CSmsCommandData::HeaderPresent()"); + + return (iFirstOctet&TSmsFirstOctet::ESmsUDHIMask)==TSmsFirstOctet::ESmsUDHIHeaderPresent; + } // CSmsCommandData::HeaderPresent + + +void CSmsCommandData::SetHeaderPresent(TBool aHeaderPresent) + { + LOGGSMU1("CSmsCommandData::SetHeaderPresent()"); + + iFirstOctet=aHeaderPresent? (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderPresent: (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderNotPresent; + } // CSmsCommandData::SetHeaderPresent + + +TSmsParameterIndicator::TSmsParameterIndicator(): + TSmsOctet(ESmsPIDProtocolIdentifierPresent|ESmsPIDUserDataPresent|ESmsPIDDataCodingSchemePresent) + { + } // TSmsParameterIndicator::TSmsParameterIndicator + + +TSmsCommandType::TSmsCommandType(): + TSmsOctet(ESmsCommandTypeEnquiry) + { + } // TSmsCommandType::TSmsCommandType + + +TSmsProtocolIdentifier::TSmsProtocolIdentifier(): + TSmsOctet((TInt)ESmsPIDTelematicInterworking|(TInt)ESmsNoTelematicDevice) + { + } // TSmsProtocolIdentifier::TSmsProtocolIdentifier + + +TSmsProtocolIdentifier::TSmsTelematicDeviceIndicator TSmsProtocolIdentifier::TelematicDeviceIndicator() const + { + __ASSERT_DEBUG(PIDType()==ESmsPIDTelematicInterworking,Panic(KGsmuPanicNoTelematicInterworking)); + return (TSmsTelematicDeviceIndicator) (iValue&EPIDTelematicDeviceIndicatorMask); + } // TSmsProtocolIdentifier::TSmsTelematicDeviceIndicator + + +void TSmsProtocolIdentifier::SetTelematicDeviceIndicator(TSmsTelematicDeviceIndicator aIndicator) + { + LOGGSMU1("TSmsProtocolIdentifier::SetTelematicDeviceIndicator()"); + + __ASSERT_DEBUG(PIDType()==ESmsPIDTelematicInterworking,Panic(KGsmuPanicNoTelematicInterworking)); + + //iValue=(TUint8) ((iValue&ESmsPIDTypeMask)|aIndicator); + iValue=(TUint8) ((iValue&(~EPIDTelematicDeviceIndicatorMask))|aIndicator); + } // TSmsProtocolIdentifier::SetTelematicDeviceIndicator + + +TSmsProtocolIdentifier::TSmsTelematicDeviceType TSmsProtocolIdentifier::TelematicDeviceType() const + { + __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsTelematicDevice,Panic(KGsmuPanicNoTelematicDevice)); + return (TSmsTelematicDeviceType) (iValue&ESmsTelematicDeviceTypeMask); + } // TSmsProtocolIdentifier::TSmsTelematicDeviceType + + +void TSmsProtocolIdentifier::SetTelematicDeviceType(TSmsTelematicDeviceType aDeviceType) + { + LOGGSMU1("TSmsProtocolIdentifier::SetTelematicDeviceType()"); + + __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsTelematicDevice,Panic(KGsmuPanicNoTelematicDevice)); + iValue=(TUint8) ((iValue&(~ESmsTelematicDeviceTypeMask))|aDeviceType); + } // TSmsProtocolIdentifier::SetTelematicDeviceType + + +TInt TSmsProtocolIdentifier::ShortMessageALProtocol() const + { + // Ignore in code coverage - not used in SMS stack and not exported + // but cannot be removed as impacts public header. + BULLSEYE_OFF + LOGGSMU1("TSmsProtocolIdentifier::ShortMessageALProtocol()"); + + __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsNoTelematicDevice,Panic(KGsmuPanicNoTelematicDevice)); + return (TSmsShortMessageALProtocol) (iValue&ESmsShortMessageALProtocolMask); + BULLSEYE_RESTORE + } + +void TSmsProtocolIdentifier::SetShortMessageALProtocol(TSmsShortMessageALProtocol aProtocol) + { + // Ignore in code coverage - not used in SMS stack and not exported + // but cannot be removed as impacts public header. + BULLSEYE_OFF + LOGGSMU1("TSmsProtocolIdentifier::SetShortMessageALProtocol()"); + + __ASSERT_DEBUG(TelematicDeviceIndicator()==ESmsNoTelematicDevice,Panic(KGsmuPanicNoTelematicDevice)); + iValue=(TUint8) ((iValue&(~ESmsShortMessageALProtocolMask))|aProtocol); + BULLSEYE_RESTORE + } + +TInt TSmsProtocolIdentifier::ShortMessageType() const + { + LOGGSMU1("TSmsProtocolIdentifier::ShortMessageType()"); + + __ASSERT_DEBUG(PIDType()==ESmsPIDShortMessageType,Panic(KGsmuPanicNoShortMessageType)); + return (TSmsShortMessageType) (iValue&ESmsShortMessageTypeMask); + } // TSmsProtocolIdentifier::ShortMessageType + + +void TSmsProtocolIdentifier::SetShortMessageType(TSmsShortMessageType aShortMessageType) + { + LOGGSMU1("TSmsProtocolIdentifier::SetShortMessageType()"); + + __ASSERT_DEBUG(PIDType()==ESmsPIDShortMessageType,Panic(KGsmuPanicNoShortMessageType)); + //iValue=(TUint8) ((iValue&(~ESmsPIDTypeMask))|aShortMessageType); + iValue=(TUint8) ((iValue&(~ESmsShortMessageTypeMask))|aShortMessageType); + } // TSmsProtocolIdentifier::SetShortMessageType + + +TSmsDataCodingScheme::TSmsDataCodingScheme(): + TSmsOctet((TInt)ESmsDCSTextUncompressedWithNoClassInfo|(TInt)ESmsAlphabet7Bit|(TInt)ESmsClass0) + // Constructor is expected to set the octet = 0, This is needed by + // CSmsDeliverReport::DecodeL, CSmsSubmitReport::DecodeL and CSmsStatusReport::DecodeL, per + // 23.040 v6.5.0 section 9.2.3.27. + { + } // CSmsDeliverReport::DecodeL + + +TBool TSmsDataCodingScheme::TextCompressed() const + { + LOGGSMU1("TSmsDataCodingScheme::TextCompressed()"); + + TInt bits7to4=Bits7To4(); + return (bits7to4==ESmsDCSTextCompressedWithNoClassInfo) || (bits7to4==ESmsDCSTextCompressedWithClassInfo) || + (bits7to4==ESmsDCSAutoDelNoClassInfoCompressedText) || (bits7to4==ESmsDCSAutoDelClassInfoTextCompressedText); + } // TSmsDataCodingScheme::TextCompressed + + +void TSmsDataCodingScheme::SetTextCompressed(TBool aCompressed) + { + LOGGSMU1("TSmsDataCodingScheme::SetTextCompressed()"); + + TInt bits7to4=Bits7To4(); + if (aCompressed) + { + switch (bits7to4) + { + case (ESmsDCSTextUncompressedWithNoClassInfo): + { + iValue=(TUint8) (ESmsDCSTextCompressedWithNoClassInfo|(iValue&(~ESmsDCSBits7To4Mask))); + break; + } + case (ESmsDCSAutoDelNoClassInfoUncompressedText): + { + iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoCompressedText|(iValue&(~ESmsDCSBits7To4Mask))); + break; + } + case (ESmsDCSAutoDelClassInfoUncompressedText): + { + iValue=(TUint8) (ESmsDCSAutoDelClassInfoTextCompressedText|(iValue&(~ESmsDCSBits7To4Mask))); + break; + } + case (ESmsDCSTextUncompressedWithClassInfo): + case (ESmsDCSTextUncompressed7BitOr8Bit): + { + iValue=(TUint8) (ESmsDCSTextCompressedWithClassInfo|(iValue&(~ESmsDCSBits7To4Mask))); + break; + } + case (ESmsDCSTextCompressedWithNoClassInfo): + case (ESmsDCSTextCompressedWithClassInfo): + case (ESmsDCSAutoDelNoClassInfoCompressedText): + case (ESmsDCSAutoDelClassInfoTextCompressedText): + break; + default: + break; + // has to be tested, what happens in this default case + //Panic(KGsmuPanicNotSupportedWithDCSBits7To4); + } + } + else + { + switch (bits7to4) + { + case (ESmsDCSTextCompressedWithNoClassInfo): + { + iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&(~ESmsDCSBits7To4Mask))); + break; + } + case (ESmsDCSTextCompressedWithClassInfo): + { + iValue=(TUint8) (ESmsDCSTextUncompressedWithClassInfo|(iValue&(~ESmsDCSBits7To4Mask))); + break; + } + case (ESmsDCSAutoDelNoClassInfoCompressedText): + { + iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoUncompressedText|(iValue&(~ESmsDCSBits7To4Mask))); + break; + } + case (ESmsDCSAutoDelClassInfoTextCompressedText): + { + iValue=(TUint8) ( ESmsDCSAutoDelClassInfoUncompressedText|(iValue&(~ESmsDCSBits7To4Mask))); + break; + } + case (ESmsDCSTextUncompressedWithNoClassInfo): + case (ESmsDCSTextUncompressedWithClassInfo): + case (ESmsDCSAutoDelClassInfoUncompressedText): + case (ESmsDCSAutoDelNoClassInfoUncompressedText): + case (ESmsDCSTextUncompressed7BitOr8Bit): + default: + { + } + } + } + } // TSmsDataCodingScheme::SetTextCompressed + + +TSmsDataCodingScheme::TSmsAlphabet TSmsDataCodingScheme::Alphabet() const + { + LOGGSMU1("TSmsDataCodingScheme::TSmsAlphabet()"); + + TInt bits7to4=Bits7To4(); + TInt alphabet=ESmsAlphabet7Bit; + switch (bits7to4) + { + case (ESmsDCSTextUncompressedWithNoClassInfo): + case (ESmsDCSTextUncompressedWithClassInfo): + case (ESmsDCSTextCompressedWithNoClassInfo): // Alphabet not used in these cases + case (ESmsDCSTextCompressedWithClassInfo): + case (ESmsDCSAutoDelNoClassInfoUncompressedText): + case (ESmsDCSAutoDelClassInfoUncompressedText): + case (ESmsDCSAutoDelNoClassInfoCompressedText): + case (ESmsDCSAutoDelClassInfoTextCompressedText): + { + alphabet=iValue&ESmsAlphabetMask; + break; + } + case (ESmsDCSTextUncompressed7BitOr8Bit): + { + alphabet=iValue&ESmsAlphabet8Bit; // N.B. only one bit used to code alphabet + break; + } + case (ESmsDCSMessageWaitingIndicationDiscardMessage): + case (ESmsDCSMessageWaitingIndication7Bit): + { + alphabet=ESmsAlphabet7Bit; + break; + } + case (ESmsDCSMessageWaitingIndicationUCS2): + { + alphabet=ESmsAlphabetUCS2; + break; + } + default: + LOGGSMU1("TSmsDataCodingScheme::Alphabet() WARNING! default case has been reached"); + break; + } + return (TSmsAlphabet) alphabet; + } // TSmsDataCodingScheme::TSmsAlphabet + +void TSmsDataCodingScheme::SetAlphabet(TSmsAlphabet aAlphabet) + { + LOGGSMU1("TSmsDataCodingScheme::SetAlphabet()"); + + TInt bits7to4=Bits7To4(); + switch (bits7to4) + { + case (ESmsDCSTextUncompressedWithNoClassInfo): + case (ESmsDCSTextUncompressedWithClassInfo): + case (ESmsDCSTextCompressedWithNoClassInfo): // Alphabet not used in these cases + case (ESmsDCSTextCompressedWithClassInfo): + case (ESmsDCSAutoDelNoClassInfoUncompressedText): + case (ESmsDCSAutoDelClassInfoUncompressedText): + case (ESmsDCSAutoDelNoClassInfoCompressedText): + case (ESmsDCSAutoDelClassInfoTextCompressedText): + { + iValue=(TUint8) ((iValue&(~ESmsAlphabetMask))|aAlphabet); + break; + } + case (ESmsDCSTextUncompressed7BitOr8Bit): + { + if ((aAlphabet==ESmsAlphabet7Bit) || (aAlphabet==ESmsAlphabet8Bit)) + { + iValue=(TUint8) ((iValue&(~ESmsAlphabet8Bit))|aAlphabet); // N.B. only one bit used to code alphabet + } + break; + } + case (ESmsDCSMessageWaitingIndicationDiscardMessage): + { + if (aAlphabet!=ESmsAlphabet7Bit) + { + LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet); + } + break; + } + case (ESmsDCSMessageWaitingIndication7Bit): + { + if (aAlphabet==ESmsAlphabetUCS2) + { + iValue=(TUint8) (ESmsDCSMessageWaitingIndicationUCS2|(iValue&(~ESmsDCSBits7To4Mask))); + } + else + { + LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet); + } + break; + } + case (ESmsDCSMessageWaitingIndicationUCS2): + { + if (aAlphabet==ESmsAlphabet7Bit) + { + iValue=(TUint8) (ESmsDCSMessageWaitingIndication7Bit|(iValue&(~ESmsDCSBits7To4Mask))); + } + else + { + LOGGSMU3("TSmsDataCodingScheme::SetAlphabet() WARNING! Not Supported With Discard Message [Bits7To4=%d], [aAlphabet=%d]", bits7to4, aAlphabet); + } + break; + } + default: + LOGGSMU1("TSmsDataCodingScheme::SetAlphabet() WARNING! default case has been reached"); + break; + } + } // TSmsDataCodingScheme::SetAlphabet + + +TBool TSmsDataCodingScheme::Class(TSmsClass& aClass) const + { + LOGGSMU1("TSmsDataCodingScheme::Class()"); + + switch (Bits7To4()) + { + case (ESmsDCSTextUncompressedWithClassInfo): + case (ESmsDCSTextCompressedWithClassInfo): + case (ESmsDCSAutoDelClassInfoUncompressedText): + case (ESmsDCSAutoDelClassInfoTextCompressedText): + case (ESmsDCSTextUncompressed7BitOr8Bit): + aClass=(TSmsClass) (iValue&ESmsClassMask); + return ETrue; + default: + return EFalse; + } + } // TSmsDataCodingScheme::Class + + +void TSmsDataCodingScheme::SetClass(TBool aClassDefined,TSmsDataCodingScheme::TSmsClass aClass) + { + LOGGSMU1("TSmsDataCodingScheme::SetClass()"); + + TInt bits7to4=Bits7To4(); + if (aClassDefined) + { + switch (bits7to4) + { + case (ESmsDCSTextUncompressedWithNoClassInfo): + { + iValue=(TUint8) (ESmsDCSTextUncompressedWithClassInfo|(iValue&ESmsAlphabetMask|aClass)); + break; + } + case (ESmsDCSTextCompressedWithNoClassInfo): + { + iValue=(TUint8) (ESmsDCSTextCompressedWithClassInfo|(iValue&ESmsAlphabetMask|aClass)); + break; + } + case (ESmsDCSAutoDelNoClassInfoUncompressedText): + { + iValue=(TUint8) (ESmsDCSAutoDelClassInfoUncompressedText|(iValue&ESmsAlphabetMask|aClass)); + break; + } + case (ESmsDCSAutoDelNoClassInfoCompressedText): + { + iValue=(TUint8) (ESmsDCSAutoDelClassInfoTextCompressedText|(iValue&ESmsAlphabetMask|aClass)); + break; + } + case (ESmsDCSTextUncompressedWithClassInfo): + case (ESmsDCSTextCompressedWithClassInfo): + case (ESmsDCSAutoDelClassInfoUncompressedText): + case (ESmsDCSAutoDelClassInfoTextCompressedText): + case (ESmsDCSTextUncompressed7BitOr8Bit): + + { + iValue=(TUint8) (iValue&(~ESmsClassMask)|aClass); + break; + } + default: + LOGGSMU1("WARNING! default case has been reached"); + break; + } + } + else + { + switch (bits7to4) + { + case (ESmsDCSTextUncompressedWithClassInfo): + { + iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass); + break; + } + case (ESmsDCSTextCompressedWithClassInfo): + { + iValue=(TUint8) (ESmsDCSTextCompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass); + break; + } + case (ESmsDCSAutoDelClassInfoUncompressedText): + { + iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoUncompressedText|(iValue&ESmsAlphabetMask)|aClass); + break; + } + case (ESmsDCSAutoDelClassInfoTextCompressedText): + { + iValue=(TUint8) (ESmsDCSAutoDelNoClassInfoCompressedText|(iValue&ESmsAlphabetMask)|aClass); + break; + } + case (ESmsDCSTextUncompressed7BitOr8Bit): + { + iValue=(TUint8) (ESmsDCSTextUncompressedWithNoClassInfo|(iValue&ESmsAlphabetMask)|aClass); + break; + } + case (ESmsDCSTextUncompressedWithNoClassInfo): + case (ESmsDCSTextCompressedWithNoClassInfo): + case (ESmsDCSAutoDelNoClassInfoUncompressedText): + case (ESmsDCSAutoDelNoClassInfoCompressedText): + case (ESmsDCSMessageWaitingIndicationDiscardMessage): + case (ESmsDCSMessageWaitingIndication7Bit): + case (ESmsDCSMessageWaitingIndicationUCS2): + default: + { + } + } + } + } // TSmsDataCodingScheme::SetClass + + +TSmsDataCodingScheme::TSmsIndicationState TSmsDataCodingScheme::IndicationState() const + { + LOGGSMU1("TSmsDataCodingScheme::IndicationState()"); + + TInt bits7to4=Bits7To4(); + TSmsIndicationState state=ESmsIndicationInactive; + switch (bits7to4) + { + case (ESmsDCSMessageWaitingIndicationDiscardMessage): + case (ESmsDCSMessageWaitingIndication7Bit): + case (ESmsDCSMessageWaitingIndicationUCS2): + { + state=(TSmsIndicationState) (iValue&ESmsIndicationStateMask); + break; + } + default: + LOGGSMU1("WARNING! default case has been reached"); + break; + } + return state; + } // TSmsDataCodingScheme::TSmsIndicationState + + +void TSmsDataCodingScheme::SetIndicationState(TSmsIndicationState aState) + { + LOGGSMU1("TSmsDataCodingScheme::SetIndicationState()"); + + TInt bits7to4=Bits7To4(); + switch (bits7to4) + { + case (ESmsDCSMessageWaitingIndicationDiscardMessage): + case (ESmsDCSMessageWaitingIndication7Bit): + case (ESmsDCSMessageWaitingIndicationUCS2): + { + iValue=(TUint8) (aState | (iValue&(~ESmsIndicationStateMask))); + break; + } + default: + LOGGSMU1("TSmsDataCodingScheme::SetIndicationState() WARNING! default case has been reached"); + break; + } + } // TSmsDataCodingScheme::SetIndicationState + + +TSmsDataCodingScheme::TSmsIndicationType TSmsDataCodingScheme::IndicationType() const + { + LOGGSMU1("TSmsDataCodingScheme::IndicationType()"); + + TInt bits7to4=Bits7To4(); + TSmsIndicationType type=ESmsVoicemailMessageWaiting; + switch (bits7to4) + { + case (ESmsDCSMessageWaitingIndicationDiscardMessage): + case (ESmsDCSMessageWaitingIndication7Bit): + case (ESmsDCSMessageWaitingIndicationUCS2): + { + type=(TSmsIndicationType) (iValue&ESmsIndicationTypeMask); + break; + } + default: + LOGGSMU1("TSmsDataCodingScheme::IndicationType() WARNING default case has been reached"); + break; + } + return type; + } // TSmsDataCodingScheme::TSmsIndicationType + + +void TSmsDataCodingScheme::SetIndicationType(TSmsIndicationType aType) + { + LOGGSMU1("TSmsDataCodingScheme::SetIndicationType()"); + + TInt bits7to4=Bits7To4(); + switch (bits7to4) + { + case (ESmsDCSMessageWaitingIndicationDiscardMessage): + case (ESmsDCSMessageWaitingIndication7Bit): + case (ESmsDCSMessageWaitingIndicationUCS2): + { + iValue=(TUint8) (aType | (iValue&(~ESmsIndicationTypeMask))); + break; + } + default: + LOGGSMU1("TSmsDataCodingScheme::SetIndicationType() WARNING! default case has been reached"); + break; + } + } // TSmsDataCodingScheme::SetIndicationType + + +/** + * Allocates and creates a CSmsAlphabetConverter object, specifying an Alphabet + * Coding scheme and a Binary flag. + * + * @param aCharacterSetConverter Pre-initialised character set converter + * @param aFs File system handle + * @param aSmsAlphabet Data coding scheme alphabet + * @param aIsBinary Set to true for WAP or compressed data + * @return New CSmsAlphabetConverter object + * @capability None + */ +EXPORT_C CSmsAlphabetConverter* CSmsAlphabetConverter::NewLC(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsDataCodingScheme::TSmsAlphabet aSmsAlphabet,TBool aIsBinary) + { + LOGGSMU1("CSmsAlphabetConverter::NewLC()"); + + CSmsAlphabetConverter* converter=new (ELeave)CSmsAlphabetConverter(aCharacterSetConverter,aFs,aSmsAlphabet,aIsBinary); + CleanupStack::PushL(converter); + converter->ConstructL(); + return converter; + } // CSmsAlphabetConverter::NewLC + + +/** + * Destructor. + * @capability None + */ +EXPORT_C CSmsAlphabetConverter::~CSmsAlphabetConverter() + { + delete iConvertedNativeCharacters; + delete iConvertedUDElements; + delete iUnconvertedNativeCharacters; + delete iUnconvertedUDElements; + } // CSmsAlphabetConverter::NewLC + + +// +// C'tor - standard stuff +// +CSmsAlphabetConverter::CSmsAlphabetConverter(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsDataCodingScheme::TSmsAlphabet aSmsAlphabet,TBool aIsBinary) + : iCharacterSetConverter(aCharacterSetConverter), + iFs(aFs), + iSmsAlphabet(aSmsAlphabet), + iIsBinary(aIsBinary), + iUnconvertedNativeCharactersPtr(NULL,0), + iUnconvertedUDElementsPtr(NULL,0) + { + } // CSmsAlphabetConverter::CSmsAlphabetConverter + + +// +// Ensures this is a supported character set if not binary conversion +// +void CSmsAlphabetConverter::ConstructL() + { + LOGGSMU1("CSmsAlphabetConverter::ConstructL()"); + + + if (!iIsBinary) + { + switch (iSmsAlphabet) + { + case TSmsDataCodingScheme::ESmsAlphabet7Bit: + case TSmsDataCodingScheme::ESmsAlphabet8Bit: + case TSmsDataCodingScheme::ESmsAlphabetUCS2: + { + // Supported + break; + } + default: + { + // Not supported + User::Leave(KErrGsmSMSDataCodingSchemeNotSupported); + break; + } + } + } + } // CSmsAlphabetConverter::ConstructL + + +// +// Returns whether the character set converter is invoked. Provided to allow +// clients to provided efficient converted length calculation where no +// conversion is required. +// +void CSmsAlphabetConverter::ConversionPropertiesL(TSmsAlphabetConversionProperties& aConversionProperties) const + { + LOGGSMU1("CSmsAlphabetConverter::ConversionPropertiesL()"); + + + // Set defaults + aConversionProperties.iWidthConversion=ESmsAlphabetWidthConversionFixed; + aConversionProperties.iUDElementsPerNativeCharacter=1; + // Modify if different + if (iIsBinary) + return; + switch (iSmsAlphabet) + { + case TSmsDataCodingScheme::ESmsAlphabet7Bit: + case TSmsDataCodingScheme::ESmsAlphabet8Bit: + { + aConversionProperties.iWidthConversion=ESmsAlphabetWidthConversionVariable; + break; + } + case TSmsDataCodingScheme::ESmsAlphabetUCS2: + { + aConversionProperties.iUDElementsPerNativeCharacter=sizeof(TText); + break; + } + default: + { + User::Leave(KErrGsmSMSDataCodingSchemeNotSupported); + } + } + } // CSmsAlphabetConverter::ConversionPropertiesL + + +/** + * Converts from the native character set to unpacked user data elements of the + * desired character set. + * + * The function stores the converted data internally. + * + * @param aNativeCharacters The native character set data (Unicode only) + * @return Converted characters + * @capability None + */ +EXPORT_C TPtrC8 CSmsAlphabetConverter::ConvertFromNativeL(const TDesC& aNativeCharacters) + { + LOGGSMU1("CSmsAlphabetConverter::ConvertFromNativeL()"); + + TInt numberOfUnconvertibleCharacters, numberOfDowngradedCharacters; + + return ConvertFromNativeL(aNativeCharacters, ESmsEncodingNone, + numberOfUnconvertibleCharacters, + numberOfDowngradedCharacters); + } // CSmsAlphabetConverter::ConvertFromNativeL + + +/** + * Converts from the native character set to unpacked user data elements of the + * desired character set. + * + * The function stores the converted data internally. + * + * @param aNativeCharacters The native character set data (Unicode only) + * @param aNumberOfUnconvertibleCharacters Number of characters unconverted + * @param aNumberOfDowngradedCharacters Number of characters downgraded + * @param aEncoding Alternative 7bit encoding to used (if needed) + * + * @return Converted characters + * + * @capability None + */ +EXPORT_C TPtrC8 CSmsAlphabetConverter::ConvertFromNativeL(const TDesC& aNativeCharacters, + TSmsEncoding aEncoding, + TInt& aNumberOfUnconvertibleCharacters, + TInt& aNumberOfDowngradedCharacters) + { + LOGGSMU2("CSmsAlphabetConverter::ConvertFromNativeL(): aEncoding=%d", aEncoding); + + aNumberOfUnconvertibleCharacters = 0; + aNumberOfDowngradedCharacters = 0; + + // Check for some shortcuts + if (iIsBinary || iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit) + { + // Binary data stored as padded unicode + TPtr8 outputPtr=CheckAllocBufferL(&iConvertedUDElements,aNativeCharacters.Length(),0); + outputPtr.Copy(aNativeCharacters); + iUnconvertedNativeCharactersPtr.Zero(); + return outputPtr; + } + else if (iSmsAlphabet==TSmsDataCodingScheme::ESmsAlphabetUCS2) + { + TInt nativeCharactersLength = aNativeCharacters.Length(); + // 16-bit copy with possible endianess correction + TInt elementCount=nativeCharactersLength*2; + TPtr8 outputPtr(CheckAllocBufferL(&iConvertedUDElements,elementCount,elementCount)); + for (TInt i=0;i>8); + outputPtr[2*i+1]=(TUint8)aNativeCharacters[i]; + } + iUnconvertedNativeCharactersPtr.Zero(); + return outputPtr; + } + else // No shortcuts, do proper conversion + { + PrepareForConversionFromNativeL(aEncoding); + + // Create input buffer + TInt newInputLength=iUnconvertedNativeCharactersPtr.Length()+aNativeCharacters.Length(); + iUnconvertedNativeCharactersPtr.Set(CheckAllocBufferL(&iUnconvertedNativeCharacters,newInputLength,iUnconvertedNativeCharactersPtr.Length())); + iUnconvertedNativeCharactersPtr.Append(aNativeCharacters); + + // Ensure buffer is at least the length of the input buffer + TPtr8 outputPtr=CheckAllocBufferL(&iConvertedUDElements,iUnconvertedNativeCharactersPtr.Length(),0); + + TInt retryCount=0; + TInt unconvertedCount=iUnconvertedNativeCharactersPtr.Length(); + while (unconvertedCount) + { + TInt tempNumberOfUnconvertibleCharacters = 0; + TInt tempNumberOfDowngradedCharacters = 0; + + // Get a pointer to unfilled area of output buffer + TPtr8 fillPtr((TUint8*)outputPtr.Ptr()+outputPtr.Length(),0,outputPtr.MaxLength()-outputPtr.Length()); + // Try the conversion & get number of unconverted characters + TInt newUnconvertedCount=iCharacterSetConverter.ConvertFromUnicode(fillPtr,iUnconvertedNativeCharactersPtr); + if (newUnconvertedCount<0) + break; + + // Compare what is converted with the original, to get downgrade count + TPtr tempBufPtr((TUint16*)iUnconvertedNativeCharactersPtr.Ptr(), 0, fillPtr.Length()); + TInt offset = aNativeCharacters.Length() - unconvertedCount; + TInt state = CCnvCharacterSetConverter::KStateDefault; + TInt notRestored = iCharacterSetConverter.ConvertToUnicode(tempBufPtr, fillPtr, state); + + if (notRestored > 0) + { + tempNumberOfUnconvertibleCharacters += notRestored; + } + + for (TInt pos = 0; pos < tempBufPtr.Length(); pos++) + { + if (tempBufPtr[pos] != aNativeCharacters[offset + pos]) + { + if (tempBufPtr[pos] != KReplacementCharacter) + { + tempNumberOfDowngradedCharacters++; + } + else + { + tempNumberOfUnconvertibleCharacters++; + } + } + } + + // + // If characters were downgraded or unconverted then replace them + // with downgrades from the PREQ2090 converter. + // + if (tempNumberOfUnconvertibleCharacters > 0 && + aEncoding != ESmsEncodingNone) + { + HBufC8* downgradesBuf = HBufC8::NewLC(iUnconvertedNativeCharactersPtr.Length()); + HBufC* nativeBuf = HBufC::NewLC(iUnconvertedNativeCharactersPtr.Length()); + TPtr8 downgradesPtr = downgradesBuf->Des(); + TPtr nativePtr = nativeBuf->Des(); + + PrepareForConversionFromNativeL(ESmsEncodingNone); + + // Attempt to convert the text + TInt ret = iCharacterSetConverter.ConvertFromUnicode(downgradesPtr, iUnconvertedNativeCharactersPtr); + if (ret >= 0) + { + // Compare what is converted with the original... + state = CCnvCharacterSetConverter::KStateDefault; + notRestored = iCharacterSetConverter.ConvertToUnicode(nativePtr, downgradesPtr, state); + + if (notRestored >= 0) + { + // Merge in the downgrades + TInt pos; + + for (pos = 0; pos < tempBufPtr.Length(); pos++) + { + if (tempBufPtr[pos] != aNativeCharacters[offset + pos]) + { + if (tempBufPtr[pos] != KReplacementCharacter) + { + tempBufPtr[pos] = nativePtr[pos]; + } + } + } + + // Reconvert... + PrepareForConversionFromNativeL(aEncoding); + + newUnconvertedCount=iCharacterSetConverter.ConvertFromUnicode(fillPtr,iUnconvertedNativeCharactersPtr); + if (newUnconvertedCount<0) + break; + + // Recount the changed characters... + tempNumberOfUnconvertibleCharacters = 0; + tempNumberOfDowngradedCharacters = 0; + + for (pos = 0; pos < tempBufPtr.Length(); pos++) + { + if (tempBufPtr[pos] != aNativeCharacters[offset + pos]) + { + if (tempBufPtr[pos] != KReplacementCharacter) + { + tempNumberOfDowngradedCharacters++; + } + else + { + tempNumberOfUnconvertibleCharacters++; + } + } + } + } + } + + CleanupStack::PopAndDestroy(2, downgradesBuf); + } + + // + // Store these downgraded/unconvertible character counts... + // + aNumberOfDowngradedCharacters += tempNumberOfDowngradedCharacters; + aNumberOfUnconvertibleCharacters += tempNumberOfUnconvertibleCharacters; + + // Update original buffer length, check retry count and realloc if req'd + outputPtr.SetLength(outputPtr.Length()+fillPtr.Length()); + if (newUnconvertedCount==unconvertedCount) + { + if (++retryCount>KMaxSmsAlphabetConversionRetries) + { + __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicConversionRetriedOut)); + break; + } + } + else + { + iUnconvertedNativeCharactersPtr.Delete(0,unconvertedCount-newUnconvertedCount); + retryCount=0; + } + unconvertedCount=newUnconvertedCount; + // Check for realloc + if (unconvertedCount) + outputPtr.Set(CheckAllocBufferL(&iConvertedUDElements,iConvertedUDElements->Length()+Max(unconvertedCount,KMinSmsAlphabetConversionAllocIncrement),outputPtr.Length())); + } + + return outputPtr; + } + } // CSmsAlphabetConverter::ConvertFromNativeL + + +/** + * Converts the user data elements of the specified character set to the native + * character set. + * + * @param aUDElements The converted character set data + * + * @return Native character set data (Unicode only) + * + * @capability None + */ +EXPORT_C TPtrC CSmsAlphabetConverter::ConvertToNativeL(const TDesC8& aUDElements) + { + LOGGSMU1("CSmsAlphabetConverter::ConvertToNativeL()"); + + return ConvertToNativeL(aUDElements, ESmsEncodingNone); + } // CSmsAlphabetConverter::ConvertToNativeL + + +/** + * Converts the user data elements of the specified character set to the native + * character set. + * + * @param aUDElements The converted character set data + * @param aEncoding Alternative 7bit encoding to used (if needed) + * + * @return Native character set data (Unicode only) + * + * @capability None + */ +EXPORT_C TPtrC CSmsAlphabetConverter::ConvertToNativeL(const TDesC8& aUDElements, + TSmsEncoding aEncoding) + { + LOGGSMU2("CSmsAlphabetConverter::ConvertToNativeL(): aEncoding=%d", aEncoding); + + // Check for some shortcuts + if (iIsBinary || iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet8Bit) + { + // Binary data stored as padded unicode + TPtr16 outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,aUDElements.Length(),0); + outputPtr.Copy(aUDElements); + iUnconvertedUDElementsPtr.Zero(); + return outputPtr; + } + else if (iSmsAlphabet==TSmsDataCodingScheme::ESmsAlphabetUCS2) + { + // 16-bit copy with possible endianess correction + TInt charCount=aUDElements.Length()/2; + TPtr16 outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,charCount,charCount); + for (TInt i=0; iKMaxSmsAlphabetConversionRetries) + { + __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicConversionRetriedOut)); + break; + } + } + else + { + iUnconvertedUDElementsPtr.Delete(0,unconvertedCount-newUnconvertedCount); + retryCount=0; + } + unconvertedCount=newUnconvertedCount; + // Check for realloc + if (unconvertedCount) + outputPtr.Set(CheckAllocBufferL(&iConvertedNativeCharacters,iConvertedNativeCharacters->Length()+Max(unconvertedCount,KMinSmsAlphabetConversionAllocIncrement),outputPtr.Length())); + } + return outputPtr; + } + } // CSmsAlphabetConverter::ConvertToNativeL + + +/** + * Tests if the character is supported by the current character set. + * This function can be used with 7bit and 8bit alphabets. + * + * @param aChar Character to investigate. + * + * @return ETrue if the character is supported. + * + * @note Since the function is based on the old behaviour (pre-PREQ2090) + * it does not accept a downgraded character or alternative encoding + * as being supported. + */ +TBool CSmsAlphabetConverter::IsSupportedL(TChar aChar) + { + LOGGSMU2("[1] CSmsAlphabetConverter::IsSupportedL(aChar=0x%04x)", (TUint) aChar); + + TBool isDowngrade, isRequiresAlternativeEncoding; + + TBool supported = IsSupportedL(aChar, ESmsEncodingNone, + isDowngrade, isRequiresAlternativeEncoding); + + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported); + + return supported; + } // CSmsAlphabetConverter::IsSupportedL + + +/** + * Tests if the descriptor text is supported by the current character set. + * This function can be used with 7bit and 8bit alphabets. + * + * @param aDes Text string to check. + * @param aNumberOfUnconvertibleCharacters Exit param for the number of + * characters unconvertible. + * @param aIndexOfFirstUnconvertibleCharacter Exit param for the first + * unconverted character. + * + * @return ETrue if the character is supported. + */ +TBool CSmsAlphabetConverter::IsSupportedL(const TDesC& aDes, TInt& aNumberOfUnconvertibleCharacters, + TInt& aIndexOfFirstUnconvertibleCharacter) + { + LOGGSMU2("[2] CSmsAlphabetConverter::IsSupportedL(aDes=\"%S\")", &aDes); + + TInt desLength = aDes.Length(); + // + // Initialise the exit params... + // + aNumberOfUnconvertibleCharacters = 0; + aIndexOfFirstUnconvertibleCharacter = desLength; + + // + // Create buffers for the input converted to 7Bit and a buffer for it once + // converted back again... + // + HBufC8* encodedBuf = HBufC8::NewLC(desLength*2); // worse case + HBufC* backToUnicodeAfterStdBuf = HBufC::NewLC(desLength); + TPtr8 encoded(encodedBuf->Des()); + TPtr backToUnicodeAfterStd(backToUnicodeAfterStdBuf->Des()); + + // + // Convert the input string to standard 7bit (with downgrades if needed)... + // + PrepareForConversionFromNativeL(ESmsEncodingNone); + + TInt notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes); + + if (notConverted > 0) + { + aNumberOfUnconvertibleCharacters += notConverted; + } + else if (notConverted < 0) + { + aNumberOfUnconvertibleCharacters = desLength; + } + + // + // Convert it back again to the native format... + // + TInt state = CCnvCharacterSetConverter::KStateDefault; + TInt notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterStd, encoded, state); + + if (notRestored > 0) + { + aNumberOfUnconvertibleCharacters += notRestored; + } + else if (notRestored < 0) + { + aNumberOfUnconvertibleCharacters = desLength; + } + + // + // Work out if the string is acceptable as it is (e.g. no unconvertible + // and no downgrades). We only need do this if the previous conversions were + // complete with no issues. + // + for (TInt pos = desLength-1; pos >= 0; --pos) + { + if (backToUnicodeAfterStd[pos] != aDes[pos]) + { + aNumberOfUnconvertibleCharacters++; + aIndexOfFirstUnconvertibleCharacter = pos; + } + } + + CleanupStack::PopAndDestroy(backToUnicodeAfterStdBuf); + CleanupStack::PopAndDestroy(encodedBuf); + + // + // Useful logging... + // + TBool supported = (aNumberOfUnconvertibleCharacters == 0); + + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfUnconvertibleCharacters=%d.", aNumberOfUnconvertibleCharacters); + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIndexOfFirstUnconvertibleCharacter=%d.", aIndexOfFirstUnconvertibleCharacter); + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported); + + return supported; + } // CSmsAlphabetConverter::IsSupportedL + + +/** + * Tests if the character is supported by the current character set. + * This function can be used with 7bit and 8bit alphabets. + * + * @param aChar Character to investigate. + * @param aEncoding Alternative 7bit encoding (if used). + * @param aIsDowngrade Exit param set to ETrue if the + * character has to be downgraded. + * @param aRequiresAlternativeEncoding Exit param set to ETrue if the + * alternative encoding has to be + * used to encode it. + * + * @return ETrue if the character is supported. + */ +TBool CSmsAlphabetConverter::IsSupportedL(TChar aChar, TSmsEncoding aEncoding, + TBool& aIsDowngrade, + TBool& aRequiresAlternativeEncoding) + { + LOGGSMU2("[3] CSmsAlphabetConverter::IsSupportedL(aChar=0x%04x)", (TUint) aChar); + + // + // Convert the character... + // + TInt numberOfUnconvertibleCharacters, numberOfDowngradedCharacters, + numberRequiringAlternativeEncoding, indexOfFirstUnconvertibleCharacter; + TBuf<4> toEncode; + + toEncode.SetLength(1); + toEncode[0]=(TText)aChar; + + TBool supported = IsSupportedL(toEncode, aEncoding, + numberOfUnconvertibleCharacters, + numberOfDowngradedCharacters, + numberRequiringAlternativeEncoding, + indexOfFirstUnconvertibleCharacter); + + // + // Calculate the exit params... + // + aIsDowngrade = (numberOfDowngradedCharacters > 0); + aRequiresAlternativeEncoding = (numberRequiringAlternativeEncoding > 0); + + // + // Useful logging... + // + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIsDowngrade=%d.", aIsDowngrade); + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aRequiresAlternativeEncoding=%d.", aRequiresAlternativeEncoding); + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported); + + return supported; + } // CSmsAlphabetConverter::IsSupportedL + + +/** + * Tests if the descriptor text is supported by the current character set. + * This function can be used with 7bit and 8bit alphabets. + * + * @param aDes Text string to check. + * @param aEncoding Alternative 7bit encoding (if used). + * @param aNumberOfUnconvertibleCharacters Exit param for the number of + * characters unconvertible. + * @param aNumberOfDowngradedCharacters Exit param for the number of + * downgraded characters. + * @param aNumberRequiringAlternativeEncoding Exit param for the number of + * characters requiring use of + * the alternative encoder. + * @param aIndexOfFirstUnconvertibleCharacter Exit param for the first + * unconverted character. + * + * @return ETrue if the character is supported. + */ +TBool CSmsAlphabetConverter::IsSupportedL(const TDesC& aDes, TSmsEncoding aEncoding, + TInt& aNumberOfUnconvertibleCharacters, + TInt& aNumberOfDowngradedCharacters, + TInt& aNumberRequiringAlternativeEncoding, + TInt& aIndexOfFirstUnconvertibleCharacter) + { + LOGGSMU2("[4] CSmsAlphabetConverter::IsSupportedL(aDes=\"%S\")", &aDes); + + TInt desLength = aDes.Length(); + // + // Initialise the exit params... + // + aNumberOfUnconvertibleCharacters = 0; + aNumberOfDowngradedCharacters = 0; + aNumberRequiringAlternativeEncoding = 0; + aIndexOfFirstUnconvertibleCharacter = desLength; + + // + // Create buffers for the input converted to 7Bit and a buffer for it once + // converted back again... + // + HBufC8* encodedBuf = HBufC8::NewLC(desLength*2); // worse case + HBufC* backToUnicodeAfterStdBuf = HBufC::NewLC(desLength); + TPtr8 encoded(encodedBuf->Des()); + TPtr backToUnicodeAfterStd(backToUnicodeAfterStdBuf->Des()); + + // + // Convert the input string to standard 7bit (with downgrades if needed)... + // + PrepareForConversionFromNativeL(ESmsEncodingNone); + + TInt notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes); + + if (notConverted > 0) + { + aNumberOfUnconvertibleCharacters += notConverted; + } + else if (notConverted < 0) + { + aNumberOfUnconvertibleCharacters = desLength; + } + + // + // Convert it back again to the native format... + // + TInt state = CCnvCharacterSetConverter::KStateDefault; + TInt notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterStd, encoded, state); + + if (notRestored > 0) + { + aNumberOfUnconvertibleCharacters += notRestored; + } + else if (notRestored < 0) + { + aNumberOfUnconvertibleCharacters = desLength; + } + + // + // Work out if the string is acceptable as it is (e.g. no unconvertible + // and no downgrades). + // + for (TInt pos = desLength-1; pos >= 0; --pos) + { + if (backToUnicodeAfterStd[pos] != aDes[pos]) + { + if (backToUnicodeAfterStd[pos] != KReplacementCharacter) + { + aNumberOfDowngradedCharacters++; + } + else + { + aNumberOfUnconvertibleCharacters++; + aIndexOfFirstUnconvertibleCharacter = pos; + } + } + } + + TInt totalCharFaultsSoFar = aNumberOfUnconvertibleCharacters + + aNumberOfDowngradedCharacters; + + // + // If the total unconvertible plus downgrades is zero, then there is nothing + // more to do as the string can be converted to 7bit with no issues and no + // other encoder is needed. + // + // Otherwise we have to look at the alternative encoder... + // + if (totalCharFaultsSoFar == 0) + { + // + // We are done (the return counts are already zero and therefore + // correct at this point too!). + // + } + else if (iSmsAlphabet != TSmsDataCodingScheme::ESmsAlphabet7Bit || + aEncoding == ESmsEncodingNone) + { + // + // The string was not perfectly converted, but there is no alternative + // encoder to try. We are done. + // + } + else + { + // + // Initialise the params... + // + TInt tmpDowngradedCharacters = 0; + TInt tmpUnconvertibleCharacters = 0; + TInt tmpIndexOfFirstUnconvertibleCharacter = desLength; + + // + // Convert the input string to the alternative encoding... + // + PrepareForConversionFromNativeL(aEncoding); + + notConverted = iCharacterSetConverter.ConvertFromUnicode(encoded, aDes); + if (notConverted > 0) + { + tmpUnconvertibleCharacters = notConverted; + } + else if (notConverted < 0) + { + tmpUnconvertibleCharacters = desLength; + } + + // + // Convert it back again to the native format... + // + HBufC* backToUnicodeAfterAltBuf = HBufC::NewLC(desLength); + TPtr backToUnicodeAfterAlt(backToUnicodeAfterAltBuf->Des()); + TInt state = CCnvCharacterSetConverter::KStateDefault; + TInt notRestored = iCharacterSetConverter.ConvertToUnicode(backToUnicodeAfterAlt, encoded, state); + + if (notRestored > 0) + { + tmpUnconvertibleCharacters += notRestored; + } + else if (notRestored < 0) + { + tmpUnconvertibleCharacters = desLength; + } + + // + // Now work out which characters are downgrades, require alternative encoding + // or are unsupported. + // + for (TInt pos = desLength-1; pos >= 0; --pos) + { + if (backToUnicodeAfterStd[pos] != aDes[pos]) + { + // Not supported by standard encoder... + if (backToUnicodeAfterAlt[pos] == aDes[pos]) + { + // Supported by alternative encoder... + aNumberRequiringAlternativeEncoding++; + } + else if (backToUnicodeAfterStd[pos] != KReplacementCharacter) + { + // Downgraded by standard encoder... + tmpDowngradedCharacters++; + } + else if (backToUnicodeAfterAlt[pos] != KReplacementCharacter) + { + // Downgraded by alternative encoder... + tmpDowngradedCharacters++; + aNumberRequiringAlternativeEncoding++; + } + else + { + // Unconvertible... + tmpUnconvertibleCharacters++; + tmpIndexOfFirstUnconvertibleCharacter = pos; + } + } + } + + // Is this better? + if ( totalCharFaultsSoFar >= (tmpUnconvertibleCharacters + tmpDowngradedCharacters) ) + { + // Best conversion is the alternative conversion + aNumberOfUnconvertibleCharacters = tmpUnconvertibleCharacters; + aNumberOfDowngradedCharacters = tmpDowngradedCharacters; + aIndexOfFirstUnconvertibleCharacter = tmpIndexOfFirstUnconvertibleCharacter; + } + else + { + // Best conversion is the standard conversion + aNumberRequiringAlternativeEncoding = 0; + } + + CleanupStack::PopAndDestroy(backToUnicodeAfterAltBuf); + } + + CleanupStack::PopAndDestroy(backToUnicodeAfterStdBuf); + CleanupStack::PopAndDestroy(encodedBuf); + + // + // Useful logging... + // + TBool supported = (aNumberOfUnconvertibleCharacters == 0); + + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfUnconvertibleCharacters=%d.", aNumberOfUnconvertibleCharacters); + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberOfDowngradedCharacters=%d.", aNumberOfDowngradedCharacters); + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aNumberRequiringAlternativeEncoding=%d.", aNumberRequiringAlternativeEncoding); + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): aIndexOfFirstUnconvertibleCharacter=%d.", aIndexOfFirstUnconvertibleCharacter); + LOGGSMU2("CSmsAlphabetConverter::IsSupportedL(): supported=%d.", supported); + + return supported; + } // CSmsAlphabetConverter::IsSupportedL + + +/** + * Given a piece of text and an alternative encoding, this function works out + * which encoding is best to use and returns the ID of that converter. + * + * @param aNativeCharacters Text to use as a sample. + * @param aEncoding Suggested alternative 7bit encoding method. + * + * @return Encoding that should be used. + */ +TSmsEncoding CSmsAlphabetConverter::FindBestAlternativeEncodingL(const TDesC& aNativeCharacters, + TSmsEncoding aSuggestedEncoding) + { + LOGGSMU2("CSmsAlphabetConverter::FindBestAlternativeEncodingL(): aSuggestedEncoding=%d", + aSuggestedEncoding); + + TSmsEncoding encodingToUse = ESmsEncodingNone; + + // + // If this is not 7bit or the alternative encoding is not set then do + // nothing... + // + if (aSuggestedEncoding != ESmsEncodingNone && + iSmsAlphabet == TSmsDataCodingScheme::ESmsAlphabet7Bit) + { + TInt numberOfUnconvertibleCharacters, numberOfDowngradedCharacters; + TInt numberRequiringAlternativeEncoding, indexOfFirstUnconvertibleCharacter; + + // + // First try the default encoding (but in this case treat downgrades + // as unconverted, since later encoders might do better)... + // + IsSupportedL(aNativeCharacters, ESmsEncodingNone, + numberOfUnconvertibleCharacters, + numberOfDowngradedCharacters, + numberRequiringAlternativeEncoding, + indexOfFirstUnconvertibleCharacter); + + TInt leastUnconvertibleCharacters = numberOfUnconvertibleCharacters + numberOfDowngradedCharacters; + + // + // Create a list of alternative encodings to try... + // + TSmsEncoding encodingList[8]; + TInt encodingCount = 0; + + if (aSuggestedEncoding == ESmsEncodingTurkishLockingAndSingleShift) + { + encodingList[encodingCount++] = ESmsEncodingTurkishSingleShift; + encodingList[encodingCount++] = ESmsEncodingTurkishLockingShift; + } + else if (aSuggestedEncoding == ESmsEncodingPortugueseLockingAndSingleShift) + { + encodingList[encodingCount++] = ESmsEncodingPortugueseSingleShift; + encodingList[encodingCount++] = ESmsEncodingPortugueseLockingShift; + } + + encodingList[encodingCount++] = aSuggestedEncoding; + encodingList[encodingCount++] = ESmsEncodingNone; + + // + // Now try the all the alternatives... + // + for (TInt encoder = 0; encoder < encodingCount; encoder++) + { + IsSupportedL(aNativeCharacters, encodingList[encoder], + numberOfUnconvertibleCharacters, + numberOfDowngradedCharacters, + numberRequiringAlternativeEncoding, + indexOfFirstUnconvertibleCharacter); + if (numberOfUnconvertibleCharacters + numberOfDowngradedCharacters < leastUnconvertibleCharacters) + { + encodingToUse = encodingList[encoder]; + leastUnconvertibleCharacters = numberOfUnconvertibleCharacters + numberOfDowngradedCharacters; + } + } + } + + LOGGSMU2("CSmsAlphabetConverter::FindBestAlternativeEncodingL(): encodingToUse=%d", encodingToUse); + + return encodingToUse; + } // CSmsAlphabetConverter::FindBestAlternativeEncoding + + +/** + * Confirms that the requested encoding method is present (e.g. the converter + * plug-in can be loaded). + * + * @param aEncoding Alternative 7bit encoding method. + * + * @leave KErrNotSupported if the encoder is not available. + */ +void CSmsAlphabetConverter::ConfirmAlternativeEncoderL(TSmsEncoding aEncoding) const + { + // + // Check the ID for the encoder exists... + // + if (aEncoding != ESmsEncodingNone) + { + TUint encoderID; + + GetAlternativeEncoderIDL(aEncoding, encoderID); + + // + // Confirm it can be loaded... + // + if (iCharacterSetConverter.PrepareToConvertToOrFromL(encoderID, iFs) != CCnvCharacterSetConverter::EAvailable) + { + User::Leave(KErrNotSupported); + } + } + } // CSmsAlphabetConverter::ConfirmAlternativeEncoderL + + +/** + * Prepares the converted for conversion from native charset. + * Character set specific preparation is performed here. + * + * @param aEncoding Alternative 7bit encoding to use if required. + */ +void CSmsAlphabetConverter::PrepareForConversionFromNativeL(TSmsEncoding aEncoding) + { + LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): aEncoding=%d", + aEncoding); + + __ASSERT_DEBUG(iIsBinary==EFalse,Panic(KGsmuPanicUnsupportedAlphabet)); + switch (iSmsAlphabet) + { + case TSmsDataCodingScheme::ESmsAlphabet7Bit: + { + // + // If an alternative encoding has been specified then try and + // load that converter... + // + if (aEncoding != ESmsEncodingNone) + { + TUint alternativeEncoderID; + + GetAlternativeEncoderIDL(aEncoding, alternativeEncoderID); + if (alternativeEncoderID != 0) + { + CCnvCharacterSetConverter::TAvailability availability; + + LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): Converter 0x%08x", + alternativeEncoderID); + + availability = iCharacterSetConverter.PrepareToConvertToOrFromL(alternativeEncoderID, iFs); + if (availability == CCnvCharacterSetConverter::EAvailable) + { + // Force unicode line termination characters to simple line feed + iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters( + CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed); + + // Job done, return + return; + } + + // Plug-in could not be loaded, so drop through and load the default! + } + } + + // + // Check for the PREQ2090 7bit converter with Eastern European + // downgrade support first, otherwise if the plug-in is not found + // use the standard internal converter. + // + CCnvCharacterSetConverter::TAvailability availability; + + availability = iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierExtendedSms7Bit, iFs); + if (availability == CCnvCharacterSetConverter::ENotAvailable) + { + availability = iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierSms7Bit, iFs); + if (availability == CCnvCharacterSetConverter::ENotAvailable) + { + User::Leave(KErrNotFound); + } + } + + // Force unicode line termination characters to simple line feed + iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters( + CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed); + break; + } + case TSmsDataCodingScheme::ESmsAlphabet8Bit: + { + CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierCodePage1252,iFs); + if (availability==CCnvCharacterSetConverter::ENotAvailable) + { + User::Leave(KErrNotFound); + } + + // Force unicode line termination characters to simple line feed + iCharacterSetConverter.SetDowngradeForExoticLineTerminatingCharacters( + CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed); + break; + } + case TSmsDataCodingScheme::ESmsAlphabetUCS2: + default: + { + User::Leave(KErrNotSupported); + } + } + } // CSmsAlphabetConverter::PrepareForConversionFromNativeL + + +/** + * Prepares the converted for conversion to unicode. Character set + * specific preparation is performed here. + * + * @param aEncoding Alternative 7bit encoding to use if required. + */ +void CSmsAlphabetConverter::PrepareForConversionToNativeL(TSmsEncoding aEncoding) + { + LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionToNativeL(): aEncoding=%d", + aEncoding); + + switch (iSmsAlphabet) + { + case TSmsDataCodingScheme::ESmsAlphabet7Bit: + { + // + // If an alternative encoding has been specified then try and + // load that converter... + // + if (aEncoding != ESmsEncodingNone) + { + TUint alternativeEncoderID; + + GetAlternativeEncoderIDL(aEncoding, alternativeEncoderID); + if (alternativeEncoderID != 0) + { + CCnvCharacterSetConverter::TAvailability availability; + + LOGGSMU2("CSmsAlphabetConverter::PrepareForConversionFromNativeL(): Converter 0x%08x", + alternativeEncoderID); + + availability = iCharacterSetConverter.PrepareToConvertToOrFromL(alternativeEncoderID, iFs); + if (availability == CCnvCharacterSetConverter::EAvailable) + { + // Job done, return + return; + } + + // Plug-in could not be loaded, so drop through and load the default! + } + } + + // + // Always use the internal converter, as it is quicker to prepare + // and the PREQ2090 7bit converter with Eastern European downgrade + // offers no benefit when converting to native. + // + CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierSms7Bit,iFs); + if (availability==CCnvCharacterSetConverter::ENotAvailable) + { + User::Leave(KErrNotFound); + } + break; + } + case TSmsDataCodingScheme::ESmsAlphabet8Bit: + { + CCnvCharacterSetConverter::TAvailability availability=iCharacterSetConverter.PrepareToConvertToOrFromL(KCharacterSetIdentifierCodePage1252,iFs); + if (availability==CCnvCharacterSetConverter::ENotAvailable) + { + User::Leave(KErrNotFound); + } + break; + } + case TSmsDataCodingScheme::ESmsAlphabetUCS2: + default: + { + User::Leave(KErrNotSupported); + } + } + } // CSmsAlphabetConverter::PrepareForConversionToNativeL + + +/** + * This function returns the alternative encoding converters that are used + * incase the default GSM encoding cannot encode the message completely + * without data loss. + * + * @param aEncoding Encoding to obtain the converter for. + * @param aEncoderID Returned converter UID if present. + * + * @leave KErrArgument if the encoding enum is invalid or + */ +void CSmsAlphabetConverter::GetAlternativeEncoderIDL(TSmsEncoding aEncoding, TUint& aEncoderID) const + { + LOGGSMU2("CSmsAlphabetConverter::GetAlternativeEncoderIDL(%d)", aEncoding); + + aEncoderID = 0; + + // + // Decide on appropriate encoders. + // + switch (aEncoding) + { + case ESmsEncodingNone: + { + // Nothing to set. + } + break; + + case ESmsEncodingTurkishSingleShift: + { + aEncoderID = KCharacterSetIdentifierTurkishSingleSms7Bit; + } + break; + + case ESmsEncodingTurkishLockingShift: + { + aEncoderID = KCharacterSetIdentifierTurkishLockingSms7Bit; + } + break; + + case ESmsEncodingTurkishLockingAndSingleShift: + { + aEncoderID = KCharacterSetIdentifierTurkishLockingAndSingleSms7Bit; + } + break; + + case ESmsEncodingSpanishSingleShift: + { + aEncoderID = KCharacterSetIdentifierSpanishSingleSms7Bit; + } + break; + + case ESmsEncodingPortugueseSingleShift: + { + aEncoderID = KCharacterSetIdentifierPortugueseSingleSms7Bit; + } + break; + + case ESmsEncodingPortugueseLockingShift: + { + aEncoderID = KCharacterSetIdentifierPortugueseLockingSms7Bit; + } + break; + + case ESmsEncodingPortugueseLockingAndSingleShift: + { + aEncoderID = KCharacterSetIdentifierPortugueseLockingAndSingleSms7Bit; + } + break; + + default: + { + // + // Invalid encoder method! + // + User::Leave(KErrArgument); + } + }; + } // CSmsAlphabetConverter::GetAlternativeEncoderIDL + + +// +// Ensures the allocated 16 bit buffer is at least of the specified length +// +TPtr16 CSmsAlphabetConverter::CheckAllocBufferL(HBufC16** aBuffer,TInt aMaxLength,TInt aUsedLength) + { + LOGGSMU1("CSmsAlphabetConverter::CheckAllocBufferL()"); + + if (*aBuffer!=NULL) + { + if ((*aBuffer)->Length()ReAllocL(aMaxLength); + (*aBuffer)->Des().SetLength(aMaxLength); + } + } + else + { + *aBuffer=HBufC16::NewMaxL(aMaxLength); + } + return TPtr16((TUint16*)(*aBuffer)->Des().Ptr(),aUsedLength,(*aBuffer)->Length()); + } // CSmsAlphabetConverter::CheckAllocBufferL + + +// +// Ensures the allocated 8 bit buffer is at least of the specified length +// +TPtr8 CSmsAlphabetConverter::CheckAllocBufferL(HBufC8** aBuffer,TInt aMaxLength,TInt aUsedLength) + { + LOGGSMU1("CSmsAlphabetConverter::CheckAllocBufferL()"); + + if (*aBuffer!=NULL) + { + if ((*aBuffer)->Length()ReAllocL(aMaxLength); + (*aBuffer)->Des().SetLength(aMaxLength); + } + } + else + { + *aBuffer=HBufC8::NewMaxL(aMaxLength); + } + return TPtr8((TUint8*)(*aBuffer)->Des().Ptr(),aUsedLength,(*aBuffer)->Length()); + } // CSmsAlphabetConverter::CheckAllocBufferL + + +/** + * @internalComponent + * + * Determines whether the address format matches the specified type. + * + * @param aType Specifies an indicator type, as defined in the Common PCN Handset Specification + * @return returns ETrue if address is of specified type, EFalse otherwise + */ +EXPORT_C TBool TGsmSmsTelNumber::IsInstanceOf(TTypeOfIndicator aType) + { + LOGGSMU1("TGsmSmsTelNumber::IsInstanceOf()"); + + TBool rc = EFalse; + + (void) aType; + + if((aType == EVoiceMessageWaitingIndicator) + && ((iTypeOfAddress & TGsmSmsTypeOfAddress::EGsmSmsTONMask)==EGsmSmsTONAlphaNumeric) + && (iTelNumber.Length()==ECPHSSizeOfAddressField) + && ((iTelNumber[ECPHSAddressIndicatorType] & ECPSHIndicatorTypeBitMask) == ECPSHVoiceMailId) + && ((iTelNumber[ECPHSAddressIndicatorId] & ECPSHIndicatorIdBitMask) == ECPSHIndicatorId )) + rc = ETrue; + + return rc; + } // TGsmSmsTelNumber::IsInstanceOf + + +// +// CSmsAddress +// + +CSmsAddress* CSmsAddress::NewL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs) + { + LOGGSMU1("CSmsAddress::NewL()"); + + CSmsAddress* address=new(ELeave) CSmsAddress(aCharacterSetConverter,aFs); + CleanupStack::PushL(address); + TPtrC ptr; + address->SetAddressL(ptr); + CleanupStack::Pop(); + return address; + } // CSmsAddress::NewL + + +CSmsAddress::~CSmsAddress() + { + delete iBuffer; + } // CSmsAddress::NewL + + +/** + * Duplicates this CSmsAddress object. + * + * @return Pointer to the newly created CSmsAddress object. + */ +CSmsAddress* CSmsAddress::DuplicateL() const + { + LOGGSMU1("CSmsAddress::DuplicateL()"); + + CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter, iFs); + CleanupStack::PushL(address); + + address->SetRawAddressL(iTypeOfAddress, *iBuffer); + + CleanupStack::Pop(); + + return address; + } // CSmsAddress::DuplicateL + + +TPtrC CSmsAddress::Address() const + { + LOGGSMU1("CSmsAddress::Address()"); + + TPtrC ptr; + if (iBuffer) + ptr.Set(iBuffer->Des()); + return ptr; + } // CSmsAddress::Address + + +void CSmsAddress::SetRawAddressL(TGsmSmsTypeOfAddress aTypeOfAddress, TPtrC aBufferPtr) + { + LOGGSMU1("CSmsAddress::SetRawAddressL()"); + + iTypeOfAddress = aTypeOfAddress; + + NewBufferL(aBufferPtr.Length()); + + *iBuffer=aBufferPtr; + } // CSmsAddress::SetRawAddressL + + +TGsmSmsTypeOfAddress& CSmsAddress::TypeOfAddress() + { + LOGGSMU1("CSmsAddress::TypeOfAddress()"); + + return iTypeOfAddress; + } // CSmsAddress::TypeOfAddress + + +void CSmsAddress::SetAddressL(const TDesC& aAddress) + { + LOGGSMU1("CSmsAddress::SetAddressL()"); + + TInt length=aAddress.Length(); + NewBufferL(length); + iBuffer->Des().Copy(aAddress); + + const TGsmSmsTypeOfNumber typeofnumber=length && (iBuffer->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown; + iTypeOfAddress.SetTON(typeofnumber); + } // CSmsAddress::SetAddressL + + +void CSmsAddress::ParsedAddress(TGsmSmsTelNumber& aParsedAddress) const + { + aParsedAddress.iTypeOfAddress = iTypeOfAddress; + + TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength(); + + if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric) + { + TInt parsedlength=Address().Length(); + if (parsedlength>maxparsedlength) + parsedlength=maxparsedlength; + aParsedAddress.iTelNumber.Copy(Address().Mid(0,parsedlength)); + } + else + { + aParsedAddress.iTelNumber.SetLength(maxparsedlength); + + TInt length=iBuffer->Des().Length(); + TInt parsedlength=0; + for (TInt i=0; (iDes()[i]; + switch(ch) + { + case '*': + case '#': + case 'a': + case 'b': + case 'c': + aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch; + parsedlength++; + break; + default: + if ((ch>='0') && (ch<='9')) + { + aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch; + parsedlength++; + } + break; + } + } + + aParsedAddress.iTelNumber.SetLength(parsedlength); + } + } + + +void CSmsAddress::SetParsedAddressL(const TGsmSmsTelNumber& aParsedAddress) + { + LOGGSMU1("CSmsAddress::SetParsedAddressL()"); + + iTypeOfAddress=aParsedAddress.iTypeOfAddress; + DoSetParsedAddressL(aParsedAddress.iTelNumber); + } // CSmsAddress::SetParsedAddressL + + +TUint8 CSmsAddress::SizeL() + { + LOGGSMU1("CSmsAddress::SizeL()"); + + TUint8 size = 0; + + TBuf8 testBuffer; + testBuffer.SetLength(KSmsAddressMaxAddressLength); + TUint8* startPtr = &testBuffer[0]; + TUint8* endPtr = NULL; + + TRAPD(err,endPtr = EncodeL(startPtr)); + + if (err != KErrNone) + { + User::Leave(KErrArgument); + } + else + { + // handle architectures whose address space increments or whose address space decrements. + (endPtr > startPtr) ? (size = endPtr - startPtr) : (size = startPtr - endPtr); + } + + return size; + } // CSmsAddress::SizeL + + +TUint8* CSmsAddress::EncodeL(TUint8* aPtr) const + { + TGsmSmsTelNumber parsedaddress; + ParsedAddress(parsedaddress); + + switch (iTypeOfAddress.TON()) + { + case EGsmSmsTONAlphaNumeric: + { + // Mark buffer for length encoding after conversion + TUint8* lengthPtr=aPtr++; + // Encode type + aPtr=iTypeOfAddress.EncodeL(aPtr); + // 7-bit conversion + TPtrC address=Address(); + TInt convertedNumUDUnits=0; + TPtr8 packedPtr(aPtr,0,KSmsAddressMaxAddressValueLength); + TSmsAlphabetPacker packer(TSmsDataCodingScheme::ESmsAlphabet7Bit,EFalse,0); + aPtr+=packer.ConvertAndPackL(iCharacterSetConverter,iFs,packedPtr,address,convertedNumUDUnits); + // Now encode length + TSmsOctet length=(convertedNumUDUnits*7+3)/4; + length.EncodeL(lengthPtr); + break; + } + case EGsmSmsTONInternationalNumber: + default: + { + TSmsOctet length=parsedaddress.iTelNumber.Length(); + if (length > KSmsAddressMaxAddressValueLength * 2) + // each address value occupies one nibble. + { + User::Leave(KErrArgument); + } + aPtr=length.EncodeL(aPtr); + aPtr=iTypeOfAddress.EncodeL(aPtr); + TSmsOctet octet; + for (TInt i=0; iDes().Ptr(),0,iBuffer->Length()); + + if (remainder.Length() < KSmsAddressMaxAddressValueLength) + User::Leave(KErrGsmuDecoding); + + TPtrC8 packedPtr(remainder.Ptr(), KSmsAddressMaxAddressValueLength); + TSmsAlphabetPacker unpacker(TSmsDataCodingScheme::ESmsAlphabet7Bit,EFalse,0); + unpacker.UnpackAndConvertL(iCharacterSetConverter,iFs,packedPtr,unpackedPtr,numUDUnits); + aPdu.IncL(length / 2); + if ((length % 2) != 0) + aPdu.IncL(); + } + break; + } + case EGsmSmsTONInternationalNumber: + default: + { + TGsmSmsTelNumber parsedaddress; + if (length>parsedaddress.iTelNumber.MaxLength()) + User::Leave(KErrGsmuDecoding); + parsedaddress.iTelNumber.SetLength(length); + TSmsOctet octet; + for (TInt i=0; i>4; + + switch(tempOctet) + { + case 10: // 1010 + { + parsedaddress.iTelNumber[i] = '*'; + } + break; + + case 11: // 1011 + { + parsedaddress.iTelNumber[i] = '#'; + } + break; + + case 12: // 1100 + { + parsedaddress.iTelNumber[i] = 'a'; + } + break; + + case 13: // 1101 + { + parsedaddress.iTelNumber[i] = 'b'; + } + break; + + case 14: // 1110 + { + parsedaddress.iTelNumber[i] = 'c'; + } + break; + + case 15: + // Skip if 1111 is received + break; + + default: + parsedaddress.iTelNumber[i]=(TUint8) (tempOctet+'0'); + // unwanted bits zeroed in the beginning + + break; + } + } + } + DoSetParsedAddressL(parsedaddress.iTelNumber); + } + } + } + +void CSmsAddress::InternalizeL(RReadStream& aStream) + { + aStream >> iTypeOfAddress; + HBufC* buffer=HBufC::NewL(aStream,256); + delete iBuffer; + iBuffer=buffer; + } // CSmsAddress::InternalizeL + + +void CSmsAddress::ExternalizeL(RWriteStream& aStream) const + { + aStream << iTypeOfAddress; + aStream << *iBuffer; + } // CSmsAddress::ExternalizeL + + +CSmsAddress::CSmsAddress(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs): + iCharacterSetConverter(aCharacterSetConverter), + iFs(aFs), + iTypeOfAddress(EGsmSmsTONUnknown, EGsmSmsNPIISDNTelephoneNumberingPlan) + { + } // CSmsAddress::CSmsAddress + + +void CSmsAddress::NewBufferL(TInt aLength) + { + LOGGSMU1("CSmsAddress::NewBufferL()"); + + HBufC* buffer=HBufC::NewL(aLength); + delete iBuffer; + iBuffer=buffer; + iBuffer->Des().SetLength(aLength); + iBuffer->Des().FillZ(); + } + + +void CSmsAddress::DoSetParsedAddressL(const TDesC& aAddress) + { + LOGGSMU2("CSmsAddress::DoSetParsedAddressL() the length of the Address [Length = %d", aAddress.Length()); + + TInt length=aAddress.Length(); + if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) && + (length && (aAddress[0]!='+'))) + { + NewBufferL(length+1); + iBuffer->Des()[0]='+'; + TPtr ptr((TText*) (iBuffer->Des().Ptr()+1),length,length); + ptr.Copy(aAddress); + } + else + { + NewBufferL(length); + iBuffer->Des().Copy(aAddress); + } + } // CSmsAddress::DoSetParsedAddressL + + +TSmsServiceCenterTimeStamp::TSmsServiceCenterTimeStamp() + { + iTimeZoneNumQuarterHours = 0; + } // TSmsServiceCenterTimeStamp::TSmsServiceCenterTimeStamp + + +void TSmsServiceCenterTimeStamp::SetTimeOffset(TInt aNumQuarterHours) + { + __ASSERT_DEBUG((aNumQuarterHours>=-KSmsMaxTimeZoneNumQuarterHours) && (aNumQuarterHours<=KSmsMaxTimeZoneNumQuarterHours),Panic(KGsmuPanicNumQuarterHoursOutOfRange)); + iTimeZoneNumQuarterHours=aNumQuarterHours; + } // TSmsServiceCenterTimeStamp::SetTimeOffset + + +TUint8* TSmsServiceCenterTimeStamp::EncodeL(TUint8* aPtr) const + { + LOGGSMU1("TSmsServiceCenterTimeStamp::EncodeL()"); + + TInt numquarterhours=iTimeZoneNumQuarterHours; + + TInt timeZoneOffsetInSeconds = numquarterhours * CSmsMessage::E15MinutesRepresentedInSeconds; + TTimeIntervalSeconds offsetFromUTCToLocal(timeZoneOffsetInSeconds); + + TTime time = iTime; + time += offsetFromUTCToLocal; + + TDateTime datetime=time.DateTime(); + + TSmsOctet octet; + octet.FillSemiOctets(datetime.Year()%100); + aPtr=octet.EncodeL(aPtr); + octet.FillSemiOctets(datetime.Month()+1); + aPtr=octet.EncodeL(aPtr); + octet.FillSemiOctets(datetime.Day()+1); + aPtr=octet.EncodeL(aPtr); + octet.FillSemiOctets(datetime.Hour()); + aPtr=octet.EncodeL(aPtr); + octet.FillSemiOctets(datetime.Minute()); + aPtr=octet.EncodeL(aPtr); + octet.FillSemiOctets(datetime.Second()); + aPtr=octet.EncodeL(aPtr); + + TInt signbit=ESmsTimeZonePositive; + if (numquarterhours<0) + { + numquarterhours=-numquarterhours; + signbit=ESmsTimeZoneNegative; + } + + TSmsOctet timezone; + timezone.FillSemiOctets(numquarterhours); + timezone=timezone|signbit; + return timezone.EncodeL(aPtr); + } // TSmsServiceCenterTimeStamp::EncodeL + + +void TSmsServiceCenterTimeStamp::DecodeL(TGsmuLex8& aPdu, TInt& aTimeError) + { + LOGGSMU1("TSmsServiceCenterTimeStamp::DecodeL()"); + + TSmsOctet octet; + octet.DecodeL(aPdu); + TInt year=octet.SemiOctetsToNum(); + if (year>95) + year+=1900; + else + year+=2000; + octet.DecodeL(aPdu); + TInt month=octet.SemiOctetsToNum(); + octet.DecodeL(aPdu); + + TInt day=octet.SemiOctetsToNum(); + octet.DecodeL(aPdu); + TInt hour=octet.SemiOctetsToNum(); + octet.DecodeL(aPdu); + TInt minute=octet.SemiOctetsToNum(); + octet.DecodeL(aPdu); + TInt second=octet.SemiOctetsToNum(); + + TDateTime datetime; + aTimeError = datetime.Set(year,(TMonth) (month-1),day-1,hour,minute,second,0); + + TSmsOctet timezone; + timezone.DecodeL(aPdu); + + TInt signBit = (timezone&ESmsTimeZoneSignBitMask) ? ESmsTimeZoneNegative : ESmsTimeZonePositive; + timezone=timezone &(~ESmsTimeZoneSignBitMask); // clear sign bit + + TInt offsetToUTCInSeconds = 0; + if (timezone.SemiOctetsToNum() <= KSmsMaxTimeZoneNumQuarterHours) + { + offsetToUTCInSeconds = ((TInt) timezone.SemiOctetsToNum()) * CSmsMessage::E15MinutesRepresentedInSeconds; + if (signBit == ESmsTimeZoneNegative) + { + offsetToUTCInSeconds = -offsetToUTCInSeconds; + } + + TTimeIntervalSeconds offsetToUTC(offsetToUTCInSeconds) ; + + if (aTimeError == KErrNone) + { + TTime time = datetime; + time -= offsetToUTC; + iTime = time; + + iTimeZoneNumQuarterHours=(signBit == ESmsTimeZonePositive) ? timezone.SemiOctetsToNum(): -timezone.SemiOctetsToNum(); + } + + } + else // Time zone out of range, set to 0 per 23.040 4.4.0 Section 9.2.3.11 + { + if (aTimeError == KErrNone) + { + iTime = datetime; + iTimeZoneNumQuarterHours=0; + } + } + } // TSmsServiceCenterTimeStamp::DecodeL + + +void TSmsServiceCenterTimeStamp::InternalizeL(RReadStream& aStream) + { + TInt64 time; + aStream >> time; + iTime=time; + iTimeZoneNumQuarterHours=aStream.ReadInt32L(); + } // TSmsServiceCenterTimeStamp::InternalizeL + + +void TSmsServiceCenterTimeStamp::ExternalizeL(RWriteStream& aStream) const + { + aStream << iTime.Int64(); + aStream.WriteInt32L(iTimeZoneNumQuarterHours); + } // TSmsServiceCenterTimeStamp::ExternalizeL + + +TSmsValidityPeriod::TSmsValidityPeriod(TSmsFirstOctet& aFirstOctet): + iFirstOctet(aFirstOctet), + iTimeIntervalMinutes(EOneDayUnitInMinutes) + { + } // TSmsValidityPeriod::TSmsValidityPeriod + + +TTime TSmsValidityPeriod::Time() const + { + LOGGSMU1("TSmsValidityPeriod::Time()"); + + TTime time; + time.UniversalTime(); + time+=iTimeIntervalMinutes; + return time; + } // TSmsValidityPeriod::Time + + +TUint8* TSmsValidityPeriod::EncodeL(TUint8* aPtr) const + { + LOGGSMU1("TSmsValidityPeriod::EncodeL()"); + + TInt validityperiodformat=ValidityPeriodFormat(); + switch (validityperiodformat) + { + case (TSmsFirstOctet::ESmsVPFNone): + break; + case (TSmsFirstOctet::ESmsVPFInteger): + { + TInt timeintervalminutes=iTimeIntervalMinutes.Int(); + __ASSERT_DEBUG((timeintervalminutes>=EFiveMinuteUnitInMinutes) && (timeintervalminutes<=63*EOneWeekUnitLimitInMinutes),Panic(KGsmuPanicValidityPeriodOutOfRange)); + TSmsOctet octet; + if (timeintervalminutes<=EFiveMinuteUnitLimitInMinutes) + octet=((timeintervalminutes/EFiveMinuteUnitInMinutes)-1); + else if (timeintervalminutes<=EHalfHourUnitLimitInMinutes) + octet=(((timeintervalminutes-(EHalfHourUnitLimitInMinutes/2))/EHalfHourUnitInMinutes)+EFiveMinuteUnitLimit); + + else if (timeintervalminutes<=EOneDayUnitLimitInMinutes) + octet=((timeintervalminutes/EOneDayUnitInMinutes)+166); + else + octet=((timeintervalminutes/EOneWeekUnitInMinutes)+192); + + aPtr=octet.EncodeL(aPtr); + break; + } + case (TSmsFirstOctet::ESmsVPFSemiOctet): + { + TSmsServiceCenterTimeStamp timestamp; + timestamp.SetTime(Time()); + + TTimeIntervalSeconds timeIntervalInSeconds(User::UTCOffset()); + timestamp.SetTimeOffset(timeIntervalInSeconds.Int() / CSmsMessage::E15MinutesRepresentedInSeconds); + + aPtr=timestamp.EncodeL(aPtr); + break; + } + default: + __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat)); + User::Leave(KErrGsmSMSTPVPFNotSupported); + break; + }; + return aPtr; + } // TSmsValidityPeriod::EncodeL + +TUint8* TSmsValidityPeriod::EncodeL(TUint8* aPtr, const TEncodeParams* aEncodeParams) const + { + LOGGSMU1("TSmsValidityPeriod::EncodeL()"); + + TInt validityperiodformat=ValidityPeriodFormat(); + switch (validityperiodformat) + { + case (TSmsFirstOctet::ESmsVPFNone): + break; + case (TSmsFirstOctet::ESmsVPFInteger): + { + TInt timeintervalminutes=iTimeIntervalMinutes.Int(); + __ASSERT_DEBUG((timeintervalminutes>=EFiveMinuteUnitInMinutes) && (timeintervalminutes<=63*EOneWeekUnitLimitInMinutes),Panic(KGsmuPanicValidityPeriodOutOfRange)); + TSmsOctet octet; + if (timeintervalminutes<=EFiveMinuteUnitLimitInMinutes) + octet=((timeintervalminutes/EFiveMinuteUnitInMinutes)-1); + else if (timeintervalminutes<=EHalfHourUnitLimitInMinutes) + octet=(((timeintervalminutes-(EHalfHourUnitLimitInMinutes/2))/EHalfHourUnitInMinutes)+EFiveMinuteUnitLimit); + + else if (timeintervalminutes<=EOneDayUnitLimitInMinutes) + octet=((timeintervalminutes/EOneDayUnitInMinutes)+166); + else + octet=((timeintervalminutes/EOneWeekUnitInMinutes)+192); + + aPtr=octet.EncodeL(aPtr); + break; + } + case (TSmsFirstOctet::ESmsVPFSemiOctet): + { + //The reason TSmsValidityPeriod::EncodeL(TUint8* aPtr, const TEncodeParams* aEncodeParams) was + //created was to allow the CSmsMessage's time stamp to be used when generating the validity time. + //The CSmsMessage's time stamp is typically created when the message is constructed by the SMS Stack client. + //This means the validity time is based from the point the SMS Stack client actually sends the message, rather + //than the SMS Stack encodes it + + TSmsServiceCenterTimeStamp timestamp; + timestamp.SetTime( *aEncodeParams->iTimeStamp + iTimeIntervalMinutes ); + + TTimeIntervalSeconds timeIntervalInSeconds( *aEncodeParams->iTimeIntervalInSeconds ); + timestamp.SetTimeOffset(timeIntervalInSeconds.Int() / CSmsMessage::E15MinutesRepresentedInSeconds); + + aPtr=timestamp.EncodeL(aPtr); + break; + } + default: + __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat)); + User::Leave(KErrGsmSMSTPVPFNotSupported); + break; + }; + return aPtr; + } // TSmsValidityPeriod::EncodeL + +void TSmsValidityPeriod::DecodeL(TGsmuLex8& aPdu) + { + LOGGSMU1("TSmsValidityPeriod::DecodeL()"); + + TInt validityperiodformat=ValidityPeriodFormat(); + switch (validityperiodformat) + { + case (TSmsFirstOctet::ESmsVPFNone): + break; + case (TSmsFirstOctet::ESmsVPFInteger): + { + TSmsOctet octet; + octet.DecodeL(aPdu); + if (octet<=EFiveMinuteUnitLimit) + iTimeIntervalMinutes=(octet+1)*EFiveMinuteUnitInMinutes; + else if (octet<=EHalfHourUnitLimit) + iTimeIntervalMinutes=((EOneDayUnitInMinutes/2)+((octet-EFiveMinuteUnitLimit)*EHalfHourUnitInMinutes)); + else if (octet<=EOneDayUnitLimit) + iTimeIntervalMinutes=(octet-166)*EOneDayUnitInMinutes; + else + iTimeIntervalMinutes=(octet-192)*EOneWeekUnitInMinutes; + break; + } + case (TSmsFirstOctet::ESmsVPFSemiOctet): + { + TSmsServiceCenterTimeStamp timestamp; + TInt timeError; + timestamp.DecodeL(aPdu, timeError); + User::LeaveIfError(timeError); + TTime time; + time.UniversalTime(); + timestamp.Time().MinutesFrom(time,iTimeIntervalMinutes); + break; + } + default: + __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicUnsupportedValidityPeriodFormat)); + User::Leave(KErrGsmSMSTPVPFNotSupported); + break; + }; + } // TSmsValidityPeriod::DecodeL + + +void TSmsValidityPeriod::InternalizeL(RReadStream& aStream) + { + TInt timeintervalinminutes=aStream.ReadInt32L(); + iTimeIntervalMinutes=timeintervalinminutes; + } // TSmsValidityPeriod::InternalizeL + + +void TSmsValidityPeriod::ExternalizeL(RWriteStream& aStream) const + { + aStream.WriteInt32L(iTimeIntervalMinutes.Int()); + } // TSmsValidityPeriod::ExternalizeL + + +CSmsInformationElement* CSmsInformationElement::NewL(TSmsInformationElementIdentifier aIdentifier,const TDesC8& aData) + { + LOGGSMU1("CSmsInformationElement::NewL()"); + + CSmsInformationElement* informationelement=new(ELeave) CSmsInformationElement(aIdentifier); + CleanupStack::PushL(informationelement); + informationelement->ConstructL(aData); + CleanupStack::Pop(); + return informationelement; + } // CSmsInformationElement::NewL + + +CSmsInformationElement* CSmsInformationElement::NewL() + { + LOGGSMU1("CSmsInformationElement::NewL()"); + + CSmsInformationElement* informationelement=new(ELeave) CSmsInformationElement(ESmsIEIConcatenatedShortMessages8BitReference); + CleanupStack::PushL(informationelement); + TPtrC8 data; + informationelement->ConstructL(data); + CleanupStack::Pop(); + return informationelement; + } // CSmsInformationElement::NewL + + +/** + * Destructor. + */ +CSmsInformationElement::~CSmsInformationElement() + { + delete iData; + } // CSmsInformationElement::NewL + + +/** + * Gets the Information Element data. + * + * @return Information Element data + * @capability None + */ +EXPORT_C TPtr8 CSmsInformationElement::Data() + { + LOGGSMU1("CSmsInformationElement::Data()"); + + return iData->Des(); + } // CSmsInformationElement::Data + + +/** + * Gets the (const) Information Element data. + * + * @return Information Element data + * @capability None + */ +EXPORT_C const TDesC8& CSmsInformationElement::Data() const + { + LOGGSMU1("CSmsInformationElement::Data()"); + + return *iData; + } // CSmsInformationElement::Data + + +/** + * Gets the Information Element Identifier. + * + * @return Information Element Identifier + * @capability None + */ +EXPORT_C CSmsInformationElement::TSmsInformationElementIdentifier CSmsInformationElement::Identifier() const + { + return TSmsId(TInt(iIdentifier)); + } // CSmsInformationElement::TSmsInformationElementIdentifier + + +TUint8* CSmsInformationElement::EncodeL(TUint8* aPtr) const + { + LOGGSMU1("CSmsInformationElement::EncodeL()"); + + TSmsOctet id=iIdentifier; + aPtr=id.EncodeL(aPtr); + TSmsOctet informationelementlength=iData->Des().Length(); + aPtr=informationelementlength.EncodeL(aPtr); + Mem::Copy(aPtr,iData->Des().Ptr(),informationelementlength); + aPtr+=TInt(informationelementlength); + return aPtr; + } // CSmsInformationElement::EncodeL + + +void CSmsInformationElement::DecodeL(TGsmuLex8& aPdu) + { + LOGGSMU1("CSmsInformationElement::DecodeL()"); + + TSmsOctet id; + id.DecodeL(aPdu); + iIdentifier=static_cast((TInt)id); + + TSmsOctet informationelementlength; + informationelementlength.DecodeL(aPdu); + + switch(iIdentifier) + { + case (ESmsIEIConcatenatedShortMessages8BitReference): + if(informationelementlength !=3) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsIEISpecialSMSMessageIndication): + if(informationelementlength !=2) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsIEIApplicationPortAddressing8Bit): + if(informationelementlength !=2) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsIEIApplicationPortAddressing16Bit): + if(informationelementlength !=4) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsIEISMSCControlParameters): + if(informationelementlength !=1) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsIEIUDHSourceIndicator): + if(informationelementlength !=1) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsIEIConcatenatedShortMessages16BitReference): + if(informationelementlength !=4) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsIEIRFC822EmailHeader): + if(informationelementlength !=1) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsHyperLinkFormat): + if(informationelementlength !=4) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsNationalLanguageSingleShift): + if(informationelementlength != 1) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsNationalLanguageLockingShift): + if(informationelementlength != 1) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + case (ESmsIEISIMToolkitSecurityHeaders1): + case (ESmsIEISIMToolkitSecurityHeaders2): + case (ESmsIEISIMToolkitSecurityHeaders3): + case (ESmsIEISIMToolkitSecurityHeaders4): + case (ESmsIEISIMToolkitSecurityHeaders5): + case (ESmsIEISIMToolkitSecurityHeaders6): + case (ESmsIEISIMToolkitSecurityHeaders7): + case (ESmsIEISIMToolkitSecurityHeaders8): + case (ESmsIEISIMToolkitSecurityHeaders9): + case (ESmsIEISIMToolkitSecurityHeaders10): + case (ESmsIEISIMToolkitSecurityHeaders11): + case (ESmsIEISIMToolkitSecurityHeaders12): + case (ESmsIEISIMToolkitSecurityHeaders13): + case (ESmsIEISIMToolkitSecurityHeaders14): + case (ESmsIEISIMToolkitSecurityHeaders15): + case (ESmsIEISIMToolkitSecurityHeaders16): + if(informationelementlength !=0) + User::Leave(KErrGsmSMSTpduNotSupported); + break; + default: + break; + } + + const TPtrC8 data(aPdu.NextAndIncL(informationelementlength)); + NewDataL(informationelementlength); + TPtr8 ptr(iData->Des()); + ptr.Copy(data); + } // CSmsInformationElement::DecodeL + + +void CSmsInformationElement::InternalizeL(RReadStream& aStream) + { + TSmsOctet id; + aStream >> id; + iIdentifier=static_cast((TInt)id); + delete iData; + iData=NULL; + iData=HBufC8::NewL(aStream,CSmsUserData::KSmsMaxUserDataSize); + } // CSmsInformationElement::InternalizeL + + +void CSmsInformationElement::ExternalizeL(RWriteStream& aStream) const + { + TSmsOctet id; + id=(TInt)iIdentifier; + aStream << id; + aStream << *iData; + } // CSmsInformationElement::ExternalizeL + + +void CSmsInformationElement::ConstructL(const TDesC8& aData) + { + LOGGSMU1("CSmsInformationElement::ConstructL()"); + + NewDataL(aData.Length()); + iData->Des().Copy(aData); + } // CSmsInformationElement::ConstructL + + +void CSmsInformationElement::NewDataL(TInt aLength) + { + LOGGSMU1("CSmsInformationElement::NewDataL()"); + + HBufC8* data=HBufC8::NewL(aLength); + delete iData; + iData=data; + iData->Des().SetLength(aLength); + } // CSmsInformationElement::NewDataL + + +TUint CSmsInformationElement::Length()const + { + LOGGSMU1("CSmsInformationElement::Length()"); + + return 2+iData->Length(); // 2 stands for IEID and IEDL + } // CSmsInformationElement::Length + + +/** + * @internalComponent + * + * This method maps an information element to an index into an array of categories. + * + * @param aId + * The information Element Identifier. + * @param aIndex + * The index into the array of categories + * @return + * True if the information element can be mapped. + * False otherwise. + */ +TBool TSmsInformationElementCategories::TranslateCategoryToIndex(TInformationElementId aId, TInt& aIndex) + { + LOGGSMU1("CSmsMessage::TranslateCategoryToIndex"); + + TBool rc = ETrue; + + if (aId < CSmsInformationElement::ESmsIEMaximum) + { + switch (aId) + { + case CSmsInformationElement::ESmsIEIConcatenatedShortMessages8BitReference: + case CSmsInformationElement::ESmsIEIConcatenatedShortMessages16BitReference: + case CSmsInformationElement::ESmsIEISMSCControlParameters: + case CSmsInformationElement::ESmsIEIRFC822EmailHeader: + { + aIndex = EIndexCtrlMandatoryInEveryPDUButWithValueSpecificToPDU; + break; + } + case CSmsInformationElement::ESmsIEISpecialSMSMessageIndication: + { + aIndex = EIndexCtrlMandatoryInEveryPDUMultipleInstancesPerPDU; + break; + } + case CSmsInformationElement::ESmsHyperLinkFormat: + { + aIndex = EIndexCtrlMultipleInstancesAllowed; + break; + } + case CSmsInformationElement::ESmsNationalLanguageSingleShift: + case CSmsInformationElement::ESmsNationalLanguageLockingShift: + { + aIndex = EIndexCtrlOptionalInEveryPDUWithValueSpecificToPDU; + break; + } + case CSmsInformationElement::ESmsReplyAddressFormat: + { + aIndex = EIndexCtrlMandatoryIn1stPDUOnly; + break; + } + case CSmsInformationElement::ESmsEnhanceVoiceMailInformation: + { + aIndex = EIndexCtrlSingleInstanceOnly; + break; + } + case CSmsInformationElement::ESmsEnhancedTextFormatting: + case CSmsInformationElement::ESmsEnhancedPredefinedSound: + case CSmsInformationElement::ESmsEnhancedUserDefinedSound: + case CSmsInformationElement::ESmsEnhancedPredefinedAnimation: + case CSmsInformationElement::ESmsEnhancedLargeAnimation: + case CSmsInformationElement::ESmsEnhancedSmallAnimation: + case CSmsInformationElement::ESmsEnhancedLargePicture: + case CSmsInformationElement::ESmsEnhancedSmallPicture: + case CSmsInformationElement::ESmsEnhancedVariablePicture: + case CSmsInformationElement::ESmsEnhancedUserPromptIndicator: + case CSmsInformationElement::ESmsEnhancedExtendedObject: + case CSmsInformationElement::ESmsEnhancedReusedExtendedObject: + case CSmsInformationElement::ESmsEnhancedCompressionControl: + case CSmsInformationElement::ESmsEnhancedODI: + case CSmsInformationElement::ESmsEnhancedStandardWVG: + case CSmsInformationElement::ESmsEnhancedCharacterSizeWVG: + case CSmsInformationElement::ESmsEnhancedextendedObjectDataRequest: + { + aIndex = EIndexEmsInformationElement; + break; + } + case CSmsInformationElement::ESmsIEIReserved: + case CSmsInformationElement::ESmsIEIValueNotUsed: + { + rc = EFalse; + break; + } + default: + { + aIndex = EIndexCtrlMandatoryInEveryPDUAndWithIdenticalValues; + break; + } + } + } + else + { + rc = EFalse; + LOGGSMU3("CSmsMessage::TranslateCategoryToIndex id = %d, found = %d", aId, rc); + } + return rc; + } // TSmsInformationElementCategories::TranslateCategoryToIndex + + +/** + * @internalComponent + * + * This method gets an information element identifier's category. + * + * @param aId + * The information Element Identifier. + * @param aCategory + * The category of information element. + * @return + * ETrue if successful, EFalse if an information identifier is unknown or cannot + * be mapped. + */ +TBool TSmsInformationElementCategories::GetCategoryDefinition(TInformationElementId aId, TInformationElementCategory& aCategory) + { + LOGGSMU1("TSmsInformationElementCategories::GetCategoryDefinition"); + TInt index; + + if (TranslateCategoryToIndex(aId,index)) + { + aCategory = categories[index]; + } + else + { + LOGGSMU2("TSmsInformationElementCategories::GetCategoryDefinition, Failure, aId = %d", aId); + return EFalse; + } + + return ETrue; + } // TSmsInformationElementCategories::GetCategoryDefinition + + +const TSmsInformationElementCategories::TInformationElementCategory TSmsInformationElementCategories::categories[TSmsInformationElementCategories::ENumberOfIndices] = + { + TSmsInformationElementCategories::EEmsInformationElement, // EDefaultEMSIndex + TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUAndWithIdenticalValues, // EDefaultControlIndex + TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUMultipleInstancesPerPDU, // EIndexForSpecialSMSMessageIndication, Concatenated Short Messages + TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUButWithValueSpecificToPDU,// EIndexForIRFC822EmailHeader, Application Port Addresses + TSmsInformationElementCategories::ECtrlMandatoryIn1stPDUOnly, // EIndexReplyAddressFormat + TSmsInformationElementCategories::ECtrlSingleInstanceOnly, // EIndexEnhanceVoiceMailInformation + TSmsInformationElementCategories::ECtrlMultipleInstancesAllowed // EIndexForHyperLinkFormat + }; + + +CSmsUserData* CSmsUserData::NewL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsFirstOctet& aFirstOctet,const TSmsDataCodingScheme& aDataCodingScheme) + { + LOGGSMU1("CSmsUserData::NewL()"); + + CSmsUserData* userdata=new(ELeave) CSmsUserData(aCharacterSetConverter,aFs,aFirstOctet,aDataCodingScheme); + CleanupStack::PushL(userdata); + userdata->ConstructL(); + CleanupStack::Pop(); + return userdata; + } // CSmsUserData::NewL + + +/** + * Destructor. + */ +CSmsUserData::~CSmsUserData() + { + iInformationElementArray.ResetAndDestroy(); + delete iBody; + } // CSmsUserData::NewL + + +/** + * Gets an information element by index. + * + * @param aIndex Index of the information element within the User Data + * @return Information element + * @capability None + */ +EXPORT_C CSmsInformationElement& CSmsUserData::InformationElement(TInt aIndex) const + { + LOGGSMU1("CSmsUserData::InformationElement()"); + + return *iInformationElementArray[aIndex]; + } // CSmsUserData::InformationElement + + +CSmsInformationElement*& CSmsUserData::InformationElementPtr(TInt aIndex) + { + LOGGSMU1("CSmsUserData::InformationElementPtr()"); + + return iInformationElementArray[aIndex]; + } // CSmsUserData::InformationElementPtr + + +/** + * Gets the index of an information element. + * + * @param aIdentifier An information element Identifier to search for + * @param aIndex The index within the User Data of the information element (if + * found). If more than 1 instance of this information element exists, then + * the 1st instance will be returned. + * + * Use InformationELementIndexL to get all elements. + * @return True if aIdentifier is found in the User Data + * @capability None + */ +EXPORT_C TBool CSmsUserData::InformationElementIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,TInt& aIndex) const + { + LOGGSMU1("CSmsUserData::InformationElementIndex()"); + + TBool found=EFalse; + TInt count=NumInformationElements(); + for (TInt i=0; (!found) && (i=0); i--) + if (InformationElement(i).Identifier()==aIdentifier) + { + found=ETrue; + aIndex=i; + } + return found; + } // CSmsUserData::InformationElementLastIndex + + +/** + * @internalComponent + * + * Locates every information element of type aIdentifier and + * stores its location index in the output array aIndices. + * + * @param aIdentifer + * The information element Identifier to search for + * @param aIndices + * A collection containing the location index for each information element of this type. + */ +void CSmsUserData::InformationElementIndicesL(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier, CArrayFixFlat& aIndices) const + { + LOGGSMU1("CSmsUserData::InformationElementIndicesL()"); + + aIndices.Reset(); + + TInt count=NumInformationElements(); + for (TInt i=0; iEncodeInformationElementL(); + iInformationElementArray.AppendL(aIe); + + TInt sizeLeft=MaxPackedUDUnitsInBodyRemaining(); + iInformationElementArray.Delete(iInformationElementArray.Count()-1); + if(sizeLeft==0 && iBody && (iBody->Length() > 0) && (*iBody)[iBody->Length()-1] == KSms7BitAlphabetEscapeChar) + { + --aCharsAddedToCurrentPDU; + --aSeg.iElementsExtracted; + TPtr8 ptr(iBody->Des()); + ptr.Delete(iBody->Length()-1,1); + --sizeLeft; + } + return sizeLeft>=0; + } // CSmsUserData::EmsInformationElementWillFitL + + +/** + * Tests whether the control information element will fit in the current PDU. + * + * Note that whilst a pointer to the aIe is passed as an + * input argument, the information element is still owned + * by the calling function, regardless of the return code. + * + * @param aInformationElement A pointer to an information Element + * @capability None + */ +TBool CSmsUserData::ControlInformationElementWillFitL(CSmsInformationElement* aIe) + { + LOGGSMU1("CSmsUserData::ControlInformationElementWillFitL()"); + + if (aIe == NULL) + { + User::Leave(KErrGeneral); + } + + TSmsInformationElementCategories::TInformationElementCategory category; + + if (TSmsInformationElementCategories::GetCategoryDefinition(aIe->Identifier(), category) == EFalse || + category == TSmsInformationElementCategories::EEmsInformationElement) + { + User::Leave(KErrArgument); + } + + iInformationElementArray.AppendL(aIe); + + TInt sizeLeft=MaxPackedUDUnitsInBodyRemaining(); + iInformationElementArray.Delete(iInformationElementArray.Count()-1); + + // Not considering whether escape characters exist in the buffer + // as control information elements do not add text to the buffer. + + return sizeLeft>=0; + } // CSmsUserData::ControlInformationElementWillFitL + + +/** + * Adds an information element. + * This method can be used to create information elements in the range: + * 00 - 09 - i.e. Control Information Elements + * It can be used to create information elements in the following ranges + * (on the assumption that the information element is intended to be encoded into + * every PDU): + * 24 - 25 - i.e. National Language Encodings + * 70 - 7F - i.e. SIM Tool Kit Security Headers + * 80 - 9F - i.e SMS to SME specific use + * C0 - CF - i.e. SC specific use + * + * Information elements in the following ranges should not be + * added using this interface. Instead they should be added using + * the following identified interfaces: + * 0A-1F - Use the interfaces provided to support EMS Elements + * 20 - Use the interfaces provided for Email in CSmsMessage + * 21 - Use the interface provided by CSmsHyperLinkOperations + * 22 - Use the interface provided by CSmsReplyAddressOperations + * 23 - Use the interface provided by CSmsEnhancedVoiceMailOperations + * + * This interface should not be used for information element in the following + * ranges, these are reserved for future use in TS23.040 V6.5.0 and their + * characteristics and repeatability have not yet been defined. + * 26-6F + * A0-BF + * E0-FF + * + * @param aIdentifier An information element Identifier for aData + * @param aData The information element to add to the User Data + * @leave + * KErrNotSupported if the information element is not supported via this interface. + * @capability None + */ +EXPORT_C void CSmsUserData::AddInformationElementL(TSmsId aIdentifier,const TDesC8& aData) + { + LOGGSMU1("CSmsUserData::AddInformationElementL"); + + if ((aIdentifier >= 0x21) && (aIdentifier <= 0x23) || + (aIdentifier >= 0x26) && (aIdentifier <= 0x6F) || + (aIdentifier >= 0xA0) && (aIdentifier <= 0xBF) || + (aIdentifier >= 0xE0) && (aIdentifier <= 0xFF)) + { + User::Leave(KErrNotSupported); + } + UpdateInformationElementArrayL(aIdentifier, aData); + + } // CSmsUserData::AddInformationElementL + + +/** + * @internalComponent + * + * Either adds an information element to + * iInformationElementArray. + * + * @param aIdentifier An information element Identifier for aData + * @param aData The information element to add to the User Data + */ +void CSmsUserData::UpdateInformationElementArrayL(TSmsId aIdentifier,const TDesC8& aData) + { + LOGGSMU1("CSmsUserData::UpdateInformationElementsL"); + + TInt count=NumInformationElements(); + if(!CEmsFactory::Supported(aIdentifier)) + { + for (TInt i=0; i& aSmsPDUArray,CSmsBufferBase& aBuffer) + break; + } + default: + { + LOGGSMU3("CSmsUserData::AddInformationElementL8 category = %d, identifier = %d",category,aIdentifier); + User::Leave(KErrNotSupported); + break; + } + } + } + } + } + + CSmsInformationElement* informationElement=CSmsInformationElement::NewL(aIdentifier,aData); + CleanupStack::PushL(informationElement); + iInformationElementArray.AppendL(informationElement); + CleanupStack::Pop(); + SetHeaderPresent(ETrue); + } // CSmsUserData::UpdateInformationElementArrayL + + +void CSmsUserData::AddEmsInformationElementL(CEmsInformationElement* aIe) + { + LOGGSMU1("CSmsUserData::AddEmsInformationElementL()"); + + // Before using an EmsInformationElement polymorphically as an SmsIE, + // we need to make sure that the IE has been encoded + aIe->EncodeInformationElementL(); + iInformationElementArray.AppendL(aIe); + SetHeaderPresent(ETrue); + } // CSmsUserData::AddEmsInformationElementL + + +/** + * Removes an information element at the specified index. + * + * @param aIndex Information element index + * @capability None + */ +EXPORT_C void CSmsUserData::RemoveInformationElement(TInt aIndex) + { + LOGGSMU1("CSmsUserData::RemoveInformationElement()"); + // Since iInformationElementArray[aIndex] pointer is removed from iInformationElementArray, there is no double free issue. + // coverity[double_free] + delete iInformationElementArray[aIndex]; + iInformationElementArray[aIndex] = NULL; + iInformationElementArray.Delete(aIndex); + + if (NumInformationElements()==0) + { + SetHeaderPresent(EFalse); + } + } // CSmsUserData::RemoveInformationElement + + +TInt CSmsUserData::MaxPackedUDUnitsInBodyRemaining() const + { + LOGGSMU1("CSmsUserData::MaxPackedUDUnitsInBodyRemaining()"); + + TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits(); + TInt maxPackedUDUnitsInBody=0; + if (iDataCodingScheme.TextCompressed()||(iDataCodingScheme.Alphabet()!=TSmsDataCodingScheme::ESmsAlphabet7Bit)) + { + maxPackedUDUnitsInBody=KSmsMaxUserDataSize-totalHeaderLengthInUDLUnits; + if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabetUCS2) + { + // Cannot split unicode character across PDU boundary + maxPackedUDUnitsInBody&=~1; + } + } + else // 7-bit + { + maxPackedUDUnitsInBody=(8*KSmsMaxUserDataSize)/7-totalHeaderLengthInUDLUnits; + } + + if (iBody) + return maxPackedUDUnitsInBody-=iBody->Length(); + return maxPackedUDUnitsInBody; + } // CSmsUserData::MaxPackedUDUnitsInBodyRemaining + + +TInt CSmsUserData::MaxPackedUDUnitsInBodyRemaining(TUint aIELen) const + { + LOGGSMU1("CSmsUserData::MaxPackedUDUnitsInBodyRemaining()"); + + TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits(aIELen); + TInt maxPackedUDUnitsInBody=0; + if (iDataCodingScheme.TextCompressed()||(iDataCodingScheme.Alphabet()!=TSmsDataCodingScheme::ESmsAlphabet7Bit)) + { + maxPackedUDUnitsInBody=KSmsMaxUserDataSize-totalHeaderLengthInUDLUnits; + if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabetUCS2) + { + // Cannot split unicode character across PDU boundary + maxPackedUDUnitsInBody&=~1; + } + } + else // 7-bit + { + maxPackedUDUnitsInBody=(8*KSmsMaxUserDataSize)/7-totalHeaderLengthInUDLUnits; + } + + if (iBody) + return maxPackedUDUnitsInBody-=iBody->Length(); + return maxPackedUDUnitsInBody; + } // CSmsUserData::MaxPackedUDUnitsInBodyRemaining + + +/** + * @capability None + */ +EXPORT_C TInt CSmsUserData::MaxBodyLengthInChars() const + { + LOGGSMU1("CSmsUserData::MaxBodyLengthInChars()"); + + TInt totalheaderlengthinudlunits=TotalHeaderLengthInUDLUnits(); + TInt maxbodylengthinchars=0; + if (iDataCodingScheme.TextCompressed()) + { + maxbodylengthinchars=KSmsMaxUserDataSize-totalheaderlengthinudlunits; + } + else + { + switch (iDataCodingScheme.Alphabet()) + { + case (TSmsDataCodingScheme::ESmsAlphabet7Bit): + { + maxbodylengthinchars=(8*KSmsMaxUserDataSize)/7-totalheaderlengthinudlunits; + break; + } + case (TSmsDataCodingScheme::ESmsAlphabet8Bit): + { + maxbodylengthinchars=KSmsMaxUserDataSize-totalheaderlengthinudlunits; + break; + } + case (TSmsDataCodingScheme::ESmsAlphabetUCS2): + { + maxbodylengthinchars=(KSmsMaxUserDataSize-totalheaderlengthinudlunits)/2; + break; + } + default: + LOGGSMU1("CSmsUserData::MaxBodyLengthInChars() WARNING! default case has been reached"); + break; + } + } + return maxbodylengthinchars; + } // CSmsUserData::MaxBodyLengthInChars + + +/** + * Gets the unpacked User Data Elements. + * + * @return Unpacked User Data Elements + * @capability None + */ +EXPORT_C TPtrC8 CSmsUserData::Body() const + { + LOGGSMU1("CSmsUserData::Body()"); + + return iBody->Des(); + } // CSmsUserData::Body + + +/** + * Sets the User Data (unpacked). + * + * @param aBody Unpacked User Data Elements + * @capability None + */ +EXPORT_C void CSmsUserData::SetBodyL(const TDesC8& aBody) + { + LOGGSMU1("CSmsUserData::SetBodyL()"); + + //Some tests fail with this line in, despite it being a valid condition! + //__ASSERT_DEBUG(aBody.Length() <= MaxBodyLengthInChars(), User::Leave(KErrTooBig)); + + NewBodyL(aBody.Length()); + iBody->Des().Copy(aBody); + } // CSmsUserData::SetBodyL + + +void CSmsUserData::AppendBodyL(const TDesC8& aBody) + { + LOGGSMU1("CSmsUserData::AppendBodyL()"); + + if (iBody) + { + //Some tests fail with this line in, despite it being a valid condition! + //__ASSERT_DEBUG(aBody.Length() + iBody->Length() <= MaxBodyLengthInChars(), User::Leave(KErrTooBig)); + + iBody = iBody->ReAllocL(aBody.Length()+iBody->Length()); + iBody->Des().Append(aBody); + } + else + { + SetBodyL(aBody); + } + } // CSmsUserData::AppendBodyL + + +/** + * Tests if the character is supported by the current character set. + * This function can be used with 7bit and 8bit alphabets. + * + * @param aChar Character to investigate. + * + * @return ETrue if the character is supported. + * + * @note Since the function is based on the old behaviour (pre-PREQ2090) + * it does not accept a downgraded character or alternative encoding + * as being supported. + * + * @capability None + */ +EXPORT_C TBool CSmsUserData::IsSupportedL(TChar aChar) + { + LOGGSMU1("CSmsUserData::IsSupportedL()"); + + CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData()); + TBool result=converter->IsSupportedL(aChar); + CleanupStack::PopAndDestroy(); + + return result; + } // CSmsUserData::IsSupportedL + + +/** + * Tests if the descriptor text is supported by the current character set. + * This function can be used with 7bit and 8bit alphabets. + * + * @param aDes Text string to check. + * @param aNumberOfUnconvertibleCharacters Exit param for the number of + * characters unconvertible. + * @param aIndexOfFirstUnconvertibleCharacter Exit param for the first + * unconverted character. + * + * @return ETrue if the character is supported. + * + * @capability None + */ +EXPORT_C TBool CSmsUserData::IsSupportedL(const TDesC& aDes, TInt& aNumberOfUnconvertibleCharacters, + TInt& aIndexOfFirstUnconvertibleCharacter) const + { + LOGGSMU1("[1] CSmsUserData::IsSupportedL()"); + + CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData()); + TBool result=converter->IsSupportedL(aDes, aNumberOfUnconvertibleCharacters, + aIndexOfFirstUnconvertibleCharacter); + CleanupStack::PopAndDestroy(); + + return result; + } // CSmsUserData::IsSupportedL + + +/** + * Tests if the descriptor text is supported by the current character set. + * This function can be used with 7bit and 8bit alphabets. + * + * @param aDes Text string to check. + * @param aEncoding Alternative encoding method. + * @param aNumberOfUnconvertibleCharacters Exit param for the number of + * characters unconvertible. + * @param aNumberOfDowngradedCharacters Exit param for the number of + * downgraded characters. + * @param aNumberRequiringAlternativeEncoding Exit param for the number of + * characters requiring use of + * the alternative encoder. + * @param aIndexOfFirstUnconvertibleCharacter Exit param for the first + * unconverted character. + * + * @return ETrue if the character is supported. + * + * @capability None + */ +EXPORT_C TBool CSmsUserData::IsSupportedL(const TDesC& aDes, TSmsEncoding aEncoding, + TInt& aNumberOfUnconvertibleCharacters, + TInt& aNumberOfDowngradedCharacters, + TInt& aNumberRequiringAlternativeEncoding, + TInt& aIndexOfFirstUnconvertibleCharacter) const + { + LOGGSMU1("[2] CSmsUserData::IsSupportedL()"); + + CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(iCharacterSetConverter,iFs,iDataCodingScheme.Alphabet(),IsBinaryData()); + TBool result=converter->IsSupportedL(aDes, aEncoding, + aNumberOfUnconvertibleCharacters, + aNumberOfDowngradedCharacters, + aNumberRequiringAlternativeEncoding, + aIndexOfFirstUnconvertibleCharacter); + CleanupStack::PopAndDestroy(); + + return result; + } // CSmsUserData::IsSupportedL + + +TUint8* CSmsUserData::EncodeL(TUint8* aPtr) const + { + LOGGSMU1("CSmsUserData::EncodeL()"); + + __ASSERT_DEBUG(0<=MaxPackedUDUnitsInBodyRemaining(),Panic(KGsmuPanicUserDataBodyTooLong)); + // Encode the user data length + TInt totalHeaderLengthInUDLUnits=TotalHeaderLengthInUDLUnits(); + TSmsOctet userDataLength=totalHeaderLengthInUDLUnits+TSmsOctet(BodyLengthInUDLUnits()); + aPtr=userDataLength.EncodeL(aPtr); + // Encode any user data header + if (HeaderPresent()) + { + TSmsOctet headerLength=HeaderLength(); + aPtr=headerLength.EncodeL(aPtr); + TInt numInformationElements=NumInformationElements(); + for (TInt i=0; iEncodeL(aPtr); + } + // Pack the user data body + TInt startBit=0; + if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit) + startBit=(totalHeaderLengthInUDLUnits*7)%8; + TSmsAlphabetPacker packer(iDataCodingScheme.Alphabet(),IsBinaryData(),startBit); + TPtr8 ptr((TUint8*)aPtr,0,packer.PackedOctetsRequiredL(Body().Length())); + aPtr+=packer.PackL(ptr,Body()); + return aPtr; + } // CSmsUserData::EncodeL + + +void CSmsUserData::DecodeL(TGsmuLex8& aPdu) + { + DecodeL(aPdu, EFalse); + } + +void CSmsUserData::DecodeL(TGsmuLex8& aPdu, TBool aAcceptTruncation) + { + LOGGSMU1("CSmsUserData::DecodeL()"); + + // Reset current data + iInformationElementArray.ResetAndDestroy(); + // Decode the user data + TSmsOctet userDataLength; + userDataLength.DecodeL(aPdu); + TSmsOctet headerLength; + // Decode any user data header + TBool headerPresent=HeaderPresent(); + /* + if (headerPresent || IsHeaderPresent(aPtr,dataLength)) + */ + if (headerPresent) + { + headerLength.DecodeL(aPdu); + if ((1+headerLength)>KSmsMaxUserDataSize) + User::Leave(KErrGsmSMSTpduNotSupported); + while (HeaderLength()DecodeL(aPdu); + iInformationElementArray.AppendL(informationelement); + CleanupStack::Pop(informationelement); + } + if (HeaderLength()!=headerLength) + User::Leave(KErrGsmSMSTpduNotSupported); + } + // Decode the body - make sure we have enough buffer + TInt headerLengthInUDLUnits=TotalHeaderLengthInUDLUnits(); + TInt bodyLengthInUDLUnits=userDataLength-headerLengthInUDLUnits; + + if(bodyLengthInUDLUnits <=0) + { + NewBodyL(0); + return; + } + + NewBodyL(bodyLengthInUDLUnits); + + // Unpack the body + TInt startBit=0; + if (iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet7Bit) + startBit=(headerLengthInUDLUnits*7)%8; + TSmsAlphabetPacker unpacker(iDataCodingScheme.Alphabet(),IsBinaryData(),startBit); + TInt bodyLengthInOctets=unpacker.PackedOctetsRequiredL(bodyLengthInUDLUnits); + TPtr8 destPtr((TUint8*)iBody->Des().Ptr(),0,bodyLengthInUDLUnits); + + const TPtrC8 sourcePtr(aPdu.NextWithNoIncL(bodyLengthInOctets,aAcceptTruncation)); + if ( aAcceptTruncation && sourcePtr.Length() < bodyLengthInOctets) + { + // field was truncated in an acceptable situation (User Data in Status Report PDU) + bodyLengthInUDLUnits = unpacker.NumUDUnitsL(sourcePtr.Length()); + } + unpacker.UnpackL(sourcePtr,destPtr,bodyLengthInUDLUnits); + + //@note No need to call aPdu.IncL() because CSmsUserData is always at the end of a PDU + } // CSmsUserData::DecodeL + + +void CSmsUserData::InternalizeL(RReadStream& aStream) + { + iInformationElementArray.ResetAndDestroy(); + TInt numiformationelements=aStream.ReadInt32L(); + // The "header present" flag must mirror whether information elements are present, and + // the parental iFirstOctet should already be set by its InternalizeL() + __ASSERT_DEBUG(((!HeaderPresent() && numiformationelements == 0) || (HeaderPresent() && numiformationelements > 0)), Panic(KGsmuPanicInformationElementIndexOutOfRange)); + for (TInt i=0; i> *informationelement; + iInformationElementArray.AppendL(informationelement); + CleanupStack::Pop(); + } + delete iBody; + iBody=NULL; + iBody=HBufC8::NewL(aStream,KSmsMaxUserDataLengthInChars); + } // CSmsUserData::InternalizeL + + +void CSmsUserData::ExternalizeL(RWriteStream& aStream) const + { + TInt numiformationelements=iInformationElementArray.Count(); + aStream.WriteInt32L(numiformationelements); + for (TInt i=0; iSetBodyL(Body()); + + for (TInt ie = 0; ie < iInformationElementArray.Count(); ie++) + { + CSmsInformationElement* oldIE = iInformationElementArray[ie]; + + if (CEmsFactory::Supported(oldIE->Identifier())) + { + CEmsInformationElement* newIE = static_cast(oldIE)->DuplicateL(); + + CleanupStack::PushL(newIE); + userdata->AddEmsInformationElementL(newIE); + CleanupStack::Pop(newIE); + } + else + { + userdata->UpdateInformationElementArrayL(oldIE->Identifier(), oldIE->Data()); + } + } + + CleanupStack::Pop(); + + return userdata; + } // CSmsUserData::DuplicateL + + +TInt CSmsUserData::HeaderLength() const + { + LOGGSMU1("CSmsUserData::HeaderLength()"); + + TInt numinformationelements=NumInformationElements(); + TInt headerlength=0; + for (TInt i=0; iLength(); + return headerlength; + } // CSmsUserData::HeaderLength + + +TInt CSmsUserData::TotalHeaderLengthInUDLUnits() const + { + LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits()"); + + TInt totalheaderlengthinudlunits=0; + if (iInformationElementArray.Count()>0) + { + TInt totalheaderlength=1+HeaderLength(); + if (iDataCodingScheme.TextCompressed()) + { + totalheaderlengthinudlunits=totalheaderlength; + } + else + { + switch(iDataCodingScheme.Alphabet()) + { + case (TSmsDataCodingScheme::ESmsAlphabet7Bit): + { + totalheaderlengthinudlunits=((8*totalheaderlength)+6)/7; // Rounds up + break; + } + case (TSmsDataCodingScheme::ESmsAlphabet8Bit): + case (TSmsDataCodingScheme::ESmsAlphabetUCS2): + { + totalheaderlengthinudlunits=totalheaderlength; + break; + } + default: + LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits() WARNING default case has been reached"); + break; + } + } + } + return totalheaderlengthinudlunits; + } // CSmsUserData::TotalHeaderLengthInUDLUnits + + +TInt CSmsUserData::TotalHeaderLengthInUDLUnits(TInt aIElen) const + { + LOGGSMU1("CSmsUserData::TotalHeaderLengthInUDLUnits()"); + + TInt totalheaderlengthinudlunits=0; + TInt totalheaderlength=aIElen; + + if (iInformationElementArray.Count()>0) + totalheaderlength+=HeaderLength(); + + if(totalheaderlength)totalheaderlength+=1; //UDHL + + if (iDataCodingScheme.TextCompressed()) + { + totalheaderlengthinudlunits=totalheaderlength; + } + else + { + switch(iDataCodingScheme.Alphabet()) + { + case (TSmsDataCodingScheme::ESmsAlphabet7Bit): + { + totalheaderlengthinudlunits=((8*totalheaderlength)+6)/7; // Rounds up + break; + } + case (TSmsDataCodingScheme::ESmsAlphabet8Bit): + case (TSmsDataCodingScheme::ESmsAlphabetUCS2): + { + totalheaderlengthinudlunits=totalheaderlength; + break; + } + default: + break; + } + } + return totalheaderlengthinudlunits; + } // CSmsUserData::TotalHeaderLengthInUDLUnits + + +TInt CSmsUserData::BodyLengthInUDLUnits() const + { + LOGGSMU1("CSmsUserData::BodyLengthInUDLUnits()"); + + return iBody->Des().Length(); + } // CSmsUserData::BodyLengthInUDLUnits + + +void CSmsUserData::NewBodyL(TInt aLength) + { + LOGGSMU1("CSmsUserData::NewBodyL()"); + + + HBufC8* body=HBufC8::NewL(aLength); + delete iBody; + iBody=body; + iBody->Des().SetLength(aLength); + + } // CSmsUserData::NewBodyL + + +TBool CSmsUserData::HeaderPresent() const + { + LOGGSMU1("CSmsUserData::HeaderPresent()"); + + return (iFirstOctet&TSmsFirstOctet::ESmsUDHIMask)==TSmsFirstOctet::ESmsUDHIHeaderPresent; + } // CSmsUserData::HeaderPresent + + +void CSmsUserData::SetHeaderPresent(TBool aHeaderPresent) + { + LOGGSMU1("CSmsUserData::SetHeaderPresent()"); + + iFirstOctet=aHeaderPresent? (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderPresent: (iFirstOctet&(~TSmsFirstOctet::ESmsUDHIMask))|TSmsFirstOctet::ESmsUDHIHeaderNotPresent; + } // CSmsUserData::SetHeaderPresent + + +TBool CSmsUserData::IsBinaryData() const + { + LOGGSMU1("CSmsUserData::IsBinaryData()"); + + TInt index=0; + return (iDataCodingScheme.TextCompressed()) || + ((iDataCodingScheme.Alphabet()==TSmsDataCodingScheme::ESmsAlphabet8Bit) && + (InformationElementIndex(CSmsInformationElement::ESmsIEIApplicationPortAddressing8Bit,index) || + InformationElementIndex(CSmsInformationElement::ESmsIEIApplicationPortAddressing16Bit,index))); + } // CSmsUserData::IsBinaryData + + +/** + * Converts type of number and numbering plan identification information + * from the type of address parameter to the NMobilePhone::TMobileTON + * and NMobilePhone::TMobileNPI format. + * + * @return aTon The number type + * @return aNpi The numbering plan + * + * @capability None + */ +EXPORT_C void TGsmSmsTypeOfAddress::ConvertToETelMM(NMobilePhone::TMobileTON& aTon,NMobilePhone::TMobileNPI& aNpi) const + { + LOGGSMU1("TGsmSmsTypeOfAddress::ConvertToETelMM()"); + + switch (TON()) + { + case EGsmSmsTONInternationalNumber: + { + aTon = (NMobilePhone::EInternationalNumber); + break; + } + case EGsmSmsTONNationalNumber: + { + aTon = (NMobilePhone::ENationalNumber); + break; + } + case EGsmSmsTONNetworkSpecificNumber: + { + aTon = (NMobilePhone::ENetworkSpecificNumber); + break; + } + case EGsmSmsTONSubscriberNumber: + { + aTon = (NMobilePhone::ESubscriberNumber); + break; + } + case EGsmSmsTONAlphaNumeric: + { + aTon = (NMobilePhone::EAlphanumericNumber); + break; + } + case EGsmSmsTONAbbreviatedNumber: + { + aTon = (NMobilePhone::EAbbreviatedNumber); + break; + } + + default: + { + aTon = (NMobilePhone::EUnknownNumber); + break; + } + } + + switch (NPI()) + { + case EGsmSmsNPIISDNTelephoneNumberingPlan: + { + aNpi = (NMobilePhone::EIsdnNumberPlan); + break; + } + case EGsmSmsNPIDataNumberingPlan: + { + aNpi = (NMobilePhone::EDataNumberPlan); + break; + } + case EGsmSmsNPITelexNumberingPlan: + { + aNpi = (NMobilePhone::ETelexNumberPlan); + break; + } + case EGsmSmsNPINationalNumberingPlan: + { + aNpi = (NMobilePhone::ENationalNumberPlan); + break; + } + case EGsmSmsNPIPrivateNumberingPlan: + { + aNpi = (NMobilePhone::EPrivateNumberPlan); + break; + } + case EGsmSmsNPIERMESNumberingPlan: + { + aNpi = (NMobilePhone::EERMESNumberPlan); + break; + } + + default: + { + aNpi = (NMobilePhone::EUnknownNumberingPlan); + break; + } + } + } // NMobilePhone::TMobileNPI + + +/** + * Converts type of number and numbering plan identification information + * from the NMobilePhone::TMobileTON and NMobilePhone::TMobileNPI format + * to the type of address parameter. + * + * @param aTon The number type + * @param aNpi The numbering plan + * + * @capability None + */ +EXPORT_C void TGsmSmsTypeOfAddress::SetFromETelMM(NMobilePhone::TMobileTON aTon,NMobilePhone::TMobileNPI aNpi) + { + LOGGSMU1("TGsmSmsTypeOfAddress::SetFromETelMM()"); + + switch (aTon) + { + case NMobilePhone::EInternationalNumber: + { + SetTON( EGsmSmsTONInternationalNumber ); + break; + } + case NMobilePhone::ENationalNumber: + { + SetTON( EGsmSmsTONNationalNumber ); + break; + } + case NMobilePhone::ENetworkSpecificNumber: + { + SetTON( EGsmSmsTONNetworkSpecificNumber ); + break; + } + case NMobilePhone::ESubscriberNumber: + { + SetTON( EGsmSmsTONSubscriberNumber ); + break; + } + case NMobilePhone::EAlphanumericNumber: + { + SetTON( EGsmSmsTONAlphaNumeric ); + break; + } + case NMobilePhone::EAbbreviatedNumber: + { + SetTON( EGsmSmsTONAbbreviatedNumber ); + break; + } + + default: + { + SetTON( EGsmSmsTONUnknown ); + break; + } + } + + switch (aNpi) + { + case NMobilePhone::EIsdnNumberPlan: + { + SetNPI( EGsmSmsNPIISDNTelephoneNumberingPlan ); + break; + } + case NMobilePhone::EDataNumberPlan: + { + SetNPI( EGsmSmsNPIDataNumberingPlan ); + break; + } + case NMobilePhone::ETelexNumberPlan: + { + SetNPI( EGsmSmsNPITelexNumberingPlan ); + break; + } + case NMobilePhone::ENationalNumberPlan: + { + SetNPI( EGsmSmsNPINationalNumberingPlan ); + break; + } + case NMobilePhone::EPrivateNumberPlan: + { + SetNPI( EGsmSmsNPIPrivateNumberingPlan ); + break; + } + case NMobilePhone::EERMESNumberPlan: + { + SetNPI( EGsmSmsNPIERMESNumberingPlan ); + break; + } + + default: + { + SetNPI( EGsmSmsNPIUnknown ); + break; + } + } + } // NMobilePhone::TMobileTON + + +/** + * @publishedAll + * + * Indicates whether this message is a Voice Mail Notification + * or a Voice Mail Deletion Confirmation. + * + * @return + * TVoiceMailInfoType, indicating whether this message is a Voice Mail + * Notification or a Voice Mail Deletion Confirmation. + * + * @capability None + */ +EXPORT_C TVoiceMailInfoType CEnhancedVoiceMailBoxInformation::Type() const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::Type()"); + + return iType; + } // CEnhancedVoiceMailBoxInformation::Type + + +/** + * @publishedAll + * + * Sets the subscriber profile per 23.040 v6.5 Section 9.2.3.24.13.1. + * + * @param aProfile + * The required subscriber profile + * + * @capability None + */ +EXPORT_C void CEnhancedVoiceMailBoxInformation::SetProfile(TSmsMessageProfileType aProfile) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetProfile()"); + + iProfile = aProfile; + } // CEnhancedVoiceMailBoxInformation::SetProfile + + +/** + * @publishedAll + * + * Gets the subscriber profile per 23.040 v6.5 Section 9.2.3.24.13.1. + * + * @param aProfile + * The current subscriber profile + * + * @capability None + */ +EXPORT_C TSmsMessageProfileType CEnhancedVoiceMailBoxInformation::Profile() const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::Profile()"); + + return iProfile; + } // CEnhancedVoiceMailBoxInformation::Profile + + +/** + * @publishedAll + * + * Configures the storage directive + * + * @param aIsStored + * Set to True if the SM is to be stored in the ME or USIM, + * False is the SM is to be discarded. + * + * @capability None + */ +EXPORT_C void CEnhancedVoiceMailBoxInformation::SetStorage(TBool aIsStored) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetStorage()"); + + iStorage = aIsStored; + } // CEnhancedVoiceMailBoxInformation::SetStorage + + +/** + * @publishedAll + * + * Indicates whether the SM is to be stored or discarded + * + * @return + * True if the SM is to be stored in the ME or USIM, + * False is the SM is to be discarded. + * + * @capability None + */ +EXPORT_C TBool CEnhancedVoiceMailBoxInformation::Store() const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::Store()"); + + return iStorage; + } // CEnhancedVoiceMailBoxInformation::Store + + +/** + * @publishedAll + * + * Used to set or reset the voice mail status to almost full. + * + * @param aIsStored + * Set to True the voice mail system is almost full. + * Set to False otherwise. + * + * @capability None + */ +EXPORT_C void CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity(TBool aIsAlmostFull) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity()"); + + iAlmostFull = aIsAlmostFull; + } // CEnhancedVoiceMailBoxInformation::SetAlmostMaximumCapacity + + +/** + * @publishedAll + * + * Indicates whether the voice mail system is almost at full capacity. + * + * @return + * True, if the voice mail system is almost full. + * False otherwise. + * + * @capability None + */ +EXPORT_C TBool CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity() const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity()"); + + return iAlmostFull; + } // CEnhancedVoiceMailBoxInformation::AlmostMaximumCapacity + + +/** + * @publishedAll + * + * Used to set or reset the voice mail status to full. + * + * @param aIsStored + * Set to True the voice mail system is full. + * Set to False otherwise. + * + * @capability None + */ +EXPORT_C void CEnhancedVoiceMailBoxInformation::SetMaximumCapacity(TBool aIsFull) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetMaximumCapacity()"); + + iFull = aIsFull; + } // CEnhancedVoiceMailBoxInformation::SetMaximumCapacity + + +/** + * @publishedAll + * + * Indicates whether the voice mail status is full. + * + * @return + * True if the voice mail system is almost full. + * False otherwise. + * + * @capability None + */ +EXPORT_C TBool CEnhancedVoiceMailBoxInformation::MaximumCapacity() const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::MaximumCapacity()"); + + return iFull; + } // CEnhancedVoiceMailBoxInformation::MaximumCapacity + + +/** + * @publishedAll + * + * Indicates whether the message contains extension bytes + * + * @return + * True if the message contains extension bytes. + * False otherwise. + * + * @capability None + */ +EXPORT_C TBool CEnhancedVoiceMailBoxInformation::ExtensionIndicator() const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::ExtensionIndicator()"); + + return iExtensionIndicator; + } // CEnhancedVoiceMailBoxInformation::ExtensionIndicator + + +void CEnhancedVoiceMailBoxInformation::NewBufferL(TInt aLength) + { + LOGGSMU2("CEnhancedVoiceMailBoxInformation::NewBufferL, length = %d",aLength); + + HBufC* buffer=HBufC::NewL(aLength); + delete iAccessAddress; + iAccessAddress=buffer; + iAccessAddress->Des().SetLength(aLength); + iAccessAddress->Des().FillZ(); + } // CEnhancedVoiceMailBoxInformation::NewBufferL + + +/** + * @publishedAll + * + * Used to set the voice mail box number, overwriting any pre-existing number. + * + * @param aAddress + * The voice mail box address. + * + * @capability None + */ +EXPORT_C void CEnhancedVoiceMailBoxInformation::SetAccessAddressL(const TDesC& aAddress) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetAccessAddressL()"); + + TInt length=aAddress.Length(); + NewBufferL(length); + iAccessAddress->Des().Copy(aAddress); + + const TGsmSmsTypeOfNumber typeofnumber=length && (iAccessAddress->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown; + iTypeOfAddress.SetTON(typeofnumber); + } // CEnhancedVoiceMailBoxInformation::SetAccessAddressL + + +/** + * @publishedAll + * + * Retrieves the voice mail box number. + * + * @return + * A pointer to the voice mail box number. + * + * @capability None + */ +EXPORT_C TPtrC CEnhancedVoiceMailBoxInformation::AccessAddress() const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::AccessAddress()"); + + TPtrC ptr; + if (iAccessAddress) + ptr.Set(iAccessAddress->Des()); + return ptr; + } // CEnhancedVoiceMailBoxInformation::AccessAddress + + +/** + * @publishedAll + * + * Used to set the voice mail box number as a parsed address + * + * @param aParsedAddress + * The parsed address to be used as the voice mail box number. + * + * @capability None + */ +EXPORT_C void CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL(const TGsmSmsTelNumber& aParsedAddress) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL()"); + + iTypeOfAddress=aParsedAddress.iTypeOfAddress; + DoSetParsedAddressL(aParsedAddress.iTelNumber); + } // CEnhancedVoiceMailBoxInformation::SetParsedAccessAddressL + + +/** + * @publishedAll + * + * Used to get the voice mail box number as a parsed address. + * + * @param aParsedAddress + * An output parameter which is set to the parsed address. + * + * @capability None + */ +EXPORT_C void CEnhancedVoiceMailBoxInformation::ParsedAccessAddress(TGsmSmsTelNumber& aParsedAddress) const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::ParsedAccessAddress()"); + + aParsedAddress.iTypeOfAddress = iTypeOfAddress; + + TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength(); + + if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric) + { + TInt parsedlength=AccessAddress().Length(); + if (parsedlength>maxparsedlength) + parsedlength=maxparsedlength; + aParsedAddress.iTelNumber.Copy(AccessAddress().Mid(0,parsedlength)); + } + else + { + aParsedAddress.iTelNumber.SetLength(maxparsedlength); + + TInt length=iAccessAddress->Des().Length(); + TInt parsedlength=0; + for (TInt i=0; (iDes()[i]; + if ((ch>='0') && (ch<='9')) + { + aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch; + parsedlength++; + } + } + + aParsedAddress.iTelNumber.SetLength(parsedlength); + } + } // CEnhancedVoiceMailBoxInformation::ParsedAccessAddress + + +void CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL(const TDesC& aAddress) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL()"); + + TInt length=aAddress.Length(); + if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) && + (length && (aAddress[0]!='+'))) + { + NewBufferL(length+1); + iAccessAddress->Des()[0]='+'; + TPtr ptr((TText*) (iAccessAddress->Des().Ptr()+1),length,length); + ptr.Copy(aAddress); + } + else + { + NewBufferL(length); + iAccessAddress->Des().Copy(aAddress); + } + } // CEnhancedVoiceMailBoxInformation::DoSetParsedAddressL + + +/** + * @publishedAll + * + * Sets the number of voice messages to a value in the range 0 to 255. + * + * @param aNumber + * The number of voice messages. + * + * @capability None + */ +EXPORT_C void CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages(TUint8 aNumber) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages()"); + + iNumberOfVoiceMessages=aNumber; + } // CEnhancedVoiceMailBoxInformation::SetNumberOfVoiceMessages + + +/** + * @publishedAll + * + * Retrieves the number of voice messages that are unread. + * + * @return + * The number of unread voice messages. + * + * @capability None + */ +EXPORT_C TUint8 CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages() const + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages()"); + + return iNumberOfVoiceMessages; + } // CEnhancedVoiceMailBoxInformation::NumberOfVoiceMessages + + +TUint8* CEnhancedVoiceMailBoxInformation::EncodeL(TUint8* aPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const + { + *aPtr = (((TUint8) iType) & EMask1Bit ) + + ((((TUint8) iProfile) & EMask2Bits) << 2) + + ((((TUint8) iStorage) & EMask1Bit ) << 4) + + ((((TUint8) iAlmostFull) & EMask1Bit ) << 5) + + ((((TUint8) iFull) & EMask1Bit ) << 6) + + (((TUint8) iExtensionIndicator ) << 7); + + LOGGSMU2("CEnhancedVoiceMailBoxInformation::EncodeL 1st byte = %d",*aPtr); + aPtr++; + + // Create an address object to encode the mail box access address into the + // format required by 23.040 v6.5.0 section 9.1.2.5. + CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs); + CleanupStack::PushL(address); + TPtrC accessAddressPtr; + if (iAccessAddress) + { + accessAddressPtr.Set(iAccessAddress->Des()); + } + address->SetRawAddressL(iTypeOfAddress,accessAddressPtr); + aPtr = address->EncodeL(aPtr); + CleanupStack::PopAndDestroy(address); + + *aPtr = (TUint8) iNumberOfVoiceMessages; + aPtr++; + + return aPtr; + } // CEnhancedVoiceMailBoxInformation::EncodeL + + +void CEnhancedVoiceMailBoxInformation::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) + { + TUint8 Byte1 = aVoiceMailInfo.GetL(); + + iType = (TVoiceMailInfoType) (Byte1 & EMask1Bit); + iProfile = (TSmsMessageProfileType ) ((Byte1 >> 2) & EMask2Bits); + iStorage = (TBool) ((Byte1 >> 4) & EMask1Bit); + iAlmostFull = (TBool) ((Byte1 >> 5) & EMask1Bit); + iFull = (TBool) ((Byte1 >> 6) & EMask1Bit); + iExtensionIndicator = (TBool) ((Byte1 >> 7) & EMask1Bit); + + LOGGSMU2("CEnhancedVoiceMailBoxInformation::DecodeL 1st byte = %d", Byte1); + + // Create an address object to deccode the mail box access address from the + // format required by 23.040 v6.5.0 section 9.1.2.5. + CSmsAddress* decodedAddress = CSmsAddress::NewL(aCharacterSetConverter,aFs); + CleanupStack::PushL(decodedAddress); + + // CSmsAddress::DecodeL is also used to decode source and destination addresses. + // CSmsAddress::DecodeL expects internally that alphanumeric addresses will be size + // CSmsAddress::KSmsAddressMaxAddressValueLength=10. + // Need to add padding bytes to bring the address field up to the maximum size. + const TPtrC8 remainder(aVoiceMailInfo.Remainder()); + + if (remainder.Length() < CSmsAddress::KSmsAddressMaxAddressLength) + { + TBuf8 data; + data = remainder; + TInt actualLength = data.Length(); + data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength); + + for (TUint8 j = actualLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++) + { + data[j] = 0; + } + + TGsmuLex8 encodedAddress(data); + decodedAddress->DecodeL(encodedAddress); + // might want to check that aVoiceMailInfo can be incremented + // by encodedAddress.Offset. + aVoiceMailInfo.Inc(encodedAddress.Offset()); + } + else + { + decodedAddress->DecodeL(aVoiceMailInfo); + } + + TInt length=(decodedAddress->Address()).Length(); + NewBufferL(length); + iAccessAddress->Des().Copy((decodedAddress->Address().Ptr()),length); + + iTypeOfAddress = decodedAddress->TypeOfAddress(); + + CleanupStack::PopAndDestroy(decodedAddress); + + iNumberOfVoiceMessages = aVoiceMailInfo.GetL(); + LOGGSMU2("CEnhancedVoiceMailBoxInformation::DecodeL iNumberOfVoiceMessages = %d", iNumberOfVoiceMessages); + } // CEnhancedVoiceMailBoxInformation::DecodeL + + +CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation() + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()"); + + // Consider changing this over to a Panic. + iType = EGsmSmsVoiceMailNotification; + iOctet1Bit1 = EFalse; + iProfile = EGsmSmsProfileId1; + iStorage = EFalse; + iAlmostFull = EFalse; + iFull = EFalse; + iExtensionIndicator = EFalse; + iTypeOfAddress = 0; + } // CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation + + +CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation(TVoiceMailInfoType aTVoiceMailInfoType) + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation()"); + + iType = aTVoiceMailInfoType; + iOctet1Bit1 = EFalse; + iProfile = EGsmSmsProfileId1; + iStorage = EFalse; + iAlmostFull = EFalse; + iFull = EFalse; + iExtensionIndicator = EFalse; + iTypeOfAddress = 0; + } // CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation + + +/** + * @internalComponent + * + * Prevent clients from using the copy constructor by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation(const CEnhancedVoiceMailBoxInformation&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailBoxInformation::CEnhancedVoiceMailBoxInformation"); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the equality operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +TBool CEnhancedVoiceMailBoxInformation::operator==(const CEnhancedVoiceMailBoxInformation&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailBoxInformation::operator=="); + Panic(KGsmuPanicMethodBodyNotImplemented); + return EFalse; + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the assignment operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +void CEnhancedVoiceMailBoxInformation::operator=(const CEnhancedVoiceMailBoxInformation&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailBoxInformation::operator="); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +void CEnhancedVoiceMailBoxInformation::ConstructL() + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::ConstructL()"); + + NewBufferL(0); + } // CEnhancedVoiceMailBoxInformation::ConstructL + + +CEnhancedVoiceMailBoxInformation::~CEnhancedVoiceMailBoxInformation() + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::~CEnhancedVoiceMailBoxInformation"); + delete iAccessAddress; + } // CEnhancedVoiceMailBoxInformation::ConstructL + + +CEnhancedVoiceMailBoxInformation* CEnhancedVoiceMailBoxInformation::NewL() + { + LOGGSMU1("CEnhancedVoiceMailBoxInformation::NewL()"); + + CEnhancedVoiceMailBoxInformation* aCEnhancedVoiceMailBoxInformation=new(ELeave) CEnhancedVoiceMailBoxInformation(); + CleanupStack::PushL(aCEnhancedVoiceMailBoxInformation); + aCEnhancedVoiceMailBoxInformation->ConstructL(); + CleanupStack::Pop(aCEnhancedVoiceMailBoxInformation); + return aCEnhancedVoiceMailBoxInformation; + } // CEnhancedVoiceMailBoxInformation::NewL + + +/** + * @publishedAll + * + * Sets the message id to a value between 0 and 65535. + * + * @param aNumber + * The message id + * + * @capability None + */ +EXPORT_C void CVoiceMailNotification::SetMessageId(TUint16 aMessageId) + { + LOGGSMU1("CVoiceMailNotification::SetMessageId()"); + + iMessageId = aMessageId; + } // CVoiceMailNotification::SetMessageId + + +/** + * @publishedAll + * + * Retrieves the message id, a value in the range 0 to 65535. + * + * @return + * The message id, + * + * @capability None + */ +EXPORT_C TUint16 CVoiceMailNotification::MessageId() const + { + LOGGSMU1("CVoiceMailNotification::MessageId()"); + + return iMessageId; + } // CVoiceMailNotification::MessageId + + +/** + * @publishedAll + * + * Sets the voice mail message length to a value between 0 and 255 + * + * @param aLength + * The voice mail message length. + * + * @capability None + */ +EXPORT_C void CVoiceMailNotification::SetMessageLength(TUint8 aLength) + { + LOGGSMU1("CVoiceMailNotification::SetMessageLength()"); + + iMessageLength=aLength; + } // CVoiceMailNotification::SetMessageLength + + +/** + * @publishedAll + * + * Retrieves the voice mail message length, a value in the range 0 to 255. + * + * @return + * The voice mail message length. + * + * @capability None + */ +EXPORT_C TUint8 CVoiceMailNotification::MessageLength() const + { + LOGGSMU1("CVoiceMailNotification::MessageLength()"); + + return iMessageLength; + } // CVoiceMailNotification::MessageLength + + +/** + * @publishedAll + * + * Sets the number of days that the voice message will be retained to + * a value between 0 and 31. Values in excess of 31 will be capped at + * 31. + * + * @param aDays + * The number of retention days. + * + * @capability None + */ +EXPORT_C void CVoiceMailNotification::SetRetentionDays(TUint8 aDays) + { + LOGGSMU1("CVoiceMailNotification::SetRetentionDays()"); + + if (aDays > 31) + { + iRetentionDays = 31; + } + else + { + iRetentionDays = aDays; + } + } // CVoiceMailNotification::SetRetentionDays + + +/** + * @publishedAll + * + * Retrieves the number of days the voice message will be retained. + * + * @return + * The number of days the voice message will be retained. + * + * @capability None + */ +EXPORT_C TUint8 CVoiceMailNotification::RetentionDays() const + { + LOGGSMU1("CVoiceMailNotification::RetentionDays()"); + + return iRetentionDays; + } // CVoiceMailNotification::RetentionDays + + +/** + * @publishedAll + * + * Sets the message priority to urgent + * + * @param aPriority + * Set to True if the priority is urgent, + * Otherwise set to False. + * + * @capability None + */ +EXPORT_C void CVoiceMailNotification::SetPriorityIndication(TBool aPriority) + { + LOGGSMU1("CVoiceMailNotification::SetPriorityIndication()"); + + iPriorityIndication=aPriority; + } // CVoiceMailNotification::SetPriorityIndication + + +/** + * @publishedAll + * + * Retrieves the priority indication. + * + * @return + * True if the priority is urgent, + * False otherwise. + * + * @capability None + */ +EXPORT_C TBool CVoiceMailNotification::PriorityIndication() const + { + LOGGSMU1("CVoiceMailNotification::PriorityIndication()"); + + return iPriorityIndication; + } // CVoiceMailNotification::PriorityIndication + + +/** + * @publishedAll + * + * Indicates whether the voice mail notification contains extension bytes. + * + * @return + * True if the voice mail notification contains extension bytes. + * False otherwise. + * + * @capability None + */ +EXPORT_C TBool CVoiceMailNotification::MessageExtensionIndication() const + { + LOGGSMU1("CVoiceMailNotification::MessageExtensionIndication()"); + + return iMessageExtensionIndicator; + } // CVoiceMailNotification::MessageExtensionIndication + + +void CVoiceMailNotification::NewBufferL(TInt aLength) + { + LOGGSMU1("CVoiceMailNotification::NewBufferL()"); + + HBufC* buffer=HBufC::NewL(aLength); + delete iCallingLineIdentity; + iCallingLineIdentity=buffer; + iCallingLineIdentity->Des().SetLength(aLength); + iCallingLineIdentity->Des().FillZ(); + } // CVoiceMailNotification::NewBufferL + + +/** + * @publishedAll + * + * Used to set the calling line idenity + * + * @param aLineIdentity + * + * @capability None + */ +EXPORT_C void CVoiceMailNotification::SetCallingLineIdentityL(TDesC& aLineIdentity) + { + LOGGSMU1("CVoiceMailNotification::SetCallingLineIdentityL()"); + + TInt length=aLineIdentity.Length(); + NewBufferL(length); + iCallingLineIdentity->Des().Copy(aLineIdentity); + + const TGsmSmsTypeOfNumber typeofnumber=length && (iCallingLineIdentity->Des()[0]=='+')? EGsmSmsTONInternationalNumber: EGsmSmsTONUnknown; + iTypeOfAddress.SetTON(typeofnumber); + } // CVoiceMailNotification::SetCallingLineIdentityL + + +/** + * @publishedAll + * + * Retrieves the Calling Line Identity + * + * @return + * A pointer to the Calling Line Identity. + * + * @capability None + */ +EXPORT_C TPtrC CVoiceMailNotification::CallingLineIdentity() const + { + LOGGSMU1("CVoiceMailNotification::CallingLineIdentity()"); + + TPtrC ptr; + if (iCallingLineIdentity) + ptr.Set(iCallingLineIdentity->Des()); + return ptr; + } // CVoiceMailNotification::CallingLineIdentity + + +/** + * @publishedAll + * + * Set the Calling Line Id as a parsed address. + * + * @param aParsedAddress + * The Calling Line Id as a parsed address. + * + * @capability None + */ +EXPORT_C void CVoiceMailNotification::SetParsedCallingLineIdentityL(TGsmSmsTelNumber& aParsedAddress) + { + LOGGSMU1("CVoiceMailNotification::SetParsedCallingLineIdentityL()"); + + iTypeOfAddress=aParsedAddress.iTypeOfAddress; + DoSetParsedAddressL(aParsedAddress.iTelNumber); + } // CVoiceMailNotification::SetParsedCallingLineIdentityL + + +/** + * @publishedAll + * + * Gets the Calling Line Id as a parsed address. + * + * @param aParsedAddress + * An output parameter which is to be set to the parsed calling line ID. + * + * @capability None + */ +EXPORT_C void CVoiceMailNotification::ParsedCallingLineIdentity(TGsmSmsTelNumber& aParsedAddress) const + { + LOGGSMU1("CVoiceMailNotification::ParsedCallingLineIdentity()"); + + aParsedAddress.iTypeOfAddress = iTypeOfAddress; + + TInt maxparsedlength=aParsedAddress.iTelNumber.MaxLength(); + + if (iTypeOfAddress.TON()==EGsmSmsTONAlphaNumeric) + { + TInt parsedlength=CallingLineIdentity().Length(); + if (parsedlength>maxparsedlength) + parsedlength=maxparsedlength; + aParsedAddress.iTelNumber.Copy(CallingLineIdentity().Mid(0,parsedlength)); + } + else + { + aParsedAddress.iTelNumber.SetLength(maxparsedlength); + + TInt length=iCallingLineIdentity->Des().Length(); + TInt parsedlength=0; + for (TInt i=0; (iDes()[i]; + if ((ch>='0') && (ch<='9')) + { + aParsedAddress.iTelNumber[parsedlength]=(TUint8) ch; + parsedlength++; + } + } + + aParsedAddress.iTelNumber.SetLength(parsedlength); + } + } // CVoiceMailNotification::ParsedCallingLineIdentity + + +void CVoiceMailNotification::NewExtensionL(TInt aLength) + { + LOGGSMU1("CVoiceMailNotification::NewExtensionL()"); + + HBufC* buffer=HBufC::NewL(aLength); + delete iExtension; + iExtension=buffer; + iExtension->Des().SetLength(aLength); + iExtension->Des().FillZ(); + } // CVoiceMailNotification::NewExtensionL + + +/*void CVoiceMailNotification::SetExtension(TDesC& aExtension) + { + LOGGSMU1("CVoiceMailNotification::SetExtension()"); + + TInt length=aExtension.Length(); + NewExtensionL(length); + iExtension->Des().Copy(aExtension); + } // CVoiceMailNotification::SetExtension + +TPtrC CVoiceMailNotification::Extension() const + { + LOGGSMU1("CVoiceMailNotification::Extension()"); + + TPtrC ptr; + if (iExtension) + ptr.Set(iExtension->Des()); + return ptr; + }*/ + + +/** + * @internalComponent + * + * Determines the size of the encoded Voice Mail Notification. + * + * @param aCharacterSetConverter A reference to a character set converter. + * @param aFs A reference to the file server. + * @return The size of the encoded Voice Mail Notification + * + * @capability None + */ +TUint8 CVoiceMailNotification::SizeL(CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) + { + LOGGSMU1("CVoiceMailNotification::SizeL()"); + + const TUint8 KTotalSizeOfFixedLengthAttributes = 4; + TUint8 size = KTotalSizeOfFixedLengthAttributes; + + // need to find the size of the calling line ID. + CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs); + CleanupStack::PushL(address); + + TPtrC callingLineIdentityPtr; + if (iCallingLineIdentity) + { + callingLineIdentityPtr.Set(iCallingLineIdentity->Des()); + } + + address->SetRawAddressL(iTypeOfAddress,callingLineIdentityPtr); + + size += address->SizeL(); + CleanupStack::PopAndDestroy(address); + + return size; + } // CVoiceMailNotification::SizeL + + +TUint8* CVoiceMailNotification::EncodeL(TUint8* aPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const + { + // When changes are made to this function that affect the + // number of bytes that are encoded, this should be reflected in + // CVoiceMailNotification::SizeL() + LOGGSMU1("CVoiceMailNotification::EncodeL"); + + + *aPtr = (TUint8) (iMessageId >> 8); // Message Id MSB + aPtr++; + *aPtr = (TUint8) iMessageId; // Message Id LSB + aPtr++; + *aPtr = (TUint8) iMessageLength; + aPtr++; + *aPtr = ((TUint8) (iRetentionDays & EMask5Bits)) + + (((TUint8) iPriorityIndication) << 6) + + (((TUint8) iMessageExtensionIndicator) << 7); + aPtr++; + + CSmsAddress* address = CSmsAddress::NewL(aCharacterSetConverter,aFs); + CleanupStack::PushL(address); + + TPtrC callingLineIdentityPtr; + if (iCallingLineIdentity) + { + callingLineIdentityPtr.Set(iCallingLineIdentity->Des()); + } + + address->SetRawAddressL(iTypeOfAddress,callingLineIdentityPtr); + + aPtr = address->EncodeL(aPtr); + CleanupStack::PopAndDestroy(address); + + return aPtr; + } // CVoiceMailNotification::EncodeL + + +void CVoiceMailNotification::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) + { + LOGGSMU1("CVoiceMailNotification::DecodeL"); + + iMessageId = (((TUint16) aVoiceMailInfo.GetL()) << 8); + iMessageId += ((TUint16) aVoiceMailInfo.GetL()); + + iMessageLength=aVoiceMailInfo.GetL(); + + TUint8 currentByte = aVoiceMailInfo.GetL(); + + iRetentionDays = currentByte & EMask5Bits; + iPriorityIndication = ((currentByte >> 6) & EMask1Bit); + iMessageExtensionIndicator = ((currentByte >> 7) & EMask1Bit); + + CSmsAddress* decodedAddress = CSmsAddress::NewL(aCharacterSetConverter,aFs); + CleanupStack::PushL(decodedAddress); + + const TPtrC8 remainder(aVoiceMailInfo.Remainder()); + // The address information element makes an assumption that aVoiceMail must + // be of size CSmsAddress::KSmsAddressMaxAddressLength + // Provide padding to ensure that this is the case. + if (remainder.Length() < CSmsAddress::KSmsAddressMaxAddressLength) + { + TBuf8 data; + data = remainder; + TInt actualLength = data.Length(); + data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength); + + for (TUint8 j = actualLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++) + { + data[j] = 0; + } + + TGsmuLex8 encodedAddress(data); + decodedAddress->DecodeL(encodedAddress); + // Should be the last piece of data to be decoded + // The next line is included for completeness. + aVoiceMailInfo.Inc(encodedAddress.Offset()); + } + else + { + decodedAddress->DecodeL(aVoiceMailInfo); + } + + TInt length=(decodedAddress->Address()).Length(); + NewBufferL(length); + iCallingLineIdentity->Des().Copy((decodedAddress->Address().Ptr()),length); + + iTypeOfAddress = decodedAddress->TypeOfAddress(); + + CleanupStack::PopAndDestroy(decodedAddress); + + if (iMessageExtensionIndicator) + { + TUint8 extensionLength = aVoiceMailInfo.GetL(); + aVoiceMailInfo.Inc(extensionLength); + } + } // CVoiceMailNotification::DecodeL + + +/** + * @internalComponent + * + * Prevent clients from using the copy constructor by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +CVoiceMailNotification::CVoiceMailNotification(const CVoiceMailNotification&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CVoiceMailNotification::CVoiceMailNotification"); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the equality operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +TBool CVoiceMailNotification::operator==(const CVoiceMailNotification&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CVoiceMailNotification::operator=="); + Panic(KGsmuPanicMethodBodyNotImplemented); + return EFalse; + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the assignment operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +void CVoiceMailNotification::operator=(const CVoiceMailNotification&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CVoiceMailNotification::operator="); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +CVoiceMailNotification::CVoiceMailNotification() + { + LOGGSMU1("CVoiceMailNotification::CVoiceMailNotification()"); + + iMessageId = 0; + iMessageLength = 0; + iRetentionDays = 0; + iOctetN8Bit1 = EFalse; + iPriorityIndication = EFalse; + iMessageExtensionIndicator = EFalse; + iTypeOfAddress = 0; + } // CVoiceMailNotification::CVoiceMailNotification + + +/** + * @publishedAll + * + * Class Destructor + * + * @capability None + */ +EXPORT_C CVoiceMailNotification::~CVoiceMailNotification() + { + LOGGSMU1("CVoiceMailNotification::~CVoiceMailNotification"); + delete iCallingLineIdentity; + delete iExtension; + } // CVoiceMailNotification::CVoiceMailNotification + + +void CVoiceMailNotification::ConstructL() + { + LOGGSMU1("CVoiceMailNotification::ConstructL()"); + + NewBufferL(0); + NewExtensionL(0); + } // CVoiceMailNotification::ConstructL + + +/** + * @publishedAll + * + * Class construction method. + * + * @capability None + */ +EXPORT_C CVoiceMailNotification* CVoiceMailNotification::NewL() + { + LOGGSMU1("CVoiceMailNotification::NewL()"); + + CVoiceMailNotification* aCVoiceMailNotification=new(ELeave) CVoiceMailNotification(); + CleanupStack::PushL(aCVoiceMailNotification); + aCVoiceMailNotification->ConstructL(); + CleanupStack::Pop(aCVoiceMailNotification); + return aCVoiceMailNotification; + } // CVoiceMailNotification::NewL + + +void CVoiceMailNotification::DoSetParsedAddressL(const TDesC& aAddress) + { + LOGGSMU1("CVoiceMailNotification::DoSetParsedAddressL()"); + + TInt length=aAddress.Length(); + if ((iTypeOfAddress.TON()==EGsmSmsTONInternationalNumber) && + (length && (aAddress[0]!='+'))) + { + NewBufferL(length+1); + iCallingLineIdentity->Des()[0]='+'; + TPtr ptr((TText*) (iCallingLineIdentity->Des().Ptr()+1),length,length); + ptr.Copy(aAddress); + } + else + { + NewBufferL(length); + iCallingLineIdentity->Des().Copy(aAddress); + } + } // CVoiceMailNotification::DoSetParsedAddressL + + +/** + * @publishedAll + * + * Retrieves the number of voice message notifications contained in + * this information. The range is 0 to 15. + * + * @return + * The number of voice message notifications in this information element. + * + * @capability None + */ +EXPORT_C TUint8 CEnhancedVoiceMailNotification::NumberOfVoiceMails() + { + LOGGSMU1("CEnhancedVoiceMailNotification::NumberOfVoiceMails()"); + + return (TUint8) iNotifications->Count(); + } // CEnhancedVoiceMailNotification::NumberOfVoiceMails + + +/*void CEnhancedVoiceMailNotification::SetExtension(TDesC& aExtension) + { + LOGGSMU1("CEnhancedVoiceMailNotification::SetExtension()"); + + TInt length=aExtension.Length(); + NewExtensionL(length); + iExtension->Des().Copy(aExtension); + } // CEnhancedVoiceMailNotification::SetExtension + +TPtrC CEnhancedVoiceMailNotification::Extension() const + { + LOGGSMU1("CEnhancedVoiceMailNotification::Extension()"); + + TPtrC ptr; + if (iExtension) + ptr.Set(iExtension->Des()); + return ptr; + }*/ + + +/** + * @publishedAll + * + * Provides a reference to the collection that is used to contain the Voice Mail Notifications. + * A maximum of 15 voice mail confirmations is supported. If more that 15 voice mails notifications are added + * the CEnhancedVoiceMailNotification will not be added to the CSmsMessage by the CSmsEnhancedVoiceMailOperations + * class. + * + * @return + * A reference to the collection that is used to contain the Voice Mail Notifications. + * + * @capability None + */ +EXPORT_C RPointerArray& CEnhancedVoiceMailNotification::GetVoiceMailNotifications() + { + LOGGSMU1("CEnhancedVoiceMailNotification::GetVoiceMailNotifications()"); + + return *iNotifications; + } // CEnhancedVoiceMailNotification::GetVoiceMailNotifications + + +void CEnhancedVoiceMailNotification::NewExtensionL(TInt aLength) + { + LOGGSMU1("CEnhancedVoiceMailNotification::NewExtensionL()"); + + HBufC* buffer=HBufC::NewL(aLength); + delete iExtension; + iExtension=buffer; + iExtension->Des().SetLength(aLength); + iExtension->Des().FillZ(); + } // CEnhancedVoiceMailNotification::NewExtensionL + + +/** + * @publishedAll + * + * Class construction method. + * + * @capability None + */ +EXPORT_C CEnhancedVoiceMailNotification* CEnhancedVoiceMailNotification::NewL() + { + LOGGSMU1("CEnhancedVoiceMailNotification::NewL()"); + + CEnhancedVoiceMailNotification* aCEnhancedVoiceMailNotification=new(ELeave) CEnhancedVoiceMailNotification(); + CleanupStack::PushL(aCEnhancedVoiceMailNotification); + aCEnhancedVoiceMailNotification->CEnhancedVoiceMailBoxInformation::ConstructL(); + aCEnhancedVoiceMailNotification->ConstructL(); + CleanupStack::Pop(aCEnhancedVoiceMailNotification); + return aCEnhancedVoiceMailNotification; + } // CEnhancedVoiceMailNotification::NewL + + +CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification() : CEnhancedVoiceMailBoxInformation(EGsmSmsVoiceMailNotification) + { + } // CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification + + +/** + * @internalComponent + * + * Prevent clients from using the copy constructor by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification(const CEnhancedVoiceMailNotification&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailNotification::CEnhancedVoiceMailNotification"); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the equality operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +TBool CEnhancedVoiceMailNotification::operator==(const CEnhancedVoiceMailNotification&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailNotification::operator=="); + Panic(KGsmuPanicMethodBodyNotImplemented); + return EFalse; + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the assignment operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +void CEnhancedVoiceMailNotification::operator=(const CEnhancedVoiceMailNotification&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailNotification::operator="); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +/** + * @publishedAll + * + * Class destructor. + * + * @capability None + */ +EXPORT_C CEnhancedVoiceMailNotification::~CEnhancedVoiceMailNotification() + { + LOGGSMU1("CEnhancedVoiceMailNotification::~CEnhancedVoiceMailNotification"); + delete iExtension; + iNotifications->ResetAndDestroy(); + iNotifications->Close(); + delete iNotifications; + } // CEnhancedVoiceMailNotification::operator + + +void CEnhancedVoiceMailNotification::ConstructL() + { + LOGGSMU1("CEnhancedVoiceMailNotification::ConstructL()"); + + NewExtensionL(0); + iNotifications = new (ELeave) RPointerArray(KMaxNumberOfNotifications); + } // CEnhancedVoiceMailNotification::ConstructL + + +TUint8* CEnhancedVoiceMailNotification::EncodeL(TUint8* aCurrentPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const + { + LOGGSMU1("CEnhancedVoiceMailNotification::EncodeL"); + + TUint8* startPtr = aCurrentPtr; + + aCurrentPtr = CEnhancedVoiceMailBoxInformation::EncodeL(aCurrentPtr, aCharacterSetConverter, aFs); + + TUint8 count = (TUint8) iNotifications->Count(); + if (count > KMaxNumberOfNotifications) + { + User::Leave(KErrArgument); + } + + *aCurrentPtr = (count & KSmsNotificationBitMask); + aCurrentPtr++; + + TInt16 spaceAlreadyAllocated = 0; // handle architectures whose address space increments and whose address space decrements. + (aCurrentPtr > startPtr) ? (spaceAlreadyAllocated = aCurrentPtr - startPtr) : (spaceAlreadyAllocated = startPtr - aCurrentPtr); + + TInt16 remainingSize = (TInt16)(CEnhancedVoiceMailNotification::KSmsMaxEnhancedVoiceMailSize - spaceAlreadyAllocated); + for (TUint i = 0; i < count; i++) + { + remainingSize -= (TInt16)(*iNotifications)[i]->SizeL(aCharacterSetConverter,aFs); + if (remainingSize < 0) + { + User::Leave(KErrArgument); + } + + aCurrentPtr = (*iNotifications)[i]->EncodeL(aCurrentPtr, aCharacterSetConverter, aFs); + } + + return aCurrentPtr; + } // CEnhancedVoiceMailNotification::EncodeL + + +void CEnhancedVoiceMailNotification::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) + { + LOGGSMU1("CEnhancedVoiceMailNotification::DecodeL"); + + CEnhancedVoiceMailBoxInformation::DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs); + + TUint8 numberOfNotifications = (aVoiceMailInfo.GetL() & KSmsNotificationBitMask); + + if (iExtensionIndicator) + { + TUint8 extensionLength = aVoiceMailInfo.GetL(); + aVoiceMailInfo.Inc(extensionLength); + } + + for (TUint8 i = 0; i < numberOfNotifications; i++) + { + CVoiceMailNotification* voiceMailNotification = CVoiceMailNotification::NewL(); + CleanupStack::PushL(voiceMailNotification); + voiceMailNotification->DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs); + iNotifications->AppendL(voiceMailNotification); + CleanupStack::Pop(voiceMailNotification); + } + } // CEnhancedVoiceMailNotification::DecodeL + + +/** + * @publishedAll + * + * Sets the message ID of the specific Voice Mail message + * whose deletion is being confirmed. + * + * @param aMessageId + * The message ID of the specific voice mail message whose deletion + * is being confirmed. + * + * @capability None + */ +EXPORT_C void CVoiceMailDeletion::SetMessageId(TUint16 aMessageId) + { + LOGGSMU1("CVoiceMailDeletion::SetMessageId()"); + + iMessageId=aMessageId; + } // CVoiceMailDeletion::SetMessageId + + +/** + * @publishedAll + * + * Retrieves the message ID of the Voice Mail message + * whose deletion is being confirmed, range 0 to 65535. + * + * @return + * The message ID of the Voice Mail message whose deletion + * is being confirmed, range 0 to 65535. + * + * @capability None + */ +EXPORT_C TUint16 CVoiceMailDeletion::MessageId() const + { + LOGGSMU1("CVoiceMailDeletion::MessageId()"); + + return iMessageId; + } // CVoiceMailDeletion::MessageId + + +/** + * @publishedAll + * + * Indicates whether the voice mail deletion contains extension bytes. + * + * @return + * True if the voice mail deletion contains extension bytes. + * False otherwise. + * + * @capability None + */ +EXPORT_C TBool CVoiceMailDeletion::MessageExtensionIndication() const + { + LOGGSMU1("CVoiceMailDeletion::MessageExtensionIndication()"); + + return iExtensionIndicator; + } // CVoiceMailDeletion::MessageExtensionIndication + + +TUint8 CVoiceMailDeletion::SizeL() + { + LOGGSMU1("CVoiceMailDeletion::SizeL()"); + + const TUint8 KSizeOfVoiceMailDeletion = 3; + return KSizeOfVoiceMailDeletion; + } // CVoiceMailDeletion::SizeL + + +TUint8* CVoiceMailDeletion::EncodeL(TUint8* aPtr) const + { + // When changes are made which affect the + // number of bytes encoded, this should be + // reflected in VoiceMailDeletion::SizeL() + LOGGSMU1("CVoiceMailDeletion::EncodeL"); + + *aPtr = (TUint8) (iMessageId >> 8); + aPtr++; + *aPtr = (TUint8) iMessageId; + aPtr++; + *aPtr = ((TUint8) iExtensionIndicator) << 7; + aPtr++; + return aPtr; + } // CVoiceMailDeletion::EncodeL + + +void CVoiceMailDeletion::DecodeL(TGsmuLex8& aVoiceMailInfo) + { + LOGGSMU1("CVoiceMailDeletion::DecodeL"); + + iMessageId = (((TUint16) aVoiceMailInfo.GetL()) << 8) + + ((TUint16) aVoiceMailInfo.GetL()); + iExtensionIndicator = (aVoiceMailInfo.GetL() >> 7); + + if (iExtensionIndicator) + { + TUint8 extensionLength = aVoiceMailInfo.GetL(); + aVoiceMailInfo.Inc(extensionLength); + } + } // CVoiceMailDeletion::DecodeL + + +CVoiceMailDeletion::CVoiceMailDeletion() + { + iMessageId = 0; + iExtensionIndicator = EFalse; + } // CVoiceMailDeletion::CVoiceMailDeletion + + +/** + * @internalComponent + * + * Prevent clients from using the copy constructor by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +CVoiceMailDeletion::CVoiceMailDeletion(const CVoiceMailDeletion&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CVoiceMailDeletion::CVoiceMailDeletion"); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the equality operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +TBool CVoiceMailDeletion::operator==(const CVoiceMailDeletion&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CVoiceMailDeletion::operator=="); + Panic(KGsmuPanicMethodBodyNotImplemented); + return EFalse; + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the assignment operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +void CVoiceMailDeletion::operator=(const CVoiceMailDeletion&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CVoiceMailDeletion::operator="); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +/** + * @publishedAll + * + * Class destructor. + * + * @capability None + */ +EXPORT_C CVoiceMailDeletion::~CVoiceMailDeletion() + { + LOGGSMU1("CVoiceMailDeletion::~CVoiceMailDeletion"); + + delete iExtension; + } // CVoiceMailDeletion::operator + + +void CVoiceMailDeletion::ConstructL() + { + LOGGSMU1("CVoiceMailDeletion::ConstructL()"); + + NewBufferL(0); + } // CVoiceMailDeletion::ConstructL + + +void CVoiceMailDeletion::NewBufferL(TInt aLength) + { + LOGGSMU1("CVoiceMailDeletion::NewBufferL()"); + + HBufC* buffer=HBufC::NewL(aLength); + delete iExtension; + iExtension=buffer; + iExtension->Des().SetLength(aLength); + iExtension->Des().FillZ(); + } // CVoiceMailDeletion::NewBufferL + + +/** + * @publishedAll + * + * Class constructor + * + * @capability None + */ +EXPORT_C CVoiceMailDeletion* CVoiceMailDeletion::NewL() + { + LOGGSMU1("CVoiceMailDeletion::NewL()"); + + CVoiceMailDeletion* voiceMailDeletion=new(ELeave) CVoiceMailDeletion(); + CleanupStack::PushL(voiceMailDeletion); + voiceMailDeletion->ConstructL(); + CleanupStack::Pop(voiceMailDeletion); + return voiceMailDeletion; + } // CVoiceMailDeletion::NewL + + +/* +void CVoiceMailDeletion::SetExtension(TDesC& aExtension) + { + LOGGSMU1("CVoiceMailDeletion::SetExtension()"); + + TInt length=aExtension.Length(); + NewBufferL(length); + iExtension->Des().Copy(aExtension); + } // CVoiceMailDeletion::SetExtension + + +TPtrC CVoiceMailDeletion::Extension() const + { + LOGGSMU1("CVoiceMailDeletion::Extension()"); + + TPtrC ptr; + if (iExtension) + ptr.Set(iExtension->Des()); + return ptr; + }*/ + + +void CEnhancedVoiceMailDeleteConfirmations::NewExtensionL(TInt aLength) + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NewExtensionL()"); + + HBufC* buffer=HBufC::NewL(aLength); + delete iExtension; + iExtension=buffer; + iExtension->Des().SetLength(aLength); + iExtension->Des().FillZ(); + } // CEnhancedVoiceMailDeleteConfirmations::NewExtensionL + + +CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations() : CEnhancedVoiceMailBoxInformation(EGsmSmsVoiceMailDeleteConfirmation) + { + //NOP + } // CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations + + +/** + * @publishedAll + * + * Class destructor + * + * @capability None + */ +EXPORT_C CEnhancedVoiceMailDeleteConfirmations::~CEnhancedVoiceMailDeleteConfirmations() + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::~CEnhancedVoiceMailDeleteConfirmations"); + + delete iExtension; + iVoiceMailDeletions->ResetAndDestroy(); + iVoiceMailDeletions->Close(); + delete iVoiceMailDeletions; + } // CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations + + +/** + * @internalComponent + * + * Prevent clients from using the copy constructor by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations(const CEnhancedVoiceMailDeleteConfirmations&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::CEnhancedVoiceMailDeleteConfirmations"); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the equality operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +TBool CEnhancedVoiceMailDeleteConfirmations::operator==(const CEnhancedVoiceMailDeleteConfirmations&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::operator=="); + Panic(KGsmuPanicMethodBodyNotImplemented); + return EFalse; + BULLSEYE_RESTORE + } + +/** + * @internalComponent + * + * Prevent clients from using the assignment operator by including it in the class definition + * but making it protected and not exporting it. + * + * @capability None + */ +void CEnhancedVoiceMailDeleteConfirmations::operator=(const CEnhancedVoiceMailDeleteConfirmations&) + { + // Ignore in code coverage - not intended to be used + BULLSEYE_OFF + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::operator="); + Panic(KGsmuPanicMethodBodyNotImplemented); + BULLSEYE_RESTORE + } + +void CEnhancedVoiceMailDeleteConfirmations::ConstructL() + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::ConstructL()"); + + NewExtensionL(0); + + iVoiceMailDeletions = new (ELeave) RPointerArray(15); + } // CEnhancedVoiceMailDeleteConfirmations::ConstructL + + +/** + * @publishedAll + * + * Class constructor + * + * @capability None + */ +EXPORT_C CEnhancedVoiceMailDeleteConfirmations* CEnhancedVoiceMailDeleteConfirmations::NewL() + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NewL()"); + + CEnhancedVoiceMailDeleteConfirmations* aCEnhancedVoiceMailDeleteConfirmations=new(ELeave) CEnhancedVoiceMailDeleteConfirmations(); + CleanupStack::PushL(aCEnhancedVoiceMailDeleteConfirmations); + aCEnhancedVoiceMailDeleteConfirmations->CEnhancedVoiceMailBoxInformation::ConstructL(); + aCEnhancedVoiceMailDeleteConfirmations->ConstructL(); + CleanupStack::Pop(aCEnhancedVoiceMailDeleteConfirmations); + return aCEnhancedVoiceMailDeleteConfirmations; + } // CEnhancedVoiceMailDeleteConfirmations::NewL + + +/** + * @publishedAll + * + * Indicates the number of message IDs that follow in this IE. + * + * @return + * The number of message IDs that follow. + * + * @capability None + */ +EXPORT_C TUint8 CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes() + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes()"); + + return iVoiceMailDeletions->Count(); + } // CEnhancedVoiceMailDeleteConfirmations::NumberOfDeletes + + +/** + * @publishedAll + * + * Provides a reference to the collection that is used to contain the Voice Mail Deletion + * notifications. Up to 31 instances of CVoiceMailDeletion can be stored. If more than + * 31 instances are added, the CEnhancedVoiceMailDeleteConfirmations will not be added to + * the CSmsMessage. + * + * @return + * A reference to the collection that is used to contain the Voice Mail Deletion + * notifications. + * + * @capability None + */ +EXPORT_C RPointerArray& CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions() + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions()"); + + return *iVoiceMailDeletions; + } // CEnhancedVoiceMailDeleteConfirmations::GetVoiceMailDeletions + + +/* +void CEnhancedVoiceMailDeleteConfirmations::SetExtension(TDesC& aExtension) + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::SetExtension()"); + + TInt length=aExtension.Length(); + NewBufferL(length); + iExtension->Des().Copy(aExtension); + } // CEnhancedVoiceMailDeleteConfirmations::SetExtension + + +TPtrC CEnhancedVoiceMailDeleteConfirmations::Extension() const + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::Extension()"); + + TPtrC ptr; + if (iExtension) + { + ptr.Set(iExtension->Des()); + } + return ptr; + }*/ + + +TUint8* CEnhancedVoiceMailDeleteConfirmations::EncodeL(TUint8* aCurrentPtr, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) const + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::EncodeL"); + + TUint8* startPtr = aCurrentPtr; + + aCurrentPtr = CEnhancedVoiceMailBoxInformation::EncodeL(aCurrentPtr, aCharacterSetConverter, aFs); + + TUint8 count = ((TUint8)iVoiceMailDeletions->Count()); + + if (count > KMaxNumberOfNotifications) + { + User::Leave(KErrArgument); + } + + *aCurrentPtr= (count & KSmsNotificationBitMask); + aCurrentPtr++; + + TInt16 spaceAlreadyAllocated; // handle architectures whose address space increments and whose address space decrements. + (aCurrentPtr > startPtr) ? (spaceAlreadyAllocated = aCurrentPtr - startPtr) : (spaceAlreadyAllocated = startPtr - aCurrentPtr); + + // allow space for id and length bytes + TInt16 remainingSize = (TInt16)(CEnhancedVoiceMailBoxInformation::KSmsMaxEnhancedVoiceMailSize - spaceAlreadyAllocated); + + for (TUint i = 0; i < count; i++) + { + remainingSize -= (TInt16)(*iVoiceMailDeletions)[i]->SizeL(); + if (remainingSize < 0) + { + User::Leave(KErrArgument); + } + + aCurrentPtr = (*iVoiceMailDeletions)[i]->EncodeL(aCurrentPtr); + } + + return aCurrentPtr; + } // CEnhancedVoiceMailDeleteConfirmations::EncodeL + + +void CEnhancedVoiceMailDeleteConfirmations::DecodeL(TGsmuLex8& aVoiceMailInfo, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) + { + LOGGSMU1("CEnhancedVoiceMailDeleteConfirmations::DecodeL"); + + CEnhancedVoiceMailBoxInformation::DecodeL(aVoiceMailInfo, aCharacterSetConverter, aFs); + + TUint numberOfVMDeletions = (aVoiceMailInfo.GetL() & KSmsNotificationBitMask); + + if (iExtensionIndicator) + { + TUint8 extensionLength = aVoiceMailInfo.GetL(); + aVoiceMailInfo.Inc(extensionLength); + } + + for (TUint8 i = 0; i < numberOfVMDeletions; i++) + { + // Create a Voice Mail Deletion + CVoiceMailDeletion* voiceMailDeletion = CVoiceMailDeletion::NewL(); + CleanupStack::PushL(voiceMailDeletion); + voiceMailDeletion->DecodeL(aVoiceMailInfo); + CleanupStack::Pop(voiceMailDeletion); + iVoiceMailDeletions->Append(voiceMailDeletion); + } + } // CEnhancedVoiceMailDeleteConfirmations::DecodeL