diff -r 000000000000 -r 3553901f7fa8 smsprotocols/smsstack/gsmu/src/gsmupriv.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smsprotocols/smsstack/gsmu/src/gsmupriv.cpp Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,246 @@ +// Copyright (c) 2000-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: +// Implements utility classes private to the GSMU dll +// +// + +/** + @file +*/ + +#include "gsmupriv.h" +#include "Gsmumain.h" +#include + +// +// TSmsPacker - packs and unpacks data encoded in an SMS alphabet +// + +/** + * Constructor + */ +TSmsAlphabetPacker::TSmsAlphabetPacker(TSmsDataCodingScheme::TSmsAlphabet aAlphabet,TBool aIsBinary,TInt aStartBit) + : iAlphabet(aAlphabet),iIsBinary(aIsBinary),iStartBit(aStartBit) + { + // NOP + } // TSmsAlphabetPacker::TSmsAlphabetPacker + + +/** + * Packs user data units from aIn and appends to aOut. + */ +TInt TSmsAlphabetPacker::PackL(TDes8& aOut,const TDesC8& aIn) + { + LOGGSMU1("TSmsAlphabetPacker::PackL()"); + + // Ensure we've got the right length + TInt packedOctetsRequired=PackedOctetsRequiredL(aIn.Length()); + if (packedOctetsRequired>(aOut.MaxLength()-aOut.Length())) + User::Leave(KErrOverflow); + // Do the conversion + TInt elementSizeInBits=ElementSizeInBitsL(); + if (elementSizeInBits==8) + { + // Straight copy here + aOut.Append(aIn); + } + else if (elementSizeInBits==7) + { + // Get raw pointers and do packing + TUint8* outPtr=(TUint8*)aOut.Ptr()+aOut.Length(); + const TUint8* inPtr=aIn.Ptr(); + + outPtr[0]=0; + for (TInt i=0; i>(8-iStartBit)); + } + iStartBit=(iStartBit+7)%8; + } + // Increment the length for the packed data + aOut.SetLength(aOut.Length()+packedOctetsRequired); + } + else + { + __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicPackAlphabetInvalid)); + } + // Return number of bytes used + return packedOctetsRequired; + } // TSmsAlphabetPacker::PackL + + +/** + * Unpacks user data units from aIn and appends to aOut. + */ +TInt TSmsAlphabetPacker::UnpackL(const TDesC8& aIn,TDes8& aOut,TInt aNumUDUnits) + { + LOGGSMU1("TSmsAlphabetPacker::UnpackL()"); + + TInt length=aNumUDUnits; + // Ensure we've got enough input and output buffer + // defect fix for + // EDNOPMA-4YPJ34 Short message with alphanumeric address in From field is not received + // aIn.length is constant (KSmsAddressMaxAddressValueLength = 10) + // PackedOctetsRequiredL is dependant on aNumUDUnits + // otheriwse if a short alphanumeric address is received GSMU leaves + // and the smsprot returns protocol error to the service center + // if (PackedOctetsRequiredL(aIn.Length())>aNumUDUnits) + if (PackedOctetsRequiredL(aNumUDUnits)>aIn.Length()) + User::Leave(KErrCorrupt); + if (aOut.Length()+length>aOut.MaxLength()) + User::Leave(KErrCorrupt); + TInt elementSizeInBits=ElementSizeInBitsL(); + if (elementSizeInBits==8) + { + aOut.Append(aIn); + } + else if (elementSizeInBits==7) + { + // Get raw pointers and do packing + TUint8* outPtr=(TUint8*)aOut.Ptr()+aOut.Length(); + const TUint8* inPtr=aIn.Ptr(); + + for (TInt i=0; i>iStartBit) & 0x7F; + if (iStartBit) + { + inPtr++; + from|=(*inPtr<<(8-iStartBit)) & 0x7F; + } + outPtr[i]=(TUint8) from; + iStartBit=(iStartBit+7)%8; + } + aOut.SetLength(aOut.Length()+length); + } + else + { + __ASSERT_DEBUG(EFalse,Panic(KGsmuPanicPackAlphabetInvalid)); + } + return length; + } // TSmsAlphabetPacker::UnpackL + + +/** + * Converts then packs the input data, aIn, and appends to aOut + */ +TInt TSmsAlphabetPacker::ConvertAndPackL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TDes8& aOut,const TDesC& aIn,TInt& aConvertedNumUDUnits) + { + LOGGSMU1("TSmsAlphabetPacker::ConvertAndPackL()"); + + // Do the conversion + // VEP Fix for defect EXT-568BMW, when length of alphanumeric destination address + // was set wrong and also special characters defined in 7-bit default aplhabet (ä,ö...) + // were converted incorrectly + CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(aCharacterSetConverter,aFs,iAlphabet,iIsBinary); + TPtrC8 convertedPtr=converter->ConvertFromNativeL(aIn); + aConvertedNumUDUnits=convertedPtr.Length(); + // Do the packing + TInt octetsUsed=PackL(aOut,convertedPtr); + // Cleanup and return + CleanupStack::PopAndDestroy(converter); + return octetsUsed; + } // TSmsAlphabetPacker::ConvertAndPackL + + +/** + * Unpacks the converts the input data, aIn, and appends to aOut + */ +TInt TSmsAlphabetPacker::UnpackAndConvertL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,const TDesC8& aIn,TDes& aOut,TInt aNumUDUnits) + { + LOGGSMU1("TSmsAlphabetPacker::UnpackAndConvertL()"); + + // Unpack first + HBufC8* unpackedBuffer=HBufC8::NewLC(aNumUDUnits); + TPtr8 unpackedBufferPtr(unpackedBuffer->Des()); + UnpackL(aIn,unpackedBufferPtr,aNumUDUnits); + // Convert + CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(aCharacterSetConverter,aFs,iAlphabet,iIsBinary); + TPtrC convertedPtr=converter->ConvertToNativeL(*unpackedBuffer); + if (convertedPtr.Length()>(aOut.MaxLength()-aOut.Length())) + User::Leave(KErrCorrupt); + // Cleanup and return + aOut.Append(convertedPtr); + CleanupStack::PopAndDestroy(2); // unpackedBuffer,converter + return aNumUDUnits; + } // TSmsAlphabetPacker::UnpackAndConvertL + + +/** + * Returns the number of octets needed to pack the specified number of + */ +TInt TSmsAlphabetPacker::PackedOctetsRequiredL(TInt aNumUDUnits) const + { + LOGGSMU1("TSmsAlphabetPacker::PackedOctetsRequiredL()"); + + TInt octetsRequired=0; + TInt elementSizeInBits=ElementSizeInBitsL(); + if (elementSizeInBits==8) + octetsRequired=aNumUDUnits; + else + octetsRequired=(iStartBit+aNumUDUnits*elementSizeInBits + 7)/8; // Rounds up + return octetsRequired; + } // TSmsAlphabetPacker::PackedOctetsRequiredL + +/** + * Returns the number of UD units that are packed in the specified number of octets + */ +TInt TSmsAlphabetPacker::NumUDUnitsL(TInt aOctets) const + { + TInt numUD=0; + TInt elementSizeInBits=ElementSizeInBitsL(); + if (elementSizeInBits==8) + numUD=aOctets; + else + numUD=(8*aOctets - iStartBit)/elementSizeInBits; + return numUD; + } + +/** + * Returns the size in bits of a UDL element for the alphabet. Leaves if + * invalid data coding scheme. + */ +TInt TSmsAlphabetPacker::ElementSizeInBitsL() const + { + LOGGSMU1("TSmsAlphabetPacker::ElementSizeInBitsL()"); + + TInt ret = 8; + + if (iIsBinary) + return ret; + switch (iAlphabet) + { + case TSmsDataCodingScheme::ESmsAlphabet7Bit: + { + ret = 7; + break; + } + case TSmsDataCodingScheme::ESmsAlphabet8Bit: + case TSmsDataCodingScheme::ESmsAlphabetUCS2: + { + ret = 8; + break; + } + default: + { + User::Leave(KErrGsmSMSDataCodingSchemeNotSupported); + } + } + return ret; + } // TSmsAlphabetPacker::ElementSizeInBitsL