remotelock/RemoteLockEngine/Src/RemoteLock.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 12 Mar 2010 15:46:51 +0200
branchRCL_3
changeset 7 6e226572c5f0
parent 0 164170e6151a
child 21 09b1ac925e3f
permissions -rw-r--r--
Revision: 201007 Kit: 201008

/*
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Implementation of RemoteLock Engine
*
*/


// INCLUDE FILES 
#include <smscmds.h>
#include <smutset.h>
#include <smuthdr.h>
#include <e32property.h>
#include <PSVariables.h>
#include <mtclreg.h> //CClientMtmRegistry
#include <smsclnt.h> //CSmsClientMtm
#include <txtrich.h>
#include <bautils.h> //file system utilities
#include <RemoteLock.rsg>
#ifdef RD_MULTIPLE_DRIVE 
#include <driveinfo.h>
#else
#include <pathinfo.h> 
#endif //RD_MULTIPLE_DRIVE 
#include <coreapplicationuisdomainpskeys.h>
#include <charconv.h>
#include <ProfileEngineSDKCRKeys.h>
#include <Profile.hrh>
#include <stringresourcereader.h> //CStringResourceReader
#include "RemoteLockTrace.h"
#include "RemoteLock.h"

// EXTERNAL DATA STRUCTURES

// EXTERNAL FUNCTION PROTOTYPES  

// CONSTANTS

_LIT( KRLockResourceFileName ,"z:\\Resource\\apps\\Remotelock.RSC" );

//Interval of reconnecting to the message server 
const TInt KRLockTimerInterval( 10000000 ); 
const TInt KRLockMaxMemoryCardPasswdLength( 8 );
const TInt KBufLengthInUnicodeCheck = 200;

// MACROS

// LOCAL CONSTANTS AND MACROS

// MODULE DATA STRUCTURES

// LOCAL FUNCTION PROTOTYPES

// FORWARD DECLARATIONS

// ---------------------------------------------------------------------------
// E32Main()
// ---------------------------------------------------------------------------
//
GLDEF_C TInt E32Main() 
    {    
    __UHEAP_MARK;
    if ( User::TrapHandler() != NULL )
        {
        User::SetTrapHandler( NULL );
        }
        
    CTrapCleanup* cleanup = CTrapCleanup::New();
    if ( !cleanup )
        {
        return KErrNone;
        }

    TRAPD( err, ThreadStartL() );
    ( void ) err;
    
    delete cleanup;
    __UHEAP_MARKEND;

    return err;    
    }


// ---------------------------------------------------------------------------
// ThreadStartL()
// ---------------------------------------------------------------------------
//
LOCAL_C TInt ThreadStartL()
    {
    RL_TRACE_PRINT(" [ rl.exe ] Inside ThreadStartL() "); 
    CActiveScheduler *threadScheduler = new CActiveScheduler;
    
    CleanupStack::PushL( threadScheduler );
    
    CActiveScheduler::Install( threadScheduler );
    
    RL_TRACE_PRINT(" [ rl.exe ] Create remotelock object "); 

    CRemoteLock* remoteLock = CRemoteLock::NewL();
    
    RL_TRACE_PRINT(" [ rl.exe ] Creation of Remotelock is done" );
    
    CleanupStack::PushL( remoteLock );
        
    RL_TRACE_PRINT(" Doing Rendezvous..."); 
    // Initialisation complete, now signal the client
    RProcess::Rendezvous(KErrNone);            

    CActiveScheduler::Start();
    
    CleanupStack::PopAndDestroy( 2 );
    
    return KErrNone;
    }


// ---------------------------------------------------------------------------
// CRemoteLock::NewL
// Two-Phased constructor.
// ---------------------------------------------------------------------------
//
CRemoteLock* CRemoteLock::NewL()
    {
    RL_TRACE_PRINT(" [ rl.exe ] NewL()");
    
    CRemoteLock* self = new ( ELeave ) CRemoteLock;
    
    CleanupStack::PushL( self );
    
    self->ConstructL();  
    
    CleanupStack::Pop();
    
    RL_TRACE_PRINT(" [ rl.exe ] exit NewL() ");
    
    return self;
    }


// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
CRemoteLock::~CRemoteLock()
    {
    Cancel();
    delete iRemoteLockSetting;
    delete iRemoteLockCode;
    delete iMemoryCardPasswd;
    delete iStoredCode;
    delete iStoredTrimmedCode;
    delete iClientMtmForSending;
    delete iMtmReg;
    delete iMsvSession;
    delete iObserver;
    
    if ( iProfileNotifyHandler ) 
        {
      iProfileNotifyHandler->StopListening();
      delete iProfileNotifyHandler;
        }
    delete iProfileSession; 
    }


// ---------------------------------------------------------------------------
// CRemoteLock::HandleSessionEventL
//
// Called by message server when new event occures.
// ---------------------------------------------------------------------------
//
void CRemoteLock::HandleSessionEventL( 
    TMsvSessionEvent aEvent, 
    TAny* aArg1, 
    TAny* aArg2, 
    TAny* /*aArg3*/  )
    {
    RL_TRACE_PRINT(" [ rl.exe ] HandleSessionEventL() ");  
    switch ( aEvent )
        {            
        // A new entry has been created in the message server
        case EMsvEntriesCreated: 
            {
            RL_TRACE_PRINT(" [ rl.exe ] HandleSessionEventL() 1");  
            if ( !iIsEnabled )
                {
                // Do nothing if remote lock is disabled
                return;
                }
            
            if ( *( static_cast<TMsvId*>( aArg2 ) ) != 
                KMsvGlobalInBoxIndexEntryId )
                {
                // Doing nothing if not to inbox
                return;
                }

            CMsvEntrySelection* entries =
                static_cast<CMsvEntrySelection*>( aArg1 );

            for ( TInt i = 0; i < entries->Count(); i++ )
                {
                TMsvEntry entryInfo;
                TMsvId serviceId;
                iMsvSession->GetEntry( entries->At( i ), serviceId, entryInfo );

                if ( entryInfo.iMtm != KUidMsgTypeSMS || 
                    entryInfo.iDescription.Length() > KRLockMaxLockCodeLength || 
                    entryInfo.iDescription.Length() == 0)
                    {
                    // Doing nothing if not a SMS, or length not appropriate.
                    return;
                    }

                // For performance reasons, lets first compare the content of 
                // the SMS (taken from the TMsvEntry, containing no extra 
                // spaces) against the saved digest of a trimmed remote lock 
                // code. This way unnecessary access to CMsvEntry is avoided 
                // if these two do not match.
                
                
                if ( iRemoteLockSetting->CompareLockCodesL( 
                    entryInfo.iDescription, *iStoredTrimmedCode ) )
                    {
                    CMsvEntry* entry = 
                        iMsvSession->GetEntryL( entries->At( i ) );
                
                    // The CMsvEntry object must be deleted by the client
                    // when it is no longer required. 
                    CleanupStack::PushL( entry );

                    TRAPD( error, HandleMessageL( entry ) );

                    CleanupStack::PopAndDestroy( 1 ); // entry
                    
                    delete iRemoteLockCode;
                    iRemoteLockCode = NULL;
                    
                    User::LeaveIfError( error );
                    } // if
                } // for
            break;
            } // case
      
        // When message server is closed and server terminated
        case EMsvCloseSession:
        case EMsvServerFailedToStart:
        case EMsvServerTerminated:
            {
            RL_TRACE_PRINT(" [ rl.exe ] HandleSessionEventL() 2");  
            // When server is terminated remote lock will
            // try to reconnect it in every 10 seconds.
            After( KRLockTimerInterval );
            break;
            }

        default:
            break;
        }
    RL_TRACE_PRINT(" [ rl.exe ] exit HandleSessionEventL() ");
    }


// ---------------------------------------------------------------------------
// CRemoteLock::HandleRemoteLockNotifyL
// Function is called when remote lock setting is changed by client
// ---------------------------------------------------------------------------
//
void CRemoteLock::HandleRemoteLockNotifyL()
    {
    RL_TRACE_PRINT(" [ rl.exe ] HandleNotify() ");
    CheckSettingsL();
    RL_TRACE_PRINT(" [ rl.exe ] exit HandleNotify() ")
    }
    
    
// ---------------------------------------------------------------------------
// CRemoteLock::CRemoteLock
// default constructor
// ---------------------------------------------------------------------------
CRemoteLock::CRemoteLock() : CTimer( CActive::EPriorityStandard )
    {
    iRemoteLockCode = NULL;
    iMemoryCardPasswd = NULL;
    iStoredCode = NULL;
    iStoredTrimmedCode = NULL;
    iClientMtmForSending = NULL;
    iMtmReg = NULL;
    iRemoteLockSetting = NULL;
    iMsvSession = NULL;
    iIsEnabled = EFalse;
    iLockedByRL = EFalse; 
    iMemoryCardLockedByRL = EFalse;
    iSubscribeProfile = EFalse;
    iProfileSession = NULL;
    iObserver = NULL;
    iProfileNotifyHandler = NULL;   
    }


// ---------------------------------------------------------------------------
// CRemoteLock::ConstructL
// Symbian 2nd phase constructor can leave.
// ---------------------------------------------------------------------------
//
void CRemoteLock::ConstructL()
    {    
    RL_TRACE_PRINT(" [ Rl.exe ] ConstructL()"); 
    
    CTimer::ConstructL();
    
    iRemoteLockSetting = CRemoteLockSettings::NewL( this ); 
     
    iRemoteLockSetting->RemoteLockNotifyL( ETrue );
    
    CheckSettingsL(); 
    // Add active object into active scheduler
    CActiveScheduler::Add( this );
        
    
    
    RL_TRACE_PRINT(" [ rl.exe ] exit ConstructL() ");
    }
    
    
// ---------------------------------------------------------------------------
// CRemoteLock::HandleMessageL()
//
// Handles the message: checks if it really is remote lock message, and acts
// accordingly.
// ---------------------------------------------------------------------------
//
void CRemoteLock::HandleMessageL( CMsvEntry* aEntry )
    {
    RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() ");
    delete iRemoteLockCode;
    iRemoteLockCode = NULL;
    TMsvEntry entryInfo = aEntry->Entry();
    if ( !iMtmReg )
        {
        iMtmReg = CClientMtmRegistry::NewL( *iMsvSession );
        }

    // Loops 100 times to ensure the clientMtm is correctly created
    CBaseMtm* clientMtm = NULL;
    TInt error = 0;
    TInt i;
    for ( i = 0; i < 100; i++ )
        {
        TRAP( error, clientMtm = iMtmReg->NewMtmL( entryInfo.iMtm ));
        if ( error == KErrNone )
            {
            break;
            }
        } 
   
    RL_TRACE_PRINT_NUM("[rl.exe] HandleMessageL() error after NewMTmL = %d", error );

    User::LeaveIfError( error );
    CleanupStack::PushL( clientMtm );        

    clientMtm->SwitchCurrentEntryL( entryInfo.Id() );

    RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() after switch Current EntryL");
   
    CSmsClientMtm* smsClientMTM = STATIC_CAST( CSmsClientMtm*, clientMtm );
    
    // Change from 100 to 20. When the message storage is memory card. 
    // LoadMessageL() function return -21 when loading the message.
    // It might be caused by slow operation, so we add 0.05 seconds pending 
    // in each loop.
    // @ check why loading operation is slow!
    for ( i = 0; i < 20; i++ )
        {   
        RL_TRACE_PRINT_NUM("[rl.exe] HandleMessageL() error load message1 = %d", error );
        
        // Loops 100 times to ensure the LoadMessageL() succeedes
        TRAP( error, smsClientMTM->LoadMessageL() );
        
        RL_TRACE_PRINT_NUM("[rl.exe] HandleMessageL() error load message2 = %d", error );
        
        if ( error == KErrNone )
            {
            break;
            }
        
        const TInt KDelay = 50000; // 0.05s
        User::After( KDelay );
        }
    
    RL_TRACE_PRINT_NUM("[rl.exe] HandleMessageL() error after LoadMessageL = %d", error );
    
    User::LeaveIfError( error );        

    CRichText& mtmBody = smsClientMTM->Body();                            
    
    // Let's then use the real content of the SMS (taken from 
    // the message body) and compare that against the 
    // saved digest of a complete (not trimmed) remote lock 
    // code. This ensures that remote locking happens only
    // if the SMS is exactly the same as what the user has 
    // specified.
    iRemoteLockCode = HBufC::NewL( mtmBody.DocumentLength() );

    TPtr smsTextPtr = iRemoteLockCode->Des();
    smsTextPtr.Copy( mtmBody.Read( 0, mtmBody.DocumentLength() ) );
    
    
    // The following code is to get the current state
    // of manuallock. If manuallock state is off, that means
    // the owner has unlocked the phone or the phone has
    // never been locked by both remote lock and auto lock.
    RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() Pub&Sub Get autoLState");    
    TInt autoLState;
    RProperty property;
    
    #ifndef RD_STARTUP_CHANGE    
    User::LeaveIfError( property.Attach( KUidSystemCategory, KPSUidAutolockStatusValue ));
    #else
    User::LeaveIfError( property.Attach( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus ));
    #endif //RD_STARTUP_CHANGE
    property.Get( autoLState );
    
    #ifndef RD_STARTUP_CHANGE
    if ( autoLState == EPSAutolockOff ) 
    #else
    if ( autoLState == EAutolockOff ) 
    #endif //RD_STARTUP_CHANGE      
      {  
      //Assign iLockedByRL to EFalse to indicate that
      //the phone is not locked by Remote lock, the 
      //reply SMS should be sent if correct remote lock
      //code is received.
      iLockedByRL = EFalse;
      }
    
    property.Close();
    
    // If the phone receives correct lock code, the phone
    // will be locked eventhough it may have been locked by
    // auto lock.
  
    if ( VerifyAndLockL() ) 
        {
        RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() After VerifyAndLockL() ");
        // Sets remote lock sms as read
        entryInfo.SetVisible( ETrue );
        entryInfo.SetUnread( EFalse );
        entryInfo.SetNew( EFalse );
        entryInfo.SetInPreparation( EFalse );
        entryInfo.SetReadOnly( ETrue );
        aEntry->ChangeL( entryInfo );
        
        
        // Locks MemoryCard drive.
        iStateMemoryCard = SetMemoryCardPasswdL( EFalse );

        if ( iClientMtmForSending )
            {
            // Previous reply sending is still in progress, let's not start 
            // sending new one.
            User::Leave( KErrNone );
            } 
        
        // The value of iLockedByRL is checked before sending SMS
        // to make sure if the phone has been locked by remote 
        // lock. By doing this, it is able to avoid the threat where 
        // malware tries to use remote lock to keep on sending SMS.
        
        
        if ( !iLockedByRL )
            { 
            RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() Send re-SMS ");
            // Replies sms
            iLockedByRL = ETrue;
            CSmsHeader& header = smsClientMTM->SmsHeader();
            HBufC* recipientAddress = header.FromAddress().AllocLC();

            TBool initialSendMessage = EFalse;
            TRAP( error, initialSendMessage = InitialSendMessageL() );
            if ( error != KErrNone )
                {
                delete iClientMtmForSending;
                iClientMtmForSending = NULL;
                User::Leave( error );
                }
                
            RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() Check recipientaddresslenght ");
            if ( recipientAddress->Length() > 0 && initialSendMessage )
                {
                RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() before call sendMEssage ");
                TRAP( error, SendMessageL( *recipientAddress ) );
                if ( error != KErrNone )
                    {
                    RL_TRACE_PRINT(" [ rl.exe ] HandleMessageL() error occurs ");
                    delete iClientMtmForSending;
                    iClientMtmForSending = NULL;
                    User::Leave( error );
                    }
                }
            delete iClientMtmForSending;
            iClientMtmForSending = NULL;

            CleanupStack::PopAndDestroy( 1 ); // recipientAddress
            }
        CleanupStack::PopAndDestroy( 1 ); // clientMtm    
        }
    else
        {
        CleanupStack::PopAndDestroy( 1 ); // clientMtm
        }
    RL_TRACE_PRINT(" [ rl.exe ] exit HandleMessageL() ");
    }


// ---------------------------------------------------------------------------
// CRemoteLock::VerifyAndLockL()
//
// Compares if the remote lock received in SMS is correct.
// If correct, locks the terminal.
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::VerifyAndLockL()
    {
    RL_TRACE_PRINT(" [ rl.exe ] VerifyAndLockL() ");
    
    User::LeaveIfNull( iRemoteLockCode );
    User::LeaveIfNull( iStoredCode );

    if ( iRemoteLockSetting->CompareLockCodesL( 
        *iRemoteLockCode, *iStoredCode ) )
        {        
        return ActivateDeviceLock();
        }
    RL_TRACE_PRINT(" [ rl.exe ] exit VerifyAndLockL() ");
    return EFalse;
    }


// ---------------------------------------------------------------------------
// CRemoteLock::ActivateDeviceLock()
// Activate the device lock to lock the phone
// ---------------------------------------------------------------------------
// 
TBool CRemoteLock::ActivateDeviceLock()
    {
    RL_TRACE_PRINT(" [ rl.exe ] ActivateDeviceLock() ");
       
    RProperty property;
        
    TInt err = 0;
       
    #ifndef RD_STARTUP_CHANGE
    err = property.Attach( KUidSystemCategory, 
                               KPSUidAutolockStatusValue );
    #else
    err = property.Attach( KPSUidCoreApplicationUIs, 
                               KCoreAppUIsAutolockStatus );
    #endif 
    if ( err != KErrNone )
        {
        return EFalse;
        }

    #ifndef RD_STARTUP_CHANGE
    property.Set( EPSRemoteLocked );
    #else
    property.Set( ERemoteLocked );
    #endif //RD_STARTUP_CHANGE 
 
    property.Close();
    RL_TRACE_PRINT(" [ rl.exe ] exit ActivateDeviceLock() ");
    return ETrue;
    }



// ---------------------------------------------------------------------------
// CRemoteLock::CheckSettingsL
// Checks remote lock setting.
// ---------------------------------------------------------------------------
//
void CRemoteLock::CheckSettingsL()
    {
    RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL () "); 
    iRemoteLockSetting->GetEnabled( iIsEnabled );
    
    delete iStoredCode;
    iStoredCode = NULL;
    iStoredCode = HBufC::NewL( KRLockStoredLockCodeLength );
    TPtr storedCodePtr = iStoredCode->Des();
    
    delete iStoredTrimmedCode;
    iStoredTrimmedCode = NULL;
    iStoredTrimmedCode = HBufC::NewL( KRLockStoredLockCodeLength );
    TPtr storedTrimmedCodePtr = iStoredTrimmedCode->Des();
    
    iRemoteLockSetting->GetLockCode( storedCodePtr, storedTrimmedCodePtr );
        
    if ( iIsEnabled )
        {
        RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() enable "); 
       
        if ( !iMsvSession )
            {
            TRAPD( error, iMsvSession = CMsvSession::OpenAsyncL( *this ) );
        
            RL_TRACE_PRINT_NUM(" [ rl.exe ] CheckSettingsL() openasyncL %d ", error );
        
            if ( error != KErrNone )
                {
                After( KRLockTimerInterval );
                }  
            }

       if ( !iProfileSession )
           {
           RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() create session "); 
           iProfileSession = CRepository::NewL( KCRUidProfileEngine ); 
           }
       if ( !iObserver )
           {
           iObserver =  CRLLockObserver::NewL( this );      
           } 
       if( !iSubscribeProfile )
           {
           ProfileNotifyL( ETrue );
           iSubscribeProfile = ETrue; 
           }   
        }
    else
        {
        RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() disable "); 
        
        delete iClientMtmForSending;
        iClientMtmForSending = NULL;
        delete iMtmReg;
        iMtmReg = NULL;
        delete iMsvSession;
        iMsvSession = NULL;
        
        RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() delete iMsvSession ");
        
        if ( iSubscribeProfile )
            {
            if ( !iProfileSession )
                {
                RL_TRACE_PRINT(" [ rl.exe ] CheckSettingsL() create session "); 
                iProfileSession = CRepository::NewL( KCRUidProfileEngine ); 
                }
            ProfileNotifyL( EFalse );
            delete iProfileSession;
            iProfileSession = NULL;
            delete iObserver;
            iObserver = NULL; 
            iSubscribeProfile = EFalse;
            }  
        }   
    
    RL_TRACE_PRINT(" [ rl.exe ] exit CheckSettingsL() ");
    }
    

// ---------------------------------------------------------------------------
// CRemoteLock::IsMemoryCardLocked
// Check MemoryCard whether it is locked or not.
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::IsMemoryCardLocked( const TDriveInfo& aDriveInfo ) const
    {
    return aDriveInfo.iMediaAtt&( KMediaAttLocked );
    }


// ---------------------------------------------------------------------------
// CRemoteLock::HasMemoryCardPassword
// Check MemoryCard whether it has password.
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::HasMemoryCardPassword( const TDriveInfo& aDriveInfo ) const
    {
    return aDriveInfo.iMediaAtt&( KMediaAttHasPassword );
    }


// ---------------------------------------------------------------------------
// CRemoteLock::IsMemoryCardPresent
// Check MemoryCard whether it is mounted into the phone and it supports locking.
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::IsMemoryCardPresent( const TDriveInfo& aDriveInfo ) const
    {
    return aDriveInfo.iDriveAtt&( KDriveAttRemovable ) && 
        aDriveInfo.iMediaAtt&( KMediaAttLockable );
    }


// ---------------------------------------------------------------------------
// CRemoteLock::SetMemoryCardPasswdL
// Sets/remove the password to MemoryCard.
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::SetMemoryCardPasswdL( const TBool aClear )
    {
    RL_TRACE_PRINT(" [ rl.exe ] SetMemoryCardPasswdL() ");
    if ( aClear )
        {
        if ( iMemoryCardLockedByRL && iLockedByRL )
            {
            //remove the password
            if ( DoSetMemoryCardPasswdL( ETrue ) )
                {
                iMemoryCardLockedByRL = EFalse;
                RL_TRACE_PRINT(" [ rl.exe ] exit SetMemoryCardPasswdL() ");    
                return ETrue;   
                }
            else
                {
                //Only try to remove password once no matter success or not 
                iMemoryCardLockedByRL = EFalse; 
              }    
             
            }       
        }
    else
        {
        if ( iMemoryCardLockedByRL )
            {
            //the memory card is locked already by rlock, 
            //just return ETrue;
            return ETrue;
            }
        
        if ( !iRemoteLockCode || iRemoteLockCode->Length() == 0 )
            {
            return EFalse;
            }
        //Change the password
        if ( DoSetMemoryCardPasswdL( EFalse ) )
            {
            iMemoryCardLockedByRL = ETrue;
            RL_TRACE_PRINT(" [ rl.exe ] exit SetMemoryCardPasswdL() ");    
            return ETrue; 
            }
           
        }
    RL_TRACE_PRINT(" [ rl.exe ] exit SetMemoryCardPasswdL() ");    
    return EFalse;
    }   

// ---------------------------------------------------------------------------
// CRemoteLock::DoSetMemoryCardPasswdL
// Do Sets/remove the password to MemoryCard.
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::DoSetMemoryCardPasswdL( TBool aClear )
    {
    RL_TRACE_PRINT(" [ rl.exe ] DoSetMemoryCardPasswdL() ");
    RFs fsMemoryCard;
    TInt err = fsMemoryCard.Connect();
    if ( err != KErrNone )
        {
        RL_TRACE_PRINT(" [ rl.exe ] DoSetMemoryCardPasswdL() error");
        return EFalse;
        }
         
#ifdef RD_MULTIPLE_DRIVE 

   // Get the removeable user visible drives
   TDriveList driveList;
   TInt driveCount;
   
   //Get all removeable drive, both physically and logically
   User::LeaveIfError( DriveInfo::GetUserVisibleDrives(
       fsMemoryCard, driveList, driveCount, KDriveAttRemovable ) );   
   RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() driveCount = %d ", driveCount );
 
   //boolen to indicate at least one operation(clear/add password) 
   // in the loop is ok.
   TBool OperationSucceed = EFalse;
  
   RArray<TInt> arrayMemoryCardIndex;
  
   TInt max( driveList.Length() );
   
   for ( TInt i = 0; i < max; i++ )
       {
       if ( driveList[ i ] )
          {
          TUint status;	
          DriveInfo::GetDriveStatus( fsMemoryCard, i, status );	
          //To make sure the drive is physically removeable not logically removeable	
          if( status & DriveInfo::EDriveRemovable )	
              {
              //append all physical removable memory card index into this array	
              arrayMemoryCardIndex.Append(i); 
              RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() physically removable drive %d", i );
		          }
		      else
		          {
		          RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() logically removable drive %d", i );
		          }    
		      }    
       }
      
   //Lock/Unblock all physical removeable memory card
   for ( TInt i = 0; i < arrayMemoryCardIndex.Count(); i++ )
       {
       TDriveInfo driveInfoT;
       TInt driveIndex = arrayMemoryCardIndex[i];
       RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() driveIndex %d", driveIndex );	
       fsMemoryCard.Drive( driveInfoT, driveIndex );
    
       if ( IsMemoryCardPresent( driveInfoT ) ) 
          {
          	RL_TRACE_PRINT(" [ rl.exe ] Memory card is present");
          if ( aClear )
              {
              RL_TRACE_PRINT(" [ rl.exe ] DoSetMemoryCardPasswdL() Remove password");	
              if ( HasMemoryCardPassword( driveInfoT ) || IsMemoryCardLocked( driveInfoT ) ) 
                  { 
                  TMediaPassword memoryCardPassword; 
              
                  // Converts MemoryCardpassword
                  ConvertMemoryCardPassword( memoryCardPassword, ETrue  );
              
                  err = fsMemoryCard.ClearPassword( driveIndex, memoryCardPassword );
              
                  if ( err == KErrNone )
                      {
                  	  OperationSucceed = ETrue;
                      }
              
                  RL_TRACE_PRINT_NUM(" [ rl.exe ] exit DoSetMemoryCardPasswdL() password for index %d is cleaned", driveIndex);
                  //Go for next
                  }
              else
                  {
                  //Go for next
                  }      
               }
            else
               {
               RL_TRACE_PRINT(" [ rl.exe ] DoSetMemoryCardPasswdL() Set password");
               if ( !HasMemoryCardPassword( driveInfoT ) && !IsMemoryCardLocked( driveInfoT ) )
                   { 
                   TMediaPassword memoryCardPassword;
                
                   TMediaPassword nullMemoryCardPassword;
                
                   // Converts MemoryCardpassword
                   ConvertMemoryCardPassword( memoryCardPassword, EFalse );
                
                   // Locks MemoryCard drive
                   err = fsMemoryCard.LockDrive( driveIndex, nullMemoryCardPassword, memoryCardPassword, ETrue );        
                
                   if ( err == KErrNone )
                      {
                  	  OperationSucceed = ETrue;
                      }
                
                   RL_TRACE_PRINT_NUM(" [ rl.exe ] DoSetMemoryCardPasswdL() password for index %d is set", driveIndex);
                   
                   //Go for next
                   }
                else
                   {
                   //go for next
                   }   
               }
            } //if ( IsMemoryCardPresent( driveInfoT ) ) 
         } //for
    
     
     if ( aClear )
         {
     	   delete iMemoryCardPasswd; 
         iMemoryCardPasswd = NULL; 
         fsMemoryCard.Close(); 
         
         return OperationSucceed ? ETrue : EFalse;
         }
     else 
        {

        delete iMemoryCardPasswd;
        iMemoryCardPasswd = NULL; 
        iMemoryCardPasswd = iRemoteLockCode->AllocL();
        fsMemoryCard.Close();	
        
        return OperationSucceed ? ETrue : EFalse;
        }       
#else
    
    TInt i = 0;
    TParsePtrC folder( PathInfo::MemoryCardRootPath() );
    fsMemoryCard.CharToDrive( folder.Drive()[ 0 ], i );
      
    TDriveInfo driveInfoT;
    fsMemoryCard.Drive( driveInfoT, i );
    
    if ( IsMemoryCardPresent( driveInfoT ) ) 
      {
      if ( aClear )
          {
          if ( HasMemoryCardPassword( driveInfoT ) || IsMemoryCardLocked( driveInfoT ) ) 
              { 
              TMediaPassword memoryCardPassword; 
              // Converts MemoryCardpassword
              ConvertMemoryCardPassword( memoryCardPassword, ETrue  );
              err = fsMemoryCard.ClearPassword( i, memoryCardPassword );
              
              if( err == KErrNone )
                  {
                  delete iMemoryCardPasswd; 
                  iMemoryCardPasswd = NULL; 
                  }
              fsMemoryCard.Close(); 
              RL_TRACE_PRINT(" [ rl.exe ] exit DoSetMemoryCardPasswdL() clear");
              return ( err == KErrNone );
              }
          else
              {
              fsMemoryCard.Close();  
              return ETrue;
              }      
           }
        else
           {
           if ( !HasMemoryCardPassword( driveInfoT ) && !IsMemoryCardLocked( driveInfoT ) )
                { 
                TMediaPassword memoryCardPassword;
                TMediaPassword nullMemoryCardPassword;
                // Converts MemoryCardpassword
                ConvertMemoryCardPassword( memoryCardPassword, EFalse );
                // Locks MemoryCard drive
                err = fsMemoryCard.LockDrive( i, nullMemoryCardPassword, memoryCardPassword, ETrue );        
                if ( err == KErrNone )
                    {
                    if ( iMemoryCardPasswd )
                          {
                          delete iMemoryCardPasswd;
                          iMemoryCardPasswd = NULL; 
                          }
                     iMemoryCardPasswd = iRemoteLockCode->AllocL();
                     }
          
                fsMemoryCard.Close();
                RL_TRACE_PRINT(" [ rl.exe ] exit DoSetMemoryCardPasswdL() change");
                return ( err == KErrNone );  
                }
            else
                {
                fsMemoryCard.Close();  
                return EFalse;
                }   
            }
        }    
    fsMemoryCard.Close();
    return EFalse;  
    
#endif //RD_MULTIPLE_DRIVE       
    }

// ---------------------------------------------------------------------------
// CRemoteLock::ConvertMemoryCardPasswordL
// Converts MemoryCardPassword to acceptable format.
// ---------------------------------------------------------------------------
//
void CRemoteLock::ConvertMemoryCardPassword( TMediaPassword& aPassword, const TBool aClear ) 
    {
    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() ");
    
    TBuf16 < KMaxMediaPassword / 2 > memoryCardPassword; 
    // Takes left most 8 digits of lockcode as
    // the password of MemoryCard.
    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() 1");
    
    if ( aClear )
        {
        if ( iMemoryCardPasswd )
           {
           memoryCardPassword.Copy( iMemoryCardPasswd->Left( KRLockMaxMemoryCardPasswdLength ) );
           }
        }
     else
        {
        if ( iRemoteLockCode )
            {
            memoryCardPassword.Copy( iRemoteLockCode->Left( KRLockMaxMemoryCardPasswdLength ) );
            }
        } 
  
    // Fills the descriptor's data area with binary zeroes, i.e. 0x00, 
    // replacing any existing data.
    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() 2");
    aPassword.FillZ( KMaxMediaPassword ); 

    aPassword.Zero();
    // Sets the length of the data to zero.
    // Copies data into this descriptor replacing any existing data. 
    // The length of this descriptor is set to reflect the new data
    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() 3");
    aPassword.Copy( reinterpret_cast<TUint8 *>
        ( &memoryCardPassword[ 0 ] ), memoryCardPassword.Length() * 2 );
        
    RL_TRACE_PRINT(" [ rl.exe ] ConvertMemoryCardPassword() over ");    
    }
  
  
// ---------------------------------------------------------------------------
// CRemoteLock::InitialSendMessageL
// Reply SMS when the terminal is successfully locked.
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::InitialSendMessageL()
    {
    RL_TRACE_PRINT(" [ rl.exe ] InitialSendMessageL() ");
    
    RProperty property;
    
    TInt err = 0;
     
    #ifndef RD_STARTUP_CHANGE        
    err = property.Attach( KUidSystemCategory, KPSUidAutolockStatusValue );              
    #else
    err = property.Attach( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus );
    #endif
    
    if ( err != KErrNone )
        {
      return EFalse;
        }
    
    TInt state = 0;
    
    CleanupClosePushL( property );
    
    err = property.Get( state );
    if ( err != KErrNone )
        {
      CleanupStack::PopAndDestroy( 1 );
        return EFalse;
        }
         
    #ifndef RD_STARTUP_CHANGE
    if ( state  == EPSRemoteLocked )
    #else
    if ( state == ERemoteLocked )
    #endif // RD_STARTUP_CHANGE 
      {
      // message server entry id
      TMsvId msvId = NULL;
      // Set up a new message
      msvId = CreateNewMessageL();
      //Set the new message to be the current entry
      SetEntryL( msvId );
      CleanupStack::PopAndDestroy( 1 ); // property
      RL_TRACE_PRINT(" [ rl.exe ] exit InitialSendMessageL() ETrue "); 
      return ETrue; 
      }
    CleanupStack::PopAndDestroy( 1 ); // property   
    RL_TRACE_PRINT(" [ rl.exe ] exit InitialSendMessageL() "); 
    return EFalse;
    }


// ---------------------------------------------------------------------------
// CRemoteLock::CreateNewMessageL()
// Creates a new message server entry and set up default values.
// Return values:      TMsvId (the id of created entry)
// ---------------------------------------------------------------------------
//
TMsvId CRemoteLock::CreateNewMessageL()
    {
    RL_TRACE_PRINT(" [ rl.exe ] CreateNewMessageL() ");
    TMsvEntry newEntry;
    // The type of message is SMS
    newEntry.iMtm = KUidMsgTypeSMS;
    // The type of the entry: message
    newEntry.iType = KUidMsvMessageEntry;                    
    newEntry.iServiceId = KMsvLocalServiceIndexEntryId;
    // Set the date of the entry to home time
    newEntry.iDate.UniversalTime();                           
    newEntry.SetInPreparation( ETrue );                      

    CMsvEntry* entry = CMsvEntry::NewL( *iMsvSession, 
        KMsvDraftEntryIdValue, TMsvSelectionOrdering() );
    CleanupStack::PushL( entry );
    CMsvOperationWait* wait = CMsvOperationWait::NewLC();
    wait->Start();    

    // Asynchronously create a new entry.    
    CMsvOperation* oper = entry->CreateL( newEntry, wait->iStatus );
    CleanupStack::PushL( oper );

    CActiveScheduler::Start();

    // Keep track of the progress of the create operation.
    TMsvLocalOperationProgress progress = 
        McliUtils::GetLocalProgressL( *oper );
    User::LeaveIfError( progress.iError );

    // Set entry context to the created one
    // operation progress contains the ID of the created entry
    entry->SetEntryL( progress.iId ); 

    CleanupStack::PopAndDestroy( 3 );
    RL_TRACE_PRINT(" [ rl.exe ] CreateNewMessageL() end ");
    return progress.iId;
    }


// ---------------------------------------------------------------------------
// CRemoteLock::SetEntryL(TMsvId aEntryId)
// Set up current message entry.
// Note: It can be useful to remember the original entry id for 
//       error handling.
// ---------------------------------------------------------------------------
//
void CRemoteLock::SetEntryL( TMsvId aEntryId )
    {
    RL_TRACE_PRINT(" [ rl.exe ] SetEntryL() ");
    // Get the server entry from our session
    CMsvEntry* entry = iMsvSession->GetEntryL( aEntryId );
    CleanupStack::PushL( entry );
    delete iClientMtmForSending;
    iClientMtmForSending = NULL;
    
    TInt error;
    TInt i;
    for ( i = 0; i < 100; i++ )
        {
        TRAP( error, 
            iClientMtmForSending = iMtmReg->NewMtmL( entry->Entry().iMtm ) );
        if ( error == KErrNone )
            {
             RL_TRACE_PRINT(" [ rl.exe ] SetEntryL() iClientMtmForSending ");
            break;
            }
        } 

    User::LeaveIfError( error );
    iClientMtmForSending->SetCurrentEntryL( entry );

    CleanupStack::Pop( 1 ); // entry
    RL_TRACE_PRINT(" [ rl.exe ] exit SetEntryL() ");
    entry = NULL;
    }


// ---------------------------------------------------------------------------
// CRemoteLock::MoveMessageEntryL(TMsvId aTarget) const
// Moves an entry to another parent.
// Return values:      TMsvId of the moved message
// ---------------------------------------------------------------------------
//
TMsvId CRemoteLock::MoveMessageEntryL( TMsvId aTarget )
    {
    User::LeaveIfNull( iClientMtmForSending );
    TMsvEntry msvEntry( ( iClientMtmForSending->Entry() ).Entry() );
    TMsvId id = msvEntry.Id();

    if ( msvEntry.Parent() != aTarget )
        {
        TMsvSelectionOrdering sort;
        sort.SetShowInvisibleEntries( ETrue );    
        // Take a handle to the parent entry
        CMsvEntry* parentEntry = 
            CMsvEntry::NewL( 
            iClientMtmForSending->Session(), msvEntry.Parent(), sort );

        CleanupStack::PushL( parentEntry );
    
        // Move original from the parent to the new location
        CMsvOperationWait* wait = CMsvOperationWait::NewLC();
        wait->Start();
    
        CMsvOperation* op = 
                parentEntry->MoveL( msvEntry.Id(), aTarget, wait->iStatus );

        CleanupStack::PushL( op );
        CActiveScheduler::Start();     
        TMsvLocalOperationProgress prog=McliUtils::GetLocalProgressL( *op );
        User::LeaveIfError(prog.iError);
    
        id = prog.iId; 
        CleanupStack::PopAndDestroy( 3 ); // op, wait, parentEntry
        }
    return id;
    }


// ---------------------------------------------------------------------------
// CRemoteLock::SendMessageL
// Reply SMS when the terminal is successfully locked.
// Return values:      ETrue or EFalse
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::SendMessageL( const TDesC& aRecipientAddress )
    {
    RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() ");
    
    User::LeaveIfNull( iClientMtmForSending );
    
    RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() 1 ");
    
    TMsvEntry msvEntry = ( iClientMtmForSending->Entry() ).Entry();

    // We get the message body from Mtm and insert a bodytext
    CRichText& mtmBody = iClientMtmForSending->Body();
    mtmBody.Reset();
    
    TFileName fileName; 
    fileName = KRLockResourceFileName;

    // Use CStringResourceReader instead of StringLoader
    // StringLoader is meant for applications in app framework   
    CStringResourceReader* resourceReader = CStringResourceReader::NewLC( fileName );

    RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() 3");
    
    HBufC* retBuf = NULL;

    if ( iStateMemoryCard )
        {
        RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() memory card locked");
        // When memory card is locked.
        TPtrC buf;
        buf.Set( resourceReader->ReadResourceString(R_RLOC_TI_EVERYTHING_LOCKED) );
        retBuf = buf.AllocLC();
        }
    else
        {
        RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() only phone locked ");
        TPtrC buf;
        buf.Set( resourceReader->ReadResourceString(R_RLOC_TI_PHONE_LOCKED) );
        retBuf = buf.AllocLC();
        }
    mtmBody.InsertL( 0, *retBuf );
    msvEntry.iDescription.Set( *retBuf );
     
    // Set aRecipientAddress into the Details of the entry
    msvEntry.iDetails.Set( aRecipientAddress );  
    msvEntry.SetInPreparation( EFalse );         
    
    // Set the sending state (immediately)
    msvEntry.SetSendingState( KMsvSendStateWaiting );                         
    msvEntry.iDate.UniversalTime();   
    // To handle the sms specifics we start using SmsMtm
    CSmsClientMtm* smsMtm = STATIC_CAST( CSmsClientMtm*, 
                                         iClientMtmForSending );
    smsMtm->RestoreServiceAndSettingsL();

    // SMS MTM encapsulation of an SMS message.
    CSmsHeader& header = smsMtm->SmsHeader();
    CSmsSettings* sendOptions = CSmsSettings::NewL();
    CleanupStack::PushL( sendOptions );
    // Reset existing settings
    sendOptions->CopyL( smsMtm->ServiceSettings() ); 
    // Set unicode if needed
    if ( NeedsToBeSentAsUnicodeL( retBuf->Des() ))
        {
        sendOptions->SetCharacterSet( TSmsDataCodingScheme::ESmsAlphabetUCS2 );
        }
    // Set send options to be delivered immediately
    sendOptions->SetDelivery( ESmsDeliveryImmediately );      
    header.SetSmsSettingsL( *sendOptions );
    
    // let's check if there's sc address
    if (header.Message().ServiceCenterAddress().Length() == 0)
        {
        // no, there isn't. Use the default SC number. 
        CSmsSettings* serviceSettings = NULL;
        serviceSettings = &( smsMtm->ServiceSettings() );
        
        RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() Get SC number ");    
        if ( serviceSettings->ServiceCenterCount() )
            {
            //Set sc address to default.
            CSmsServiceCenter& sc = serviceSettings->GetServiceCenter(
                serviceSettings->DefaultServiceCenter() );
            header.Message().SetServiceCenterAddressL( sc.Address() );
            }
        }
    
    // Add recipient to the list.
    smsMtm->AddAddresseeL( aRecipientAddress, msvEntry.iDetails );

    CMsvEntry& entry = iClientMtmForSending->Entry();
    entry.ChangeL( msvEntry );                
    smsMtm->SaveMessageL();                 

    // Move message to outbox
    TMsvId movedId;
    TInt err;
    for ( TInt i = 0; i < 100; i++ )
        {
        TRAP( err, movedId = MoveMessageEntryL( 
                                 KMsvGlobalOutBoxIndexEntryId ));  
        if ( err == KErrNone )
            break;
        }
    RL_TRACE_PRINT(" [ rl.exe ] SendMessageL() put created message in outbox ");
    User::LeaveIfError( err );
    // We must create an entry selection for message copies 
    CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
    CleanupStack::PushL( selection );
    selection->AppendL( movedId );        
    // schedule the sending with the active scheduler
    SetScheduledSendingStateL( selection );   
    CleanupStack::PopAndDestroy( 4 ); // resourceReader,retbuf,sendOptions,selection 
    RL_TRACE_PRINT(" [ rl.exe ] Exit SendMessageL() ");
    return ETrue; 
    }


// ---------------------------------------------------------------------------
// CRemoteLock::SetScheduledSendingStateL
// Schedules the message to be sent through the etel server.
// Return values:      none
// ---------------------------------------------------------------------------
//
void CRemoteLock::SetScheduledSendingStateL( CMsvEntrySelection* aSelection )
    {
    User::LeaveIfNull( iClientMtmForSending );
    // Add entry to task scheduler
    TBuf8<1> dummyParams;
    CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
    waiter->Start();

    // invoking async schedule copy command on our mtm
    CMsvOperation* op= iClientMtmForSending->InvokeAsyncFunctionL(
            ESmsMtmCommandScheduleCopy,
            *aSelection,
            dummyParams,
            waiter->iStatus );

    CleanupStack::PushL( op );
    CActiveScheduler::Start();

    CleanupStack::PopAndDestroy( 2 ); // op, wait 
    }


// ---------------------------------------------------------------------------
// CRemoteLock::RunL
// Reconnect msg server after it is shut down
// Return values:      none
// ---------------------------------------------------------------------------
//
void CRemoteLock::RunL()
    {
    RL_TRACE_PRINT(" [ rl.exe ] RunL() ");
    delete iClientMtmForSending;
    iClientMtmForSending = NULL;
    delete iMtmReg;
    iMtmReg = NULL;
    delete iMsvSession;
    iMsvSession = NULL;

    TRAPD( error, iMsvSession = CMsvSession::OpenAsyncL( *this ) );

    if ( error != KErrNone )
        {
        After( KRLockTimerInterval );
        }
    RL_TRACE_PRINT(" [ rl.exe ] Exit RunL() ");    
    }


// ---------------------------------------------------------------------------
// CRemoteLock::NeedsToBeSentAsUnicodeL
// Check if needs to be sent as unicode
// Return value ETrue or EFalse
// ---------------------------------------------------------------------------
//
TBool CRemoteLock::NeedsToBeSentAsUnicodeL( const TDesC& aInputString ) const
    {
    TBool needsToBeSentAsUnicode = EFalse;
    CCnvCharacterSetConverter* const
        characterSetConverter = CCnvCharacterSetConverter::NewLC();
    
    RFs fsSession;
    TInt err = fsSession.Connect();
    User::LeaveIfError( err );
    CleanupClosePushL( fsSession ); 
    const TUint KSmsEdSmsStrictPluginID = 0x101F85CD;
    characterSetConverter->PrepareToConvertToOrFromL(
        KSmsEdSmsStrictPluginID,
        fsSession);

    characterSetConverter->SetDowngradeForExoticLineTerminatingCharacters(
        CCnvCharacterSetConverter::EDowngradeExoticLineTerminatingCharactersToJustLineFeed );
   
    for (TPtrC remainderOfInputString( aInputString ); remainderOfInputString.Length()>0 ; )
        {
        TBuf8<KBufLengthInUnicodeCheck> notUsed;
        TInt numberOfUnconvertibleCharacters = 0;
        const TInt returnValue = 
            characterSetConverter->ConvertFromUnicode( 
                notUsed,
                remainderOfInputString, 
                numberOfUnconvertibleCharacters );
        if (( returnValue < 0 ) || ( numberOfUnconvertibleCharacters > 0 )) 
            // if there was an error in trying to do the conversion, or if there was an
            // unconvertible character (e.g. a Chinese character)
            {
            needsToBeSentAsUnicode = ETrue;
            break;
            }
        
        remainderOfInputString.Set( remainderOfInputString.Right( returnValue ));
        }
    CleanupStack::PopAndDestroy( 2 );
    return needsToBeSentAsUnicode;
    }


// ---------------------------------------------------------------------------
// CRemoteLock::HandleUnlockEvent()
// Callback function for unlocking event observer
// ---------------------------------------------------------------------------
void CRemoteLock::HandleUnlockEvent()
    { 
    TRAPD( err, SetMemoryCardPasswdL( ETrue ) );
    err = err;
    iLockedByRL = EFalse;
    }   

// -----------------------------------------------------------------------------
// CRemoteLock::ProfileNotifyL
// Setup Profile notifier
// Returns:   ETrue if everything is OK
//            EFalse otherwise
// -----------------------------------------------------------------------------
//
TBool CRemoteLock::ProfileNotifyL( 
    const TBool aNotifyEnable ) 
    {
    RL_TRACE_PRINT(" [ rl.exe ] ProfileNotifyL() ");
    
    if ( !iProfileNotifyHandler )
        {
        RL_TRACE_PRINT(" [ rl.exe ] ProfileNotifyL() create notify handler");
        iProfileNotifyHandler = CCenRepNotifyHandler::NewL( *this, *iProfileSession ); 
        }
    
    if ( aNotifyEnable )
        {
        
        TInt err = iProfileSession->Get( KProEngActiveProfile, iCurrentProfile );
        User::LeaveIfError( err );
        RL_TRACE_PRINT(" [ rl.exe ] ProfileNotifyL() startlisten");
        iProfileNotifyHandler->StartListeningL();  
        }
    else
        {
        RL_TRACE_PRINT(" [ rl.exe ] ProfileNotifyL() stop listen ");
        iProfileNotifyHandler->StopListening();
        
        delete iProfileNotifyHandler;
        iProfileNotifyHandler = NULL;
        }
    RL_TRACE_PRINT(" [ rl.exe ] exit ProfileNotifyL() ");
    return ETrue;
    }
    
// -----------------------------------------------------------------------------
// CRemoteLock::GetProfile
// Get the current Profile
// Returns:   ETrue if everything is OK
//            EFalse otherwise
// -----------------------------------------------------------------------------
//
TBool CRemoteLock::GetProfile( TInt& aProfile )
    {
    RL_TRACE_PRINT(" [ rl.exe ] GetProfile() ");
    TInt err;
    err = iProfileSession->Get( KProEngActiveProfile, aProfile );
    RL_TRACE_PRINT(" [ rl.exe ] exit GetProfile() ");
    return ( err == KErrNone );
    }    


// -----------------------------------------------------------------------------
// CRemoteLock::HandleNotifyGeneric
// Remote lock Notify handler 
//
// -----------------------------------------------------------------------------
//
void CRemoteLock::HandleNotifyGeneric(
    TUint32 /*aId*/ ) 
    {
    RL_TRACE_PRINT(" [ rl.exe ] HandleNotifyGeneric() "); 
    
    TInt profile = 0; 
    GetProfile( profile ); 
    
    if ( ( profile == EProfileOffLineId ) && ( iIsEnabled  ) && ( iCurrentProfile != EProfileOffLineId )) 
        {
        ActivateDeviceLock();  
        }
        
    iCurrentProfile = profile;
    RL_TRACE_PRINT(" [ rl.exe ] exit HandleNotifyGeneric() ");
    }
    
//EOF