--- a/bluetoothengine/btnotif/btnotifsrv/src/btnotifpairinghelper.cpp Wed May 05 09:56:48 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,958 +0,0 @@
-/*
-* ============================================================================
-* Name : btnotifpairinghelper.cpp
-* Part of : bluetoothengine / btnotif
-* Description : Helper class for processing pairing requests and results, as extended functionality for CBTNotifConnection.
-*
-* Copyright © 2009 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:
-* Nokia Corporation
-* ============================================================================
-* Template version: 4.1
-*/
-
-#include "btnotifpairinghelper.h"
-#include <bt_sock.h>
-#include <btextnotifiers.h>
-#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
-#include <btextnotifierspartner.h>
-#endif
-
-#include "btnotifconnection.h"
-#include "btnotifconnectiontracker.h"
-#include "btnotificationmanager.h"
-#include "btnotifserver.h"
-#include "bluetoothtrace.h"
-
-/** Id for the active object for a dedicated bonding session. */
-const TInt KDedicatedBonding = 50;
-/** Length of the default PIN. */
-const TInt KDefaultPinLength = 4;
-/** Default PIN character. */
-const TText8 KDefaultPinValue = '0';
-/** Format syntax for numeric comparison value. */
-_LIT( KNumCompFormat, "%06u" );
-/** Format syntax for passkey display value. */
-_LIT( KPassKeyFormat, "%06u" );
-
-
-// ======== LOCAL FUNCTIONS ========
-
-// ---------------------------------------------------------------------------
-// ?description
-// ---------------------------------------------------------------------------
-//
-/*?type ?function_name( ?arg_type ?arg,
- ?arg_type ?arg )
- {
- }
-*/
-
-// ======== MEMBER FUNCTIONS ========
-
-// ---------------------------------------------------------------------------
-// C++ default constructor.
-// ---------------------------------------------------------------------------
-//
-CBTNotifPairingHelper::CBTNotifPairingHelper( CBTNotifConnection* aConnection,
- CBTNotifConnectionTracker* aTracker )
-: iConnection( aConnection ),
- iTracker( aTracker )
- {
- }
-
-
-// ---------------------------------------------------------------------------
-// Symbian 2nd-phase constructor.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::ConstructL()
- {
- if( iConnection )
- {
- iDevice = iConnection->BTDevice();
- }
- }
-
-
-// ---------------------------------------------------------------------------
-// NewL
-// ---------------------------------------------------------------------------
-//
-CBTNotifPairingHelper* CBTNotifPairingHelper::NewL( CBTNotifConnection* aConnection,
- CBTNotifConnectionTracker* aTracker )
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- CBTNotifPairingHelper* self = new( ELeave ) CBTNotifPairingHelper( aConnection, aTracker );
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop( self );
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- return self;
- }
-
-
-// ---------------------------------------------------------------------------
-// Destructor.
-// ---------------------------------------------------------------------------
-//
-CBTNotifPairingHelper::~CBTNotifPairingHelper()
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- if( iNotification )
- {
- // Clear the notification callback, we cannot receive them anymore.
- iNotification->RemoveObserver();
- iNotification->Close(); // Also dequeues the notification from the queue.
- iNotification = NULL;
- }
- delete iParams;
- if( iBondingActive )
- {
- iBondingActive->Cancel(); // Will close subsession;
- }
- delete iBondingActive;
- iBondingSession.Close();
- iBondingSocket.Close();
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
-// ---------------------------------------------------------------------------
-// Handle the authentication result from the baseband. Show the result in a note.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::HandleAuthenticationCompleteL( TInt aError )
- {
- BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aError );
- if( iOperation == EDedicatedBonding || iOperation == EAwaitingPairingResult ||
- iOperation == EAutoPairing )
- {
- // Default case (aError == 0): Success, we are now paired.
- TBTDialogResourceId resourceId = EPairingSuccess;
- TBool autoPairing = ( iOperation == EAutoPairing ); // Remember the autopairing state
- iOperation = EShowPairingSuccess;
- if( aError && aError != KHCIErrorBase )
- {
- // Authentication failure, means pairing failed.
- resourceId = EPairingFailure;
- iOperation = EShowPairingFailure;
- // Communicate the error now that we still remember it.
- if( iDedicatedBonding )
- {
- if( autoPairing && aError == KHCIErrorBase - EAuthenticationFailure )
- {
- BOstrace0( TRACE_NORMAL, DUMMY_DEVLIST,
- "[BTNOTIF]\t CBTNotifPairingHelper::HandleAuthenticationCompleteL: Autopairing failed, we need to try again.");
- // Autopairing failed, we need to try again.
- iOperation = EAutoPairing; // Reset back
- resourceId = ENoResource;
- }
- CompleteBondingL( aError );
- }
- }
- if( resourceId )
- {
- // Inform the user of the result.
- BOstrace0( TRACE_NORMAL, DUMMY_DEVLIST,
- "[BTNOTIF]\t CBTNotifPairingHelper::HandleAuthenticationCompleteL: pairing successful, inform user" );
- PrepareNotificationL( TBluetoothDialogParams::EGlobalNotif, resourceId );
- // MBRNotificationClosed will be called from this, which will
- // check the next stage.
- }
- }
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }
-
-
-// ---------------------------------------------------------------------------
-// Start a bonding operation with the remote device.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::StartBondingL( TInt aHandle )
- {
- BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aHandle );
- __ASSERT_ALWAYS( iOperation == EIdle || iOperation == EDedicatedBonding
- || iOperation == EAutoPairing, PanicServer( EBTNotifPanicBadState ) );
- if( !iBondingActive )
- {
- iBondingActive = CBtSimpleActive::NewL( *this, KDedicatedBonding );
- }
- if( aHandle )
- {
- iDedicatedBonding = aHandle;
- }
- if( iOperation == EIdle )
- {
- iOperation = EDedicatedBonding;
- }
- if( iOperation == EDedicatedBonding && iTracker->PairingServerSession() )
- {
- if( !iBondingActive->IsActive() )
- {
- BtTraceBtAddr1( TRACE_DEBUG,DUMMY_LIST,"CBTNotifPairingHelper::StartBondingL()",iDevice->BDAddr() );
- iBondingSession.Start( *iTracker->PairingServerSession(),
- iDevice->BDAddr(), iBondingActive->RequestStatus() );
- iBondingActive->GoActive();
- }
- }
- else
- {
- // We are doing autopairing (or the unlikely situation that the pairing server is unavailable)
- CompleteBondingL( KErrServerTerminated );
- }
- BOstraceFunctionExit1( DUMMY_DEVLIST, this);
- }
-
-
-// ---------------------------------------------------------------------------
-// Cancel an ongoing bonding operation with the remote device.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CancelBondingL()
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- if( iDedicatedBonding )
- {
- CompleteBondingL( KErrCancel ); // Closes sessions
- if( iNotification )
- {
- // Cancel the outstanding user query
- // This will also unregister us from the notification.
- TInt err = iNotification->Close();
- NOTIF_NOTHANDLED( !err )
- iNotification = NULL;
- }
- if( iNotifierUid )
- {
- // Also finish up the notifier processing.
- CompletePairingNotifierL( KErrCancel, EFalse, KNullDesC8 );
- }
- iOperation = EIdle;
- iConnection->PairingCompleted(); // This may delete us.
- }
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
-// ---------------------------------------------------------------------------
-// Handle a notifier request for pairing with the remote device of this connection.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::StartPairingNotifierL( TInt aUid, const TDesC8& aParams )
- {
- BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aUid );
- if( iDevice->GlobalSecurity().Banned() && !iDedicatedBonding )
- {
- // ToDo: should this case actually be ignored, and presume that
- // the caller will take care of unblocking the device?
- iOperation = EIdle;
- User::Leave( KErrAccessDenied );
- }
- // Store the parameters locally, we need them later again.
- delete iParams;
- iParams = NULL;
- iParams = HBufC8::NewL( aParams.Length() );
- *iParams = aParams;
- iNotifierUid = aUid;
-
- if( iDevice->IsValidPaired() && iDevice->IsPaired() )
- {
- // The device is still paired, we unpair it first.
- // Deleting the link key will set the device as unpaired.
- iDevice->DeleteLinkKey();
- iOperation = EUnpairing; // So that parent state does not get changed.
- iConnection->UpdateRegistryEntryL();
- // Note that this will only be done before trying autopairing, so
- // it not interfere with a second attempt;
- }
- // Update the device name
- TBTPasskeyDisplayParams params; // Enough for reading the base class type parameter
- TPckgC<TBTPasskeyDisplayParams> paramsPckg( params );
- paramsPckg.Set( *iParams );
- if( paramsPckg().DeviceName().Length() )
- {
- // The name in the parameter package is the latest one, retrieved from
- // the remote device during this connection. Update locally.
- iDevice->SetDeviceNameL( BTDeviceNameConverter::ToUTF8L( paramsPckg().DeviceName() ) );
- }
-
- TBool locallyInitiated = EFalse;
- TBuf<8> numVal;
- TBluetoothDialogParams::TBTDialogType dialog = TBluetoothDialogParams::EInvalidDialog;
- TBTDialogResourceId resource = ENoResource;
- // Read the notifier parameters (sets iOperation as well)
- ParseNotifierReqParamsL( locallyInitiated, numVal, dialog, resource );
- // If this is an incoming pairing, we first ask the user to accept it.
- if( !locallyInitiated && !iDedicatedBonding )
- {
- // Ignore the initatior if we initiated bonding.
- StartAcceptPairingQueryL(); // Overrides iOperation
- }
- else
- {
- __ASSERT_ALWAYS( resource != ENoResource, PanicServer( EBTNotifPanicBadState ) );
- CheckAutoPairingL( locallyInitiated, numVal );
- // CheckAutoPairingL sets
- if( iOperation != EAutoPairing )
- {
- PrepareNotificationL( dialog, resource );
- if( numVal.Length() )
- {
- TInt err = iNotification->SetData( TBluetoothDeviceDialog::EAdditionalDesc, numVal );
- NOTIF_NOTHANDLED( !err )
- }
- }
- }
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }
-
-
-// ---------------------------------------------------------------------------
-// Update a notifier, update the outstanding dialog if the notifier request
-// is currently being served.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::UpdatePairingNotifierL( TInt aUid, const TDesC8& aParams )
- {
- (void) aUid;
- TBTNotifierUpdateParams2 params; // Enough for reading the base class type parameter
- TPckgC<TBTNotifierUpdateParams2> paramsPckg( params );
- paramsPckg.Set( aParams );
- if( paramsPckg().Type() == TBTNotifierUpdateParams2::EPasskeyDisplay )
- {
- // Paskey display update - keypress on remote device.
- }
- else
- {
- // name update
- TBTDeviceNameUpdateParams nameUpdate;
- TPckgC<TBTDeviceNameUpdateParams> nameUpdatePckg( nameUpdate );
- nameUpdatePckg.Set( aParams );
- // The result means result of conversion to unicode
- if( !nameUpdatePckg().Result() )
- {
- // Only update locally, registry will update us with the same info later on.
- iDevice->SetDeviceNameL( BTDeviceNameConverter::ToUTF8L( nameUpdatePckg().DeviceName() ) );
- if( iNotification )
- {
- // Update the dialog with the new name. It is up to the dialog to
- // determine the validity (in case another dialog is shown).
- //iNotification->Update( )
- }
- }
- }
- }
-
-
-// ---------------------------------------------------------------------------
-// Cancel a request, dismiss the outstanding dialog if the notifier request
-// is currently being served.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CancelPairingNotifierL( TInt aUid )
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- // ToDo: we need to check that the UID and the outstanding notification
- // type are matching?
- if( iOperation > EIdle && iOperation < EPostPairingOperations && aUid == iNotifierUid &&
- ( aUid == KBTPinCodeEntryNotifierUid.iUid ||
- aUid == KBTNumericComparisonNotifierUid.iUid ||
- aUid == KBTPasskeyDisplayNotifierUid.iUid ) )
- {
- if( iNotification )
- {
- // Cancel the user query
- // This will also unregister us from the notification.
- TInt err = iNotification->Close();
- NOTIF_NOTHANDLED( !err )
- iNotification = NULL;
- }
- iOperation = EIdle;
- iNotifierUid = 0;
- // We do not call pairing completed from here, our parent will
- // check our status by itself, and may delete us.
-
- // Any bonding requester needs to be informed though.
- CancelBondingL();
- }
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
-// ---------------------------------------------------------------------------
-//
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::StartJustWorksProcessingL()
- {
- }
-
-
-// ---------------------------------------------------------------------------
-//
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CancelJustWorksProcessingL()
- {
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBTNotificationResult.
-// Handle a result from a user query.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::MBRDataReceived( CHbSymbianVariantMap& aData )
- {
- (void) aData;
- NOTIF_NOTIMPL
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBTNotificationResult.
-// The notification is finished.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::MBRNotificationClosed( TInt aError, const TDesC8& aData )
- {
- BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aError );
- // First unregister from the notification, so we can already get the next one.
- iNotification->RemoveObserver();
- iNotification = NULL;
- TRAP_IGNORE( NotificationClosedL( aError, aData ) );
- if( iOperation == EIdle )
- {
- // Any error has been communicated already.
- iConnection->PairingCompleted(); // This may delete us.
- }
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBtSimpleActiveObserver.
-// Handle the active object completion.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::RequestCompletedL( CBtSimpleActive* aActive,
- TInt aStatus )
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- switch( aActive->RequestId() )
- {
- case KDedicatedBonding:
- {
- if( iDedicatedBonding )
- {
- // If the result hasn't been processed already.
- HandleAuthenticationCompleteL( aStatus );
- }
- }
- break;
- default:
- NOTIF_NOTIMPL
- break;
- }
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBtSimpleActiveObserver.
-// Cancel and clean up all requests related to the active object.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CancelRequest( TInt aRequestId )
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- switch( aRequestId )
- {
- case KDedicatedBonding:
- iBondingSession.Close();
- break;
- default:
- NOTIF_NOTIMPL
- break;
- }
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-// ---------------------------------------------------------------------------
-// From class MBtSimpleActiveObserver.
-//
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::HandleError( CBtSimpleActive* aActive,
- TInt aError )
- {
- (void) aActive;
- (void) aError;
- }
-
-// ---------------------------------------------------------------------------
-// Process the user input and complete the outstanding pairing request.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CompletePairingNotifierL( TInt aError, TBool aResult,
- const TDesC8& aData )
- {
- BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aError );
- TInt err = aError;
- TPtrC8 resultData;
- if( !err )
- {
- // The returned data is the entered passkey.
- TBool proceed = iTracker->UpdateBlockingHistoryL( iDevice, aResult );
- if( iOperation == ESspPairing && iNotifierUid == KBTNumericComparisonNotifierUid.iUid )
- {
- // Numeric comparison needs the boolean result passed back.
- TPckgBuf<TBool> userAcceptance( aResult );
- resultData.Set( userAcceptance );
- }
- if( aResult )
- {
- if( iOperation == ELegacyPairing || iOperation == EAutoPairing )
- {
- // Check the passkey entered by the user.
- // The length of the returned data equals the number of characters
- // entered by the user.
- TBTPinCode pinCode;
- pinCode().iLength = aData.Length();
- TUint minLen = 0;
- TBool locallyInitiated = EFalse; // Not used here.
- ParsePinCodeReqParamsL( locallyInitiated, minLen );
- if( aData.Length() >= minLen )
- {
- // Check that the length of the passkey meets the minimum
- // required pin code length
- for( TInt i = 0; i < aData.Length(); i++ )
- {
- pinCode().iPIN[i] = aData[i];
- }
- resultData.Set( pinCode );
- }
- else
- {
- // PIN wasn't long enough. This should be handled by the dialog though.
- err = KErrCompletion;
- }
- }
- // Now we just wait for the result to come in.
- if( iOperation != EAutoPairing )
- {
- iOperation = EAwaitingPairingResult;
- }
- }
- else
- {
- err = KErrCancel;
- TBool locallyInitiated = EFalse; // Needed below
- TBuf<8> numVal; // Not needed here.
- TBluetoothDialogParams::TBTDialogType type = TBluetoothDialogParams::EInvalidDialog;
- TBTDialogResourceId resource = ENoResource; // Resources and type are not needed here.
- // Check the notifier parameters
- ParseNotifierReqParamsL( locallyInitiated, numVal, type, resource );
- if( proceed && locallyInitiated && !iDedicatedBonding )
- {
- // The user denied the connection, ask to block the device.
- // This is only for pairing (and not bonding) initiated by us,
- // as the user already gets the opportunity to block when
- // rejecting an incoming pairing request.
- // This case may be for someone requesting to access a service
- // which requires authentication by us, but not by the remote device.
- iConnection->LaunchBlockingQueryL();
- // For incoming pairing, blocking is asked after rejecting the
- // pairing request. This is done in CompleteAcceptPairingQueryL
- }
- CompleteBondingL( err ); // Notify the client if there was a bonding request.
- }
- }
- iNotifierUid = 0; // Clean up notifier data
- delete iParams;
- iParams = NULL;
- if( err )
- {
- iOperation = EIdle; // We are done now.
- }
- // Complete the message with the result, and result data if any.
- iConnection->CompleteClientRequest( err, resultData );
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }
-
-
-// ---------------------------------------------------------------------------
-// Completes a bonding operation.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CompleteBondingL( TInt aError )
- {
- BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aError );
- if( iDedicatedBonding )
- {
- if( iBondingActive )
- {
- iBondingActive->Cancel(); // Will close subsession;
- }
- iBondingSession.Close(); // In case not active
- iBondingSocket.Close();
- }
- // Determine if we try another time.
- if( ( iOperation == EAutoPairing && aError == KHCIErrorBase - EAuthenticationFailure ) ||
- ( iDedicatedBonding && iOperation == EAwaitingPairingResult &&
- aError == KErrRemoteDeviceIndicatedNoBonding ) ||
- aError == KErrServerTerminated )
- {
- // The cases are: 2) autopairing with a headset that has a non-default passkey
- // 2) SSP dedicated bonding with a device that does not allow that.
- // 3) the pairing server is unavailable (unlikely)
- // Then we try another time, requesting authentication on a
- // RBTPhysicialLinkAdapter
- BOstrace0( TRACE_NORMAL, DUMMY_DEVLIST,
- "[BTNOTIF]\t CBTNotifPairingHelper::CompleteBondingL: trying another time." );
- TInt err = iBondingSocket.Open( iTracker->SocketServerSession(), iConnection->Address() );
- TUint32 linkState = 0;
- if( !err )
- {
- err = iBondingSocket.PhysicalLinkState( linkState );
- }
- if( !err && linkState & ENotifyPhysicalLinkUp )
- {
- err = iBondingSocket.Authenticate();
- // Now wait for the dialog and then the link state notification
- }
- else
- {
- // We need to wait for the link to come up. We wait until our
- // parent calls us again.
- iBondingSocket.Close();
- }
- if( err )
- {
- // Cannot continue, show the result to the user.
- BOstrace0( TRACE_NORMAL, DUMMY_DEVLIST,
- "[BTNOTIF]\t CBTNotifPairingHelper::HandleAuthenticationCompleteL: pairing failed, complete message." );
- iOperation = EShowPairingFailure;
- PrepareNotificationL( TBluetoothDialogParams::ENote, EPairingFailure );
- }
- }
- if( iDedicatedBonding && iOperation != EAutoPairing )
- {
- BOstrace0( TRACE_NORMAL, DUMMY_DEVLIST,
- "[BTNOTIF]\t CBTNotifPairingHelper::CompleteBondingL: complete message." );
- TInt err = iTracker->Server()->CompleteMessage( iDedicatedBonding, aError, KNullDesC8 );
- NOTIF_NOTHANDLED( !err )
- iDedicatedBonding = 0;
- }
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }
-
-
-// ---------------------------------------------------------------------------
-//
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CompleteJustWorksProcessingL( TInt aError )
- {
- (void) aError;
- }
-
-
-// ---------------------------------------------------------------------------
-// Ask the user to allow incoming pairing.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::StartAcceptPairingQueryL()
- {
- iOperation = EAcceptPairing;
- PrepareNotificationL( TBluetoothDialogParams::EQuery, EIncomingPairing );
- // if rejected, the client message is completed in CompleteAcceptPairingQueryL
- }
-
-
-// ---------------------------------------------------------------------------
-// The user was asked to accept an incoming pairing. Process and proceed.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CompleteAcceptPairingQueryL( TInt aError, TBool aResult )
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- // Set our state to idle for now. This may get changed if the user just chose
- // to block, or if we have a pending request.
- iOperation = EIdle;
- TInt err = aError;
- if( !err )
- {
- TBool proceed = iTracker->UpdateBlockingHistoryL( iDevice, aResult );
- if( aResult )
- {
- // User accepted, continue to show pairing query.
- // Minimum lenght does not apply, should only be set on outgoing pairing
- TBool locallyInitiated = EFalse;
- TBuf<8> numVal;
- TBluetoothDialogParams::TBTDialogType dialog = TBluetoothDialogParams::EInvalidDialog;
- TBTDialogResourceId resource = ENoResource;
- // Read the notifier parameters
- ParseNotifierReqParamsL( locallyInitiated, numVal, dialog, resource );
- __ASSERT_ALWAYS( resource != ENoResource, PanicServer( EBTNotifPanicBadState ) );
- PrepareNotificationL( dialog, resource );
- if( numVal.Length() )
- {
- TInt err = iNotification->SetData( TBluetoothDeviceDialog::EAdditionalDesc, numVal );
- NOTIF_NOTHANDLED( !err )
- }
- }
- else
- {
- err = KErrCancel;
- if( proceed )
- {
- // The user denied the connection, ask to block the device.
- iConnection->LaunchBlockingQueryL();
- }
- }
- }
- if( err )
- {
- // The user denied the connection, or something else prevented completion.
- CompletePairingNotifierL( err, EFalse, KNullDesC8 );
- }
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
-// ---------------------------------------------------------------------------
-// Launch a dialog for setting the device as trusted.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::StartTrustedQueryL()
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- // Assume that the registry update has come through by now.
- iOperation = EQueryTrust;
- PrepareNotificationL( TBluetoothDialogParams::EQuery, ESetTrusted );
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
-// ---------------------------------------------------------------------------
-// Process the user input for setting the device as trusted.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CompleteTrustedQueryL( TInt aError, TBool aResult )
- {
- BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aError );
- BOstraceExt2( TRACE_DEBUG, DUMMY_DEVLIST,
- "CBTNotifPairingHelper::CompleteTrustedQueryL() err=%d result=%d", aError, aResult );
- iOperation = EIdle; // We are done with pairing now.
- if( !aError && aResult )
- {
- // need to update pairing info from registry before writing trusted status
- iConnection->UpdateRegistryEntryL(true);
- }
- CompleteBondingL( KErrNone ); // Notify the client if there was a bonding request.
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }
-
-
-// ---------------------------------------------------------------------------
-// Parse the parameters of a request for pairing.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::ParseNotifierReqParamsL( TBool& aLocallyInitiated,
- TDes& aNumVal, TBluetoothDialogParams::TBTDialogType& aDialogType,
- TBTDialogResourceId& aResourceId )
- {
- // Determine the notifier type by the length of the parameter buffer
- if( iNotifierUid == KBTPinCodeEntryNotifierUid.iUid )
- {
- aNumVal.Zero();
- TUint minLen = 0;
- ParsePinCodeReqParamsL( aLocallyInitiated, minLen );
- if( minLen )
- {
- // Don't set zero to this buffer, the buffer length serves for this.
- aNumVal.Num( minLen );
- }
- aDialogType = TBluetoothDialogParams::EInput;
- aResourceId = EPinInput;
- if( iOperation != EAutoPairing )
- {
- iOperation = ELegacyPairing;
- }
- }
- else if( iNotifierUid == KBTNumericComparisonNotifierUid.iUid )
- {
- ParseNumericCompReqParamsL( aLocallyInitiated, aNumVal );
- aDialogType = TBluetoothDialogParams::EQuery;
- aResourceId = ENumericComparison;
- iOperation = ESspPairing;
- }
- else if( iNotifierUid == KBTPasskeyDisplayNotifierUid.iUid )
- {
- ParsePasskeyDisplayReqParamsL( aLocallyInitiated, aNumVal );
- aDialogType = TBluetoothDialogParams::EQuery;
- aResourceId = EPasskeyDisplay;
- iOperation = ESspPairing;
- }
- }
-
-
-// ---------------------------------------------------------------------------
-// Parse the parameters of a request for pairing using pin query.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::ParsePinCodeReqParamsL( TBool& aLocallyInitiated,
- TUint& aNumVal )
- {
- TBTPinCodeEntryNotifierParams params;
- TPckgC<TBTPinCodeEntryNotifierParams> paramsPckg( params );
- paramsPckg.Set( *iParams );
- aLocallyInitiated = paramsPckg().LocallyInitiated();
- aNumVal = paramsPckg().PinCodeMinLength();
- }
-
-
-// ---------------------------------------------------------------------------
-// Parse the parameters of a request for pairing using numeric comparison.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::ParseNumericCompReqParamsL( TBool& aLocallyInitiated,
- TDes& aNumVal )
- {
- TBTNumericComparisonParams params;
- TPckgC<TBTNumericComparisonParams> paramsPckg( params );
- paramsPckg.Set( *iParams );
- aLocallyInitiated = paramsPckg().LocallyInitiated();
- TBTNumericComparisonParams::TComparisonScenario scenario =
- paramsPckg().ComparisonScenario();
- aNumVal.Format( KNumCompFormat, paramsPckg().NumericalValue() );
- }
-
-
-// ---------------------------------------------------------------------------
-// Parse the parameters of a request for pairing using passkey display.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::ParsePasskeyDisplayReqParamsL( TBool& aLocallyInitiated,
- TDes& aNumVal )
- {
- TBTPasskeyDisplayParams params;
- TPckgC<TBTPasskeyDisplayParams> paramsPckg( params );
- paramsPckg.Set( *iParams );
- aLocallyInitiated = paramsPckg().LocallyInitiated();
- aNumVal.Format( KPassKeyFormat, paramsPckg().NumericalValue() );
- }
-
-
-// ---------------------------------------------------------------------------
-// Check if we can guess the PIN and complete the notifier without user interaction.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::CheckAutoPairingL( TBool aLocallyInitiated, const TDesC& aNumVal )
- {
- TUint minLen = 0;
- if( aNumVal.Length() )
- {
- ParsePinCodeReqParamsL( aLocallyInitiated, minLen );
- }
- // ToDo: Add support for NFC OOB pairing
- if( iDedicatedBonding && iOperation == ELegacyPairing &&
- iDevice->DeviceClass().MajorDeviceClass() == EMajorDeviceAV &&
- iDevice->DeviceClass().MinorDeviceClass() != EMinorDeviceAVHandsfree &&
- minLen <= KDefaultPinLength )
- {
- // Outgoing bonding with headset and no passkey requirement => AutomatedPairing
- // Complete message with 0000 and return.
- iOperation = EAutoPairing;
- TBuf8<KDefaultPinLength + sizeof( TPckgBuf<TBool> )> defaultPin( KDefaultPinLength );
- for( TInt i = 0; i < KDefaultPinLength; i++ )
- {
- defaultPin[i] = KDefaultPinValue;
- }
- // Complete the pairing through the function dedicated to that.
- CompletePairingNotifierL( KErrNone, ETrue, defaultPin );
- }
- else if( iOperation == EAutoPairing )
- {
- iOperation = ELegacyPairing; // Reset the autopairing status
- }
- }
-
-
-// ---------------------------------------------------------------------------
-// Get and configure a notification.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::PrepareNotificationL( TBluetoothDialogParams::TBTDialogType aType,
- TBTDialogResourceId aResourceId )
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- __ASSERT_ALWAYS( iOperation != EIdle || aType == TBluetoothDialogParams::ENote, PanicServer( EBTNotifPanicBadState ) );
- iNotification = iTracker->NotificationManager()->GetNotification();
- User::LeaveIfNull( iNotification ); // For OOM exception, leaves with KErrNoMemory
- iNotification->SetObserver( this );
- iNotification->SetNotificationType( aType, aResourceId );
- TBTDeviceName name;
- GetDeviceNameL( name, *iDevice );
- TInt err = iNotification->SetData( TBluetoothDeviceDialog::EDeviceName, name );
- NOTIF_NOTHANDLED( !err )
- // Re-use name buffer for 16-bit descriptor representation of remote address.
- iConnection->Address().GetReadable( name );
- err = iNotification->SetData( TBluetoothDialogParams::EAddress, name );
- NOTIF_NOTHANDLED( !err )
- err = iNotification->SetData( (TInt) TBluetoothDeviceDialog::EDeviceClass,
- iDevice->DeviceClass().DeviceClass() );
- err = iTracker->NotificationManager()->QueueNotification( iNotification );
- NOTIF_NOTHANDLED( !err )
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
-// ---------------------------------------------------------------------------
-// The notification is finished, handle the result.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifPairingHelper::NotificationClosedL( TInt aError, const TDesC8& aData )
- {
- BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aError );
- // Read the result.
- TPckgC<TBool> result( EFalse );
- result.Set( aData.Ptr(), result.Length() ); // Read the part containing the result
- // Set a pointer descriptor to capture the remaining data, if any.
- TPtrC8 dataPtr( aData.Mid( result.Length() ) );
- switch( iOperation )
- {
- case EAcceptPairing:
- CompleteAcceptPairingQueryL( aError, result() );
- break;
- case ELegacyPairing:
- case ESspPairing:
- CompletePairingNotifierL( aError, result(), dataPtr );
- break;
- case EQueryTrust:
- CompleteTrustedQueryL( aError, result() );
- break;
- case EShowPairingSuccess:
- StartTrustedQueryL();
- break;
- case EShowPairingFailure:
- // Pairing failure, we are done.
- iOperation = EIdle;
- break;
- default:
- NOTIF_NOTIMPL
- break;
- }
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }