telephonyserverplugins/simatktsy/utility/src/tsatutility.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2006-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 // Name        : TSatUtility.cpp
       
    15 // Part of     : Common Sim Atk TSY / commonsimatktsy
       
    16 // Sat Utility classes implementation.
       
    17 // Version     : 1.0
       
    18 //
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include "tsatutility.h"        // Class header
       
    24 #include "tflogger.h"           // TFLOGSTRING
       
    25 #include <ctsy/serviceapi/cmmsmsutility.h>		// TON and NPI constants
       
    26 
       
    27 // -----------------------------------------------------------------------------
       
    28 // TSatUtility::TonAndNpi
       
    29 // Map TON and NPI to RSat TON and NPI values
       
    30 // -----------------------------------------------------------------------------
       
    31 //
       
    32 EXPORT_C void TSatUtility::TonAndNpi
       
    33         (
       
    34         const TInt aTonAndNpi,                
       
    35         RSat::TTypeOfNumber* aTon,      
       
    36         RSat::TNumberingPlan* aNpi      
       
    37         )
       
    38     {
       
    39     TFLOGSTRING( "UTILITY: TSatUtility::TonAndNpi" );
       
    40     TInt ton( ( aTonAndNpi >> 4 ) & KTONMask ); // TON mask value 0x07
       
    41 
       
    42     switch ( ton )
       
    43         {
       
    44         case KTonUnknown:
       
    45             {
       
    46             *aTon = RSat::EUnknownNumber;
       
    47             break;
       
    48             }
       
    49         case KInternationalNumber:
       
    50             {
       
    51             *aTon = RSat::EInternationalNumber;
       
    52             break;
       
    53             }
       
    54         case KNationalNumber:
       
    55             {
       
    56             *aTon = RSat::ENationalNumber;
       
    57             break;                    
       
    58             }
       
    59         case KNetworkSpecificNumber:
       
    60             {
       
    61             *aTon = RSat::ENetworkSpecificNumber;
       
    62             break;
       
    63             }
       
    64         case KSubscriberNumber:
       
    65             {
       
    66             *aTon = RSat::EDedicatedNumber;
       
    67             break;
       
    68             }
       
    69         case KAlphanumeric:         
       
    70             {
       
    71             *aTon = RSat::EAlphanumericNumber;
       
    72             break;
       
    73             }
       
    74         case KAbbreviatedNumber:    
       
    75             {
       
    76             *aTon = RSat::EAbbreviatedNumber;
       
    77             break;
       
    78             }
       
    79         default:
       
    80             {
       
    81             *aTon = RSat::ETypeOfNumberNotSet;
       
    82             break;
       
    83             }
       
    84         }
       
    85 
       
    86     // Numbering plan
       
    87     TInt npi( aTonAndNpi & KNPIMask ); // NPI mask value 0x0F
       
    88 
       
    89     switch ( npi )
       
    90         {
       
    91         case KNpiUnknown:
       
    92             {
       
    93             *aNpi = RSat::EUnknownNumberingPlan;
       
    94             break;
       
    95             }
       
    96         case KIsdnTelephoneNumPlan:
       
    97             {
       
    98             *aNpi = RSat::EIsdnNumberPlan;
       
    99             break;
       
   100             }
       
   101         case KDataNumPlan:
       
   102             {
       
   103             *aNpi = RSat::EDataNumberPlan;
       
   104             break;
       
   105             }
       
   106         case KTelexNumPlan:
       
   107             {
       
   108             *aNpi = RSat::ETelexNumberPlan;
       
   109             break;
       
   110             }
       
   111         case KNationalNumPlan:
       
   112             {
       
   113             *aNpi = RSat::ENationalNumberPlan;
       
   114             break;
       
   115             }
       
   116         case KPrivateNumPlan:
       
   117             {
       
   118             *aNpi = RSat::EPrivateNumberPlan;
       
   119             break;
       
   120             }
       
   121         case KServiceCentreSpecificPlan1:
       
   122             {
       
   123             *aNpi = RSat::EServiceCentreSpecificPlan1;
       
   124             break;
       
   125             }
       
   126         case KServiceCentreSpecificPlan2:
       
   127             {
       
   128             *aNpi = RSat::EServiceCentreSpecificPlan2;
       
   129             break;
       
   130             }
       
   131         case KErmesNumPlan:    
       
   132             {
       
   133             *aNpi = RSat::EERMESNumberPlan;
       
   134             break;
       
   135             }
       
   136         default:
       
   137             {
       
   138             *aNpi = RSat::ENumberingPlanNotSet;
       
   139             break;
       
   140             }
       
   141         }
       
   142     }
       
   143 
       
   144 // -----------------------------------------------------------------------------
       
   145 // TSatUtility::Packed7to8Unpacked
       
   146 // Converts 7-bit packed string to 8-bit unpacked format.
       
   147 // -----------------------------------------------------------------------------
       
   148 //
       
   149 EXPORT_C TInt TSatUtility::Packed7to8Unpacked
       
   150         ( 
       
   151         const TPtrC8 aSource,   
       
   152         TDes8& aTarget    
       
   153         )
       
   154     {
       
   155     TFLOGSTRING( "UTILITY: TSatUtility::Packed7to8Unpacked" );
       
   156     TInt ret( KErrNone );
       
   157     // The string is in packed GSM default alphabet format.
       
   158     // Converted to 8-bit format
       
   159     TUint8 maskRightPartOfCurrentByte( 0x7F );
       
   160     TUint8 shiftLeft( 0 );
       
   161     TUint8 leftPartFromPreviousByte( 0 );  
       
   162     TInt sourceLength = aSource.Length();  
       
   163     // Initialize the target string before starting
       
   164     aTarget.Zero();
       
   165     
       
   166     // Check out which string is the shortest and use its length as a limit
       
   167     TInt length ( Min( sourceLength, aTarget.MaxLength() ) );
       
   168     for ( TInt i = 0; i < length; i++ )
       
   169         {
       
   170         TUint8 leftPartOfCurrentChar =  static_cast<TUint8>( ( 
       
   171             aSource[i] & maskRightPartOfCurrentByte ) << shiftLeft );
       
   172             
       
   173         // Append the character in the output text string
       
   174         aTarget.Append( leftPartOfCurrentChar | leftPartFromPreviousByte );  
       
   175               
       
   176         // Updates         
       
   177         if ( 6 == shiftLeft )
       
   178             {
       
   179             // After 6 shifts, the character is in bit7..bit1, 
       
   180             // therefore it has to be shifted one bit to the right.
       
   181             aTarget.Append( aSource[i] >> 1 );
       
   182             // Restart
       
   183             leftPartFromPreviousByte = 0;
       
   184             shiftLeft = 0;
       
   185             maskRightPartOfCurrentByte = 0x7F;            
       
   186             }
       
   187         else
       
   188             {
       
   189             leftPartFromPreviousByte = static_cast<TUint8>( ( 
       
   190                 aSource[i] ) >> ( 7-shiftLeft ) );
       
   191             maskRightPartOfCurrentByte = static_cast<TUint8>( 
       
   192                 maskRightPartOfCurrentByte >> 1 );
       
   193             shiftLeft++;
       
   194             } 
       
   195         }   
       
   196         
       
   197     // Whe should still notify the requesting method about exceeding the length
       
   198     if ( length < sourceLength )
       
   199         {
       
   200         ret = KErrOverflow;
       
   201         TFLOGSTRING2( "UTILITY: TSatUtility::Packed7to8Unpacked,\
       
   202             Input data too long. %d bytes could not be converted", 
       
   203             ( sourceLength - length ) );
       
   204         }
       
   205   
       
   206     return ret;
       
   207     }
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // TSatUtility::UCSToPacked7
       
   211 // Converts UCS2 string to 7-bit packed format
       
   212 // -----------------------------------------------------------------------------
       
   213 //
       
   214 EXPORT_C void TSatUtility::UCSToPacked7
       
   215         ( 
       
   216         const TPtrC aInput,   
       
   217         TDes8& aOutput   
       
   218         )
       
   219     {
       
   220     TFLOGSTRING( "UTILITY: TSatUtility::UCSToPacked7" );
       
   221     
       
   222     TBuf8<KMaxUssdStringLengthInBytes> string;
       
   223     
       
   224     // This method interrupts converting if the target buffer is full, so
       
   225     // the length can not be exceeded
       
   226     ConvertUnicode16To7Bit( aInput, string ); 
       
   227 
       
   228     TUint8 move( 0 );
       
   229     TInt i( 0 );
       
   230     TInt length( string.Length() );
       
   231 
       
   232     // If the input data was too long, some data will miss from the end here
       
   233     for ( i = 0; i < length; i += 1 )
       
   234         {
       
   235         // Get first character
       
   236         TUint8 char1 = static_cast<TUint8>( string[i] >> move ); 
       
   237         TUint8 char2;
       
   238         
       
   239         if ( ( i + 1 ) < length )
       
   240             {
       
   241             // Get next character
       
   242             char2 = static_cast<TUint8>( string[i + 1]  << ( 7 - move ) );
       
   243             }
       
   244         else
       
   245             {
       
   246             // No more characters
       
   247             char2 = 0;
       
   248             }
       
   249         // Append packed character
       
   250         aOutput.Append( static_cast<TUint8>( char1 | char2 ) );
       
   251 
       
   252         if ( ( 6 == move ) && char2 )
       
   253             {
       
   254             i++;
       
   255             move = 0;
       
   256             }
       
   257         else
       
   258             {
       
   259             move++;
       
   260             }
       
   261         }
       
   262 
       
   263     if ( !( ( length + 1 ) % 8 ) )
       
   264         {
       
   265         // If the total number of characters in the text string equals (8n-1) 
       
   266         // where n=1,2,3 etc. then there are 7 spare bits at the end of the 
       
   267         // message. To avoid the situation where the receiving entity confuses
       
   268         // 7 binary zero pad bits as the @ character, the carriage return 
       
   269         // (i.e. <CR>) character shall be used for padding in this situation,
       
   270         // as defined in TS 23.038 [5].
       
   271         aOutput[  aOutput.Length() - 1 ] = static_cast<TUint8>( 
       
   272             aOutput[ aOutput.Length() - 1 ] | KCrShiftedOneBitToLeft );
       
   273         }
       
   274     }
       
   275 
       
   276 // -----------------------------------------------------------------------------
       
   277 // TSatUtility::BCDToAscii
       
   278 // Converts BCD string to ASCII format
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 EXPORT_C TInt TSatUtility::BCDToAscii		
       
   282         ( 
       
   283         const TPtrC8 aInput,  
       
   284         TDes8& aOutput   
       
   285         )
       
   286     {
       
   287     TFLOGSTRING( "UTILITY: TSatUtility::BCDToAscii" );
       
   288     TInt ret( KErrNone );
       
   289     
       
   290     // Convert Abbreviated dialling numbers format back to ASCII format.
       
   291     // See 3GPP TS 11.11, EFadn
       
   292     aOutput.Zero();
       
   293     // Check out which string is the shortest and use its length as a limit
       
   294     TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) );
       
   295     
       
   296     for ( TInt i = 0; i < length; i++ )
       
   297         {
       
   298         // Two bcd string chars are coded in one byte,
       
   299         // 1st char is in low nibble and 2nd is in high nibble
       
   300         // if the high nibble doesn't contain a char it's value is 0xf
       
   301         TUint8 byte = aInput[i];
       
   302         aOutput.Append( KAscii[byte & 0x0F] );
       
   303         
       
   304         if ( KMaskF0 != ( byte & KMaskF0 ) )
       
   305             {
       
   306             aOutput.Append( KAscii[byte >> 4] );
       
   307             }
       
   308         }
       
   309         
       
   310     // Whe should still notify the requesting method about exceeding the length
       
   311     if ( length < aInput.Length() )
       
   312         {
       
   313         ret = KErrOverflow;
       
   314         TFLOGSTRING2( "UTILITY: TSatUtility::BCDToAscii,Input data too long.\
       
   315             %d bytes could not be converted", ( aInput.Length() - length ) );
       
   316         }    
       
   317         
       
   318     return ret;
       
   319     }
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 // TSatUtility::AsciiToBCD
       
   323 // Convert ASCII string to binary coded decimal, invalid characters are dropped 
       
   324 // and will not be part of bcd string.
       
   325 // -----------------------------------------------------------------------------
       
   326 //
       
   327 EXPORT_C TInt TSatUtility::AsciiToBCD
       
   328         ( 
       
   329         const TDesC8& aInput, 
       
   330         TDes8& aOutput        
       
   331         )
       
   332     {
       
   333     TFLOGSTRING( "UTILITY: TSatUtility::AsciiToBCD" );
       
   334     TInt ret( KErrNone );
       
   335     TInt i;
       
   336     TInt j;
       
   337     TInt outLen( 0 );
       
   338     TInt length( aInput.Length() );
       
   339     
       
   340     aOutput.Zero();
       
   341     
       
   342     // Go through the whole string
       
   343     for ( i = 0; i < length; i++ )
       
   344         {
       
   345         TUint8 bcd = 0x0F;  // Should never be part of number
       
   346         TBool found( EFalse );
       
   347         
       
   348         // Search for the ASCII character
       
   349         for ( j = 0; ( j < KAsciiBcdTableLength ) && !found; j++ )
       
   350             {
       
   351             // If the character matches, set the corresponding value
       
   352             if ( KAsciiToBCD[j][0] == aInput[i] )
       
   353                 {
       
   354                 bcd = KAsciiToBCD[j][1];
       
   355                 found = ETrue;
       
   356                 }
       
   357             }
       
   358 
       
   359         // Add only valid bcd characters...
       
   360         if ( found )
       
   361             {
       
   362             if( aOutput.MaxLength() > aOutput.Length() )
       
   363             	{               	
       
   364 	            // Store to string
       
   365 	            if ( ( outLen % 2 ) == 0 )
       
   366 	                {
       
   367 	                aOutput.Append( bcd );
       
   368 	                }
       
   369 	            else
       
   370 	                {
       
   371 	                aOutput[outLen / 2] |= ( bcd << 4 );
       
   372 	                }
       
   373             	}
       
   374             else
       
   375                 {
       
   376                 TFLOGSTRING( "UTILITY: TSatUtility::AsciiToBCD, Overflow!" );
       
   377                 ret = KErrOverflow;
       
   378                 }
       
   379                 
       
   380             outLen++;
       
   381             }
       
   382         else
       
   383             {
       
   384             TFLOGSTRING3("UTILITY: TSatUtility::AsciiToBCD -- dropped \
       
   385                 character %d at i=%d", TInt( aInput[i] ), i );
       
   386             }
       
   387             
       
   388         } // For
       
   389 
       
   390     // If odd number of digits add endmark
       
   391     if ( ( outLen % 2 ) != 0 )
       
   392         {
       
   393         aOutput[outLen / 2] |= KMaskF0;
       
   394         }
       
   395         
       
   396     return ret;
       
   397     }
       
   398 
       
   399 // -----------------------------------------------------------------------------
       
   400 // TSatUtility::RemoveWildAndExpansionDigit
       
   401 // Remove Wild 'w' and Expansion digit '.' from EFadn string. Used in SetUpCall 
       
   402 // proactive command.
       
   403 // -----------------------------------------------------------------------------
       
   404 //
       
   405 EXPORT_C void TSatUtility::RemoveWildAndExpansionDigit
       
   406         (
       
   407         const TPtrC8 aString,  
       
   408         TDes8& aOutput   
       
   409         )
       
   410     {
       
   411     TFLOGSTRING( "UTILITY: TSatUtility::RemoveWildAndExpansionDigit" );
       
   412     aOutput.Zero();    
       
   413     TUint8 i( 0 );
       
   414     TInt maxLength = aOutput.MaxLength();
       
   415     TInt length( aString.Length() );
       
   416     
       
   417     // Append as many characters as there is room for in the target string
       
   418     for ( i = 0; ( i < length ) && ( aOutput.Length() < maxLength ); i++ )
       
   419         {
       
   420         if ( ( 'w' != aString[i] ) && ( '.' != aString[i] ) )
       
   421             {
       
   422             aOutput.Append( aString[i] );
       
   423             }
       
   424         }
       
   425     }
       
   426 
       
   427 // -----------------------------------------------------------------------------
       
   428 // TSatUtility::SetAlphaId
       
   429 // Set Alpha identifier as a Unicode text string and according to the alphabet 
       
   430 // used
       
   431 // -----------------------------------------------------------------------------
       
   432 //
       
   433 EXPORT_C void TSatUtility::SetAlphaId				
       
   434         ( 
       
   435         const TPtrC8 aRawData, 
       
   436         TDes& aAlphaId  
       
   437         )
       
   438     {
       
   439     TFLOGSTRING( "UTILITY: TSatUtility::SetAlphaId" );
       
   440     if ( ( KUCS2ArabicCoding == aRawData[0] )
       
   441         || ( KUCS2GreekCoding == aRawData[0] )
       
   442         || ( KUCS2TurkishCoding == aRawData[0] ) )
       
   443         {
       
   444         ConvertAlphaFieldsToUnicode( aRawData, aAlphaId );
       
   445         }
       
   446     else
       
   447         {
       
   448         // 8-bit 
       
   449         TBuf8<RSat::KAlphaIdMaxSize> rawData8;
       
   450         rawData8.Copy( aRawData );
       
   451         Convert7BitToUnicode16( rawData8, aAlphaId );
       
   452         }     
       
   453     }
       
   454 
       
   455 // -----------------------------------------------------------------------------
       
   456 // TSatUtility::ConvertToSemiOctet
       
   457 // Convert integer to BCD format. Only two last digits is used.
       
   458 // Example TInt 2004 -> 0x40.
       
   459 // -----------------------------------------------------------------------------
       
   460 //
       
   461 EXPORT_C TUint8 TSatUtility::ConvertToSemiOctet
       
   462         ( 
       
   463         const TInt aTime  
       
   464         )
       
   465     {
       
   466     TFLOGSTRING( "UTILITY: TSatUtility::ConvertToSemiOctet" );
       
   467     // Converting given time to meet the TP-Service-Centre-Time-Stamp format in
       
   468     // 3GPP TS 23.040.
       
   469 
       
   470     TInt msd( ( aTime / 10 ) % 10 ); // Most significant decimal
       
   471     TInt lsd( ( aTime % 10 ) );      // Least significant decimal
       
   472     TUint8 ret( TUint8( ( lsd << 4 ) | ( msd ) ) );
       
   473     return ret;
       
   474     }
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // TSatUtility::Convert7BitToUnicode16
       
   478 // Convert a text from GSM 7 bit default alphabet to Unicode format.
       
   479 // -----------------------------------------------------------------------------
       
   480 //
       
   481 EXPORT_C void TSatUtility::Convert7BitToUnicode16
       
   482         (
       
   483         const TDesC8& aInput,
       
   484         TDes16& aOutput  
       
   485         )
       
   486     {
       
   487     TFLOGSTRING( "UTILITY: TSatUtility::Convert7BitToUnicode16" );
       
   488     TInt i( 0 );
       
   489     
       
   490     aOutput.Zero();
       
   491     
       
   492     // Check out which string is the shortest and use its length as a limit
       
   493     TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) );
       
   494     
       
   495     for( i = 0; i < length; i++ )
       
   496         {
       
   497         TUint8 character( aInput[i] );
       
   498 
       
   499         // This code is an escape to an extension of the 7 bit default alphabet
       
   500         // table. 
       
   501         if ( 0x1B == character )
       
   502             {
       
   503             // Extension table
       
   504             switch ( aInput[i+1] )
       
   505                 {
       
   506                 case 0x28: //{
       
   507                     {
       
   508                     aOutput.Append( static_cast<TUint16>( 0x7B ) );
       
   509                     break;
       
   510                     }
       
   511                 case 0x29: //}
       
   512                     {
       
   513                     aOutput.Append( static_cast<TUint16>( 0x7D ) );
       
   514                     break;
       
   515                     }
       
   516                 case 0x3C: //[
       
   517                     {
       
   518                     aOutput.Append( static_cast<TUint16>( 0x5B ) );
       
   519                     break;
       
   520                     }
       
   521                 case 0x3E: //]
       
   522                     {
       
   523                     aOutput.Append( static_cast<TUint16>( 0x5D ) );
       
   524                     break;
       
   525                     }
       
   526                 case 0x3D: //~
       
   527                     {
       
   528                     aOutput.Append( static_cast<TUint16>( 0x7E ) );
       
   529                     break;
       
   530                     }
       
   531                 case 0x2F: 
       
   532                     {
       
   533                     aOutput.Append( static_cast<TUint16>( 0x5C ) );
       
   534                     break;
       
   535                     }
       
   536                 case 0x14: // ^
       
   537                     {
       
   538                     aOutput.Append( static_cast<TUint16>( 0x5E ) );
       
   539                     break;
       
   540                     }
       
   541                 case 0x65: // Euro 0x20AC
       
   542                     {
       
   543                     aOutput.Append( static_cast<TUint16>( 0x20AC ) );
       
   544                     break;
       
   545                     }
       
   546                 case 0x40: // |
       
   547                     {
       
   548                     aOutput.Append( static_cast<TUint16>( 0x7C ) );
       
   549                     break;
       
   550                     }
       
   551                 default:
       
   552                     {
       
   553                     // A space if not found in the table
       
   554                     aOutput.Append( static_cast<TUint16>( 0x20 ) );
       
   555                     break;
       
   556                     }
       
   557                 }
       
   558             // Characters in extension table takes two bytes
       
   559             i++;
       
   560             }
       
   561         // Check that bit 8 is set to '0'
       
   562         else if ( 0x7F >= character )
       
   563             {
       
   564             // Character is in normal 7-bit table.
       
   565             aOutput.Append( KUnicode[ character ] );
       
   566             }
       
   567         else
       
   568             {
       
   569             // Do nothing
       
   570             }
       
   571         }
       
   572     }
       
   573 
       
   574 // -----------------------------------------------------------------------------
       
   575 // TSatUtility::ConvertUnicode16To7Bit
       
   576 // Converts unicode16 string to GSM 7 bit default alphabet character mode
       
   577 // -----------------------------------------------------------------------------
       
   578 //
       
   579 EXPORT_C TInt TSatUtility::ConvertUnicode16To7Bit
       
   580         (
       
   581         const TDesC16& aInput,
       
   582         TDes8& aOutput   
       
   583         )
       
   584     {
       
   585     TFLOGSTRING( "UTILITY: TSatUtility::ConvertUnicode16To7Bit" );
       
   586     TInt i( 0 );
       
   587     TInt j( 0 );
       
   588     TInt ret( KErrNone );
       
   589     TBool found( EFalse );
       
   590     TInt outputMaxLength = aOutput.MaxLength();
       
   591     
       
   592     // Check out which string is the shortest and use its length as a limit
       
   593     TInt length ( Min( aInput.Length(), aOutput.MaxLength() ) );
       
   594     for ( i = 0; i < length; i++ )
       
   595         {
       
   596         for ( j = 0; j < KSizeOfConversionArray; j++ )
       
   597             {
       
   598             if ( KUnicode16ToSms7[j][0] == aInput[i] )
       
   599                 {
       
   600 
       
   601                 aOutput.Append( static_cast<TUint8>( 
       
   602                     KUnicode16ToSms7[j][1] ) );
       
   603                 found = ETrue;
       
   604                 }
       
   605             }
       
   606             
       
   607         if ( !found )
       
   608             {
       
   609             aOutput.Append( static_cast<TUint8>( aInput[i] & 0x00FF ) );
       
   610             }
       
   611             
       
   612         found = EFalse;                        
       
   613         }
       
   614     
       
   615     // Whe should still notify the requesting method about exceeding the length
       
   616     if ( length < aInput.Length() )
       
   617         {
       
   618         ret = KErrOverflow;
       
   619         TFLOGSTRING2( "UTILITY: TSatUtility::ConvertUnicode16To7Bit,\
       
   620             Input data too long. %d bytes could not be converted", 
       
   621             ( aInput.Length() - length ) );
       
   622         }
       
   623         
       
   624     return ret;
       
   625     }
       
   626 
       
   627 // -----------------------------------------------------------------------------
       
   628 // TSatUtility::FillDurationStructure
       
   629 // Fill in a TDuration structure
       
   630 // -----------------------------------------------------------------------------
       
   631 //
       
   632 EXPORT_C void TSatUtility::FillDurationStructure
       
   633         (
       
   634         CBerTlv& aBerTlv,             
       
   635         RSat::TDuration& aTDuration   
       
   636         )
       
   637     {
       
   638     TFLOGSTRING( "UTILITY: TSatUtility::FillDurationStructure" );
       
   639     CTlv duration;
       
   640     aTDuration.iTimeUnit = RSat::ENoDurationAvailable;
       
   641     TInt returnValue( aBerTlv.TlvByTagValue( 
       
   642         &duration, KTlvDurationTag ) );
       
   643         
       
   644     if ( KErrNotFound != returnValue )
       
   645         {
       
   646         TUint8 durationTimeUnit = duration.GetShortInfo( ETLV_TimeUnit );
       
   647         switch ( durationTimeUnit )
       
   648             {
       
   649             case KMinutes:
       
   650                 {
       
   651                 // Minutes
       
   652                 aTDuration.iTimeUnit = RSat::EMinutes;
       
   653                 break;
       
   654                 }
       
   655             case KSeconds:
       
   656                 {
       
   657                 // Seconds
       
   658                 aTDuration.iTimeUnit = RSat::ESeconds;
       
   659                 break;
       
   660                 }
       
   661             case KTenthsOfSeconds:
       
   662                 {
       
   663                 // Tenths of seconds
       
   664                 aTDuration.iTimeUnit = RSat::ETenthsOfSeconds;
       
   665                 break;
       
   666                 }
       
   667             default:
       
   668                 {
       
   669                 aTDuration.iTimeUnit = RSat::ETimeUnitNotSet;
       
   670                 }
       
   671             }
       
   672             // Time interval
       
   673             aTDuration.iNumOfUnits = duration.GetShortInfo( ETLV_TimeInterval );     
       
   674         }
       
   675     }
       
   676 
       
   677 // -----------------------------------------------------------------------------
       
   678 // TSatUtility::FillIconStructure
       
   679 // Fill in a TIconId structure
       
   680 // -----------------------------------------------------------------------------
       
   681 //
       
   682 EXPORT_C void TSatUtility::FillIconStructure
       
   683         ( 
       
   684         CBerTlv& aBerTlv,        
       
   685         RSat::TIconId& aTIconId, 
       
   686         const TInt aItemNmb            
       
   687         )
       
   688     {
       
   689     TFLOGSTRING( "UTILITY: TSatUtility::FillIconStructure" );
       
   690     CTlv iconId;
       
   691     aTIconId.iQualifier = RSat::ENoIconId;
       
   692     TInt returnValue( aBerTlv.TlvByTagValue( &iconId, KTlvIconIdentifierTag, 
       
   693         aItemNmb ) );
       
   694     
       
   695     if ( KErrNotFound != returnValue )
       
   696         {
       
   697         TUint8 iconQualifier = iconId.GetShortInfo( ETLV_IconQualifier );        
       
   698         aTIconId.iIdentifier = iconId.GetShortInfo( ETLV_IconIdentifier );
       
   699         // The icon qualifier indicates to the ME how the icon is to be used.
       
   700         if ( iconQualifier )
       
   701             {
       
   702             aTIconId.iQualifier = RSat::ENotSelfExplanatory;
       
   703             }
       
   704         else
       
   705             {
       
   706             aTIconId.iQualifier = RSat::ESelfExplanatory;
       
   707             }
       
   708         }
       
   709     }
       
   710 
       
   711 // -----------------------------------------------------------------------------
       
   712 // TSatUtility::SetText
       
   713 // Set Text string as a Unicode text string and according to the alphabet used
       
   714 // -----------------------------------------------------------------------------
       
   715 //
       
   716 EXPORT_C void TSatUtility::SetText 
       
   717         (
       
   718         CTlv& aTextTlv, 
       
   719         TDes& aUnicodeOutput   
       
   720         ) 
       
   721     {
       
   722     TFLOGSTRING( "UTILITY: TSatUtility::SetText" );
       
   723     if ( aTextTlv.GetLength() )
       
   724         {
       
   725         TPtrC8 sourceString;
       
   726 
       
   727         sourceString.Set( aTextTlv.GetData( ETLV_TextString ) );
       
   728 
       
   729         TBuf8<KTextBufferMaxSize> string( sourceString );
       
   730         // SMS default alphabet DCS
       
   731         if ( !( aTextTlv.GetShortInfo( ETLV_DataCodingScheme ) 
       
   732             & KPacked7BitTextMask ) )
       
   733             {
       
   734             // Unpack
       
   735             Packed7to8Unpacked( sourceString, string );
       
   736             
       
   737             if ( aUnicodeOutput.MaxLength() < string.Length() )
       
   738                 {
       
   739                 string.SetLength( aUnicodeOutput.MaxLength() );
       
   740                 }
       
   741             // Convert to unicode format
       
   742             Convert7BitToUnicode16( string, aUnicodeOutput );
       
   743             }
       
   744         // UCS2 DCS
       
   745         else if ( aTextTlv.GetShortInfo( ETLV_DataCodingScheme )
       
   746             & KUCS2DCS )
       
   747             {
       
   748             Copy8to16LE( sourceString, aUnicodeOutput );
       
   749             }
       
   750         // 8-bit DCS
       
   751         else if ( aTextTlv.GetShortInfo( ETLV_DataCodingScheme )
       
   752             & K8BitDCS )
       
   753             {            
       
   754             // 8-bit string to 16-bit string
       
   755             Convert7BitToUnicode16( string, aUnicodeOutput );
       
   756             }
       
   757         else // Reserved cases: SMS default alphabet
       
   758             {
       
   759              // Unpack
       
   760             Packed7to8Unpacked( sourceString, string );
       
   761             
       
   762             if ( aUnicodeOutput.MaxLength() < string.Length() )
       
   763                 {
       
   764                 string.SetLength( aUnicodeOutput.MaxLength() );
       
   765                 }
       
   766             // Convert to unicode format
       
   767             Convert7BitToUnicode16( string, aUnicodeOutput );           
       
   768             }
       
   769         }
       
   770     }
       
   771 
       
   772 // -----------------------------------------------------------------------------
       
   773 // TSatUtility::ConvertAlphaFieldsToUnicode
       
   774 // Convert Alpha fields format to Unicode format.
       
   775 // -----------------------------------------------------------------------------
       
   776 //
       
   777 EXPORT_C void TSatUtility::ConvertAlphaFieldsToUnicode
       
   778         (
       
   779         const TDesC8& aSource,
       
   780         TDes& aTarget 
       
   781         )
       
   782     {   
       
   783     TFLOGSTRING( "UTILITY: TSatUtility::ConvertAlphaFieldsToUnicode" );
       
   784     // ArabicCoding, GreekCoding and TurkishCoding have different coding 
       
   785     // methods. There is a tag for each type of alphabet (resp. 80, 81 or 82) 
       
   786     // before the text, and there are base pointers used for expanding 1 byte 
       
   787     // to 2 bytes as required by UCS2  
       
   788     // Ref: 3GPP TS 11.11, Annex B
       
   789 
       
   790     // Base pointer is a "half-page" in the UCS2 code space
       
   791     TUint16 basePointer( 0 );
       
   792     TInt offset( 0 );
       
   793    
       
   794     TInt ret( KErrNone );
       
   795 
       
   796     switch ( aSource[0] )
       
   797         {
       
   798         case KUCS2ArabicCoding:
       
   799             {
       
   800             // Copy everything after tag byte
       
   801             Copy8to16LE( aSource.Mid( 1, aSource.Length() - 1 ), aTarget );
       
   802             //Check if any text present
       
   803             if ( aTarget.Length() )
       
   804                 {
       
   805                 // Remove padding bytes if any
       
   806                 if ( 0xFFFF == aTarget[ aTarget.Length() - 1 ] )
       
   807                     {
       
   808                     aTarget.SetLength( aTarget.Length() - 1 );
       
   809                     }
       
   810                 }
       
   811             // No expanding needed, already in unicode format.
       
   812             ret = KErrNotFound;
       
   813             break;
       
   814             }
       
   815         case KUCS2GreekCoding:
       
   816             {
       
   817             // Characters starts at position 3
       
   818             offset = 3;
       
   819             // Base pointer is given in one byte
       
   820             // and needs to be sifted 7-bit to left to get correct base pointer
       
   821             basePointer = TUint16( aSource[2] << 7 ) ;
       
   822             break;
       
   823             }
       
   824         case KUCS2TurkishCoding:
       
   825             {
       
   826             // Characters starts at position 4
       
   827             offset = 4;
       
   828             // Base pointer is two bytes, 16-bit
       
   829             TSatUtility::CopyTwo8toOne16LE( aSource, basePointer, 2 );
       
   830             break;
       
   831             }
       
   832         default:
       
   833             // Do nothing
       
   834             break;
       
   835         }
       
   836     
       
   837     if ( ( KErrNone == ret ) && ( 2 < aSource.Length() ) )
       
   838         {
       
   839          // The second octet contains a value indicating the number of 
       
   840          // characters in the string. (Not in the case of Arabic string)
       
   841          TInt length( aSource[1] );
       
   842          
       
   843         // Expanding 1 byte format to 2 bytes
       
   844         while ( length )
       
   845             {
       
   846             // If bit 8 of the octet is set to zero, the remaining 7 bits of 
       
   847             // the octet contain a GSM Default Alphabet character, whereas if
       
   848             // bit 8 of the octet is set to one, the remaining seven bits are
       
   849             // an offset value added to the base pointer defined in octets 
       
   850             // three and four, and the resultant 16 bit value is a UCS2 code 
       
   851             // point, and defines a UCS2 character.
       
   852             if ( 0x7F <= aSource[offset] )
       
   853                 {
       
   854                 // Append base pointer and offset
       
   855                 aTarget.Append( basePointer + ( aSource[offset] & 0x7F ) );
       
   856                 }
       
   857             else
       
   858                 {
       
   859                 // GSM default alphabet.
       
   860                 TBuf<1> dest16bit;
       
   861                 TBuf8<1> src7bit;
       
   862                 // Get character
       
   863                 src7bit.Append( aSource[offset] );
       
   864                 // Convert GSM default alphabet character to unicode
       
   865                 Convert7BitToUnicode16( src7bit, dest16bit );
       
   866                 // Append converted character to output string
       
   867                 aTarget.Append( dest16bit );
       
   868                 }
       
   869             offset++;
       
   870             length--;
       
   871             }
       
   872         }
       
   873     }
       
   874 
       
   875 // -----------------------------------------------------------------------------
       
   876 // TSatUtility::Copy16to8LE
       
   877 // Converts 16-bit data to 8-bit data with little endian.
       
   878 // -----------------------------------------------------------------------------
       
   879 //
       
   880 EXPORT_C TInt TSatUtility::Copy16to8LE
       
   881         (
       
   882         const TDesC16& aSource,  
       
   883         TDes8& aTarget            
       
   884         )
       
   885     {   
       
   886     TFLOGSTRING( "UTILITY: TSatUtility::Copy16to8LE" );
       
   887     TInt ret( KErrNone );
       
   888     TInt length( 0 );
       
   889     
       
   890     // Checks that data length are acceblable
       
   891     if ( aSource.Size() > aTarget.MaxSize() )
       
   892         {
       
   893         TFLOGSTRING( "UTILITY: TSatUtility::Copy16to8LE, Length exceeded!" );
       
   894         ret = KErrOverflow;
       
   895         length = ( aTarget.MaxSize() / 2 );
       
   896         }
       
   897     else
       
   898         {
       
   899         length = aSource.Length();
       
   900         }
       
   901 
       
   902     // Append source to target using rigth endian
       
   903     for ( TInt i = 0; i < length; i++ )
       
   904         {
       
   905         aTarget.Append( TUint8( aSource[i] >> 8) );
       
   906         aTarget.Append( TUint8( aSource[i] & 0xff ) );
       
   907         }
       
   908         
       
   909     return ret;
       
   910     }
       
   911     
       
   912 // -----------------------------------------------------------------------------
       
   913 // TSatUtility::Copy8to16LE
       
   914 // Converts 8-bit data to 16-bit data with little endian
       
   915 // -----------------------------------------------------------------------------
       
   916 //
       
   917 EXPORT_C TInt TSatUtility::Copy8to16LE
       
   918         (
       
   919         const TDesC8& aSource,  
       
   920         TDes16& aTarget         
       
   921         )
       
   922     {
       
   923     TFLOGSTRING( "UTILITY: TSatUtility::Copy8to16LE" );    
       
   924     TInt ret( KErrNone );
       
   925     // Check out which string is the shortest and use its length as a limit
       
   926     TInt length ( Min( ( ( aSource.Length() / 2 ) * 2 ), aTarget.MaxSize() ) );
       
   927 
       
   928     // Append source to target using right endian
       
   929     for ( TInt i = 0; i < length; i += 2 )
       
   930         {
       
   931         aTarget.Append( TUint16( aSource[i + 1] | ( aSource[i] << 8) ) );
       
   932         }
       
   933         
       
   934     // Whe should still notify the requesting method about exceeding the length
       
   935     if ( length < aSource.Length() )
       
   936         {
       
   937         ret = KErrOverflow;
       
   938         TFLOGSTRING2( "UTILITY: TSatUtility::ConvertUnicode16To7Bit,\
       
   939             Input data too long. %d bytes could not be converted", 
       
   940             ( aSource.Length() - length ) );
       
   941         }
       
   942         
       
   943     return ret;
       
   944     }
       
   945 
       
   946 // -----------------------------------------------------------------------------
       
   947 // TSatUtility::DecodeCbsDcs
       
   948 // Finds whether the data coding scheme, coded in CBS format, is 7-bit, 8-bit 
       
   949 // or 16-bit. Converts the input DCS from CBS format to SMS format. 
       
   950 // Reference: 3gpp ts 23.038
       
   951 // -----------------------------------------------------------------------------
       
   952 //
       
   953 EXPORT_C TSmsDcs TSatUtility::DecodeCbsDcs
       
   954 		(
       
   955     	const TUint8 aDcs 
       
   956     	)
       
   957     {
       
   958     TFLOGSTRING("UTILITY: TSatUtility::DecodeCbsDcs");
       
   959     
       
   960     // Constant values are not defined in order to
       
   961     // avoid confusion with too many constants names.
       
   962     
       
   963     // Coding group: 4 left most significant bits
       
   964     TUint8 codingGroup = ( aDcs & 0xF0 )>>4;
       
   965     // Lower quartet: 4 right most significant bits
       
   966     TUint8 lowQuartet = ( aDcs & 0x0F );
       
   967     // Character set: bit 2 and 3, in [bit7...bit0]
       
   968     TUint8 characterSet = ( aDcs & 0x0C )>>2;
       
   969     // Initialize output to Unknown or Reserved
       
   970     TSmsDcs decodedDcs( ESmsUnknownOrReservedDcs );
       
   971     // Switch according to the coding group
       
   972     switch ( codingGroup )
       
   973         {
       
   974         // Language specified, usually in 7-bit
       
   975         // b0000 or b0010 or b0011
       
   976         case 0x00:
       
   977         case 0x02:
       
   978         case 0x03:
       
   979             {
       
   980             // 7-bit alphabet
       
   981             decodedDcs = ESms7BitDcs;
       
   982             break;
       
   983             }
       
   984         // b0001
       
   985         // Message preceded by language indication
       
   986         case 0x01: 
       
   987             {
       
   988             
       
   989             if ( 0x00==lowQuartet )
       
   990                 {
       
   991                 decodedDcs = ESms7BitDcs;
       
   992                 }
       
   993             else if ( 0x01==lowQuartet )
       
   994                 {
       
   995                 decodedDcs = ESms16BitDcs;
       
   996                 }
       
   997             break;
       
   998             }
       
   999         // General data coding indication
       
  1000         // b01xx  or b1001
       
  1001         case 0x04:
       
  1002         case 0x05:
       
  1003         case 0x06:
       
  1004         case 0x07:
       
  1005         case 0x09:
       
  1006             {
       
  1007             // The character set determines the alphabet/compression
       
  1008             if ( 0x00 == characterSet )
       
  1009                 {
       
  1010                 decodedDcs = ESms7BitDcs;
       
  1011                 }
       
  1012             else if ( 0x01 == characterSet )
       
  1013                 {
       
  1014                 decodedDcs = ESms8BitDcs;
       
  1015                 }
       
  1016             else if ( 0x02 == characterSet )
       
  1017                 {
       
  1018                 decodedDcs = ESms16BitDcs;
       
  1019                 }
       
  1020             break;
       
  1021             }
       
  1022         // Data coding / Message handling
       
  1023         // either 8-bit or 7-bit
       
  1024         case 0x0F:
       
  1025             {
       
  1026             // only bit 2 informs about the
       
  1027             // character set.
       
  1028             if ( aDcs & 0x04 )
       
  1029                 {
       
  1030                 decodedDcs = ESms8BitDcs;
       
  1031                 }
       
  1032             else
       
  1033                 {
       
  1034                 decodedDcs = ESms7BitDcs;
       
  1035                 }
       
  1036             break;
       
  1037             }
       
  1038         default:
       
  1039             {
       
  1040             // the DCS value is reserved.
       
  1041             TFLOGSTRING("UTILITY: TSatUtility::DecodeCbsDcs, reserved value");
       
  1042             break;
       
  1043             }
       
  1044         }
       
  1045     return decodedDcs;
       
  1046     }
       
  1047 
       
  1048 // -----------------------------------------------------------------------------
       
  1049 // TSatUtility::CopyTwo8toOne16LE
       
  1050 // Gets two 8-bit bytes and copies them to the one 16-bit byte with little 
       
  1051 // endianes. Used when reading data from response or indication. 
       
  1052 // -----------------------------------------------------------------------------
       
  1053 //
       
  1054 EXPORT_C TInt TSatUtility::CopyTwo8toOne16LE
       
  1055         (
       
  1056         const TDesC8& aSource,
       
  1057         TUint16& aTarget,       
       
  1058         const TInt aIndex         
       
  1059         )
       
  1060     {
       
  1061     TFLOGSTRING("UTILITY: TSatUtility::CopyTwo8toOne16LE");
       
  1062     TInt ret( KErrNone );
       
  1063     // Check first that we dont try to read data that is not there..
       
  1064     if ( aSource.Length() > aIndex + 1 )
       
  1065         {
       
  1066         aTarget = static_cast<TUint16>( aSource[aIndex] << 8 );         
       
  1067         aTarget = static_cast<TUint16>( aTarget | aSource[aIndex + 1] );
       
  1068         }
       
  1069     else
       
  1070         {
       
  1071         ret = KErrOverflow;
       
  1072         TFLOGSTRING3("UTILITY: TSatUtility::CopyTwo8toOne16LE, Index too high\
       
  1073             Index: %d, Source data length: %d", aIndex, aSource.Length() );
       
  1074         }
       
  1075         
       
  1076     return ret;
       
  1077     }
       
  1078 
       
  1079             
       
  1080 // End of file