bluetoothengine/bteng/src/btengserver.cpp
changeset 23 988cddd6adbd
parent 0 f63038272f30
child 13 b6f55cd40afd
equal deleted inserted replaced
22:4255033c5d30 23:988cddd6adbd
    14 * Description:  Server-side implementation of BTEng
    14 * Description:  Server-side implementation of BTEng
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 
    18 
    19 
       
    20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    21 #include <bthci.h>
       
    22 #include <bt_subscribe_partner.h>
       
    23 #endif
       
    24 
       
    25 #include <e32base.h>
    19 #include <e32base.h>
    26 #include <btmanclient.h>
    20 #include <btmanclient.h>
    27 #include <es_sock.h>
    21 #include <es_sock.h>
    28 #include <btnotif.h>
    22 #include <btnotif.h>
    29 #include <utf.h>
    23 #include <utf.h>
    30 #include <ecom/ecom.h>
    24 #include <ecom/ecom.h>
    31 #include <centralrepository.h>
    25 #include <centralrepository.h>
    32 #include <featmgr.h>
    26 #include <btengdomaincrkeys.h>
    33 #include <AknSmallIndicator.h>
       
    34 #include <avkon.hrh>
       
    35 #include <bt_subscribe.h>
    27 #include <bt_subscribe.h>
    36 #include "btengserver.h"
    28 #include "btengserver.h"
    37 #include "btengsrvstate.h"
    29 #include "btengsrvstate.h"
    38 #include "btengsrvsession.h"
    30 #include "btengsrvsession.h"
    39 #include "btengsrvpluginmgr.h"
    31 #include "btengsrvpluginmgr.h"
    40 #include "btengsrvbbconnectionmgr.h"
    32 #include "btengsrvbbconnectionmgr.h"
       
    33 #include "btengsrvsettingsmgr.h"
    41 #include "btengsrvkeywatcher.h"
    34 #include "btengsrvkeywatcher.h"
    42 #include "btengsdpdbhandler.h"
    35 #include "btengsdpdbhandler.h"
    43 #include "btengclientserver.h"
    36 #include "btengclientserver.h"
    44 #include "btengsecpolicy.h"
    37 #include "btengsecpolicy.h"
    45 #include "btengprivatecrkeys.h"
       
    46 #include "btengprivatepskeys.h"
    38 #include "btengprivatepskeys.h"
    47 #include "btengplugin.h"
    39 #include "btengplugin.h"
    48 #include "btengpairman.h"
    40 #include "btengpairman.h"
    49 #include "debug.h"
    41 #include "debug.h"
    50 
    42 
    51 /**  Bluetooth Engine server thread name */
    43 /**  Bluetooth Engine server thread name */
    52 _LIT( KBTEngThreadName, "BTEngine" );
    44 _LIT( KBTEngThreadName, "BTEngine" );
    53 
    45 /**  Timeout (3 sec) for shutting down the server (when power is off and no clients connected). */
    54 /**  Constant for converting minutes to microseconds */
       
    55 const TInt64 KMinutesInMicroSecs = MAKE_TINT64( 0, 60000000 );
       
    56 
       
    57 /**  Idle timeout for shutting down the server (when power is off, 
       
    58  *   and no clients are connected). The value is 3 seconds.
       
    59  */
       
    60 const TInt KBTEngSrvIdleTimeout = 3000000;
    46 const TInt KBTEngSrvIdleTimeout = 3000000;
    61 
       
    62 /**  Timeout for disabling Simple Pairing debug mode. The value is 30 minutes. */
       
    63 const TInt KBTEngSspDebugModeTimeout = 1800000000;
       
    64 
       
    65 /**  Timeout for determining that BT is not turned off automatically. 
       
    66  *   The value is 10.5 seconds.
       
    67  */
       
    68 const TInt KBTEngBtAutoOffTimeout = 10500000;
       
    69 
       
    70 /**  Enumeration of bitmask for keeping track of different timers. */
       
    71 enum TTimerQueued
       
    72     {
       
    73     ENone               = 0x00,
       
    74     EScanModeTimer      = 0x01,
       
    75     EIdleTimer          = 0x02,
       
    76     EAutoPowerOffTimer  = 0x04,
       
    77     ESspDebugModeTimer  = 0x08 
       
    78     };
       
    79 
       
    80 /**  PubSub key read and write policies */
    47 /**  PubSub key read and write policies */
    81 _LIT_SECURITY_POLICY_C2( KBTEngPSKeyReadPolicy, 
    48 _LIT_SECURITY_POLICY_C2( KBTEngPSKeyReadPolicy, ECapabilityLocalServices, ECapabilityReadDeviceData );
    82                           ECapabilityLocalServices, ECapabilityReadDeviceData );
    49 _LIT_SECURITY_POLICY_C2( KBTEngPSKeyWritePolicy, ECapabilityLocalServices, ECapabilityWriteDeviceData );
    83 _LIT_SECURITY_POLICY_C2( KBTEngPSKeyWritePolicy, 
    50 
    84                           ECapabilityLocalServices, ECapabilityWriteDeviceData );
       
    85 
       
    86 // Default values for Major and Minor Device Class
       
    87 const TUint16 KCoDDefaultServiceClass = EMajorServiceTelephony | EMajorServiceObjectTransfer | EMajorServiceNetworking;
       
    88 const TUint8 KCoDDefaultMajorDeviceClass = EMajorDevicePhone;
       
    89 const TUint8 KCoDDefaultMinorDeviceClass = EMinorDevicePhoneSmartPhone;
       
    90 
    51 
    91 // ======== LOCAL FUNCTIONS ========
    52 // ======== LOCAL FUNCTIONS ========
    92 
    53 
    93 // ---------------------------------------------------------------------------
    54 // ---------------------------------------------------------------------------
    94 // Constructs and returns an application object.
    55 // Constructs and returns an application object.
   147 // ---------------------------------------------------------------------------
   108 // ---------------------------------------------------------------------------
   148 //
   109 //
   149 CBTEngServer::CBTEngServer()
   110 CBTEngServer::CBTEngServer()
   150 :   CPolicyServer( EPriorityHigh, KBTEngServerPolicy )
   111 :   CPolicyServer( EPriorityHigh, KBTEngServerPolicy )
   151     {
   112     {
   152     iEnableDutMode = EFalse;
       
   153     }
   113     }
   154 
   114 
   155 
   115 
   156 // ---------------------------------------------------------------------------
   116 // ---------------------------------------------------------------------------
   157 // Symbian 2nd-phase constructor
   117 // Symbian 2nd-phase constructor
   188     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory,
   148     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory,
   189                                             KBTTurnBTOffQueryOn,
   149                                             KBTTurnBTOffQueryOn,
   190                                             RProperty::EInt,
   150                                             RProperty::EInt,
   191                                             KBTEngPSKeyReadPolicy,
   151                                             KBTEngPSKeyReadPolicy,
   192                                             KBTEngPSKeyWritePolicy) );
   152                                             KBTEngPSKeyWritePolicy) );
   193     
       
   194     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory,
   153     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory,
   195                                             KBTNotifierLocks,
   154                                             KBTNotifierLocks,
   196                                             RProperty::EByteArray,
   155                                             RProperty::EByteArray,
   197                                             KBTEngPSKeyReadPolicy,
   156                                             KBTEngPSKeyReadPolicy,
   198                                             KBTEngPSKeyWritePolicy) );    
   157                                             KBTEngPSKeyWritePolicy) );    
   199     
   158     
   200     User::LeaveIfError( iSocketServ.Connect() );
   159     User::LeaveIfError( iSocketServ.Connect() );
   201     LoadBTPowerManagerL();
   160 
   202         // The server is only started by its client, so leave the state 
   161         // The server is only started by its client, so leave the state 
   203         // machine in Init state. A request to turn power on will follow 
   162         // machine in Init state. A request to turn power on will follow 
   204         // usually immediately.
   163         // usually immediately.
   205     iServerState = CBTEngSrvState::NewL( this );
   164     iServerState = CBTEngSrvState::NewL( this );
   206     iWatcher = CBTEngSrvKeyWatcher::NewL( this );
   165     iWatcher = CBTEngSrvKeyWatcher::NewL( this );
       
   166     iSettingsMgr = CBTEngSrvSettingsMgr::NewL( this );
   207     iPluginMgr = CBTEngSrvPluginMgr::NewL( this );
   167     iPluginMgr = CBTEngSrvPluginMgr::NewL( this );
   208     iBBConnMgr = CBTEngSrvBBConnMgr::NewL( iSocketServ );
   168     iBBConnMgr = CBTEngSrvBBConnMgr::NewL( iSocketServ );
   209     
   169 
   210     User::LeaveIfError( iBTRegServ.Connect() );
   170     User::LeaveIfError( iBTRegServ.Connect() );
   211     iPairMan = CBTEngPairMan::NewL( *this );
   171     iPairMan = CBTEngPairMan::NewL( *this );
   212     
   172 
   213     TCallBack idleCb( IdleTimerCallBack, this );
   173     TCallBack idleCb( IdleTimerCallBack, this );
   214     iIdleCallBack.Set( idleCb );
   174     iIdleCallBack.Set( idleCb );
   215     TCallBack sspCb( DebugModeTimerCallBack, this );
   175     TCallBack sspCb( DebugModeTimerCallBack, this );
   216     iDebugModeCallBack.Set( sspCb );
   176     iDebugModeCallBack.Set( sspCb );
   217     TCallBack scanModeCb( ScanModeTimerCallBack, this );
   177     TCallBack scanModeCb( ScanModeTimerCallBack, this );
   218     iScanModeCallBack.Set( scanModeCb );
   178     iScanModeCallBack.Set( scanModeCb );
   219     TCallBack powerOffCb( AutoPowerOffCallBack, this );
   179     TCallBack powerOffCb( AutoPowerOffCallBack, this );
   220     iPowerOffCallBack.Set( powerOffCb );
   180     iPowerOffCallBack.Set( powerOffCb );
   221     iTimer = CDeltaTimer::NewL(CActive::EPriorityLow);
   181     iTimer = CDeltaTimer::NewL(CActive::EPriorityLow);
   222     
       
   223     iEnterpriseEnablementMode = BluetoothFeatures::EnterpriseEnablementL();
       
   224 	TRACE_INFO( ( _L( "iEnterpriseEnablementMode = %d" ), iEnterpriseEnablementMode) )
       
   225     if ( iEnterpriseEnablementMode == BluetoothFeatures::EDisabled )
       
   226         {
       
   227         SetVisibilityModeL( EBTVisibilityModeNoScans, 0 );
       
   228         }
       
   229     
       
   230     TRACE_FUNC_EXIT
   182     TRACE_FUNC_EXIT
   231     }
   183     }
   232 
   184 
   233 
   185 
   234 // ---------------------------------------------------------------------------
   186 // ---------------------------------------------------------------------------
   254     if( iTimer )
   206     if( iTimer )
   255         {
   207         {
   256         iTimerQueued = ENone;
   208         iTimerQueued = ENone;
   257         iTimer->Remove( iScanModeCallBack );
   209         iTimer->Remove( iScanModeCallBack );
   258         iTimer->Remove( iPowerOffCallBack );
   210         iTimer->Remove( iPowerOffCallBack );
   259         iTimer->Remove( iIdleCallBack);
   211         iTimer->Remove( iIdleCallBack );
   260         iTimer->Remove( iDebugModeCallBack );
   212         iTimer->Remove( iDebugModeCallBack );
   261         }
   213         }
   262     RProperty::Delete( KPSUidBluetoothTestingMode, KBTDutEnabled );
   214     RProperty::Delete( KPSUidBluetoothTestingMode, KBTDutEnabled );
   263     RProperty::Delete( KPSUidBluetoothTestingMode, KBTSspDebugmode );
   215     RProperty::Delete( KPSUidBluetoothTestingMode, KBTSspDebugmode );
   264     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTBlockDevAddr );
   216     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTBlockDevAddr );
   267     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTTurnBTOffQueryOn );
   219     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTTurnBTOffQueryOn );
   268     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTNotifierLocks );
   220     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTNotifierLocks );
   269     delete iTimer;
   221     delete iTimer;
   270     delete iSdpDbHandler;
   222     delete iSdpDbHandler;
   271     delete iWatcher;
   223     delete iWatcher;
       
   224     delete iSettingsMgr;
   272     delete iPluginMgr;
   225     delete iPluginMgr;
   273     delete iBBConnMgr;
   226     delete iBBConnMgr;
   274     delete iServerState;
   227     delete iServerState;
   275     delete iPairMan;
   228     delete iPairMan;
   276     iPowerMgr.Close();
       
   277     iSocketServ.Close();
   229     iSocketServ.Close();
   278     iBTRegServ.Close();
   230     iBTRegServ.Close();
   279     }
   231     }
   280 
   232 
   281 
       
   282 // ---------------------------------------------------------------------------
   233 // ---------------------------------------------------------------------------
   283 // Turn BT on or off.
   234 // Turn BT on or off.
   284 // ---------------------------------------------------------------------------
   235 // ---------------------------------------------------------------------------
   285 //
   236 //
   286 void CBTEngServer::SetPowerStateL( TBTPowerStateValue aState, TBool aTemporary )
   237 void CBTEngServer::SetPowerStateL( TBTPowerState aState, TBool aTemporary )
   287     {
   238     {
   288     TRACE_FUNC_ARG( ( _L( "setting power state %d" ), (TInt) aState ) )
   239     TRACE_FUNC_ARG( ( _L( "setting power state %d (temporary=%d" ), (TInt) aState, aTemporary ) )
   289     if ( aState == EBTPowerOn && iEnterpriseEnablementMode == BluetoothFeatures::EDisabled )
   240     iSettingsMgr->SetPowerStateL( aState, aTemporary );
   290         {
       
   291         TRACE_INFO( ( _L( "\tno we're not... Bluetooth is enterprise-IT-disabled" ) ) )
       
   292         User::Leave(KErrNotSupported);
       
   293         }
       
   294     
       
   295     TBTPowerStateValue currentState = EBTPowerOff;
       
   296     CheckTemporaryPowerStateL( currentState, aState, aTemporary );
       
   297 
       
   298     if( ( currentState == aState || ( aTemporary && aState == EBTPowerOff ) ) && iServerState->CurrentOperation() == CBTEngSrvState::ESrvOpIdle )
       
   299         {
       
   300 		// The requested power state is already active, ignore silently.
       
   301 		// We don't return an error here, as there is no error situation.
       
   302         TRACE_INFO( ( _L( "SetPowerStateL: nothing to do" ) ) )
       
   303         if(currentState == aState)
       
   304             {
       
   305             // Make sure that the CenRep key is in sync.
       
   306             // During boot-up, the pwoer is set from the CenRep key, so we could 
       
   307             // end up out-of-sync.
       
   308             TRACE_INFO( ( _L( "SetPowerStateL: currentState == aState" ) ) )
       
   309             UpdateCenRepPowerKeyL( aState );
       
   310             } 
       
   311         return;
       
   312         }
       
   313     if( aState )
       
   314         {
       
   315             // Hardware power on is the first step.
       
   316         User::LeaveIfError( SetPowerState( aState ) );
       
   317         }
       
   318     else
       
   319         {
       
   320         //Prevent BT visibility in the situation when we turn OFF BT Engine 
       
   321         //but FM Radio is still alive
       
   322         SetVisibilityModeL( EBTVisibilityModeNoScans, 0 );
       
   323             // Hardware power off is the last step.
       
   324             // First disconnect all plug-ins.
       
   325         iPluginMgr->DisconnectAllPlugins();
       
   326         }
       
   327         // We only signal that BT is on after everything has completed (through 
       
   328         // the CenRep power state key), so that all services are initialized.
       
   329         // We signal that BT is off immediately though, so that our clients will 
       
   330         // not try to use BT during power down.
       
   331     iServerState->StartStateMachineL( (TBool) aState );
       
   332     TRACE_FUNC_EXIT
   241     TRACE_FUNC_EXIT
   333     }
   242     }
   334 
   243 
   335 
   244 // ---------------------------------------------------------------------------
   336 // ---------------------------------------------------------------------------
   245 // Turn BT on or off.
   337 // ?implementation_description
   246 // ---------------------------------------------------------------------------
   338 // ---------------------------------------------------------------------------
   247 //
   339 //
   248 void CBTEngServer::SetPowerStateL(const RMessage2 aMessage )
   340 void CBTEngServer::SetVisibilityModeL( TBTVisibilityMode aMode, TInt aTime )
   249     {
   341     {
   250     TRACE_FUNC_ENTRY
   342     TRACE_FUNC_ENTRY
   251     iSettingsMgr->SetPowerStateL( aMessage );
   343     
       
   344     if ( aMode != EBTVisibilityModeNoScans && iEnterpriseEnablementMode == BluetoothFeatures::EDisabled )
       
   345         {
       
   346         TRACE_INFO( ( _L( "\tnot changing anything... Bluetooth is enterprise-IT-disabled" ) ) )
       
   347         User::Leave(KErrNotSupported);
       
   348         }
       
   349 
       
   350     TInt err = KErrNone;
       
   351     iTimerQueued &= ~EScanModeTimer;
       
   352     iTimer->Remove( iScanModeCallBack );
       
   353     if( aMode != EBTVisibilityModeNoScans )
       
   354         {
       
   355         CRepository* cenRep = CRepository::NewL( KCRUidBTEngPrivateSettings );
       
   356         err = cenRep->Set( KBTDiscoverable, aMode );
       
   357         delete cenRep;
       
   358         }
       
   359     if( !err && aMode == EBTVisibilityModeTemporary )
       
   360         {
       
   361             // We need TInt64 here, as the max. time in microseconds for the 
       
   362             // max. value (1 hour) is larger than KMaxTInt32.
       
   363         TInt64 timeMicroSec = MAKE_TINT64( 0, aTime );
       
   364         timeMicroSec = timeMicroSec * KMinutesInMicroSecs;
       
   365         TTimeIntervalMicroSeconds interval( timeMicroSec );
       
   366             // Queue callback to set the visibility back to hidden.
       
   367         err = iTimer->QueueLong( interval, iScanModeCallBack );
       
   368         iTimerQueued |= EScanModeTimer;
       
   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 // The method is called when BT stack scanning mode P&S key is changed
       
   396 // ---------------------------------------------------------------------------
       
   397 //
       
   398 void CBTEngServer::UpdateVisibilityModeL( TInt aStackScanMode )
       
   399     {
       
   400     TRACE_FUNC_ENTRY
       
   401     TRACE_INFO( ( _L( "[BTEng]\t aStackScanMode: %d" ), aStackScanMode ) )
       
   402     TBTVisibilityMode currentMode;
       
   403     
       
   404     CRepository* cenRep = CRepository::NewLC( KCRUidBTEngPrivateSettings );
       
   405     User::LeaveIfError( cenRep->Get( KBTDiscoverable, (TInt&) currentMode ) );
       
   406     
       
   407         // In case we are in temp visibility mode, we cannot always know whether the BT stack
       
   408         // scan mode key was set by some external party or by us in SetVisibilityModeL above.
       
   409         // Therefore we cannot stop the timer in case aMode is EBTVisibilityModeGeneral and 
       
   410         // currentmode is EBTVisibilityModeTemporary
       
   411     if( !( currentMode == EBTVisibilityModeTemporary && aStackScanMode == EBTVisibilityModeGeneral ) )
       
   412         {
       
   413             // Cancel the timer and queue it again if needed.
       
   414         iTimerQueued &= ~EScanModeTimer;
       
   415         iTimer->Remove( iScanModeCallBack );
       
   416         if( currentMode != aStackScanMode )
       
   417             {
       
   418             if( aStackScanMode == EPageScanOnly || aStackScanMode == EInquiryAndPageScan )
       
   419                 {
       
   420                 User::LeaveIfError( cenRep->Set( KBTDiscoverable, aStackScanMode ) );
       
   421                 }
       
   422             else if( aStackScanMode == EInquiryScanOnly )
       
   423                 {
       
   424                     // We don't support ENoScansEnabled nor EInquiryScanOnly mode
       
   425                     // -> Consider these as same as Hidden 
       
   426                 User::LeaveIfError( cenRep->Set( KBTDiscoverable, EBTVisibilityModeHidden ) );
       
   427                 }
       
   428             else if( aStackScanMode == ENoScansEnabled )
       
   429                 {
       
   430                 //We don't change KBTDiscoverable here, because ENoScansEnabled
       
   431                 //indicates BT/SYSTEM shutdown is happening
       
   432                 }
       
   433             }
       
   434         }
       
   435     SetUiIndicatorsL();
       
   436     CleanupStack::PopAndDestroy( cenRep );
       
   437     TRACE_FUNC_EXIT
   252     TRACE_FUNC_EXIT
   438     }
   253     }
   439 
   254 
   440 // ---------------------------------------------------------------------------
   255 // ---------------------------------------------------------------------------
   441 // ?implementation_description
   256 // ?implementation_description
   452 
   267 
   453 // ---------------------------------------------------------------------------
   268 // ---------------------------------------------------------------------------
   454 // ?implementation_description
   269 // ?implementation_description
   455 // ---------------------------------------------------------------------------
   270 // ---------------------------------------------------------------------------
   456 //
   271 //
   457 void CBTEngServer::SetDutMode( TInt aDutMode )
       
   458     {
       
   459     TRACE_FUNC_ARG( ( _L( "DUT mode %d" ), aDutMode ) )
       
   460 
       
   461     if (aDutMode == EBTDutOff)
       
   462         {
       
   463         return;
       
   464         }
       
   465 
       
   466     TInt powerState = EBTPowerOff;
       
   467     CRepository* cenrep = NULL;
       
   468     
       
   469     TRAPD(err, cenrep = CRepository::NewL(KCRUidBluetoothPowerState));
       
   470     
       
   471     if (!err && cenrep)
       
   472         {
       
   473         cenrep->Get(KBTPowerState, powerState);
       
   474         delete cenrep;
       
   475         cenrep = NULL;
       
   476         }
       
   477     else
       
   478         {
       
   479         return;
       
   480         }
       
   481 
       
   482     if (powerState == EBTPowerOn)
       
   483         {
       
   484 
       
   485 #ifndef __WINS__
       
   486 
       
   487         TInt err = iDutMode.Open();
       
   488         TRACE_FUNC_ARG( ( _L( "Open DUT mode handle err %d" ), err) )
       
   489         if(!err) 
       
   490             {
       
   491             iDutMode.ActivateDutMode();
       
   492             iDutMode.Close();
       
   493             }
       
   494 #endif  //__WINS__                        
       
   495         }
       
   496         iEnableDutMode = EFalse;    
       
   497     }
       
   498 
       
   499 // ---------------------------------------------------------------------------
       
   500 // ?implementation_description
       
   501 // ---------------------------------------------------------------------------
       
   502 //
       
   503 void CBTEngServer::ScanModeTimerCompletedL()
       
   504     {
       
   505     TRACE_FUNC_ENTRY
       
   506     // The timer has completed, so remove our reference as well.
       
   507     iTimerQueued &= ~EScanModeTimer;
       
   508     iTimer->Remove( iScanModeCallBack );
       
   509     SetVisibilityModeL( EBTVisibilityModeHidden, 0 );
       
   510     TBTPowerStateValue power = EBTPowerOff;
       
   511     TInt err = GetHwPowerState( (TBTPowerStateValue&) power );
       
   512     if( !err && power )
       
   513         {
       
   514         // Show a notification to the user
       
   515         TBTGenericInfoNotiferParamsPckg pckg;
       
   516         pckg().iMessageType = EBTVisibilityTimeout;
       
   517         
       
   518         RNotifier notifier;
       
   519         TInt err = notifier.Connect();
       
   520         if( !err )
       
   521             {
       
   522             err = notifier.StartNotifier( KBTGenericInfoNotifierUid, pckg );
       
   523             notifier.Close();
       
   524             }
       
   525         }
       
   526     TRACE_FUNC_RES( ( _L( "result: %d" ), err ) )
       
   527     }
       
   528 
       
   529 
       
   530 // ---------------------------------------------------------------------------
       
   531 // ?implementation_description
       
   532 // ---------------------------------------------------------------------------
       
   533 //
       
   534 void CBTEngServer::DisconnectAllCompleted()
   272 void CBTEngServer::DisconnectAllCompleted()
   535     {
   273     {
   536         // Check if we are powering off. Otherwise we have just been 
   274         // Check if we are powering off. Otherwise we have just been 
   537         // requested to disconnect all, e.g. for system shutdown.
   275         // requested to disconnect all, e.g. for system shutdown.
   538     if( iServerState->CurrentOperation() == CBTEngSrvState::EPowerOff )
   276     if( iServerState->CurrentOperation() == CBTEngSrvState::EPowerOff )
   539         {
   277         {
   540         (void) SetPowerState( EFalse );
   278         (void) iSettingsMgr->SetHwPowerState( EBTOff );
   541             // Put the state machine into idle state.
   279             // Put the state machine into idle state.
   542         iServerState->ChangeState();
   280         iServerState->ChangeState();
   543         }
   281         }
   544     }
   282     }
   545 
   283 
   566     iTimer->Remove( iIdleCallBack );
   304     iTimer->Remove( iIdleCallBack );
   567     }
   305     }
   568 
   306 
   569 
   307 
   570 // ---------------------------------------------------------------------------
   308 // ---------------------------------------------------------------------------
   571 // A session has been ended, update the session count.
   309 // A session has been ended, update the session count and inform others.
   572 // ---------------------------------------------------------------------------
   310 // ---------------------------------------------------------------------------
   573 //
   311 //
   574 void CBTEngServer::RemoveSession( TBool aAutoOff )
   312 void CBTEngServer::RemoveSession( CSession2* aSession, TBool aAutoOff )
   575     {
   313     {
   576 	TRACE_FUNC_ENTRY
   314 	TRACE_FUNC_ENTRY
   577 	TRACE_INFO( ( _L( "[CBTEngServer]\t aAutoOff %d"), aAutoOff ))
   315 	TRACE_INFO( ( _L( "[CBTEngServer]\t aAutoOff %d"), aAutoOff ))
   578 	TRACE_INFO( ( _L( "[CBTEngServer]\t iSessionCount %d"), iSessionCount ))
   316 	TRACE_INFO( ( _L( "[CBTEngServer]\t iSessionCount %d"), iSessionCount ))
   579     iSessionCount--;
   317     iSessionCount--;
       
   318 	iSettingsMgr->SessionClosed( aSession );
       
   319 	iPairMan->SessionClosed( aSession );
   580     if( aAutoOff )
   320     if( aAutoOff )
   581         {
   321         {
   582         TRAP_IGNORE( SetPowerStateL( EBTPowerOff, ETrue ) );
   322         TRAP_IGNORE( SetPowerStateL( EBTOff, ETrue ) );
   583         }
   323         }
   584     else
   324     else
   585         {
   325         {
   586         CheckIdle();
   326         CheckIdle();
   587         }
   327         }
   588 	TRACE_FUNC_EXIT
   328 	TRACE_FUNC_EXIT
       
   329     }
       
   330 
       
   331 // ---------------------------------------------------------------------------
       
   332 // Queue a new timer.
       
   333 // ---------------------------------------------------------------------------
       
   334 //
       
   335 void CBTEngServer::QueueTimer( CBTEngServer::TTimerQueued aTimer, TInt64 aInterval )
       
   336     {
       
   337     TRACE_FUNC_ARG( ( _L( "queueing timer %d" ), (TInt) aTimer ) )
       
   338     iTimerQueued |= aTimer;
       
   339     TTimeIntervalMicroSeconds interval( aInterval );
       
   340     switch( aTimer )
       
   341         {
       
   342         case EScanModeTimer:
       
   343             (void) iTimer->QueueLong( interval, iScanModeCallBack );
       
   344             break;
       
   345         case EIdleTimer:
       
   346             iTimer->QueueLong( aInterval, iIdleCallBack );
       
   347             break;
       
   348         case EAutoPowerOffTimer:
       
   349             iTimer->QueueLong( aInterval, iPowerOffCallBack );
       
   350             break;
       
   351         case ESspDebugModeTimer:
       
   352             iTimer->QueueLong( aInterval, iDebugModeCallBack );
       
   353             break;
       
   354         default:
       
   355             PanicServer( EBTEngPanicCorrupt );
       
   356         }
       
   357     }
       
   358 
       
   359 
       
   360 // ---------------------------------------------------------------------------
       
   361 // Remove a queued timer.
       
   362 // ---------------------------------------------------------------------------
       
   363 //
       
   364 void CBTEngServer::RemoveTimer( CBTEngServer::TTimerQueued aTimer )
       
   365     {
       
   366     TRACE_FUNC_ARG( ( _L( "removing timer %d" ), (TInt) aTimer ) )
       
   367     iTimerQueued &= ~aTimer;
       
   368     // Timers can be removed without being queued, no need to check.
       
   369     switch( aTimer )
       
   370         {
       
   371         case EScanModeTimer:
       
   372             iTimer->Remove( iScanModeCallBack );
       
   373             break;
       
   374         case EIdleTimer:
       
   375             iTimer->Remove( iIdleCallBack );
       
   376             break;
       
   377         case EAutoPowerOffTimer:
       
   378             iTimer->Remove( iPowerOffCallBack );
       
   379             break;
       
   380         case ESspDebugModeTimer:
       
   381             iTimer->Remove( iDebugModeCallBack );
       
   382             break;
       
   383         default:
       
   384             PanicServer( EBTEngPanicCorrupt );
       
   385         }
       
   386     TRACE_FUNC_EXIT
   589     }
   387     }
   590 
   388 
   591 
   389 
   592 // ---------------------------------------------------------------------------
   390 // ---------------------------------------------------------------------------
   593 // From class CPolicyServer.
   391 // From class CPolicyServer.
   626     iTimerQueued &= ~EIdleTimer;
   424     iTimerQueued &= ~EIdleTimer;
   627     iTimer->Remove( iIdleCallBack );
   425     iTimer->Remove( iIdleCallBack );
   628     if( iSessionCount <= 0 )
   426     if( iSessionCount <= 0 )
   629         {
   427         {
   630             // No more sessions, check the power state.
   428             // No more sessions, check the power state.
   631         TBTPowerStateValue pwr = EBTPowerOff;
   429         TBTPowerState power = EBTOff;
   632         TInt err = GetHwPowerState( pwr );
   430         TInt err = iSettingsMgr->GetHwPowerState( power );
   633         TRACE_INFO( ( _L( "[BTEng]\t No sessions; power state: %d" ), pwr ) )
   431         TRACE_INFO( ( _L( "[BTEng]\t No sessions; power state: %d" ), power ) )
   634         if( !err &&!pwr 
   432         if( !err && power == EBTOff
   635             && iServerState->CurrentOperation() == CBTEngSrvState::ESrvOpIdle )
   433             && iServerState->CurrentOperation() == CBTEngSrvState::ESrvOpIdle )
   636             {
   434             {
   637             TRACE_INFO( ( _L( "[BTEng]\t Power off; starting shutdown timer" ) ) )
   435             TRACE_INFO( ( _L( "[BTEng]\t Power off; starting shutdown timer" ) ) )
   638                 // power is off, start the shutdown timer.
   436                 // power is off, start the shutdown timer.
   639             TTimeIntervalMicroSeconds32 interval = KBTEngSrvIdleTimeout;
   437             TTimeIntervalMicroSeconds32 interval = KBTEngSrvIdleTimeout;
   640             iTimer->Queue( interval, iIdleCallBack );
   438             iTimer->Queue( interval, iIdleCallBack );
   641             iTimerQueued |= EIdleTimer;
   439             iTimerQueued |= EIdleTimer;
   642             }
   440             }
   643         }
   441         }
   644     }
       
   645 
       
   646 
       
   647 // ---------------------------------------------------------------------------
       
   648 // ?implementation_description
       
   649 // ---------------------------------------------------------------------------
       
   650 //
       
   651 TInt CBTEngServer::SetPowerState( TBool aState )
       
   652     {
       
   653     TRACE_FUNC_ENTRY
       
   654     TInt err = KErrNone;
       
   655     // HCIv2 power state type is inverted from BTPM-defined type...
       
   656     TBTPowerState powerState = (TBTPowerState) !aState;
       
   657     TRequestStatus status;
       
   658     
       
   659 #ifndef __WINS__
       
   660     iPowerMgr.SetPower( powerState, NULL, status );
       
   661     User::WaitForRequest( status );
       
   662     err = status.Int();
       
   663 #else   //__WINS__
       
   664     iPowerState = powerState;
       
   665     err = KErrNone;
       
   666 #endif  //__WINS__
       
   667 
       
   668    if( !err && aState )
       
   669         {
       
   670         TInt dutMode;
       
   671         err = RProperty::Get( KPSUidBluetoothTestingMode, KBTDutEnabled, dutMode );
       
   672         if( !err && dutMode == EBTDutOn )
       
   673             {
       
   674                 // Set the DUT mode key to OFF since DUT mode is disabled at this point
       
   675             err = RProperty::Set( KPSUidBluetoothTestingMode, KBTDutEnabled, EBTDutOff );
       
   676             }
       
   677             // Set the local name straight away, so that an error 
       
   678             // in the loading of the BT stack will be detected here.
       
   679             // Note that the HCIv2 power manager already loads the BT stack, 
       
   680             // so we do not need to do that here.
       
   681         TRAP(err,SetLocalNameL());
       
   682         }
       
   683     if( err )
       
   684         {
       
   685         // Power off if an error occurred during power on sequence.
       
   686 #ifndef __WINS__
       
   687             // This cannot happen in emulator environment.
       
   688         iPowerMgr.SetPower( EBTOff, NULL, status );
       
   689         User::WaitForRequest( status );
       
   690 #endif  //__WINS__
       
   691         } 
       
   692     TRACE_FUNC_RES( ( _L( "result: %d" ), err ) )
       
   693     return err;
       
   694     }
       
   695 
       
   696 
       
   697 // ---------------------------------------------------------------------------
       
   698 // ?implementation_description
       
   699 // ---------------------------------------------------------------------------
       
   700 //
       
   701 TInt CBTEngServer::SetLocalNameL()
       
   702     {
       
   703     TRACE_FUNC_ENTRY
       
   704     RHostResolver hostResolver;
       
   705     TBuf<KMaxBluetoothNameLen> name;
       
   706     name.Zero();
       
   707     TBuf<KMaxBluetoothNameLen> tmpName;
       
   708     
       
   709     TInt err = RProperty::Get(KPropertyUidBluetoothCategory, 
       
   710                                 KPropertyKeyBluetoothGetDeviceName, name);
       
   711     if(err == KErrNone)
       
   712         {
       
   713         err = RProperty::Get(KPropertyUidBluetoothCategory, 
       
   714                                KPropertyKeyBluetoothSetDeviceName, tmpName);
       
   715         if (tmpName.Compare(name))
       
   716             {
       
   717             // The name has not yet been updated. Use the new one.
       
   718             name.Copy(tmpName);
       
   719             }
       
   720         }
       
   721     // if name hasn't been set, check whats in the registry
       
   722     if (err || !name.Length())
       
   723         {
       
   724         GetLocalNameFromRegistryL(name);
       
   725         }
       
   726 
       
   727     TRACE_INFO( ( _L( "[CBTEngServer]\t localDev.DeviceName(): '%S'" ), &name))
       
   728     
       
   729     CleanupClosePushL(hostResolver);
       
   730     User::LeaveIfError(hostResolver.Open(iSocketServ, KBTAddrFamily, KBTLinkManager));
       
   731     User::LeaveIfError(hostResolver.SetHostName(name));    
       
   732     CleanupStack::PopAndDestroy(&hostResolver);
       
   733 
       
   734     return KErrNone;
       
   735     }
       
   736 
       
   737 
       
   738 // ---------------------------------------------------------------------------
       
   739 // Checks whats written in the registry in order to set host name 
       
   740 // ---------------------------------------------------------------------------
       
   741 //
       
   742 TInt CBTEngServer::GetLocalNameFromRegistryL(TDes& aName)
       
   743     {
       
   744     TRACE_FUNC_ENTRY
       
   745     RBTRegServ btRegServ;
       
   746     RBTLocalDevice btReg;
       
   747     TBTLocalDevice localDev;
       
   748     
       
   749     CleanupClosePushL(btRegServ);
       
   750     CleanupClosePushL(btReg);
       
   751     
       
   752     // In case of error, read local name from registry
       
   753     aName.Zero();
       
   754     User::LeaveIfError(btRegServ.Connect());
       
   755     User::LeaveIfError(btReg.Open(btRegServ));
       
   756     
       
   757     // Read the BT local name from BT Registry.
       
   758     User::LeaveIfError(btReg.Get(localDev));       
       
   759 
       
   760     CleanupStack::PopAndDestroy(2,&btRegServ);
       
   761  
       
   762     // BT registry keeps the device name in UTF-8 format, convert to unicode.
       
   763     // The error can be > 0 if there are unconverted characters.
       
   764     TInt err = CnvUtfConverter::ConvertToUnicodeFromUtf8(aName, localDev.DeviceName());
       
   765     if (err != KErrNone)
       
   766         User::Leave(err);
       
   767     return KErrNone; 
       
   768     }
       
   769 
       
   770 
       
   771 // ---------------------------------------------------------------------------
       
   772 // ?implementation_description
       
   773 // ---------------------------------------------------------------------------
       
   774 //
       
   775 void CBTEngServer::SetClassOfDeviceL()
       
   776     {
       
   777     TRACE_FUNC_ENTRY
       
   778     TUint16 serviceClass = KCoDDefaultServiceClass;
       
   779         // Check from feature manager if stereo audio is enabled.
       
   780     FeatureManager::InitializeLibL();
       
   781     TBool supported = FeatureManager::FeatureSupported( KFeatureIdBtStereoAudio );
       
   782     FeatureManager::UnInitializeLib();
       
   783     if( supported )
       
   784         {
       
   785         // A2DP spec says we should set this bit as we are a SRC
       
   786         serviceClass |= EMajorServiceCapturing;
       
   787         }
       
   788         // These values may nayway be overridden by HCI
       
   789     TBTDeviceClass cod( serviceClass, KCoDDefaultMajorDeviceClass, 
       
   790                          KCoDDefaultMinorDeviceClass );
       
   791         // Ignore error, it is non-critical
       
   792     (void) RProperty::Set( KPropertyUidBluetoothControlCategory, 
       
   793                             KPropertyKeyBluetoothSetDeviceClass, cod.DeviceClass() );
       
   794     TRACE_FUNC_EXIT
       
   795     }
       
   796 
       
   797 
       
   798 // ---------------------------------------------------------------------------
       
   799 // ?implementation_description
       
   800 // ---------------------------------------------------------------------------
       
   801 //
       
   802 void CBTEngServer::InitBTStackL()
       
   803     {
       
   804     TRACE_FUNC_ENTRY
       
   805     iBBConnMgr->Subscribe();
       
   806     TBTVisibilityMode visibility = EBTVisibilityModeHidden;
       
   807     CRepository* cenRep = CRepository::NewL( KCRUidBTEngPrivateSettings );
       
   808     TInt err = cenRep->Get( KBTDiscoverable, (TInt&) visibility );
       
   809     delete cenRep;
       
   810     if (iRestoreVisibility == EFalse)
       
   811         {
       
   812         if( err || visibility == EBTVisibilityModeTemporary && !( iTimerQueued & EScanModeTimer ) )
       
   813             {
       
   814             visibility = EBTVisibilityModeHidden;
       
   815             }
       
   816         SetVisibilityModeL( visibility, 0 );
       
   817         }
       
   818     SetClassOfDeviceL();
       
   819     TBool sspDebugMode = EFalse;
       
   820     (void) RProperty::Get( KPropertyUidBluetoothCategory, 
       
   821                             KPropertyKeyBluetoothGetSimplePairingDebugMode, 
       
   822                             (TInt&) sspDebugMode );
       
   823         // Only set debug mode to off if it is on, to prevent a loop notifications.
       
   824     if( sspDebugMode )
       
   825         {
       
   826         sspDebugMode = EFalse;
       
   827         // Add LeaveIfError if unsuccessful
       
   828         (void) RProperty::Set(KPropertyUidBluetoothCategory, 
       
   829                                KPropertyKeyBluetoothSetSimplePairingDebugMode,
       
   830                                (TInt) sspDebugMode );
       
   831         }
       
   832     TRACE_FUNC_EXIT
       
   833     }
       
   834 
       
   835 
       
   836 // ---------------------------------------------------------------------------
       
   837 // ?implementation_description
       
   838 // ---------------------------------------------------------------------------
       
   839 //
       
   840 void CBTEngServer::StopBTStackL()
       
   841     {
       
   842     TRACE_FUNC_ENTRY
       
   843     TBTVisibilityMode visibility = EBTVisibilityModeHidden;
       
   844     CRepository* cenRep = CRepository::NewL( KCRUidBTEngPrivateSettings );
       
   845           // Ignore error here; if we can't read it, likely we can't set it either.
       
   846     (void) cenRep->Get( KBTDiscoverable, (TInt&) visibility );
       
   847     delete cenRep;
       
   848     if( visibility == EBTVisibilityModeTemporary )
       
   849         {
       
   850         visibility = EBTVisibilityModeHidden;
       
   851         SetVisibilityModeL( visibility, 0 );    // Also cancels scan mode timer.
       
   852         }
       
   853 
       
   854         // Stop listening to events
       
   855     iBBConnMgr->Unsubscribe();
       
   856         // Disconnect all links
       
   857     TCallBack cb( DisconnectAllCallBack, this );
       
   858     iBBConnMgr->DisconnectAllLinksL( cb );
       
   859         // Results in a callback (which is called directly when there are no links).
       
   860     TRACE_FUNC_EXIT
       
   861     }
       
   862 
       
   863 
       
   864 // ---------------------------------------------------------------------------
       
   865 // Update the power state CenRep key.
       
   866 // ---------------------------------------------------------------------------
       
   867 //
       
   868 void CBTEngServer::UpdateCenRepPowerKeyL( TBTPowerStateValue aState )
       
   869     {
       
   870     TRACE_FUNC_ENTRY
       
   871     CRepository* cenrep = CRepository::NewLC( KCRUidBluetoothPowerState );
       
   872     User::LeaveIfError( cenrep->Set( KBTPowerState, (TInt) aState ) );
       
   873     CleanupStack::PopAndDestroy( cenrep );
       
   874     TRACE_FUNC_EXIT
       
   875     }
       
   876 
       
   877 
       
   878 // ---------------------------------------------------------------------------
       
   879 // Loads the BT Power Manager; leaves if it cannot be loaded.
       
   880 // ---------------------------------------------------------------------------
       
   881 //
       
   882 void CBTEngServer::LoadBTPowerManagerL()
       
   883     {
       
   884     TRACE_FUNC_ENTRY
       
   885     TRACE_INFO( ( _L( "[CBTEngServer]\t Using HCI API v2 power manager" ) ) )
       
   886     User::LeaveIfError( iPowerMgr.Open() );
       
   887 #ifndef __WINS__
       
   888     TRequestStatus status( KRequestPending );
       
   889     iPowerMgr.SetPower( EBTOff, NULL, status );
       
   890     User::WaitForRequest( status );
       
   891     status = ( status.Int() == KErrAlreadyExists ? KErrNone : status.Int() ); 
       
   892     User::LeaveIfError( status.Int() );
       
   893 #else   //__WINS__
       
   894     iPowerState = EBTOff;
       
   895 #endif  //__WINS__
       
   896     TRACE_FUNC_EXIT
       
   897     }
   442     }
   898 
   443 
   899 
   444 
   900 // ---------------------------------------------------------------------------
   445 // ---------------------------------------------------------------------------
   901 // ?implementation_description
   446 // ?implementation_description
   957     User::LeaveIfError( cenRep->Get( KBTVendorID, aVendorId ) );
   502     User::LeaveIfError( cenRep->Get( KBTVendorID, aVendorId ) );
   958     User::LeaveIfError( cenRep->Get( KBTProductID, aProductId ) );
   503     User::LeaveIfError( cenRep->Get( KBTProductID, aProductId ) );
   959     CleanupStack::PopAndDestroy( cenRep );  //cenRep
   504     CleanupStack::PopAndDestroy( cenRep );  //cenRep
   960     }
   505     }
   961 
   506 
   962 // ---------------------------------------------------------------------------
       
   963 // ?implementation_description
       
   964 // ---------------------------------------------------------------------------
       
   965 //
       
   966 void CBTEngServer::SetUiIndicatorsL()
       
   967     {
       
   968     TRACE_FUNC_ENTRY
       
   969     TInt powerState = EBTPowerOff;
       
   970     TBTVisibilityMode visibilityMode = EBTVisibilityModeHidden;
       
   971     CRepository* cenrep = NULL;
       
   972     TInt phys = 0;
       
   973     TInt connecting = 0;
       
   974     
       
   975     cenrep = CRepository::NewLC( KCRUidBluetoothPowerState );
       
   976     User::LeaveIfError( cenrep->Get( KBTPowerState, powerState ) );
       
   977     CleanupStack::PopAndDestroy( cenrep );  
       
   978     
       
   979     if( powerState == EBTPowerOff )
       
   980         {
       
   981         SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOff );
       
   982         SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateOff );
       
   983         SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOff );
       
   984         SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateOff );
       
   985         }
       
   986     else if( powerState == EBTPowerOn )
       
   987         {
       
   988         RProperty::Get( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothPHYCount, phys );
       
   989         RProperty::Get( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothConnecting, connecting );
       
   990         
       
   991         cenrep = CRepository::NewLC( KCRUidBTEngPrivateSettings );
       
   992         User::LeaveIfError( cenrep->Get( KBTDiscoverable, (TInt&) visibilityMode ) );
       
   993         CleanupStack::PopAndDestroy( cenrep );
       
   994         
       
   995         if( visibilityMode == EBTVisibilityModeHidden )
       
   996             {
       
   997              if ( connecting ) // BT connecting and hidden
       
   998                 {
       
   999                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOff );
       
  1000                 SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateAnimate );
       
  1001                 }
       
  1002             else if ( phys > 0 ) // BT connection active and hidden     
       
  1003                 {
       
  1004                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOff );
       
  1005                 SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateOn );
       
  1006                 }
       
  1007             else  // BT connection not active and hidden
       
  1008                 {
       
  1009                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOn );
       
  1010                 SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateOff );
       
  1011                 }
       
  1012             SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOff );
       
  1013             SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateOff );
       
  1014             }           
       
  1015         else if( visibilityMode == EBTVisibilityModeGeneral || visibilityMode == EBTVisibilityModeTemporary )
       
  1016             {     
       
  1017             if ( connecting ) // BT connecting and visible
       
  1018                 {
       
  1019                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOff );
       
  1020                 SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateAnimate );
       
  1021                 }
       
  1022             else if ( phys > 0 ) // BT connection active and visible 
       
  1023                 {
       
  1024                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOff );
       
  1025                 SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateOn );
       
  1026                 }
       
  1027             else  // BT connection not active and visible
       
  1028                 {
       
  1029                 SetIndicatorStateL( EAknIndicatorBluetoothModuleOnVisible, EAknIndicatorStateOn );
       
  1030                 SetIndicatorStateL( EAknIndicatorBluetoothVisible, EAknIndicatorStateOff );
       
  1031                 }
       
  1032             SetIndicatorStateL( EAknIndicatorBluetoothModuleOn, EAknIndicatorStateOff );
       
  1033             SetIndicatorStateL( EAknIndicatorBluetooth, EAknIndicatorStateOff );
       
  1034             }
       
  1035         }
       
  1036     TRACE_FUNC_EXIT
       
  1037     }
       
  1038 
       
  1039 // ---------------------------------------------------------------------------
       
  1040 // ?implementation_description
       
  1041 // ---------------------------------------------------------------------------
       
  1042 //
       
  1043 void CBTEngServer::SetIndicatorStateL( const TInt aIndicator, const TInt aState )
       
  1044     {
       
  1045     CAknSmallIndicator* indicator = CAknSmallIndicator::NewLC( TUid::Uid( aIndicator ) );
       
  1046     indicator->SetIndicatorStateL( aState );
       
  1047     CleanupStack::PopAndDestroy( indicator ); //indicator
       
  1048     }
       
  1049 
       
  1050 // ---------------------------------------------------------------------------
       
  1051 // Gets the current HW power state.
       
  1052 // For now this is a separate method to isolate the different variations.
       
  1053 // ---------------------------------------------------------------------------
       
  1054 //
       
  1055 TInt CBTEngServer::GetHwPowerState( TBTPowerStateValue& aState )
       
  1056     {
       
  1057     TRACE_FUNC_ENTRY
       
  1058     TInt err = KErrNone;
       
  1059     
       
  1060 #ifndef __WINS__
       
  1061     err = iPowerMgr.GetPower( (TBTPowerState&) aState, NULL );
       
  1062 #else   //__WINS__
       
  1063     aState = (TBTPowerStateValue) iPowerState;
       
  1064 #endif  //__WINS__
       
  1065     
       
  1066         // HCIv2 power state type is inverted from BTPM-defined type...
       
  1067     aState = (TBTPowerStateValue) !aState;
       
  1068     TRACE_FUNC_ARG( ( _L( "Power state is %d, result %d" ), (TInt) aState, err ) )
       
  1069     return err;
       
  1070     }
       
  1071 
       
  1072 // ---------------------------------------------------------------------------
       
  1073 // Check the power state and if BT gets turned off automatically.
       
  1074 // ---------------------------------------------------------------------------
       
  1075 //
       
  1076 void CBTEngServer::CheckTemporaryPowerStateL( TBTPowerStateValue& aCurrentState, 
       
  1077     TBTPowerStateValue aNewState, TBool aTemporary )
       
  1078     {
       
  1079 	TRACE_FUNC_ENTRY
       
  1080     User::LeaveIfError( GetHwPowerState( aCurrentState ) );
       
  1081     if( !aTemporary )
       
  1082         {
       
  1083             // Force the new power state, so clear all auto switch off flags.
       
  1084             // If power is off, this will anyway be ignored.
       
  1085         iAutoOffClients = 0;
       
  1086         iAutoSwitchOff = EFalse;
       
  1087         TCallBack cb;
       
  1088         iBBConnMgr->SetAutoSwitchOff( EFalse, cb );
       
  1089         if( iRestoreVisibility && aCurrentState == EBTPowerOn )
       
  1090             {
       
  1091                 // Set visibility mode back to the value selected by the user.
       
  1092             SetVisibilityModeL( EBTVisibilityModeGeneral, 0 );
       
  1093             iRestoreVisibility = EFalse;
       
  1094             }
       
  1095         }
       
  1096     else
       
  1097         {
       
  1098         if( aCurrentState == aNewState )
       
  1099             {
       
  1100             if( iAutoSwitchOff && aNewState == EBTPowerOn )
       
  1101                 {
       
  1102                 iAutoOffClients++;
       
  1103                 if( iTimerQueued & EAutoPowerOffTimer )
       
  1104                    {
       
  1105                    iTimer->Remove( iPowerOffCallBack );
       
  1106                    iTimerQueued &= ~EAutoPowerOffTimer;
       
  1107                    }
       
  1108                 }
       
  1109             }
       
  1110         else if( iAutoSwitchOff || aNewState == EBTPowerOn )
       
  1111             {
       
  1112             aNewState == EBTPowerOff ? iAutoOffClients-- : iAutoOffClients++;
       
  1113             iAutoSwitchOff = ETrue;
       
  1114             if( aNewState == EBTPowerOff && iAutoOffClients <= 0 )
       
  1115                 {
       
  1116                 TCallBack powerOffCb( AutoPowerOffCallBack, this );
       
  1117                 iBBConnMgr->SetAutoSwitchOff( ETrue, powerOffCb );
       
  1118                 iTimer->Queue( KBTEngBtAutoOffTimeout, iPowerOffCallBack );
       
  1119                 iTimerQueued |= EAutoPowerOffTimer;
       
  1120                 }
       
  1121             else if( aNewState == EBTPowerOn )
       
  1122                 {
       
  1123                 CRepository* cenRep = CRepository::NewLC( KCRUidBTEngPrivateSettings );
       
  1124                 TBTVisibilityMode visibility = EBTVisibilityModeGeneral;
       
  1125                 TInt err = cenRep->Get( KBTDiscoverable, (TInt&) visibility );
       
  1126                 CleanupStack::PopAndDestroy( cenRep );
       
  1127                 if( !err && visibility == EBTVisibilityModeGeneral )
       
  1128                     {
       
  1129                     SetVisibilityModeL( EBTVisibilityModeHidden, 0 );
       
  1130                     iRestoreVisibility = ETrue;
       
  1131                     }
       
  1132                 if( iTimerQueued & EAutoPowerOffTimer )
       
  1133                    {
       
  1134                    iTimer->Remove( iPowerOffCallBack );
       
  1135                    iTimerQueued &= ~EAutoPowerOffTimer;
       
  1136                    }
       
  1137                 }
       
  1138             }
       
  1139         }
       
  1140     if( iAutoOffClients < 0 )
       
  1141         {
       
  1142         iAutoOffClients = 0;
       
  1143         }
       
  1144 	TRACE_FUNC_EXIT	
       
  1145     }
       
  1146 
       
  1147 // ---------------------------------------------------------------------------
       
  1148 // Check the power state and if BT gets turned off automatically.
       
  1149 // This method is invoked either when the timer has expired, or
       
  1150 // if there are no more connections while the timer was running.
       
  1151 // ---------------------------------------------------------------------------
       
  1152 //
       
  1153 void CBTEngServer::CheckAutoPowerOffL()
       
  1154     {
       
  1155    	TRACE_FUNC_ENTRY
       
  1156 	if ( iAutoOffClients > 0 )
       
  1157 	{
       
  1158 	TRACE_INFO( ( _L( "[CBTEngServer]\t iAutoOffClients %d"), iAutoOffClients ))
       
  1159 	return;
       
  1160 	}
       
  1161     TInt linkCount = 0;
       
  1162     TInt err = RProperty::Get( KPropertyUidBluetoothCategory, 
       
  1163                                 KPropertyKeyBluetoothGetPHYCount, linkCount );
       
  1164     if( !err && !linkCount )
       
  1165         {
       
  1166         TRACE_INFO( ( _L( "[CBTEngServer]\t SetPowerStateL( EBTPowerOff, EFalse );")))
       
  1167         SetPowerStateL( EBTPowerOff, EFalse );
       
  1168         }
       
  1169     else
       
  1170         {
       
  1171         if( iRestoreVisibility )
       
  1172             {
       
  1173                 // Set visibility mode back to the value selected by the user.
       
  1174             SetVisibilityModeL( EBTVisibilityModeGeneral, 0 );
       
  1175             iRestoreVisibility = EFalse;
       
  1176             }
       
  1177             // show note if non-audio connection exists
       
  1178         if ( !iPluginMgr->CheckAudioConnectionsL() )
       
  1179             {
       
  1180 	        RNotifier notifier;
       
  1181 	        TInt err = notifier.Connect();
       
  1182 	        if( !err )
       
  1183 	            {
       
  1184 				TRequestStatus status;
       
  1185 				TBTGenericInfoNotiferParamsPckg pckg;
       
  1186 				pckg().iMessageType = EBTStayPowerOn;
       
  1187 				TBuf8<sizeof(TInt)> result;
       
  1188 	            //notifier.StartNotifier( KBTGenericInfoNotifierUid, pckg, result );
       
  1189 				notifier.StartNotifierAndGetResponse( status, 
       
  1190                                                   KBTGenericInfoNotifierUid, 
       
  1191                                                   pckg, result );   // Reply buffer not used.
       
  1192 				User::WaitForRequest( status );
       
  1193 	            notifier.Close();
       
  1194 		        }
       
  1195             }
       
  1196         iAutoOffClients = 0;
       
  1197         iAutoSwitchOff = EFalse;
       
  1198         TCallBack cb;
       
  1199         iBBConnMgr->SetAutoSwitchOff( EFalse, cb );
       
  1200         }
       
  1201 	TRACE_FUNC_EXIT	
       
  1202     }
       
  1203 
       
  1204 // ---------------------------------------------------------------------------
       
  1205 // ?implementation_description
       
  1206 // ---------------------------------------------------------------------------
       
  1207 //
       
  1208 void CBTEngServer::CheckSspDebugModeL( TBool aDebugMode )
       
  1209     {
       
  1210     TRACE_FUNC_ARG( ( _L( "SSP debug mode state %d" ), (TInt) aDebugMode ) )
       
  1211     TBTPowerState pwr = EBTOff;
       
  1212     TBool currentMode = EFalse;
       
  1213     TInt err = RProperty::Get( KPropertyUidBluetoothCategory, 
       
  1214                                 KPropertyKeyBluetoothGetSimplePairingDebugMode, 
       
  1215                                 (TInt&) currentMode );
       
  1216 #ifndef __WINS__
       
  1217     err = iPowerMgr.GetPower( pwr, NULL ); // Treat error as power off.
       
  1218 #else   //__WINS__
       
  1219     pwr = iPowerState;
       
  1220 #endif  //__WINS__
       
  1221     if( err || pwr == EBTOff )
       
  1222         {
       
  1223         iTimerQueued &= ~ESspDebugModeTimer;
       
  1224         iTimer->Remove( iDebugModeCallBack );
       
  1225             // Only set debug mode to off if it is on, to prevent a loop notifications.
       
  1226         if( currentMode )
       
  1227             {
       
  1228             (void) RProperty::Set( KPropertyUidBluetoothCategory, 
       
  1229                                     KPropertyKeyBluetoothSetSimplePairingDebugMode,
       
  1230                                     (TInt) aDebugMode );
       
  1231             }
       
  1232             // In case of an error in getting the power state, turn BT off. 
       
  1233             // If BT is already off, this call will be ignored.
       
  1234         SetPowerStateL( EBTPowerOff, EFalse );
       
  1235         }
       
  1236     else if( aDebugMode )
       
  1237         {
       
  1238             // Ignore if there already is a timer queued.
       
  1239         if( !( iTimerQueued & ESspDebugModeTimer ) )
       
  1240             {
       
  1241             iTimer->Queue( TTimeIntervalMicroSeconds32( KBTEngSspDebugModeTimeout ), 
       
  1242                             iDebugModeCallBack );
       
  1243             iTimerQueued &= ESspDebugModeTimer;
       
  1244             err =  RProperty::Set(KPropertyUidBluetoothCategory, 
       
  1245                                    KPropertyKeyBluetoothSetSimplePairingDebugMode, 
       
  1246                                    (TInt) aDebugMode );
       
  1247             }
       
  1248         }
       
  1249     else
       
  1250         {
       
  1251             // Power is on, and debug mode is set to off.
       
  1252         TInt linkCount = 0;
       
  1253         err = RProperty::Get( KPropertyUidBluetoothCategory, 
       
  1254                                KPropertyKeyBluetoothGetPHYCount, linkCount );
       
  1255         if( err || !linkCount )
       
  1256             {
       
  1257             (void) RProperty::Set(KPropertyUidBluetoothCategory, 
       
  1258                                    KPropertyKeyBluetoothSetSimplePairingDebugMode,
       
  1259                                    (TInt) aDebugMode );
       
  1260             SetPowerStateL( EBTPowerOff, EFalse );
       
  1261             }
       
  1262         else
       
  1263             {
       
  1264                 // There are still existing connections, queue the 
       
  1265                 // timer again for half the period.
       
  1266             iTimer->Queue( TTimeIntervalMicroSeconds32( KBTEngSspDebugModeTimeout / 2 ), 
       
  1267                             iDebugModeCallBack );
       
  1268             iTimerQueued &= ESspDebugModeTimer;
       
  1269             }
       
  1270         }
       
  1271     TRACE_FUNC_EXIT
       
  1272     }
       
  1273 
       
  1274 // ---------------------------------------------------------------------------
       
  1275 // returns the reference of pairing manager
       
  1276 // ---------------------------------------------------------------------------
       
  1277 //
       
  1278 CBTEngPairMan& CBTEngServer::PairManager()
       
  1279     {
       
  1280     return *iPairMan;
       
  1281     }
       
  1282 
       
  1283 // ---------------------------------------------------------------------------
       
  1284 // Delegate the information to pairing manager
       
  1285 // ---------------------------------------------------------------------------
       
  1286 //
       
  1287 void CBTEngServer::RemoteRegistryChangeDetected()
       
  1288     {
       
  1289     iPairMan->RemoteRegistryChangeDetected();
       
  1290     }
       
  1291 
       
  1292 // ---------------------------------------------------------------------------
       
  1293 // Access the reference of RSockServ
       
  1294 // ---------------------------------------------------------------------------
       
  1295 //
       
  1296 RSocketServ& CBTEngServer::SocketServ()
       
  1297     {
       
  1298     return iSocketServ;
       
  1299     }
       
  1300 
       
  1301 // ---------------------------------------------------------------------------
       
  1302 // Access the reference of RBTRegSrv
       
  1303 // ---------------------------------------------------------------------------
       
  1304 //
       
  1305 RBTRegServ& CBTEngServer::BTRegServ()
       
  1306     {
       
  1307     return iBTRegServ;
       
  1308     }
       
  1309 
   507 
  1310 // ---------------------------------------------------------------------------
   508 // ---------------------------------------------------------------------------
  1311 // Ask plugin manager the connection status of the specified device
   509 // Ask plugin manager the connection status of the specified device
  1312 // ---------------------------------------------------------------------------
   510 // ---------------------------------------------------------------------------
  1313 //
   511 //
  1319         status = iPluginMgr->IsDeviceConnected( aAddr );
   517         status = iPluginMgr->IsDeviceConnected( aAddr );
  1320         }
   518         }
  1321     return status;
   519     return status;
  1322     }
   520     }
  1323 
   521 
       
   522 
  1324 // ---------------------------------------------------------------------------
   523 // ---------------------------------------------------------------------------
  1325 // Static callback for temporary visibility mode.
   524 // Static callback for temporary visibility mode.
  1326 // ---------------------------------------------------------------------------
   525 // ---------------------------------------------------------------------------
  1327 //
   526 //
  1328 TInt CBTEngServer::ScanModeTimerCallBack( TAny* aPtr )
   527 TInt CBTEngServer::ScanModeTimerCallBack( TAny* aPtr )
  1329     {
   528     {
  1330     __ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
   529     __ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
  1331     TRAPD( err, ( (CBTEngServer*) aPtr )->ScanModeTimerCompletedL() );
   530     // The timer has completed, so remove our reference as well.
       
   531     CBTEngServer* server = (CBTEngServer*) aPtr;
       
   532     server->RemoveTimer( EScanModeTimer );
       
   533     TRAPD( err, server->SettingsManager()->ScanModeTimerCompletedL() );
  1332     return err;
   534     return err;
  1333     }
   535     }
       
   536 
  1334 
   537 
  1335 // ---------------------------------------------------------------------------
   538 // ---------------------------------------------------------------------------
  1336 // Static callback for disconnecting all Baseband connections.
   539 // Static callback for disconnecting all Baseband connections.
  1337 // ---------------------------------------------------------------------------
   540 // ---------------------------------------------------------------------------
  1338 //
   541 //
  1353     (void) aPtr;
   556     (void) aPtr;
  1354     CActiveScheduler::Stop();   // Will destroy CBTEngServer
   557     CActiveScheduler::Stop();   // Will destroy CBTEngServer
  1355     return KErrNone;
   558     return KErrNone;
  1356     }
   559     }
  1357 
   560 
       
   561 
  1358 // ---------------------------------------------------------------------------
   562 // ---------------------------------------------------------------------------
  1359 // Static callback for idle timer timeout. Turn off BT to get it out of 
   563 // Static callback for idle timer timeout. Turn off BT to get it out of 
  1360 // debug mode. If there are existing connections, queue the timer again.
   564 // debug mode. If there are existing connections, queue the timer again.
  1361 // ---------------------------------------------------------------------------
   565 // ---------------------------------------------------------------------------
  1362 //
   566 //
  1363 TInt CBTEngServer::DebugModeTimerCallBack( TAny* aPtr )
   567 TInt CBTEngServer::DebugModeTimerCallBack( TAny* aPtr )
  1364     {
   568     {
       
   569     __ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
  1365     // Set our internal debug mode key to off. Ignore error, not critical here.
   570     // Set our internal debug mode key to off. Ignore error, not critical here.
  1366     (void) RProperty::Set( KPSUidBluetoothTestingMode, KBTSspDebugmode, EFalse );
   571     (void) RProperty::Set( KPSUidBluetoothTestingMode, KBTSspDebugmode, EFalse );
  1367     
   572     CBTEngServer* server = (CBTEngServer*) aPtr;
       
   573     TRAP_IGNORE( server->SettingsManager()->CheckSspDebugModeL( EFalse ) );
       
   574     return KErrNone;
       
   575     }
       
   576 
       
   577 
       
   578 // ---------------------------------------------------------------------------
       
   579 // Static callback for auto power off.
       
   580 // ---------------------------------------------------------------------------
       
   581 //
       
   582 TInt CBTEngServer::AutoPowerOffCallBack( TAny* aPtr )
       
   583     {
  1368     __ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
   584     __ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
  1369     
   585     // The timer has completed, so remove our reference as well.
  1370     TRAP_IGNORE( ( (CBTEngServer*) aPtr )->CheckSspDebugModeL( EFalse ) );
       
  1371     return KErrNone;
       
  1372     }
       
  1373 
       
  1374 // ---------------------------------------------------------------------------
       
  1375 // Static callback for auto power off.
       
  1376 // ---------------------------------------------------------------------------
       
  1377 //
       
  1378 TInt CBTEngServer::AutoPowerOffCallBack( TAny* aPtr )
       
  1379     {
       
  1380 	TRACE_FUNC_ENTRY
       
  1381 	
       
  1382 	__ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
       
  1383 	
       
  1384     CBTEngServer* server = (CBTEngServer*) aPtr;
   586     CBTEngServer* server = (CBTEngServer*) aPtr;
  1385     server->iTimerQueued &= ~EAutoPowerOffTimer;
   587     server->RemoveTimer( EAutoPowerOffTimer );
  1386     TRAPD( err, server->CheckAutoPowerOffL() );
   588     TRAPD( err, server->SettingsManager()->CheckAutoPowerOffL() );
  1387     return err;
   589     return err;
  1388     }
   590     }
  1389 
   591 
  1390 BluetoothFeatures::TEnterpriseEnablementMode CBTEngServer::EnterpriseEnablementMode() const
       
  1391     {
       
  1392     return iEnterpriseEnablementMode;
       
  1393     }
       
  1394 
   592 
  1395 // ======== GLOBAL FUNCTIONS ========
   593 // ======== GLOBAL FUNCTIONS ========
  1396 
   594 
  1397 // ---------------------------------------------------------------------------
   595 // ---------------------------------------------------------------------------
  1398 // Main function of the executable.
   596 // Main function of the executable.