phoneclientserver/EnPolicy/Src/DosEnPolicy/CDOSEmergencyNumberPolicy.cpp
changeset 0 ff3b6d0fd310
child 19 7d48bed6ce0c
equal deleted inserted replaced
-1:000000000000 0:ff3b6d0fd310
       
     1 /*
       
     2 * Copyright (c) 2004-2005 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 "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:  Provides DOS emergency number policy API implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "CDOSEmergencyNumberPolicy.h"
       
    21 #include <mmtsy_names.h>
       
    22 #include <telservicesvariant.hrh>
       
    23 
       
    24 #include <centralrepository.h>
       
    25 #include <telservicesinternalcrkeys.h>
       
    26 #include <defaultemergencynumberscrkeys.h>
       
    27 
       
    28 // CONSTANT
       
    29 const TInt KDosEmergencyNumberMaxLength = 6;
       
    30 //Prefix for Sip.
       
    31 _LIT( KSipPrefix, "sip:" );
       
    32 //Prefix for Tel.
       
    33 _LIT( KTelPrefix, "tel:" );
       
    34 //Prefix for Sos.
       
    35 _LIT( KSosPrefix, "sos:" );
       
    36 // @ char
       
    37 _LIT( KAt, "@" );
       
    38 // Prefix length
       
    39 const TInt KPrefixLength = 4;
       
    40 
       
    41 // ============================ MEMBER FUNCTIONS ===============================
       
    42 
       
    43 // -----------------------------------------------------------------------------
       
    44 // CDosEmergencyNumberPolicy::~CDosEmergencyNumberPolicy()
       
    45 // -----------------------------------------------------------------------------
       
    46 //
       
    47 CDosEmergencyNumberPolicy::~CDosEmergencyNumberPolicy()
       
    48     {
       
    49     if ( iListener )
       
    50         {
       
    51         iListener->StopListening();
       
    52         delete iListener;
       
    53         }
       
    54     delete iCenRep;
       
    55 
       
    56     iProductSpecificList.Zero();
       
    57 
       
    58     iCustomPhone.Close();
       
    59     iMobilePhone.Close();
       
    60     }
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CDosEmergencyNumberPolicy::ConstructL()
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 void CDosEmergencyNumberPolicy::ConstructL( RTelServer& aETelServer )
       
    67     {
       
    68     iETelServer = aETelServer;
       
    69 
       
    70     User::LeaveIfError( iMobilePhone.Open( iETelServer , KMmTsyPhoneName ) );
       
    71     User::LeaveIfError( iCustomPhone.Open( iMobilePhone) );
       
    72 
       
    73     TInt variantReadOnlyValues = 0;
       
    74     TInt err = KErrNone;
       
    75 
       
    76     CRepository* variationFlags = CRepository::NewL( KCRUidTelSrvVariation );
       
    77     err = variationFlags->Get( KTelSrvVariationFlags , variantReadOnlyValues );
       
    78 
       
    79     if ( err != KErrNotFound )
       
    80         {
       
    81         User::LeaveIfError( err );
       
    82         }  
       
    83 
       
    84     if ( KTelSrvLVFlagAdvancedENCheck & variantReadOnlyValues )
       
    85         {
       
    86         iAdvancedCheck = ETrue;
       
    87         }
       
    88     else
       
    89         {
       
    90         iAdvancedCheck = EFalse;
       
    91         }
       
    92     
       
    93     delete variationFlags;
       
    94 
       
    95     iCenRep = CRepository::NewL( KCRUidDefaultEmergencyNumbers );    
       
    96     iListener = CCenRepNotifyHandler::NewL( 
       
    97         *this, 
       
    98         *iCenRep, 
       
    99         CCenRepNotifyHandler::EStringKey, 
       
   100         KDefaultEmergencyNumbersList );
       
   101     
       
   102     iListener->StartListeningL();
       
   103     
       
   104     ReadProductSpecificNumbers();
       
   105     }
       
   106 
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CDosEmergencyNumberPolicy::IsEmergencyNumberL 
       
   110 // 
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 TInt CDosEmergencyNumberPolicy::IsEmergencyNumber ( 
       
   114                                     TPhCltTelephoneNumber& aTelNumber, 
       
   115                                     TPhCltEmergencyNumberQueryMode aMode,
       
   116                                     TBool& aIsEmergencyNumber )
       
   117     {   
       
   118     TPhCltTelephoneNumber checkedTelNumber(aTelNumber);
       
   119     ParseNumber( checkedTelNumber );
       
   120     aIsEmergencyNumber = EFalse;
       
   121     RMmCustomAPI::TEmerNumberCheckMode  checkedNumberMode;
       
   122     if ( checkedNumberMode.iNumber.MaxLength() >= checkedTelNumber.Length() ) // aTelNumber -> checkedTelNumber
       
   123         {
       
   124         checkedNumberMode.iNumber = checkedTelNumber; // aTelNumber -> checkedTelNumber
       
   125         }
       
   126     else
       
   127         {
       
   128         // too long, cannot be checked
       
   129         return KErrArgument;
       
   130         }
       
   131 
       
   132     // set check type
       
   133     switch ( aMode )
       
   134         {
       
   135         case EPhCltEmergencyNumberQueryModeAdvanced:
       
   136             {
       
   137             // check if it is a product specific number.
       
   138             if ( IsInListByAdvancedMode( checkedTelNumber ) ) // aTelNumber -> checkedTelNumber
       
   139                 {
       
   140                 aTelNumber = checkedTelNumber; // aTelNumber -> checkedTelNumber
       
   141                 aIsEmergencyNumber = ETrue;
       
   142                 return KErrNone;
       
   143                 }
       
   144             
       
   145             // if TSY doesn't support advanced mode, then check by S60 advanced mode
       
   146             // based on TSY normal mode check.
       
   147             if ( ! iAdvancedCheck )
       
   148                 {
       
   149                 TInt length = 
       
   150                     Min( checkedTelNumber.Length(), KDosEmergencyNumberMaxLength ); // aTelNumber -> checkedTelNumber
       
   151                 checkedNumberMode.iCheckMode = RMmCustomAPI::EEmerNumberCheckNormal;
       
   152 
       
   153                 TInt result = KErrArgument;
       
   154                 while ( ( length > 0 ) && ! aIsEmergencyNumber )
       
   155                     {
       
   156                     checkedNumberMode.iNumber = checkedTelNumber.Right( length ); // aTelNumber -> checkedTelNumber
       
   157                     result = iCustomPhone.CheckEmergencyNumber( 
       
   158                             checkedNumberMode, aIsEmergencyNumber );
       
   159 
       
   160                     if ( result == KErrNone && aIsEmergencyNumber )
       
   161                         {
       
   162                         aTelNumber = checkedNumberMode.iNumber;
       
   163                         }
       
   164 
       
   165                     length--;
       
   166                     }
       
   167 
       
   168                 return result;
       
   169                 }
       
   170             else
       
   171                 {
       
   172                 checkedNumberMode.iCheckMode = 
       
   173                     RMmCustomAPI::EEmerNumberCheckAdvanced;
       
   174                 }
       
   175             }
       
   176             break;
       
   177         case EPhCltEmergencyNumberQueryModeNormal:
       
   178         case EPhCltEmergencyNumberQueryModeNormalWriteback:
       
   179             // check if it is a product specific number.
       
   180             if ( IsInListByNormalMode( checkedTelNumber ) ) // aTelNumber -> checkedTelNumber
       
   181                 {
       
   182                 aTelNumber = checkedTelNumber; // aTelNumber -> checkedTelNumber
       
   183                 aIsEmergencyNumber = ETrue;
       
   184                 return KErrNone;
       
   185                 }
       
   186 
       
   187             // flow thru
       
   188         default:
       
   189             checkedNumberMode.iCheckMode = 
       
   190                 RMmCustomAPI::EEmerNumberCheckNormal;
       
   191             break;
       
   192         }
       
   193 
       
   194     // do checking   
       
   195     TInt err = iCustomPhone.CheckEmergencyNumber ( 
       
   196       checkedNumberMode, aIsEmergencyNumber );
       
   197 
       
   198     aTelNumber = checkedNumberMode.iNumber;
       
   199    
       
   200     return err;
       
   201     }
       
   202 
       
   203 // -----------------------------------------------------------------------------
       
   204 // CDosEmergencyNumberPolicy::ReadProductSpecificNumbers
       
   205 // 
       
   206 // Reads product specific values from central repository
       
   207 // -----------------------------------------------------------------------------
       
   208 //
       
   209 void CDosEmergencyNumberPolicy::ReadProductSpecificNumbers()
       
   210     {
       
   211     // This is done only once in bootup phase.
       
   212     iProductSpecificList.Zero();
       
   213 
       
   214     TInt err = KErrNone;
       
   215 
       
   216 
       
   217         err = iCenRep->Get( KDefaultEmergencyNumbersList, 
       
   218                                 iProductSpecificList );
       
   219 
       
   220     if ( err != KErrNone )
       
   221         {
       
   222         // just to make sure, if central repository has modified it,
       
   223         // even when there was an error.
       
   224         iProductSpecificList.Zero();
       
   225         }
       
   226     }
       
   227 
       
   228 // -----------------------------------------------------------------------------
       
   229 // CDosEmergencyNumberPolicy::IsInListByAdvancedMode
       
   230 // 
       
   231 // Checks if the number is in list by advanced mode check.
       
   232 //
       
   233 // -----------------------------------------------------------------------------
       
   234 //
       
   235 TBool CDosEmergencyNumberPolicy::IsInListByAdvancedMode ( TDes& aNumber )
       
   236     {    
       
   237     TLex list( iProductSpecificList );
       
   238     TLexMark mark;
       
   239     TPtrC token_candidate( KNullDesC() ) ; 
       
   240     
       
   241     for ( TInt i = 0; i < KEnPolicySDEmergencyNumberListLength; i++ )
       
   242         {
       
   243         list.Mark( mark );
       
   244         list.SkipCharacters();
       
   245         TPtrC token;
       
   246         token.Set( list.MarkedToken( mark ) );
       
   247         if ( token.Length() && ( token == aNumber.Right( token.Length() ) ) )
       
   248             {
       
   249             // _DDPRINT( 4, "ENPolicy.SDM.IsInListAdvanced.ok.", place );
       
   250             if( token_candidate == KNullDesC )
       
   251                 { 
       
   252                 token_candidate.Set( token ); 
       
   253                 } 
       
   254             else 
       
   255                 { 
       
   256                 if( token.Length() > token_candidate.Length() ) 
       
   257                     { 
       
   258                     token_candidate.Set( token );                          
       
   259                     } 
       
   260                 } 
       
   261             } 
       
   262         list.Inc(); 
       
   263         } 
       
   264         
       
   265     if( token_candidate != KNullDesC ) 
       
   266         { 
       
   267         aNumber = token_candidate; 
       
   268         return ETrue; 
       
   269         }    
       
   270 
       
   271     return EFalse;   
       
   272     }
       
   273 
       
   274 // -----------------------------------------------------------------------------
       
   275 // CDosEmergencyNumberPolicy::IsInListByNormalMode
       
   276 // 
       
   277 // Checks if the number is in list by normal mode check.
       
   278 //
       
   279 // -----------------------------------------------------------------------------
       
   280 //
       
   281 TBool CDosEmergencyNumberPolicy::IsInListByNormalMode( const TDesC& aNumber )
       
   282     {
       
   283     TInt length = aNumber.Length();
       
   284     TInt place = iProductSpecificList.Find( aNumber ); // first number of aNumber
       
   285 
       
   286     // _DDPRINT( 4, "ENPolicy.SDM.IsInListNormal.ok.", place );    // debug print
       
   287 
       
   288     if ( place < 0 )
       
   289         {
       
   290         // negative value is an error, not found!
       
   291         // return immediately
       
   292         return EFalse;
       
   293         }
       
   294 
       
   295     TInt endOfMatch = place + length; // end of number + 1
       
   296 
       
   297     // we check the begining
       
   298     if ( place > 0 )
       
   299         {
       
   300         // we are not in the begining of buffer, so we have to check
       
   301         // char before that
       
   302         if ( iProductSpecificList[ place -1 ] != KEnPolicySDNumberSeparator )
       
   303             {
       
   304             // this was just a substring numbers before that
       
   305             return EFalse;
       
   306             }
       
   307         }
       
   308 
       
   309     // beginning was ok, so we can continue
       
   310     
       
   311     // now checking the end
       
   312     // there must be atleast one empty space in the end that
       
   313     // we do the checking of number end.
       
   314     if ( endOfMatch < ( iProductSpecificList.Length() - 2 ) )
       
   315         {
       
   316         if ( iProductSpecificList[ endOfMatch ] != KEnPolicySDNumberSeparator )
       
   317             {
       
   318             return EFalse;
       
   319             }
       
   320         }
       
   321         
       
   322 	//match is wrong, only part of ememergency number is matched
       
   323 	int newmatchlen = 0;
       
   324 	for (int i = place; i < iProductSpecificList.Length(); i++)
       
   325 		{
       
   326 		if(iProductSpecificList [i] != KEnPolicySDNumberSeparator )
       
   327 			newmatchlen++;
       
   328 		else
       
   329 			break;	
       
   330 		}
       
   331 		
       
   332 		if (length != newmatchlen)
       
   333 			{
       
   334 			return EFalse;
       
   335 			}
       
   336 		
       
   337 
       
   338     // if we get so far, its ok.
       
   339     return ETrue;
       
   340     }
       
   341     
       
   342 // -----------------------------------------------------------------------------
       
   343 // CDosEmergencyNumberPolicy::ParserNumber
       
   344 // 
       
   345 // Removes sip prefixis beging of the number and end of the number after @ char.
       
   346 // @ character is also removed.
       
   347 //
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 void CDosEmergencyNumberPolicy::ParseNumber( TPhCltTelephoneNumber& aTelNumber )
       
   351     {
       
   352 	// Does number contains prefix. If yes then remove it
       
   353 	
       
   354     if ( 0 == aTelNumber.FindC( KSipPrefix ) ||
       
   355          0 == aTelNumber.FindC( KTelPrefix ) ||
       
   356 	       0 == aTelNumber.FindC( KSosPrefix ) )
       
   357         {
       
   358         aTelNumber.Delete( 0, KPrefixLength );
       
   359 	      }
       
   360 	    // Does Number contains domain part. If yes remove it at beging of @ character.
       
   361       TInt atIndex = aTelNumber.Find( KAt );
       
   362       TInt telNumberLength = aTelNumber.Length();
       
   363 	    if ( 0 < atIndex && 
       
   364 	         atIndex < telNumberLength )
       
   365         {
       
   366 		    aTelNumber.Delete( atIndex, telNumberLength - atIndex );
       
   367 		    }
       
   368     }
       
   369 
       
   370 // -----------------------------------------------------------------------------
       
   371 // CDosEmergencyNumberPolicy::HandleNotifyString
       
   372 // 
       
   373 // Inherited from MCenRepNotifyHandlerCallback.
       
   374 // -----------------------------------------------------------------------------
       
   375 //
       
   376 void CDosEmergencyNumberPolicy::HandleNotifyString( 
       
   377     TUint32 aId, const TDesC16& aNewValue )
       
   378     {
       
   379     if( aId == KDefaultEmergencyNumbersList )
       
   380         {
       
   381         iProductSpecificList.Zero();
       
   382         iProductSpecificList.Copy( aNewValue );
       
   383         }
       
   384 
       
   385     }
       
   386 
       
   387 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   388 
       
   389 // -----------------------------------------------------------------------------
       
   390 // NewEnPolicy()
       
   391 // 
       
   392 // -----------------------------------------------------------------------------
       
   393 //
       
   394 EXPORT_C CEmergencyNumberPolicy* NewEnPolicyL()
       
   395     {
       
   396     return new (ELeave) CDosEmergencyNumberPolicy;
       
   397     }
       
   398 
       
   399 // End of File