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