adaptationlayer/tsy/nokiatsy_dll/src/cmmsmsgsmaddress.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
equal deleted inserted replaced
-1:000000000000 0:63b37f68c1ce
       
     1 /*
       
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 //  INCLUDE FILES
       
    21 #include "cmmsmsgsmaddress.h"
       
    22 #include <ctsy/serviceapi/cmmsmsutility.h> // for kmaxamountofdigits
       
    23 #include "tsylogger.h"
       
    24 #include "osttracedefinitions.h"
       
    25 #ifdef OST_TRACE_COMPILER_IN_USE
       
    26 #include "cmmsmsgsmaddresstraces.h"
       
    27 #endif
       
    28       // for logging purposes
       
    29 
       
    30 //  External Data Structures  
       
    31 
       
    32 //  External Function Prototypes  
       
    33 
       
    34 //  LOCAL CONSTANTS AND MACROS 
       
    35 const TUint8 KAddressMinLength = 2;
       
    36 const TUint8 KAddressLengthAndTon = 2;
       
    37 const TUint8 KDataByteInUnicode = 2;
       
    38 const TUint8 KHalfByte = 4;
       
    39 const TUint8 KLengthOfByte = 8;
       
    40 const TUint8 KLengthOfPackedByte = 7;
       
    41 const TUint8 KTwoCharInByte = 2;
       
    42 
       
    43 //  MODULE DATA STRUCTURES  
       
    44 
       
    45 //  Local Data Structures  
       
    46 
       
    47 //  Local Function Prototypes  
       
    48 
       
    49 // Converts semioct-code to character, semioctet can be 0x00 - 0x0F
       
    50 #define GSMSMSSEMIOCTETTOCHAR( bcd )  gsmSmsSemiOctetToCharTable[ bcd ]
       
    51 
       
    52 //  MEMBER FUNCTIONS
       
    53 
       
    54 //=============================================================================
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CMmSmsGsmAddress::CMmSmsGsmAddress
       
    58 // C++ constructor. Private (this class should not be instantiated).
       
    59 // ----------------------------------------------------------------------------- 
       
    60 // 
       
    61 CMmSmsGsmAddress::CMmSmsGsmAddress
       
    62         (
       
    63         //None
       
    64         )
       
    65     {
       
    66 TFLOGSTRING("TSY: CMmSmsGsmAddress::CMmSmsGsmAddress");
       
    67 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_CMMSMSGSMADDRESS, "CMmSmsGsmAddress::CMmSmsGsmAddress" );
       
    68     //none
       
    69     }
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CMmSmsGsmAddress::GsmConvUnicodeTo0340Addr
       
    73 // Converts type of number, numbering plan identification and
       
    74 // phone number given in unicode string to the Gsm 03.40 
       
    75 // standard
       
    76 // ----------------------------------------------------------------------------- 
       
    77 //
       
    78 void CMmSmsGsmAddress::GsmConvUnicodeTo0340Addr
       
    79         (
       
    80         TUint8 aTon,            //Type of number
       
    81         TUint8 aNpi,            //Numbering plan identification
       
    82         TDes8& aDest,           //Service center address
       
    83         TDesC16 const& aSource  //Telephone number
       
    84         )    
       
    85     {
       
    86 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmConvUnicodeTo0340Addr");
       
    87 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMCONVUNICODETO0340ADDR, "CMmSmsGsmAddress::GsmConvUnicodeTo0340Addr" );
       
    88     
       
    89     if ( 0 != aSource.Length() )
       
    90         {
       
    91         GsmConvUnicodeToAddr( aTon, aNpi, aDest, aSource, ETrue );  
       
    92         }
       
    93     else
       
    94         {
       
    95         // Address length of 0 is a special case
       
    96         aDest.Append( 0 );      
       
    97 
       
    98         // Type-of-Address: TON = Unknown, NPI = ISDN/telephone num plan
       
    99         aDest.Append( 0x81 );  
       
   100         }
       
   101     }
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // CMmSmsGsmAddress::GsmConv0340AddrToUnicode
       
   105 // This function converts an address format string specified in 
       
   106 // GSM 03.40 into unicode string
       
   107 // ----------------------------------------------------------------------------- 
       
   108 //
       
   109 void CMmSmsGsmAddress::GsmConv0340AddrToUnicode
       
   110         ( 
       
   111         TDes& aDest,                            //Service center address
       
   112         TDesC8 const& aSource,                  //Telephone number
       
   113         RMobilePhone::TMobileTON& aTon,         //Type of number
       
   114         RMobilePhone::TMobileNPI& aNpi          //Telephone number
       
   115         )
       
   116     {
       
   117 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmConv0340AddrToUnicode");
       
   118 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMCONV0340ADDRTOUNICODE, "CMmSmsGsmAddress::GsmConv0340AddrToUnicode" );
       
   119     
       
   120     if ( KAddressMinLength <= aSource.Length() ) 
       
   121         {
       
   122         //Address length and address type fields included
       
   123         GsmConvAddrToUnicode( aDest, aSource, aTon, aNpi, ETrue );
       
   124         }
       
   125     else
       
   126         {
       
   127         //Corrupted address
       
   128         aDest.SetLength( 0 );
       
   129         aTon = RMobilePhone::EUnknownNumber;
       
   130         aNpi = RMobilePhone::EUnknownNumberingPlan;
       
   131         }
       
   132     }
       
   133 
       
   134 // -----------------------------------------------------------------------------
       
   135 // CMmSmsGsmAddress::GsmConvUnicodeTo0411Addr
       
   136 // Converts type of number, numbering plan identification and
       
   137 // phone number given in unicode string to the Gsm 04.11 
       
   138 // standard
       
   139 // ----------------------------------------------------------------------------- 
       
   140 //
       
   141 void CMmSmsGsmAddress::GsmConvUnicodeTo0411Addr
       
   142         (
       
   143         TUint8 aTon,            //Type of number
       
   144         TUint8 aNpi,            //Numbering plan identification
       
   145         TDes8& aDest,           //Service center address
       
   146         TDesC16 const& aSource  //Telephone number
       
   147         )
       
   148     { 
       
   149 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmConvUnicodeTo0411Addr");
       
   150 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMCONVUNICODETO0411ADDR, "CMmSmsGsmAddress::GsmConvUnicodeTo0411Addr" );
       
   151     
       
   152     if ( 0 != aSource.Length() )
       
   153         {
       
   154         GsmConvUnicodeToAddr( aTon, aNpi, aDest, aSource, EFalse );
       
   155         }
       
   156     else
       
   157         {
       
   158         // Address length of 0 is a special case: no address type is given.
       
   159         aDest.Append( 0 );
       
   160         }
       
   161     }
       
   162 
       
   163 // -----------------------------------------------------------------------------
       
   164 // CMmSmsGsmAddress::GsmConv0411AddrToUnicode
       
   165 // This function converts an address format string specified in 
       
   166 // GSM 04.11 into unicode string
       
   167 // ----------------------------------------------------------------------------- 
       
   168 //
       
   169 void CMmSmsGsmAddress::GsmConv0411AddrToUnicode
       
   170         (
       
   171         TDes& aDest,                        //Destination
       
   172         TDesC8 const& aSource,              //Source
       
   173         RMobilePhone::TMobileTON& aTon,     //Type of number
       
   174         RMobilePhone::TMobileNPI& aNpi      //Numbering plan identification
       
   175         )
       
   176     {
       
   177 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmConv0411AddrToUnicode");
       
   178 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMCONV0411ADDRTOUNICODE, "CMmSmsGsmAddress::GsmConv0411AddrToUnicode" );
       
   179     
       
   180     if ( KAddressMinLength <= aSource.Length() )
       
   181         {
       
   182         //Address length and address type fields included
       
   183         GsmConvAddrToUnicode( aDest, aSource, aTon, aNpi, EFalse );
       
   184         }
       
   185     else
       
   186         {
       
   187         //No address type field
       
   188         aDest.SetLength( 0 );
       
   189         aTon = RMobilePhone::EUnknownNumber;
       
   190         aNpi = RMobilePhone::EUnknownNumberingPlan;
       
   191         }
       
   192     }
       
   193 
       
   194 // -----------------------------------------------------------------------------
       
   195 // CMmSmsGsmAddress::GsmConvUnicodeToAddr
       
   196 // Converts type of number, numbering plan identification and
       
   197 // phone number given in unicode string to the GSM 03.40 or
       
   198 // 04.11 standard
       
   199 // ----------------------------------------------------------------------------- 
       
   200 //
       
   201 void CMmSmsGsmAddress::GsmConvUnicodeToAddr
       
   202         (
       
   203         TUint8 aTon,             //Type of number
       
   204         TUint8 aNpi,             //Numbering plan identification
       
   205         TDes8& aDest,            //Service center address
       
   206         TDesC16 const& aSource,  //Telephone number
       
   207         TBool a0340Address       //GSM 03.40 address
       
   208         )
       
   209     { 
       
   210 TFLOGSTRING4("TSY: CMmSmsGsmAddress::GsmConvUnicodeToAddr - number type: %d, numbering plan: %d, number: %S", aTon, aNpi, &aSource);
       
   211 OstTraceExt3( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMCONVUNICODETOADDR, "CMmSmsGsmAddress::GsmConvUnicodeToAddr;aTon=%hhu;aNpi=%hhu;aSource=%S", aTon, aNpi, aSource );
       
   212 TFLOGSTRING2("TSY: CMmSmsGsmAddress::GsmConvUnicodeToAddr - GSM 03.40 address: %d", a0340Address);
       
   213 OstTraceExt1( TRACE_NORMAL, DUP1_CMMSMSGSMADDRESS_GSMCONVUNICODETOADDR, "CMmSmsGsmAddress::GsmConvUnicodeToAddr;a0340Address=%hhu", a0340Address );
       
   214     
       
   215     //get address length (always < 255)
       
   216     TUint8 numberLength( static_cast< TUint8 >( aSource.Length() ) );
       
   217     TUint8 destLength( numberLength );
       
   218     TInt i( 0 );
       
   219 
       
   220     /*  Solve type of address
       
   221         Type of Address field format is as follows:
       
   222 
       
   223            7      6     5     4      3      2       1       0    bit
       
   224         |     |      |     |     |      |       |       |       |
       
   225         |  1  | Type of number   | Numbering-plan-identification|
       
   226         |     |      |     |     |      |       |       |       |
       
   227     */
       
   228 
       
   229     //type of number is three bits from left and fourth bit must be '1'
       
   230     TUint8 typeOfNumber( TUint8( aTon | 0x08 ) );
       
   231     //move four bit to the left
       
   232     typeOfNumber = TUint8( typeOfNumber << 4 );
       
   233     //numbering plan is four bits from left
       
   234     TUint8 numberingPlan( TUint8( aNpi & 0x0F ) );
       
   235     //set type of number and numbering plan to the typeOfNumber variable
       
   236     typeOfNumber = TUint8( typeOfNumber | numberingPlan );
       
   237 
       
   238     if ( RMobilePhone::EAlphanumericNumber == aTon )
       
   239         {
       
   240         TBuf8< KMaxLengthOfAddressData > addressData;
       
   241         TUint8 amountOfsemiOctets( 0 );
       
   242   
       
   243         GsmUnicodeAddrToAlphanumericAddr( 
       
   244             aSource, 
       
   245             addressData,
       
   246             amountOfsemiOctets );           
       
   247 
       
   248         //fill address length field
       
   249         if ( a0340Address )
       
   250             {
       
   251             //amount of used semi-octets in address data
       
   252             aDest.Append( amountOfsemiOctets );
       
   253             }
       
   254         else    //0411 address
       
   255             {
       
   256             //Actually alphanumeric address data for 0411 address is not 
       
   257             //supported (see GSM 24.011 and 24.008)...
       
   258             //Length of address data + length of address type field
       
   259             //lint -e{732} Warning about "loss of sign". 
       
   260             //Root cause is that TDesC::Length() returns a signed TInt
       
   261             aDest.Append( addressData.Length() + 1 );
       
   262             }
       
   263 
       
   264         //add typeOfNumber to the buffer
       
   265         aDest.Append( typeOfNumber );
       
   266 
       
   267         //add address data to the buffer. 
       
   268         aDest.Insert( KAddressLengthAndTon, addressData );  
       
   269         }
       
   270     else
       
   271         {
       
   272         //number can contain character '+'
       
   273         if ( '+' == aSource[ i ] )
       
   274             {
       
   275             i++;
       
   276             destLength--;
       
   277 
       
   278             // Maximum amount of digits is 20 (3GPP TS 23.040)
       
   279             if ( KMaxAmountOfDigits < destLength ) 
       
   280                 {                                                   
       
   281                 destLength = KMaxAmountOfDigits;
       
   282                 // + 1 comes from '+'
       
   283                 numberLength = KMaxAmountOfDigits + 1;
       
   284                 }
       
   285             }
       
   286         else
       
   287             {
       
   288             // Maximum amount of digits is 20 (3GPP TS 23.040)
       
   289             if ( KMaxAmountOfDigits < destLength ) 
       
   290                 {                                                   
       
   291                 destLength = KMaxAmountOfDigits;
       
   292                 numberLength = KMaxAmountOfDigits;
       
   293                 }
       
   294             }
       
   295 
       
   296         // calculate address length in bytes (always < 255). 
       
   297         // destLength + 1 ensures that there is enough space in case of odd
       
   298         // destLength. 
       
   299         TUint8 bufferLength( static_cast< TUint8 >( 
       
   300             ( destLength + 1 ) / 2 + KAddressLengthAndTon ) );
       
   301 
       
   302         //set buffer length
       
   303         aDest.SetLength( bufferLength );
       
   304 
       
   305         //add length to the buffer
       
   306         if ( a0340Address )
       
   307             {
       
   308             //amount of used semi-octets in address data
       
   309             aDest[ 0 ] = destLength;   
       
   310             }
       
   311         else
       
   312             {
       
   313             //length of whole address data - length of address length field
       
   314             aDest[ 0 ] = static_cast< TUint8 >( bufferLength - 1 );
       
   315             }
       
   316 
       
   317         //add typeOfNumber to the buffer
       
   318         aDest[1] = typeOfNumber; 
       
   319 
       
   320         //needed variables
       
   321         TUint8 numLsb( 0 );
       
   322         TUint8 numMsb( 0 );
       
   323         TInt index( KAddressLengthAndTon );
       
   324 
       
   325         //add numbers to the buffer
       
   326         for ( ; ( i + 1 ) < numberLength ; i += 2 )
       
   327             {
       
   328             numLsb = TUint8( aSource[ i ] - '0' );
       
   329             numMsb = TUint8( static_cast< TUint8 >( 
       
   330                 aSource[ i + 1 ] - '0' ) << KHalfByte );
       
   331 
       
   332             aDest[index++] = TUint8( numLsb | numMsb );
       
   333             }
       
   334 
       
   335         //if numberLength is odd, last number is fixed with 0xF0
       
   336         if ( i < numberLength )
       
   337             {
       
   338             aDest[ index ] = TUint8( 0xF0 | ( aSource[ i ] - '0' ) );
       
   339             }
       
   340         }  
       
   341     }
       
   342 
       
   343 // -----------------------------------------------------------------------------
       
   344 // CMmSmsGsmAddress::GsmConvAddrToUnicode
       
   345 // Converts GSM 03.40 or 04.11 address to type of number, 
       
   346 // numbering plan identification and phone number given in 
       
   347 // unicode string
       
   348 // ----------------------------------------------------------------------------- 
       
   349 //
       
   350 void CMmSmsGsmAddress::GsmConvAddrToUnicode
       
   351         ( 
       
   352         TDes& aDest,                            //Service center address
       
   353         TDesC8 const& aSource,                  //Telephone number
       
   354         RMobilePhone::TMobileTON& aTon,         //Type of number
       
   355         RMobilePhone::TMobileNPI& aNpi,         //Telephone number
       
   356         TBool a0340Address                      //GSM 03.40 address
       
   357         )
       
   358     {
       
   359 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmConvAddrToUnicode");
       
   360 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMCONVADDRTOUNICODE, "CMmSmsGsmAddress::GsmConvAddrToUnicode" );
       
   361     
       
   362     TUint8  addrDataLength( 0 );
       
   363     TBool   halfs( ETrue );
       
   364     TInt    index( 0 );               
       
   365     TUint   num2( 0 );
       
   366 
       
   367     //Get amount of digits in address data
       
   368     if ( a0340Address )
       
   369         {
       
   370         addrDataLength = static_cast< TUint8> ( aSource[ index ] );
       
   371         }
       
   372     else    //04.11 address
       
   373         {
       
   374         addrDataLength = static_cast< TUint8 >( KDataByteInUnicode 
       
   375             * ( aSource[ index ] - 1 ) );
       
   376         }
       
   377 
       
   378     // Check if there are too many digits
       
   379     // Maximum amount of digits is 20 (3GPP TS 23.040)
       
   380     if ( KMaxAmountOfDigits < addrDataLength )
       
   381         {
       
   382         addrDataLength = KMaxAmountOfDigits;
       
   383         }
       
   384 
       
   385     index++;
       
   386 
       
   387     // Lets take type of number field
       
   388     TUint8 typeOfNum( aSource[ index ] );
       
   389     GsmFindOutTonAndNpi( typeOfNum, &aTon, &aNpi );
       
   390 
       
   391     if ( ( RMobilePhone::EAlphanumericNumber == aTon )
       
   392         && ( 0x00 != addrDataLength ) )
       
   393         {
       
   394         //Calculate address length in bytes. If statement above check's that
       
   395         //addrDataLength is not zero.
       
   396         TInt addrDataLengthInBytes( ( addrDataLength + 1 ) 
       
   397             / KDataByteInUnicode );
       
   398 
       
   399         //Get address data
       
   400         TPtrC8 addressData( aSource.Mid( 
       
   401             KAddressLengthAndTon, 
       
   402             addrDataLengthInBytes ) ); 
       
   403 
       
   404         //amountOfCharsInAddrData = amount of used bits / length of char
       
   405         TUint amountOfCharsInAddrData( ( addrDataLength * KHalfByte ) 
       
   406             / KLengthOfPackedByte );
       
   407            
       
   408         GsmAlphanumericAddrToUnicodeAddr( 
       
   409             addressData, 
       
   410             amountOfCharsInAddrData,
       
   411             aDest );
       
   412         }
       
   413     else
       
   414         {
       
   415         // Check if number is international number and addrDataLength is 
       
   416         // bigger than zero
       
   417         if ( ( RMobilePhone::EInternationalNumber == aTon ) 
       
   418             && ( 0x00 != addrDataLength ) )
       
   419             {
       
   420             aDest.Append( '+' );
       
   421             }
       
   422 
       
   423         index++;
       
   424 
       
   425         while ( addrDataLength-- )
       
   426             {
       
   427             if ( aSource.Length() > index )
       
   428                 {
       
   429                 if ( halfs )
       
   430                     {               
       
   431                     // Lets take only four bits from right
       
   432                     num2 = GSMSMSSEMIOCTETTOCHAR( aSource[ index ] & 0x0F );
       
   433                     aDest.Append( num2 );
       
   434                     halfs = EFalse;
       
   435                     }
       
   436                 else
       
   437                     {
       
   438                     if ( ( 0x0F == ( aSource[ index ] >> KHalfByte ) ) && !a0340Address )
       
   439                         {
       
   440                         //If 04.11 address contains odd number of digits, 
       
   441                         //bits 5 to 8 of the last octet shall be filled with an end
       
   442                         //mark coded as "1111".
       
   443                         break;
       
   444                         }
       
   445 
       
   446                     halfs = ETrue;  // Lets take only four bits from left
       
   447                     num2 = GSMSMSSEMIOCTETTOCHAR( aSource[ index ] >> KHalfByte );
       
   448                     aDest.Append( num2 );
       
   449                     index++;
       
   450                     }
       
   451                 } // if ( aSource.Length() > index )
       
   452             } // while
       
   453         }
       
   454 TFLOGSTRING4("TSY: CMmSmsGsmAddress::GsmConvAddrToUnicode - result: number type: %d, numbering plan: %d, number: %S", aTon, aNpi, &aDest);
       
   455 OstTraceExt3( TRACE_NORMAL, DUP1_CMMSMSGSMADDRESS_GSMCONVADDRTOUNICODE, "CMmSmsGsmAddress::GsmConvAddrToUnicode;aTon=%d;aNpi=%d;aDest=%S", aTon, aNpi, aDest );
       
   456 TFLOGSTRING2("TSY: CMmSmsGsmAddress::GsmConvAddrToUnicode - GSM 03.40 address", a0340Address);
       
   457 OstTraceExt1( TRACE_NORMAL, DUP2_CMMSMSGSMADDRESS_GSMCONVADDRTOUNICODE, "CMmSmsGsmAddress::GsmConvAddrToUnicode;a0340Address=%hhu", a0340Address );
       
   458     }
       
   459 
       
   460 // -----------------------------------------------------------------------------
       
   461 // CMmSmsGsmAddress::GsmFindOutTonAndNpi
       
   462 // Converts type of number and numbering plan identification
       
   463 // information from the type of address parameter to the 
       
   464 // RMobilePhone::TMobileTON and RMobilePhone::TMobileNPI format
       
   465 // ----------------------------------------------------------------------------- 
       
   466 //
       
   467 void CMmSmsGsmAddress::GsmFindOutTonAndNpi
       
   468         ( 
       
   469         TUint8 typeOfAddress,               //Type of address
       
   470         RMobilePhone::TMobileTON* ton,      //Type of number
       
   471         RMobilePhone::TMobileNPI* npi       //Numbering plan identification
       
   472         )     
       
   473     {
       
   474 TFLOGSTRING2("TSY: CMmSmsGsmAddress::GsmFindOutTonAndNpi - address type: %d", typeOfAddress);
       
   475 OstTraceExt1( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMFINDOUTTONANDNPI, "CMmSmsGsmAddress::GsmFindOutTonAndNpi;typeOfAddress=%hhu", typeOfAddress );
       
   476     
       
   477     TUint8 numberingPlanIdentification( static_cast< TUint8 >( 
       
   478         typeOfAddress & 0x0F ) );
       
   479     TUint8 temp( static_cast< TUint8 >( typeOfAddress >> KHalfByte ) );
       
   480     TUint8 typeOfNumber( static_cast< TUint8 >( temp & 0x07 ) );
       
   481 
       
   482     switch ( typeOfNumber )
       
   483         {
       
   484         case KInternationalNumber:
       
   485             {
       
   486             *ton = RMobilePhone::EInternationalNumber;
       
   487             break;
       
   488             }
       
   489         case KNationalNumber:
       
   490             {
       
   491             *ton = RMobilePhone::ENationalNumber;
       
   492             break;
       
   493             }
       
   494         case KNetworkSpecificNumber:
       
   495             {
       
   496             *ton = RMobilePhone::ENetworkSpecificNumber;
       
   497             break;
       
   498             }
       
   499         case KSubscriberNumber:
       
   500             {
       
   501             *ton = RMobilePhone::ESubscriberNumber;
       
   502             break;
       
   503             }
       
   504         case KAlphanumeric:
       
   505             {
       
   506             *ton = RMobilePhone::EAlphanumericNumber;
       
   507             break;
       
   508             }
       
   509         case KAbbreviatedNumber:
       
   510             {
       
   511             *ton = RMobilePhone::EAbbreviatedNumber;
       
   512             break;
       
   513             }
       
   514 
       
   515         default:
       
   516             {
       
   517 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmFindOutTonAndNpi - unknown type of number");
       
   518 OstTrace0( TRACE_NORMAL, DUP1_CMMSMSGSMADDRESS_GSMFINDOUTTONANDNPI, "CMmSmsGsmAddress::GsmFindOutTonAndNpi, unknown type of number" );
       
   519             *ton = RMobilePhone::EUnknownNumber;
       
   520             break;
       
   521             }
       
   522         }
       
   523 
       
   524     switch ( numberingPlanIdentification )
       
   525         {
       
   526         case KIsdnTelephoneNumPlan:
       
   527             {
       
   528             *npi = RMobilePhone::EIsdnNumberPlan;
       
   529             break;
       
   530             }
       
   531         case KDataNumPlan:
       
   532             {
       
   533             *npi = RMobilePhone::EDataNumberPlan;
       
   534             break;
       
   535             }
       
   536         case KTelexNumPlan:
       
   537             {
       
   538             *npi = RMobilePhone::ETelexNumberPlan;
       
   539             break;
       
   540             }
       
   541         case KServiceCentreSpecificPlan1:
       
   542             {
       
   543             *npi = RMobilePhone::EServiceCentreSpecificPlan1;
       
   544             break;
       
   545             }
       
   546         case KServiceCentreSpecificPlan2:
       
   547             {
       
   548             *npi = RMobilePhone::EServiceCentreSpecificPlan2;
       
   549             break;
       
   550             }
       
   551         case KNationalNumPlan:
       
   552             {
       
   553             *npi = RMobilePhone::ENationalNumberPlan;
       
   554             break;
       
   555             }
       
   556         case KPrivateNumPlan:
       
   557             {
       
   558             *npi = RMobilePhone::EPrivateNumberPlan;
       
   559             break;
       
   560             }
       
   561         case KErmesNumPlan:
       
   562             {
       
   563             *npi = RMobilePhone::EERMESNumberPlan;
       
   564             break;
       
   565             }
       
   566 
       
   567         default:
       
   568             {
       
   569 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmFindOutTonAndNpi - unknown numbering plan");
       
   570 OstTrace0( TRACE_NORMAL, DUP2_CMMSMSGSMADDRESS_GSMFINDOUTTONANDNPI, "CMmSmsGsmAddress::GsmFindOutTonAndNpi, unknown numbering plan" );
       
   571             *npi = RMobilePhone::EUnknownNumberingPlan;
       
   572             break;
       
   573             }
       
   574         }
       
   575     }
       
   576 
       
   577 // -----------------------------------------------------------------------------
       
   578 // CMmSmsGsmAddress::GsmMapTonToTUint8
       
   579 // Converts type of number from the RMobilePhone::TMobileTON
       
   580 // parameter to the TUint8 format
       
   581 // ----------------------------------------------------------------------------- 
       
   582 //
       
   583 TUint8 CMmSmsGsmAddress::GsmMapTonToTUint8
       
   584         (
       
   585         RMobilePhone::TMobileTON aTon       //Type of number
       
   586         )
       
   587     {
       
   588 TFLOGSTRING2("TSY: CMmSmsGsmAddress::GsmMapTonToTUint8 - type of number: %d", aTon);
       
   589 OstTrace1( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMMAPTONTOTUINT8, "CMmSmsGsmAddress::GsmMapTonToTUint8;aTon=%d", aTon );
       
   590     TUint8 typeOfNumber( 0 );
       
   591 
       
   592     switch ( aTon )
       
   593         {
       
   594         case RMobilePhone::EInternationalNumber:
       
   595             {
       
   596             typeOfNumber = KInternationalNumber;
       
   597             break;
       
   598             }
       
   599         case RMobilePhone::ENationalNumber:
       
   600             {
       
   601             typeOfNumber = KNationalNumber;
       
   602             break;
       
   603             }
       
   604         case RMobilePhone::ENetworkSpecificNumber:
       
   605             {
       
   606             typeOfNumber = KNetworkSpecificNumber;
       
   607             break;
       
   608             }
       
   609         case RMobilePhone::ESubscriberNumber:
       
   610             {
       
   611             typeOfNumber = KSubscriberNumber;
       
   612             break;
       
   613             } 
       
   614         case RMobilePhone::EAlphanumericNumber:
       
   615             {
       
   616             typeOfNumber = KAlphanumeric;
       
   617             break;
       
   618             } 
       
   619         case RMobilePhone::EAbbreviatedNumber:
       
   620             {
       
   621             typeOfNumber = KAbbreviatedNumber;
       
   622             break;
       
   623             } 
       
   624         case RMobilePhone::EUnknownNumber:
       
   625         default:
       
   626             {
       
   627 TFLOGSTRING2("TSY: CMmSmsGsmAddress::GsmMapTonToTUint8 - unknown type of number: %d", aTon);
       
   628 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSGSMADDRESS_GSMMAPTONTOTUINT8, "CMmSmsGsmAddress::GsmMapTonToTUint8;unknown type of number aTon=%d", aTon );
       
   629             typeOfNumber = KTonUnknown;
       
   630             } 
       
   631         }
       
   632 
       
   633     return typeOfNumber;
       
   634     }
       
   635 
       
   636 // -----------------------------------------------------------------------------
       
   637 // CMmSmsGsmAddress::GsmMapNpiToTUint8
       
   638 // Converts type of number from the RMobilePhone::TMobileNPI
       
   639 // parameter to the TUint8 format
       
   640 // ----------------------------------------------------------------------------- 
       
   641 //
       
   642 TUint8 CMmSmsGsmAddress::GsmMapNpiToTUint8
       
   643         ( 
       
   644         RMobilePhone::TMobileNPI aNpi   //Numbering plan identification
       
   645         )
       
   646     {
       
   647 TFLOGSTRING2("TSY: CMmSmsGsmAddress::GsmMapNpiToTUint8 - numbering plan identification: %d", aNpi);
       
   648 OstTrace1( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMMAPNPITOTUINT8, "CMmSmsGsmAddress::GsmMapNpiToTUint8;aNpi=%d", aNpi );
       
   649     
       
   650     TUint8 numPlanIdentification( 0 );
       
   651 
       
   652     switch ( aNpi )
       
   653         {
       
   654         case RMobilePhone::EIsdnNumberPlan:
       
   655             {
       
   656             numPlanIdentification = KIsdnTelephoneNumPlan;
       
   657             break;
       
   658             } 
       
   659         case RMobilePhone::EDataNumberPlan:
       
   660             {
       
   661             numPlanIdentification = KDataNumPlan;
       
   662             break;
       
   663             } 
       
   664         case RMobilePhone::ETelexNumberPlan:
       
   665             {
       
   666             numPlanIdentification = KTelexNumPlan;
       
   667             break;
       
   668             } 
       
   669         case RMobilePhone::EServiceCentreSpecificPlan1:
       
   670             {
       
   671             numPlanIdentification = KServiceCentreSpecificPlan1;
       
   672             break;
       
   673             } 
       
   674         case RMobilePhone::EServiceCentreSpecificPlan2:
       
   675             {
       
   676             numPlanIdentification = KServiceCentreSpecificPlan2;
       
   677             break;
       
   678             } 
       
   679         case RMobilePhone::ENationalNumberPlan:
       
   680             {
       
   681             numPlanIdentification = KNationalNumPlan;
       
   682             break;
       
   683             } 
       
   684         case RMobilePhone::EPrivateNumberPlan:
       
   685             {
       
   686             numPlanIdentification = KPrivateNumPlan;
       
   687             break;
       
   688             } 
       
   689         case RMobilePhone::EERMESNumberPlan:
       
   690             {
       
   691             numPlanIdentification = KErmesNumPlan;
       
   692             break;
       
   693             } 
       
   694         case RMobilePhone::EUnknownNumberingPlan:
       
   695         default:
       
   696             {
       
   697 TFLOGSTRING2("TSY: CMmSmsGsmAddress::GsmMapNpiToTUint8 - unknown numbering plan identification: %d", aNpi);
       
   698 OstTrace1( TRACE_NORMAL, DUP1_CMMSMSGSMADDRESS_GSMMAPNPITOTUINT8, "CMmSmsGsmAddress::GsmMapNpiToTUint8;unknown numbering plan identification aNpi=%d", aNpi );
       
   699             numPlanIdentification = KNpiUnknown;
       
   700             } 
       
   701         }
       
   702         
       
   703     return numPlanIdentification;
       
   704     }
       
   705 
       
   706 // -----------------------------------------------------------------------------
       
   707 // CMmSmsGsmAddress::GsmUnicodeAddrToAlphanumericAddr
       
   708 // Converts Unicode characters to GSM 7-bit bit Default Alphabet
       
   709 // characters (Defined in GSM 23.038). Note that all Unicode characters 
       
   710 // are not supported by the GSM 7-bit bit Default Alphabet set. Such 
       
   711 // characters are converted to spaces or to the nearest substitute
       
   712 // (generally the acute/grave marks are removed). Control characters and 
       
   713 // special characters are converted to spaces. This method supports GSM 
       
   714 // 7-bit bit Default Alphabet extension table
       
   715 // mechanism.
       
   716 //
       
   717 // After character conversion this method packs address data by calling
       
   718 // GsmLibSmsPackMessage method*/
       
   719 // ----------------------------------------------------------------------------- 
       
   720 //
       
   721 void CMmSmsGsmAddress::GsmUnicodeAddrToAlphanumericAddr
       
   722         ( 
       
   723         TDesC16 const& aSource,     // Source address data
       
   724         TDes8& aDestination,        // Destination data
       
   725         TUint8& aAmountOfSemiOctets // Amount of semi-octets
       
   726         )
       
   727     {
       
   728     
       
   729 TFLOGSTRING2("TSY: CMmSmsGsmAddress::GsmUnicodeAddrToAlphanumericAddr - source address: %S", &aSource);
       
   730 OstTraceExt1( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMUNICODEADDRTOALPHANUMERICADDR, "CMmSmsGsmAddress::GsmUnicodeAddrToAlphanumericAddr;aSource=%S", aSource );
       
   731     
       
   732     TUint16 j( 0 );
       
   733     TUint16 i( 0 );
       
   734 
       
   735     TBuf8< RMobilePhone::KMaxMobileTelNumberSize > alphaChars;
       
   736     for ( i = 0; i < aSource.Length(); i++ )
       
   737         {
       
   738         if ( ( 0x24 < aSource[ i ] ) && ( 0x5B > aSource[ i ] ) && 
       
   739              ( 0x40 != aSource[ i ] ) || 
       
   740              ( 0x60 < aSource[ i ] ) && ( 0x7B > aSource[ i ] ) )
       
   741             {
       
   742             // Conversion could be done only taking out the most significant 
       
   743             // bit from Unicode characters between 0x25 - 0x5A or 0x61 - 0x7A
       
   744             // excluding '@' (0x40).
       
   745             alphaChars.Append(aSource[ i ]);
       
   746             }
       
   747         else if ( ( 0x5A < aSource[ i ] ) && ( 0x5F > aSource[ i ] ) ||
       
   748              ( 0x7A < aSource[ i ] ) && ( 0x7F > aSource[ i ] ) ||
       
   749              ( 0x20AC == aSource[ i ] ) )
       
   750             {
       
   751             //Conversion made using GSM 7 bit default alphabet extension 
       
   752             //table. Characters: [,\,],^,{,|,},~,&euro
       
   753             for ( j = 0 ; j < KGsmExtensionConvTableSize; j++ )
       
   754                 {
       
   755                 if ( aSource[ i ] == KGsmExtensionConvTable[ j ].iUnicodeChar )
       
   756                     {
       
   757                     alphaChars.Append( 0x1B );// extension table flag
       
   758                     alphaChars.Append( 
       
   759                         KGsmExtensionConvTable[ j ].iGsmChar );
       
   760                     break;
       
   761                     }
       
   762                 }   // end of for loop
       
   763             }   
       
   764         else
       
   765             {
       
   766             //Try to find character from conversion table.
       
   767             TBool notFound( ETrue );
       
   768             for ( j = 0; j < KGsmLibConvTableSize; j++ )
       
   769                 {
       
   770                 if ( aSource[ i ] == KGsmLibConvTable[ j ].iUnicodeChar )
       
   771                     {
       
   772                     alphaChars.Append( 
       
   773                         KGsmLibConvTable[ j ].iGsmChar );
       
   774                     notFound = EFalse;
       
   775                     break;
       
   776                     }
       
   777                 }   // end of for loop 
       
   778             
       
   779             if( notFound )
       
   780                 {
       
   781                 //Couldn't found similar character. Convert to SPACE.
       
   782                 alphaChars.Append( 0x20 ); 
       
   783                 }
       
   784             }
       
   785         }
       
   786 
       
   787     TUint8 packedChars( GsmLibPackAlphanumericAddress( aDestination, 
       
   788                                                         alphaChars ) );
       
   789 
       
   790     //How many unused bits packed address contains
       
   791     TUint8 unusedBits( static_cast< TUint8 >( ( aDestination.Length() 
       
   792         * KLengthOfByte ) - ( packedChars * KLengthOfPackedByte ) ) );
       
   793 
       
   794     //How many semi-octets is used in packed address.
       
   795     if ( KHalfByte <= unusedBits )
       
   796         {
       
   797         //Last semi-octet doesn't contain address data
       
   798         aAmountOfSemiOctets = static_cast< TUint8 >( 
       
   799             ( aDestination.Length() * KTwoCharInByte ) - 1 );
       
   800         }
       
   801     else
       
   802         {
       
   803         //All semi-octets are used
       
   804         aAmountOfSemiOctets = static_cast< TUint8 >( 
       
   805             aDestination.Length() * KTwoCharInByte );
       
   806         }
       
   807     }  
       
   808 
       
   809 // -----------------------------------------------------------------------------
       
   810 // CMmSmsGsmAddress::GsmAlphanumericAddrToUnicodeAddr
       
   811 // This method first decodes a address data that has been 
       
   812 // coded using the algorithm described in GSM 03.40 annex 2 by calling
       
   813 // GsmLibUnpackAlphanumericAddress method. After that this method 
       
   814 // converts GSM 7-bit default alphabet characters to Unicode format.
       
   815 // This method supports GSM 7-bit bit Default Alphabet extension table
       
   816 // mechanism
       
   817 // ----------------------------------------------------------------------------- 
       
   818 //
       
   819 void CMmSmsGsmAddress::GsmAlphanumericAddrToUnicodeAddr
       
   820         ( 
       
   821         TDesC8 const& aSource,  // Source address data
       
   822         TUint& aAmountOfChars,  // Amount of characters in address data
       
   823         TDes16& aDestination    // Destination data
       
   824         )
       
   825     {
       
   826 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmAlphanumericAddrToUnicodeAddr");
       
   827 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMALPHANUMERICADDRTOUNICODEADDR, "CMmSmsGsmAddress::GsmAlphanumericAddrToUnicodeAddr" );
       
   828     
       
   829     //Maximum length of address data is 10 bytes. These bytes can contain
       
   830     //11 packed 7-bit characters.
       
   831     TBuf8< KMaxLengthOfAddressData + 1 > unpackedSrc;
       
   832     GsmLibUnpackAlphanumericAddress( aSource, aAmountOfChars, unpackedSrc );
       
   833 
       
   834     TUint8 unpackedLength( static_cast< TUint8 >( unpackedSrc.Length() ) );
       
   835     TUint8 j( 0 );
       
   836     TUint8 i( 0 );
       
   837 
       
   838     for ( i = 0; i < unpackedLength; i++ )
       
   839         {
       
   840         unpackedSrc[ i ] &= 0x7F;     // only 7 bits used in GSM character set
       
   841 
       
   842         if ( ( 0x24 < unpackedSrc[ i ] ) && ( 0x5B > unpackedSrc[ i ] ) && 
       
   843              ( 0x40 != unpackedSrc[ i ] ) || 
       
   844              ( 0x60 < unpackedSrc[ i ] ) && ( 0x7B > unpackedSrc[ i ] ) )
       
   845             {
       
   846             // Character codes in Unicode and GSM 7-bit default alphabet 
       
   847             // are same between 0x25 - 0x5A and 0x61 - 0x7A
       
   848             // excluding 0x40.
       
   849             aDestination.Append( unpackedSrc[ i ] );
       
   850             }
       
   851         else if ( 0x1B == unpackedSrc[ i ] )
       
   852             { 
       
   853             //0x1B is an escape code to the extension table. Code after escape
       
   854             //code should been found from extension table.
       
   855 
       
   856             i++;
       
   857 
       
   858             //It is possible that extension table contains escape code to 
       
   859             //another extension table. Increase index i until we find something 
       
   860             //else than another escape code.
       
   861             for ( ; i < unpackedLength; i++ )
       
   862                 {
       
   863                 if ( 0x1B != unpackedSrc[ i ] )
       
   864                     {
       
   865                     //Found something else than escape code. Let's convert 
       
   866                     //character from extension table to Unicode character.
       
   867                     TBool notFound( ETrue );
       
   868 
       
   869                     for ( j = 0 ; j < KGsmExtensionConvTableSize; j++ )
       
   870                         {
       
   871                         if ( unpackedSrc[ i ] == 
       
   872                             KGsmExtensionConvTable[ j ].iGsmChar )
       
   873                             {
       
   874                             aDestination.Append( 
       
   875                                 KGsmExtensionConvTable[ j ].iUnicodeChar );
       
   876                             notFound = EFalse;
       
   877                             break;
       
   878                             }
       
   879                         }  
       
   880 
       
   881                     if ( notFound )
       
   882                         {
       
   883                         //Couldn't find character from extension table.
       
   884                         //Convert to SPACE.
       
   885                         aDestination.Append( 0x20 );
       
   886                         }
       
   887 
       
   888                     break;
       
   889                     }
       
   890                 else
       
   891                     {
       
   892                     //Found escape code to another extension table. 
       
   893                     //On receipt of this code, a receiving entity shall display 
       
   894                     //a space until another extension table is defined. 
       
   895                     aDestination.Append( 0x20 );
       
   896                     }
       
   897                 }   // end of for loop
       
   898             }   // end of else if
       
   899         else
       
   900             {
       
   901             //Find character from conversion table.
       
   902             for ( j = 0; j < KGsmLibConvTableSize; j++ )
       
   903                 {
       
   904                 if ( unpackedSrc[ i ] == KGsmLibConvTable[ j ].iGsmChar )
       
   905                     {
       
   906                     aDestination.Append( 
       
   907                         KGsmLibConvTable[ j ].iUnicodeChar );
       
   908                     break;
       
   909                     }
       
   910                 }   // end of for loop 
       
   911             }   // end of else
       
   912         }   // end of for loop
       
   913     }
       
   914 
       
   915 // -----------------------------------------------------------------------------
       
   916 // CMmSmsGsmAddress::GsmLibPackAlphanumericAddress
       
   917 // This function packs a given text string consisting of 7-bit
       
   918 // characters into 8 bit bytes in such a way that a 11-character
       
   919 // address takes only 10 bytes of memory after the compression
       
   920 // ----------------------------------------------------------------------------- 
       
   921 //
       
   922 TUint8 CMmSmsGsmAddress::GsmLibPackAlphanumericAddress
       
   923         ( 
       
   924         TDes8& aDest,            // Packed address
       
   925         TDes8& aSource           // Unpacked address
       
   926         )
       
   927     {
       
   928 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmLibPackAlphanumericAddress");
       
   929 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMLIBPACKALPHANUMERICADDRESS, "CMmSmsGsmAddress::GsmLibPackAlphanumericAddress" );
       
   930     TUint8 si( 0 );
       
   931     TUint8 di( 0 );
       
   932     TUint tempModulo( 0 );
       
   933     
       
   934     // Set tempModulo and byteCount
       
   935     tempModulo = di % KLengthOfPackedByte;
       
   936     TUint8 byteCount( static_cast< TUint8 >( aSource.Length() ) );
       
   937 
       
   938     // Maximum length of address data field is 10 bytes. 10 bytes can contain
       
   939     // 11 compressed 7-bit characters. Because of this maximum
       
   940     // amount of characters in alphanumeric address is 11.
       
   941     if ( ( KMaxLengthOfAddressData + 1 ) < byteCount )
       
   942         {
       
   943         byteCount = KMaxLengthOfAddressData + 1;
       
   944         }   
       
   945 
       
   946     while ( si < byteCount )
       
   947         {
       
   948         // Check if this is the last character of the message.
       
   949         // If it is, just shift it to the right. Otherwise,
       
   950         // fill the rest of the byte with the bits of the next 
       
   951         // source character.
       
   952         
       
   953         if ( si == ( byteCount - 1 ) )
       
   954             {
       
   955             TUint num2( ( aSource[ si ] >> tempModulo ) );
       
   956             aDest.Append( num2 );
       
   957             }
       
   958         else
       
   959             {
       
   960             TUint num2( ( aSource[ si ] >> tempModulo ) | 
       
   961                 ( aSource[ si + 1 ] << ( KLengthOfPackedByte - tempModulo ) ) );
       
   962             aDest.Append( num2 );
       
   963             }
       
   964    
       
   965         di++;
       
   966         tempModulo = di % KLengthOfPackedByte;
       
   967 
       
   968         // Check if the destination byte could take the entire source character.
       
   969         // In that case, the source character does not have to be divided and
       
   970         // the next source character can be taken.
       
   971         
       
   972         if ( tempModulo == 0)
       
   973             {
       
   974             si += KTwoCharInByte;
       
   975             }
       
   976         else
       
   977             {
       
   978             si++;
       
   979             }
       
   980         }
       
   981     
       
   982     // Return the length of the coded message.
       
   983     return byteCount;
       
   984     }
       
   985 
       
   986 // -----------------------------------------------------------------------------
       
   987 // CMmSmsGsmAddress::GsmLibUnpackAlphanumericAddress
       
   988 //  This function decodes a address that has been coded using 
       
   989 // the algorithm described in GSM 03.40 annex 2. The result string will 
       
   990 // consist of bytes that contain a 7-bit character each
       
   991 // ----------------------------------------------------------------------------- 
       
   992 //
       
   993 void CMmSmsGsmAddress::GsmLibUnpackAlphanumericAddress
       
   994         ( 
       
   995         TDesC8 const& aSource,  // Packed address data
       
   996         TUint aAmountOfChars,   // Amount of characters in address data
       
   997         TDes8& aDest            // Unpacked address data 
       
   998         )
       
   999     {
       
  1000 TFLOGSTRING("TSY: CMmSmsGsmAddress::GsmLibUnpackAlphanumericAddress");
       
  1001 OstTrace0( TRACE_NORMAL, CMMSMSGSMADDRESS_GSMLIBUNPACKALPHANUMERICADDRESS, "CMmSmsGsmAddress::GsmLibUnpackAlphanumericAddress" );
       
  1002     TUint8 di( 0 );
       
  1003     TUint8 si( 0 );  
       
  1004     TUint tempModulo( 0 );
       
  1005 
       
  1006     // Maximum length of address data field is 10 bytes. 10 bytes can contain
       
  1007     // 11 compressed 7-bit characters. Because of this maximum
       
  1008     // amount of characters in alphanumeric address is 11.
       
  1009     if ( ( KMaxLengthOfAddressData + 1 ) < aAmountOfChars )
       
  1010         {
       
  1011         aAmountOfChars = KMaxLengthOfAddressData + 1;
       
  1012         }
       
  1013 
       
  1014     // The location of the current 7-bit character determines the
       
  1015     // action to be taken. Only every 7th character is not divided into
       
  1016     // two bytes. All other characters will have to be contructed by
       
  1017     // combining bits of two consequent bytes.
       
  1018 
       
  1019     for ( di = 0; di < aAmountOfChars; di++ )
       
  1020         {
       
  1021         TUint num2( 0 );
       
  1022         tempModulo = di % KLengthOfByte;
       
  1023         switch ( tempModulo )
       
  1024             {
       
  1025             case 0:
       
  1026                 {
       
  1027                 num2 = aSource[ si ] & 0x7F;
       
  1028                 break;
       
  1029                 }
       
  1030             case KLengthOfPackedByte:
       
  1031                 {
       
  1032                 num2 = ( aSource[ si ] >> 1 ) & 0x7F;
       
  1033                 si++;
       
  1034                 break;
       
  1035                 }
       
  1036             default:
       
  1037                 {
       
  1038                 num2  = aSource[ si ] >> ( KLengthOfByte - tempModulo );
       
  1039                 num2 &= KGsmLibSmsUnpackMaskTable[ tempModulo ];
       
  1040                 num2 |= aSource[ si+1 ] << ( tempModulo );
       
  1041                 num2 &= 0x7F;
       
  1042                 si++;
       
  1043                 break;
       
  1044                 }
       
  1045             }
       
  1046             
       
  1047         aDest.Append( num2 );
       
  1048         }
       
  1049     }
       
  1050 
       
  1051 //  End of File