smsprotocols/smsstack/gsmu/src/gsmupriv.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implements utility classes private to the GSMU dll
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include "gsmupriv.h"
       
    23 #include "Gsmumain.h"
       
    24 #include <exterror.h>
       
    25 
       
    26 //
       
    27 // TSmsPacker - packs and unpacks data encoded in an SMS alphabet
       
    28 //
       
    29 
       
    30 /**
       
    31  *  Constructor
       
    32  */
       
    33 TSmsAlphabetPacker::TSmsAlphabetPacker(TSmsDataCodingScheme::TSmsAlphabet aAlphabet,TBool aIsBinary,TInt aStartBit)
       
    34 	: iAlphabet(aAlphabet),iIsBinary(aIsBinary),iStartBit(aStartBit)
       
    35 	{
       
    36 	// NOP
       
    37 	} // TSmsAlphabetPacker::TSmsAlphabetPacker
       
    38 
       
    39 
       
    40 /**
       
    41  *  Packs user data units from aIn and appends to aOut.
       
    42  */
       
    43 TInt TSmsAlphabetPacker::PackL(TDes8& aOut,const TDesC8& aIn)
       
    44 	{
       
    45 	LOGGSMU1("TSmsAlphabetPacker::PackL()");
       
    46 
       
    47 	// Ensure we've got the right length
       
    48 	TInt packedOctetsRequired=PackedOctetsRequiredL(aIn.Length());
       
    49 	if (packedOctetsRequired>(aOut.MaxLength()-aOut.Length()))
       
    50 		User::Leave(KErrOverflow);
       
    51 	// Do the conversion
       
    52 	TInt elementSizeInBits=ElementSizeInBitsL();
       
    53 	if (elementSizeInBits==8)
       
    54 		{
       
    55 		// Straight copy here
       
    56 		aOut.Append(aIn);
       
    57 		}
       
    58 	else if (elementSizeInBits==7)
       
    59 		{
       
    60 		// Get raw pointers and do packing
       
    61 		TUint8* outPtr=(TUint8*)aOut.Ptr()+aOut.Length();
       
    62 		const TUint8* inPtr=aIn.Ptr();
       
    63 
       
    64 		outPtr[0]=0;
       
    65 		for (TInt i=0; i<aIn.Length(); i++)
       
    66 			{
       
    67 			TUint8 to=inPtr[i];
       
    68 			*outPtr|=(to<<iStartBit);
       
    69 			if (iStartBit)
       
    70 				{
       
    71 				outPtr++;
       
    72 				*outPtr=(TUint8) (to>>(8-iStartBit));
       
    73 				}
       
    74 			iStartBit=(iStartBit+7)%8;
       
    75 			}
       
    76 		// Increment the length for the packed data
       
    77 		aOut.SetLength(aOut.Length()+packedOctetsRequired);
       
    78 		}
       
    79 	else
       
    80 		{
       
    81 		__ASSERT_DEBUG(EFalse,Panic(KGsmuPanicPackAlphabetInvalid));
       
    82 		}
       
    83 	// Return number of bytes used
       
    84 	return packedOctetsRequired;
       
    85 	} // TSmsAlphabetPacker::PackL
       
    86 
       
    87 
       
    88 /**
       
    89  *  Unpacks user data units from aIn and appends to aOut.
       
    90  */
       
    91 TInt TSmsAlphabetPacker::UnpackL(const TDesC8& aIn,TDes8& aOut,TInt aNumUDUnits)
       
    92 	{
       
    93 	LOGGSMU1("TSmsAlphabetPacker::UnpackL()");
       
    94 
       
    95 	TInt length=aNumUDUnits;
       
    96 	// Ensure we've got enough input and output buffer
       
    97  	// defect fix for
       
    98  	// EDNOPMA-4YPJ34	Short message with alphanumeric address in From field is not received
       
    99  	// aIn.length is constant (KSmsAddressMaxAddressValueLength = 10)
       
   100  	// PackedOctetsRequiredL is dependant on aNumUDUnits
       
   101  	// otheriwse if a short alphanumeric address is received GSMU leaves
       
   102  	// and the smsprot returns protocol error to the service center
       
   103  	// if (PackedOctetsRequiredL(aIn.Length())>aNumUDUnits)
       
   104  	if (PackedOctetsRequiredL(aNumUDUnits)>aIn.Length())
       
   105 		User::Leave(KErrCorrupt);
       
   106 	if (aOut.Length()+length>aOut.MaxLength())
       
   107 		User::Leave(KErrCorrupt);
       
   108 	TInt elementSizeInBits=ElementSizeInBitsL();
       
   109 	if (elementSizeInBits==8)
       
   110 		{
       
   111 		aOut.Append(aIn);
       
   112 		}
       
   113 	else if (elementSizeInBits==7)
       
   114 		{
       
   115 		// Get raw pointers and do packing
       
   116 		TUint8* outPtr=(TUint8*)aOut.Ptr()+aOut.Length();
       
   117 		const TUint8* inPtr=aIn.Ptr();
       
   118 
       
   119 		for (TInt i=0; i<length; i++)
       
   120 			{
       
   121 			TInt from=(*inPtr>>iStartBit) & 0x7F;
       
   122 			if (iStartBit)
       
   123 				{
       
   124 				inPtr++;
       
   125 				from|=(*inPtr<<(8-iStartBit)) & 0x7F;
       
   126 				}
       
   127 			outPtr[i]=(TUint8) from;
       
   128 			iStartBit=(iStartBit+7)%8;
       
   129 			}
       
   130 		aOut.SetLength(aOut.Length()+length);
       
   131 		}
       
   132 	else
       
   133 		{
       
   134 		__ASSERT_DEBUG(EFalse,Panic(KGsmuPanicPackAlphabetInvalid));
       
   135 		}
       
   136 	return length;
       
   137 	} // TSmsAlphabetPacker::UnpackL
       
   138 
       
   139 
       
   140 /**
       
   141  *  Converts then packs the input data, aIn, and appends to aOut
       
   142  */
       
   143 TInt TSmsAlphabetPacker::ConvertAndPackL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,TDes8& aOut,const TDesC& aIn,TInt& aConvertedNumUDUnits)
       
   144     {
       
   145 	LOGGSMU1("TSmsAlphabetPacker::ConvertAndPackL()");
       
   146 
       
   147 	// Do the conversion
       
   148 	// VEP Fix for defect EXT-568BMW, when length of alphanumeric destination address
       
   149 	// was set wrong and also special characters defined in 7-bit default aplhabet (ä,ö...)
       
   150 	// were converted incorrectly
       
   151 	CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(aCharacterSetConverter,aFs,iAlphabet,iIsBinary);
       
   152 	TPtrC8 convertedPtr=converter->ConvertFromNativeL(aIn);
       
   153 	aConvertedNumUDUnits=convertedPtr.Length();
       
   154 	// Do the packing
       
   155 	TInt octetsUsed=PackL(aOut,convertedPtr);
       
   156 	// Cleanup and return
       
   157 	CleanupStack::PopAndDestroy(converter);
       
   158 	return octetsUsed;
       
   159     } // TSmsAlphabetPacker::ConvertAndPackL
       
   160 
       
   161 
       
   162 /**
       
   163  *  Unpacks the converts the input data, aIn, and appends to aOut
       
   164  */
       
   165 TInt TSmsAlphabetPacker::UnpackAndConvertL(CCnvCharacterSetConverter& aCharacterSetConverter,RFs& aFs,const TDesC8& aIn,TDes& aOut,TInt aNumUDUnits)
       
   166 	{
       
   167 	LOGGSMU1("TSmsAlphabetPacker::UnpackAndConvertL()");
       
   168 
       
   169 	// Unpack first
       
   170 	HBufC8* unpackedBuffer=HBufC8::NewLC(aNumUDUnits);
       
   171 	TPtr8 unpackedBufferPtr(unpackedBuffer->Des());
       
   172 	UnpackL(aIn,unpackedBufferPtr,aNumUDUnits);
       
   173 	// Convert
       
   174 	CSmsAlphabetConverter* converter=CSmsAlphabetConverter::NewLC(aCharacterSetConverter,aFs,iAlphabet,iIsBinary);
       
   175 	TPtrC convertedPtr=converter->ConvertToNativeL(*unpackedBuffer);
       
   176 	if (convertedPtr.Length()>(aOut.MaxLength()-aOut.Length()))
       
   177 		User::Leave(KErrCorrupt);
       
   178 	// Cleanup and return
       
   179 	aOut.Append(convertedPtr);
       
   180 	CleanupStack::PopAndDestroy(2);	// unpackedBuffer,converter
       
   181 	return aNumUDUnits;
       
   182 	} // TSmsAlphabetPacker::UnpackAndConvertL
       
   183 
       
   184 
       
   185 /**
       
   186  *  Returns the number of octets needed to pack the specified number of
       
   187  */
       
   188 TInt TSmsAlphabetPacker::PackedOctetsRequiredL(TInt aNumUDUnits) const
       
   189 	{
       
   190 	LOGGSMU1("TSmsAlphabetPacker::PackedOctetsRequiredL()");
       
   191 
       
   192 	TInt octetsRequired=0;
       
   193 	TInt elementSizeInBits=ElementSizeInBitsL();
       
   194 	if (elementSizeInBits==8)
       
   195 		octetsRequired=aNumUDUnits;
       
   196 	else
       
   197 		octetsRequired=(iStartBit+aNumUDUnits*elementSizeInBits + 7)/8;	// Rounds up
       
   198 	return octetsRequired;
       
   199 	} // TSmsAlphabetPacker::PackedOctetsRequiredL
       
   200 
       
   201 /**
       
   202  * Returns the number of UD units that are packed in the specified number of octets
       
   203  */
       
   204 TInt TSmsAlphabetPacker::NumUDUnitsL(TInt aOctets) const
       
   205 	{
       
   206 	TInt numUD=0;
       
   207 	TInt elementSizeInBits=ElementSizeInBitsL();
       
   208 	if (elementSizeInBits==8)
       
   209 		numUD=aOctets;
       
   210 	else
       
   211 		numUD=(8*aOctets - iStartBit)/elementSizeInBits;
       
   212 	return numUD;
       
   213 	}
       
   214 
       
   215 /**
       
   216  *  Returns the size in bits of a UDL element for the alphabet.  Leaves if
       
   217  *  invalid data coding scheme.
       
   218  */
       
   219 TInt TSmsAlphabetPacker::ElementSizeInBitsL() const
       
   220 	{
       
   221 	LOGGSMU1("TSmsAlphabetPacker::ElementSizeInBitsL()");
       
   222 
       
   223     TInt ret = 8;
       
   224 
       
   225 	if (iIsBinary)
       
   226 		return ret;
       
   227 	switch (iAlphabet)
       
   228 		{
       
   229 		case TSmsDataCodingScheme::ESmsAlphabet7Bit:
       
   230 			{
       
   231 			ret = 7;
       
   232             break;
       
   233 			}
       
   234 		case TSmsDataCodingScheme::ESmsAlphabet8Bit:
       
   235 		case TSmsDataCodingScheme::ESmsAlphabetUCS2:
       
   236 			{
       
   237 			ret = 8;
       
   238             break;
       
   239 			}
       
   240 		default:
       
   241 			{
       
   242             User::Leave(KErrGsmSMSDataCodingSchemeNotSupported);
       
   243 			}
       
   244 		}
       
   245     return ret;
       
   246 	} // TSmsAlphabetPacker::ElementSizeInBitsL