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