--- /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;
+ }