|
1 /* |
|
2 * Copyright (c) 2006 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: Bluetooth Engine API for managing device settings. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include <centralrepository.h> |
|
21 #include <featmgr.h> |
|
22 #include <utf.h> |
|
23 |
|
24 #include "btengsettings.h" |
|
25 #include "btengprivatecrkeys.h" |
|
26 #include "btengsettingsnotify.h" |
|
27 #include "btengclient.h" |
|
28 #include "debug.h" |
|
29 |
|
30 |
|
31 // ======== MEMBER FUNCTIONS ======== |
|
32 |
|
33 // --------------------------------------------------------------------------- |
|
34 // C++ default constructor |
|
35 // --------------------------------------------------------------------------- |
|
36 // |
|
37 CBTEngSettings::CBTEngSettings( MBTEngSettingsObserver* aObserver ) |
|
38 : iObserver( aObserver ) |
|
39 { |
|
40 } |
|
41 |
|
42 |
|
43 // --------------------------------------------------------------------------- |
|
44 // Symbian 2nd-phase constructor |
|
45 // --------------------------------------------------------------------------- |
|
46 // |
|
47 void CBTEngSettings::ConstructL() |
|
48 { |
|
49 TRACE_FUNC_ENTRY |
|
50 // Check if BT is supported at all |
|
51 FeatureManager::InitializeLibL(); |
|
52 TBool btSupported = FeatureManager::FeatureSupported( KFeatureIdBt ); |
|
53 FeatureManager::UnInitializeLib(); |
|
54 if( !btSupported ) |
|
55 { |
|
56 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t ConstructL: BT not supported!!" ) ) ) |
|
57 User::Leave( KErrNotSupported ); |
|
58 } |
|
59 if( iObserver ) |
|
60 { |
|
61 iSettingsWatcher = CBTEngSettingsNotify::NewL( iObserver ); |
|
62 } |
|
63 TRACE_FUNC_EXIT |
|
64 } |
|
65 |
|
66 |
|
67 // --------------------------------------------------------------------------- |
|
68 // NewL |
|
69 // --------------------------------------------------------------------------- |
|
70 // |
|
71 EXPORT_C CBTEngSettings* CBTEngSettings::NewL( MBTEngSettingsObserver* aObserver ) |
|
72 { |
|
73 CBTEngSettings* self = CBTEngSettings::NewLC( aObserver ); |
|
74 CleanupStack::Pop( self ); |
|
75 return self; |
|
76 } |
|
77 |
|
78 |
|
79 // --------------------------------------------------------------------------- |
|
80 // NewLC |
|
81 // --------------------------------------------------------------------------- |
|
82 // |
|
83 EXPORT_C CBTEngSettings* CBTEngSettings::NewLC( MBTEngSettingsObserver* aObserver ) |
|
84 { |
|
85 CBTEngSettings* self = new( ELeave ) CBTEngSettings( aObserver ); |
|
86 CleanupStack::PushL( self ); |
|
87 self->ConstructL(); |
|
88 return self; |
|
89 } |
|
90 |
|
91 |
|
92 // --------------------------------------------------------------------------- |
|
93 // Destructor |
|
94 // --------------------------------------------------------------------------- |
|
95 // |
|
96 CBTEngSettings::~CBTEngSettings() |
|
97 { |
|
98 TRACE_FUNC_ENTRY |
|
99 delete iSettingsWatcher; |
|
100 } |
|
101 |
|
102 |
|
103 // --------------------------------------------------------------------------- |
|
104 // Gets the current BT hardware power state |
|
105 // (on or off) from central repository. |
|
106 // --------------------------------------------------------------------------- |
|
107 // |
|
108 EXPORT_C TInt CBTEngSettings::GetPowerState( TBTPowerStateValue& aState ) |
|
109 { |
|
110 TRACE_FUNC_ENTRY |
|
111 aState = EBTPowerOff; |
|
112 TRAPD( err, GetCenRepKeyL( KCRUidBluetoothPowerState, KBTPowerState, |
|
113 (TInt&) aState, EBTPowerOff, EBTPowerOn ) ); |
|
114 return err; |
|
115 } |
|
116 |
|
117 |
|
118 // --------------------------------------------------------------------------- |
|
119 // Sets the Bluetooth hardware power state. |
|
120 // --------------------------------------------------------------------------- |
|
121 // |
|
122 EXPORT_C TInt CBTEngSettings::SetPowerState( TBTPowerStateValue aState ) |
|
123 { |
|
124 TRACE_FUNC_ENTRY |
|
125 if( aState != EBTPowerOff && aState != EBTPowerOn ) |
|
126 { |
|
127 return KErrArgument; |
|
128 } |
|
129 RBTEng bteng; |
|
130 TInt err = bteng.Connect(); |
|
131 if( !err ) |
|
132 { |
|
133 err = bteng.SetPowerState( aState, EFalse ); |
|
134 bteng.Close(); |
|
135 } |
|
136 TRACE_FUNC_EXIT |
|
137 return err; |
|
138 } |
|
139 |
|
140 |
|
141 // --------------------------------------------------------------------------- |
|
142 // Gets the current Bluetooth hardware visibility mode |
|
143 // (visible or hidden) from central repository. |
|
144 // --------------------------------------------------------------------------- |
|
145 // |
|
146 EXPORT_C TInt CBTEngSettings::GetVisibilityMode( TBTVisibilityMode& aMode ) |
|
147 { |
|
148 TRACE_FUNC_ENTRY |
|
149 aMode = EBTVisibilityModeGeneral; |
|
150 TRAPD( err, GetCenRepKeyL( KCRUidBTEngPrivateSettings, KBTDiscoverable, |
|
151 (TInt&) aMode, EBTVisibilityModeHidden, |
|
152 EBTVisibilityModeGeneral, |
|
153 EBTVisibilityModeTemporary, |
|
154 EBTVisibilityModeTemporary ) ); |
|
155 return err; |
|
156 } |
|
157 |
|
158 |
|
159 // --------------------------------------------------------------------------- |
|
160 // Sets the Bluetooth hardware visibility mode. The visible mode can also |
|
161 // be temporary visible, specified by the aTime parameter (time in seconds). |
|
162 // --------------------------------------------------------------------------- |
|
163 // |
|
164 EXPORT_C TInt CBTEngSettings::SetVisibilityMode( TBTVisibilityMode aMode, TInt aTime ) |
|
165 { |
|
166 TRACE_FUNC_ENTRY |
|
167 if( aMode != EBTVisibilityModeHidden && aMode != EBTVisibilityModeGeneral && |
|
168 aMode != EBTVisibilityModeTemporary ) |
|
169 { |
|
170 return KErrArgument; |
|
171 } |
|
172 RBTEng bteng; |
|
173 TInt err = bteng.Connect(); |
|
174 if( !err ) |
|
175 { |
|
176 err = bteng.SetVisibilityMode( aMode, aTime ); |
|
177 bteng.Close(); |
|
178 } |
|
179 |
|
180 TRACE_FUNC_EXIT |
|
181 return err; |
|
182 } |
|
183 |
|
184 |
|
185 // --------------------------------------------------------------------------- |
|
186 // Gets the Bluetooth friendly name the Bluetooth stack. |
|
187 // --------------------------------------------------------------------------- |
|
188 // |
|
189 EXPORT_C TInt CBTEngSettings::GetLocalName( TDes& aName ) |
|
190 { |
|
191 TRACE_FUNC_ENTRY |
|
192 aName.Zero(); |
|
193 TBool nameStatus = EFalse; |
|
194 TBuf<KHCILocalDeviceNameMaxLength> tmpName; |
|
195 |
|
196 TInt err = GetLocalNameModified( nameStatus ); |
|
197 |
|
198 if( err || nameStatus == EBTLocalNameDefault ) |
|
199 { |
|
200 return err; |
|
201 } |
|
202 |
|
203 err = RProperty::Get( KPropertyUidBluetoothCategory, |
|
204 KPropertyKeyBluetoothGetDeviceName, aName ); |
|
205 if( !err ) |
|
206 { |
|
207 err = RProperty::Get( KPropertyUidBluetoothCategory, |
|
208 KPropertyKeyBluetoothSetDeviceName, tmpName ); |
|
209 if ( tmpName.Compare( aName ) ) |
|
210 { |
|
211 // The name has not yet been updated. Use the new one. |
|
212 aName.Copy( tmpName ); |
|
213 } |
|
214 } |
|
215 |
|
216 if( err || !aName.Length() ) |
|
217 { |
|
218 // An error occured, try still registry |
|
219 aName.Zero(); |
|
220 err = HandleBTRegistryNameSetting( const_cast<TDes&>( aName ) ); |
|
221 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t registry set result: %d"), err) ); |
|
222 } |
|
223 |
|
224 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t GetLocalName - result %d, name: %S" ), |
|
225 err, &aName ) ) |
|
226 return err; |
|
227 } |
|
228 |
|
229 // --------------------------------------------------------------------------- |
|
230 // Sets the Bluetooth friendly name. |
|
231 // --------------------------------------------------------------------------- |
|
232 // |
|
233 EXPORT_C TInt CBTEngSettings::SetLocalName( const TDes& aName ) |
|
234 { |
|
235 TRACE_FUNC_ENTRY |
|
236 TRACE_FUNC_ARG( ( _L( "aName lenght: %d" ), aName.Length() ) ) |
|
237 if( aName.Length() == 0 || aName.Length() > KMaxBluetoothNameLen ) |
|
238 { |
|
239 // Zero-length name means that the name has not been set; |
|
240 // such reset should not be done through BTEngSettings. |
|
241 return KErrArgument; |
|
242 } |
|
243 |
|
244 TInt err = RProperty::Set( KPropertyUidBluetoothCategory, |
|
245 KPropertyKeyBluetoothSetDeviceName, aName ); |
|
246 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t RProperty::Set: %d"), err) ); |
|
247 |
|
248 // Always update the name to registry |
|
249 TInt err2 = HandleBTRegistryNameSetting( const_cast<TDes&>( aName ) ); |
|
250 |
|
251 TBool nameChanged = EFalse; |
|
252 if( !err || !err2 ) |
|
253 { |
|
254 // Check if this is the first time name setting. |
|
255 err = GetLocalNameModified( nameChanged ); |
|
256 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t GetLocalNameModified: err %d, namechanged %d"), |
|
257 err, nameChanged) ); |
|
258 } |
|
259 |
|
260 if( ( !err || !err2 ) && nameChanged == EBTLocalNameDefault ) |
|
261 { |
|
262 // Set the name as changed. |
|
263 CRepository* cenRep = NULL; |
|
264 TRAP( err, cenRep = CRepository::NewL( KCRUidBTEngPrivateSettings ) ); |
|
265 if( !err ) |
|
266 { |
|
267 err = cenRep->Set( KBTLocalNameChanged, EBTLocalNameSet ); |
|
268 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t cenRep->Set( KBTLocalNameChanged, EBTLocalNameSet ): %d"), err) ); |
|
269 } |
|
270 delete cenRep; |
|
271 } |
|
272 |
|
273 TRACE_FUNC_RES( ( _L( "result %d" ), err ) ) |
|
274 return err; |
|
275 } |
|
276 |
|
277 |
|
278 // --------------------------------------------------------------------------- |
|
279 // Sets the Bluetooth hardware power state for temporary connections. |
|
280 // --------------------------------------------------------------------------- |
|
281 // |
|
282 EXPORT_C TInt CBTEngSettings::ChangePowerStateTemporarily() |
|
283 { |
|
284 TRACE_FUNC_ENTRY |
|
285 TInt err = KErrNone; |
|
286 if( !iSettingsWatcher ) |
|
287 { |
|
288 TRAP( err, iSettingsWatcher = CBTEngSettingsNotify::NewL( NULL ) ); |
|
289 } |
|
290 if( !err ) |
|
291 { |
|
292 err = iSettingsWatcher->TogglePowerTemporarily(); |
|
293 } |
|
294 TRACE_FUNC_EXIT |
|
295 return err; |
|
296 } |
|
297 |
|
298 // --------------------------------------------------------------------------- |
|
299 // Get the Bluetooth offline mode settings |
|
300 // --------------------------------------------------------------------------- |
|
301 // |
|
302 EXPORT_C TInt CBTEngSettings::GetOfflineModeSettings( |
|
303 TCoreAppUIsNetworkConnectionAllowed& aOffline, |
|
304 TBTEnabledInOfflineMode& aOfflineAllowed ) |
|
305 { |
|
306 TRACE_FUNC_ENTRY |
|
307 aOffline = ECoreAppUIsNetworkConnectionAllowed; |
|
308 aOfflineAllowed = EBTEnabledInOfflineMode; |
|
309 TRAPD( err, GetCenRepKeyL( KCRUidCoreApplicationUIs, |
|
310 KCoreAppUIsNetworkConnectionAllowed, (TInt&) aOffline, |
|
311 ECoreAppUIsNetworkConnectionNotAllowed, |
|
312 ECoreAppUIsNetworkConnectionAllowed ) ); |
|
313 if( !err && aOffline == ECoreAppUIsNetworkConnectionNotAllowed ) |
|
314 { |
|
315 TRAP( err, GetCenRepKeyL( KCRUidBluetoothEngine, KBTEnabledInOffline, |
|
316 (TInt&) aOfflineAllowed, EBTDisabledInOfflineMode, |
|
317 EBTEnabledInOfflineMode ) ); |
|
318 } |
|
319 return err; |
|
320 } |
|
321 |
|
322 |
|
323 // --------------------------------------------------------------------------- |
|
324 // Checks from central repository whether the Bluetooth friendly name |
|
325 // has been modified . |
|
326 // --------------------------------------------------------------------------- |
|
327 // |
|
328 TInt CBTEngSettings::GetLocalNameModified( TBool& aStatus ) |
|
329 { |
|
330 TRACE_FUNC_ENTRY |
|
331 |
|
332 aStatus = (TBool) EBTLocalNameDefault; |
|
333 TRAPD( err, GetCenRepKeyL( KCRUidBTEngPrivateSettings, KBTLocalNameChanged, |
|
334 (TInt&) aStatus, EBTLocalNameDefault, |
|
335 EBTLocalNameSet ) ); |
|
336 return err; |
|
337 } |
|
338 |
|
339 |
|
340 // --------------------------------------------------------------------------- |
|
341 // Gets the specified CenRep key and checks if it is within a valid range; |
|
342 // if not, it it reset to the default value. |
|
343 // --------------------------------------------------------------------------- |
|
344 // |
|
345 void CBTEngSettings::GetCenRepKeyL( const TUid aUid, const TInt aKey, TInt& aValue, |
|
346 const TInt aMinRange1, const TInt aMaxRange1, |
|
347 const TInt aMinRange2, const TInt aMaxRange2 ) |
|
348 { |
|
349 TRACE_FUNC_ARG( ( _L( "aKey: %d" ), aKey ) ) |
|
350 // [SvV] Test that both logging macro do the same: |
|
351 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t GetCenRepKeyL - start (aKey: %d)" ), aKey ) ) |
|
352 TInt val = aValue; |
|
353 |
|
354 CRepository* cenRep = CRepository::NewL( aUid ); |
|
355 TInt err = cenRep->Get( aKey, val ); |
|
356 // Check that the value is within the allowed ranges. |
|
357 TBool validRange = ETrue; |
|
358 if( val < aMinRange1 || val > aMaxRange1 ) |
|
359 { |
|
360 // The value is not within the first range |
|
361 if( !aMinRange2 && !aMaxRange2 ) |
|
362 { |
|
363 // No second range is specified, so the value is out-of-range. |
|
364 validRange = EFalse; |
|
365 } |
|
366 else if( !( val >= aMinRange2 && val <= aMaxRange2 ) ) |
|
367 { |
|
368 // The value is not within the second range either, |
|
369 // so the value is out-of-range. |
|
370 validRange = EFalse; |
|
371 } |
|
372 } |
|
373 if( err || !validRange ) |
|
374 { |
|
375 TRACE_INFO( ( _L( "Error occured! err(%d) val(%d), range %d-%d (2nd: %d-%d)" ), |
|
376 err, val, aMinRange1, aMaxRange1, aMinRange2, aMaxRange2 ) ) |
|
377 // If an error occured, we cannot trust the central repository, |
|
378 // so return to default value to be safe. |
|
379 val = aValue; // Revert to the original value |
|
380 (void) cenRep->Set( aKey, val ); // Just try once, ignore return value |
|
381 } |
|
382 delete cenRep; |
|
383 aValue = val; |
|
384 |
|
385 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t GetCenRepKeyL - key value: %d; err: %d" ), |
|
386 val, err ) ) |
|
387 TRACE_FUNC_RES( ( _L( "key value: %d; err: %d" ), val, err ) ) |
|
388 User::LeaveIfError( err ); |
|
389 } |
|
390 |
|
391 |
|
392 // --------------------------------------------------------------------------- |
|
393 // Gets or sets the BT local name from Bluetooth Registry. |
|
394 // --------------------------------------------------------------------------- |
|
395 // |
|
396 TInt CBTEngSettings::HandleBTRegistryNameSetting( TDes& aName ) |
|
397 { |
|
398 TRACE_FUNC_ENTRY |
|
399 RBTRegServ btRegServ; |
|
400 RBTLocalDevice btReg; |
|
401 TInt err = btRegServ.Connect(); |
|
402 if( !err ) |
|
403 { |
|
404 err = btReg.Open( btRegServ ); |
|
405 } |
|
406 TBTLocalDevice localDev; |
|
407 if( !err ) |
|
408 { |
|
409 // Read the BT local name from BT Registry. |
|
410 err = btReg.Get( localDev ); |
|
411 } |
|
412 |
|
413 if( !err ) |
|
414 { |
|
415 // BT registry keeps the device name in UTF-8 format. |
|
416 TBuf8<KHCILocalDeviceNameMaxLength> utf8Name; |
|
417 if( aName.Length() == 0 ) |
|
418 { |
|
419 // The error can be > 0 if there are unconverted characters. |
|
420 err = CnvUtfConverter::ConvertToUnicodeFromUtf8( aName, |
|
421 localDev.DeviceName() ); |
|
422 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t getting name from registry: err %d %S" ), |
|
423 err, &aName)) |
|
424 } |
|
425 else |
|
426 { |
|
427 // Write the supplied name to BT Registry. |
|
428 // The error can be > 0 if there are unconverted characters. |
|
429 err = CnvUtfConverter::ConvertFromUnicodeToUtf8( utf8Name, aName ); |
|
430 if( !err ) |
|
431 { |
|
432 localDev.SetDeviceName( utf8Name ); |
|
433 err = btReg.Modify( localDev ); |
|
434 } |
|
435 TRACE_INFO( ( _L( "[BTENGSETTINGS]\t setting name to registry:err %d, %S" ), |
|
436 err, &aName)) |
|
437 } |
|
438 } |
|
439 |
|
440 btReg.Close(); |
|
441 btRegServ.Close(); |
|
442 TRACE_FUNC_EXIT |
|
443 |
|
444 return err; |
|
445 } |