bluetoothengine/bteng/src/btengserver.cpp
changeset 0 f63038272f30
child 10 0707dd69d236
child 15 00f9ee97d895
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "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:  Server-side implementation of BTEng
       
    15 *
       
    16 */
       
    17 
       
    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>
       
    26 #include <btmanclient.h>
       
    27 #include <es_sock.h>
       
    28 #include <btnotif.h>
       
    29 #include <utf.h>
       
    30 #include <ecom/ecom.h>
       
    31 #include <centralrepository.h>
       
    32 #include <featmgr.h>
       
    33 #include <AknSmallIndicator.h>
       
    34 #include <avkon.hrh>
       
    35 #include <bt_subscribe.h>
       
    36 #include "btengserver.h"
       
    37 #include "btengsrvstate.h"
       
    38 #include "btengsrvsession.h"
       
    39 #include "btengsrvpluginmgr.h"
       
    40 #include "btengsrvbbconnectionmgr.h"
       
    41 #include "btengsrvkeywatcher.h"
       
    42 #include "btengsdpdbhandler.h"
       
    43 #include "btengclientserver.h"
       
    44 #include "btengsecpolicy.h"
       
    45 #include "btengprivatecrkeys.h"
       
    46 #include "btengprivatepskeys.h"
       
    47 #include "btengplugin.h"
       
    48 #include "btengpairman.h"
       
    49 #include "debug.h"
       
    50 
       
    51 /**  Bluetooth Engine server thread name */
       
    52 _LIT( KBTEngThreadName, "BTEngine" );
       
    53 
       
    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;
       
    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 */
       
    81 _LIT_SECURITY_POLICY_C2( KBTEngPSKeyReadPolicy, 
       
    82                           ECapabilityLocalServices, ECapabilityReadDeviceData );
       
    83 _LIT_SECURITY_POLICY_C2( KBTEngPSKeyWritePolicy, 
       
    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 
       
    91 // ======== LOCAL FUNCTIONS ========
       
    92 
       
    93 // ---------------------------------------------------------------------------
       
    94 // Constructs and returns an application object.
       
    95 // ---------------------------------------------------------------------------
       
    96 //
       
    97 void RunServerL()
       
    98     {
       
    99     TRACE_FUNC_ENTRY
       
   100     User::RenameThread( KBTEngThreadName );
       
   101         // Create and install the active scheduler for this thread.
       
   102     CActiveScheduler* scheduler = new( ELeave ) CActiveScheduler();
       
   103     CleanupStack::PushL( scheduler );
       
   104     CActiveScheduler::Install( scheduler );
       
   105         // create the server (leave it on the cleanup stack)
       
   106 	CBTEngServer* btServer = CBTEngServer::NewLC();
       
   107         // Initialisation complete, now signal the client
       
   108     RProcess::Rendezvous( KErrNone );
       
   109         // The server is not up and running.
       
   110     TRACE_INFO( ( _L( "[BTENG]\t BTEng server now up and running" ) ) )
       
   111 	    // The active scheduler runs during the lifetime of this thread.
       
   112     CActiveScheduler::Start();
       
   113         // Cleanup the server and scheduler.
       
   114     CleanupStack::PopAndDestroy( btServer );
       
   115     CleanupStack::PopAndDestroy( scheduler );
       
   116     TRACE_FUNC_EXIT
       
   117     }
       
   118 
       
   119 
       
   120 // ---------------------------------------------------------------------------
       
   121 // Completes the message and panics the client.
       
   122 // ---------------------------------------------------------------------------
       
   123 //
       
   124 void PanicClient( const RMessage2& aMessage, TInt aPanic )
       
   125     {
       
   126     TRACE_INFO( ( _L( "[BTENG]\t PanicClient: Reason %d" ), aPanic ) )
       
   127     aMessage.Panic( KBTEngPanic, aPanic );
       
   128     }
       
   129 
       
   130 
       
   131 // ---------------------------------------------------------------------------
       
   132 // Panic the server.
       
   133 // ---------------------------------------------------------------------------
       
   134 //
       
   135 void PanicServer( TInt aPanic )
       
   136     {
       
   137     TRACE_INFO( ( _L( "[BTENG]\t PanicClient: Reason %d" ), aPanic ) )
       
   138     User::Panic( KBTEngPanic, aPanic );
       
   139     }
       
   140 
       
   141 
       
   142 // ======== MEMBER FUNCTIONS ========
       
   143 
       
   144 // ---------------------------------------------------------------------------
       
   145 // C++ default constructor
       
   146 // (Priority is not as high as in prev. architecture, but should be enough)
       
   147 // ---------------------------------------------------------------------------
       
   148 //
       
   149 CBTEngServer::CBTEngServer()
       
   150 :   CPolicyServer( EPriorityHigh, KBTEngServerPolicy )
       
   151     {
       
   152     iEnableDutMode = EFalse;
       
   153     }
       
   154 
       
   155 
       
   156 // ---------------------------------------------------------------------------
       
   157 // Symbian 2nd-phase constructor
       
   158 // ---------------------------------------------------------------------------
       
   159 //
       
   160 void CBTEngServer::ConstructL()
       
   161     {
       
   162     TRACE_FUNC_ENTRY
       
   163         // No need to check _BT flag here, as the server can 
       
   164         // only be started by BTEng components.
       
   165 
       
   166         // Add the server to the active scheduler (from CServer2):
       
   167     StartL( KBTEngServerName );
       
   168     User::LeaveIfError( RProperty::Define( KPSUidBluetoothTestingMode, KBTDutEnabled, 
       
   169                                             RProperty::EInt, KBTEngPSKeyReadPolicy, 
       
   170                                             KBTEngPSKeyWritePolicy ) );
       
   171     User::LeaveIfError( RProperty::Define( KPSUidBluetoothTestingMode, KBTSspDebugmode, 
       
   172                                             RProperty::EInt, KBTEngPSKeyReadPolicy, 
       
   173                                             KBTEngPSKeyWritePolicy ) );
       
   174     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory, 
       
   175                                             KBTBlockDevAddr, RProperty::EText, 
       
   176                                             KBTEngPSKeyReadPolicy, 
       
   177                                             KBTEngPSKeyWritePolicy ) );
       
   178     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory,
       
   179                                             KBTOutgoingPairing,
       
   180                                             RProperty::EByteArray,
       
   181                                             KBTEngPSKeyReadPolicy,
       
   182                                             KBTEngPSKeyWritePolicy) );
       
   183     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory,
       
   184                                             KBTConnectionTimeStamp,
       
   185                                             RProperty::EByteArray,
       
   186                                             KBTEngPSKeyReadPolicy,
       
   187                                             KBTEngPSKeyWritePolicy) );
       
   188     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory,
       
   189                                             KBTTurnBTOffQueryOn,
       
   190                                             RProperty::EInt,
       
   191                                             KBTEngPSKeyReadPolicy,
       
   192                                             KBTEngPSKeyWritePolicy) );
       
   193     
       
   194     User::LeaveIfError( RProperty::Define( KPSUidBluetoothEnginePrivateCategory,
       
   195                                             KBTNotifierLocks,
       
   196                                             RProperty::EByteArray,
       
   197                                             KBTEngPSKeyReadPolicy,
       
   198                                             KBTEngPSKeyWritePolicy) );    
       
   199     
       
   200     User::LeaveIfError( iSocketServ.Connect() );
       
   201     LoadBTPowerManagerL();
       
   202         // 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 
       
   204         // usually immediately.
       
   205     iServerState = CBTEngSrvState::NewL( this );
       
   206     iWatcher = CBTEngSrvKeyWatcher::NewL( this );
       
   207     iPluginMgr = CBTEngSrvPluginMgr::NewL( this );
       
   208     iBBConnMgr = CBTEngSrvBBConnMgr::NewL( iSocketServ );
       
   209     
       
   210     User::LeaveIfError( iBTRegServ.Connect() );
       
   211     iPairMan = CBTEngPairMan::NewL( *this );
       
   212     
       
   213     TCallBack idleCb( IdleTimerCallBack, this );
       
   214     iIdleCallBack.Set( idleCb );
       
   215     TCallBack sspCb( DebugModeTimerCallBack, this );
       
   216     iDebugModeCallBack.Set( sspCb );
       
   217     TCallBack scanModeCb( ScanModeTimerCallBack, this );
       
   218     iScanModeCallBack.Set( scanModeCb );
       
   219     TCallBack powerOffCb( AutoPowerOffCallBack, this );
       
   220     iPowerOffCallBack.Set( powerOffCb );
       
   221     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
       
   231     }
       
   232 
       
   233 
       
   234 // ---------------------------------------------------------------------------
       
   235 // NewL
       
   236 // ---------------------------------------------------------------------------
       
   237 //
       
   238 CBTEngServer* CBTEngServer::NewLC()
       
   239     {
       
   240     CBTEngServer* self = new( ELeave ) CBTEngServer();
       
   241     CleanupStack::PushL( self );
       
   242     self->ConstructL();
       
   243     return self;
       
   244     }
       
   245 
       
   246 
       
   247 // ---------------------------------------------------------------------------
       
   248 // Destructor
       
   249 // ---------------------------------------------------------------------------
       
   250 //
       
   251 CBTEngServer::~CBTEngServer()
       
   252     {
       
   253     TRACE_FUNC_ENTRY
       
   254     if( iTimer )
       
   255         {
       
   256         iTimerQueued = ENone;
       
   257         iTimer->Remove( iScanModeCallBack );
       
   258         iTimer->Remove( iPowerOffCallBack );
       
   259         iTimer->Remove( iIdleCallBack);
       
   260         iTimer->Remove( iDebugModeCallBack );
       
   261         }
       
   262     RProperty::Delete( KPSUidBluetoothTestingMode, KBTDutEnabled );
       
   263     RProperty::Delete( KPSUidBluetoothTestingMode, KBTSspDebugmode );
       
   264     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTBlockDevAddr );
       
   265     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTOutgoingPairing );
       
   266     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTConnectionTimeStamp );
       
   267     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTTurnBTOffQueryOn );
       
   268     RProperty::Delete( KPSUidBluetoothEnginePrivateCategory, KBTNotifierLocks );
       
   269     delete iTimer;
       
   270     delete iSdpDbHandler;
       
   271     delete iWatcher;
       
   272     delete iPluginMgr;
       
   273     delete iBBConnMgr;
       
   274     delete iServerState;
       
   275     delete iPairMan;
       
   276     iPowerMgr.Close();
       
   277     iSocketServ.Close();
       
   278     iBTRegServ.Close();
       
   279     }
       
   280 
       
   281 
       
   282 // ---------------------------------------------------------------------------
       
   283 // Turn BT on or off.
       
   284 // ---------------------------------------------------------------------------
       
   285 //
       
   286 void CBTEngServer::SetPowerStateL( TBTPowerStateValue aState, TBool aTemporary )
       
   287     {
       
   288     TRACE_FUNC_ARG( ( _L( "setting power state %d" ), (TInt) aState ) )
       
   289     if ( aState == EBTPowerOn && iEnterpriseEnablementMode == BluetoothFeatures::EDisabled )
       
   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
       
   333     }
       
   334 
       
   335 
       
   336 // ---------------------------------------------------------------------------
       
   337 // ?implementation_description
       
   338 // ---------------------------------------------------------------------------
       
   339 //
       
   340 void CBTEngServer::SetVisibilityModeL( TBTVisibilityMode aMode, TInt aTime )
       
   341     {
       
   342     TRACE_FUNC_ENTRY
       
   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
       
   438     }
       
   439 
       
   440 // ---------------------------------------------------------------------------
       
   441 // ?implementation_description
       
   442 // ---------------------------------------------------------------------------
       
   443 //
       
   444 void CBTEngServer::DisconnectAllL()
       
   445     {
       
   446     TRACE_FUNC_ENTRY
       
   447     iPluginMgr->DisconnectAllPlugins();
       
   448     TCallBack cb( DisconnectAllCallBack, this );
       
   449     iBBConnMgr->DisconnectAllLinksL( cb );
       
   450     }
       
   451 
       
   452 
       
   453 // ---------------------------------------------------------------------------
       
   454 // ?implementation_description
       
   455 // ---------------------------------------------------------------------------
       
   456 //
       
   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()
       
   535     {
       
   536         // Check if we are powering off. Otherwise we have just been 
       
   537         // requested to disconnect all, e.g. for system shutdown.
       
   538     if( iServerState->CurrentOperation() == CBTEngSrvState::EPowerOff )
       
   539         {
       
   540         (void) SetPowerState( EFalse );
       
   541             // Put the state machine into idle state.
       
   542         iServerState->ChangeState();
       
   543         }
       
   544     }
       
   545 
       
   546 
       
   547 // ---------------------------------------------------------------------------
       
   548 // ?implementation_description
       
   549 // ---------------------------------------------------------------------------
       
   550 //
       
   551 void CBTEngServer::DispatchPluginMessageL( const RMessage2& aMessage )
       
   552     {
       
   553     iPluginMgr->ProcessCommandL( aMessage );
       
   554     }
       
   555 
       
   556 
       
   557 // ---------------------------------------------------------------------------
       
   558 // A new session has been added, update the session count.
       
   559 // ---------------------------------------------------------------------------
       
   560 //
       
   561 void CBTEngServer::AddSession()
       
   562     {
       
   563     iSessionCount++;
       
   564         // Remove the idle timer.
       
   565     iTimerQueued &= ~EIdleTimer;
       
   566     iTimer->Remove( iIdleCallBack );
       
   567     }
       
   568 
       
   569 
       
   570 // ---------------------------------------------------------------------------
       
   571 // A session has been ended, update the session count.
       
   572 // ---------------------------------------------------------------------------
       
   573 //
       
   574 void CBTEngServer::RemoveSession( TBool aAutoOff )
       
   575     {
       
   576 	TRACE_FUNC_ENTRY
       
   577 	TRACE_INFO( ( _L( "[CBTEngServer]\t aAutoOff %d"), aAutoOff ))
       
   578 	TRACE_INFO( ( _L( "[CBTEngServer]\t iSessionCount %d"), iSessionCount ))
       
   579     iSessionCount--;
       
   580     if( aAutoOff )
       
   581         {
       
   582         TRAP_IGNORE( SetPowerStateL( EBTPowerOff, ETrue ) );
       
   583         }
       
   584     else
       
   585         {
       
   586         CheckIdle();
       
   587         }
       
   588 	TRACE_FUNC_EXIT
       
   589     }
       
   590 
       
   591 
       
   592 // ---------------------------------------------------------------------------
       
   593 // From class CPolicyServer.
       
   594 // Checks version compatibility and constructs a new session object.
       
   595 // ---------------------------------------------------------------------------
       
   596 //
       
   597 CSession2* CBTEngServer::NewSessionL( const TVersion& aVersion, 
       
   598     const RMessage2& aMessage ) const
       
   599     {
       
   600     TRACE_FUNC_ENTRY
       
   601     (void) aMessage;
       
   602     // Compare our version with client-side version, CServer2 requires that 
       
   603     // we leave if they are not compatible. 
       
   604     // Compatible is interpreted here as equal or greater than our version.
       
   605     TVersion srvVersion( KBTEngServerVersionMajor, KBTEngServerVersionMinor, 
       
   606                           KBTEngServerVersionBuild );
       
   607 
       
   608     if( !User::QueryVersionSupported( aVersion, srvVersion ) )
       
   609         {
       
   610         // EFalse is returned if our version is not less than or 
       
   611         // equal to the client version.
       
   612         User::Leave( KErrNotSupported );
       
   613         }
       
   614     return CBTEngSrvSession::NewL();
       
   615     }
       
   616 
       
   617 
       
   618 // ---------------------------------------------------------------------------
       
   619 // ?implementation_description
       
   620 // ---------------------------------------------------------------------------
       
   621 //
       
   622 void CBTEngServer::CheckIdle()
       
   623     {
       
   624     TRACE_FUNC_ENTRY
       
   625     __ASSERT_DEBUG( iTimer, PanicServer( EBTEngPanicMemberVarIsNull ) );
       
   626     iTimerQueued &= ~EIdleTimer;
       
   627     iTimer->Remove( iIdleCallBack );
       
   628     if( iSessionCount <= 0 )
       
   629         {
       
   630             // No more sessions, check the power state.
       
   631         TBTPowerStateValue pwr = EBTPowerOff;
       
   632         TInt err = GetHwPowerState( pwr );
       
   633         TRACE_INFO( ( _L( "[BTEng]\t No sessions; power state: %d" ), pwr ) )
       
   634         if( !err &&!pwr 
       
   635             && iServerState->CurrentOperation() == CBTEngSrvState::ESrvOpIdle )
       
   636             {
       
   637             TRACE_INFO( ( _L( "[BTEng]\t Power off; starting shutdown timer" ) ) )
       
   638                 // power is off, start the shutdown timer.
       
   639             TTimeIntervalMicroSeconds32 interval = KBTEngSrvIdleTimeout;
       
   640             iTimer->Queue( interval, iIdleCallBack );
       
   641             iTimerQueued |= EIdleTimer;
       
   642             }
       
   643         }
       
   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     }
       
   898 
       
   899 
       
   900 // ---------------------------------------------------------------------------
       
   901 // ?implementation_description
       
   902 // ---------------------------------------------------------------------------
       
   903 //
       
   904 void CBTEngServer::ManageDIServiceL( TBool aState )
       
   905     {
       
   906     TRACE_FUNC_ENTRY
       
   907         // The session with the SDP database is kept open during the 
       
   908         // lifetime of BTEng server. This ensures that the database server 
       
   909         // will not destroy itself (and the SDP record) when there are no 
       
   910         // sessions anymore (which it would do). This also ensures that other 
       
   911         // sessions (of BT Engine Discovery API) can be closed without the SDP
       
   912         // database being destroyed, and so saving memory.
       
   913     TInt err = KErrNone;
       
   914     if( !iSdpDbHandler )
       
   915         {
       
   916         iSdpDbHandler = CBTEngSdpDbHandler::NewL();
       
   917         }
       
   918     if( aState && !iDiSdpRecHandle )
       
   919         {
       
   920             // Use TRAP here, because the function will leave if 
       
   921             // the required CenRep keys are not available.
       
   922         TInt vendorId = 0;
       
   923         TInt productId = 0;
       
   924         TRAP( err, GetProductIdsL( vendorId, productId ) );
       
   925 #ifdef  __WINS__
       
   926         err = KErrNone; // Ignore error and load with S60 RnD default values.
       
   927 #endif  //__WINS__
       
   928         if( !err )
       
   929             {
       
   930             TUUID uuid( EBTProfileDI );
       
   931             iSdpDbHandler->RegisterSdpRecordL( uuid, vendorId, productId, 
       
   932                                                 iDiSdpRecHandle );
       
   933             }
       
   934         }
       
   935     if( ( !aState || err ) && iDiSdpRecHandle )
       
   936         {
       
   937             // Either we are shutting down, or we did not manage 
       
   938             // to fill the record with required data -> delete it.
       
   939         iSdpDbHandler->DeleteSdpRecordL( iDiSdpRecHandle );
       
   940         iDiSdpRecHandle = 0;
       
   941         delete iSdpDbHandler;
       
   942         iSdpDbHandler = NULL;
       
   943         }
       
   944     User::LeaveIfError( err );  // To pass back the result of the operation.
       
   945     TRACE_FUNC_EXIT
       
   946     }
       
   947 
       
   948 
       
   949 // ---------------------------------------------------------------------------
       
   950 // ?implementation_description
       
   951 // ---------------------------------------------------------------------------
       
   952 //
       
   953 void CBTEngServer::GetProductIdsL( TInt& aVendorId, TInt& aProductId )
       
   954     {
       
   955     TRACE_FUNC_ENTRY
       
   956     CRepository* cenRep = CRepository::NewLC( KCRUidBluetoothEngine );
       
   957     User::LeaveIfError( cenRep->Get( KBTVendorID, aVendorId ) );
       
   958     User::LeaveIfError( cenRep->Get( KBTProductID, aProductId ) );
       
   959     CleanupStack::PopAndDestroy( cenRep );  //cenRep
       
   960     }
       
   961 
       
   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 
       
  1310 // ---------------------------------------------------------------------------
       
  1311 // Ask plugin manager the connection status of the specified device
       
  1312 // ---------------------------------------------------------------------------
       
  1313 //
       
  1314 TBTEngConnectionStatus CBTEngServer::IsDeviceConnected( const TBTDevAddr& aAddr )
       
  1315     {
       
  1316     TBTEngConnectionStatus status = EBTEngNotConnected;
       
  1317     if ( iPluginMgr )
       
  1318         {
       
  1319         status = iPluginMgr->IsDeviceConnected( aAddr );
       
  1320         }
       
  1321     return status;
       
  1322     }
       
  1323 
       
  1324 // ---------------------------------------------------------------------------
       
  1325 // Static callback for temporary visibility mode.
       
  1326 // ---------------------------------------------------------------------------
       
  1327 //
       
  1328 TInt CBTEngServer::ScanModeTimerCallBack( TAny* aPtr )
       
  1329     {
       
  1330     __ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
       
  1331     TRAPD( err, ( (CBTEngServer*) aPtr )->ScanModeTimerCompletedL() );
       
  1332     return err;
       
  1333     }
       
  1334 
       
  1335 // ---------------------------------------------------------------------------
       
  1336 // Static callback for disconnecting all Baseband connections.
       
  1337 // ---------------------------------------------------------------------------
       
  1338 //
       
  1339 TInt CBTEngServer::DisconnectAllCallBack( TAny* aPtr )
       
  1340     {
       
  1341     __ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
       
  1342     ( (CBTEngServer*) aPtr )->DisconnectAllCompleted();
       
  1343     return KErrNone;
       
  1344     }
       
  1345 
       
  1346 
       
  1347 // ---------------------------------------------------------------------------
       
  1348 // Static callback for idle timer timeout. We are shutting down ourselves.
       
  1349 // ---------------------------------------------------------------------------
       
  1350 //
       
  1351 TInt CBTEngServer::IdleTimerCallBack( TAny* aPtr )
       
  1352     {
       
  1353     (void) aPtr;
       
  1354     CActiveScheduler::Stop();   // Will destroy CBTEngServer
       
  1355     return KErrNone;
       
  1356     }
       
  1357 
       
  1358 // ---------------------------------------------------------------------------
       
  1359 // 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.
       
  1361 // ---------------------------------------------------------------------------
       
  1362 //
       
  1363 TInt CBTEngServer::DebugModeTimerCallBack( TAny* aPtr )
       
  1364     {
       
  1365     // Set our internal debug mode key to off. Ignore error, not critical here.
       
  1366     (void) RProperty::Set( KPSUidBluetoothTestingMode, KBTSspDebugmode, EFalse );
       
  1367     
       
  1368     __ASSERT_ALWAYS(aPtr, PanicServer(EBTEngPanicArgumentIsNull) );
       
  1369     
       
  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;
       
  1385     server->iTimerQueued &= ~EAutoPowerOffTimer;
       
  1386     TRAPD( err, server->CheckAutoPowerOffL() );
       
  1387     return err;
       
  1388     }
       
  1389 
       
  1390 BluetoothFeatures::TEnterpriseEnablementMode CBTEngServer::EnterpriseEnablementMode() const
       
  1391     {
       
  1392     return iEnterpriseEnablementMode;
       
  1393     }
       
  1394 
       
  1395 // ======== GLOBAL FUNCTIONS ========
       
  1396 
       
  1397 // ---------------------------------------------------------------------------
       
  1398 // Main function of the executable.
       
  1399 // ---------------------------------------------------------------------------
       
  1400 //
       
  1401 GLDEF_C TInt E32Main()
       
  1402     {
       
  1403     __UHEAP_MARK;
       
  1404     TRACE_FUNC_ENTRY
       
  1405     CTrapCleanup* cleanup = CTrapCleanup::New();
       
  1406     TInt err = KErrNoMemory;
       
  1407     if ( cleanup )
       
  1408         {
       
  1409         TRAP( err, RunServerL() );
       
  1410         delete cleanup;
       
  1411         }
       
  1412     __UHEAP_MARKEND;
       
  1413     return err;
       
  1414     }