bluetoothengine/bteng/src/btengsrvsettingsmgr.cpp
changeset 15 00f9ee97d895
child 17 f05641c183ff
equal deleted inserted replaced
2:0b192a3a05a4 15:00f9ee97d895
       
     1 /*
       
     2 * Copyright (c) 2009-2010 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: Class to manage Bluetooth hardware and stack settings.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "btengsrvsettingsmgr.h"
       
    19 #include <bthci.h>
       
    20 #include <bt_subscribe_partner.h>
       
    21 #include <btnotif.h>
       
    22 #include <btengdomainpskeys.h>
       
    23 #include <centralrepository.h>
       
    24 #include <featmgr.h>
       
    25 #include <AknSmallIndicator.h>
       
    26 #include <avkon.hrh>
       
    27 
       
    28 #include "btengserver.h"
       
    29 #include "btengsrvpluginmgr.h"
       
    30 #include "btengsrvbbconnectionmgr.h"
       
    31 #include "btengsrvstate.h"
       
    32 #include "debug.h"
       
    33 
       
    34 #ifndef SETLOCALNAME
       
    35 #include <btengsettings.h>
       
    36 #endif
       
    37 
       
    38 /** ID of active object helper */
       
    39 const TInt KBTEngSettingsActive = 30;
       
    40 /** Constant for converting minutes to microseconds */
       
    41 //const TInt64 KMinutesInMicroSecs = 60000000;
       
    42 const TInt64 KMinutesInMicroSecs = MAKE_TINT64( 0, 60000000 );
       
    43 /**  Timeout for disabling Simple Pairing debug mode. The value is 30 minutes. */
       
    44 //const TInt KBTEngSspDebugModeTimeout = 1800000000;
       
    45 const TInt64 KBTEngSspDebugModeTimeout = MAKE_TINT64( 0, 1800000000 );
       
    46 /**  Timeout for turning BT off automatically. The value is 10.5 seconds. */
       
    47 const TInt KBTEngBtAutoOffTimeout = 10500000;
       
    48 /**  Default values for Major Service Class */
       
    49 const TUint16 KCoDDefaultServiceClass = EMajorServiceTelephony | EMajorServiceObjectTransfer | EMajorServiceNetworking;
       
    50 /**  Default values for Major Device Class */
       
    51 const TUint8 KCoDDefaultMajorDeviceClass = EMajorDevicePhone;
       
    52 /**  Default values for Minor Device Class */
       
    53 const TUint8 KCoDDefaultMinorDeviceClass = EMinorDevicePhoneSmartPhone;
       
    54 
       
    55 
       
    56 // ======== MEMBER FUNCTIONS ========
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // C++ default constructor
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 CBTEngSrvSettingsMgr::CBTEngSrvSettingsMgr( CBTEngServer* aServer )
       
    63 :   iServer( aServer )
       
    64     {
       
    65     }
       
    66 
       
    67 
       
    68 // ---------------------------------------------------------------------------
       
    69 // Symbian second-phase constructor
       
    70 // ---------------------------------------------------------------------------
       
    71 //
       
    72 void CBTEngSrvSettingsMgr::ConstructL()
       
    73     {
       
    74     TRACE_FUNC_ENTRY
       
    75     iActive = CBTEngActive::NewL( *this, KBTEngSettingsActive );
       
    76     LoadBTPowerManagerL();
       
    77     iEnterpriseEnablementMode = BluetoothFeatures::EnterpriseEnablementL();
       
    78     TRACE_INFO( ( _L( "iEnterpriseEnablementMode = %d" ), iEnterpriseEnablementMode) )
       
    79     if ( iEnterpriseEnablementMode == BluetoothFeatures::EDisabled )
       
    80         {
       
    81         SetVisibilityModeL( EBTVisibilityModeNoScans, 0 );
       
    82         }
       
    83     TRACE_FUNC_EXIT
       
    84     }
       
    85 
       
    86 
       
    87 // ---------------------------------------------------------------------------
       
    88 // NewL
       
    89 // ---------------------------------------------------------------------------
       
    90 //
       
    91 CBTEngSrvSettingsMgr* CBTEngSrvSettingsMgr::NewL( CBTEngServer* aServer )
       
    92     {
       
    93     CBTEngSrvSettingsMgr* self = new( ELeave ) CBTEngSrvSettingsMgr( aServer );
       
    94     CleanupStack::PushL( self );
       
    95     self->ConstructL();
       
    96     CleanupStack::Pop( self );
       
    97     return self;
       
    98     }
       
    99 
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // Destructor
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 CBTEngSrvSettingsMgr::~CBTEngSrvSettingsMgr()
       
   106     {
       
   107     if( iActive && iActive->IsActive() )
       
   108         {
       
   109         // Cancel the outstanding request.
       
   110         iPowerMgr.Cancel();
       
   111         }
       
   112     delete iActive;  
       
   113     iPowerMgr.Close();
       
   114     }
       
   115 
       
   116 
       
   117 // ---------------------------------------------------------------------------
       
   118 // Power Bluetooth hardware on or off.
       
   119 // ---------------------------------------------------------------------------
       
   120 //
       
   121 TInt CBTEngSrvSettingsMgr::SetHwPowerState( TBTPowerState aState )
       
   122     {
       
   123     TRACE_FUNC_ENTRY
       
   124     TInt err = KErrNone;
       
   125 #ifndef __WINS__
       
   126     if( iActive->IsActive() )
       
   127         {
       
   128         // Cancel the outstanding request.
       
   129         iPowerMgr.Cancel();
       
   130         iActive->Cancel();
       
   131         }
       
   132     iPowerMgr.SetPower( aState, NULL, iActive->RequestStatus() );
       
   133     iActive->GoActive();
       
   134 #else   //__WINS__
       
   135     iPowerState = aState;
       
   136 #endif  //__WINS__
       
   137 
       
   138    if( !err && aState == EBTOn )
       
   139         {
       
   140         TInt dutMode = EBTDutOff;
       
   141         err = RProperty::Get( KPSUidBluetoothTestingMode, KBTDutEnabled, dutMode );
       
   142         if( !err && dutMode == EBTDutOn )
       
   143             {
       
   144             // Set the DUT mode key to OFF since DUT mode is disabled at this point
       
   145             err = RProperty::Set( KPSUidBluetoothTestingMode, KBTDutEnabled, EBTDutOff );
       
   146             }
       
   147         }
       
   148     if( err )
       
   149         {
       
   150         // Power off if an error occurred during power on sequence.
       
   151 #ifndef __WINS__
       
   152             // This cannot happen in emulator environment.
       
   153         iPowerMgr.Cancel();
       
   154         iActive->Cancel();
       
   155         iPowerMgr.SetPower( EBTOff, NULL, iActive->RequestStatus() );
       
   156         User::WaitForRequest( iActive->RequestStatus() );
       
   157         // Result will be communicated through the caller of this function (by leaving).
       
   158 #else   //__WINS__
       
   159         iPowerState = EBTOff;
       
   160 #endif  //__WINS__
       
   161         } 
       
   162     TRACE_FUNC_RES( ( _L( "result: %d" ), err ) )
       
   163     return err;
       
   164     }
       
   165 
       
   166 
       
   167 // ---------------------------------------------------------------------------
       
   168 // Turn BT on or off.
       
   169 // ---------------------------------------------------------------------------
       
   170 //
       
   171 void CBTEngSrvSettingsMgr::SetPowerStateL( TBTPowerState aState, TBool aTemporary )
       
   172     {
       
   173     TRACE_FUNC_ARG( ( _L( "%d (temporary=%d" ), aState, aTemporary ) )
       
   174     if ( aState == EBTOn && iEnterpriseEnablementMode == BluetoothFeatures::EDisabled )
       
   175         {
       
   176         TRACE_INFO( ( _L( "no we're not... Bluetooth is enterprise-IT-disabled" ) ) )
       
   177         User::Leave(KErrNotSupported);
       
   178         }
       
   179     TBool idle = ( iServer->StateMachine()->CurrentOperation() == CBTEngSrvState::ESrvOpIdle );
       
   180     TBTPowerState currentState = EBTOff;
       
   181     CheckTemporaryPowerStateL( currentState, aState, aTemporary );
       
   182 
       
   183     if ( ( currentState == aState || ( aTemporary && aState == EBTOff ) ) && idle )
       
   184         {
       
   185         // The requested power state is already active, ignore silently.
       
   186         // We don't return an error here, as there is no error situation.
       
   187         TRACE_INFO( ( _L( "SetPowerStateL: nothing to do" ) ) )
       
   188         if ( currentState == aState )
       
   189             {
       
   190             // Make sure that the CenRep key is in sync.
       
   191             // During boot-up, the pwoer is set from the CenRep key, so we could 
       
   192             // end up out-of-sync.
       
   193             TRACE_INFO( ( _L( "SetPowerStateL: currentState == aState" ) ) )
       
   194             UpdateCenRepPowerKeyL( aState );
       
   195             } 
       
   196         return;
       
   197         }
       
   198     if ( aState == EBTOn )
       
   199         {
       
   200         // Hardware power on is the first step.
       
   201         User::LeaveIfError( SetHwPowerState( aState ) );
       
   202         }
       
   203     else
       
   204         {
       
   205         //Prevent BT visibility in the situation when we turn OFF BT Engine 
       
   206         //but FM Radio is still alive
       
   207         SetVisibilityModeL( EBTVisibilityModeNoScans, 0 );
       
   208         // Hardware power off is the last step.
       
   209         // First disconnect all plug-ins.
       
   210         iServer->PluginManager()->DisconnectAllPlugins();
       
   211         }
       
   212     // We only signal that BT is on after everything has completed (through 
       
   213     // the CenRep power state key), so that all services are initialized.
       
   214     // We signal that BT is off immediately though, so that our clients will 
       
   215     // not try to use BT during power down.
       
   216     iServer->StateMachine()->StartStateMachineL( aState );
       
   217     TRACE_FUNC_EXIT
       
   218     }
       
   219 
       
   220 // ---------------------------------------------------------------------------
       
   221 // Turn BT on or off.
       
   222 // ---------------------------------------------------------------------------
       
   223 //
       
   224 void CBTEngSrvSettingsMgr::SetPowerStateL(const RMessage2 aMessage )
       
   225     {
       
   226     TRACE_FUNC_ENTRY
       
   227     __ASSERT_ALWAYS( aMessage.Function() == EBTEngSetPowerState, 
       
   228             PanicServer( EBTEngPanicExpectSetPowerOpcode ) );
       
   229     if ( !iMessage.IsNull() )
       
   230         {
       
   231         // A power management request from a client is outstanding.
       
   232         User::Leave( KErrAlreadyExists );
       
   233         }
       
   234  
       
   235     TBTPowerStateValue arg = (TBTPowerStateValue) aMessage.Int0();
       
   236     // TBTPowerState power state type is inverted from TBTPowerStateValue,
       
   237     // which is used by the client to pass the parameter...
       
   238     TBTPowerState reqedPowerState( EBTOff );
       
   239     if ( arg == EBTPowerOn )
       
   240         {
       
   241         reqedPowerState = EBTOn;
       
   242         }
       
   243     TBool tempPowerOn = (TBool) aMessage.Int1();
       
   244     
       
   245     SetPowerStateL( reqedPowerState, tempPowerOn );
       
   246     if ( iServer->StateMachine()->CurrentOperation() == CBTEngSrvState::ESrvOpIdle )
       
   247         {
       
   248         // The request is accepted but the state machine is not running. This means the
       
   249         // requested power state is already active. Request is done.
       
   250         aMessage.Complete( KErrNone );
       
   251         }
       
   252     else
       
   253         {
       
   254         iMessage = RMessage2( aMessage );
       
   255         }
       
   256     TRACE_FUNC_EXIT
       
   257     }
       
   258 
       
   259 // ---------------------------------------------------------------------------
       
   260 // Initialize Bluetooth stack settings.
       
   261 // ---------------------------------------------------------------------------
       
   262 //
       
   263 void CBTEngSrvSettingsMgr::InitBTStackL()
       
   264     {
       
   265     TRACE_FUNC_ENTRY
       
   266     iServer->BasebandConnectionManager()->Subscribe();
       
   267     TBTVisibilityMode visibility = EBTVisibilityModeHidden;
       
   268     CRepository* cenRep = CRepository::NewL( KCRUidBTEngPrivateSettings );
       
   269     TInt err = cenRep->Get( KBTDiscoverable, (TInt&) visibility );
       
   270     delete cenRep;
       
   271     if (iRestoreVisibility == EFalse)
       
   272         {
       
   273         if( err || visibility == EBTVisibilityModeTemporary &&
       
   274             !( iServer->IsTimerQueued( CBTEngServer::EScanModeTimer ) ) )
       
   275             {
       
   276             visibility = EBTVisibilityModeHidden;
       
   277             }
       
   278         SetVisibilityModeL( visibility, 0 );
       
   279         }
       
   280 
       
   281     TBool sspDebugMode = EFalse;
       
   282     (void) RProperty::Get( KPropertyUidBluetoothCategory,
       
   283                 KPropertyKeyBluetoothGetSimplePairingDebugMode, (TInt&) sspDebugMode );
       
   284         // Only set debug mode to off if it is on, to prevent a loop notifications.
       
   285     if( sspDebugMode )
       
   286         {
       
   287         sspDebugMode = EFalse;
       
   288         // Add LeaveIfError if unsuccessful
       
   289         (void) RProperty::Set(KPropertyUidBluetoothCategory,
       
   290                     KPropertyKeyBluetoothSetSimplePairingDebugMode, (TInt) sspDebugMode );
       
   291         }
       
   292     TRACE_FUNC_EXIT
       
   293     }
       
   294 
       
   295 
       
   296 // ---------------------------------------------------------------------------
       
   297 // Reset settings and disconnect all links.
       
   298 // ---------------------------------------------------------------------------
       
   299 //
       
   300 void CBTEngSrvSettingsMgr::StopBTStackL()
       
   301     {
       
   302     TRACE_FUNC_ENTRY
       
   303     TBTVisibilityMode visibility = EBTVisibilityModeHidden;
       
   304     CRepository* cenRep = CRepository::NewL( KCRUidBTEngPrivateSettings );
       
   305           // Ignore error here; if we can't read it, likely we can't set it either.
       
   306     (void) cenRep->Get( KBTDiscoverable, (TInt&) visibility );
       
   307     delete cenRep;
       
   308     if( visibility == EBTVisibilityModeTemporary )
       
   309         {
       
   310         visibility = EBTVisibilityModeHidden;
       
   311         SetVisibilityModeL( visibility, 0 );    // Also cancels scan mode timer.
       
   312         }
       
   313 
       
   314         // Stop listening to events
       
   315     iServer->BasebandConnectionManager()->Unsubscribe();
       
   316         // Disconnect all links
       
   317     TCallBack cb( CBTEngServer::DisconnectAllCallBack, iServer );
       
   318     iServer->BasebandConnectionManager()->DisconnectAllLinksL( cb );
       
   319         // Results in a callback (which is called directly when there are no links).
       
   320     TRACE_FUNC_EXIT
       
   321     }
       
   322 
       
   323 
       
   324 // ---------------------------------------------------------------------------
       
   325 // Update the power state CenRep key.
       
   326 // ---------------------------------------------------------------------------
       
   327 //
       
   328 void CBTEngSrvSettingsMgr::UpdateCenRepPowerKeyL( TBTPowerState aState )
       
   329     {
       
   330     TRACE_FUNC_ENTRY
       
   331     CRepository* cenrep = CRepository::NewLC( KCRUidBluetoothPowerState );
       
   332     // TBTPowerState power state type is inverted from TBTPowerStateValue...
       
   333     TBTPowerStateValue power = (TBTPowerStateValue) !aState;
       
   334     User::LeaveIfError( cenrep->Set( KBTPowerState, (TInt) power ) );
       
   335     CleanupStack::PopAndDestroy( cenrep );
       
   336     TRACE_FUNC_EXIT
       
   337     }
       
   338 
       
   339 
       
   340 // ---------------------------------------------------------------------------
       
   341 // ?implementation_description
       
   342 // ---------------------------------------------------------------------------
       
   343 //
       
   344 void CBTEngSrvSettingsMgr::SetVisibilityModeL( TBTVisibilityMode aMode, TInt aTime )
       
   345     {
       
   346     TRACE_FUNC_ARG( ( _L( "[aMode: %d" ), aMode ) )
       
   347     if ( aMode != EBTVisibilityModeNoScans && iEnterpriseEnablementMode == BluetoothFeatures::EDisabled )
       
   348         {
       
   349         TRACE_INFO( ( _L( "\tnot changing anything... Bluetooth is enterprise-IT-disabled" ) ) )
       
   350         User::Leave( KErrNotSupported );
       
   351         }
       
   352 
       
   353     TInt err = KErrNone;
       
   354     iServer->RemoveTimer( CBTEngServer::EScanModeTimer );
       
   355     if( aMode != EBTVisibilityModeNoScans )
       
   356         {
       
   357         CRepository* cenRep = CRepository::NewL( KCRUidBTEngPrivateSettings );
       
   358         err = cenRep->Set( KBTDiscoverable, aMode );
       
   359         delete cenRep;
       
   360         }
       
   361     if( !err && aMode == EBTVisibilityModeTemporary )
       
   362         {
       
   363             // We need TInt64 here, as the max. time in microseconds for the 
       
   364             // max. value (1 hour) is larger than KMaxTInt32.
       
   365         TInt64 timeMicroSec = MAKE_TINT64( 0, aTime );
       
   366         timeMicroSec = timeMicroSec * KMinutesInMicroSecs;
       
   367             // Queue callback to set the visibility back to hidden.
       
   368         iServer->QueueTimer( CBTEngServer::EScanModeTimer, (TInt64) timeMicroSec );
       
   369         aMode = EBTVisibilityModeGeneral;
       
   370         }
       
   371     else if( !err && iRestoreVisibility )
       
   372         {
       
   373             // The user overrides, do not restore visibility mode anymore.
       
   374         iRestoreVisibility = EFalse;
       
   375         }
       
   376     if( !err )
       
   377         {
       
   378         err = RProperty::Set( KUidSystemCategory, 
       
   379                                KPropertyKeyBluetoothSetScanningStatus, aMode );
       
   380         }
       
   381     TBool hiddenMode = ( aMode == EBTVisibilityModeHidden );
       
   382     if( !err && aMode != EBTVisibilityModeNoScans )
       
   383         {
       
   384             // In hidden mode, we only accept connections from paired devices.
       
   385         err = RProperty::Set( KUidSystemCategory, 
       
   386                                KPropertyKeyBluetoothSetAcceptPairedOnlyMode, 
       
   387                                hiddenMode );
       
   388         }
       
   389 
       
   390     User::LeaveIfError( err );  // To communicate the result to the client.
       
   391     TRACE_FUNC_EXIT
       
   392     }
       
   393 
       
   394 
       
   395 // ---------------------------------------------------------------------------
       
   396 // Timed visible mode has expired.
       
   397 // ---------------------------------------------------------------------------
       
   398 //
       
   399 void CBTEngSrvSettingsMgr::ScanModeTimerCompletedL()
       
   400     {
       
   401     TRACE_FUNC_ENTRY
       
   402     SetVisibilityModeL( EBTVisibilityModeHidden, 0 );
       
   403     TBTPowerState power = EBTOff;
       
   404     TInt err = GetHwPowerState( power );
       
   405     // See p2.1.2.1.2 of the UI spec
       
   406     // NB:  Please distinguish between TBTPowerState::EBTOff (defined in hcitypes.h)
       
   407     //      and TBTPowerStateValue::EBTPowerOff (defined in btserversdkcrkeys.h)
       
   408     //      because they have the opposite values
       
   409     if( !err && (power != EBTOff))
       
   410         {
       
   411         // Show a notification to the user
       
   412         TBTGenericInfoNotiferParamsPckg pckg;
       
   413         pckg().iMessageType = EBTVisibilityTimeout;
       
   414         
       
   415         RNotifier notifier;
       
   416         TInt err = notifier.Connect();
       
   417         if( !err )
       
   418             {
       
   419             err = notifier.StartNotifier( KBTGenericInfoNotifierUid, pckg );
       
   420             notifier.Close();
       
   421             }
       
   422         }
       
   423     TRACE_FUNC_RES( ( _L( "result: %d" ), err ) )
       
   424     }
       
   425 
       
   426 
       
   427 // ---------------------------------------------------------------------------
       
   428 // Check the secure simple pairing debug mode and turn it off if needed.
       
   429 // ---------------------------------------------------------------------------
       
   430 //
       
   431 void CBTEngSrvSettingsMgr::CheckSspDebugModeL( TBool aDebugMode )
       
   432     {
       
   433     TRACE_FUNC_ARG( ( _L( "SSP debug mode state %d" ), (TInt) aDebugMode ) )
       
   434     TBTPowerState pwr = EBTOff;
       
   435     TBool currentMode = EFalse;
       
   436     TInt err = RProperty::Get( KPropertyUidBluetoothCategory, 
       
   437                                 KPropertyKeyBluetoothGetSimplePairingDebugMode, 
       
   438                                 (TInt&) currentMode );
       
   439 #ifndef __WINS__
       
   440     err = iPowerMgr.GetPower( pwr, NULL ); // Treat error as power off.
       
   441 #else   //__WINS__
       
   442     pwr = iPowerState;
       
   443 #endif  //__WINS__
       
   444     if( err || pwr == EBTOff )
       
   445         {
       
   446         iServer->RemoveTimer( CBTEngServer::ESspDebugModeTimer );
       
   447             // Only set debug mode to off if it is on, to prevent a loop notifications.
       
   448         if( currentMode )
       
   449             {
       
   450             (void) RProperty::Set( KPropertyUidBluetoothCategory, 
       
   451                                     KPropertyKeyBluetoothSetSimplePairingDebugMode,
       
   452                                     (TInt) aDebugMode );
       
   453             }
       
   454             // In case of an error in getting the power state, turn BT off. 
       
   455             // If BT is already off, this call will be ignored.
       
   456         SetPowerStateL( EBTOff, EFalse );
       
   457         }
       
   458     else if( aDebugMode )
       
   459         {
       
   460             // Ignore if there already is a timer queued.
       
   461         if( !( iServer->IsTimerQueued( CBTEngServer::ESspDebugModeTimer ) ) )
       
   462             {
       
   463             iServer->QueueTimer( CBTEngServer::ESspDebugModeTimer, (TInt64) KBTEngSspDebugModeTimeout );
       
   464             err =  RProperty::Set(KPropertyUidBluetoothCategory, 
       
   465                                    KPropertyKeyBluetoothSetSimplePairingDebugMode, 
       
   466                                    (TInt) aDebugMode );
       
   467             }
       
   468         }
       
   469     else
       
   470         {
       
   471             // Power is on, and debug mode is set to off.
       
   472         TInt linkCount = 0;
       
   473         err = RProperty::Get( KPropertyUidBluetoothCategory, 
       
   474                                KPropertyKeyBluetoothGetPHYCount, linkCount );
       
   475         if( err || !linkCount )
       
   476             {
       
   477             (void) RProperty::Set(KPropertyUidBluetoothCategory, 
       
   478                                    KPropertyKeyBluetoothSetSimplePairingDebugMode,
       
   479                                    (TInt) aDebugMode );
       
   480             SetPowerStateL( EBTOff, EFalse );
       
   481             }
       
   482         else
       
   483             {
       
   484             // There are still existing connections, queue the
       
   485             // timer again for half the period.
       
   486             TInt64 interval = KBTEngSspDebugModeTimeout / 2;
       
   487             iServer->QueueTimer( CBTEngServer::ESspDebugModeTimer, interval );
       
   488             }
       
   489         }
       
   490     TRACE_FUNC_EXIT
       
   491     }
       
   492 
       
   493 // ---------------------------------------------------------------------------
       
   494 // A session will be ended, completes the pending request for this session.
       
   495 // ---------------------------------------------------------------------------
       
   496 //
       
   497 void CBTEngSrvSettingsMgr::SessionClosed( CSession2* aSession )
       
   498     {
       
   499     TRACE_FUNC_ARG( ( _L( " session %x"), aSession ) )
       
   500     if ( !iMessage.IsNull() && iMessage.Session() == aSession )
       
   501         {
       
   502         iMessage.Complete( KErrCancel );
       
   503         }
       
   504     TRACE_FUNC_EXIT
       
   505     }
       
   506 
       
   507 // ---------------------------------------------------------------------------
       
   508 // Check the power state and if BT gets turned off automatically.
       
   509 // This method is invoked either when the timer has expired, or
       
   510 // if there are no more connections while the timer was running.
       
   511 // ---------------------------------------------------------------------------
       
   512 //
       
   513 void CBTEngSrvSettingsMgr::CheckAutoPowerOffL()
       
   514     {
       
   515     TRACE_FUNC_ENTRY
       
   516     if ( iAutoOffClients > 0 )
       
   517         {
       
   518         TRACE_INFO( ( _L( "[CBTEngServer]\t iAutoOffClients %d"), iAutoOffClients ) )
       
   519         return;
       
   520         }
       
   521     TInt linkCount = 0;
       
   522     TInt err = RProperty::Get( KPropertyUidBluetoothCategory, 
       
   523                                 KPropertyKeyBluetoothGetPHYCount, linkCount );
       
   524     if( !err && !linkCount )
       
   525         {
       
   526         TRACE_INFO( ( _L( "[CBTEngServer]\t SetPowerStateL( EBTOff, EFalse );")))
       
   527         SetPowerStateL( EBTOff, EFalse );
       
   528         }
       
   529     else
       
   530         {
       
   531         if( iRestoreVisibility )
       
   532             {
       
   533                 // Set visibility mode back to the value selected by the user.
       
   534             SetVisibilityModeL( EBTVisibilityModeGeneral, 0 );
       
   535             iRestoreVisibility = EFalse;
       
   536             }
       
   537             // show note if non-audio connection exists
       
   538         if ( !iServer->PluginManager()->CheckAudioConnectionsL() )
       
   539             {
       
   540             RNotifier notifier;
       
   541             TInt err = notifier.Connect();
       
   542             if( !err )
       
   543                 {
       
   544                 TRequestStatus status;
       
   545                 TBTGenericInfoNotiferParamsPckg pckg;
       
   546                 pckg().iMessageType = EBTStayPowerOn;
       
   547                 TBuf8<sizeof(TInt)> result;
       
   548                 //notifier.StartNotifier( KBTGenericInfoNotifierUid, pckg, result );
       
   549                 notifier.StartNotifierAndGetResponse( status, 
       
   550                                                   KBTGenericInfoNotifierUid, 
       
   551                                                   pckg, result );   // Reply buffer not used.
       
   552                 User::WaitForRequest( status );
       
   553                 notifier.Close();
       
   554                 }
       
   555             }
       
   556         iAutoOffClients = 0;
       
   557         iAutoSwitchOff = EFalse;
       
   558         TCallBack cb;
       
   559         iServer->BasebandConnectionManager()->SetAutoSwitchOff( EFalse, cb );
       
   560         }
       
   561     TRACE_FUNC_EXIT 
       
   562     }
       
   563 
       
   564 
       
   565 // ---------------------------------------------------------------------------
       
   566 // The method is called when BT stack scanning mode P&S key is changed
       
   567 // ---------------------------------------------------------------------------
       
   568 //
       
   569 void CBTEngSrvSettingsMgr::UpdateVisibilityModeL( TInt aStackScanMode )
       
   570     {
       
   571     TRACE_FUNC_ARG( ( _L( "[aStackScanMode: %d" ), aStackScanMode ) )
       
   572     TBTVisibilityMode currentMode;
       
   573 
       
   574     CRepository* cenRep = CRepository::NewLC( KCRUidBTEngPrivateSettings );
       
   575     User::LeaveIfError( cenRep->Get( KBTDiscoverable, (TInt&) currentMode ) );
       
   576 
       
   577         // In case we are in temp visibility mode, we cannot always know whether the BT stack
       
   578         // scan mode key was set by some external party or by us in SetVisibilityModeL above.
       
   579         // Therefore we cannot stop the timer in case aMode is EBTVisibilityModeGeneral and 
       
   580         // currentmode is EBTVisibilityModeTemporary
       
   581     if( !( currentMode == EBTVisibilityModeTemporary && aStackScanMode == EBTVisibilityModeGeneral ) )
       
   582         {
       
   583             // Cancel the timer and queue it again if needed.
       
   584         iServer->RemoveTimer( CBTEngServer::EScanModeTimer );
       
   585         if( currentMode != aStackScanMode )
       
   586             {
       
   587             if( aStackScanMode == EPageScanOnly || aStackScanMode == EInquiryAndPageScan )
       
   588                 {
       
   589                 User::LeaveIfError( cenRep->Set( KBTDiscoverable, aStackScanMode ) );
       
   590                 }
       
   591             else if( aStackScanMode == EInquiryScanOnly )
       
   592                 {
       
   593                     // We don't support ENoScansEnabled nor EInquiryScanOnly mode
       
   594                     // -> Consider these as same as Hidden 
       
   595                 User::LeaveIfError( cenRep->Set( KBTDiscoverable, EBTVisibilityModeHidden ) );
       
   596                 }
       
   597             else if( aStackScanMode == ENoScansEnabled )
       
   598                 {
       
   599                 //We don't change KBTDiscoverable here, because ENoScansEnabled
       
   600                 //indicates BT/SYSTEM shutdown is happening
       
   601                 }
       
   602             }
       
   603         }
       
   604     SetUiIndicatorsL();
       
   605     CleanupStack::PopAndDestroy( cenRep );
       
   606     TRACE_FUNC_EXIT
       
   607     }
       
   608 
       
   609 
       
   610 // ---------------------------------------------------------------------------
       
   611 // Set Device Under Test mode.
       
   612 // ---------------------------------------------------------------------------
       
   613 //
       
   614 void CBTEngSrvSettingsMgr::SetDutMode( TInt aDutMode )
       
   615     {
       
   616     TRACE_FUNC_ARG( ( _L( "DUT mode %d" ), aDutMode ) )
       
   617 
       
   618     if (aDutMode == EBTDutOff)
       
   619         {
       
   620         return;
       
   621         }
       
   622 
       
   623     TInt powerState = EBTOff;
       
   624     CRepository* cenrep = NULL;
       
   625     
       
   626     TRAPD(err, cenrep = CRepository::NewL(KCRUidBluetoothPowerState));
       
   627     
       
   628     if (!err && cenrep)
       
   629         {
       
   630         cenrep->Get(KBTPowerState, powerState);
       
   631         delete cenrep;
       
   632         cenrep = NULL;
       
   633         }
       
   634     else
       
   635         {
       
   636         return;
       
   637         }
       
   638 
       
   639     if (powerState == EBTPowerOn)
       
   640         {
       
   641 
       
   642 #ifndef __WINS__
       
   643         RBluetoothDutMode dutMode;
       
   644         TInt err = dutMode.Open();
       
   645         TRACE_FUNC_ARG( ( _L( "Open DUT mode handle err %d" ), err) )
       
   646         if(!err) 
       
   647             {
       
   648             dutMode.ActivateDutMode();
       
   649             dutMode.Close();
       
   650             }
       
   651 #endif  //__WINS__                        
       
   652         }
       
   653     }
       
   654 
       
   655 
       
   656 // ---------------------------------------------------------------------------
       
   657 // From class MBTEngActiveObserver.
       
   658 // Callback to notify that an outstanding request has completed.
       
   659 // ---------------------------------------------------------------------------
       
   660 //
       
   661 void CBTEngSrvSettingsMgr::RequestCompletedL( CBTEngActive* aActive, TInt aId, TInt aStatus )
       
   662     {
       
   663     __ASSERT_ALWAYS( aId == KBTEngSettingsActive, PanicServer( EBTEngPanicCorrupt ) );
       
   664     TRACE_FUNC_ENTRY
       
   665     (void) aActive;
       
   666     if ( aStatus != KErrNone && aStatus != KErrAlreadyExists && aStatus != KErrCancel )
       
   667         {
       
   668         // Something went wrong, so we turn BT off again.
       
   669         SetPowerStateL( EBTOff, EFalse );
       
   670         }
       
   671     else
       
   672         {
       
   673         // Write CoD only when the hardware has fully powered up.
       
   674         TBTPowerState currState ( EBTOff );
       
   675         (void) GetHwPowerState( currState );
       
   676         if ( currState == EBTOn )
       
   677             {
       
   678             SetClassOfDeviceL();
       
   679 #ifndef SETLOCALNAME 
       
   680             // the macro SETLOCALNAME is used as a workaround to tackle the BT name 
       
   681             // could not be saved to BT chip before chip initialization completed for the first time,
       
   682             // which is one of the regression after improving the BT boot up time. 
       
   683             // To be removed once the final solution is in place. 
       
   684             CBTEngSettings* settings = CBTEngSettings::NewL();
       
   685             TBTDeviceName localName;           
       
   686             localName.Zero();
       
   687             TInt err = settings->GetLocalName(localName);
       
   688             if (err == KErrNone)
       
   689                 {
       
   690                 settings->SetLocalName(localName);
       
   691                 }
       
   692             delete settings;
       
   693 #endif
       
   694             }
       
   695         }
       
   696     if ( !iMessage.IsNull())
       
   697         {
       
   698         iMessage.Complete( aStatus );
       
   699         }
       
   700     TRACE_FUNC_EXIT
       
   701     }
       
   702 
       
   703 
       
   704 // ---------------------------------------------------------------------------
       
   705 // From class MBTEngActiveObserver.
       
   706 // Callback to notify that an error has occurred in RunL.
       
   707 // ---------------------------------------------------------------------------
       
   708 //
       
   709 void CBTEngSrvSettingsMgr::HandleError( CBTEngActive* aActive, TInt aId, TInt aError )
       
   710     {
       
   711     (void) aActive;
       
   712     (void) aId;
       
   713     if ( !iMessage.IsNull())
       
   714         {
       
   715         iMessage.Complete( aError );
       
   716         }
       
   717     }
       
   718 
       
   719 
       
   720 // ---------------------------------------------------------------------------
       
   721 // Loads the BT Power Manager; leaves if it cannot be loaded.
       
   722 // ---------------------------------------------------------------------------
       
   723 //
       
   724 void CBTEngSrvSettingsMgr::LoadBTPowerManagerL()
       
   725     {
       
   726     TRACE_FUNC_ENTRY
       
   727     TRACE_INFO( ( _L( "[CBTEngSrvSettingsMgr]\t Using HCI API v2 power manager" ) ) )
       
   728     User::LeaveIfError( iPowerMgr.Open() );
       
   729 #ifndef __WINS__
       
   730     iPowerMgr.SetPower( EBTOff, NULL, iActive->RequestStatus() );
       
   731     User::WaitForRequest( iActive->RequestStatus() );
       
   732     TInt status = ( iActive->RequestStatus().Int() == KErrAlreadyExists ? KErrNone : iActive->RequestStatus().Int() ); 
       
   733     User::LeaveIfError( status );
       
   734 #else   //__WINS__
       
   735     iPowerState = EBTOff;
       
   736 #endif  //__WINS__
       
   737     TRACE_FUNC_EXIT
       
   738     }
       
   739 
       
   740 
       
   741 // ---------------------------------------------------------------------------
       
   742 // ?implementation_description
       
   743 // ---------------------------------------------------------------------------
       
   744 //
       
   745 void CBTEngSrvSettingsMgr::SetUiIndicatorsL()
       
   746     {
       
   747     TRACE_FUNC_ENTRY
       
   748     TBTPowerStateValue powerState = EBTPowerOff;
       
   749     TBTVisibilityMode visibilityMode = EBTVisibilityModeHidden;
       
   750     CRepository* cenrep = NULL;
       
   751     TInt phys = 0;
       
   752     TInt connecting = 0;
       
   753 
       
   754     cenrep = CRepository::NewLC( KCRUidBluetoothPowerState );
       
   755     User::LeaveIfError( cenrep->Get( KBTPowerState, (TInt&) powerState ) );
       
   756     CleanupStack::PopAndDestroy( cenrep );
       
   757     
       
   758     if( powerState == EBTPowerOff )
       
   759         {
       
   760         SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOff );
       
   761         SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateOff );
       
   762         SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOff );
       
   763         SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateOff );
       
   764         }
       
   765     else
       
   766         {
       
   767         // Power is on.
       
   768         RProperty::Get( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothPHYCount, phys );
       
   769         RProperty::Get( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothConnecting, connecting );
       
   770         
       
   771         cenrep = CRepository::NewLC( KCRUidBTEngPrivateSettings );
       
   772         User::LeaveIfError( cenrep->Get( KBTDiscoverable, (TInt&) visibilityMode ) );
       
   773         CleanupStack::PopAndDestroy( cenrep );
       
   774         
       
   775         if( visibilityMode == EBTVisibilityModeHidden )
       
   776             {
       
   777              if ( connecting ) // BT connecting and hidden
       
   778                 {
       
   779                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOff );
       
   780                 SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateAnimate );
       
   781                 }
       
   782             else if ( phys > 0 ) // BT connection active and hidden     
       
   783                 {
       
   784                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOff );
       
   785                 SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateOn );
       
   786                 }
       
   787             else  // BT connection not active and hidden
       
   788                 {
       
   789                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOn );
       
   790                 SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateOff );
       
   791                 }
       
   792             SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOff );
       
   793             SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateOff );
       
   794             }           
       
   795         else if( visibilityMode == EBTVisibilityModeGeneral || visibilityMode == EBTVisibilityModeTemporary )
       
   796             {     
       
   797             if ( connecting ) // BT connecting and visible
       
   798                 {
       
   799                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOff );
       
   800                 SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateAnimate );
       
   801                 }
       
   802             else if ( phys > 0 ) // BT connection active and visible 
       
   803                 {
       
   804                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOff );
       
   805                 SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateOn );
       
   806                 }
       
   807             else  // BT connection not active and visible
       
   808                 {
       
   809                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOn );
       
   810                 SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateOff );
       
   811                 }
       
   812             SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOff );
       
   813             SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateOff );
       
   814             }
       
   815         }
       
   816     TRACE_FUNC_EXIT
       
   817     }
       
   818 
       
   819 
       
   820 // ---------------------------------------------------------------------------
       
   821 // ?implementation_description
       
   822 // ---------------------------------------------------------------------------
       
   823 //
       
   824 void CBTEngSrvSettingsMgr::SetIndicatorStateL( const TInt aIndicator, const TInt aState )
       
   825     {
       
   826     CAknSmallIndicator* indicator = CAknSmallIndicator::NewLC( TUid::Uid( aIndicator ) );
       
   827     indicator->SetIndicatorStateL( aState );
       
   828     CleanupStack::PopAndDestroy( indicator ); //indicator
       
   829     }
       
   830 
       
   831 
       
   832 // ---------------------------------------------------------------------------
       
   833 // Gets the current HW power state.
       
   834 // For now this is a separate method to isolate the different variations.
       
   835 // ---------------------------------------------------------------------------
       
   836 //
       
   837 TInt CBTEngSrvSettingsMgr::GetHwPowerState( TBTPowerState& aState )
       
   838     {
       
   839     TRACE_FUNC_ENTRY
       
   840     TInt err = KErrNone;
       
   841     
       
   842 #ifndef __WINS__
       
   843     err = iPowerMgr.GetPower( aState, NULL );
       
   844 #else   //__WINS__
       
   845     aState = iPowerState;
       
   846 #endif  //__WINS__
       
   847     TRACE_FUNC_ARG( ( _L( "Power state is %d, result %d" ), (TInt) aState, err ) )
       
   848     return err;
       
   849     }
       
   850 
       
   851 // ---------------------------------------------------------------------------
       
   852 // Check the power state and if BT gets turned off automatically.
       
   853 // ---------------------------------------------------------------------------
       
   854 //
       
   855 void CBTEngSrvSettingsMgr::CheckTemporaryPowerStateL( TBTPowerState& aCurrentState, 
       
   856     TBTPowerState aNewState, TBool aTemporary )
       
   857     {
       
   858     TRACE_FUNC_ENTRY
       
   859     User::LeaveIfError( GetHwPowerState( aCurrentState ) );
       
   860     if( !aTemporary )
       
   861         {
       
   862             // Force the new power state, so clear all auto switch off flags.
       
   863             // If power is off, this will anyway be ignored.
       
   864         iAutoOffClients = 0;
       
   865         iAutoSwitchOff = EFalse;
       
   866         TCallBack cb;
       
   867         iServer->BasebandConnectionManager()->SetAutoSwitchOff( EFalse, cb );
       
   868         if( iRestoreVisibility && aCurrentState == EBTOn )
       
   869             {
       
   870                 // Set visibility mode back to the value selected by the user.
       
   871             SetVisibilityModeL( EBTVisibilityModeGeneral, 0 );
       
   872             iRestoreVisibility = EFalse;
       
   873             }
       
   874         }
       
   875     else
       
   876         {
       
   877         if( aCurrentState == aNewState )
       
   878             {
       
   879             if( iAutoSwitchOff && aNewState == EBTOn )
       
   880                 {
       
   881                 iAutoOffClients++;
       
   882                 iServer->RemoveTimer( CBTEngServer::EAutoPowerOffTimer );
       
   883                 }
       
   884             }
       
   885         else if( iAutoSwitchOff || aNewState == EBTOn )
       
   886             {
       
   887             aNewState == EBTOff ? iAutoOffClients-- : iAutoOffClients++;
       
   888             iAutoSwitchOff = ETrue;
       
   889             if( aNewState == EBTOff && iAutoOffClients <= 0 )
       
   890                 {
       
   891                 TCallBack powerOffCb( CBTEngServer::AutoPowerOffCallBack, iServer );
       
   892                 iServer->BasebandConnectionManager()->SetAutoSwitchOff( ETrue, powerOffCb );
       
   893                 TInt64 interval = KBTEngBtAutoOffTimeout;
       
   894                 iServer->QueueTimer( CBTEngServer::EAutoPowerOffTimer, interval );
       
   895                 }
       
   896             else if( aNewState == EBTOn )
       
   897                 {
       
   898                 CRepository* cenRep = CRepository::NewLC( KCRUidBTEngPrivateSettings );
       
   899                 TBTVisibilityMode visibility = EBTVisibilityModeGeneral;
       
   900                 TInt err = cenRep->Get( KBTDiscoverable, (TInt&) visibility );
       
   901                 CleanupStack::PopAndDestroy( cenRep );
       
   902                 if( !err && visibility == EBTVisibilityModeGeneral )
       
   903                     {
       
   904                     SetVisibilityModeL( EBTVisibilityModeHidden, 0 );
       
   905                     iRestoreVisibility = ETrue;
       
   906                    }
       
   907                 iServer->RemoveTimer( CBTEngServer::EAutoPowerOffTimer );
       
   908                 }
       
   909             }
       
   910         }
       
   911     if( iAutoOffClients < 0 )
       
   912         {
       
   913         iAutoOffClients = 0;
       
   914         }
       
   915     TRACE_FUNC_EXIT 
       
   916     }
       
   917 
       
   918 
       
   919 // ---------------------------------------------------------------------------
       
   920 // Set the Class of Device.
       
   921 // ---------------------------------------------------------------------------
       
   922 //
       
   923 void CBTEngSrvSettingsMgr::SetClassOfDeviceL()
       
   924     {
       
   925     TRACE_FUNC_ENTRY
       
   926     TUint16 serviceClass = KCoDDefaultServiceClass;
       
   927         // Check from feature manager if stereo audio is enabled.
       
   928     FeatureManager::InitializeLibL();
       
   929     TBool supported = FeatureManager::FeatureSupported( KFeatureIdBtStereoAudio );
       
   930     FeatureManager::UnInitializeLib();
       
   931     if( supported )
       
   932         {
       
   933         // A2DP spec says we should set this bit as we are a SRC
       
   934         serviceClass |= EMajorServiceCapturing;
       
   935         }
       
   936         // These values may nayway be overridden by HCI
       
   937     TBTDeviceClass cod( serviceClass, KCoDDefaultMajorDeviceClass, 
       
   938                          KCoDDefaultMinorDeviceClass );
       
   939         // Ignore error, it is non-critical
       
   940     (void) RProperty::Set( KPropertyUidBluetoothControlCategory, 
       
   941                             KPropertyKeyBluetoothSetDeviceClass, cod.DeviceClass() );
       
   942     TRACE_FUNC_EXIT
       
   943     }