bluetoothengine/btnotif/btnotifsrv/src/btnotifoutgoingpairinghandler.cpp
changeset 47 9e2a905b887f
parent 42 b72428996822
child 57 5ebadcda06cb
--- a/bluetoothengine/btnotif/btnotifsrv/src/btnotifoutgoingpairinghandler.cpp	Mon Jul 12 19:25:26 2010 +0300
+++ b/bluetoothengine/btnotif/btnotifsrv/src/btnotifoutgoingpairinghandler.cpp	Fri Jul 23 15:57:13 2010 +0300
@@ -20,10 +20,21 @@
 #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
     {
     /**
@@ -84,6 +95,7 @@
     {
     BaseConstructL();
     User::LeaveIfError( iTimer.CreateLocal() );
+    iPairingAttempt = KMaxRepeatedPairingAttempt;
     }
 
 // ---------------------------------------------------------------------------
@@ -113,14 +125,22 @@
     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*/ )
+TInt CBTNotifOutgoingPairingHandler::ObserveIncomingPair( const TBTDevAddr& aAddr )
     {
+    (void)aAddr;
     return KErrServerBusy;
     }
 
@@ -136,7 +156,6 @@
         // we don't allow another pairing request.
         User::Leave( KErrServerBusy );
         }
-    
     iAddr = aAddr;
     iCod = TBTDeviceClass( aCod );
     UnSetPairResult();
@@ -161,6 +180,14 @@
     {
     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;
+        }
     }
 
 
@@ -185,7 +212,7 @@
         const TUint8 KZeroPinValue = '0';
         for (TInt i = 0; i < KDefaultHeadsetPinLength; ++i)
             {
-            aPin().iPIN[i] = KZeroPinValue;
+                aPin().iPIN[i] = KZeroPinValue;
             }
         aPin().iLength = KDefaultHeadsetPinLength;
         }
@@ -202,6 +229,14 @@
         {
         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;
+            }
         }
     }
 
@@ -296,8 +331,23 @@
             }
         if ( aStatus )
             {
-            iParent.OutgoingPairCompleted( 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();
+                }
+             }
         }
     }
 
@@ -344,6 +394,14 @@
     (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;
+        }
     }
 
 // ---------------------------------------------------------------------------
@@ -390,3 +448,106 @@
     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 );
+    }
+
+
+