--- 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 <gsmuelem.h>
-#include <gsmumsg.h>
-#include "Gsmumain.h"
-#include <gsmusar.h>
-#include "gsmupriv.h"
-#include <s32strm.h>
-#include <etelmm.h>
-#include <gsmuetel.h>
-#include <exterror.h>
-#include <emsinformationelement.h>
-#include <emsformatie.h>
-#include <charconv.h>
-
-/**
- * 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<TUint8>(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<TUint8>(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<count); i++)
- if (InformationElement(i).Identifier()==aIdentifier)
- {
- found=ETrue;
- aIndex=i;
- }
- return found;
- } // CSmsCommandData::InformationElementIndex
-
-
-void CSmsCommandData::AddInformationElementL(const TSmsId aIdentifier,const TDesC8& aData)
- {
- LOGGSMU1("CSmsCommandData::AddInformationElementL()");
-
- //
- // Currently there is no restriction on how many instances of an information element can be
- // placed in the collection.
- // No restriction will be placed on the number of Special SMS Message Indications that can be
- // added in order to maintain FC.
- // (cf CSmsUserData::AddInformationElementL(const TSmsId aIdentifier,const TDesC8& aData);
- //
- CSmsInformationElement* informationelement=CSmsInformationElement::NewL(aIdentifier,aData);
- CleanupStack::PushL(informationelement);
- iInformationElementArray.AppendL(informationelement);
- CleanupStack::Pop();
- if (NumInformationElements()>=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; i<NumInformationElements(); i++)
- {
- aPtr=iInformationElementArray[i]->EncodeL(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()<headerLength)
- {
- CSmsInformationElement* informationElement=CSmsInformationElement::NewL();
- CleanupStack::PushL(informationElement);
- informationElement->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<numInformationElements; i++)
- {
- CSmsInformationElement* informationElement=CSmsInformationElement::NewL();
- CleanupStack::PushL(informationElement);
- aStream >> *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; i<numInformationElements; i++)
- aStream << *iInformationElementArray[i];
- aStream << *iBuffer;
- } // CSmsCommandData::ExternalizeL
-
-
-CSmsCommandData::CSmsCommandData(TSmsFirstOctet& aFirstOctet):
- iFirstOctet(aFirstOctet),
- iInformationElementArray(8)
- {
- } // CSmsCommandData::CSmsCommandData
-
-
-TInt CSmsCommandData::HeaderLength() const
- {
- LOGGSMU1("CSmsCommandData::HeaderLength()");
-
- TInt headerLength=0;
- for (TInt i=0; i<NumInformationElements(); i++)
- headerLength+=iInformationElementArray[i]->Length();
- 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<nativeCharactersLength;i++)
- {
- outputPtr[2*i]=(TUint8)(aNativeCharacters[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; i<charCount; i++)
- {
- outputPtr[i]=(TText)(aUDElements[2*i]<<8);
- outputPtr[i]=(TText)(outputPtr[i]+(aUDElements[2*i+1]));
- }
- iUnconvertedUDElementsPtr.Zero();
- return outputPtr;
- }
- else
- {
- PrepareForConversionToNativeL(aEncoding);
-
- // Create input buffer with unconverted characters prepended
- TInt newInputLength=iUnconvertedUDElementsPtr.Length()+aUDElements.Length();
- iUnconvertedUDElementsPtr.Set(CheckAllocBufferL(&iUnconvertedUDElements,newInputLength,iUnconvertedUDElementsPtr.Length()));
- iUnconvertedUDElementsPtr.Append(aUDElements);
-
- // Ensure buffer is at least the length of the input buffer
- TPtr outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,iUnconvertedUDElementsPtr.Length(),0);
-
- TInt retryCount=0;
- TInt unconvertedCount=iUnconvertedUDElementsPtr.Length();
- TInt state=CCnvCharacterSetConverter::KStateDefault;
- while (unconvertedCount)
- {
- // Get a pointer to unfilled area of output buffer
- TPtr16 fillPtr((TUint16*)outputPtr.Ptr()+outputPtr.Length(),0,outputPtr.MaxLength()-outputPtr.Length());
- // Try the conversion & get number of unconverted characters
- TInt newUnconvertedCount=iCharacterSetConverter.ConvertToUnicode(fillPtr,iUnconvertedUDElementsPtr,state);
- if (newUnconvertedCount<0)
- break;
- // Update original buffer length & check retry count
- outputPtr.SetLength(outputPtr.Length()+fillPtr.Length());
- if (newUnconvertedCount==unconvertedCount)
- {
- if (++retryCount>KMaxSmsAlphabetConversionRetries)
- {
- __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()<aMaxLength)
- {
- *aBuffer=(*aBuffer)->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()<aMaxLength)
- {
- *aBuffer=(*aBuffer)->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; (i<length) && (parsedlength<maxparsedlength); i++)
- {
- TText ch=iBuffer->Des()[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<KSmsAddressMaxAddressLength> 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; i<length; i++)
- {
- if ((i%2)==0) // even
- {
- switch(parsedaddress.iTelNumber[i])
- {
- case '*':
- {
- octet=10; // 1010 as a binary, according to 23.040 …
- }
- break;
-
- case '#':
- {
- octet=11; // 1011 as a binary, according to 23.040…
- }
- break;
-
- case 'a':
- {
- octet=12; // 1100 as a binary, according to 23.040...
- }
- break;
-
- case 'b':
- {
- octet=13; // 1101 as a binary, according to 23.040…
- }
- break;
-
- case 'c':
- {
- octet=14; // 1110 as a binary, according to 23.040…
- }
- break;
-
- default:
- octet=(parsedaddress.iTelNumber[i])-'0';
- break;
- }
- }
- else
- {
- TInt tempOctet = 0;
-
- switch(parsedaddress.iTelNumber[i])
- {
- case '*':
- {
- tempOctet=10; // 1010 as a binary, according to 23.040…
- }
- break;
-
- case '#':
- {
- tempOctet=11; // 1011 as a binary, according to 23.040…
- }
- break;
-
- case 'a':
- {
- tempOctet=12; // 1100 as a binary, according to 23.040…
- }
- break;
-
- case 'b':
- {
- tempOctet=13; // 1101 as a binary, according to 23.040…
- }
- break;
-
- case 'c':
- {
- tempOctet=14; // 1110 as a binary, according to 23.040…
- }
- break;
-
- default:
- tempOctet=(parsedaddress.iTelNumber[i])-'0';
- break;
- }
- octet=octet|tempOctet<<4;
- aPtr=octet.EncodeL(aPtr);
- }
-
- } // end for loop
-
- if (length%2) // odd number of semioctets
- {
- octet=octet|0xF0;
- aPtr=octet.EncodeL(aPtr);
- }
-
- } // end default case
- }
- return aPtr;
- }
-
-
-void CSmsAddress::DecodeL(TGsmuLex8& aPdu)
- {
- TSmsOctet length; //represents the number of valid semi-octets
- length.DecodeL(aPdu);
- iTypeOfAddress.DecodeL(aPdu);
-
- switch (iTypeOfAddress.TON())
- {
- case EGsmSmsTONAlphaNumeric:
- {
- const TUint cphs1 = aPdu.GetL();
- const TUint cphs2 = aPdu.GetL();
- aPdu.UnGet();
- aPdu.UnGet();
-
- const TPtrC8 remainder(aPdu.Remainder());
- // we assume that it is a cphs message waiting indicator
- // we might want to do further tests tobe sure that it is a CPHS message
- if( (length==4)
- && ((cphs1 & 0x7E) == 0x10) // x001 000x constant value
- && ((cphs2 & 0x7E) == 0x00) // x000 000x constant value
- )
- {
- TGsmSmsTelNumber parsedaddress;
- parsedaddress.iTelNumber.SetLength(length);
- //Copy the two bytes of the cphs message waiting address into the parsed address
- parsedaddress.iTelNumber[0]=(TUint8)length;
- parsedaddress.iTelNumber[1]= (TUint8)iTypeOfAddress;
- parsedaddress.iTelNumber[2]= (TUint8)aPdu.GetL();
- parsedaddress.iTelNumber[3]= (TUint8)aPdu.GetL();
- DoSetParsedAddressL(parsedaddress.iTelNumber);
- }
- else if(length==11 && remainder.Left(6).CompareF(KMOSES) ==KErrNone ) //check for MOSES
- {
- DoSetParsedAddressL(KNETWORK);
- aPdu.IncL(6);
- }
- else
- {
- // Encoded length is number of semi-octets used to store address using
- // 7-bit char set - determine number of user data units required
- const TInt numUDUnits=length*4/7;
- // Unpack the data - assume max converted length twice the unconverted length
- // VEP Why this assumption, the length will be doubled at the client because of that??
- // EXT-568BMW
- // Fix is not to multiply by 2
- //NewBufferL(2*numUDUnits);
- NewBufferL(numUDUnits);
- TPtr unpackedPtr((TText*)iBuffer->Des().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<length; i++)
- {
- if ((i%2)==0) // even
- {
- TUint8 tempOctet = 0;
- octet.DecodeL(aPdu);
- tempOctet = (TUint8)octet&0x0F; // four topmost bits set to zero
-
- 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');
- break;
- }
- }
- else
- {
- TUint8 tempOctet = 0;
- octet&0xF0; // four least significant bits…
- tempOctet = (TUint8)octet>>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<TSmsInformationElementIdentifier>((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<TSmsInformationElementIdentifier>((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<count); i++)
- if (InformationElement(i).Identifier()==aIdentifier)
- {
- found=ETrue;
- aIndex=i;
- }
- return found;
- } // CSmsUserData::InformationElementIndex
-
-
-/**
- * Gets the last 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 last 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::InformationElementLastIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,TInt& aIndex) const
- {
- LOGGSMU1("CSmsUserData::InformationElementLastIndex()");
-
- TBool found=EFalse;
- TInt count=NumInformationElements();
- for (TInt i=count-1; (!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<TInt>& aIndices) const
- {
- LOGGSMU1("CSmsUserData::InformationElementIndicesL()");
-
- aIndices.Reset();
-
- TInt count=NumInformationElements();
- for (TInt i=0; i<count; i++)
- {
- if (InformationElement(i).Identifier()==aIdentifier)
- {
- aIndices.AppendL(i);
- }
- }
- } // CSmsUserData::InformationElementIndicesL
-
-
-/**
- * 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 An EMS Information Element
- */
-TBool CSmsUserData::EmsInformationElementWillFitL(CEmsInformationElement* aIe,CSmsEMSBufferSegmenter& aSeg,TUint& aCharsAddedToCurrentPDU)
- {
- LOGGSMU1("CSmsUserData::EmsInformationElementWillFitL()");
-
- // Before using an EmsInformationElement polymorphically as an SmsIE,
- // we need to make sure that the IE has been encoded
- aIe->EncodeInformationElementL();
- 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<count; i++)
- {
- if (InformationElement(i).Identifier()==aIdentifier)
- {
- TSmsInformationElementCategories::TInformationElementCategory category;
-
- if (TSmsInformationElementCategories::GetCategoryDefinition(aIdentifier, category) == EFalse)
- {
- User::Leave(KErrArgument);
- }
-
- switch (category)
- {
- case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUMultipleInstancesPerPDU:
- {
- if (InformationElement(i).Identifier() == CSmsInformationElement::ESmsIEISpecialSMSMessageIndication)
- {
- LOGGSMU3("CSmsUserData::AddInformationElementL1 category = %d, identifier = %d",category,aIdentifier);
-
- //if Msg type is the same, swap with the most recent value
- if ((InformationElement(i).Data()[0] & ((TUint8) EGsmSmsSpecialMessageIndicationTypeMask)) ==
- (aData[0] & ((TUint8) EGsmSmsSpecialMessageIndicationTypeMask)))
- {
- User::Leave(KErrAlreadyExists);
- }
- }
- else
- {
- LOGGSMU4("CSmsUserData::AddInformationElementL3 category = %d, identifier = %d, data = %S",category,aIdentifier, &aData);
- User::Leave(KErrArgument);
- }
- break;
- }
- case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUAndWithIdenticalValues:
- case TSmsInformationElementCategories::ECtrlMandatoryIn1stPDUOnly:
- case TSmsInformationElementCategories::ECtrlSingleInstanceOnly:
- {
- LOGGSMU3("CSmsUserData::AddInformationElementL4 category = %d, identifier = %d",category,aIdentifier);
- User::Leave(KErrAlreadyExists);
- break;
- }
- case TSmsInformationElementCategories::ECtrlMultipleInstancesAllowed:
- {
- LOGGSMU3("CSmsUserData::AddInformationElementL5 category = %d, identifier = %d",category,aIdentifier);
- break;
- }
- case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUButWithValueSpecificToPDU:
- {
- LOGGSMU3("CSmsUserData::AddInformationElementL6 category = %d, identifier = %d",category,aIdentifier);
- User::Leave(KErrAlreadyExists);
- // currently the email header is updated in:
- // void CSmsMessage::DecodeBufferL(CArrayPtr<CSmsPDU>& 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; i<numInformationElements; i++)
- aPtr=iInformationElementArray[i]->EncodeL(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()<headerLength)
- {
- CSmsInformationElement* informationelement=CSmsInformationElement::NewL();
- CleanupStack::PushL(informationelement);
- informationelement->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<numiformationelements; i++)
- {
- CSmsInformationElement* informationelement=CSmsInformationElement::NewL();
- CleanupStack::PushL(informationelement);
- aStream >> *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; i<numiformationelements; i++)
- aStream << *iInformationElementArray[i];
- aStream << *iBody;
- } // CSmsUserData::ExternalizeL
-
-
-CSmsUserData::CSmsUserData(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsFirstOctet& aFirstOctet,const TSmsDataCodingScheme& aDataCodingScheme):
- iCharacterSetConverter(aCharacterSetConverter),
- iFs(aFs),
- iFirstOctet(aFirstOctet),
- iDataCodingScheme(aDataCodingScheme),
- iInformationElementArray(8)
- {
- } // CSmsUserData::CSmsUserData
-
-
-void CSmsUserData::ConstructL()
- {
- LOGGSMU1("CSmsUserData::ConstructL()");
-
- NewBodyL(0);
- } // CSmsUserData::ConstructL
-
-
-/**
- * Duplicates this CSmsUserData object.
- *
- * @return Pointer to the newly created CSmsUserData object.
- */
-CSmsUserData* CSmsUserData::DuplicateL(TSmsFirstOctet& aFirstOctet,
- const TSmsDataCodingScheme& aDataCodingScheme) const
- {
- LOGGSMU1("CSmsUserData::DuplicateL()");
-
- CSmsUserData* userdata = CSmsUserData::NewL(iCharacterSetConverter, iFs,
- aFirstOctet, aDataCodingScheme);
- CleanupStack::PushL(userdata);
-
- userdata->SetBodyL(Body());
-
- for (TInt ie = 0; ie < iInformationElementArray.Count(); ie++)
- {
- CSmsInformationElement* oldIE = iInformationElementArray[ie];
-
- if (CEmsFactory::Supported(oldIE->Identifier()))
- {
- CEmsInformationElement* newIE = static_cast<CEmsInformationElement*>(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; i<numinformationelements; i++)
- headerlength+=iInformationElementArray[i]->Length();
- 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; (i<length) && (parsedlength<maxparsedlength); i++)
- {
- TText ch=iAccessAddress->Des()[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<CSmsAddress::KSmsAddressMaxAddressLength> 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; (i<length) && (parsedlength<maxparsedlength); i++)
- {
- TText ch=iCallingLineIdentity->Des()[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<CSmsAddress::KSmsAddressMaxAddressLength> 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<CVoiceMailNotification>& 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<CVoiceMailNotification>(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<CVoiceMailDeletion>(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<CVoiceMailDeletion>& 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 <gsmuelem.h>
+#include <gsmumsg.h>
+#include "Gsmumain.h"
+#include <gsmusar.h>
+#include "gsmupriv.h"
+#include <s32strm.h>
+#include <etelmm.h>
+#include <gsmuetel.h>
+#include <exterror.h>
+#include <emsinformationelement.h>
+#include <emsformatie.h>
+#include <charconv.h>
+
+/**
+ * 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<TUint8>(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<TUint8>(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<count); i++)
+ if (InformationElement(i).Identifier()==aIdentifier)
+ {
+ found=ETrue;
+ aIndex=i;
+ }
+ return found;
+ } // CSmsCommandData::InformationElementIndex
+
+
+void CSmsCommandData::AddInformationElementL(const TSmsId aIdentifier,const TDesC8& aData)
+ {
+ LOGGSMU1("CSmsCommandData::AddInformationElementL()");
+
+ //
+ // Currently there is no restriction on how many instances of an information element can be
+ // placed in the collection.
+ // No restriction will be placed on the number of Special SMS Message Indications that can be
+ // added in order to maintain FC.
+ // (cf CSmsUserData::AddInformationElementL(const TSmsId aIdentifier,const TDesC8& aData);
+ //
+ CSmsInformationElement* informationelement=CSmsInformationElement::NewL(aIdentifier,aData);
+ CleanupStack::PushL(informationelement);
+ iInformationElementArray.AppendL(informationelement);
+ CleanupStack::Pop();
+ if (NumInformationElements()>=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; i<NumInformationElements(); i++)
+ {
+ aPtr=iInformationElementArray[i]->EncodeL(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()<headerLength)
+ {
+ CSmsInformationElement* informationElement=CSmsInformationElement::NewL();
+ CleanupStack::PushL(informationElement);
+ informationElement->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<numInformationElements; i++)
+ {
+ CSmsInformationElement* informationElement=CSmsInformationElement::NewL();
+ CleanupStack::PushL(informationElement);
+ aStream >> *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; i<numInformationElements; i++)
+ aStream << *iInformationElementArray[i];
+ aStream << *iBuffer;
+ } // CSmsCommandData::ExternalizeL
+
+
+CSmsCommandData::CSmsCommandData(TSmsFirstOctet& aFirstOctet):
+ iFirstOctet(aFirstOctet),
+ iInformationElementArray(8)
+ {
+ } // CSmsCommandData::CSmsCommandData
+
+
+TInt CSmsCommandData::HeaderLength() const
+ {
+ LOGGSMU1("CSmsCommandData::HeaderLength()");
+
+ TInt headerLength=0;
+ for (TInt i=0; i<NumInformationElements(); i++)
+ headerLength+=iInformationElementArray[i]->Length();
+ 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<nativeCharactersLength;i++)
+ {
+ outputPtr[2*i]=(TUint8)(aNativeCharacters[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; i<charCount; i++)
+ {
+ outputPtr[i]=(TText)(aUDElements[2*i]<<8);
+ outputPtr[i]=(TText)(outputPtr[i]+(aUDElements[2*i+1]));
+ }
+ iUnconvertedUDElementsPtr.Zero();
+ return outputPtr;
+ }
+ else
+ {
+ PrepareForConversionToNativeL(aEncoding);
+
+ // Create input buffer with unconverted characters prepended
+ TInt newInputLength=iUnconvertedUDElementsPtr.Length()+aUDElements.Length();
+ iUnconvertedUDElementsPtr.Set(CheckAllocBufferL(&iUnconvertedUDElements,newInputLength,iUnconvertedUDElementsPtr.Length()));
+ iUnconvertedUDElementsPtr.Append(aUDElements);
+
+ // Ensure buffer is at least the length of the input buffer
+ TPtr outputPtr=CheckAllocBufferL(&iConvertedNativeCharacters,iUnconvertedUDElementsPtr.Length(),0);
+
+ TInt retryCount=0;
+ TInt unconvertedCount=iUnconvertedUDElementsPtr.Length();
+ TInt state=CCnvCharacterSetConverter::KStateDefault;
+ while (unconvertedCount)
+ {
+ // Get a pointer to unfilled area of output buffer
+ TPtr16 fillPtr((TUint16*)outputPtr.Ptr()+outputPtr.Length(),0,outputPtr.MaxLength()-outputPtr.Length());
+ // Try the conversion & get number of unconverted characters
+ TInt newUnconvertedCount=iCharacterSetConverter.ConvertToUnicode(fillPtr,iUnconvertedUDElementsPtr,state);
+ if (newUnconvertedCount<0)
+ break;
+ // Update original buffer length & check retry count
+ outputPtr.SetLength(outputPtr.Length()+fillPtr.Length());
+ if (newUnconvertedCount==unconvertedCount)
+ {
+ if (++retryCount>KMaxSmsAlphabetConversionRetries)
+ {
+ __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()<aMaxLength)
+ {
+ *aBuffer=(*aBuffer)->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()<aMaxLength)
+ {
+ *aBuffer=(*aBuffer)->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; (i<length) && (parsedlength<maxparsedlength); i++)
+ {
+ TText ch=iBuffer->Des()[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<KSmsAddressMaxAddressLength> 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; i<length; i++)
+ {
+ if ((i%2)==0) // even
+ {
+ switch(parsedaddress.iTelNumber[i])
+ {
+ case '*':
+ {
+ octet=10; // 1010 as a binary, according to 23.040 …
+ }
+ break;
+
+ case '#':
+ {
+ octet=11; // 1011 as a binary, according to 23.040…
+ }
+ break;
+
+ case 'a':
+ {
+ octet=12; // 1100 as a binary, according to 23.040...
+ }
+ break;
+
+ case 'b':
+ {
+ octet=13; // 1101 as a binary, according to 23.040…
+ }
+ break;
+
+ case 'c':
+ {
+ octet=14; // 1110 as a binary, according to 23.040…
+ }
+ break;
+
+ default:
+ octet=(parsedaddress.iTelNumber[i])-'0';
+ break;
+ }
+ }
+ else
+ {
+ TInt tempOctet = 0;
+
+ switch(parsedaddress.iTelNumber[i])
+ {
+ case '*':
+ {
+ tempOctet=10; // 1010 as a binary, according to 23.040…
+ }
+ break;
+
+ case '#':
+ {
+ tempOctet=11; // 1011 as a binary, according to 23.040…
+ }
+ break;
+
+ case 'a':
+ {
+ tempOctet=12; // 1100 as a binary, according to 23.040…
+ }
+ break;
+
+ case 'b':
+ {
+ tempOctet=13; // 1101 as a binary, according to 23.040…
+ }
+ break;
+
+ case 'c':
+ {
+ tempOctet=14; // 1110 as a binary, according to 23.040…
+ }
+ break;
+
+ default:
+ tempOctet=(parsedaddress.iTelNumber[i])-'0';
+ break;
+ }
+ octet=octet|tempOctet<<4;
+ aPtr=octet.EncodeL(aPtr);
+ }
+
+ } // end for loop
+
+ if (length%2) // odd number of semioctets
+ {
+ octet=octet|0xF0;
+ aPtr=octet.EncodeL(aPtr);
+ }
+
+ } // end default case
+ }
+ return aPtr;
+ }
+
+
+void CSmsAddress::DecodeL(TGsmuLex8& aPdu)
+ {
+ TSmsOctet length; //represents the number of valid semi-octets
+ length.DecodeL(aPdu);
+ iTypeOfAddress.DecodeL(aPdu);
+
+ switch (iTypeOfAddress.TON())
+ {
+ case EGsmSmsTONAlphaNumeric:
+ {
+ const TUint cphs1 = aPdu.GetL();
+ const TUint cphs2 = aPdu.GetL();
+ aPdu.UnGet();
+ aPdu.UnGet();
+
+ const TPtrC8 remainder(aPdu.Remainder());
+ // we assume that it is a cphs message waiting indicator
+ // we might want to do further tests tobe sure that it is a CPHS message
+ if( (length==4)
+ && ((cphs1 & 0x7E) == 0x10) // x001 000x constant value
+ && ((cphs2 & 0x7E) == 0x00) // x000 000x constant value
+ )
+ {
+ TGsmSmsTelNumber parsedaddress;
+ parsedaddress.iTelNumber.SetLength(length);
+ //Copy the two bytes of the cphs message waiting address into the parsed address
+ parsedaddress.iTelNumber[0]=(TUint8)length;
+ parsedaddress.iTelNumber[1]= (TUint8)iTypeOfAddress;
+ parsedaddress.iTelNumber[2]= (TUint8)aPdu.GetL();
+ parsedaddress.iTelNumber[3]= (TUint8)aPdu.GetL();
+ DoSetParsedAddressL(parsedaddress.iTelNumber);
+ }
+ else if(length==11 && remainder.Left(6).CompareF(KMOSES) ==KErrNone ) //check for MOSES
+ {
+ DoSetParsedAddressL(KNETWORK);
+ aPdu.IncL(6);
+ }
+ else
+ {
+ // Encoded length is number of semi-octets used to store address using
+ // 7-bit char set - determine number of user data units required
+ const TInt numUDUnits=length*4/7;
+ // Unpack the data - assume max converted length twice the unconverted length
+ // VEP Why this assumption, the length will be doubled at the client because of that??
+ // EXT-568BMW
+ // Fix is not to multiply by 2
+ //NewBufferL(2*numUDUnits);
+ NewBufferL(numUDUnits);
+ TPtr unpackedPtr((TText*)iBuffer->Des().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<length; i++)
+ {
+ if ((i%2)==0) // even
+ {
+ TUint8 tempOctet = 0;
+ octet.DecodeL(aPdu);
+ tempOctet = (TUint8)octet&0x0F; // four topmost bits set to zero
+
+ 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');
+ break;
+ }
+ }
+ else
+ {
+ TUint8 tempOctet = 0;
+ octet&0xF0; // four least significant bits…
+ tempOctet = (TUint8)octet>>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<TSmsInformationElementIdentifier>((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<TSmsInformationElementIdentifier>((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<count); i++)
+ if (InformationElement(i).Identifier()==aIdentifier)
+ {
+ found=ETrue;
+ aIndex=i;
+ }
+ return found;
+ } // CSmsUserData::InformationElementIndex
+
+
+/**
+ * Gets the last 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 last 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::InformationElementLastIndex(CSmsInformationElement::TSmsInformationElementIdentifier aIdentifier,TInt& aIndex) const
+ {
+ LOGGSMU1("CSmsUserData::InformationElementLastIndex()");
+
+ TBool found=EFalse;
+ TInt count=NumInformationElements();
+ for (TInt i=count-1; (!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<TInt>& aIndices) const
+ {
+ LOGGSMU1("CSmsUserData::InformationElementIndicesL()");
+
+ aIndices.Reset();
+
+ TInt count=NumInformationElements();
+ for (TInt i=0; i<count; i++)
+ {
+ if (InformationElement(i).Identifier()==aIdentifier)
+ {
+ aIndices.AppendL(i);
+ }
+ }
+ } // CSmsUserData::InformationElementIndicesL
+
+
+/**
+ * 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 An EMS Information Element
+ */
+TBool CSmsUserData::EmsInformationElementWillFitL(CEmsInformationElement* aIe,CSmsEMSBufferSegmenter& aSeg,TUint& aCharsAddedToCurrentPDU)
+ {
+ LOGGSMU1("CSmsUserData::EmsInformationElementWillFitL()");
+
+ // Before using an EmsInformationElement polymorphically as an SmsIE,
+ // we need to make sure that the IE has been encoded
+ aIe->EncodeInformationElementL();
+ 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<count; i++)
+ {
+ if (InformationElement(i).Identifier()==aIdentifier)
+ {
+ TSmsInformationElementCategories::TInformationElementCategory category;
+
+ if (TSmsInformationElementCategories::GetCategoryDefinition(aIdentifier, category) == EFalse)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ switch (category)
+ {
+ case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUMultipleInstancesPerPDU:
+ {
+ if (InformationElement(i).Identifier() == CSmsInformationElement::ESmsIEISpecialSMSMessageIndication)
+ {
+ LOGGSMU3("CSmsUserData::AddInformationElementL1 category = %d, identifier = %d",category,aIdentifier);
+
+ //if Msg type is the same, swap with the most recent value
+ if ((InformationElement(i).Data()[0] & ((TUint8) EGsmSmsSpecialMessageIndicationTypeMask)) ==
+ (aData[0] & ((TUint8) EGsmSmsSpecialMessageIndicationTypeMask)))
+ {
+ User::Leave(KErrAlreadyExists);
+ }
+ }
+ else
+ {
+ LOGGSMU4("CSmsUserData::AddInformationElementL3 category = %d, identifier = %d, data = %S",category,aIdentifier, &aData);
+ User::Leave(KErrArgument);
+ }
+ break;
+ }
+ case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUAndWithIdenticalValues:
+ case TSmsInformationElementCategories::ECtrlMandatoryIn1stPDUOnly:
+ case TSmsInformationElementCategories::ECtrlSingleInstanceOnly:
+ {
+ LOGGSMU3("CSmsUserData::AddInformationElementL4 category = %d, identifier = %d",category,aIdentifier);
+ User::Leave(KErrAlreadyExists);
+ break;
+ }
+ case TSmsInformationElementCategories::ECtrlMultipleInstancesAllowed:
+ {
+ LOGGSMU3("CSmsUserData::AddInformationElementL5 category = %d, identifier = %d",category,aIdentifier);
+ break;
+ }
+ case TSmsInformationElementCategories::ECtrlMandatoryInEveryPDUButWithValueSpecificToPDU:
+ {
+ LOGGSMU3("CSmsUserData::AddInformationElementL6 category = %d, identifier = %d",category,aIdentifier);
+ User::Leave(KErrAlreadyExists);
+ // currently the email header is updated in:
+ // void CSmsMessage::DecodeBufferL(CArrayPtr<CSmsPDU>& 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; i<numInformationElements; i++)
+ aPtr=iInformationElementArray[i]->EncodeL(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()<headerLength)
+ {
+ CSmsInformationElement* informationelement=CSmsInformationElement::NewL();
+ CleanupStack::PushL(informationelement);
+ informationelement->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<numiformationelements; i++)
+ {
+ CSmsInformationElement* informationelement=CSmsInformationElement::NewL();
+ CleanupStack::PushL(informationelement);
+ aStream >> *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; i<numiformationelements; i++)
+ aStream << *iInformationElementArray[i];
+ aStream << *iBody;
+ } // CSmsUserData::ExternalizeL
+
+
+CSmsUserData::CSmsUserData(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TSmsFirstOctet& aFirstOctet,const TSmsDataCodingScheme& aDataCodingScheme):
+ iCharacterSetConverter(aCharacterSetConverter),
+ iFs(aFs),
+ iFirstOctet(aFirstOctet),
+ iDataCodingScheme(aDataCodingScheme),
+ iInformationElementArray(8)
+ {
+ } // CSmsUserData::CSmsUserData
+
+
+void CSmsUserData::ConstructL()
+ {
+ LOGGSMU1("CSmsUserData::ConstructL()");
+
+ NewBodyL(0);
+ } // CSmsUserData::ConstructL
+
+
+/**
+ * Duplicates this CSmsUserData object.
+ *
+ * @return Pointer to the newly created CSmsUserData object.
+ */
+CSmsUserData* CSmsUserData::DuplicateL(TSmsFirstOctet& aFirstOctet,
+ const TSmsDataCodingScheme& aDataCodingScheme) const
+ {
+ LOGGSMU1("CSmsUserData::DuplicateL()");
+
+ CSmsUserData* userdata = CSmsUserData::NewL(iCharacterSetConverter, iFs,
+ aFirstOctet, aDataCodingScheme);
+ CleanupStack::PushL(userdata);
+
+ userdata->SetBodyL(Body());
+
+ for (TInt ie = 0; ie < iInformationElementArray.Count(); ie++)
+ {
+ CSmsInformationElement* oldIE = iInformationElementArray[ie];
+
+ if (CEmsFactory::Supported(oldIE->Identifier()))
+ {
+ CEmsInformationElement* newIE = static_cast<CEmsInformationElement*>(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; i<numinformationelements; i++)
+ headerlength+=iInformationElementArray[i]->Length();
+ 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; (i<length) && (parsedlength<maxparsedlength); i++)
+ {
+ TText ch=iAccessAddress->Des()[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<CSmsAddress::KSmsAddressMaxAddressLength> 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; (i<length) && (parsedlength<maxparsedlength); i++)
+ {
+ TText ch=iCallingLineIdentity->Des()[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<CSmsAddress::KSmsAddressMaxAddressLength> 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<CVoiceMailNotification>& 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<CVoiceMailNotification>(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<CVoiceMailDeletion>(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<CVoiceMailDeletion>& 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