bluetoothengine/bteng/src/btengsrvkeywatcher.cpp
changeset 0 f63038272f30
child 8 0707dd69d236
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/bteng/src/btengsrvkeywatcher.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,559 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Watcher for BTEng server PubSub and CenRep keys.
+*
+*/
+
+
+
+#include <startupdomainpskeys.h>
+#include <coreapplicationuisdomainpskeys.h>
+#include <ctsydomainpskeys.h>
+#include <centralrepository.h>
+#include <bt_subscribe.h>
+
+#include "btengsrvkeywatcher.h"
+#include "btengserver.h"
+#include "btengsrvpluginmgr.h"
+#include "btengprivatepskeys.h"
+#include "btengprivatecrkeys.h"
+#include "debug.h"
+
+/**  Identification for active object */
+const TInt KBTEngDutWatcher = 15;
+/**  Identification for active object */
+const TInt KBTEngLockWatcher = 16;
+/**  Identification for active object */
+const TInt KBTEngSysWatcher = 17;
+/**  Identification for active object */
+const TInt KBTEngPHYCountWatcher = 18;
+/**  Identification for active object */
+const TInt KBTEngBtConnectionWatcher = 19;
+/**  Identification for active object */
+const TInt KBTEngScanningWatcher = 20;
+/**  Identification for active object */
+const TInt KBTEngEmergencyWatcher = 21;
+/**  Identification for active object */
+const TInt KBTEngSapWatcher = 22;
+/**  Identification for active object */
+const TInt KBTEngAddrWatcher = 23;
+/**  Identification for active object */
+const TInt KBTEngRegistryWatcher = 24;
+/**  Identification for active object */
+const TInt KBTEngSspDebugWatcher = 25;
+/**  Buffer size for BT device address as stored in CenRep */
+const TInt KCenRepAddrBufSize = 2 * KBTDevAddrSize;
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// C++ default constructor
+// ---------------------------------------------------------------------------
+//
+CBTEngSrvKeyWatcher::CBTEngSrvKeyWatcher( CBTEngServer* aServer )
+:   iServer( aServer )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd-phase constructor
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvKeyWatcher::ConstructL()
+    {
+    TRACE_FUNC_ENTRY
+    TInt err = iDutModeKey.Attach( KPSUidBluetoothTestingMode, KBTDutEnabled );
+    if( !err )
+        {
+        iDutModeWatcher = CBTEngActive::NewL( *this, KBTEngDutWatcher, 
+                                               CActive::EPriorityStandard );
+        iDutModeKey.Subscribe( iDutModeWatcher->RequestStatus() );
+        iDutModeWatcher->GoActive();
+        }
+#ifdef RD_REMOTELOCK
+    err = iPhoneLockKey.Attach( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus );
+    if( !err )
+        {
+        iPhoneLockWatcher = CBTEngActive::NewL( *this, KBTEngLockWatcher, 
+                                                 CActive::EPriorityStandard );
+        iPhoneLockKey.Subscribe( iPhoneLockWatcher->RequestStatus() );
+        iPhoneLockWatcher->GoActive();
+        }
+#endif  //RD_REMOTELOCK
+
+    err = iSystemStateKey.Attach( KPSUidStartup, KPSGlobalSystemState );
+    if( !err )
+        {
+        iSystemStateWatcher = CBTEngActive::NewL( *this, KBTEngSysWatcher, 
+                                                   CActive::EPriorityStandard );
+        iSystemStateKey.Subscribe( iSystemStateWatcher->RequestStatus() );
+        iSystemStateWatcher->GoActive();
+        }
+        
+    err = iPHYCountKey.Attach( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothPHYCount );
+    if( !err )
+        {
+        iPHYCountWatcher = CBTEngActive::NewL( *this, KBTEngPHYCountWatcher, 
+                                               CActive::EPriorityStandard );
+        iPHYCountKey.Subscribe( iPHYCountWatcher->RequestStatus() );
+        iPHYCountWatcher->GoActive();
+        }
+        
+    err = iBtConnectionKey.Attach( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothConnecting );
+    if( !err )
+        {
+        iBtConnectionWatcher = CBTEngActive::NewL( *this, KBTEngBtConnectionWatcher, 
+                                               CActive::EPriorityStandard );
+        iBtConnectionKey.Subscribe( iBtConnectionWatcher->RequestStatus() );
+        iBtConnectionWatcher->GoActive();
+        }
+
+    err = iBtScanningKey.Attach( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothSetScanningStatus );
+    if( !err )
+        {
+        iBtScanningWatcher = CBTEngActive::NewL( *this, KBTEngScanningWatcher, 
+                                               CActive::EPriorityStandard );
+        iBtScanningKey.Subscribe( iBtScanningWatcher->RequestStatus() );
+        iBtScanningWatcher->GoActive();
+        }
+
+    err = iEmergencyCallKey.Attach( KPSUidCtsyEmergencyCallInfo, KCTSYEmergencyCallInfo );
+    if( !err )
+        {
+        iEmergencyCallWatcher = CBTEngActive::NewL( *this, KBTEngEmergencyWatcher, 
+                                                   CActive::EPriorityStandard );
+        iEmergencyCallKey.Subscribe( iEmergencyCallWatcher->RequestStatus() );
+        iEmergencyCallWatcher->GoActive();
+        }
+
+    err = iBtRegistryKey.Attach( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothGetRegistryTableChange );
+    if( !err )
+        {
+        iBtRegistryWatcher = CBTEngActive::NewL( *this, KBTEngRegistryWatcher, 
+                                                 CActive::EPriorityStandard );
+        iBtRegistryKey.Subscribe( iBtRegistryWatcher->RequestStatus() );
+        iBtRegistryWatcher->GoActive();
+        }
+
+    err = iSspDebugModeKey.Attach( KPSUidBluetoothTestingMode, KBTSspDebugmode );
+    if( !err )
+        {
+        iSspDebugModeWatcher = CBTEngActive::NewL( *this, KBTEngSspDebugWatcher, 
+                                                    CActive::EPriorityStandard );
+        iSspDebugModeKey.Subscribe( iSspDebugModeWatcher->RequestStatus() );
+        iSspDebugModeWatcher->GoActive();
+        }
+
+        // Use TRAP here, because it leaves if the key does not exist.
+    TRAP( err, iSapKeyCenRep = CRepository::NewL( KCRUidBTEngPrivateSettings ) );
+    if( !err )
+        {
+        iSapModeWatcher = CBTEngActive::NewL( *this, KBTEngSapWatcher, 
+                                                     CActive::EPriorityStandard );
+        err = iSapKeyCenRep->NotifyRequest( KBTSapEnabled, 
+                                             iSapModeWatcher->RequestStatus() );
+        }
+    if( !err )
+        {
+        iSapModeWatcher->GoActive();
+        }
+    err = iBdaddrKey.Attach( KPropertyUidBluetoothCategory, 
+                              KPropertyKeyBluetoothGetLocalDeviceAddress );
+                              
+    if( !err )
+        {
+        CheckBDAddrL();
+        }
+    TRACE_FUNC_EXIT
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CBTEngSrvKeyWatcher* CBTEngSrvKeyWatcher::NewL( CBTEngServer* aServer )
+    {
+    CBTEngSrvKeyWatcher* self = new( ELeave ) CBTEngSrvKeyWatcher( aServer );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CBTEngSrvKeyWatcher::~CBTEngSrvKeyWatcher()
+    {
+    if( iDutModeKey.Handle() )
+        {
+        iDutModeKey.Cancel();
+        }
+    delete iDutModeWatcher;
+    iDutModeKey.Close();
+
+#ifdef RD_REMOTELOCK
+    if( iPhoneLockKey.Handle() )
+        {
+        iPhoneLockKey.Cancel();
+        }
+    delete iPhoneLockWatcher;
+    iPhoneLockKey.Close();
+#endif  //RD_REMOTELOCK
+
+    if( iSystemStateKey.Handle() )
+        {
+        iSystemStateKey.Cancel();
+        }
+    delete iSystemStateWatcher;
+    iSystemStateKey.Close();
+    
+    if( iPHYCountKey.Handle() )
+        {
+        iPHYCountKey.Cancel();
+        }
+    delete iPHYCountWatcher;
+    iPHYCountKey.Close();
+     
+    if( iBtConnectionKey.Handle() )
+        {
+        iBtConnectionKey.Cancel();
+        }
+    delete iBtConnectionWatcher;
+    iBtConnectionKey.Close();
+    
+    if( iBtScanningKey.Handle() )
+        {
+        iBtScanningKey.Cancel();
+        }
+    delete iBtScanningWatcher;
+    iBtScanningKey.Close();
+
+    if( iEmergencyCallKey.Handle() )
+        {
+        iEmergencyCallKey.Cancel();
+        }
+    delete iEmergencyCallWatcher;
+    iEmergencyCallKey.Close();
+    
+    if( iSspDebugModeKey.Handle() )
+        {
+        iSspDebugModeKey.Cancel();
+        }
+    delete iSspDebugModeWatcher;
+    iSspDebugModeKey.Close();
+
+    if( iBtRegistryKey.Handle() )
+    	{
+    	iBtRegistryKey.Cancel();
+    	}
+    delete iBtRegistryWatcher;
+    iBtRegistryKey.Close();
+
+    if( iSapKeyCenRep )
+        {
+        iSapKeyCenRep->NotifyCancel( KBTSapEnabled );
+        }
+    delete iSapModeWatcher;
+    delete iSapKeyCenRep;
+
+    if( iBdaddrKey.Handle() )
+        {
+        iBdaddrKey.Cancel();
+        }
+    delete iBdaddrWatcher;
+    iBdaddrKey.Close();
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class MBTEngActiveObserver.
+// Processes a changed key value.
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvKeyWatcher::RequestCompletedL( CBTEngActive* aActive, TInt aId, 
+    TInt aStatus )
+    {
+    TRACE_FUNC_ARG( ( _L( "status %d" ), aStatus ) )
+    ASSERT( aStatus != KErrPermissionDenied );
+    TInt val = 0;
+    switch( aId )
+        {
+        case KBTEngDutWatcher:
+            {
+            TRACE_INFO( ( _L( "DUT mode key changed" ) ) )
+            iDutModeKey.Subscribe( aActive->RequestStatus() );
+            aActive->GoActive();
+            if( !aStatus && !iDutModeKey.Get( val ) )
+                {
+                iServer->SetDutMode( val );
+                }
+            }
+            break;
+        case KBTEngLockWatcher:
+            {
+            TRACE_INFO( ( _L( "phone lock key changed" ) ) )
+#ifdef RD_REMOTELOCK
+            iPhoneLockKey.Subscribe( aActive->RequestStatus() );
+            aActive->GoActive();
+            TInt remoteLockVal = 0;
+            remoteLockVal = ERemoteLocked;
+            if( !aStatus && !iPhoneLockKey.Get( val ) && val == remoteLockVal )
+                {
+                iServer->SetPowerStateL( EBTPowerOff, EFalse );
+                }
+#endif  //RD_REMOTELOCK
+            }
+            break;
+        case KBTEngSysWatcher:
+            {
+            TRACE_INFO( ( _L( "System state key changed" ) ) )
+            iSystemStateKey.Subscribe( aActive->RequestStatus() );
+            aActive->GoActive();
+            if( !aStatus && !iSystemStateKey.Get( val ) && 
+                 val == ESwStateShuttingDown )
+                {
+                iServer->SetVisibilityModeL( EBTVisibilityModeNoScans , 0 );
+                iServer->DisconnectAllL();   
+                }
+            }
+            break;   
+        case KBTEngPHYCountWatcher:
+            {
+            TRACE_INFO( ( _L( "PHY count key changed" ) ) )
+            iPHYCountKey.Subscribe( aActive->RequestStatus() );
+            aActive->GoActive();
+            iServer->SetUiIndicatorsL();
+            }
+            break;
+        case KBTEngBtConnectionWatcher:
+            {
+            TRACE_INFO( ( _L( "BT connection key changed" ) ) )
+            iBtConnectionKey.Subscribe( aActive->RequestStatus() );
+            aActive->GoActive();
+            iServer->SetUiIndicatorsL();
+            }
+            break;        
+        case KBTEngScanningWatcher:
+            {
+            TRACE_INFO( ( _L( "BT stack scanning key changed" ) ) )
+            iBtScanningKey.Subscribe( aActive->RequestStatus() );
+            aActive->GoActive();
+            if ( !iBtScanningKey.Get( val ) )
+                {
+                iServer->UpdateVisibilityModeL( val );
+                }
+            }
+            break;
+        case KBTEngEmergencyWatcher:
+            {
+            TRACE_INFO( ( _L( "Emergency call key changed" ) ) )
+            iEmergencyCallKey.Subscribe( aActive->RequestStatus() );
+            aActive->GoActive();
+            if( !aStatus && !iEmergencyCallKey.Get( val ) && val )
+                {
+                // An emergency call initiated -> Close SAP connection if it's active
+                iServer->iPluginMgr->DisconnectProfile( EBTProfileSAP );
+                }
+            }
+            break;
+        case KBTEngSspDebugWatcher:
+            {
+            TRACE_INFO( ( _L( "Simple pairing debug mode key changed" ) ) )
+            iSspDebugModeKey.Subscribe( aActive->RequestStatus() );
+            aActive->GoActive();
+            if( !aStatus && !iSspDebugModeKey.Get( val ) )
+                {
+                iServer->CheckSspDebugModeL( (TBool) val );
+                }
+            break;
+            }
+        case KBTEngRegistryWatcher:
+        	{
+            TRACE_INFO( ( _L( "BT Registry key changed" ) ) )
+            TInt myChangedTable;
+
+			iBtRegistryKey.Subscribe( aActive->RequestStatus() );
+			aActive->GoActive();
+
+            TInt err = iBtRegistryKey.Get( myChangedTable );
+            if( !err && myChangedTable == KRegistryChangeRemoteTable )
+            	{
+            	TRACE_INFO( ( _L("BT Remote registry key changed") ) )
+            	iServer->RemoteRegistryChangeDetected();            	
+            	}
+        	break;
+        	}    
+        case KBTEngSapWatcher:
+            {
+            TRACE_INFO( ( _L( "SAP mode key changed" ) ) )
+            iSapKeyCenRep->NotifyRequest( KBTSapEnabled, aActive->RequestStatus() );
+            aActive->GoActive();
+            iSapKeyCenRep->Get( KBTSapEnabled, val );
+            
+            TBTPowerStateValue powerState = EBTPowerOff;
+            User::LeaveIfError( iServer->GetHwPowerState( (TBTPowerStateValue&) powerState ) );
+            if( aStatus >= 0 && powerState )
+                {
+                // Relevant only if BT is on
+                if( val == EBTSapEnabled )
+                    {
+                    iServer->iPluginMgr->LoadBTSapPluginL();
+                    }
+                else
+                    {
+                    iServer->iPluginMgr->UnloadBTSapPlugin();
+                    }
+                }
+            }
+            break;
+        case KBTEngAddrWatcher:
+            {
+            TBuf8<KBTDevAddrSize> addrPubSub;
+			iBdaddrKey.Subscribe( aActive->RequestStatus() );
+			aActive->GoActive();
+
+            if( !aStatus && !iBdaddrKey.Get( addrPubSub ) && 
+                 addrPubSub.Length() == KBTDevAddrSize )
+                {
+				iBdaddrKey.Cancel();
+
+                TBTDevAddr addr( addrPubSub );
+                TBuf<KCenRepAddrBufSize> addrCenRep;
+                addr.GetReadable( addrCenRep );
+                    // Write the key to CenRep and stop listening.
+                CRepository* cenRep = CRepository::NewL( 
+                                            KCRUidBluetoothLocalDeviceAddress );
+                cenRep->Set( KBTLocalDeviceAddress, addrCenRep );
+                if ( iBdaddrWatcher )
+                    {
+                    delete iBdaddrWatcher;
+                    iBdaddrWatcher = NULL;
+                    }
+                iBdaddrKey.Close();
+                }
+            }
+            break;
+        default:
+            {
+            TRACE_INFO( ( _L( "[BTENG]\t wrong key notification! id=%d" ), aId ) )
+            }
+            break;
+
+        }
+    TRACE_FUNC_EXIT
+    }
+
+
+// ---------------------------------------------------------------------------
+// From class MBTEngActiveObserver.
+// Handles a leave in RunL/RequestCompletedL by checking that all 
+// the subscriptions are active.
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvKeyWatcher::HandleError( CBTEngActive* aActive, TInt aId, 
+    TInt aError )
+    {
+    TRACE_FUNC_ARG( ( _L( "status %d" ), aError ) )
+    (void) aError;
+    if( !aActive->IsActive() )
+        {
+        switch( aId )
+            {
+            case KBTEngDutWatcher:
+                {
+                iDutModeKey.Subscribe( aActive->RequestStatus() );
+                }
+                break;
+            case KBTEngLockWatcher:
+                {
+#ifdef RD_REMOTELOCK
+                iPhoneLockKey.Subscribe( aActive->RequestStatus() );
+#else
+                return; // we don't want to go active without subscribing
+#endif  //RD_REMOTELOCK
+                }
+                break;
+            case KBTEngSysWatcher:
+                {
+                iSystemStateKey.Subscribe( aActive->RequestStatus() );
+                }
+                break;
+            case KBTEngSspDebugWatcher:
+                {
+                iSspDebugModeKey.Subscribe( aActive->RequestStatus() );
+                }
+                break;
+            case KBTEngSapWatcher:
+                {
+                iSapKeyCenRep->NotifyRequest( KBTSapEnabled, aActive->RequestStatus() );
+                }
+                break;
+            default:
+                {
+                TRACE_INFO( ( _L( "[BTENG]\t wrong key notification! id=%d" ), aId ) )
+                }
+                return; // we don't want to go active without subscribing
+            }
+        aActive->GoActive();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// Checks if we have already stored the BD_ADDR in CenRep; if not, we get it
+// from PubSub. If not available from PubSub yet, we subscribe to the key.
+// ---------------------------------------------------------------------------
+//
+void CBTEngSrvKeyWatcher::CheckBDAddrL()
+    {
+    TBuf<KCenRepAddrBufSize> addrCenRep;
+    CRepository* cenRep = NULL;
+        // Use TRAP to catch a leave if the CenRep key does not exist.
+    TRAPD( err, cenRep = CRepository::NewL( KCRUidBluetoothLocalDeviceAddress ) );
+    CleanupStack::PushL( cenRep );
+    if( !err )
+        {
+        err = cenRep->Get( KBTLocalDeviceAddress, addrCenRep );
+        }
+    if( err || addrCenRep.Length() != KCenRepAddrBufSize )
+        {
+        TBuf8<KBTDevAddrSize> addrPubSub;
+        err = iBdaddrKey.Get( addrPubSub );
+        if( !err && addrPubSub.Length() == KBTDevAddrSize )
+            {
+            TBTDevAddr addr( addrPubSub );  // For easy conversion
+            addr.GetReadable( addrCenRep );
+            cenRep->Set( KBTLocalDeviceAddress, addrCenRep );
+            iBdaddrKey.Close();
+            }
+        else
+            {
+            iBdaddrWatcher = CBTEngActive::NewL( *this, KBTEngAddrWatcher, 
+                                                        CActive::EPriorityStandard );
+            iBdaddrKey.Subscribe( iBdaddrWatcher->RequestStatus() );
+            iBdaddrWatcher->GoActive();
+            }
+        }
+    else
+        {
+        iBdaddrKey.Close();
+        }
+    CleanupStack::PopAndDestroy( cenRep );
+    }