bluetoothengine/btnotif/btnotifsrv/src/btnotifincomingpairinghandler.cpp
changeset 33 837dcc42fd6a
child 40 997690c3397a
child 42 b72428996822
equal deleted inserted replaced
19:43824b19ee35 33:837dcc42fd6a
       
     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: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include "btnotifincomingpairinghandler.h"
       
    19 #include "btnotifpairingmanager.h"
       
    20 #include "btnotifoutgoingpairinghandler.h"
       
    21 #include <btengconstants.h>
       
    22 
       
    23 const TInt KBTNotifWaitingForPairingOkDelay = 500000; // 0.5s
       
    24 
       
    25 enum TPairingStageId
       
    26     {
       
    27     /**
       
    28      * is monitoring physical link status
       
    29      */
       
    30     EPhysicalLinkNotify = 100,
       
    31     EWaitingForPairingOk,
       
    32     };
       
    33 
       
    34 // ======== MEMBER FUNCTIONS ========
       
    35 
       
    36 // ---------------------------------------------------------------------------
       
    37 // C++ default constructor
       
    38 // ---------------------------------------------------------------------------
       
    39 //
       
    40 CBTNotifIncomingPairingHandler::CBTNotifIncomingPairingHandler( CBTNotifPairingManager& aParent, 
       
    41     const TBTDevAddr& aAddr) : CBTNotifBasePairingHandler( aParent, aAddr )
       
    42     {
       
    43     }
       
    44 
       
    45 // ---------------------------------------------------------------------------
       
    46 // 2nd phase constructor
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 void CBTNotifIncomingPairingHandler::ConstructL()
       
    50     {
       
    51     BaseConstructL();
       
    52     iActivePairingOk = CBtSimpleActive::NewL(*this, EWaitingForPairingOk );
       
    53     User::LeaveIfError( iPairingOkTimer.CreateLocal() );
       
    54     }
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 // NewL
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 CBTNotifBasePairingHandler* CBTNotifIncomingPairingHandler::NewL( CBTNotifPairingManager& aParent, 
       
    61     const TBTDevAddr& aAddr)
       
    62     {
       
    63     CBTNotifIncomingPairingHandler* self = new (ELeave) CBTNotifIncomingPairingHandler(aParent, aAddr);
       
    64     CleanupStack::PushL( self );
       
    65     self->ConstructL();
       
    66     CleanupStack::Pop( self );
       
    67     return self;
       
    68     }
       
    69 
       
    70 // ---------------------------------------------------------------------------
       
    71 // Destructor
       
    72 // ---------------------------------------------------------------------------
       
    73 //
       
    74 CBTNotifIncomingPairingHandler::~CBTNotifIncomingPairingHandler()
       
    75     {
       
    76     // TRACE_FUNC_ENTRY
       
    77     // Cancel all outstanding requests
       
    78     CancelPlaNotification();
       
    79     iPla.Close();
       
    80     delete iActivePairingOk;
       
    81     iPairingOkTimer.Close();
       
    82     // TRACE_FUNC_EXIT
       
    83     }
       
    84 
       
    85 // ---------------------------------------------------------------------------
       
    86 // Accept this message only if the specified device is the same as this is
       
    87 // dealing with.
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 TInt CBTNotifIncomingPairingHandler::ObserveIncomingPair( const TBTDevAddr& aAddr )
       
    91     {
       
    92     TInt err( KErrServerBusy );
       
    93     if ( iAddr == aAddr )
       
    94         {
       
    95         err = KErrNone;
       
    96         iUserAwarePairing = ETrue; // This function is called by a notifier, which means the UI has been involved
       
    97         // Therefore we can display it in the paired devices list
       
    98         if ( !iActive->IsActive() && !OpenPhysicalLinkAdaptor() )
       
    99             {
       
   100             // If we are observing physical link, or showing user a note,
       
   101             // we won't interrupt it.
       
   102             UnSetPairResult();
       
   103             MonitorPhysicalLink();
       
   104             }
       
   105         }
       
   106     return err;
       
   107     }
       
   108 
       
   109 // ---------------------------------------------------------------------------
       
   110 // Assign the responsibility of outgoing pair handling to CBTEngOtgPair
       
   111 // ---------------------------------------------------------------------------
       
   112 //
       
   113 void CBTNotifIncomingPairingHandler::HandleOutgoingPairL( const TBTDevAddr& aAddr, TUint aCod )
       
   114     {
       
   115     // TRACE_FUNC_ENTRY
       
   116     // Outgoing pairing always takes highest priority:
       
   117     CBTNotifBasePairingHandler* pairinghandler = CBTNotifOutgoingPairingHandler::NewL( iParent, aAddr );
       
   118     pairinghandler->HandleOutgoingPairL( aAddr, aCod );
       
   119     iParent.RenewPairingHandler( pairinghandler );
       
   120     // TRACE_FUNC_EXIT
       
   121     }
       
   122 
       
   123 // ---------------------------------------------------------------------------
       
   124 // Accept this message only if the specified device is the same as this is
       
   125 // dealing with.
       
   126 // ---------------------------------------------------------------------------
       
   127 //
       
   128 void CBTNotifIncomingPairingHandler::StopPairHandling( const TBTDevAddr& aAddr )
       
   129     {
       
   130     if ( aAddr == iAddr )
       
   131         {
       
   132         // TRACE_FUNC_ENTRY
       
   133         iParent.RenewPairingHandler( NULL );
       
   134         // TRACE_FUNC_EXIT
       
   135         }
       
   136     }
       
   137 
       
   138 // ---------------------------------------------------------------------------
       
   139 // Notify user if pairing failed.
       
   140 // ---------------------------------------------------------------------------
       
   141 //
       
   142 void CBTNotifIncomingPairingHandler::DoHandlePairServerResult( TInt aResult )
       
   143     {
       
   144     CancelPlaNotification();
       
   145     // For a successful pairing, we need wait for registry table change.
       
   146     if( aResult != KErrNone && aResult != KHCIErrorBase )
       
   147         {
       
   148         // Pair failure situation.
       
   149         SetPairResult( aResult );
       
   150         // todo: show pairing failure note.
       
   151         }
       
   152     }
       
   153 
       
   154 // ---------------------------------------------------------------------------
       
   155 // Kill this if the linkkey type indicates OBEX authentication.
       
   156 // Otherwise notify user the pair result.
       
   157 // ---------------------------------------------------------------------------
       
   158 //
       
   159 void CBTNotifIncomingPairingHandler::DoHandleRegistryNewPairedEvent( const TBTNamelessDevice& aDev )
       
   160     {
       
   161     // TRACE_FUNC_ENTRY
       
   162     
       
   163     // First of all cancel the iPairingOkTimer timer, if active
       
   164     if (iActivePairingOk->IsActive())
       
   165         {
       
   166         iActivePairingOk->Cancel();
       
   167         UnSetPairResult();  // we might have set it before (if the link went down) so we want to reset it.   
       
   168         }
       
   169     if (aDev.LinkKeyType() == ELinkKeyUnauthenticatedNonUpgradable && !iUserAwarePairing)
       
   170 		{
       
   171 		// If an application uses btengconnman API to connect a service of 
       
   172 		// this device and JW pairing occurred as part of security enforcement,
       
   173 		// it shall be a user aware pairing, and we shall add this device in paired
       
   174 		// view. In this way, user is able to disconnect the device from our UI.
       
   175 		// Otherwise the link key has been created by a device without IO requesting 
       
   176 		// a service connection with phone. We won't take any action (e.g. remove 
       
   177 		// link key) in this case. As the result, this device can't be seen in our UI, 
       
   178 		// however other applications are still freely to use its services.
       
   179 		// TRACE_INFO(_L("[BTEng]: CBTEngIncPair: JW pairing with no IO device" ) )
       
   180 		TBTEngConnectionStatus status = iParent.ConnectStatus( aDev.Address() );
       
   181 		if ( status == EBTEngConnecting || status == EBTEngConnected )
       
   182 			{
       
   183 			// the return error is ingore as we can not have other proper 
       
   184 			// exception handling option:
       
   185 			(void) iParent.AddUiCookieJustWorksPaired( aDev );
       
   186 			}
       
   187 		iParent.RenewPairingHandler( NULL );
       
   188 		}
       
   189     else if (aDev.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable && !iUserAwarePairing)
       
   190 		{
       
   191 		// The linkkey has been created  by an incoming OBEX service request
       
   192 		// which resulted a pairing event received from pair server.
       
   193 		// TRACE_INFO(_L("[BTEng]: CBTEngIncPair: JW pairing with IO device" ) )
       
   194 		  iParent.RenewPairingHandler( NULL );
       
   195 		}
       
   196     else
       
   197 		{
       
   198 		if (aDev.LinkKeyType() == ELinkKeyUnauthenticatedNonUpgradable || aDev.LinkKeyType() == ELinkKeyUnauthenticatedUpgradable)
       
   199 			{
       
   200 			// The user was involved in the pairing, so display in the paired devices list
       
   201 			(void) iParent.AddUiCookieJustWorksPaired(aDev);
       
   202 			}
       
   203 		// TRACE_INFO(_L("[BTEng]: CBTEngIncPair: Non-JW pairing"))
       
   204 		// Other pairing model than Just Works:
       
   205 		CancelPlaNotification();
       
   206 		SetPairResult( KErrNone );
       
   207 		iParent.RenewPairingHandler( NULL );
       
   208 		}
       
   209     // TRACE_FUNC_EXIT
       
   210     }
       
   211 
       
   212 // ---------------------------------------------------------------------------
       
   213 // From class MBTNotifPairingAOObserver.
       
   214 // ---------------------------------------------------------------------------
       
   215 //
       
   216 void CBTNotifIncomingPairingHandler::RequestCompletedL( CBtSimpleActive* aActive, TInt aStatus )
       
   217     {
       
   218     // TRACE_FUNC_ARG( ( _L( "aId: %d, aStatus: %d"), aId, aStatus ) )
       
   219         // Check which request completed.
       
   220     switch( aActive->RequestId() )
       
   221         {
       
   222         case EPhysicalLinkNotify:
       
   223             {
       
   224                 // Check if the link has disconnected.
       
   225             HandlePhysicalLinkResultL( aStatus );
       
   226             break;
       
   227             }
       
   228         case EWaitingForPairingOk:
       
   229             {
       
   230             // pairing failed, inform user:
       
   231             if (iPairResult == KErrNone)
       
   232                 {
       
   233                 // iPairResult must have been set as an error. if it's not it means somewhere else
       
   234                 // it has been reset. But we need to have it set to an error as we are notifying 
       
   235                 // the "unable to pair" message.
       
   236                 SetPairResult(KErrGeneral);
       
   237                 }
       
   238             iParent.RenewPairingHandler( NULL );
       
   239             break;
       
   240             } 
       
   241         default:
       
   242                 // Should not be possible, but no need for handling.
       
   243             break;
       
   244         }
       
   245     // TRACE_FUNC_EXIT
       
   246     }
       
   247 
       
   248 
       
   249 // ---------------------------------------------------------------------------
       
   250 // From class MBTEngActiveObserver.
       
   251 // cancels an outstanding request according to the given id.
       
   252 // ---------------------------------------------------------------------------
       
   253 //
       
   254 void CBTNotifIncomingPairingHandler::CancelRequest( TInt aRequestId )
       
   255     {
       
   256     switch ( aRequestId ) 
       
   257         {
       
   258         case EPhysicalLinkNotify:
       
   259             {
       
   260             iPla.CancelNextBasebandChangeEventNotifier();
       
   261             }
       
   262         case EWaitingForPairingOk:
       
   263             {
       
   264             iPairingOkTimer.Cancel();
       
   265             }
       
   266         }
       
   267     }
       
   268 
       
   269 // ---------------------------------------------------------------------------
       
   270 // From class MBTNotifPairingAOObserver.
       
   271 // Handles a leave in RequestCompleted by simply self-destructing.
       
   272 // ---------------------------------------------------------------------------
       
   273 //
       
   274 void CBTNotifIncomingPairingHandler::HandleError( CBtSimpleActive* aActive, TInt aError )
       
   275     {
       
   276     // TRACE_FUNC_ARG( ( _L( "request id: %d, error: %d" ), aId, aError ) )
       
   277     (void) aActive;
       
   278     (void) aError;
       
   279         // Our error handling is to just stop observing. 
       
   280         // Nothing critical to be preserved here, the user 
       
   281         // just won't get any notification of pairing result.
       
   282     iParent.RenewPairingHandler( NULL );
       
   283     }
       
   284 
       
   285 // ---------------------------------------------------------------------------
       
   286 // Subscribe to physical link notifications. 
       
   287 // physical link must exist when calling this function.
       
   288 // ---------------------------------------------------------------------------
       
   289 //
       
   290 void CBTNotifIncomingPairingHandler::MonitorPhysicalLink()
       
   291     {
       
   292     // TRACE_FUNC_ENTRY
       
   293     iActive->SetRequestId( EPhysicalLinkNotify );
       
   294         // Subscribe to disconnect and error events.
       
   295     iPla.NotifyNextBasebandChangeEvent( iBbEvent, 
       
   296                             iActive->RequestStatus(), 
       
   297                             ENotifyPhysicalLinkDown | ENotifyPhysicalLinkError );
       
   298     iActive->GoActive();
       
   299     // TRACE_FUNC_EXIT
       
   300     }
       
   301 
       
   302 // ---------------------------------------------------------------------------
       
   303 // Opens the adaptor if physical link exists.
       
   304 // ---------------------------------------------------------------------------
       
   305 //
       
   306 TInt CBTNotifIncomingPairingHandler::OpenPhysicalLinkAdaptor()
       
   307     {
       
   308     // TRACE_FUNC_ENTRY
       
   309     TInt err ( KErrNone );
       
   310     if( !iPla.IsOpen() )
       
   311         {
       
   312             // Try to open the adapter in case it failed earlier.
       
   313             // This can happen for outgoing dedicated bonding with 
       
   314             // non-SSP device, as the PIN dialog can be kept open even 
       
   315             // though the link has dropped because of a time-out.
       
   316         err = iPla.Open( iParent.SocketServ(), iAddr );
       
   317         }
       
   318     // TRACE_INFO( (_L("[BTEng]: CBTEngIncPair::HasPhysicalLink ? %d"), iPla.IsOpen() ) )
       
   319     return err;
       
   320     }
       
   321 
       
   322 // ---------------------------------------------------------------------------
       
   323 // Cancel outstanding physical link notification
       
   324 // ---------------------------------------------------------------------------
       
   325 //
       
   326 void CBTNotifIncomingPairingHandler::CancelPlaNotification()
       
   327     {
       
   328     // TRACE_FUNC_ENTRY
       
   329     if( iActive && iActive->RequestId() == EPhysicalLinkNotify )
       
   330         {
       
   331         // cancel Baseband monitor
       
   332         iActive->Cancel();
       
   333         }
       
   334     // TRACE_FUNC_EXIT
       
   335     }
       
   336 
       
   337 // ---------------------------------------------------------------------------
       
   338 // Handle a physical link event. Notify pair failed if physical link is down.
       
   339 // ---------------------------------------------------------------------------
       
   340 //
       
   341 void CBTNotifIncomingPairingHandler::HandlePhysicalLinkResultL( TInt aResult )
       
   342     {
       
   343     // TRACE_FUNC_ARG( ( _L( " BBEvent 0x%08X, code %d"), 
       
   344     //                        iBbEvent().EventType(), iBbEvent().SymbianErrorCode() ) )
       
   345         // Check if the connection is still alive.
       
   346     TBool physicalLinkDown = 
       
   347         ( iBbEvent().EventType() == ENotifyPhysicalLinkDown | ENotifyPhysicalLinkError );
       
   348 
       
   349     if( aResult || physicalLinkDown )
       
   350         {
       
   351         // link went down. It might be because of pairing failed or the remote device disconnected the
       
   352         // physical link after a successful pairing.
       
   353         // we wait for 0.5 secs before notifying the "unable to pair" message as, if the pair is 
       
   354         // successful, we manage it to show the right confirmation message.
       
   355         SetPairResult( (aResult == 0) ? KErrGeneral : aResult );
       
   356         iPairingOkTimer.After(iActivePairingOk->iStatus, KBTNotifWaitingForPairingOkDelay);
       
   357         iActivePairingOk->GoActive();
       
   358         }
       
   359     else
       
   360         {
       
   361         // Uninteresting event, re-subscribe.
       
   362         MonitorPhysicalLink();
       
   363         }
       
   364     // TRACE_FUNC_EXIT
       
   365     }
       
   366 
       
   367 
       
   368