bluetoothengine/bteng/btengsettings/src/btengsettings.cpp
changeset 0 f63038272f30
child 22 613943a21004
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/bteng/btengsettings/src/btengsettings.cpp	Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,445 @@
+/*
+* 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:  Bluetooth Engine API for managing device settings.
+*
+*/
+
+
+
+#include <centralrepository.h>
+#include <featmgr.h>
+#include <utf.h>
+
+#include "btengsettings.h"
+#include "btengprivatecrkeys.h"
+#include "btengsettingsnotify.h"
+#include "btengclient.h"
+#include "debug.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// C++ default constructor
+// ---------------------------------------------------------------------------
+//
+CBTEngSettings::CBTEngSettings( MBTEngSettingsObserver* aObserver )
+:   iObserver( aObserver )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd-phase constructor
+// ---------------------------------------------------------------------------
+//
+void CBTEngSettings::ConstructL()
+    {
+    TRACE_FUNC_ENTRY
+        // Check if BT is supported at all
+    FeatureManager::InitializeLibL();
+    TBool btSupported = FeatureManager::FeatureSupported( KFeatureIdBt );
+    FeatureManager::UnInitializeLib();
+    if( !btSupported )
+        {
+        TRACE_INFO( ( _L( "[BTENGSETTINGS]\t ConstructL: BT not supported!!" ) ) )
+        User::Leave( KErrNotSupported );
+        }
+    if( iObserver )
+        {
+        iSettingsWatcher = CBTEngSettingsNotify::NewL( iObserver );
+        }
+    TRACE_FUNC_EXIT
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBTEngSettings* CBTEngSettings::NewL( MBTEngSettingsObserver* aObserver )
+    {
+    CBTEngSettings* self = CBTEngSettings::NewLC( aObserver );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// NewLC
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBTEngSettings* CBTEngSettings::NewLC( MBTEngSettingsObserver* aObserver )
+    {
+    CBTEngSettings* self = new( ELeave ) CBTEngSettings( aObserver );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CBTEngSettings::~CBTEngSettings()
+    {
+    TRACE_FUNC_ENTRY
+    delete iSettingsWatcher;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Gets the current BT hardware power state 
+// (on or off) from central repository.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTEngSettings::GetPowerState( TBTPowerStateValue& aState )
+    {
+    TRACE_FUNC_ENTRY
+    aState = EBTPowerOff;
+    TRAPD( err, GetCenRepKeyL( KCRUidBluetoothPowerState, KBTPowerState, 
+                               (TInt&) aState, EBTPowerOff, EBTPowerOn ) );
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Sets the Bluetooth hardware power state.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTEngSettings::SetPowerState( TBTPowerStateValue aState )
+    {
+    TRACE_FUNC_ENTRY
+    if( aState != EBTPowerOff && aState != EBTPowerOn )
+        {
+        return KErrArgument;
+        }
+    RBTEng bteng;
+    TInt err = bteng.Connect();
+    if( !err )
+        {
+        err = bteng.SetPowerState( aState, EFalse );
+        bteng.Close();
+        }
+    TRACE_FUNC_EXIT
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Gets the current Bluetooth hardware visibility mode 
+// (visible or hidden) from central repository.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTEngSettings::GetVisibilityMode( TBTVisibilityMode& aMode )
+    {
+    TRACE_FUNC_ENTRY
+    aMode = EBTVisibilityModeGeneral;
+    TRAPD( err, GetCenRepKeyL( KCRUidBTEngPrivateSettings, KBTDiscoverable, 
+                               (TInt&) aMode, EBTVisibilityModeHidden, 
+                               EBTVisibilityModeGeneral, 
+                               EBTVisibilityModeTemporary, 
+                               EBTVisibilityModeTemporary ) );
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Sets the Bluetooth hardware visibility mode. The visible mode can also 
+// be temporary visible, specified by the aTime parameter (time in seconds).
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTEngSettings::SetVisibilityMode( TBTVisibilityMode aMode, TInt aTime )
+    {
+    TRACE_FUNC_ENTRY
+    if( aMode != EBTVisibilityModeHidden && aMode != EBTVisibilityModeGeneral && 
+        aMode != EBTVisibilityModeTemporary )
+        {
+        return KErrArgument;
+        }
+    RBTEng bteng;
+    TInt err = bteng.Connect();
+    if( !err )
+        {
+        err = bteng.SetVisibilityMode( aMode, aTime );
+        bteng.Close();
+        }
+
+    TRACE_FUNC_EXIT
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Gets the Bluetooth friendly name the Bluetooth stack.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTEngSettings::GetLocalName( TDes& aName )
+    {
+    TRACE_FUNC_ENTRY
+    aName.Zero();
+    TBool nameStatus = EFalse;
+    TBuf<KHCILocalDeviceNameMaxLength> tmpName;
+    
+    TInt err = GetLocalNameModified( nameStatus );
+    
+    if( err || nameStatus == EBTLocalNameDefault )
+        {
+        return err;
+        }
+
+    err = RProperty::Get( KPropertyUidBluetoothCategory, 
+                           KPropertyKeyBluetoothGetDeviceName, aName );
+    if( !err )
+        {
+        err = RProperty::Get( KPropertyUidBluetoothCategory, 
+                               KPropertyKeyBluetoothSetDeviceName, tmpName );
+        if ( tmpName.Compare( aName ) )
+            {
+                // The name has not yet been updated. Use the new one.
+            aName.Copy( tmpName );
+            }
+        }
+        
+    if( err || !aName.Length() )
+        {
+            // An error occured, try still registry
+        aName.Zero();
+        err = HandleBTRegistryNameSetting( const_cast<TDes&>( aName ) );
+        TRACE_INFO( ( _L( "[BTENGSETTINGS]\t registry set result: %d"), err) );
+        }                            
+                                     	        	                               
+    TRACE_INFO( ( _L( "[BTENGSETTINGS]\t GetLocalName - result %d, name: %S" ),
+                        err, &aName ) )
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// Sets the Bluetooth friendly name.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTEngSettings::SetLocalName( const TDes& aName )
+    {
+    TRACE_FUNC_ENTRY
+    TRACE_FUNC_ARG( ( _L( "aName lenght: %d" ), aName.Length() ) )
+    if( aName.Length() == 0 || aName.Length() > KMaxBluetoothNameLen )
+        {
+            // Zero-length name means that the name has not been set;
+            // such reset should not be done through BTEngSettings.
+        return KErrArgument;
+        }
+        
+    TInt err = RProperty::Set( KPropertyUidBluetoothCategory, 
+                           KPropertyKeyBluetoothSetDeviceName, aName );
+    TRACE_INFO( ( _L( "[BTENGSETTINGS]\t RProperty::Set: %d"), err) );
+    
+        // Always update the name to registry
+    TInt err2 = HandleBTRegistryNameSetting( const_cast<TDes&>( aName ) );
+
+    TBool nameChanged = EFalse;
+    if( !err || !err2 )
+        {				       	
+            // Check if this is the first time name setting.
+        err = GetLocalNameModified( nameChanged );
+        TRACE_INFO( ( _L( "[BTENGSETTINGS]\t GetLocalNameModified: err %d, namechanged %d"), 
+        		err, nameChanged) );               	
+        }
+        
+    if( ( !err || !err2 )  && nameChanged == EBTLocalNameDefault )
+        {
+            // Set the name as changed.
+        CRepository* cenRep = NULL;
+        TRAP( err, cenRep = CRepository::NewL( KCRUidBTEngPrivateSettings ) );
+        if( !err )
+            { 
+            err = cenRep->Set( KBTLocalNameChanged, EBTLocalNameSet );
+            TRACE_INFO( ( _L( "[BTENGSETTINGS]\t cenRep->Set( KBTLocalNameChanged, EBTLocalNameSet ): %d"), err) ); 
+            }
+        delete cenRep;
+        }
+        
+    TRACE_FUNC_RES( ( _L( "result %d" ), err ) )
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Sets the Bluetooth hardware power state for temporary connections.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTEngSettings::ChangePowerStateTemporarily()
+    {
+    TRACE_FUNC_ENTRY
+    TInt err = KErrNone;
+    if( !iSettingsWatcher )
+        {
+        TRAP( err, iSettingsWatcher = CBTEngSettingsNotify::NewL( NULL ) );
+        }
+    if( !err )
+        {
+        err = iSettingsWatcher->TogglePowerTemporarily();
+        }
+    TRACE_FUNC_EXIT
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// Get the Bluetooth offline mode settings
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBTEngSettings::GetOfflineModeSettings( 
+        TCoreAppUIsNetworkConnectionAllowed& aOffline, 
+        TBTEnabledInOfflineMode& aOfflineAllowed )
+    {
+    TRACE_FUNC_ENTRY
+    aOffline = ECoreAppUIsNetworkConnectionAllowed;
+    aOfflineAllowed = EBTEnabledInOfflineMode;
+    TRAPD( err, GetCenRepKeyL( KCRUidCoreApplicationUIs, 
+                               KCoreAppUIsNetworkConnectionAllowed, (TInt&) aOffline, 
+                               ECoreAppUIsNetworkConnectionNotAllowed, 
+                               ECoreAppUIsNetworkConnectionAllowed ) );
+    if( !err && aOffline == ECoreAppUIsNetworkConnectionNotAllowed )
+        {
+        TRAP( err, GetCenRepKeyL( KCRUidBluetoothEngine, KBTEnabledInOffline, 
+                                  (TInt&) aOfflineAllowed, EBTDisabledInOfflineMode, 
+                                  EBTEnabledInOfflineMode ) );
+        }
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Checks from central repository whether the Bluetooth friendly name 
+// has been modified .
+// ---------------------------------------------------------------------------
+//
+TInt CBTEngSettings::GetLocalNameModified( TBool& aStatus )
+    {
+    TRACE_FUNC_ENTRY
+
+    aStatus = (TBool) EBTLocalNameDefault;
+    TRAPD( err, GetCenRepKeyL( KCRUidBTEngPrivateSettings, KBTLocalNameChanged, 
+                               (TInt&) aStatus, EBTLocalNameDefault, 
+                               EBTLocalNameSet ) );
+    return err;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Gets the specified CenRep key and checks if it is within a valid range; 
+// if not, it it reset to the default value.
+// ---------------------------------------------------------------------------
+//
+void CBTEngSettings::GetCenRepKeyL( const TUid aUid, const TInt aKey, TInt& aValue, 
+                                    const TInt aMinRange1, const TInt aMaxRange1, 
+                                    const TInt aMinRange2, const TInt aMaxRange2 )
+    {
+    TRACE_FUNC_ARG( ( _L( "aKey: %d" ), aKey ) )
+// [SvV] Test that both logging macro do the same:
+    TRACE_INFO( ( _L( "[BTENGSETTINGS]\t GetCenRepKeyL - start (aKey: %d)" ), aKey ) )
+    TInt val = aValue;
+
+    CRepository* cenRep = CRepository::NewL( aUid );
+    TInt err = cenRep->Get( aKey, val );
+        // Check that the value is within the allowed ranges.
+    TBool validRange = ETrue;
+    if( val < aMinRange1 || val > aMaxRange1 )
+        {
+            // The value is not within the first range
+        if( !aMinRange2 && !aMaxRange2 )
+            {
+                // No second range is specified, so the value is out-of-range.
+            validRange = EFalse;
+            }
+        else if( !( val >= aMinRange2 && val <= aMaxRange2 ) )
+            {
+                // The value is not within the second range either, 
+                // so the value is out-of-range.
+            validRange = EFalse;
+            }
+        }
+    if( err || !validRange )
+        {
+        TRACE_INFO( ( _L( "Error occured! err(%d) val(%d), range %d-%d (2nd: %d-%d)" ), 
+                       err, val, aMinRange1, aMaxRange1, aMinRange2, aMaxRange2 ) )
+            // If an error occured, we cannot trust the central repository,
+            // so return to default value to be safe.
+        val = aValue;   // Revert to the original value
+        (void) cenRep->Set( aKey, val );    // Just try once, ignore return value
+        }
+    delete cenRep;
+    aValue = val;
+
+    TRACE_INFO( ( _L( "[BTENGSETTINGS]\t GetCenRepKeyL - key value: %d; err: %d" ), 
+                val, err ) )
+    TRACE_FUNC_RES( ( _L( "key value: %d; err: %d" ), val, err ) )
+    User::LeaveIfError( err );
+    }
+
+
+// ---------------------------------------------------------------------------
+// Gets or sets the BT local name from Bluetooth Registry.
+// ---------------------------------------------------------------------------
+//
+TInt CBTEngSettings::HandleBTRegistryNameSetting( TDes& aName )
+    {
+    TRACE_FUNC_ENTRY
+    RBTRegServ btRegServ;
+    RBTLocalDevice btReg;
+    TInt err = btRegServ.Connect();
+    if( !err )
+        {
+        err = btReg.Open( btRegServ );
+        }
+    TBTLocalDevice localDev;
+    if( !err )
+        {
+            // Read the BT local name from BT Registry.
+        err = btReg.Get( localDev );
+        }
+           
+    if( !err )
+        {
+            // BT registry keeps the device name in UTF-8 format.
+        TBuf8<KHCILocalDeviceNameMaxLength> utf8Name;
+        if( aName.Length() == 0 )
+            {
+                // The error can be > 0 if there are unconverted characters.
+            err = CnvUtfConverter::ConvertToUnicodeFromUtf8( aName, 
+                                                        localDev.DeviceName() );
+            TRACE_INFO( ( _L( "[BTENGSETTINGS]\t getting name from registry: err %d %S" ), 
+            		err, &aName))
+            }
+        else
+            {
+                // Write the supplied  name to BT Registry.
+                // The error can be > 0 if there are unconverted characters.
+            err = CnvUtfConverter::ConvertFromUnicodeToUtf8( utf8Name, aName );
+            if( !err )
+                {
+                localDev.SetDeviceName( utf8Name );
+                err = btReg.Modify( localDev );
+                }
+            TRACE_INFO( ( _L( "[BTENGSETTINGS]\t setting name to registry:err %d, %S" ), 
+            		err, &aName))
+            }
+        }
+                
+    btReg.Close();
+    btRegServ.Close();
+    TRACE_FUNC_EXIT
+    
+    return err;
+    }