// 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 <ctsy/serviceapi/cmmsmsutility.h> // 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<TUint8>( ( 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<TUint8>( ( aSource[i] ) >> ( 7-shiftLeft ) ); maskRightPartOfCurrentByte = static_cast<TUint8>( 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<KMaxUssdStringLengthInBytes> 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<TUint8>( string[i] >> move ); TUint8 char2; if ( ( i + 1 ) < length ) { // Get next character char2 = static_cast<TUint8>( string[i + 1] << ( 7 - move ) ); } else { // No more characters char2 = 0; } // Append packed character aOutput.Append( static_cast<TUint8>( 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. <CR>) character shall be used for padding in this situation, // as defined in TS 23.038 [5]. aOutput[ aOutput.Length() - 1 ] = static_cast<TUint8>( 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<RSat::KAlphaIdMaxSize> 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<TUint16>( 0x7B ) ); break; } case 0x29: //} { aOutput.Append( static_cast<TUint16>( 0x7D ) ); break; } case 0x3C: //[ { aOutput.Append( static_cast<TUint16>( 0x5B ) ); break; } case 0x3E: //] { aOutput.Append( static_cast<TUint16>( 0x5D ) ); break; } case 0x3D: //~ { aOutput.Append( static_cast<TUint16>( 0x7E ) ); break; } case 0x2F: { aOutput.Append( static_cast<TUint16>( 0x5C ) ); break; } case 0x14: // ^ { aOutput.Append( static_cast<TUint16>( 0x5E ) ); break; } case 0x65: // Euro 0x20AC { aOutput.Append( static_cast<TUint16>( 0x20AC ) ); break; } case 0x40: // | { aOutput.Append( static_cast<TUint16>( 0x7C ) ); break; } default: { // A space if not found in the table aOutput.Append( static_cast<TUint16>( 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<TUint8>( KUnicode16ToSms7[j][1] ) ); found = ETrue; } } if ( !found ) { aOutput.Append( static_cast<TUint8>( 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<KTextBufferMaxSize> 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<TUint16>( aSource[aIndex] << 8 ); aTarget = static_cast<TUint16>( 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