bluetoothengine/btnotif/btnotifsrv/src/btnotifpairingmanager.cpp
changeset 31 a0ea99b6fa53
equal deleted inserted replaced
30:df7a93ede42e 31:a0ea99b6fa53
       
     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 "btnotifpairingmanager.h"
       
    19 #include "btnotifoutgoingpairinghandler.h"
       
    20 #include "btnotifincomingpairinghandler.h"
       
    21 #include "btnotifpairnotifier.h"
       
    22 #include "btnotifclientserver.h"
       
    23 #include <e32property.h>
       
    24 #include "btnotifconnectiontracker.h"
       
    25 
       
    26 /**  Identification for active object */
       
    27 enum TPairManActiveRequestId
       
    28     {
       
    29     ESimplePairingResult,
       
    30     EAuthenticationResult,
       
    31     ERegistryGetLocalAddress,
       
    32     };
       
    33 
       
    34 // ---------------------------------------------------------------------------
       
    35 // Tells if two TBTNamelessDevice instances are for the same remote device
       
    36 // ---------------------------------------------------------------------------
       
    37 //
       
    38 TBool CompareDeviceByAddress( const TBTNamelessDevice& aDevA, const TBTNamelessDevice& aDevB )
       
    39     {
       
    40     return aDevA.Address() == aDevB.Address();
       
    41     }
       
    42 
       
    43 // ---------------------------------------------------------------------------
       
    44 // Tells if these two instances are for the same remote device
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 TBool MatchDeviceAddress(const TBTDevAddr* aAddr, const TBTNamelessDevice& aDev)
       
    48     {
       
    49     return *aAddr == aDev.Address();
       
    50     }
       
    51 
       
    52 // ======== MEMBER FUNCTIONS ========
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // C++ default constructor
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 CBTNotifPairingManager::CBTNotifPairingManager(
       
    59         CBTNotifConnectionTracker& aParent,
       
    60         CBtDevRepository& aDevRepository)
       
    61     : iParent( aParent ), iDevRepository( aDevRepository )
       
    62     {
       
    63     }
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // Symbian 2nd-phase constructor
       
    67 // ---------------------------------------------------------------------------
       
    68 //
       
    69 void CBTNotifPairingManager::ConstructL()
       
    70     {
       
    71     // Connect to pairing server for authentication & simple pairing 
       
    72     // results directly from the BT stack.
       
    73     // Pairing server doesn't exist if we run BT 2.0 stack:
       
    74     iPairingServ = new (ELeave) RBluetoothPairingServer;
       
    75     TInt err = iPairingServ->Connect();
       
    76     if ( err)
       
    77         {
       
    78         delete iPairingServ;
       
    79         iPairingServ = NULL;
       
    80         }
       
    81     else
       
    82         {
       
    83         User::LeaveIfError( iPairingResult.Open( *iPairingServ ) );
       
    84         User::LeaveIfError( iAuthenResult.Open( *iPairingServ ) );
       
    85         iSSPResultActive = CBtSimpleActive::NewL( *this, ESimplePairingResult );
       
    86         iAuthenResultActive = CBtSimpleActive::NewL( *this, EAuthenticationResult );
       
    87         SubscribeSspPairingResult();
       
    88         SubscribeAuthenticateResult();
       
    89         }
       
    90     User::LeaveIfError( iRegistry.Open( iParent.RegistryServerSession() ) );
       
    91     // RProperty for accessing the local device address
       
    92     User::LeaveIfError( iPropertyLocalAddr.Attach(
       
    93             KPropertyUidBluetoothCategory, KPropertyKeyBluetoothGetLocalDeviceAddress) );
       
    94     // Initialise paired devices list
       
    95     iLocalAddrActive = CBtSimpleActive::NewL( *this, ERegistryGetLocalAddress );
       
    96     SubscribeLocalAddress();
       
    97     iPairNotifier = CBTNotifPairNotifier::NewL( *this );
       
    98     iDevRepository.AddObserverL( this );
       
    99     }
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // NewL
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 CBTNotifPairingManager* CBTNotifPairingManager::NewL(
       
   106         CBTNotifConnectionTracker& aParent,
       
   107         CBtDevRepository& aDevRepository )
       
   108     {
       
   109     CBTNotifPairingManager* self = NULL;
       
   110     self = new  CBTNotifPairingManager( aParent, aDevRepository );
       
   111     CleanupStack::PushL( self );
       
   112     self->ConstructL();
       
   113     CleanupStack::Pop( self );
       
   114     return self;
       
   115     }
       
   116 
       
   117 // ---------------------------------------------------------------------------
       
   118 // Destructor
       
   119 // ---------------------------------------------------------------------------
       
   120 //
       
   121 CBTNotifPairingManager::~CBTNotifPairingManager()
       
   122     {
       
   123     delete iSSPResultActive;
       
   124     delete iAuthenResultActive;
       
   125     delete iPairNotifier;
       
   126     delete iPairingHandler;
       
   127     iPairedDevices.Close();
       
   128     iPairingResult.Close();
       
   129     iAuthenResult.Close();
       
   130     if ( iPairingServ )
       
   131         {
       
   132         iPairingServ->Close();
       
   133         delete iPairingServ;
       
   134         }
       
   135     iRegistry.Close();
       
   136     delete iLocalAddrActive;
       
   137     iPropertyLocalAddr.Close();
       
   138     if ( !iMessage.IsNull() )
       
   139         {
       
   140         iMessage.Complete( KErrCancel );
       
   141         }
       
   142     }
       
   143 
       
   144 // ---------------------------------------------------------------------------
       
   145 // Initialises the paired devices list.
       
   146 // If the local address is not available from the P&S key 
       
   147 // KPropertyKeyBluetoothGetLocalDeviceAddress, then the list may need to be 
       
   148 // updated once the H/W is switched on. This is so that any registry update 
       
   149 // from a restore operation can be included in the list, without mistaking the 
       
   150 // new devices for new pairings.
       
   151 // ---------------------------------------------------------------------------
       
   152 //
       
   153 void CBTNotifPairingManager::SubscribeLocalAddress()
       
   154     {
       
   155     // Check that we have the Bluetooth local address. If we don't then initialise anyway, but subscribe for an update.
       
   156     // This allows us to refresh our paired devices list to include updates made to the remote devices table of the 
       
   157     // Bluetooth registry from a restore operation. We need to include these devices without mistaking them for new 
       
   158     // pairings. We look solely at the P&S key for the address to avoid the condition whereby the address has been
       
   159     // entered into the reigstry but the Bluetooth Manager server has not begun the restore process yet. The signalling
       
   160     // of the P&S key will cause Bluetooth Manager to update the registry with any restored devices before fulfilling
       
   161     // any further requests.
       
   162 
       
   163     // Subscribe to local address property in case we need an update.
       
   164     iPropertyLocalAddr.Subscribe( iLocalAddrActive->iStatus );
       
   165     iLocalAddrActive->SetRequestId( ERegistryGetLocalAddress );
       
   166     iLocalAddrActive->GoActive();
       
   167     }
       
   168 
       
   169 // ---------------------------------------------------------------------------
       
   170 // Tells whether the local address is available from the P&S key 
       
   171 // KPropertyKeyBluetoothGetLocalDeviceAddress.
       
   172 // ---------------------------------------------------------------------------
       
   173 //
       
   174 TBool CBTNotifPairingManager::IsLocalAddressAvailable()
       
   175     {
       
   176     // Attempt to read address from P&S key.
       
   177     TBuf8<KBTDevAddrSize> btAddrDes;
       
   178     TInt err = iPropertyLocalAddr.Get( btAddrDes );
       
   179 
       
   180     // Is the P&S key defined yet? (if not, stack not up yet)
       
   181     if ( err == KErrNone )
       
   182         {
       
   183         // P&S key defined, is local address set? (if not, H/W not initialised yet)
       
   184         if ( btAddrDes.Length() == KBTDevAddrSize )
       
   185             {
       
   186             TBTDevAddr btAddr = btAddrDes;
       
   187             if ( btAddr != TBTDevAddr() )
       
   188                 {
       
   189                 return ETrue;
       
   190                 }
       
   191             }
       
   192         }
       
   193     return EFalse;
       
   194     }
       
   195 
       
   196 // ---------------------------------------------------------------------------
       
   197 // Handles pairing related requests from BTNotif clients.
       
   198 // ---------------------------------------------------------------------------
       
   199 //
       
   200 void CBTNotifPairingManager::HandleBondingRequestL( const RMessage2& aMessage )
       
   201     {
       
   202     TInt opcode = aMessage.Function();
       
   203     TBTDevAddrPckgBuf addrPkg;
       
   204     switch( opcode )
       
   205         {
       
   206         case EBTNotifPairDevice:
       
   207             {
       
   208             if ( !iMessage.IsNull() )
       
   209                 {
       
   210                 User::Leave( KErrServerBusy );
       
   211                 }
       
   212             TBTDevAddrPckgBuf addrPkg;
       
   213             aMessage.ReadL( EBTNotifSrvParamSlot, addrPkg );
       
   214             UnpairDevice( addrPkg() );
       
   215             PairDeviceL( addrPkg(), aMessage.Int2() );
       
   216             iMessage = RMessage2( aMessage );
       
   217             break;
       
   218             }
       
   219         case EBTNotifCancelPairDevice:
       
   220             {
       
   221             // Only the client who requested pairing can cancel it:
       
   222             if ( !iMessage.IsNull() && aMessage.Session() == iMessage.Session() )
       
   223                 {
       
   224                 iPairingHandler->CancelOutgoingPair();
       
   225                 iMessage.Complete( KErrCancel );
       
   226                 }
       
   227             aMessage.Complete( KErrNone );
       
   228             break;
       
   229             }
       
   230         default:
       
   231             {
       
   232             User::Leave( KErrArgument );
       
   233             }
       
   234         }
       
   235     }
       
   236 
       
   237 // ---------------------------------------------------------------------------
       
   238 // Process a client message related to notifiers.
       
   239 // ---------------------------------------------------------------------------
       
   240 //
       
   241 void CBTNotifPairingManager::HandlePairingNotifierRequestL( const RMessage2& aMessage )
       
   242     {
       
   243     iPairNotifier->StartPairingNotifierL( aMessage );
       
   244     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   245     }
       
   246 
       
   247 // ---------------------------------------------------------------------------
       
   248 // Returns the RBluetoothPairingServer instance.
       
   249 // ---------------------------------------------------------------------------
       
   250 //
       
   251 RBluetoothPairingServer* CBTNotifPairingManager::PairingServer()
       
   252     {
       
   253     return iPairingServ;
       
   254     }
       
   255 
       
   256 // ---------------------------------------------------------------------------
       
   257 // Access the reference of RSockServ
       
   258 // ---------------------------------------------------------------------------
       
   259 //
       
   260 RSocketServ& CBTNotifPairingManager::SocketServ()
       
   261     {
       
   262     return iParent.SocketServerSession();
       
   263     }
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // Access the reference of RBTRegSrv
       
   267 // ---------------------------------------------------------------------------
       
   268 //
       
   269 CBtDevRepository& CBTNotifPairingManager::BTDevRepository()
       
   270     {
       
   271     return iDevRepository;
       
   272     }
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 // Access the reference of CBTNotifConnectionTracker
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 CBTNotifConnectionTracker& CBTNotifPairingManager::ConnectionTracker()
       
   279     {
       
   280     return iParent;
       
   281     }
       
   282 
       
   283 // ---------------------------------------------------------------------------
       
   284 // Deletes the current pairing handler and transfer the responsibility
       
   285 // to the specified.
       
   286 // ---------------------------------------------------------------------------
       
   287 //
       
   288 void CBTNotifPairingManager::RenewPairingHandler( 
       
   289         CBTNotifBasePairingHandler* aPairingHandler )
       
   290     {
       
   291     delete iPairingHandler;
       
   292     iPairingHandler = aPairingHandler;
       
   293     }
       
   294 
       
   295 // ---------------------------------------------------------------------------
       
   296 // Find the session who requested this and completes its request.
       
   297 // ---------------------------------------------------------------------------
       
   298 //
       
   299 void CBTNotifPairingManager::OutgoingPairCompleted( TInt aErr )
       
   300     {
       
   301     // the meaning of KHCIErrorBase equals KErrNone. Hide this specific BT stack
       
   302 	// detail from clients:
       
   303     if ( !iMessage.IsNull()  )
       
   304         {
       
   305         iMessage.Complete( (aErr == KHCIErrorBase) ? KErrNone : aErr );
       
   306         }
       
   307     }
       
   308 
       
   309 // ---------------------------------------------------------------------------
       
   310 // A session will be ended, completes the pending request for this session.
       
   311 // ---------------------------------------------------------------------------
       
   312 //
       
   313 void CBTNotifPairingManager::SessionClosed( CSession2* aSession )
       
   314     {
       
   315     // TRACE_FUNC_ARG( ( _L( " session %x"), aSession ) )
       
   316     if ( !iMessage.IsNull() && iMessage.Session() == aSession )
       
   317         {
       
   318         iMessage.Complete( KErrCancel );
       
   319         }
       
   320     }
       
   321 
       
   322 // ---------------------------------------------------------------------------
       
   323 // Unpair the device from registry
       
   324 // ---------------------------------------------------------------------------
       
   325 //
       
   326 void CBTNotifPairingManager::UnpairDevice( const TBTDevAddr& aAddr )
       
   327     {
       
   328     TIdentityRelation<TBTNamelessDevice> addrComp( CompareDeviceByAddress );
       
   329     TBTNamelessDevice dev;
       
   330     dev.SetAddress( aAddr );
       
   331     // only do unpairing if the we have a link key with it.
       
   332     TInt index = iPairedDevices.Find( dev, addrComp );
       
   333     if ( index > KErrNotFound )
       
   334         {
       
   335         dev = iPairedDevices[index];
       
   336         TRequestStatus status( KRequestPending );
       
   337         // Unpair the device in registry (synchronously)
       
   338         iRegistry.UnpairDevice( dev.Address(), status );
       
   339         User::WaitForRequest( status );
       
   340         // TRACE_INFO( ( _L( "Delete link key, res %d"), status.Int() ) )
       
   341         if ( status == KErrNone )
       
   342             {
       
   343             TBTDeviceSecurity security = dev.GlobalSecurity();
       
   344             // Clear trust setting so that correct icon will be shown in ui applications.
       
   345             security.SetNoAuthenticate(EFalse );
       
   346             security.SetNoAuthorise(EFalse );
       
   347             dev.SetGlobalSecurity(security);
       
   348             dev.DeleteLinkKey();
       
   349             if ( dev.IsValidUiCookie() && 
       
   350                  ( dev.UiCookie() & EBTUiCookieJustWorksPaired ) )
       
   351                 {
       
   352                 // Remove the UI cookie bit for Just Works pairing.
       
   353                 TInt32 cookie = dev.UiCookie() & ~EBTUiCookieJustWorksPaired;
       
   354                 dev.SetUiCookie( cookie );
       
   355                 // TRACE_INFO( ( _L( "UI cookie %x cleared"), EBTUiCookieJustWorksPaired ) );
       
   356                 }
       
   357             // modify the device in registry synchronously
       
   358             // status.Int() could be -1 if the device is not in registry 
       
   359             // which is totally fine for us.
       
   360             (void) UpdateRegDevice( dev );
       
   361             }
       
   362         }
       
   363     }
       
   364 
       
   365 TInt CBTNotifPairingManager::AddUiCookieJustWorksPaired( const TBTNamelessDevice& aDev )
       
   366     {
       
   367     TInt err( KErrNone );
       
   368     // There might be UI cookies used by other applications,
       
   369     // we should not overwrite them. 
       
   370     TInt32 cookie = aDev.IsValidUiCookie() ? aDev.UiCookie() : EBTUiCookieUndefined;
       
   371     if ( !( cookie & EBTUiCookieJustWorksPaired ) )
       
   372         {
       
   373         // Only update the cookie if the wanted one is not in registry yet
       
   374         // to keep minimal operations with registry.
       
   375         TBTNamelessDevice dev = aDev;		
       
   376         cookie |= EBTUiCookieJustWorksPaired;
       
   377         dev.SetUiCookie( cookie );
       
   378         err = UpdateRegDevice( dev );
       
   379         // TRACE_INFO( ( _L( "[BTENG] CBTEngOtgPair write Ui cookie ret %d"), err ) );
       
   380         }
       
   381     return err;
       
   382     }
       
   383 
       
   384 // ---------------------------------------------------------------------------
       
   385 // update a nameless device in registry
       
   386 // ---------------------------------------------------------------------------
       
   387 //
       
   388 TInt CBTNotifPairingManager::UpdateRegDevice( const TBTNamelessDevice& aDev )
       
   389     {
       
   390     TRequestStatus status( KRequestPending );
       
   391     // update the device in registry synchronously
       
   392     iRegistry.ModifyDevice( aDev, status );
       
   393     User::WaitForRequest( status );
       
   394     // TRACE_INFO( ( _L( "UpdateRegDevice, ret %d"), status.Int() ) )
       
   395     return status.Int();
       
   396     }
       
   397 
       
   398 // ---------------------------------------------------------------------------
       
   399 // 0000 for outgoing pairing with a headset.
       
   400 // The placeholder for future extension (pin code passed in for pairing)
       
   401 // ---------------------------------------------------------------------------
       
   402 //
       
   403 void CBTNotifPairingManager::GetPinCode(
       
   404         TBTPinCode& aPin, const TBTDevAddr& aAddr, TInt aMinPinLength )
       
   405     {
       
   406     if ( iPairingHandler )
       
   407         {
       
   408         iPairingHandler->GetPinCode( aPin, aAddr, aMinPinLength );
       
   409         }
       
   410     else
       
   411         {
       
   412         // make sure not to leave any text as PIN.
       
   413         aPin.Zero();
       
   414         }
       
   415     }
       
   416 
       
   417 // ---------------------------------------------------------------------------
       
   418 // Ask server class the connection status of the specified device
       
   419 // ---------------------------------------------------------------------------
       
   420 //
       
   421 TBTEngConnectionStatus CBTNotifPairingManager::ConnectStatus( const TBTDevAddr& aAddr )
       
   422     {
       
   423     const CBtDevExtension* devExt = iDevRepository.Device(aAddr);
       
   424     TBTEngConnectionStatus status = EBTEngNotConnected;
       
   425     if ( devExt ) 
       
   426         {
       
   427         status = devExt->ServiceConnectionStatus();
       
   428         }
       
   429     return status;
       
   430     }
       
   431 
       
   432 // ---------------------------------------------------------------------------
       
   433 // From class MBTNotifPairingAOObserver.
       
   434 // Checks if there is an authentication result.
       
   435 // ---------------------------------------------------------------------------
       
   436 //
       
   437 void CBTNotifPairingManager::RequestCompletedL( CBtSimpleActive* aActive, TInt aStatus )
       
   438     {
       
   439     // TRACE_FUNC_ARG( ( _L( "aId: %d, aStatus: %d"), aId, aStatus ) )
       
   440     // Check which request is completed.
       
   441     switch( aActive->RequestId() )
       
   442         {
       
   443         case ESimplePairingResult:
       
   444             {
       
   445             TBTDevAddr tmpAddr = iSimplePairingRemote;
       
   446             if (aStatus != KErrServerTerminated)
       
   447                 {
       
   448                 SubscribeSspPairingResult();
       
   449                 }
       
   450             HandlePairingResultL( tmpAddr, aStatus );
       
   451             break;
       
   452             }
       
   453         case EAuthenticationResult:
       
   454             {
       
   455             TBTDevAddr tmpAddr = iAuthenticateRemote;
       
   456             if (aStatus != KErrServerTerminated)
       
   457                 {
       
   458                 SubscribeAuthenticateResult();
       
   459                 }
       
   460             HandlePairingResultL( tmpAddr, aStatus );
       
   461             break;
       
   462             }
       
   463         case ERegistryGetLocalAddress:
       
   464             {
       
   465             TBool value = IsLocalAddressAvailable();
       
   466             SubscribeLocalAddress();
       
   467             if ( value ) 
       
   468                 {
       
   469                 // Refresh paired devices list to include any restored devices.
       
   470                 iDevRepository.ReInitialize();
       
   471                 }
       
   472             break;
       
   473             }
       
   474         default:
       
   475             // Should not be possible, but no need for handling.
       
   476             break;
       
   477         }
       
   478     }
       
   479 
       
   480 // ---------------------------------------------------------------------------
       
   481 // From class MBTEngActiveObserver.
       
   482 // cancels an outstanding request according to the given id.
       
   483 // ---------------------------------------------------------------------------
       
   484 //
       
   485 void CBTNotifPairingManager::CancelRequest( TInt aRequestId )
       
   486     {
       
   487     switch ( aRequestId )
       
   488         {
       
   489         case ESimplePairingResult:
       
   490             {
       
   491             // Cancel listening Simple pairing result
       
   492             iPairingResult.CancelSimplePairingResult();
       
   493             break;
       
   494             }
       
   495         case EAuthenticationResult:
       
   496             {
       
   497             // Cancel listening authentication result
       
   498             iAuthenResult.CancelAuthenticationResult();
       
   499             break;
       
   500             }
       
   501         case ERegistryGetLocalAddress:
       
   502             {
       
   503             // cancel listening local address status change
       
   504             iPropertyLocalAddr.Cancel();
       
   505             break;
       
   506             }
       
   507         }
       
   508     }
       
   509 
       
   510 // ---------------------------------------------------------------------------
       
   511 // From class MBtSimpleActiveObserver.
       
   512 // ---------------------------------------------------------------------------
       
   513 //
       
   514 void CBTNotifPairingManager::HandleError( CBtSimpleActive* aActive, TInt aError )
       
   515     {
       
   516     // TRACE_FUNC_ARG( ( _L( "request id: %d, error: %d" ), aId, aError ) )
       
   517     (void) aActive;
       
   518     (void) aError;
       
   519     }
       
   520 
       
   521 // ---------------------------------------------------------------------------
       
   522 // From class MBtDevRepositoryObserver.
       
   523 // ---------------------------------------------------------------------------
       
   524 //
       
   525 void CBTNotifPairingManager::RepositoryInitialized()
       
   526     {
       
   527     TRAPD(err, UpdatePairedDeviceListL() );
       
   528     if ( !err && iPairingHandler )
       
   529         {
       
   530         // non-null pairing handler means we are involved in a
       
   531         // pairing operation already.
       
   532         // todo: is some handling for above case needed?
       
   533         }
       
   534     }
       
   535 
       
   536 // ---------------------------------------------------------------------------
       
   537 // From class MBtDevRepositoryObserver.
       
   538 // ---------------------------------------------------------------------------
       
   539 //
       
   540 void CBTNotifPairingManager::DeletedFromRegistry( const TBTDevAddr& aAddr )
       
   541     {
       
   542     // We are only interested in the removal of a paired device.
       
   543     // thus check whether it is in our local paired list:
       
   544     TInt i = iPairedDevices.Find( aAddr, MatchDeviceAddress);
       
   545     if ( i > KErrNotFound )
       
   546         {
       
   547         iPairedDevices.Remove( i );
       
   548         }
       
   549     }
       
   550 
       
   551 // ---------------------------------------------------------------------------
       
   552 // From class MBtDevRepositoryObserver.
       
   553 // ---------------------------------------------------------------------------
       
   554 //
       
   555 void CBTNotifPairingManager::AddedToRegistry( const CBtDevExtension& aDevice )
       
   556     {
       
   557     // We are only interested in paired device.
       
   558     if ( CBtDevExtension::IsBonded( aDevice.Device().AsNamelessDevice() ) )
       
   559         {
       
   560         TRAP_IGNORE( 
       
   561                 HandleRegistryBondingL( aDevice.Device().AsNamelessDevice() ) );
       
   562         }
       
   563     }
       
   564 
       
   565 
       
   566 // ---------------------------------------------------------------------------
       
   567 // From class MBtDevRepositoryObserver.
       
   568 // ---------------------------------------------------------------------------
       
   569 //
       
   570 void CBTNotifPairingManager::ChangedInRegistry(
       
   571         const CBtDevExtension& aDevice, TUint aSimilarity )
       
   572     {
       
   573     // We are only interested in paired device.
       
   574     // thus check whether it is in our local paired list:
       
   575     TInt i = iPairedDevices.Find( aDevice.Addr(), MatchDeviceAddress);
       
   576     TBool bonded = CBtDevExtension::IsBonded( aDevice.Device().AsNamelessDevice() );
       
   577     if ( i == KErrNotFound )
       
   578         {
       
   579         if ( bonded ) 
       
   580             {
       
   581             TRAP_IGNORE(
       
   582                     HandleRegistryBondingL( 
       
   583                             aDevice.Device().AsNamelessDevice() ) );                
       
   584             }
       
   585         return;
       
   586         }
       
   587     // Device was inregistry before, but we need to evaluate its bonding
       
   588     // status.
       
   589     // The given similarity will tell if the linkkey and paired is changed
       
   590     // or not.
       
   591     TInt pairingProperty = TBTNamelessDevice::EIsPaired 
       
   592             | TBTNamelessDevice::ELinkKey;
       
   593     if ( ( pairingProperty & aSimilarity) == pairingProperty )
       
   594         {
       
   595         // no pairing or linkkey change. Nothing to do for pairing handling.
       
   596         // but we'd better update local copy just in case other data
       
   597         // of this device is needed by someone:
       
   598         iPairedDevices[i] = aDevice.Device().AsNamelessDevice();
       
   599         return;
       
   600         }
       
   601     if ( !CBtDevExtension::IsBonded( aDevice.Device().AsNamelessDevice() ) )
       
   602         {
       
   603         // device is not user-bonded.
       
   604         iPairedDevices.Remove( i );
       
   605         return;
       
   606         }
       
   607     // it is a new paired device if its link-key has been upgraded
       
   608     if ( aDevice.Device().LinkKeyType() != ELinkKeyUnauthenticatedUpgradable )
       
   609         {
       
   610         iPairedDevices.Remove( i );
       
   611         TRAP_IGNORE(
       
   612                 HandleRegistryBondingL( 
       
   613                         aDevice.Device().AsNamelessDevice() ) );                
       
   614         }
       
   615     }
       
   616 
       
   617 // ---------------------------------------------------------------------------
       
   618 // From class MBtDevRepositoryObserver.
       
   619 // This class is not interested in such events.
       
   620 // ---------------------------------------------------------------------------
       
   621 //
       
   622 void CBTNotifPairingManager::ServiceConnectionChanged(
       
   623         const CBtDevExtension& aDevice, TBool aConnected )
       
   624     {
       
   625     (void) aDevice;
       
   626     (void) aConnected;
       
   627     }
       
   628 
       
   629 // ---------------------------------------------------------------------------
       
   630 // Activate or deactivate a pairing handler
       
   631 // ---------------------------------------------------------------------------
       
   632 //
       
   633 TInt CBTNotifPairingManager::SetPairObserver(const TBTDevAddr& aAddr, TBool aActivate)
       
   634     {
       
   635     // TRACE_FUNC_ARG( ( _L( "%d" ), aActivate ) )
       
   636     // TRACE_BDADDR( aAddr )
       
   637     TInt err( KErrNone );
       
   638     if ( !aActivate )
       
   639         {
       
   640         if ( iPairingHandler )
       
   641             {
       
   642             iPairingHandler->StopPairHandling( aAddr );
       
   643             }
       
   644         return err;
       
   645         }
       
   646     
       
   647     if ( !iPairingHandler)
       
   648         {
       
   649         // This is an incoming pair, unpair it from registry and 
       
   650         // create the handler:
       
   651         UnpairDevice( aAddr );
       
   652         TRAP( err, iPairingHandler = CBTNotifIncomingPairingHandler::NewL( *this, aAddr ));     
       
   653         }
       
   654     if ( iPairingHandler)
       
   655         {
       
   656         // let the handler decide what to do:
       
   657         err = iPairingHandler->ObserveIncomingPair( aAddr );
       
   658         }
       
   659     return err;
       
   660     }
       
   661 
       
   662 // ---------------------------------------------------------------------------
       
   663 // Delegates the request to current pair handler
       
   664 // ---------------------------------------------------------------------------
       
   665 //
       
   666 void CBTNotifPairingManager::PairDeviceL( const TBTDevAddr& aAddr, TUint32 aCod )
       
   667     {
       
   668     if ( !iPairingHandler)
       
   669         {
       
   670         // no existing pair handling, create one:
       
   671         iPairingHandler = CBTNotifOutgoingPairingHandler::NewL( *this, aAddr );
       
   672         }
       
   673     // let pair handler decide what to do:
       
   674     iPairingHandler->HandleOutgoingPairL( aAddr, aCod );
       
   675     }
       
   676 
       
   677 // ---------------------------------------------------------------------------
       
   678 // cancel Subscribings to simple pairing result and authentication result from
       
   679 // Pairing Server
       
   680 // ---------------------------------------------------------------------------
       
   681 //
       
   682 void CBTNotifPairingManager::CancelSubscribePairingAuthenticate()
       
   683     {
       
   684     if( iSSPResultActive )
       
   685         {
       
   686         // Cancel listening Simple pairing result
       
   687         iSSPResultActive->Cancel();
       
   688         }
       
   689     if( iAuthenResultActive )
       
   690         {
       
   691         iAuthenResultActive->Cancel();
       
   692         }
       
   693     }
       
   694 
       
   695 // ---------------------------------------------------------------------------
       
   696 // Subscribes to simple pairing result from Pairing Server (if not already 
       
   697 // subscribed).
       
   698 // ---------------------------------------------------------------------------
       
   699 //
       
   700 void CBTNotifPairingManager::SubscribeSspPairingResult()
       
   701     {
       
   702     if ( !iSSPResultActive->IsActive() )
       
   703         {
       
   704         iPairingResult.SimplePairingResult( iSimplePairingRemote, iSSPResultActive->RequestStatus() );
       
   705         iSSPResultActive->GoActive();
       
   706         }
       
   707     }
       
   708 
       
   709 // ---------------------------------------------------------------------------
       
   710 // Subscribes to authentication result from Pairing Server (if not already
       
   711 // subscribed).
       
   712 // ---------------------------------------------------------------------------
       
   713 //
       
   714 void CBTNotifPairingManager::SubscribeAuthenticateResult()
       
   715     {
       
   716     if ( !iAuthenResultActive->IsActive() )
       
   717         {
       
   718         // Subscribe authentication result (which requires pairing for unpaired devices)
       
   719         iAuthenResult.AuthenticationResult( iAuthenticateRemote, iAuthenResultActive->RequestStatus() );
       
   720         iAuthenResultActive->GoActive();
       
   721         }
       
   722     }
       
   723 
       
   724 // ---------------------------------------------------------------------------
       
   725 // Handle a pairing result from the pairing server.
       
   726 // ---------------------------------------------------------------------------
       
   727 //
       
   728 void CBTNotifPairingManager::HandlePairingResultL( const TBTDevAddr& aAddr, TInt aResult )
       
   729     {
       
   730     // TRACE_FUNC_ARG( (_L("result %d"), aResult ) )
       
   731     // TRACE_BDADDR( aAddr );
       
   732     if ( !iPairingHandler && ( aResult == KErrNone || aResult == KHCIErrorBase ) )
       
   733         {
       
   734         // we only create new handler if incoming pairing succeeds.
       
   735         // Pairing failure could be caused by user local cancellation, as the  
       
   736         // result, the handler was destroyed by notifier. We shall not
       
   737         // instantiate the handler again.
       
   738         // If a pairing failed due to other reasons than user local cancelling,
       
   739         // it will be catched by the already started handler 
       
   740         // (except Just Works pairing - no handler for it at all until we receive
       
   741         // registry change event. Thus if incoming JWs pairing failed, no user
       
   742         // notification will be shown.)
       
   743         iPairedDevices.Find( aAddr, MatchDeviceAddress);
       
   744         TInt index = iPairedDevices.Find( aAddr, MatchDeviceAddress);
       
   745         // If the device is not found in the old paired device list, it is a new
       
   746         // paired device:
       
   747         if ( index == KErrNotFound)
       
   748             {
       
   749             // No handler yet, create incoming pairing handler:
       
   750             iPairingHandler = CBTNotifIncomingPairingHandler::NewL( *this, aAddr );
       
   751             }
       
   752         }
       
   753     if ( iPairingHandler )
       
   754         {
       
   755         iPairingHandler->HandlePairServerResult( aAddr, aResult );
       
   756         }
       
   757     }
       
   758 
       
   759 // ---------------------------------------------------------------------------
       
   760 // copy the nameless devices to local array
       
   761 // ---------------------------------------------------------------------------
       
   762 //
       
   763 void CBTNotifPairingManager::UpdatePairedDeviceListL()
       
   764     {
       
   765     iPairedDevices.Reset();
       
   766     const RDevExtensionArray& alldevs = iDevRepository.AllDevices();
       
   767     for ( TInt i = 0; i < alldevs.Count(); i++ )
       
   768         {
       
   769         // TRACE_BDADDR( iPairedDevicesResp->Results()[i]->BDAddr() );
       
   770         // TRACE_INFO((_L("[BTENG]\t linkkeytype %d"), 
       
   771         //        iPairedDevicesResp->Results()[i]->LinkKeyType()))
       
   772         if ( CBtDevExtension::IsBonded( alldevs[i]->Device().AsNamelessDevice() ) )
       
   773             {
       
   774             iPairedDevices.AppendL( alldevs[i]->Device().AsNamelessDevice() );
       
   775             }
       
   776         }
       
   777     }
       
   778 
       
   779 // ---------------------------------------------------------------------------
       
   780 // Create incoming pairing handler if no one exists yet.
       
   781 // ---------------------------------------------------------------------------
       
   782 //
       
   783 void CBTNotifPairingManager::HandleRegistryBondingL(
       
   784         const TBTNamelessDevice& aNameless)
       
   785     {
       
   786     TInt err = iPairedDevices.Append( aNameless );
       
   787     if ( !err && !iPairingHandler)
       
   788         {
       
   789         // New paired device, but no pairing handler yet.
       
   790         // this means an incoming pairing has occured:
       
   791         TRAP( err, iPairingHandler = 
       
   792                 CBTNotifIncomingPairingHandler::NewL( *this, aNameless.Address() ) );
       
   793         }
       
   794     if ( !err )
       
   795         {
       
   796         // We have a pairing handler now.
       
   797         // Ask pair handler to decide what to do:
       
   798         iPairingHandler->HandleRegistryNewPairedEvent( 
       
   799                 aNameless );
       
   800         }
       
   801     else if ( iPairingHandler )
       
   802         {
       
   803         // error could occur due to no memory, 
       
   804         // let us try aborting pairing handling
       
   805         iPairingHandler->StopPairHandling( aNameless.Address() );
       
   806         }
       
   807     }
       
   808 
       
   809