bluetoothengine/btnotif/btnotifsrv/src/btnotifconnectiontracker.cpp
changeset 31 a0ea99b6fa53
parent 29 48ae3789ce00
child 40 997690c3397a
equal deleted inserted replaced
30:df7a93ede42e 31:a0ea99b6fa53
     1 /*
     1 /*
     2 * ============================================================================
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3 *  Name        : btnotifconnectiontracker.cpp
     3 * All rights reserved.
     4 *  Part of     : bluetoothengine / btnotif
     4 * This component and the accompanying materials are made available
     5 *  Description : Bluetooth connection tracker and manager.
     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".
     6 *
     8 *
     7 *  Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies).
     9 * Initial Contributors:
     8 *  All rights reserved.
    10 * Nokia Corporation - initial contribution.
     9 *  This component and the accompanying materials are made available
       
    10 *  under the terms of "Eclipse Public License v1.0"
       
    11 *  which accompanies this distribution, and is available
       
    12 *  at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
    13 *
    11 *
    14 *  Initial Contributors:
    12 * Contributors:
    15 *  Nokia Corporation - initial contribution.
       
    16 *
    13 *
    17 *  Contributors:
    14 * Description: Bluetooth connection tracker and manager.
    18 *  Nokia Corporation
    15 *
    19 * ============================================================================
       
    20 * Template version: 4.1
       
    21 */
    16 */
    22 
    17 
    23 #include "btnotifconnectiontracker.h"
    18 #include "btnotifconnectiontracker.h"
    24 #include <btextnotifiers.h>
    19 #include <btextnotifiers.h>
    25 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    26 #include <btextnotifierspartner.h>
    21 #include <btextnotifierspartner.h>
    27 #endif
    22 #endif
    28 
    23 
    29 #include "btnotifconnection.h"
    24 #include <btservices/btdevextension.h>
       
    25 #include <btservices/btdevrepository.h>
       
    26 
    30 #include "btnotifsession.h"
    27 #include "btnotifsession.h"
    31 #include "btnotifclientserver.h"
    28 #include "btnotifclientserver.h"
    32 #include "bluetoothtrace.h"
    29 #include "bluetoothtrace.h"
       
    30 #include "btnotifpairingmanager.h"
    33 
    31 
    34 /**  Id for the link key watcher active object. */
       
    35 const TInt KLinkCountWatcher = 30;
       
    36 /**  Id for the pairing result watcher active object. */
       
    37 const TInt KSspResultWatcher = 31;
       
    38 /**  Id for the registry watcher active object (TEMP!). */
       
    39 const TInt KRegistryWatcher = 41;
       
    40 /**  Time window for determining if there are too many requests. */
    32 /**  Time window for determining if there are too many requests. */
    41 #ifndef __WINS__
    33 #ifndef __WINS__
    42 #define KDENYTHRESHOLD TTimeIntervalSeconds(3)
    34 #define KDENYTHRESHOLD TTimeIntervalSeconds(3)
    43 #else   //__WINS__
    35 #else   //__WINS__
    44 #define KDENYTHRESHOLD TTimeIntervalSeconds(5)
    36 #define KDENYTHRESHOLD TTimeIntervalSeconds(5)
    45 #endif  //__WINS__
    37 #endif  //__WINS__
    46 
    38 
    47 
    39 
    48 // ======== LOCAL FUNCTIONS ========
    40 // ======== LOCAL FUNCTIONS ========
    49 
       
    50 // ---------------------------------------------------------------------------
       
    51 // Checks if the notifier is one launched by the security manager of the
       
    52 // protocol stack. These notifiers need to be served unless really not possible.
       
    53 // ---------------------------------------------------------------------------
       
    54 //
       
    55 TBool IsStackSecmanNotifier( TInt aUid )
       
    56     {
       
    57     TBool result = EFalse;
       
    58     if( aUid == KBTManAuthNotifierUid.iUid || aUid == KBTManPinNotifierUid.iUid ||
       
    59         aUid == KBTPinCodeEntryNotifierUid.iUid || aUid == KBTNumericComparisonNotifierUid.iUid ||
       
    60         aUid == KBTPasskeyDisplayNotifierUid.iUid )
       
    61         {
       
    62         result = ETrue;
       
    63         }
       
    64     return result;
       
    65     }
       
    66 
       
    67 
    41 
    68 // ======== MEMBER FUNCTIONS ========
    42 // ======== MEMBER FUNCTIONS ========
    69 
    43 
    70 // ---------------------------------------------------------------------------
    44 // ---------------------------------------------------------------------------
    71 // C++ default constructor
    45 // C++ default constructor
    82 // ---------------------------------------------------------------------------
    56 // ---------------------------------------------------------------------------
    83 //
    57 //
    84 void CBTNotifConnectionTracker::ConstructL()
    58 void CBTNotifConnectionTracker::ConstructL()
    85     {
    59     {
    86     BOstraceFunctionEntry0( DUMMY_DEVLIST );
    60     BOstraceFunctionEntry0( DUMMY_DEVLIST );
    87     // Start watching the number of baseband links.
       
    88     TInt err = iLinkCount.Attach( KPropertyUidBluetoothCategory,
       
    89                 KPropertyKeyBluetoothGetPHYCount );
       
    90     // There is not much point to continue if we can't attach to
       
    91     // the link count key.
       
    92     User::LeaveIfError( err );
       
    93     iLinkCountActive = CBtSimpleActive::NewL( *this, KLinkCountWatcher );
       
    94     iLinkCount.Subscribe( iLinkCountActive->RequestStatus() );
       
    95     iLinkCountActive->GoActive();
       
    96     // Open a handle to the registry server
    61     // Open a handle to the registry server
    97     User::LeaveIfError( iBTRegistrySession.Connect() );
    62     User::LeaveIfError( iBTRegistrySession.Connect() );
    98     // Open a handle to the socket server
    63     // Open a handle to the socket server
    99     User::LeaveIfError( iSockServ.Connect() );
    64     User::LeaveIfError( iSockServ.Connect() );
   100     iPairingServ = new( ELeave ) RBluetoothPairingServer();
    65     iPairingManager = CBTNotifPairingManager::NewL(*this, iServer->DevRepository() );
   101     if( iPairingServ->Connect() )
       
   102         {
       
   103         // Delete in case of error - there is no good other way to keep track.
       
   104         delete iPairingServ;
       
   105         iPairingServ = NULL;
       
   106         }
       
   107     else
       
   108         {
       
   109         iSspResultActive = CBtSimpleActive::NewL( *this, KSspResultWatcher );
       
   110         User::LeaveIfError( iSspResultSession.Open( *iPairingServ ) );
       
   111         iSspResultSession.SimplePairingResult( iSspResultAddr, iSspResultActive->RequestStatus() );
       
   112         iSspResultActive->GoActive();
       
   113         }
       
   114     iConnMan = CBTEngConnMan::NewL( this );
       
   115     iPhyLinks = CBluetoothPhysicalLinks::NewL( *this, iSockServ );
       
   116 // ToDo: remove this when registry notifications API is available!!
       
   117     err = iRegistryChange.Attach( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothRegistryTableChange );
       
   118     User::LeaveIfError( err );
       
   119     iRegistryActive = CBtSimpleActive::NewL( *this, KRegistryWatcher );
       
   120     iRegistryChange.Subscribe( iRegistryActive->RequestStatus() );
       
   121     iRegistryActive->GoActive();
       
   122 // End ToDo
       
   123     BOstraceFunctionExit0( DUMMY_DEVLIST );
    66     BOstraceFunctionExit0( DUMMY_DEVLIST );
   124     }
    67     }
   125 
    68 
   126 
    69 
   127 // ---------------------------------------------------------------------------
    70 // ---------------------------------------------------------------------------
   143 // ---------------------------------------------------------------------------
    86 // ---------------------------------------------------------------------------
   144 //
    87 //
   145 CBTNotifConnectionTracker::~CBTNotifConnectionTracker()
    88 CBTNotifConnectionTracker::~CBTNotifConnectionTracker()
   146     {
    89     {
   147     BOstraceFunctionEntry0( DUMMY_DEVLIST );
    90     BOstraceFunctionEntry0( DUMMY_DEVLIST );
   148     iConnArray.ResetAndDestroy();
       
   149     iConnArray.Close();
       
   150     iDeniedRequests.Close();
    91     iDeniedRequests.Close();
   151     delete iLinkCountActive;
    92     delete iPairingManager;
   152     iLinkCount.Close();
       
   153     
       
   154     delete iConnMan;
       
   155     delete iPhyLinks;
       
   156     iSockServ.Close();
    93     iSockServ.Close();
   157     delete iSspResultActive;
       
   158     iSspResultSession.Close();
       
   159     if( iPairingServ )
       
   160         {
       
   161         iPairingServ->Close();
       
   162         delete iPairingServ;
       
   163         }
       
   164     delete iRegistryActive;
       
   165     iRegistryChange.Close();
       
   166     iBTRegistrySession.Close();
    94     iBTRegistrySession.Close();
   167     BOstraceFunctionExit0( DUMMY_DEVLIST );
    95     BOstraceFunctionExit0( DUMMY_DEVLIST );
   168     }
    96     }
   169 
    97 
   170 // ---------------------------------------------------------------------------
    98 // ---------------------------------------------------------------------------
   171 // Process a client message related to notifiers.
    99 // Process notifier message related to pairing notifiers.
   172 // ---------------------------------------------------------------------------
   100 // ---------------------------------------------------------------------------
   173 //
   101 //
   174 void CBTNotifConnectionTracker::DispatchNotifierMessageL( const RMessage2& aMessage )
   102 void CBTNotifConnectionTracker::HandlePairingNotifierRequestL( const RMessage2& aMessage )
   175     {
   103     {
   176     BOstraceFunctionEntryExt ( DUMMY_LIST, this, aMessage.Function() );
   104     BOstraceFunctionEntryExt ( DUMMY_LIST, this, aMessage.Function() );
   177     TInt opcode = aMessage.Function();
   105     iPairingManager->HandlePairingNotifierRequestL(aMessage);
   178     TInt uid = aMessage.Int0();
       
   179     const RMessage2* message = &aMessage;
       
   180     // Use a pointer to the original message, so that we don't duplicate it.
       
   181     // Then we avoid any bookkeeping for keeping them in sync.
       
   182     if( opcode == EBTNotifCancelNotifier )
       
   183         {
       
   184         // We only accept a cancel message from the same session as the original
       
   185         // request (this is enforced by the RNotifier backend). So we use the
       
   186         // session of the cancel request (if this would change, the same way as
       
   187         // for updates can be followed).
       
   188         // We need to find the original request to identify the handler of the 
       
   189         // connection; the uid points to the original request.
       
   190         message = ( (CBTNotifSession *) aMessage.Session() )->FindMessageFromUid( uid );
       
   191         }
       
   192     else if( opcode == EBTNotifUpdateNotifier )
       
   193         {
       
   194         // We accept a update messages from any client, although in practice,
       
   195         // they will all come from the same session (through RNotifier).
       
   196         // We need to find the original request to identify the handler of the 
       
   197         // connection (the uid points to the original request). Through the 
       
   198         // server, we get it from any session.
       
   199         message = iServer->FindMessageFromUid( uid );
       
   200         }
       
   201     if( !message )
       
   202         {
       
   203         // It's hard to continue if we don't know where to route the message.
       
   204         User::Leave( KErrDisconnected );
       
   205         }
       
   206     TBuf8<0x250> paramsBuf;    // Size needs to be long enough to read all possible parameter sizes.
       
   207     CBTNotifConnection* connection = FindConnectionFromMessageL( opcode, *message, paramsBuf );
       
   208     if( !connection )
       
   209         {
       
   210         User::Leave( KErrDisconnected );
       
   211         }
       
   212     switch( opcode )
       
   213         {
       
   214         case EBTNotifStartSyncNotifier:
       
   215         case EBTNotifStartAsyncNotifier:
       
   216             connection->HandleNotifierRequestL( paramsBuf, aMessage );
       
   217             break;
       
   218         case EBTNotifUpdateNotifier:
       
   219             connection->HandleNotifierUpdateL( paramsBuf, aMessage );
       
   220             break;
       
   221         case EBTNotifCancelNotifier:
       
   222             // Complete the cancel message already here, so that the caller can
       
   223             // continue, and the next operation can close sessions with the caller.
       
   224             aMessage.Complete( KErrNone );
       
   225             connection->CancelNotifierRequestL( *message );
       
   226             break;
       
   227         default:
       
   228             break;
       
   229         }
       
   230     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
   106     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
   231     }
   107     }
   232 
       
   233 
   108 
   234 // ---------------------------------------------------------------------------
   109 // ---------------------------------------------------------------------------
   235 // Handle a request related to pairing.
   110 // Handle a request related to pairing.
   236 // ---------------------------------------------------------------------------
   111 // ---------------------------------------------------------------------------
   237 //
   112 //
   238 void CBTNotifConnectionTracker::HandleBondingRequestL( const RMessage2& aMessage )
   113 void CBTNotifConnectionTracker::HandleBondingRequestL( const RMessage2& aMessage )
   239     {
   114     {
   240     BOstraceFunctionEntryExt ( DUMMY_LIST, this, aMessage.Function() );
   115     BOstraceFunctionEntryExt ( DUMMY_LIST, this, aMessage.Function() );
   241     // Bonding is an infrequently occurring operation, so we don't waste memory
   116     iPairingManager->HandleBondingRequestL(aMessage);
   242     // to keep a copy of the parameters. Instead we read them again when needed.
       
   243     TPckgBuf<TBTDevAddr> addrBuf;
       
   244     TInt opcode = aMessage.Function();
       
   245     if( opcode == EBTEngPairDevice )
       
   246         {
       
   247         aMessage.ReadL( EBTNotifSrvParamSlot, addrBuf );
       
   248         }
       
   249     else if( opcode == EBTEngCancelPairDevice )
       
   250         {
       
   251         const RMessage2* message =
       
   252                 ( (CBTNotifSession *) aMessage.Session() )->FindMessageFromUid( EBTEngPairDevice );
       
   253         message->ReadL( EBTNotifSrvParamSlot, addrBuf );
       
   254         }
       
   255     BtTraceBtAddr1( TRACE_DEBUG, DUMMY_LIST, "CBTNotifConnectionTracker::HandleBondingRequestL() addr=", addrBuf() );
       
   256 	TInt err = KErrNotFound;
       
   257 	CBTNotifConnection* connection = FindConnectionHandler( addrBuf() );
       
   258     if( opcode == EBTEngPairDevice )
       
   259         {
       
   260         if( !connection )
       
   261             {
       
   262             // Create a connection first, then tell it to bond.
       
   263             err = iPhyLinks->CreateConnection( addrBuf() );
       
   264             connection = CBTNotifConnection::NewLC( addrBuf(), this );
       
   265             iConnArray.AppendL( connection );
       
   266             CleanupStack::Pop( connection );
       
   267             }
       
   268         else
       
   269             {
       
   270             // There is an existing connection. Care must be taken, the connection
       
   271             // _should_ be disconnect first if this device is already paired, so that
       
   272             // we are sure that we don't mix up the state of the connection.
       
   273             RBTPhysicalLinkAdapter link;
       
   274             err = link.Open( iSockServ, addrBuf() );
       
   275             TUint32 linkState = 0;
       
   276             if( !err )
       
   277                 {
       
   278                 err = link.PhysicalLinkState( linkState );
       
   279                 }
       
   280             if( !err && linkState & ( ENotifyAuthenticationComplete | ENotifyEncryptionChangeOn ) )
       
   281                 {
       
   282                 // For now, we just reject the request.
       
   283                 err = KErrAlreadyExists;
       
   284                 }
       
   285             link.Close();
       
   286             }
       
   287         if( !err )
       
   288             {
       
   289             // Start bonding immediately so that the connection object is in the right state.
       
   290             connection->StartBondingL( aMessage );
       
   291             }
       
   292         }
       
   293     else if( opcode == EBTEngCancelPairDevice && connection )
       
   294         {
       
   295         connection->CancelBondingL();
       
   296         err = KErrNone;
       
   297         aMessage.Complete( err );
       
   298         }
       
   299 	// KErrNotFound is returned for a request to cancel pairing that has no connection.
       
   300     if( err )
       
   301         {
       
   302         aMessage.Complete( err );
       
   303         }
       
   304     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
   117     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
   305     }
   118     }
   306 
       
   307 
       
   308 // ---------------------------------------------------------------------------
       
   309 // Handle a change in the number of connections.
       
   310 // ---------------------------------------------------------------------------
       
   311 //
       
   312 void CBTNotifConnectionTracker::HandleLinkCountChangeL()
       
   313     {
       
   314     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   315     TInt linkCount = 0;
       
   316     User::LeaveIfError( iLinkCount.Get( linkCount ) );
       
   317     if( linkCount )
       
   318         {
       
   319         RBTDevAddrArray links;
       
   320         CleanupClosePushL( links );
       
   321         User::LeaveIfError( iPhyLinks->Enumerate( links, 10 ) );
       
   322         __ASSERT_ALWAYS( links.Count(), PanicServer( EBTNotifPanicBadState ) );
       
   323         for( TInt i = iConnArray.Count() -1; i >= 0 ; i-- )
       
   324             {
       
   325             // Loop backwards, as we may remove entries from the array.
       
   326 
       
   327             // First check the existing connections, and 
       
   328             // remove disconnected links
       
   329             TBTDevAddr addr = iConnArray[i]->Address();
       
   330             TInt pos = links.Find( addr );
       
   331             if( pos > KErrNotFound )
       
   332                 {
       
   333                 // The link we know is still connected,
       
   334                 // remove the watceher from the array.
       
   335                 links.Remove( pos );
       
   336                 // ToDo: see comment below!
       
   337                 }
       
   338             else if( iConnArray[i]->CurrentOperation() == CBTNotifConnection::EIdle )
       
   339                 {
       
   340                 // This link is no more connected and idle, remove.
       
   341                 CBTNotifConnection* connection = iConnArray[i];
       
   342                 iConnArray.Remove( i ); // Does not delete the object.
       
   343                 delete connection;
       
   344                 }
       
   345             // else we wait for the link to complete its operations.
       
   346             }
       
   347         // Now we have an array with only the new connections.
       
   348         // Add new watchers.
       
   349         for( TInt i = 0; i < links.Count(); i++ )
       
   350             {
       
   351             CBTNotifConnection* connection = CBTNotifConnection::NewLC( links[i], this );
       
   352             iConnArray.AppendL( connection );
       
   353             CleanupStack::Pop( connection );
       
   354             }
       
   355         // Close the links RBTDevAddrArray, needed before going out of scope.
       
   356         CleanupStack::PopAndDestroy();
       
   357         }
       
   358     else
       
   359         {
       
   360         for( TInt i = iConnArray.Count() -1; i >= 0 ; i-- )
       
   361             {
       
   362             if( iConnArray[i]->CurrentOperation() == CBTNotifConnection::EIdle )
       
   363                 {
       
   364                 // This link is now idle, so we can remove it safely.
       
   365                 CBTNotifConnection* connection = iConnArray[i];
       
   366                 iConnArray.Remove( i ); // Does not delete the object.
       
   367                 delete connection;
       
   368                 }
       
   369             }
       
   370         if( !iConnArray.Count() )
       
   371             {
       
   372             // The array is idle, clean up the array resources.
       
   373             iConnArray.Reset();
       
   374             }
       
   375         }
       
   376     BOstraceFunctionExit0( DUMMY_DEVLIST );
       
   377     }
       
   378 
       
   379 
   119 
   380 // ---------------------------------------------------------------------------
   120 // ---------------------------------------------------------------------------
   381 // Check if this device has been denied a connection already before.
   121 // Check if this device has been denied a connection already before.
   382 // Also check if a previous connection attempt has just been rejected.
   122 // Also check if a previous connection attempt has just been rejected.
   383 // ---------------------------------------------------------------------------
   123 // ---------------------------------------------------------------------------
   413         }
   153         }
   414     BOstraceFunctionExit0( DUMMY_DEVLIST );
   154     BOstraceFunctionExit0( DUMMY_DEVLIST );
   415     return result;
   155     return result;
   416     }
   156     }
   417 
   157 
   418 
       
   419 // ---------------------------------------------------------------------------
       
   420 // From class MBluetoothPhysicalLinksNotifier.
       
   421 // Handle baseband connection completion.
       
   422 // ---------------------------------------------------------------------------
       
   423 //
       
   424 void CBTNotifConnectionTracker::HandleCreateConnectionCompleteL( TInt aErr )
       
   425     {
       
   426     BOstraceFunctionEntryExt ( DUMMY_LIST, this, aErr );
       
   427 	// We only connect links for starting outgoing bonding.
       
   428 	const RMessage2* message = iServer->FindMessageFromUid( (TInt) EBTEngPairDevice );
       
   429 	if( message )
       
   430 		{
       
   431         TPckgBuf<TBTDevAddr> addrBuf;
       
   432         message->ReadL( EBTNotifSrvParamSlot, addrBuf );
       
   433         CBTNotifConnection* connection = FindConnectionHandler( addrBuf() );
       
   434         __ASSERT_ALWAYS( connection, PanicServer( EBTNotifPanicBadState ) );
       
   435         if( !aErr && connection->CurrentOperation() == CBTNotifConnection::EIdle )
       
   436             {
       
   437 			TRAP( aErr, connection->StartBondingL( *message ) );
       
   438 			}
       
   439         if( aErr && connection->CurrentOperation() == CBTNotifConnection::EBonding )
       
   440             {
       
   441             connection->PairingResult( aErr );  // Launch error note
       
   442             }
       
   443 		}
       
   444 	BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   445     }
       
   446 
       
   447 
       
   448 // ---------------------------------------------------------------------------
       
   449 // From class MBluetoothPhysicalLinksNotifier.
       
   450 // Handle baseband disconnection.
       
   451 // ---------------------------------------------------------------------------
       
   452 //
       
   453 void CBTNotifConnectionTracker::HandleDisconnectCompleteL( TInt aErr )
       
   454     {
       
   455     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   456 	// We only disconnect links for starting outgoing bonding.
       
   457 	const RMessage2* message = iServer->FindMessageFromUid( (TInt) EBTEngPairDevice );
       
   458 	if( message )
       
   459 		{
       
   460         TPckgBuf<TBTDevAddr> addrBuf;
       
   461         message->ReadL( EBTNotifSrvParamSlot, addrBuf );
       
   462 		if( !aErr )
       
   463 			{
       
   464 			aErr = iPhyLinks->CreateConnection( addrBuf() );
       
   465 			}
       
   466 		if( aErr )
       
   467 			{
       
   468 			iServer->CompleteMessage( message->Handle(), aErr, KNullDesC8 );
       
   469             CBTNotifConnection* connection = FindConnectionHandler( addrBuf() );
       
   470             __ASSERT_ALWAYS( connection, PanicServer( EBTNotifPanicBadState ) );
       
   471             connection->PairingResult( aErr );  // Launch error note
       
   472 			}
       
   473     	}
       
   474 	BOstraceFunctionExit0( DUMMY_DEVLIST );
       
   475     }
       
   476 
       
   477 
       
   478 // ---------------------------------------------------------------------------
       
   479 // From class MBluetoothPhysicalLinksNotifier.
       
   480 // Handle disconnection of all links.
       
   481 // ---------------------------------------------------------------------------
       
   482 //
       
   483 void CBTNotifConnectionTracker::HandleDisconnectAllCompleteL( TInt aErr )
       
   484     {
       
   485     (void) aErr;
       
   486     }
       
   487 
       
   488 
       
   489 // ---------------------------------------------------------------------------
       
   490 // From class MBTEngConnObserver.
       
   491 // Handle service-level connection completion.
       
   492 // ---------------------------------------------------------------------------
       
   493 //
       
   494 void CBTNotifConnectionTracker::ConnectComplete( TBTDevAddr& aAddr, 
       
   495     TInt aErr, RBTDevAddrArray* aConflicts )
       
   496     {
       
   497     (void) aAddr;
       
   498     (void) aErr;
       
   499     (void) aConflicts;
       
   500     }
       
   501 
       
   502 
       
   503 // ---------------------------------------------------------------------------
       
   504 // From class MBTEngConnObserver.
       
   505 // Handle service-level disconnection.
       
   506 // ---------------------------------------------------------------------------
       
   507 //
       
   508 void CBTNotifConnectionTracker::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr )
       
   509     {
       
   510     (void) aAddr;
       
   511     (void) aErr;
       
   512     }
       
   513 
       
   514 
       
   515 // ---------------------------------------------------------------------------
       
   516 // From class MBtSimpleActiveObserver.
       
   517 // Handle the active object completion.
       
   518 // ---------------------------------------------------------------------------
       
   519 //
       
   520 void CBTNotifConnectionTracker::RequestCompletedL( CBtSimpleActive* aActive,
       
   521     TInt aStatus )
       
   522     {
       
   523     BOstraceFunctionEntryExt ( DUMMY_LIST, this, aActive->RequestId() );
       
   524     BOstraceExt2( TRACE_DEBUG, DUMMY_DEVLIST, 
       
   525             "CBTNotifConnectionTracker::MBAORequestCompletedL() requestid=%d status=%d", 
       
   526             aActive->RequestId(), aStatus);
       
   527     if( aActive->RequestId() == KLinkCountWatcher )
       
   528         {
       
   529         iLinkCount.Subscribe( aActive->RequestStatus() );
       
   530         aActive->GoActive();
       
   531         if( !aStatus )
       
   532             {
       
   533             // HandleLinkCountChangeL();
       
   534             }
       
   535         }
       
   536 // ToDo: remove this when registry notifications API is available!!
       
   537     else if( aActive->RequestId() == KRegistryWatcher )
       
   538         {
       
   539         // BTRegistry notifies of a change. Check which one.
       
   540         iRegistryChange.Subscribe( aActive->RequestStatus() );
       
   541         aActive->GoActive();
       
   542         TInt tableChanged = 0;
       
   543         if( !aStatus && !iRegistryChange.Get( tableChanged ) &&
       
   544             tableChanged == KRegistryChangeRemoteTable )
       
   545             {
       
   546             // A record for a remote device has changed. Tell all 
       
   547             // connections to update their record.
       
   548             for( TInt i = 0; i < iConnArray.Count(); i++ )
       
   549                 {
       
   550                 // Reuse the functionality in the connection
       
   551                 if( iConnArray[i]->CurrentOperation() < CBTNotifConnection::EReadingRegistry )
       
   552                     {
       
   553                     iConnArray[i]->RequestCompletedL( aActive, aStatus );
       
   554                     }
       
   555                 }
       
   556             }
       
   557         }
       
   558 // End ToDo
       
   559     else if( aActive->RequestId() == KSspResultWatcher )
       
   560         {
       
   561         iSspResultSession.SimplePairingResult( iSspResultAddr, iSspResultActive->RequestStatus() );
       
   562         iSspResultActive->GoActive();
       
   563         CBTNotifConnection* connection = FindConnectionHandler( iSspResultAddr );
       
   564         // ToDo: how to handle a result of a link that already disconnected? 
       
   565         if( connection )
       
   566             {
       
   567             connection->PairingResult( aStatus );
       
   568             }
       
   569         }
       
   570     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   571     }
       
   572 
       
   573 
       
   574 // ---------------------------------------------------------------------------
       
   575 // From class MBtSimpleActiveObserver.
       
   576 // Cancel and clean up all requests related to the active object.
       
   577 // ---------------------------------------------------------------------------
       
   578 //
       
   579 void CBTNotifConnectionTracker::CancelRequest( TInt aRequestId )
       
   580     {
       
   581     BOstraceFunctionEntry0( DUMMY_DEVLIST );
       
   582     if( aRequestId == KLinkCountWatcher )
       
   583         {
       
   584         iLinkCount.Cancel();
       
   585         }
       
   586     else if( aRequestId == KSspResultWatcher )
       
   587         {
       
   588         iSspResultSession.CancelSimplePairingResult();
       
   589         }
       
   590     else if ( aRequestId == KRegistryWatcher )
       
   591         {
       
   592         iRegistryChange.Cancel();
       
   593         }
       
   594     BOstraceFunctionExit0( DUMMY_DEVLIST );
       
   595     }
       
   596 
       
   597 // ---------------------------------------------------------------------------
       
   598 // From class MBtSimpleActiveObserver.
       
   599 // 
       
   600 // ---------------------------------------------------------------------------
       
   601 //
       
   602 void CBTNotifConnectionTracker::HandleError( CBtSimpleActive* aActive, 
       
   603         TInt aError )
       
   604     {
       
   605     (void) aActive;
       
   606     (void) aError;
       
   607     }
       
   608 
       
   609 // ---------------------------------------------------------------------------
       
   610 // Parse the details from a client message and find the associated handler.
       
   611 // ---------------------------------------------------------------------------
       
   612 //
       
   613 CBTNotifConnection* CBTNotifConnectionTracker::FindConnectionFromMessageL(
       
   614     TInt aOpcode, const RMessage2& aMessage, TDes8& aBuffer )
       
   615     {
       
   616     BOstraceFunctionEntry1( DUMMY_DEVLIST, this );
       
   617     TInt uid = aMessage.Int0();
       
   618     aMessage.ReadL( EBTNotifSrvParamSlot, aBuffer );
       
   619     TBTDevAddr addr = ParseAddressL( uid, aBuffer );
       
   620     // If this is a 
       
   621     CBTNotifConnection* connection = FindConnectionHandler( addr );
       
   622     if( !connection && IsStackSecmanNotifier( uid ) &&
       
   623         ( aOpcode == EBTNotifStartAsyncNotifier || aOpcode == EBTNotifStartSyncNotifier ) )
       
   624         {
       
   625         // A notifier from stack. This happens if e.g. the pairing
       
   626         // request comes in before the link count changes (like security
       
   627         // mode 3). Create the handler and queue the request.
       
   628         // And note that 
       
   629         connection = CBTNotifConnection::NewLC( addr, this );
       
   630         iConnArray.AppendL( connection );
       
   631         CleanupStack::Pop( connection );
       
   632         }
       
   633     BOstraceFunctionExitExt( DUMMY_DEVLIST, this, connection );
       
   634     return connection;
       
   635     }
       
   636 
       
   637 
       
   638 // ---------------------------------------------------------------------------
       
   639 // read the address from a client message.
       
   640 // ---------------------------------------------------------------------------
       
   641 //
       
   642 TBTDevAddr CBTNotifConnectionTracker::ParseAddressL( TInt aUid,
       
   643     const TDesC8& aParamsBuf ) const
       
   644     {
       
   645     BOstraceFunctionEntry1( DUMMY_DEVLIST, this );
       
   646     TBTDevAddr addr;
       
   647     if( IsStackSecmanNotifier( aUid ) )
       
   648         {
       
   649         // For all these, the address is the first data member,
       
   650         // so can be read using the TBTNotifierParams data structure.
       
   651         TBTNotifierParams params;
       
   652         TPckgC<TBTNotifierParams> paramsPckg( params );
       
   653         paramsPckg.Set( aParamsBuf );
       
   654         addr = paramsPckg().iBDAddr;
       
   655         }
       
   656     //else if(  ) other notifier types
       
   657     BOstraceFunctionExitExt( DUMMY_DEVLIST, this, &addr );  
       
   658     return addr;
       
   659     }
       
   660 
       
   661 
       
   662 // ---------------------------------------------------------------------------
       
   663 // Find a specific connection.
       
   664 // ---------------------------------------------------------------------------
       
   665 //
       
   666 CBTNotifConnection* CBTNotifConnectionTracker::FindConnectionHandler(
       
   667     const TBTDevAddr& aAddr ) const
       
   668     {
       
   669     BOstraceFunctionEntry1( DUMMY_DEVLIST, this );
       
   670     CBTNotifConnection* conn = NULL;
       
   671     if( aAddr != TBTDevAddr() )
       
   672         {
       
   673         // This may be replaced by RArray::Find with appropriate key
       
   674         for( TInt i = 0; i < iConnArray.Count(); i++ )
       
   675             {
       
   676             if( iConnArray[i]->Address() == aAddr )
       
   677                 {
       
   678                 conn = iConnArray[i];
       
   679                 break;
       
   680                 }
       
   681             }
       
   682         }
       
   683     BOstraceFunctionExitExt( DUMMY_DEVLIST, this, conn );
       
   684     return conn;
       
   685     }
       
   686 
       
   687 
       
   688 // ---------------------------------------------------------------------------
   158 // ---------------------------------------------------------------------------
   689 // Record and check the time between connection attempts.
   159 // Record and check the time between connection attempts.
   690 // ---------------------------------------------------------------------------
   160 // ---------------------------------------------------------------------------
   691 //
   161 //
   692 TBool CBTNotifConnectionTracker::RecordConnectionAttempts( TBool aAccepted )
   162 TBool CBTNotifConnectionTracker::RecordConnectionAttempts( TBool aAccepted )
   717     // It is reset in case the user accepted the request.
   187     // It is reset in case the user accepted the request.
   718     iLastReject = now.Int64();
   188     iLastReject = now.Int64();
   719     BOstraceFunctionExitExt( DUMMY_DEVLIST, this, result );
   189     BOstraceFunctionExitExt( DUMMY_DEVLIST, this, result );
   720     return result;
   190     return result;
   721     }
   191     }
       
   192