bluetoothengine/btnotif/btnotifsrv/src/btnotifoutgoingpairinghandler.cpp
branchRCL_3
changeset 23 9386f31cc85b
parent 22 613943a21004
child 24 269724087bed
--- a/bluetoothengine/btnotif/btnotifsrv/src/btnotifoutgoingpairinghandler.cpp	Tue Aug 31 15:25:10 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,553 +0,0 @@
-/*
-* Copyright (c) 2010 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: Pairing handler for local device initiated pairing
-*
-*/
-
-#include "btnotifoutgoingpairinghandler.h"
-#include <btengconstants.h>
-#include <btservices/btdevextension.h>
-#include "btnotifsecuritymanager.h"
-#include "bluetoothtrace.h"
-#include "bluetoothnotification.h"
-#include "btnotifserver.h"
-#include "btnotifconnectiontracker.h"
-#include "btnotificationmanager.h"
-
-/**  Length of the default PIN. */
-const TInt KDefaultHeadsetPinLength = 4;
-
-/** Maximum repeated outgoing pairing attempt.
- *  if the pairing fails the UI specs says
- *  we can ask twice the user if he/she want 
- *  to retry pairing. 
- */
-const TInt KMaxRepeatedPairingAttempt = 2;
-
-enum TPairingStageId
-    {
-    /**
-     * no pairing operation ongoing
-     */
-    ENoBonding = 0,
-    
-    /**
-     * pair with dedicated bonding method
-     */
-    EDedicatedBonding = 200,
-    
-    /**
-     * pair with general bonding by establishing L2CAP connection.
-     */
-    EGeneralBonding,  
-    
-    /**
-     * delaying next pairing request for a while
-     */
-    EGeneralBondingRetryTimer,
-    
-    /**
-     * The last pairing retry
-     */
-    EGeneralBondingRetry,
-    
-    /**
-     * disconnecting physical link after pairing operation.
-     * 
-     * todo: not used yet.
-     */
-    EDisconnectLinkAfterBonding,
-    };
-
-/**  SDP PSM (used for pairing) */
-const TInt KSDPPSM = 0x0001;
-
-// Delay time to void Repeated Attempts on pairing
-const TInt KGeneralBondingRetryDelayMicroSeconds = 5000000; // 5.0s
-
-// ======== MEMBER FUNCTIONS ========
-
-// ---------------------------------------------------------------------------
-// C++ default constructor
-// ---------------------------------------------------------------------------
-//
-CBTNotifOutgoingPairingHandler::CBTNotifOutgoingPairingHandler( CBTNotifSecurityManager& aParent, const TBTDevAddr& aAddr)
-    :  CBTNotifBasePairingHandler( aParent, aAddr )
-    {
-    }
-
-// ---------------------------------------------------------------------------
-// Symbian 2nd-phase constructor
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::ConstructL()
-    {
-    BaseConstructL();
-    User::LeaveIfError( iTimer.CreateLocal() );
-    iPairingAttempt = KMaxRepeatedPairingAttempt;
-    }
-
-// ---------------------------------------------------------------------------
-// NewL
-// ---------------------------------------------------------------------------
-//
-CBTNotifBasePairingHandler* CBTNotifOutgoingPairingHandler::NewL( CBTNotifSecurityManager& aParent, 
-        const TBTDevAddr& aAddr )
-    {
-    CBTNotifOutgoingPairingHandler* self = new( ELeave ) CBTNotifOutgoingPairingHandler( aParent, aAddr );
-    CleanupStack::PushL( self );
-    self->ConstructL();
-    CleanupStack::Pop( self );
-    return self;
-    }
-
-// ---------------------------------------------------------------------------
-// Destructor
-// ---------------------------------------------------------------------------
-//
-CBTNotifOutgoingPairingHandler::~CBTNotifOutgoingPairingHandler()
-    {
-    if ( iActive ) 
-        {
-        iActive->Cancel();
-        }
-    iBondingSession.Close();
-    iSocket.Close();
-    iTimer.Close();
-    if( iNotification )
-        {
-        // Clear the notification callback, we cannot receive them anymore.
-        iNotification->RemoveObserver();
-        iNotification->Close(); // Also dequeues the notification from the queue.
-        iNotification = NULL;
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// Simply deny the request as this is handing outgoing pairing
-// ---------------------------------------------------------------------------
-//
-TInt CBTNotifOutgoingPairingHandler::ObserveIncomingPair( const TBTDevAddr& aAddr )
-    {
-    (void)aAddr;
-    return KErrServerBusy;
-    }
-
-// ---------------------------------------------------------------------------
-// Accept the request only this device is not busy with another pairing request.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::HandleOutgoingPairL( const TBTDevAddr& aAddr, TUint aCod )
-    {
-    BOstrace1(TRACE_DEBUG,DUMMY_DEVLIST," cod 0x%08x", aCod );
-    if ( iActive->IsActive() || aAddr != iAddr )
-        {
-        // we don't allow another pairing request.
-        User::Leave( KErrServerBusy );
-        }
-    iAddr = aAddr;
-    iCod = TBTDeviceClass( aCod );
-    UnSetPairResult();
-    iParent.UnpairDevice( iAddr );
-    if ( CBtDevExtension::IsHeadset( iCod ) )
-        {
-        // If the devie is a headset, set to 0000 pin auto pairing
-        iPairMode = EBTOutgoingHeadsetAutoPairing;
-        }
-    else
-        {
-        iPairMode = EBTOutgoingNoneHeadsetPairing;
-        }
-    DoPairingL();
-    }
-
-// ---------------------------------------------------------------------------
-// Cancels an outstanding pair request by self-destruct
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::CancelOutgoingPair()
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    iParent.RenewPairingHandler( NULL );
-    if( iNotification )
-        {
-        // Cancel the user query
-        // This will also unregister us from the notification.
-        TInt err = iNotification->Close();
-        NOTIF_NOTHANDLED( !err )
-        iNotification = NULL;
-        }
-    }
-
-
-// ---------------------------------------------------------------------------
-// when phone initiated a pairing request towards a headset,
-// Pin code 0000 is first tried.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::GetPinCode( 
-        TBTPinCode& aPin, const TBTDevAddr& aAddr, TInt aMinPinLength )
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    aPin().iLength = 0;
-    if ( aMinPinLength <= KDefaultHeadsetPinLength 
-            && aAddr == iAddr
-            && iPairMode == EBTOutgoingHeadsetAutoPairing)
-        {
-        // if the pairing requires a stronger security level (indicated
-        // by aMinPinLength), 
-        // 0000 will not be supplied as it does not mmet the security
-        // requirements
-        const TUint8 KZeroPinValue = '0';
-        for (TInt i = 0; i < KDefaultHeadsetPinLength; ++i)
-            {
-                aPin().iPIN[i] = KZeroPinValue;
-            }
-        aPin().iLength = KDefaultHeadsetPinLength;
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// Abort pairing handling, request the owner to destroy this.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::StopPairHandling( const TBTDevAddr& aAddr )
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    if ( aAddr == iAddr )
-        {
-        iParent.OutgoingPairCompleted( KErrCancel );
-        iParent.RenewPairingHandler( NULL );
-        if( iNotification )
-            {
-            // Cancel the user query
-            // This will also unregister us from the notification.
-            TInt err = iNotification->Close();
-            NOTIF_NOTHANDLED( !err )
-            iNotification = NULL;
-            }
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// Pairing result will be received when pairing operation completes.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::DoHandlePairServerResult( TInt aResult )
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-	if (aResult == (KHCIErrorBase-EPairingNotAllowed))
-		{
-		// if EPairingNotAllowed is recieved then any further pairing attempts will fail
-		// so don't attampt to pair
-        iPairMode = EBTOutgoingPairNone;
-		}
-    }
-
-// ---------------------------------------------------------------------------
-// Cancels possible outstanding pairing and notify user pair success.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::DoHandleRegistryNewPairedEvent( 
-        const TBTNamelessDevice& aDev )
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    TInt err( KErrNone );
-    // If pairing was performed using Just Works mode, we set a 
-    // UICookie to indicate that the device is successfully 
-    // bonded so that this device will be listed in paired device view of
-    // bluetooth application:
-    if ( aDev.LinkKeyType() == ELinkKeyUnauthenticatedNonUpgradable )
-        {
-        BOstrace0(TRACE_DEBUG,DUMMY_DEVLIST,"[BTNOTIF] Outgoing Pairing, Just Works pairing");
-        err = iParent.AddUiCookieJustWorksPaired( aDev );
-        }
-    iActive->Cancel();
-    SetPairResult( err ? err : KErrNone );
-    if(err == KErrNone){
-    TRAP_IGNORE(ShowPairingResultNoteL(err));
-    }
-    iParent.OutgoingPairCompleted( err );
-    iParent.RenewPairingHandler( NULL );
-    }
-
-// ---------------------------------------------------------------------------
-// From class MBTNotifPairingAOObserver.
-// Based on the result code, decides the next operation, either try pairing 
-// with another mode, or complete pair request.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::RequestCompletedL( 
-        CBtSimpleActive* aActive, TInt aStatus )
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    BOstraceExt3(TRACE_DEBUG,DUMMY_DEVLIST,"reqid %d, status: %d, pair mode %d ", aActive->RequestId(), aStatus, iPairMode);
-    if( aActive->RequestId() == EDedicatedBonding && 
-				( aStatus == KErrRemoteDeviceIndicatedNoBonding || 
-					( aStatus && iPairMode != EBTOutgoingNoneHeadsetPairing && iPairMode != EBTOutgoingPairNone ) )   )
-        {
-        // try general pairing if the remote doesn't have dedicated bonding, or
-        // pairing fails with a headset.
-        DoPairingL();
-        }
-    else if ( aStatus && iPairMode == EBTOutgoingHeadsetAutoPairing )
-        {
-        iPairMode = EBTOutgoingHeadsetManualPairing;
-        // auto pairing with headset failed, try to pair again with manual pin:
-        BOstrace0(TRACE_DEBUG,DUMMY_DEVLIST," auto pairing failed, switch to manual pairing");     
-        DoPairingL();
-        }
-    else if ( aStatus && aActive->RequestId() == EGeneralBonding && 
-              iPairMode == EBTOutgoingHeadsetManualPairing )
-        {
-        // pairing headset with manual pin failed, wait for a while and try again:
-        iActive->SetRequestId( EGeneralBondingRetryTimer );
-        iTimer.After( iActive->iStatus, KGeneralBondingRetryDelayMicroSeconds );
-        iActive->GoActive();
-        }
-    else if( aActive->RequestId() == EGeneralBondingRetryTimer )
-        {
-        // try to pair headset again with manual pin again:
-        DoPairingL();
-        }
-    else if ( aStatus )
-        {
-        // we only starts showing note if pairing failed.
-        // For a successful pair, we must wait until registry has been updated.
-        if ( !IsPairResultSet() )
-            {
-            SetPairResult( aStatus );
-            }
-        if ( aStatus )
-            {
-            // retry pairing
-            if(aStatus && iPairingAttempt > 0)
-                {
-                if(aActive->RequestId() == EGeneralBondingRetry && iPairMode == EBTOutgoingHeadsetManualPairing)
-                    {
-                    // Headset pairing failed, reset and try again from auto pairing
-                    iActive->SetRequestId(EGeneralBonding);
-                    }
-                iPairingAttempt --;
-                ShowPairingRetryDialog();
-                }
-            else
-                {
-                iPairingAttempt --;
-                ShowPairingFailureDialog();
-                }
-             }
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// From class MBTEngActiveObserver.
-// cancels an outstanding request according to the given id.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::CancelRequest( TInt aRequestId )
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    switch ( aRequestId )
-        {
-        case EDedicatedBonding:
-            {
-            iBondingSession.Close();
-            break;
-            }
-        case EGeneralBonding:
-        case EGeneralBondingRetry:
-            {
-            iSocket.CancelConnect();
-            iSocket.Close();
-            break;
-            }
-        case EGeneralBondingRetryTimer:
-            {
-            iTimer.Cancel();
-            break;
-            }     
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// From class MBTEngActiveObserver.
-// Handles a leave in RequestCompleted by self-destructing.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::HandleError( 
-        CBtSimpleActive* aActive, TInt aError )
-    {
-    BOstrace1(TRACE_DEBUG,DUMMY_DEVLIST,"error: %d", aError );
-    // Our RunL can actually not leave, so we should never reach here.
-    (void) aActive;
-    iParent.OutgoingPairCompleted( aError );
-    iParent.RenewPairingHandler( NULL );
-    if( iNotification )
-        {
-        // Cancel the user query
-        // This will also unregister us from the notification.
-        TInt err = iNotification->Close();
-        NOTIF_NOTHANDLED( !err )
-        iNotification = NULL;
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// decide the next state and issue pair request
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::DoPairingL()
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    TPairingStageId currentMode = ( TPairingStageId ) iActive->RequestId();
-    ASSERT( !iActive->IsActive() );
-    TPairingStageId nextMode( EGeneralBonding );
-    
-    // if running BTv2.0 stack, dedicated bonding method 
-    // is not available.
-    if ( currentMode == ENoBonding && iParent.PairingServer() != NULL )
-        {
-        nextMode = EDedicatedBonding;
-        }
-    else if(currentMode == EGeneralBondingRetryTimer)
-        {
-        nextMode = EGeneralBondingRetry;
-        }
-    
-    BOstraceExt2(TRACE_DEBUG,DUMMY_DEVLIST,"[BTENG] CBTEngOtgPair::DoPairingL: bonding mode: pre %d, next %d", currentMode, nextMode);
-    
-    iActive->SetRequestId( nextMode );
-    if ( nextMode == EDedicatedBonding )
-        {
-        iBondingSession.Start( *iParent.PairingServer(), iAddr, iActive->RequestStatus() );          
-        }
-    else
-        {
-        TBTServiceSecurity sec;
-        sec.SetAuthentication( ETrue );
-        iSockAddr.SetBTAddr( iAddr );
-        iSockAddr.SetPort(KSDPPSM);
-        iSockAddr.SetSecurity( sec );    
-        iSocket.Close();
-        User::LeaveIfError( iSocket.Open( iParent.SocketServ(), KL2CAPDesC ) );
-        iSocket.Connect( iSockAddr, iActive->RequestStatus() );
-        }
-    iActive->GoActive();
-    BOstraceFunctionExit0( DUMMY_DEVLIST );
-    }
-
-// ---------------------------------------------------------------------------
-// From class MBTNotificationResult.
-// Handle a result from a user query.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::MBRDataReceived( CHbSymbianVariantMap& aData )
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    (void) aData;
-    BOstraceFunctionExit0( DUMMY_DEVLIST );
-    }
-
-// ---------------------------------------------------------------------------
-// From class MBTNotificationResult.
-// The notification is finished.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::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 ) );
-    BOstraceFunctionExit1( DUMMY_DEVLIST, this );
-    }
-
-// ---------------------------------------------------------------------------
-// Get and configure a notification.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::PrepareNotificationL( TBluetoothDialogParams::TBTDialogType aType,
-    TBTDialogResourceId aResourceId )
-    {
-    BOstraceFunctionEntry0( DUMMY_DEVLIST );
-    iNotification = 
-            iParent.ConnectionTracker().NotificationManager()->GetNotification();
-    User::LeaveIfNull( iNotification ); // For OOM exception, leaves with KErrNoMemory
-    iNotification->SetObserver( this );
-    iNotification->SetNotificationType( aType, aResourceId );
-    const CBtDevExtension* dev = iParent.BTDevRepository().Device(iAddr);
-    if(dev)
-        {
-        User::LeaveIfError(iNotification->SetData( TBluetoothDeviceDialog::EDeviceName, dev->Alias()));
-        }
-    else
-        {
-        TBTDeviceName name;
-        iAddr.GetReadable(name);
-        User::LeaveIfError(iNotification->SetData( TBluetoothDeviceDialog::EDeviceName, name));
-        NOTIF_NOTHANDLED( !err )            
-        }
-    iParent.ConnectionTracker().NotificationManager()->QueueNotificationL( iNotification);
-    NOTIF_NOTHANDLED( !err )
-    BOstraceFunctionExit0( DUMMY_DEVLIST );
-    }
-
-// ---------------------------------------------------------------------------
-// The notification is finished, handle the result.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::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() ) );
-
-    if(result() && iPairingAttempt >= 0)
-        {
-            HandleOutgoingPairL(iAddr,iCod.DeviceClass());
-        }
-    else
-        {
-            iPairingAttempt = KMaxRepeatedPairingAttempt; // reset the counter
-            iParent.OutgoingPairCompleted( KErrCancel );
-            iParent.RenewPairingHandler( NULL );
-        }
-    BOstraceFunctionExit1( DUMMY_DEVLIST, this );
-    }
-
-// ---------------------------------------------------------------------------
-// Show a dialog to ask the user to retry the pairing
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::ShowPairingRetryDialog()
-    {
-    PrepareNotificationL( TBluetoothDialogParams::EQuery, EPairingFailureRetry);
-    }
-
-// ---------------------------------------------------------------------------
-// Show a dialog to tell the user pairing retry attempt failed
-// ---------------------------------------------------------------------------
-//
-void CBTNotifOutgoingPairingHandler::ShowPairingFailureDialog()
-    {
-    PrepareNotificationL( TBluetoothDialogParams::EQuery, EPairingFailureOk );
-    }
-
-
-