bluetoothengine/btnotif/btnotifsrv/src/btnotifoutgoingpairinghandler.cpp
branchRCL_3
changeset 56 9386f31cc85b
parent 55 613943a21004
child 61 269724087bed
equal deleted inserted replaced
55:613943a21004 56:9386f31cc85b
     1 /*
       
     2 * Copyright (c) 2010 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: Pairing handler for local device initiated pairing
       
    15 *
       
    16 */
       
    17 
       
    18 #include "btnotifoutgoingpairinghandler.h"
       
    19 #include <btengconstants.h>
       
    20 #include <btservices/btdevextension.h>
       
    21 #include "btnotifsecuritymanager.h"
       
    22 #include "bluetoothtrace.h"
       
    23 #include "bluetoothnotification.h"
       
    24 #include "btnotifserver.h"
       
    25 #include "btnotifconnectiontracker.h"
       
    26 #include "btnotificationmanager.h"
       
    27 
       
    28 /**  Length of the default PIN. */
       
    29 const TInt KDefaultHeadsetPinLength = 4;
       
    30 
       
    31 /** Maximum repeated outgoing pairing attempt.
       
    32  *  if the pairing fails the UI specs says
       
    33  *  we can ask twice the user if he/she want 
       
    34  *  to retry pairing. 
       
    35  */
       
    36 const TInt KMaxRepeatedPairingAttempt = 2;
       
    37 
       
    38 enum TPairingStageId
       
    39     {
       
    40     /**
       
    41      * no pairing operation ongoing
       
    42      */
       
    43     ENoBonding = 0,
       
    44     
       
    45     /**
       
    46      * pair with dedicated bonding method
       
    47      */
       
    48     EDedicatedBonding = 200,
       
    49     
       
    50     /**
       
    51      * pair with general bonding by establishing L2CAP connection.
       
    52      */
       
    53     EGeneralBonding,  
       
    54     
       
    55     /**
       
    56      * delaying next pairing request for a while
       
    57      */
       
    58     EGeneralBondingRetryTimer,
       
    59     
       
    60     /**
       
    61      * The last pairing retry
       
    62      */
       
    63     EGeneralBondingRetry,
       
    64     
       
    65     /**
       
    66      * disconnecting physical link after pairing operation.
       
    67      * 
       
    68      * todo: not used yet.
       
    69      */
       
    70     EDisconnectLinkAfterBonding,
       
    71     };
       
    72 
       
    73 /**  SDP PSM (used for pairing) */
       
    74 const TInt KSDPPSM = 0x0001;
       
    75 
       
    76 // Delay time to void Repeated Attempts on pairing
       
    77 const TInt KGeneralBondingRetryDelayMicroSeconds = 5000000; // 5.0s
       
    78 
       
    79 // ======== MEMBER FUNCTIONS ========
       
    80 
       
    81 // ---------------------------------------------------------------------------
       
    82 // C++ default constructor
       
    83 // ---------------------------------------------------------------------------
       
    84 //
       
    85 CBTNotifOutgoingPairingHandler::CBTNotifOutgoingPairingHandler( CBTNotifSecurityManager& aParent, const TBTDevAddr& aAddr)
       
    86     :  CBTNotifBasePairingHandler( aParent, aAddr )
       
    87     {
       
    88     }
       
    89 
       
    90 // ---------------------------------------------------------------------------
       
    91 // Symbian 2nd-phase constructor
       
    92 // ---------------------------------------------------------------------------
       
    93 //
       
    94 void CBTNotifOutgoingPairingHandler::ConstructL()
       
    95     {
       
    96     BaseConstructL();
       
    97     User::LeaveIfError( iTimer.CreateLocal() );
       
    98     iPairingAttempt = KMaxRepeatedPairingAttempt;
       
    99     }
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // NewL
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 CBTNotifBasePairingHandler* CBTNotifOutgoingPairingHandler::NewL( CBTNotifSecurityManager& aParent, 
       
   106         const TBTDevAddr& aAddr )
       
   107     {
       
   108     CBTNotifOutgoingPairingHandler* self = new( ELeave ) CBTNotifOutgoingPairingHandler( aParent, aAddr );
       
   109     CleanupStack::PushL( self );
       
   110     self->ConstructL();
       
   111     CleanupStack::Pop( self );
       
   112     return self;
       
   113     }
       
   114 
       
   115 // ---------------------------------------------------------------------------
       
   116 // Destructor
       
   117 // ---------------------------------------------------------------------------
       
   118 //
       
   119 CBTNotifOutgoingPairingHandler::~CBTNotifOutgoingPairingHandler()
       
   120     {
       
   121     if ( iActive ) 
       
   122         {
       
   123         iActive->Cancel();
       
   124         }
       
   125     iBondingSession.Close();
       
   126     iSocket.Close();
       
   127     iTimer.Close();
       
   128     if( iNotification )
       
   129         {
       
   130         // Clear the notification callback, we cannot receive them anymore.
       
   131         iNotification->RemoveObserver();
       
   132         iNotification->Close(); // Also dequeues the notification from the queue.
       
   133         iNotification = NULL;
       
   134         }
       
   135     }
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // Simply deny the request as this is handing outgoing pairing
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 TInt CBTNotifOutgoingPairingHandler::ObserveIncomingPair( const TBTDevAddr& aAddr )
       
   142     {
       
   143     (void)aAddr;
       
   144     return KErrServerBusy;
       
   145     }
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 // Accept the request only this device is not busy with another pairing request.
       
   149 // ---------------------------------------------------------------------------
       
   150 //
       
   151 void CBTNotifOutgoingPairingHandler::HandleOutgoingPairL( const TBTDevAddr& aAddr, TUint aCod )
       
   152     {
       
   153     BOstrace1(TRACE_DEBUG,DUMMY_DEVLIST," cod 0x%08x", aCod );
       
   154     if ( iActive->IsActive() || aAddr != iAddr )
       
   155         {
       
   156         // we don't allow another pairing request.
       
   157         User::Leave( KErrServerBusy );
       
   158         }
       
   159     iAddr = aAddr;
       
   160     iCod = TBTDeviceClass( aCod );
       
   161     UnSetPairResult();
       
   162     iParent.UnpairDevice( iAddr );
       
   163     if ( CBtDevExtension::IsHeadset( iCod ) )
       
   164         {
       
   165         // If the devie is a headset, set to 0000 pin auto pairing
       
   166         iPairMode = EBTOutgoingHeadsetAutoPairing;
       
   167         }
       
   168     else
       
   169         {
       
   170         iPairMode = EBTOutgoingNoneHeadsetPairing;
       
   171         }
       
   172     DoPairingL();
       
   173     }
       
   174 
       
   175 // ---------------------------------------------------------------------------
       
   176 // Cancels an outstanding pair request by self-destruct
       
   177 // ---------------------------------------------------------------------------
       
   178 //
       
   179 void CBTNotifOutgoingPairingHandler::CancelOutgoingPair()
       
   180     {
       
   181     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   182     iParent.RenewPairingHandler( NULL );
       
   183     if( iNotification )
       
   184         {
       
   185         // Cancel the user query
       
   186         // This will also unregister us from the notification.
       
   187         TInt err = iNotification->Close();
       
   188         NOTIF_NOTHANDLED( !err )
       
   189         iNotification = NULL;
       
   190         }
       
   191     }
       
   192 
       
   193 
       
   194 // ---------------------------------------------------------------------------
       
   195 // when phone initiated a pairing request towards a headset,
       
   196 // Pin code 0000 is first tried.
       
   197 // ---------------------------------------------------------------------------
       
   198 //
       
   199 void CBTNotifOutgoingPairingHandler::GetPinCode( 
       
   200         TBTPinCode& aPin, const TBTDevAddr& aAddr, TInt aMinPinLength )
       
   201     {
       
   202     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   203     aPin().iLength = 0;
       
   204     if ( aMinPinLength <= KDefaultHeadsetPinLength 
       
   205             && aAddr == iAddr
       
   206             && iPairMode == EBTOutgoingHeadsetAutoPairing)
       
   207         {
       
   208         // if the pairing requires a stronger security level (indicated
       
   209         // by aMinPinLength), 
       
   210         // 0000 will not be supplied as it does not mmet the security
       
   211         // requirements
       
   212         const TUint8 KZeroPinValue = '0';
       
   213         for (TInt i = 0; i < KDefaultHeadsetPinLength; ++i)
       
   214             {
       
   215                 aPin().iPIN[i] = KZeroPinValue;
       
   216             }
       
   217         aPin().iLength = KDefaultHeadsetPinLength;
       
   218         }
       
   219     }
       
   220 
       
   221 // ---------------------------------------------------------------------------
       
   222 // Abort pairing handling, request the owner to destroy this.
       
   223 // ---------------------------------------------------------------------------
       
   224 //
       
   225 void CBTNotifOutgoingPairingHandler::StopPairHandling( const TBTDevAddr& aAddr )
       
   226     {
       
   227     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   228     if ( aAddr == iAddr )
       
   229         {
       
   230         iParent.OutgoingPairCompleted( KErrCancel );
       
   231         iParent.RenewPairingHandler( NULL );
       
   232         if( iNotification )
       
   233             {
       
   234             // Cancel the user query
       
   235             // This will also unregister us from the notification.
       
   236             TInt err = iNotification->Close();
       
   237             NOTIF_NOTHANDLED( !err )
       
   238             iNotification = NULL;
       
   239             }
       
   240         }
       
   241     }
       
   242 
       
   243 // ---------------------------------------------------------------------------
       
   244 // Pairing result will be received when pairing operation completes.
       
   245 // ---------------------------------------------------------------------------
       
   246 //
       
   247 void CBTNotifOutgoingPairingHandler::DoHandlePairServerResult( TInt aResult )
       
   248     {
       
   249     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   250 	if (aResult == (KHCIErrorBase-EPairingNotAllowed))
       
   251 		{
       
   252 		// if EPairingNotAllowed is recieved then any further pairing attempts will fail
       
   253 		// so don't attampt to pair
       
   254         iPairMode = EBTOutgoingPairNone;
       
   255 		}
       
   256     }
       
   257 
       
   258 // ---------------------------------------------------------------------------
       
   259 // Cancels possible outstanding pairing and notify user pair success.
       
   260 // ---------------------------------------------------------------------------
       
   261 //
       
   262 void CBTNotifOutgoingPairingHandler::DoHandleRegistryNewPairedEvent( 
       
   263         const TBTNamelessDevice& aDev )
       
   264     {
       
   265     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   266     TInt err( KErrNone );
       
   267     // If pairing was performed using Just Works mode, we set a 
       
   268     // UICookie to indicate that the device is successfully 
       
   269     // bonded so that this device will be listed in paired device view of
       
   270     // bluetooth application:
       
   271     if ( aDev.LinkKeyType() == ELinkKeyUnauthenticatedNonUpgradable )
       
   272         {
       
   273         BOstrace0(TRACE_DEBUG,DUMMY_DEVLIST,"[BTNOTIF] Outgoing Pairing, Just Works pairing");
       
   274         err = iParent.AddUiCookieJustWorksPaired( aDev );
       
   275         }
       
   276     iActive->Cancel();
       
   277     SetPairResult( err ? err : KErrNone );
       
   278     if(err == KErrNone){
       
   279     TRAP_IGNORE(ShowPairingResultNoteL(err));
       
   280     }
       
   281     iParent.OutgoingPairCompleted( err );
       
   282     iParent.RenewPairingHandler( NULL );
       
   283     }
       
   284 
       
   285 // ---------------------------------------------------------------------------
       
   286 // From class MBTNotifPairingAOObserver.
       
   287 // Based on the result code, decides the next operation, either try pairing 
       
   288 // with another mode, or complete pair request.
       
   289 // ---------------------------------------------------------------------------
       
   290 //
       
   291 void CBTNotifOutgoingPairingHandler::RequestCompletedL( 
       
   292         CBtSimpleActive* aActive, TInt aStatus )
       
   293     {
       
   294     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   295     BOstraceExt3(TRACE_DEBUG,DUMMY_DEVLIST,"reqid %d, status: %d, pair mode %d ", aActive->RequestId(), aStatus, iPairMode);
       
   296     if( aActive->RequestId() == EDedicatedBonding && 
       
   297 				( aStatus == KErrRemoteDeviceIndicatedNoBonding || 
       
   298 					( aStatus && iPairMode != EBTOutgoingNoneHeadsetPairing && iPairMode != EBTOutgoingPairNone ) )   )
       
   299         {
       
   300         // try general pairing if the remote doesn't have dedicated bonding, or
       
   301         // pairing fails with a headset.
       
   302         DoPairingL();
       
   303         }
       
   304     else if ( aStatus && iPairMode == EBTOutgoingHeadsetAutoPairing )
       
   305         {
       
   306         iPairMode = EBTOutgoingHeadsetManualPairing;
       
   307         // auto pairing with headset failed, try to pair again with manual pin:
       
   308         BOstrace0(TRACE_DEBUG,DUMMY_DEVLIST," auto pairing failed, switch to manual pairing");     
       
   309         DoPairingL();
       
   310         }
       
   311     else if ( aStatus && aActive->RequestId() == EGeneralBonding && 
       
   312               iPairMode == EBTOutgoingHeadsetManualPairing )
       
   313         {
       
   314         // pairing headset with manual pin failed, wait for a while and try again:
       
   315         iActive->SetRequestId( EGeneralBondingRetryTimer );
       
   316         iTimer.After( iActive->iStatus, KGeneralBondingRetryDelayMicroSeconds );
       
   317         iActive->GoActive();
       
   318         }
       
   319     else if( aActive->RequestId() == EGeneralBondingRetryTimer )
       
   320         {
       
   321         // try to pair headset again with manual pin again:
       
   322         DoPairingL();
       
   323         }
       
   324     else if ( aStatus )
       
   325         {
       
   326         // we only starts showing note if pairing failed.
       
   327         // For a successful pair, we must wait until registry has been updated.
       
   328         if ( !IsPairResultSet() )
       
   329             {
       
   330             SetPairResult( aStatus );
       
   331             }
       
   332         if ( aStatus )
       
   333             {
       
   334             // retry pairing
       
   335             if(aStatus && iPairingAttempt > 0)
       
   336                 {
       
   337                 if(aActive->RequestId() == EGeneralBondingRetry && iPairMode == EBTOutgoingHeadsetManualPairing)
       
   338                     {
       
   339                     // Headset pairing failed, reset and try again from auto pairing
       
   340                     iActive->SetRequestId(EGeneralBonding);
       
   341                     }
       
   342                 iPairingAttempt --;
       
   343                 ShowPairingRetryDialog();
       
   344                 }
       
   345             else
       
   346                 {
       
   347                 iPairingAttempt --;
       
   348                 ShowPairingFailureDialog();
       
   349                 }
       
   350              }
       
   351         }
       
   352     }
       
   353 
       
   354 // ---------------------------------------------------------------------------
       
   355 // From class MBTEngActiveObserver.
       
   356 // cancels an outstanding request according to the given id.
       
   357 // ---------------------------------------------------------------------------
       
   358 //
       
   359 void CBTNotifOutgoingPairingHandler::CancelRequest( TInt aRequestId )
       
   360     {
       
   361     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   362     switch ( aRequestId )
       
   363         {
       
   364         case EDedicatedBonding:
       
   365             {
       
   366             iBondingSession.Close();
       
   367             break;
       
   368             }
       
   369         case EGeneralBonding:
       
   370         case EGeneralBondingRetry:
       
   371             {
       
   372             iSocket.CancelConnect();
       
   373             iSocket.Close();
       
   374             break;
       
   375             }
       
   376         case EGeneralBondingRetryTimer:
       
   377             {
       
   378             iTimer.Cancel();
       
   379             break;
       
   380             }     
       
   381         }
       
   382     }
       
   383 
       
   384 // ---------------------------------------------------------------------------
       
   385 // From class MBTEngActiveObserver.
       
   386 // Handles a leave in RequestCompleted by self-destructing.
       
   387 // ---------------------------------------------------------------------------
       
   388 //
       
   389 void CBTNotifOutgoingPairingHandler::HandleError( 
       
   390         CBtSimpleActive* aActive, TInt aError )
       
   391     {
       
   392     BOstrace1(TRACE_DEBUG,DUMMY_DEVLIST,"error: %d", aError );
       
   393     // Our RunL can actually not leave, so we should never reach here.
       
   394     (void) aActive;
       
   395     iParent.OutgoingPairCompleted( aError );
       
   396     iParent.RenewPairingHandler( NULL );
       
   397     if( iNotification )
       
   398         {
       
   399         // Cancel the user query
       
   400         // This will also unregister us from the notification.
       
   401         TInt err = iNotification->Close();
       
   402         NOTIF_NOTHANDLED( !err )
       
   403         iNotification = NULL;
       
   404         }
       
   405     }
       
   406 
       
   407 // ---------------------------------------------------------------------------
       
   408 // decide the next state and issue pair request
       
   409 // ---------------------------------------------------------------------------
       
   410 //
       
   411 void CBTNotifOutgoingPairingHandler::DoPairingL()
       
   412     {
       
   413     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   414     TPairingStageId currentMode = ( TPairingStageId ) iActive->RequestId();
       
   415     ASSERT( !iActive->IsActive() );
       
   416     TPairingStageId nextMode( EGeneralBonding );
       
   417     
       
   418     // if running BTv2.0 stack, dedicated bonding method 
       
   419     // is not available.
       
   420     if ( currentMode == ENoBonding && iParent.PairingServer() != NULL )
       
   421         {
       
   422         nextMode = EDedicatedBonding;
       
   423         }
       
   424     else if(currentMode == EGeneralBondingRetryTimer)
       
   425         {
       
   426         nextMode = EGeneralBondingRetry;
       
   427         }
       
   428     
       
   429     BOstraceExt2(TRACE_DEBUG,DUMMY_DEVLIST,"[BTENG] CBTEngOtgPair::DoPairingL: bonding mode: pre %d, next %d", currentMode, nextMode);
       
   430     
       
   431     iActive->SetRequestId( nextMode );
       
   432     if ( nextMode == EDedicatedBonding )
       
   433         {
       
   434         iBondingSession.Start( *iParent.PairingServer(), iAddr, iActive->RequestStatus() );          
       
   435         }
       
   436     else
       
   437         {
       
   438         TBTServiceSecurity sec;
       
   439         sec.SetAuthentication( ETrue );
       
   440         iSockAddr.SetBTAddr( iAddr );
       
   441         iSockAddr.SetPort(KSDPPSM);
       
   442         iSockAddr.SetSecurity( sec );    
       
   443         iSocket.Close();
       
   444         User::LeaveIfError( iSocket.Open( iParent.SocketServ(), KL2CAPDesC ) );
       
   445         iSocket.Connect( iSockAddr, iActive->RequestStatus() );
       
   446         }
       
   447     iActive->GoActive();
       
   448     BOstraceFunctionExit0( DUMMY_DEVLIST );
       
   449     }
       
   450 
       
   451 // ---------------------------------------------------------------------------
       
   452 // From class MBTNotificationResult.
       
   453 // Handle a result from a user query.
       
   454 // ---------------------------------------------------------------------------
       
   455 //
       
   456 void CBTNotifOutgoingPairingHandler::MBRDataReceived( CHbSymbianVariantMap& aData )
       
   457     {
       
   458     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   459     (void) aData;
       
   460     BOstraceFunctionExit0( DUMMY_DEVLIST );
       
   461     }
       
   462 
       
   463 // ---------------------------------------------------------------------------
       
   464 // From class MBTNotificationResult.
       
   465 // The notification is finished.
       
   466 // ---------------------------------------------------------------------------
       
   467 //
       
   468 void CBTNotifOutgoingPairingHandler::MBRNotificationClosed( TInt aError, const TDesC8& aData )
       
   469     {
       
   470     BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aError );
       
   471     // First unregister from the notification, so we can already get the next one.
       
   472     iNotification->RemoveObserver();
       
   473     iNotification = NULL;
       
   474     TRAP_IGNORE( NotificationClosedL( aError, aData ) );
       
   475     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   476     }
       
   477 
       
   478 // ---------------------------------------------------------------------------
       
   479 // Get and configure a notification.
       
   480 // ---------------------------------------------------------------------------
       
   481 //
       
   482 void CBTNotifOutgoingPairingHandler::PrepareNotificationL( TBluetoothDialogParams::TBTDialogType aType,
       
   483     TBTDialogResourceId aResourceId )
       
   484     {
       
   485     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   486     iNotification = 
       
   487             iParent.ConnectionTracker().NotificationManager()->GetNotification();
       
   488     User::LeaveIfNull( iNotification ); // For OOM exception, leaves with KErrNoMemory
       
   489     iNotification->SetObserver( this );
       
   490     iNotification->SetNotificationType( aType, aResourceId );
       
   491     const CBtDevExtension* dev = iParent.BTDevRepository().Device(iAddr);
       
   492     if(dev)
       
   493         {
       
   494         User::LeaveIfError(iNotification->SetData( TBluetoothDeviceDialog::EDeviceName, dev->Alias()));
       
   495         }
       
   496     else
       
   497         {
       
   498         TBTDeviceName name;
       
   499         iAddr.GetReadable(name);
       
   500         User::LeaveIfError(iNotification->SetData( TBluetoothDeviceDialog::EDeviceName, name));
       
   501         NOTIF_NOTHANDLED( !err )            
       
   502         }
       
   503     iParent.ConnectionTracker().NotificationManager()->QueueNotificationL( iNotification);
       
   504     NOTIF_NOTHANDLED( !err )
       
   505     BOstraceFunctionExit0( DUMMY_DEVLIST );
       
   506     }
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // The notification is finished, handle the result.
       
   510 // ---------------------------------------------------------------------------
       
   511 //
       
   512 void CBTNotifOutgoingPairingHandler::NotificationClosedL( TInt aError, const TDesC8& aData )
       
   513     {
       
   514     BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aError );
       
   515     // Read the result.
       
   516     TPckgC<TBool> result( EFalse );
       
   517     result.Set( aData.Ptr(), result.Length() ); // Read the part containing the result
       
   518     // Set a pointer descriptor to capture the remaining data, if any.
       
   519     TPtrC8 dataPtr( aData.Mid( result.Length() ) );
       
   520 
       
   521     if(result() && iPairingAttempt >= 0)
       
   522         {
       
   523             HandleOutgoingPairL(iAddr,iCod.DeviceClass());
       
   524         }
       
   525     else
       
   526         {
       
   527             iPairingAttempt = KMaxRepeatedPairingAttempt; // reset the counter
       
   528             iParent.OutgoingPairCompleted( KErrCancel );
       
   529             iParent.RenewPairingHandler( NULL );
       
   530         }
       
   531     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   532     }
       
   533 
       
   534 // ---------------------------------------------------------------------------
       
   535 // Show a dialog to ask the user to retry the pairing
       
   536 // ---------------------------------------------------------------------------
       
   537 //
       
   538 void CBTNotifOutgoingPairingHandler::ShowPairingRetryDialog()
       
   539     {
       
   540     PrepareNotificationL( TBluetoothDialogParams::EQuery, EPairingFailureRetry);
       
   541     }
       
   542 
       
   543 // ---------------------------------------------------------------------------
       
   544 // Show a dialog to tell the user pairing retry attempt failed
       
   545 // ---------------------------------------------------------------------------
       
   546 //
       
   547 void CBTNotifOutgoingPairingHandler::ShowPairingFailureDialog()
       
   548     {
       
   549     PrepareNotificationL( TBluetoothDialogParams::EQuery, EPairingFailureOk );
       
   550     }
       
   551 
       
   552 
       
   553