diff -r 6b1d113cdff3 -r 6638e7f4bd8f telephonyserverplugins/simatktsy/utility/src/tsatutility.cpp --- a/telephonyserverplugins/simatktsy/utility/src/tsatutility.cpp Mon May 03 13:37:20 2010 +0300 +++ b/telephonyserverplugins/simatktsy/utility/src/tsatutility.cpp Thu May 06 15:10:38 2010 +0100 @@ -1,1080 +1,1080 @@ -// Copyright (c) 2006-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: -// Name : TSatUtility.cpp -// Part of : Common Sim Atk TSY / commonsimatktsy -// Sat Utility classes implementation. -// Version : 1.0 -// - - - -// INCLUDE FILES -#include "tsatutility.h" // Class header -#include "tflogger.h" // TFLOGSTRING -#include // TON and NPI constants - -// ----------------------------------------------------------------------------- -// TSatUtility::TonAndNpi -// Map TON and NPI to RSat TON and NPI values -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::TonAndNpi - ( - const TInt aTonAndNpi, - RSat::TTypeOfNumber* aTon, - RSat::TNumberingPlan* aNpi - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::TonAndNpi" ); - TInt ton( ( aTonAndNpi >> 4 ) & KTONMask ); // TON mask value 0x07 - - switch ( ton ) - { - case KTonUnknown: - { - *aTon = RSat::EUnknownNumber; - break; - } - case KInternationalNumber: - { - *aTon = RSat::EInternationalNumber; - break; - } - case KNationalNumber: - { - *aTon = RSat::ENationalNumber; - break; - } - case KNetworkSpecificNumber: - { - *aTon = RSat::ENetworkSpecificNumber; - break; - } - case KSubscriberNumber: - { - *aTon = RSat::EDedicatedNumber; - break; - } - case KAlphanumeric: - { - *aTon = RSat::EAlphanumericNumber; - break; - } - case KAbbreviatedNumber: - { - *aTon = RSat::EAbbreviatedNumber; - break; - } - default: - { - *aTon = RSat::ETypeOfNumberNotSet; - break; - } - } - - // Numbering plan - TInt npi( aTonAndNpi & KNPIMask ); // NPI mask value 0x0F - - switch ( npi ) - { - case KNpiUnknown: - { - *aNpi = RSat::EUnknownNumberingPlan; - break; - } - case KIsdnTelephoneNumPlan: - { - *aNpi = RSat::EIsdnNumberPlan; - break; - } - case KDataNumPlan: - { - *aNpi = RSat::EDataNumberPlan; - break; - } - case KTelexNumPlan: - { - *aNpi = RSat::ETelexNumberPlan; - break; - } - case KNationalNumPlan: - { - *aNpi = RSat::ENationalNumberPlan; - break; - } - case KPrivateNumPlan: - { - *aNpi = RSat::EPrivateNumberPlan; - break; - } - case KServiceCentreSpecificPlan1: - { - *aNpi = RSat::EServiceCentreSpecificPlan1; - break; - } - case KServiceCentreSpecificPlan2: - { - *aNpi = RSat::EServiceCentreSpecificPlan2; - break; - } - case KErmesNumPlan: - { - *aNpi = RSat::EERMESNumberPlan; - break; - } - default: - { - *aNpi = RSat::ENumberingPlanNotSet; - break; - } - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::Packed7to8Unpacked -// Converts 7-bit packed string to 8-bit unpacked format. -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt TSatUtility::Packed7to8Unpacked - ( - const TPtrC8 aSource, - TDes8& aTarget - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::Packed7to8Unpacked" ); - TInt ret( KErrNone ); - // The string is in packed GSM default alphabet format. - // Converted to 8-bit format - TUint8 maskRightPartOfCurrentByte( 0x7F ); - TUint8 shiftLeft( 0 ); - TUint8 leftPartFromPreviousByte( 0 ); - TInt sourceLength = aSource.Length(); - // Initialize the target string before starting - aTarget.Zero(); - - // Check out which string is the shortest and use its length as a limit - TInt length ( Min( sourceLength, aTarget.MaxLength() ) ); - for ( TInt i = 0; i < length; i++ ) - { - TUint8 leftPartOfCurrentChar = static_cast( ( - aSource[i] & maskRightPartOfCurrentByte ) << shiftLeft ); - - // Append the character in the output text string - aTarget.Append( leftPartOfCurrentChar | leftPartFromPreviousByte ); - - // Updates - if ( 6 == shiftLeft ) - { - // After 6 shifts, the character is in bit7..bit1, - // therefore it has to be shifted one bit to the right. - aTarget.Append( aSource[i] >> 1 ); - // Restart - leftPartFromPreviousByte = 0; - shiftLeft = 0; - maskRightPartOfCurrentByte = 0x7F; - } - else - { - leftPartFromPreviousByte = static_cast( ( - aSource[i] ) >> ( 7-shiftLeft ) ); - maskRightPartOfCurrentByte = static_cast( - maskRightPartOfCurrentByte >> 1 ); - shiftLeft++; - } - } - - // Whe should still notify the requesting method about exceeding the length - if ( length < sourceLength ) - { - ret = KErrOverflow; - TFLOGSTRING2( "UTILITY: TSatUtility::Packed7to8Unpacked,\ - Input data too long. %d bytes could not be converted", - ( sourceLength - length ) ); - } - - return ret; - } - -// ----------------------------------------------------------------------------- -// TSatUtility::UCSToPacked7 -// Converts UCS2 string to 7-bit packed format -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::UCSToPacked7 - ( - const TPtrC aInput, - TDes8& aOutput - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::UCSToPacked7" ); - - TBuf8 string; - - // This method interrupts converting if the target buffer is full, so - // the length can not be exceeded - ConvertUnicode16To7Bit( aInput, string ); - - TUint8 move( 0 ); - TInt i( 0 ); - TInt length( string.Length() ); - - // If the input data was too long, some data will miss from the end here - for ( i = 0; i < length; i += 1 ) - { - // Get first character - TUint8 char1 = static_cast( string[i] >> move ); - TUint8 char2; - - if ( ( i + 1 ) < length ) - { - // Get next character - char2 = static_cast( string[i + 1] << ( 7 - move ) ); - } - else - { - // No more characters - char2 = 0; - } - // Append packed character - aOutput.Append( static_cast( char1 | char2 ) ); - - if ( ( 6 == move ) && char2 ) - { - i++; - move = 0; - } - else - { - move++; - } - } - - if ( !( ( length + 1 ) % 8 ) ) - { - // If the total number of characters in the text string equals (8n-1) - // where n=1,2,3 etc. then there are 7 spare bits at the end of the - // message. To avoid the situation where the receiving entity confuses - // 7 binary zero pad bits as the @ character, the carriage return - // (i.e. ) character shall be used for padding in this situation, - // as defined in TS 23.038 [5]. - aOutput[ aOutput.Length() - 1 ] = static_cast( - aOutput[ aOutput.Length() - 1 ] | KCrShiftedOneBitToLeft ); - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::BCDToAscii -// Converts BCD string to ASCII format -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt TSatUtility::BCDToAscii - ( - const TPtrC8 aInput, - TDes8& aOutput - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::BCDToAscii" ); - TInt ret( KErrNone ); - - // Convert Abbreviated dialling numbers format back to ASCII format. - // See 3GPP TS 11.11, EFadn - aOutput.Zero(); - // Check out which string is the shortest and use its length as a limit - TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); - - for ( TInt i = 0; i < length; i++ ) - { - // Two bcd string chars are coded in one byte, - // 1st char is in low nibble and 2nd is in high nibble - // if the high nibble doesn't contain a char it's value is 0xf - TUint8 byte = aInput[i]; - aOutput.Append( KAscii[byte & 0x0F] ); - - if ( KMaskF0 != ( byte & KMaskF0 ) ) - { - aOutput.Append( KAscii[byte >> 4] ); - } - } - - // Whe should still notify the requesting method about exceeding the length - if ( length < aInput.Length() ) - { - ret = KErrOverflow; - TFLOGSTRING2( "UTILITY: TSatUtility::BCDToAscii,Input data too long.\ - %d bytes could not be converted", ( aInput.Length() - length ) ); - } - - return ret; - } - -// ----------------------------------------------------------------------------- -// TSatUtility::AsciiToBCD -// Convert ASCII string to binary coded decimal, invalid characters are dropped -// and will not be part of bcd string. -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt TSatUtility::AsciiToBCD - ( - const TDesC8& aInput, - TDes8& aOutput - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::AsciiToBCD" ); - TInt ret( KErrNone ); - TInt i; - TInt j; - TInt outLen( 0 ); - TInt length( aInput.Length() ); - - aOutput.Zero(); - - // Go through the whole string - for ( i = 0; i < length; i++ ) - { - TUint8 bcd = 0x0F; // Should never be part of number - TBool found( EFalse ); - - // Search for the ASCII character - for ( j = 0; ( j < KAsciiBcdTableLength ) && !found; j++ ) - { - // If the character matches, set the corresponding value - if ( KAsciiToBCD[j][0] == aInput[i] ) - { - bcd = KAsciiToBCD[j][1]; - found = ETrue; - } - } - - // Add only valid bcd characters... - if ( found ) - { - if( aOutput.MaxLength() > aOutput.Length() ) - { - // Store to string - if ( ( outLen % 2 ) == 0 ) - { - aOutput.Append( bcd ); - } - else - { - aOutput[outLen / 2] |= ( bcd << 4 ); - } - } - else - { - TFLOGSTRING( "UTILITY: TSatUtility::AsciiToBCD, Overflow!" ); - ret = KErrOverflow; - } - - outLen++; - } - else - { - TFLOGSTRING3("UTILITY: TSatUtility::AsciiToBCD -- dropped \ - character %d at i=%d", TInt( aInput[i] ), i ); - } - - } // For - - // If odd number of digits add endmark - if ( ( outLen % 2 ) != 0 ) - { - aOutput[outLen / 2] |= KMaskF0; - } - - return ret; - } - -// ----------------------------------------------------------------------------- -// TSatUtility::RemoveWildAndExpansionDigit -// Remove Wild 'w' and Expansion digit '.' from EFadn string. Used in SetUpCall -// proactive command. -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::RemoveWildAndExpansionDigit - ( - const TPtrC8 aString, - TDes8& aOutput - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::RemoveWildAndExpansionDigit" ); - aOutput.Zero(); - TUint8 i( 0 ); - TInt maxLength = aOutput.MaxLength(); - TInt length( aString.Length() ); - - // Append as many characters as there is room for in the target string - for ( i = 0; ( i < length ) && ( aOutput.Length() < maxLength ); i++ ) - { - if ( ( 'w' != aString[i] ) && ( '.' != aString[i] ) ) - { - aOutput.Append( aString[i] ); - } - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::SetAlphaId -// Set Alpha identifier as a Unicode text string and according to the alphabet -// used -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::SetAlphaId - ( - const TPtrC8 aRawData, - TDes& aAlphaId - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::SetAlphaId" ); - if ( ( KUCS2ArabicCoding == aRawData[0] ) - || ( KUCS2GreekCoding == aRawData[0] ) - || ( KUCS2TurkishCoding == aRawData[0] ) ) - { - ConvertAlphaFieldsToUnicode( aRawData, aAlphaId ); - } - else - { - // 8-bit - TBuf8 rawData8; - rawData8.Copy( aRawData ); - Convert7BitToUnicode16( rawData8, aAlphaId ); - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::ConvertToSemiOctet -// Convert integer to BCD format. Only two last digits is used. -// Example TInt 2004 -> 0x40. -// ----------------------------------------------------------------------------- -// -EXPORT_C TUint8 TSatUtility::ConvertToSemiOctet - ( - const TInt aTime - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::ConvertToSemiOctet" ); - // Converting given time to meet the TP-Service-Centre-Time-Stamp format in - // 3GPP TS 23.040. - - TInt msd( ( aTime / 10 ) % 10 ); // Most significant decimal - TInt lsd( ( aTime % 10 ) ); // Least significant decimal - TUint8 ret( TUint8( ( lsd << 4 ) | ( msd ) ) ); - return ret; - } - -// ----------------------------------------------------------------------------- -// TSatUtility::Convert7BitToUnicode16 -// Convert a text from GSM 7 bit default alphabet to Unicode format. -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::Convert7BitToUnicode16 - ( - const TDesC8& aInput, - TDes16& aOutput - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::Convert7BitToUnicode16" ); - TInt i( 0 ); - - aOutput.Zero(); - - // Check out which string is the shortest and use its length as a limit - TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); - - for( i = 0; i < length; i++ ) - { - TUint8 character( aInput[i] ); - - // This code is an escape to an extension of the 7 bit default alphabet - // table. - if ( 0x1B == character ) - { - // Extension table - switch ( aInput[i+1] ) - { - case 0x28: //{ - { - aOutput.Append( static_cast( 0x7B ) ); - break; - } - case 0x29: //} - { - aOutput.Append( static_cast( 0x7D ) ); - break; - } - case 0x3C: //[ - { - aOutput.Append( static_cast( 0x5B ) ); - break; - } - case 0x3E: //] - { - aOutput.Append( static_cast( 0x5D ) ); - break; - } - case 0x3D: //~ - { - aOutput.Append( static_cast( 0x7E ) ); - break; - } - case 0x2F: - { - aOutput.Append( static_cast( 0x5C ) ); - break; - } - case 0x14: // ^ - { - aOutput.Append( static_cast( 0x5E ) ); - break; - } - case 0x65: // Euro 0x20AC - { - aOutput.Append( static_cast( 0x20AC ) ); - break; - } - case 0x40: // | - { - aOutput.Append( static_cast( 0x7C ) ); - break; - } - default: - { - // A space if not found in the table - aOutput.Append( static_cast( 0x20 ) ); - break; - } - } - // Characters in extension table takes two bytes - i++; - } - // Check that bit 8 is set to '0' - else if ( 0x7F >= character ) - { - // Character is in normal 7-bit table. - aOutput.Append( KUnicode[ character ] ); - } - else - { - // Do nothing - } - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::ConvertUnicode16To7Bit -// Converts unicode16 string to GSM 7 bit default alphabet character mode -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt TSatUtility::ConvertUnicode16To7Bit - ( - const TDesC16& aInput, - TDes8& aOutput - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::ConvertUnicode16To7Bit" ); - TInt i( 0 ); - TInt j( 0 ); - TInt ret( KErrNone ); - TBool found( EFalse ); - TInt outputMaxLength = aOutput.MaxLength(); - - // Check out which string is the shortest and use its length as a limit - TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); - for ( i = 0; i < length; i++ ) - { - for ( j = 0; j < KSizeOfConversionArray; j++ ) - { - if ( KUnicode16ToSms7[j][0] == aInput[i] ) - { - - aOutput.Append( static_cast( - KUnicode16ToSms7[j][1] ) ); - found = ETrue; - } - } - - if ( !found ) - { - aOutput.Append( static_cast( aInput[i] & 0x00FF ) ); - } - - found = EFalse; - } - - // Whe should still notify the requesting method about exceeding the length - if ( length < aInput.Length() ) - { - ret = KErrOverflow; - TFLOGSTRING2( "UTILITY: TSatUtility::ConvertUnicode16To7Bit,\ - Input data too long. %d bytes could not be converted", - ( aInput.Length() - length ) ); - } - - return ret; - } - -// ----------------------------------------------------------------------------- -// TSatUtility::FillDurationStructure -// Fill in a TDuration structure -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::FillDurationStructure - ( - CBerTlv& aBerTlv, - RSat::TDuration& aTDuration - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::FillDurationStructure" ); - CTlv duration; - aTDuration.iTimeUnit = RSat::ENoDurationAvailable; - TInt returnValue( aBerTlv.TlvByTagValue( - &duration, KTlvDurationTag ) ); - - if ( KErrNotFound != returnValue ) - { - TUint8 durationTimeUnit = duration.GetShortInfo( ETLV_TimeUnit ); - switch ( durationTimeUnit ) - { - case KMinutes: - { - // Minutes - aTDuration.iTimeUnit = RSat::EMinutes; - break; - } - case KSeconds: - { - // Seconds - aTDuration.iTimeUnit = RSat::ESeconds; - break; - } - case KTenthsOfSeconds: - { - // Tenths of seconds - aTDuration.iTimeUnit = RSat::ETenthsOfSeconds; - break; - } - default: - { - aTDuration.iTimeUnit = RSat::ETimeUnitNotSet; - } - } - // Time interval - aTDuration.iNumOfUnits = duration.GetShortInfo( ETLV_TimeInterval ); - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::FillIconStructure -// Fill in a TIconId structure -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::FillIconStructure - ( - CBerTlv& aBerTlv, - RSat::TIconId& aTIconId, - const TInt aItemNmb - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::FillIconStructure" ); - CTlv iconId; - aTIconId.iQualifier = RSat::ENoIconId; - TInt returnValue( aBerTlv.TlvByTagValue( &iconId, KTlvIconIdentifierTag, - aItemNmb ) ); - - if ( KErrNotFound != returnValue ) - { - TUint8 iconQualifier = iconId.GetShortInfo( ETLV_IconQualifier ); - aTIconId.iIdentifier = iconId.GetShortInfo( ETLV_IconIdentifier ); - // The icon qualifier indicates to the ME how the icon is to be used. - if ( iconQualifier ) - { - aTIconId.iQualifier = RSat::ENotSelfExplanatory; - } - else - { - aTIconId.iQualifier = RSat::ESelfExplanatory; - } - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::SetText -// Set Text string as a Unicode text string and according to the alphabet used -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::SetText - ( - CTlv& aTextTlv, - TDes& aUnicodeOutput - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::SetText" ); - if ( aTextTlv.GetLength() ) - { - TPtrC8 sourceString; - - sourceString.Set( aTextTlv.GetData( ETLV_TextString ) ); - - TBuf8 string( sourceString ); - // SMS default alphabet DCS - if ( !( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) - & KPacked7BitTextMask ) ) - { - // Unpack - Packed7to8Unpacked( sourceString, string ); - - if ( aUnicodeOutput.MaxLength() < string.Length() ) - { - string.SetLength( aUnicodeOutput.MaxLength() ); - } - // Convert to unicode format - Convert7BitToUnicode16( string, aUnicodeOutput ); - } - // UCS2 DCS - else if ( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) - & KUCS2DCS ) - { - Copy8to16LE( sourceString, aUnicodeOutput ); - } - // 8-bit DCS - else if ( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) - & K8BitDCS ) - { - // 8-bit string to 16-bit string - Convert7BitToUnicode16( string, aUnicodeOutput ); - } - else // Reserved cases: SMS default alphabet - { - // Unpack - Packed7to8Unpacked( sourceString, string ); - - if ( aUnicodeOutput.MaxLength() < string.Length() ) - { - string.SetLength( aUnicodeOutput.MaxLength() ); - } - // Convert to unicode format - Convert7BitToUnicode16( string, aUnicodeOutput ); - } - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::ConvertAlphaFieldsToUnicode -// Convert Alpha fields format to Unicode format. -// ----------------------------------------------------------------------------- -// -EXPORT_C void TSatUtility::ConvertAlphaFieldsToUnicode - ( - const TDesC8& aSource, - TDes& aTarget - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::ConvertAlphaFieldsToUnicode" ); - // ArabicCoding, GreekCoding and TurkishCoding have different coding - // methods. There is a tag for each type of alphabet (resp. 80, 81 or 82) - // before the text, and there are base pointers used for expanding 1 byte - // to 2 bytes as required by UCS2 - // Ref: 3GPP TS 11.11, Annex B - - // Base pointer is a "half-page" in the UCS2 code space - TUint16 basePointer( 0 ); - TInt offset( 0 ); - - TInt ret( KErrNone ); - - switch ( aSource[0] ) - { - case KUCS2ArabicCoding: - { - // Copy everything after tag byte - Copy8to16LE( aSource.Mid( 1, aSource.Length() - 1 ), aTarget ); - //Check if any text present - if ( aTarget.Length() ) - { - // Remove padding bytes if any - if ( 0xFFFF == aTarget[ aTarget.Length() - 1 ] ) - { - aTarget.SetLength( aTarget.Length() - 1 ); - } - } - // No expanding needed, already in unicode format. - ret = KErrNotFound; - break; - } - case KUCS2GreekCoding: - { - // Characters starts at position 3 - offset = 3; - // Base pointer is given in one byte - // and needs to be sifted 7-bit to left to get correct base pointer - basePointer = TUint16( aSource[2] << 7 ) ; - break; - } - case KUCS2TurkishCoding: - { - // Characters starts at position 4 - offset = 4; - // Base pointer is two bytes, 16-bit - TSatUtility::CopyTwo8toOne16LE( aSource, basePointer, 2 ); - break; - } - default: - // Do nothing - break; - } - - if ( ( KErrNone == ret ) && ( 2 < aSource.Length() ) ) - { - // The second octet contains a value indicating the number of - // characters in the string. (Not in the case of Arabic string) - TInt length( aSource[1] ); - - // Expanding 1 byte format to 2 bytes - while ( length ) - { - // If bit 8 of the octet is set to zero, the remaining 7 bits of - // the octet contain a GSM Default Alphabet character, whereas if - // bit 8 of the octet is set to one, the remaining seven bits are - // an offset value added to the base pointer defined in octets - // three and four, and the resultant 16 bit value is a UCS2 code - // point, and defines a UCS2 character. - if ( 0x7F <= aSource[offset] ) - { - // Append base pointer and offset - aTarget.Append( basePointer + ( aSource[offset] & 0x7F ) ); - } - else - { - // GSM default alphabet. - TBuf<1> dest16bit; - TBuf8<1> src7bit; - // Get character - src7bit.Append( aSource[offset] ); - // Convert GSM default alphabet character to unicode - Convert7BitToUnicode16( src7bit, dest16bit ); - // Append converted character to output string - aTarget.Append( dest16bit ); - } - offset++; - length--; - } - } - } - -// ----------------------------------------------------------------------------- -// TSatUtility::Copy16to8LE -// Converts 16-bit data to 8-bit data with little endian. -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt TSatUtility::Copy16to8LE - ( - const TDesC16& aSource, - TDes8& aTarget - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::Copy16to8LE" ); - TInt ret( KErrNone ); - TInt length( 0 ); - - // Checks that data length are acceblable - if ( aSource.Size() > aTarget.MaxSize() ) - { - TFLOGSTRING( "UTILITY: TSatUtility::Copy16to8LE, Length exceeded!" ); - ret = KErrOverflow; - length = ( aTarget.MaxSize() / 2 ); - } - else - { - length = aSource.Length(); - } - - // Append source to target using rigth endian - for ( TInt i = 0; i < length; i++ ) - { - aTarget.Append( TUint8( aSource[i] >> 8) ); - aTarget.Append( TUint8( aSource[i] & 0xff ) ); - } - - return ret; - } - -// ----------------------------------------------------------------------------- -// TSatUtility::Copy8to16LE -// Converts 8-bit data to 16-bit data with little endian -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt TSatUtility::Copy8to16LE - ( - const TDesC8& aSource, - TDes16& aTarget - ) - { - TFLOGSTRING( "UTILITY: TSatUtility::Copy8to16LE" ); - TInt ret( KErrNone ); - // Check out which string is the shortest and use its length as a limit - TInt length ( Min( ( ( aSource.Length() / 2 ) * 2 ), aTarget.MaxSize() ) ); - - // Append source to target using right endian - for ( TInt i = 0; i < length; i += 2 ) - { - aTarget.Append( TUint16( aSource[i + 1] | ( aSource[i] << 8) ) ); - } - - // Whe should still notify the requesting method about exceeding the length - if ( length < aSource.Length() ) - { - ret = KErrOverflow; - TFLOGSTRING2( "UTILITY: TSatUtility::ConvertUnicode16To7Bit,\ - Input data too long. %d bytes could not be converted", - ( aSource.Length() - length ) ); - } - - return ret; - } - -// ----------------------------------------------------------------------------- -// TSatUtility::DecodeCbsDcs -// Finds whether the data coding scheme, coded in CBS format, is 7-bit, 8-bit -// or 16-bit. Converts the input DCS from CBS format to SMS format. -// Reference: 3gpp ts 23.038 -// ----------------------------------------------------------------------------- -// -EXPORT_C TSmsDcs TSatUtility::DecodeCbsDcs - ( - const TUint8 aDcs - ) - { - TFLOGSTRING("UTILITY: TSatUtility::DecodeCbsDcs"); - - // Constant values are not defined in order to - // avoid confusion with too many constants names. - - // Coding group: 4 left most significant bits - TUint8 codingGroup = ( aDcs & 0xF0 )>>4; - // Lower quartet: 4 right most significant bits - TUint8 lowQuartet = ( aDcs & 0x0F ); - // Character set: bit 2 and 3, in [bit7...bit0] - TUint8 characterSet = ( aDcs & 0x0C )>>2; - // Initialize output to Unknown or Reserved - TSmsDcs decodedDcs( ESmsUnknownOrReservedDcs ); - // Switch according to the coding group - switch ( codingGroup ) - { - // Language specified, usually in 7-bit - // b0000 or b0010 or b0011 - case 0x00: - case 0x02: - case 0x03: - { - // 7-bit alphabet - decodedDcs = ESms7BitDcs; - break; - } - // b0001 - // Message preceded by language indication - case 0x01: - { - - if ( 0x00==lowQuartet ) - { - decodedDcs = ESms7BitDcs; - } - else if ( 0x01==lowQuartet ) - { - decodedDcs = ESms16BitDcs; - } - break; - } - // General data coding indication - // b01xx or b1001 - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x09: - { - // The character set determines the alphabet/compression - if ( 0x00 == characterSet ) - { - decodedDcs = ESms7BitDcs; - } - else if ( 0x01 == characterSet ) - { - decodedDcs = ESms8BitDcs; - } - else if ( 0x02 == characterSet ) - { - decodedDcs = ESms16BitDcs; - } - break; - } - // Data coding / Message handling - // either 8-bit or 7-bit - case 0x0F: - { - // only bit 2 informs about the - // character set. - if ( aDcs & 0x04 ) - { - decodedDcs = ESms8BitDcs; - } - else - { - decodedDcs = ESms7BitDcs; - } - break; - } - default: - { - // the DCS value is reserved. - TFLOGSTRING("UTILITY: TSatUtility::DecodeCbsDcs, reserved value"); - break; - } - } - return decodedDcs; - } - -// ----------------------------------------------------------------------------- -// TSatUtility::CopyTwo8toOne16LE -// Gets two 8-bit bytes and copies them to the one 16-bit byte with little -// endianes. Used when reading data from response or indication. -// ----------------------------------------------------------------------------- -// -EXPORT_C TInt TSatUtility::CopyTwo8toOne16LE - ( - const TDesC8& aSource, - TUint16& aTarget, - const TInt aIndex - ) - { - TFLOGSTRING("UTILITY: TSatUtility::CopyTwo8toOne16LE"); - TInt ret( KErrNone ); - // Check first that we dont try to read data that is not there.. - if ( aSource.Length() > aIndex + 1 ) - { - aTarget = static_cast( aSource[aIndex] << 8 ); - aTarget = static_cast( aTarget | aSource[aIndex + 1] ); - } - else - { - ret = KErrOverflow; - TFLOGSTRING3("UTILITY: TSatUtility::CopyTwo8toOne16LE, Index too high\ - Index: %d, Source data length: %d", aIndex, aSource.Length() ); - } - - return ret; - } - - -// End of file +// Copyright (c) 2006-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: +// Name : TSatUtility.cpp +// Part of : Common Sim Atk TSY / commonsimatktsy +// Sat Utility classes implementation. +// Version : 1.0 +// + + + +// INCLUDE FILES +#include "tsatutility.h" // Class header +#include "tflogger.h" // TFLOGSTRING +#include // TON and NPI constants + +// ----------------------------------------------------------------------------- +// TSatUtility::TonAndNpi +// Map TON and NPI to RSat TON and NPI values +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::TonAndNpi + ( + const TInt aTonAndNpi, + RSat::TTypeOfNumber* aTon, + RSat::TNumberingPlan* aNpi + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::TonAndNpi" ); + TInt ton( ( aTonAndNpi >> 4 ) & KTONMask ); // TON mask value 0x07 + + switch ( ton ) + { + case KTonUnknown: + { + *aTon = RSat::EUnknownNumber; + break; + } + case KInternationalNumber: + { + *aTon = RSat::EInternationalNumber; + break; + } + case KNationalNumber: + { + *aTon = RSat::ENationalNumber; + break; + } + case KNetworkSpecificNumber: + { + *aTon = RSat::ENetworkSpecificNumber; + break; + } + case KSubscriberNumber: + { + *aTon = RSat::EDedicatedNumber; + break; + } + case KAlphanumeric: + { + *aTon = RSat::EAlphanumericNumber; + break; + } + case KAbbreviatedNumber: + { + *aTon = RSat::EAbbreviatedNumber; + break; + } + default: + { + *aTon = RSat::ETypeOfNumberNotSet; + break; + } + } + + // Numbering plan + TInt npi( aTonAndNpi & KNPIMask ); // NPI mask value 0x0F + + switch ( npi ) + { + case KNpiUnknown: + { + *aNpi = RSat::EUnknownNumberingPlan; + break; + } + case KIsdnTelephoneNumPlan: + { + *aNpi = RSat::EIsdnNumberPlan; + break; + } + case KDataNumPlan: + { + *aNpi = RSat::EDataNumberPlan; + break; + } + case KTelexNumPlan: + { + *aNpi = RSat::ETelexNumberPlan; + break; + } + case KNationalNumPlan: + { + *aNpi = RSat::ENationalNumberPlan; + break; + } + case KPrivateNumPlan: + { + *aNpi = RSat::EPrivateNumberPlan; + break; + } + case KServiceCentreSpecificPlan1: + { + *aNpi = RSat::EServiceCentreSpecificPlan1; + break; + } + case KServiceCentreSpecificPlan2: + { + *aNpi = RSat::EServiceCentreSpecificPlan2; + break; + } + case KErmesNumPlan: + { + *aNpi = RSat::EERMESNumberPlan; + break; + } + default: + { + *aNpi = RSat::ENumberingPlanNotSet; + break; + } + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::Packed7to8Unpacked +// Converts 7-bit packed string to 8-bit unpacked format. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TSatUtility::Packed7to8Unpacked + ( + const TPtrC8 aSource, + TDes8& aTarget + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::Packed7to8Unpacked" ); + TInt ret( KErrNone ); + // The string is in packed GSM default alphabet format. + // Converted to 8-bit format + TUint8 maskRightPartOfCurrentByte( 0x7F ); + TUint8 shiftLeft( 0 ); + TUint8 leftPartFromPreviousByte( 0 ); + TInt sourceLength = aSource.Length(); + // Initialize the target string before starting + aTarget.Zero(); + + // Check out which string is the shortest and use its length as a limit + TInt length ( Min( sourceLength, aTarget.MaxLength() ) ); + for ( TInt i = 0; i < length; i++ ) + { + TUint8 leftPartOfCurrentChar = static_cast( ( + aSource[i] & maskRightPartOfCurrentByte ) << shiftLeft ); + + // Append the character in the output text string + aTarget.Append( leftPartOfCurrentChar | leftPartFromPreviousByte ); + + // Updates + if ( 6 == shiftLeft ) + { + // After 6 shifts, the character is in bit7..bit1, + // therefore it has to be shifted one bit to the right. + aTarget.Append( aSource[i] >> 1 ); + // Restart + leftPartFromPreviousByte = 0; + shiftLeft = 0; + maskRightPartOfCurrentByte = 0x7F; + } + else + { + leftPartFromPreviousByte = static_cast( ( + aSource[i] ) >> ( 7-shiftLeft ) ); + maskRightPartOfCurrentByte = static_cast( + maskRightPartOfCurrentByte >> 1 ); + shiftLeft++; + } + } + + // Whe should still notify the requesting method about exceeding the length + if ( length < sourceLength ) + { + ret = KErrOverflow; + TFLOGSTRING2( "UTILITY: TSatUtility::Packed7to8Unpacked,\ + Input data too long. %d bytes could not be converted", + ( sourceLength - length ) ); + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// TSatUtility::UCSToPacked7 +// Converts UCS2 string to 7-bit packed format +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::UCSToPacked7 + ( + const TPtrC aInput, + TDes8& aOutput + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::UCSToPacked7" ); + + TBuf8 string; + + // This method interrupts converting if the target buffer is full, so + // the length can not be exceeded + ConvertUnicode16To7Bit( aInput, string ); + + TUint8 move( 0 ); + TInt i( 0 ); + TInt length( string.Length() ); + + // If the input data was too long, some data will miss from the end here + for ( i = 0; i < length; i += 1 ) + { + // Get first character + TUint8 char1 = static_cast( string[i] >> move ); + TUint8 char2; + + if ( ( i + 1 ) < length ) + { + // Get next character + char2 = static_cast( string[i + 1] << ( 7 - move ) ); + } + else + { + // No more characters + char2 = 0; + } + // Append packed character + aOutput.Append( static_cast( char1 | char2 ) ); + + if ( ( 6 == move ) && char2 ) + { + i++; + move = 0; + } + else + { + move++; + } + } + + if ( !( ( length + 1 ) % 8 ) ) + { + // If the total number of characters in the text string equals (8n-1) + // where n=1,2,3 etc. then there are 7 spare bits at the end of the + // message. To avoid the situation where the receiving entity confuses + // 7 binary zero pad bits as the @ character, the carriage return + // (i.e. ) character shall be used for padding in this situation, + // as defined in TS 23.038 [5]. + aOutput[ aOutput.Length() - 1 ] = static_cast( + aOutput[ aOutput.Length() - 1 ] | KCrShiftedOneBitToLeft ); + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::BCDToAscii +// Converts BCD string to ASCII format +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TSatUtility::BCDToAscii + ( + const TPtrC8 aInput, + TDes8& aOutput + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::BCDToAscii" ); + TInt ret( KErrNone ); + + // Convert Abbreviated dialling numbers format back to ASCII format. + // See 3GPP TS 11.11, EFadn + aOutput.Zero(); + // Check out which string is the shortest and use its length as a limit + TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); + + for ( TInt i = 0; i < length; i++ ) + { + // Two bcd string chars are coded in one byte, + // 1st char is in low nibble and 2nd is in high nibble + // if the high nibble doesn't contain a char it's value is 0xf + TUint8 byte = aInput[i]; + aOutput.Append( KAscii[byte & 0x0F] ); + + if ( KMaskF0 != ( byte & KMaskF0 ) ) + { + aOutput.Append( KAscii[byte >> 4] ); + } + } + + // Whe should still notify the requesting method about exceeding the length + if ( length < aInput.Length() ) + { + ret = KErrOverflow; + TFLOGSTRING2( "UTILITY: TSatUtility::BCDToAscii,Input data too long.\ + %d bytes could not be converted", ( aInput.Length() - length ) ); + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// TSatUtility::AsciiToBCD +// Convert ASCII string to binary coded decimal, invalid characters are dropped +// and will not be part of bcd string. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TSatUtility::AsciiToBCD + ( + const TDesC8& aInput, + TDes8& aOutput + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::AsciiToBCD" ); + TInt ret( KErrNone ); + TInt i; + TInt j; + TInt outLen( 0 ); + TInt length( aInput.Length() ); + + aOutput.Zero(); + + // Go through the whole string + for ( i = 0; i < length; i++ ) + { + TUint8 bcd = 0x0F; // Should never be part of number + TBool found( EFalse ); + + // Search for the ASCII character + for ( j = 0; ( j < KAsciiBcdTableLength ) && !found; j++ ) + { + // If the character matches, set the corresponding value + if ( KAsciiToBCD[j][0] == aInput[i] ) + { + bcd = KAsciiToBCD[j][1]; + found = ETrue; + } + } + + // Add only valid bcd characters... + if ( found ) + { + if( aOutput.MaxLength() > aOutput.Length() ) + { + // Store to string + if ( ( outLen % 2 ) == 0 ) + { + aOutput.Append( bcd ); + } + else + { + aOutput[outLen / 2] |= ( bcd << 4 ); + } + } + else + { + TFLOGSTRING( "UTILITY: TSatUtility::AsciiToBCD, Overflow!" ); + ret = KErrOverflow; + } + + outLen++; + } + else + { + TFLOGSTRING3("UTILITY: TSatUtility::AsciiToBCD -- dropped \ + character %d at i=%d", TInt( aInput[i] ), i ); + } + + } // For + + // If odd number of digits add endmark + if ( ( outLen % 2 ) != 0 ) + { + aOutput[outLen / 2] |= KMaskF0; + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// TSatUtility::RemoveWildAndExpansionDigit +// Remove Wild 'w' and Expansion digit '.' from EFadn string. Used in SetUpCall +// proactive command. +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::RemoveWildAndExpansionDigit + ( + const TPtrC8 aString, + TDes8& aOutput + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::RemoveWildAndExpansionDigit" ); + aOutput.Zero(); + TUint8 i( 0 ); + TInt maxLength = aOutput.MaxLength(); + TInt length( aString.Length() ); + + // Append as many characters as there is room for in the target string + for ( i = 0; ( i < length ) && ( aOutput.Length() < maxLength ); i++ ) + { + if ( ( 'w' != aString[i] ) && ( '.' != aString[i] ) ) + { + aOutput.Append( aString[i] ); + } + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::SetAlphaId +// Set Alpha identifier as a Unicode text string and according to the alphabet +// used +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::SetAlphaId + ( + const TPtrC8 aRawData, + TDes& aAlphaId + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::SetAlphaId" ); + if ( ( KUCS2ArabicCoding == aRawData[0] ) + || ( KUCS2GreekCoding == aRawData[0] ) + || ( KUCS2TurkishCoding == aRawData[0] ) ) + { + ConvertAlphaFieldsToUnicode( aRawData, aAlphaId ); + } + else + { + // 8-bit + TBuf8 rawData8; + rawData8.Copy( aRawData ); + Convert7BitToUnicode16( rawData8, aAlphaId ); + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::ConvertToSemiOctet +// Convert integer to BCD format. Only two last digits is used. +// Example TInt 2004 -> 0x40. +// ----------------------------------------------------------------------------- +// +EXPORT_C TUint8 TSatUtility::ConvertToSemiOctet + ( + const TInt aTime + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::ConvertToSemiOctet" ); + // Converting given time to meet the TP-Service-Centre-Time-Stamp format in + // 3GPP TS 23.040. + + TInt msd( ( aTime / 10 ) % 10 ); // Most significant decimal + TInt lsd( ( aTime % 10 ) ); // Least significant decimal + TUint8 ret( TUint8( ( lsd << 4 ) | ( msd ) ) ); + return ret; + } + +// ----------------------------------------------------------------------------- +// TSatUtility::Convert7BitToUnicode16 +// Convert a text from GSM 7 bit default alphabet to Unicode format. +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::Convert7BitToUnicode16 + ( + const TDesC8& aInput, + TDes16& aOutput + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::Convert7BitToUnicode16" ); + TInt i( 0 ); + + aOutput.Zero(); + + // Check out which string is the shortest and use its length as a limit + TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); + + for( i = 0; i < length; i++ ) + { + TUint8 character( aInput[i] ); + + // This code is an escape to an extension of the 7 bit default alphabet + // table. + if ( 0x1B == character ) + { + // Extension table + switch ( aInput[i+1] ) + { + case 0x28: //{ + { + aOutput.Append( static_cast( 0x7B ) ); + break; + } + case 0x29: //} + { + aOutput.Append( static_cast( 0x7D ) ); + break; + } + case 0x3C: //[ + { + aOutput.Append( static_cast( 0x5B ) ); + break; + } + case 0x3E: //] + { + aOutput.Append( static_cast( 0x5D ) ); + break; + } + case 0x3D: //~ + { + aOutput.Append( static_cast( 0x7E ) ); + break; + } + case 0x2F: + { + aOutput.Append( static_cast( 0x5C ) ); + break; + } + case 0x14: // ^ + { + aOutput.Append( static_cast( 0x5E ) ); + break; + } + case 0x65: // Euro 0x20AC + { + aOutput.Append( static_cast( 0x20AC ) ); + break; + } + case 0x40: // | + { + aOutput.Append( static_cast( 0x7C ) ); + break; + } + default: + { + // A space if not found in the table + aOutput.Append( static_cast( 0x20 ) ); + break; + } + } + // Characters in extension table takes two bytes + i++; + } + // Check that bit 8 is set to '0' + else if ( 0x7F >= character ) + { + // Character is in normal 7-bit table. + aOutput.Append( KUnicode[ character ] ); + } + else + { + // Do nothing + } + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::ConvertUnicode16To7Bit +// Converts unicode16 string to GSM 7 bit default alphabet character mode +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TSatUtility::ConvertUnicode16To7Bit + ( + const TDesC16& aInput, + TDes8& aOutput + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::ConvertUnicode16To7Bit" ); + TInt i( 0 ); + TInt j( 0 ); + TInt ret( KErrNone ); + TBool found( EFalse ); + TInt outputMaxLength = aOutput.MaxLength(); + + // Check out which string is the shortest and use its length as a limit + TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) ); + for ( i = 0; i < length; i++ ) + { + for ( j = 0; j < KSizeOfConversionArray; j++ ) + { + if ( KUnicode16ToSms7[j][0] == aInput[i] ) + { + + aOutput.Append( static_cast( + KUnicode16ToSms7[j][1] ) ); + found = ETrue; + } + } + + if ( !found ) + { + aOutput.Append( static_cast( aInput[i] & 0x00FF ) ); + } + + found = EFalse; + } + + // Whe should still notify the requesting method about exceeding the length + if ( length < aInput.Length() ) + { + ret = KErrOverflow; + TFLOGSTRING2( "UTILITY: TSatUtility::ConvertUnicode16To7Bit,\ + Input data too long. %d bytes could not be converted", + ( aInput.Length() - length ) ); + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// TSatUtility::FillDurationStructure +// Fill in a TDuration structure +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::FillDurationStructure + ( + CBerTlv& aBerTlv, + RSat::TDuration& aTDuration + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::FillDurationStructure" ); + CTlv duration; + aTDuration.iTimeUnit = RSat::ENoDurationAvailable; + TInt returnValue( aBerTlv.TlvByTagValue( + &duration, KTlvDurationTag ) ); + + if ( KErrNotFound != returnValue ) + { + TUint8 durationTimeUnit = duration.GetShortInfo( ETLV_TimeUnit ); + switch ( durationTimeUnit ) + { + case KMinutes: + { + // Minutes + aTDuration.iTimeUnit = RSat::EMinutes; + break; + } + case KSeconds: + { + // Seconds + aTDuration.iTimeUnit = RSat::ESeconds; + break; + } + case KTenthsOfSeconds: + { + // Tenths of seconds + aTDuration.iTimeUnit = RSat::ETenthsOfSeconds; + break; + } + default: + { + aTDuration.iTimeUnit = RSat::ETimeUnitNotSet; + } + } + // Time interval + aTDuration.iNumOfUnits = duration.GetShortInfo( ETLV_TimeInterval ); + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::FillIconStructure +// Fill in a TIconId structure +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::FillIconStructure + ( + CBerTlv& aBerTlv, + RSat::TIconId& aTIconId, + const TInt aItemNmb + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::FillIconStructure" ); + CTlv iconId; + aTIconId.iQualifier = RSat::ENoIconId; + TInt returnValue( aBerTlv.TlvByTagValue( &iconId, KTlvIconIdentifierTag, + aItemNmb ) ); + + if ( KErrNotFound != returnValue ) + { + TUint8 iconQualifier = iconId.GetShortInfo( ETLV_IconQualifier ); + aTIconId.iIdentifier = iconId.GetShortInfo( ETLV_IconIdentifier ); + // The icon qualifier indicates to the ME how the icon is to be used. + if ( iconQualifier ) + { + aTIconId.iQualifier = RSat::ENotSelfExplanatory; + } + else + { + aTIconId.iQualifier = RSat::ESelfExplanatory; + } + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::SetText +// Set Text string as a Unicode text string and according to the alphabet used +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::SetText + ( + CTlv& aTextTlv, + TDes& aUnicodeOutput + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::SetText" ); + if ( aTextTlv.GetLength() ) + { + TPtrC8 sourceString; + + sourceString.Set( aTextTlv.GetData( ETLV_TextString ) ); + + TBuf8 string( sourceString ); + // SMS default alphabet DCS + if ( !( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) + & KPacked7BitTextMask ) ) + { + // Unpack + Packed7to8Unpacked( sourceString, string ); + + if ( aUnicodeOutput.MaxLength() < string.Length() ) + { + string.SetLength( aUnicodeOutput.MaxLength() ); + } + // Convert to unicode format + Convert7BitToUnicode16( string, aUnicodeOutput ); + } + // UCS2 DCS + else if ( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) + & KUCS2DCS ) + { + Copy8to16LE( sourceString, aUnicodeOutput ); + } + // 8-bit DCS + else if ( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) + & K8BitDCS ) + { + // 8-bit string to 16-bit string + Convert7BitToUnicode16( string, aUnicodeOutput ); + } + else // Reserved cases: SMS default alphabet + { + // Unpack + Packed7to8Unpacked( sourceString, string ); + + if ( aUnicodeOutput.MaxLength() < string.Length() ) + { + string.SetLength( aUnicodeOutput.MaxLength() ); + } + // Convert to unicode format + Convert7BitToUnicode16( string, aUnicodeOutput ); + } + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::ConvertAlphaFieldsToUnicode +// Convert Alpha fields format to Unicode format. +// ----------------------------------------------------------------------------- +// +EXPORT_C void TSatUtility::ConvertAlphaFieldsToUnicode + ( + const TDesC8& aSource, + TDes& aTarget + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::ConvertAlphaFieldsToUnicode" ); + // ArabicCoding, GreekCoding and TurkishCoding have different coding + // methods. There is a tag for each type of alphabet (resp. 80, 81 or 82) + // before the text, and there are base pointers used for expanding 1 byte + // to 2 bytes as required by UCS2 + // Ref: 3GPP TS 11.11, Annex B + + // Base pointer is a "half-page" in the UCS2 code space + TUint16 basePointer( 0 ); + TInt offset( 0 ); + + TInt ret( KErrNone ); + + switch ( aSource[0] ) + { + case KUCS2ArabicCoding: + { + // Copy everything after tag byte + Copy8to16LE( aSource.Mid( 1, aSource.Length() - 1 ), aTarget ); + //Check if any text present + if ( aTarget.Length() ) + { + // Remove padding bytes if any + if ( 0xFFFF == aTarget[ aTarget.Length() - 1 ] ) + { + aTarget.SetLength( aTarget.Length() - 1 ); + } + } + // No expanding needed, already in unicode format. + ret = KErrNotFound; + break; + } + case KUCS2GreekCoding: + { + // Characters starts at position 3 + offset = 3; + // Base pointer is given in one byte + // and needs to be sifted 7-bit to left to get correct base pointer + basePointer = TUint16( aSource[2] << 7 ) ; + break; + } + case KUCS2TurkishCoding: + { + // Characters starts at position 4 + offset = 4; + // Base pointer is two bytes, 16-bit + TSatUtility::CopyTwo8toOne16LE( aSource, basePointer, 2 ); + break; + } + default: + // Do nothing + break; + } + + if ( ( KErrNone == ret ) && ( 2 < aSource.Length() ) ) + { + // The second octet contains a value indicating the number of + // characters in the string. (Not in the case of Arabic string) + TInt length( aSource[1] ); + + // Expanding 1 byte format to 2 bytes + while ( length ) + { + // If bit 8 of the octet is set to zero, the remaining 7 bits of + // the octet contain a GSM Default Alphabet character, whereas if + // bit 8 of the octet is set to one, the remaining seven bits are + // an offset value added to the base pointer defined in octets + // three and four, and the resultant 16 bit value is a UCS2 code + // point, and defines a UCS2 character. + if ( 0x7F <= aSource[offset] ) + { + // Append base pointer and offset + aTarget.Append( basePointer + ( aSource[offset] & 0x7F ) ); + } + else + { + // GSM default alphabet. + TBuf<1> dest16bit; + TBuf8<1> src7bit; + // Get character + src7bit.Append( aSource[offset] ); + // Convert GSM default alphabet character to unicode + Convert7BitToUnicode16( src7bit, dest16bit ); + // Append converted character to output string + aTarget.Append( dest16bit ); + } + offset++; + length--; + } + } + } + +// ----------------------------------------------------------------------------- +// TSatUtility::Copy16to8LE +// Converts 16-bit data to 8-bit data with little endian. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TSatUtility::Copy16to8LE + ( + const TDesC16& aSource, + TDes8& aTarget + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::Copy16to8LE" ); + TInt ret( KErrNone ); + TInt length( 0 ); + + // Checks that data length are acceblable + if ( aSource.Size() > aTarget.MaxSize() ) + { + TFLOGSTRING( "UTILITY: TSatUtility::Copy16to8LE, Length exceeded!" ); + ret = KErrOverflow; + length = ( aTarget.MaxSize() / 2 ); + } + else + { + length = aSource.Length(); + } + + // Append source to target using rigth endian + for ( TInt i = 0; i < length; i++ ) + { + aTarget.Append( TUint8( aSource[i] >> 8) ); + aTarget.Append( TUint8( aSource[i] & 0xff ) ); + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// TSatUtility::Copy8to16LE +// Converts 8-bit data to 16-bit data with little endian +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TSatUtility::Copy8to16LE + ( + const TDesC8& aSource, + TDes16& aTarget + ) + { + TFLOGSTRING( "UTILITY: TSatUtility::Copy8to16LE" ); + TInt ret( KErrNone ); + // Check out which string is the shortest and use its length as a limit + TInt length ( Min( ( ( aSource.Length() / 2 ) * 2 ), aTarget.MaxSize() ) ); + + // Append source to target using right endian + for ( TInt i = 0; i < length; i += 2 ) + { + aTarget.Append( TUint16( aSource[i + 1] | ( aSource[i] << 8) ) ); + } + + // Whe should still notify the requesting method about exceeding the length + if ( length < aSource.Length() ) + { + ret = KErrOverflow; + TFLOGSTRING2( "UTILITY: TSatUtility::ConvertUnicode16To7Bit,\ + Input data too long. %d bytes could not be converted", + ( aSource.Length() - length ) ); + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// TSatUtility::DecodeCbsDcs +// Finds whether the data coding scheme, coded in CBS format, is 7-bit, 8-bit +// or 16-bit. Converts the input DCS from CBS format to SMS format. +// Reference: 3gpp ts 23.038 +// ----------------------------------------------------------------------------- +// +EXPORT_C TSmsDcs TSatUtility::DecodeCbsDcs + ( + const TUint8 aDcs + ) + { + TFLOGSTRING("UTILITY: TSatUtility::DecodeCbsDcs"); + + // Constant values are not defined in order to + // avoid confusion with too many constants names. + + // Coding group: 4 left most significant bits + TUint8 codingGroup = ( aDcs & 0xF0 )>>4; + // Lower quartet: 4 right most significant bits + TUint8 lowQuartet = ( aDcs & 0x0F ); + // Character set: bit 2 and 3, in [bit7...bit0] + TUint8 characterSet = ( aDcs & 0x0C )>>2; + // Initialize output to Unknown or Reserved + TSmsDcs decodedDcs( ESmsUnknownOrReservedDcs ); + // Switch according to the coding group + switch ( codingGroup ) + { + // Language specified, usually in 7-bit + // b0000 or b0010 or b0011 + case 0x00: + case 0x02: + case 0x03: + { + // 7-bit alphabet + decodedDcs = ESms7BitDcs; + break; + } + // b0001 + // Message preceded by language indication + case 0x01: + { + + if ( 0x00==lowQuartet ) + { + decodedDcs = ESms7BitDcs; + } + else if ( 0x01==lowQuartet ) + { + decodedDcs = ESms16BitDcs; + } + break; + } + // General data coding indication + // b01xx or b1001 + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x09: + { + // The character set determines the alphabet/compression + if ( 0x00 == characterSet ) + { + decodedDcs = ESms7BitDcs; + } + else if ( 0x01 == characterSet ) + { + decodedDcs = ESms8BitDcs; + } + else if ( 0x02 == characterSet ) + { + decodedDcs = ESms16BitDcs; + } + break; + } + // Data coding / Message handling + // either 8-bit or 7-bit + case 0x0F: + { + // only bit 2 informs about the + // character set. + if ( aDcs & 0x04 ) + { + decodedDcs = ESms8BitDcs; + } + else + { + decodedDcs = ESms7BitDcs; + } + break; + } + default: + { + // the DCS value is reserved. + TFLOGSTRING("UTILITY: TSatUtility::DecodeCbsDcs, reserved value"); + break; + } + } + return decodedDcs; + } + +// ----------------------------------------------------------------------------- +// TSatUtility::CopyTwo8toOne16LE +// Gets two 8-bit bytes and copies them to the one 16-bit byte with little +// endianes. Used when reading data from response or indication. +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt TSatUtility::CopyTwo8toOne16LE + ( + const TDesC8& aSource, + TUint16& aTarget, + const TInt aIndex + ) + { + TFLOGSTRING("UTILITY: TSatUtility::CopyTwo8toOne16LE"); + TInt ret( KErrNone ); + // Check first that we dont try to read data that is not there.. + if ( aSource.Length() > aIndex + 1 ) + { + aTarget = static_cast( aSource[aIndex] << 8 ); + aTarget = static_cast( aTarget | aSource[aIndex + 1] ); + } + else + { + ret = KErrOverflow; + TFLOGSTRING3("UTILITY: TSatUtility::CopyTwo8toOne16LE, Index too high\ + Index: %d, Source data length: %d", aIndex, aSource.Length() ); + } + + return ret; + } + + +// End of file