bluetoothengine/btnotif/btnotifsrv/src/btnotifsecuritymanager.cpp
branchRCL_3
changeset 56 9386f31cc85b
parent 55 613943a21004
child 61 269724087bed
equal deleted inserted replaced
55:613943a21004 56:9386f31cc85b
     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         aPin().iLength = 0;
       
   449         }
       
   450     }
       
   451 
       
   452 // ---------------------------------------------------------------------------
       
   453 // Ask server class the connection status of the specified device
       
   454 // ---------------------------------------------------------------------------
       
   455 //
       
   456 TBTEngConnectionStatus CBTNotifSecurityManager::ConnectStatus( const TBTDevAddr& aAddr )
       
   457     {
       
   458     const CBtDevExtension* devExt = iDevRepository.Device(aAddr);
       
   459     TBTEngConnectionStatus status = EBTEngNotConnected;
       
   460     if ( devExt ) 
       
   461         {
       
   462         status = devExt->ServiceConnectionStatus();
       
   463         }
       
   464     return status;
       
   465     }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // From class MBTNotifPairingAOObserver.
       
   469 // Checks if there is an authentication result.
       
   470 // ---------------------------------------------------------------------------
       
   471 //
       
   472 void CBTNotifSecurityManager::RequestCompletedL( CBtSimpleActive* aActive, TInt aStatus )
       
   473     {
       
   474     BOstraceExt2(TRACE_DEBUG,DUMMY_DEVLIST,"aId: %d, aStatus: %d", aActive->RequestId(), aStatus);
       
   475     // Check which request is completed.
       
   476     switch( aActive->RequestId() )
       
   477         {
       
   478         case ESimplePairingResult:
       
   479             {
       
   480             TBTDevAddr tmpAddr = iSimplePairingRemote;
       
   481             if (aStatus != KErrServerTerminated)
       
   482                 {
       
   483                 SubscribeSspPairingResult();
       
   484                 }
       
   485             HandlePairingResultL( tmpAddr, aStatus );
       
   486             break;
       
   487             }
       
   488         case EAuthenticationResult:
       
   489             {
       
   490             TBTDevAddr tmpAddr = iAuthenticateRemote;
       
   491             if (aStatus != KErrServerTerminated)
       
   492                 {
       
   493                 SubscribeAuthenticateResult();
       
   494                 }
       
   495             HandlePairingResultL( tmpAddr, aStatus );
       
   496             break;
       
   497             }
       
   498         case ERegistryGetLocalAddress:
       
   499             {
       
   500             TBool value = IsLocalAddressAvailable();
       
   501             SubscribeLocalAddress();
       
   502             if ( value ) 
       
   503                 {
       
   504                 // Refresh paired devices list to include any restored devices.
       
   505                 iDevRepository.ReInitialize();
       
   506                 }
       
   507             break;
       
   508             }
       
   509         default:
       
   510             // Should not be possible, but no need for handling.
       
   511             break;
       
   512         }
       
   513     }
       
   514 
       
   515 // ---------------------------------------------------------------------------
       
   516 // From class MBTEngActiveObserver.
       
   517 // cancels an outstanding request according to the given id.
       
   518 // ---------------------------------------------------------------------------
       
   519 //
       
   520 void CBTNotifSecurityManager::CancelRequest( TInt aRequestId )
       
   521     {
       
   522     switch ( aRequestId )
       
   523         {
       
   524         case ESimplePairingResult:
       
   525             {
       
   526             // Cancel listening Simple pairing result
       
   527             iPairingResult.CancelSimplePairingResult();
       
   528             break;
       
   529             }
       
   530         case EAuthenticationResult:
       
   531             {
       
   532             // Cancel listening authentication result
       
   533             iAuthenResult.CancelAuthenticationResult();
       
   534             break;
       
   535             }
       
   536         case ERegistryGetLocalAddress:
       
   537             {
       
   538             // cancel listening local address status change
       
   539             iPropertyLocalAddr.Cancel();
       
   540             break;
       
   541             }
       
   542         }
       
   543     }
       
   544 
       
   545 // ---------------------------------------------------------------------------
       
   546 // From class MBtSimpleActiveObserver.
       
   547 // ---------------------------------------------------------------------------
       
   548 //
       
   549 void CBTNotifSecurityManager::HandleError( CBtSimpleActive* aActive, TInt aError )
       
   550     {
       
   551     BOstraceExt2(TRACE_DEBUG,DUMMY_DEVLIST,"request id: %d, error: %d", aActive->RequestId(), aError);
       
   552     (void) aActive;
       
   553     (void) aError;
       
   554     }
       
   555 
       
   556 // ---------------------------------------------------------------------------
       
   557 // From class MBtDevRepositoryObserver.
       
   558 // ---------------------------------------------------------------------------
       
   559 //
       
   560 void CBTNotifSecurityManager::RepositoryInitialized()
       
   561     {
       
   562     TRAPD(err, UpdatePairedDeviceListL() );
       
   563     if ( !err && iPairingHandler )
       
   564         {
       
   565         // non-null pairing handler means we are involved in a
       
   566         // pairing operation already.
       
   567         // todo: is some handling for above case needed?
       
   568         }
       
   569     }
       
   570 
       
   571 // ---------------------------------------------------------------------------
       
   572 // From class MBtDevRepositoryObserver.
       
   573 // ---------------------------------------------------------------------------
       
   574 //
       
   575 void CBTNotifSecurityManager::DeletedFromRegistry( const TBTDevAddr& aAddr )
       
   576     {
       
   577     // We are only interested in the removal of a paired device.
       
   578     // thus check whether it is in our local paired list:
       
   579     TInt i = iPairedDevices.Find( aAddr, MatchDeviceAddress);
       
   580     if ( i > KErrNotFound )
       
   581         {
       
   582         iPairedDevices.Remove( i );
       
   583         }
       
   584     }
       
   585 
       
   586 // ---------------------------------------------------------------------------
       
   587 // From class MBtDevRepositoryObserver.
       
   588 // ---------------------------------------------------------------------------
       
   589 //
       
   590 void CBTNotifSecurityManager::AddedToRegistry( const CBtDevExtension& aDevice )
       
   591     {
       
   592     // We are only interested in paired device.
       
   593     if ( CBtDevExtension::IsBonded( aDevice.Device().AsNamelessDevice() ) )
       
   594         {
       
   595         TRAP_IGNORE( 
       
   596                 HandleRegistryBondingL( aDevice.Device().AsNamelessDevice() ) );
       
   597         }
       
   598     }
       
   599 
       
   600 
       
   601 // ---------------------------------------------------------------------------
       
   602 // From class MBtDevRepositoryObserver.
       
   603 // ---------------------------------------------------------------------------
       
   604 //
       
   605 void CBTNotifSecurityManager::ChangedInRegistry(
       
   606         const CBtDevExtension& aDevice, TUint aSimilarity )
       
   607     {
       
   608     // We are only interested in paired device.
       
   609     // thus check whether it is in our local paired list:
       
   610     TInt i = iPairedDevices.Find( aDevice.Addr(), MatchDeviceAddress);
       
   611     TBool bonded = CBtDevExtension::IsBonded( aDevice.Device().AsNamelessDevice() );
       
   612     if ( i == KErrNotFound )
       
   613         {
       
   614         if ( bonded ) 
       
   615             {
       
   616             TRAP_IGNORE(
       
   617                     HandleRegistryBondingL( 
       
   618                             aDevice.Device().AsNamelessDevice() ) );                
       
   619             }
       
   620         return;
       
   621         }
       
   622     // Device was inregistry before, but we need to evaluate its bonding
       
   623     // status.
       
   624     // The given similarity will tell if the linkkey and paired is changed
       
   625     // or not.
       
   626     TInt pairingProperty = TBTNamelessDevice::EIsPaired 
       
   627             | TBTNamelessDevice::ELinkKey;
       
   628     if ( ( pairingProperty & aSimilarity) == pairingProperty )
       
   629         {
       
   630         // no pairing or linkkey change. Nothing to do for pairing handling.
       
   631         // but we'd better update local copy just in case other data
       
   632         // of this device is needed by someone:
       
   633         iPairedDevices[i] = aDevice.Device().AsNamelessDevice();
       
   634         return;
       
   635         }
       
   636     if ( !CBtDevExtension::IsBonded( aDevice.Device().AsNamelessDevice() ) )
       
   637         {
       
   638         // device is not user-bonded.
       
   639         iPairedDevices.Remove( i );
       
   640         return;
       
   641         }
       
   642     // it is a new paired device if its link-key has been upgraded
       
   643     if ( aDevice.Device().LinkKeyType() != ELinkKeyUnauthenticatedUpgradable )
       
   644         {
       
   645         iPairedDevices.Remove( i );
       
   646         TRAP_IGNORE(
       
   647                 HandleRegistryBondingL( 
       
   648                         aDevice.Device().AsNamelessDevice() ) );                
       
   649         }
       
   650     }
       
   651 
       
   652 // ---------------------------------------------------------------------------
       
   653 // From class MBtDevRepositoryObserver.
       
   654 // This class is not interested in such events.
       
   655 // ---------------------------------------------------------------------------
       
   656 //
       
   657 void CBTNotifSecurityManager::ServiceConnectionChanged(
       
   658         const CBtDevExtension& aDevice, TBool aConnected )
       
   659     {
       
   660     (void) aDevice;
       
   661     (void) aConnected;
       
   662     }
       
   663 
       
   664 // ---------------------------------------------------------------------------
       
   665 // Activate or deactivate a pairing handler
       
   666 // ---------------------------------------------------------------------------
       
   667 //
       
   668 TInt CBTNotifSecurityManager::SetPairObserver(const TBTDevAddr& aAddr, TBool aActivate)
       
   669     {
       
   670     BOstrace1(TRACE_DEBUG,DUMMY_DEVLIST,"%d", aActivate);
       
   671     BtTraceBtAddr0(TRACE_DEBUG,DUMMY_DEVLIST, aAddr );
       
   672     TInt err( KErrNone );
       
   673     if ( !aActivate )
       
   674         {
       
   675         if ( iPairingHandler )
       
   676             {
       
   677             iPairingHandler->StopPairHandling( aAddr );
       
   678             }
       
   679         return err;
       
   680         }
       
   681     
       
   682     if ( !iPairingHandler)
       
   683         {
       
   684         // This is an incoming pair, unpair it from registry and 
       
   685         // create the handler:
       
   686         UnpairDevice( aAddr );
       
   687         TRAP( err, iPairingHandler = CBTNotifIncomingPairingHandler::NewL( *this, aAddr ));     
       
   688         }
       
   689     if ( iPairingHandler)
       
   690         {
       
   691         // let the handler decide what to do:
       
   692         err = iPairingHandler->ObserveIncomingPair( aAddr );
       
   693         }
       
   694     return err;
       
   695     }
       
   696 
       
   697 // ---------------------------------------------------------------------------
       
   698 // Delegates the request to current pair handler
       
   699 // ---------------------------------------------------------------------------
       
   700 //
       
   701 void CBTNotifSecurityManager::PairDeviceL( const TBTDevAddr& aAddr, TUint32 aCod )
       
   702     {
       
   703     if ( !iPairingHandler)
       
   704         {
       
   705         // no existing pair handling, create one:
       
   706         iPairingHandler = CBTNotifOutgoingPairingHandler::NewL( *this, aAddr );
       
   707         }
       
   708     // let pair handler decide what to do:
       
   709     iPairingHandler->HandleOutgoingPairL( aAddr, aCod );
       
   710     }
       
   711 
       
   712 // ---------------------------------------------------------------------------
       
   713 // cancel Subscribings to simple pairing result and authentication result from
       
   714 // Pairing Server
       
   715 // ---------------------------------------------------------------------------
       
   716 //
       
   717 void CBTNotifSecurityManager::CancelSubscribePairingAuthenticate()
       
   718     {
       
   719     if( iSSPResultActive )
       
   720         {
       
   721         // Cancel listening Simple pairing result
       
   722         iSSPResultActive->Cancel();
       
   723         }
       
   724     if( iAuthenResultActive )
       
   725         {
       
   726         iAuthenResultActive->Cancel();
       
   727         }
       
   728     }
       
   729 
       
   730 // ---------------------------------------------------------------------------
       
   731 // Subscribes to simple pairing result from Pairing Server (if not already 
       
   732 // subscribed).
       
   733 // ---------------------------------------------------------------------------
       
   734 //
       
   735 void CBTNotifSecurityManager::SubscribeSspPairingResult()
       
   736     {
       
   737     if ( !iSSPResultActive->IsActive() )
       
   738         {
       
   739         iPairingResult.SimplePairingResult( iSimplePairingRemote, iSSPResultActive->RequestStatus() );
       
   740         iSSPResultActive->GoActive();
       
   741         }
       
   742     }
       
   743 
       
   744 // ---------------------------------------------------------------------------
       
   745 // Subscribes to authentication result from Pairing Server (if not already
       
   746 // subscribed).
       
   747 // ---------------------------------------------------------------------------
       
   748 //
       
   749 void CBTNotifSecurityManager::SubscribeAuthenticateResult()
       
   750     {
       
   751     if ( !iAuthenResultActive->IsActive() )
       
   752         {
       
   753         // Subscribe authentication result (which requires pairing for unpaired devices)
       
   754         iAuthenResult.AuthenticationResult( iAuthenticateRemote, iAuthenResultActive->RequestStatus() );
       
   755         iAuthenResultActive->GoActive();
       
   756         }
       
   757     }
       
   758 
       
   759 // ---------------------------------------------------------------------------
       
   760 // Handle a pairing result from the pairing server.
       
   761 // ---------------------------------------------------------------------------
       
   762 //
       
   763 void CBTNotifSecurityManager::HandlePairingResultL( const TBTDevAddr& aAddr, TInt aResult )
       
   764     {
       
   765     BOstrace1(TRACE_DEBUG,DUMMY_DEVLIST,"result %d", aResult);
       
   766     BtTraceBtAddr0(TRACE_DEBUG,DUMMY_DEVLIST, aAddr );
       
   767  
       
   768     if ( !iPairingHandler && ( aResult == KErrNone || aResult == KHCIErrorBase ) )
       
   769         {
       
   770         // we only create new handler if incoming pairing succeeds.
       
   771         // Pairing failure could be caused by user local cancellation, as the  
       
   772         // result, the handler was destroyed by notifier. We shall not
       
   773         // instantiate the handler again.
       
   774         // If a pairing failed due to other reasons than user local cancelling,
       
   775         // it will be catched by the already started handler 
       
   776         // (except Just Works pairing - no handler for it at all until we receive
       
   777         // registry change event. Thus if incoming JWs pairing failed, no user
       
   778         // notification will be shown.)
       
   779         iPairedDevices.Find( aAddr, MatchDeviceAddress);
       
   780         TInt index = iPairedDevices.Find( aAddr, MatchDeviceAddress);
       
   781         // If the device is not found in the old paired device list, it is a new
       
   782         // paired device:
       
   783         if ( index == KErrNotFound)
       
   784             {
       
   785             // No handler yet, create incoming pairing handler:
       
   786             iPairingHandler = CBTNotifIncomingPairingHandler::NewL( *this, aAddr );
       
   787             }
       
   788         }
       
   789     if ( iPairingHandler )
       
   790         {
       
   791         iPairingHandler->HandlePairServerResult( aAddr, aResult );
       
   792         }
       
   793     }
       
   794 
       
   795 // ---------------------------------------------------------------------------
       
   796 // copy the nameless devices to local array
       
   797 // ---------------------------------------------------------------------------
       
   798 //
       
   799 void CBTNotifSecurityManager::UpdatePairedDeviceListL()
       
   800     {
       
   801     iPairedDevices.Reset();
       
   802     const RDevExtensionArray& alldevs = iDevRepository.AllDevices();
       
   803     for ( TInt i = 0; i < alldevs.Count(); i++ )
       
   804         {
       
   805         if ( CBtDevExtension::IsBonded( alldevs[i]->Device().AsNamelessDevice() ) )
       
   806             {
       
   807             iPairedDevices.AppendL( alldevs[i]->Device().AsNamelessDevice() );
       
   808             }
       
   809         }
       
   810     }
       
   811 
       
   812 // ---------------------------------------------------------------------------
       
   813 // Create incoming pairing handler if no one exists yet.
       
   814 // ---------------------------------------------------------------------------
       
   815 //
       
   816 void CBTNotifSecurityManager::HandleRegistryBondingL(
       
   817         const TBTNamelessDevice& aNameless)
       
   818     {
       
   819     TInt err = iPairedDevices.Append( aNameless );
       
   820     if ( !err && !iPairingHandler)
       
   821         {
       
   822         // New paired device, but no pairing handler yet.
       
   823         // this means an incoming pairing has occured:
       
   824         TRAP( err, iPairingHandler = 
       
   825                 CBTNotifIncomingPairingHandler::NewL( *this, aNameless.Address() ) );
       
   826         }
       
   827     if ( !err )
       
   828         {
       
   829         // We have a pairing handler now.
       
   830         // Ask pair handler to decide what to do:
       
   831         iPairingHandler->HandleRegistryNewPairedEvent( 
       
   832                 aNameless );
       
   833         }
       
   834     else if ( iPairingHandler )
       
   835         {
       
   836         // error could occur due to no memory, 
       
   837         // let us try aborting pairing handling
       
   838         iPairingHandler->StopPairHandling( aNameless.Address() );
       
   839         }
       
   840     }
       
   841 
       
   842 void CBTNotifSecurityManager::TrustDevice( const TBTDevAddr& aAddr )
       
   843     {
       
   844     TIdentityRelation<TBTNamelessDevice> addrComp( CompareDeviceByAddress );
       
   845     TBTNamelessDevice dev;
       
   846     dev.SetAddress( aAddr );
       
   847     TRequestStatus status( KRequestPending );
       
   848     
       
   849     iRegistry.GetDevice(dev,status);
       
   850     User::WaitForRequest( status ); 
       
   851     if(status == KErrNone)
       
   852         {
       
   853         TBTDeviceSecurity security = dev.GlobalSecurity();
       
   854         security.SetNoAuthorise(ETrue);
       
   855         security.SetBanned(EFalse);
       
   856         dev.SetGlobalSecurity(security);
       
   857         (void)UpdateRegDevice(dev);
       
   858         }
       
   859     }
       
   860