--- /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 <exterror.h>
+
+//
+// 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<aIn.Length(); i++)
+ {
+ TUint8 to=inPtr[i];
+ *outPtr|=(to<<iStartBit);
+ if (iStartBit)
+ {
+ outPtr++;
+ *outPtr=(TUint8) (to>>(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<length; i++)
+ {
+ TInt from=(*inPtr>>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