--- a/bluetoothengine/btnotif/btnotifsrv/src/btnotifconnectiontracker.cpp Fri May 14 16:01:46 2010 +0300
+++ b/bluetoothengine/btnotif/btnotifsrv/src/btnotifconnectiontracker.cpp Thu May 27 13:01:44 2010 +0300
@@ -1,23 +1,18 @@
/*
-* ============================================================================
-* Name : btnotifconnectiontracker.cpp
-* Part of : bluetoothengine / btnotif
-* Description : Bluetooth connection tracker and manager.
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
-* Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
+* Contributors:
*
-* Contributors:
-* Nokia Corporation
-* ============================================================================
-* Template version: 4.1
+* Description: Bluetooth connection tracker and manager.
+*
*/
#include "btnotifconnectiontracker.h"
@@ -26,17 +21,14 @@
#include <btextnotifierspartner.h>
#endif
-#include "btnotifconnection.h"
+#include <btservices/btdevextension.h>
+#include <btservices/btdevrepository.h>
+
#include "btnotifsession.h"
#include "btnotifclientserver.h"
#include "bluetoothtrace.h"
+#include "btnotifpairingmanager.h"
-/** Id for the link key watcher active object. */
-const TInt KLinkCountWatcher = 30;
-/** Id for the pairing result watcher active object. */
-const TInt KSspResultWatcher = 31;
-/** Id for the registry watcher active object (TEMP!). */
-const TInt KRegistryWatcher = 41;
/** Time window for determining if there are too many requests. */
#ifndef __WINS__
#define KDENYTHRESHOLD TTimeIntervalSeconds(3)
@@ -47,24 +39,6 @@
// ======== LOCAL FUNCTIONS ========
-// ---------------------------------------------------------------------------
-// Checks if the notifier is one launched by the security manager of the
-// protocol stack. These notifiers need to be served unless really not possible.
-// ---------------------------------------------------------------------------
-//
-TBool IsStackSecmanNotifier( TInt aUid )
- {
- TBool result = EFalse;
- if( aUid == KBTManAuthNotifierUid.iUid || aUid == KBTManPinNotifierUid.iUid ||
- aUid == KBTPinCodeEntryNotifierUid.iUid || aUid == KBTNumericComparisonNotifierUid.iUid ||
- aUid == KBTPasskeyDisplayNotifierUid.iUid )
- {
- result = ETrue;
- }
- return result;
- }
-
-
// ======== MEMBER FUNCTIONS ========
// ---------------------------------------------------------------------------
@@ -84,42 +58,11 @@
void CBTNotifConnectionTracker::ConstructL()
{
BOstraceFunctionEntry0( DUMMY_DEVLIST );
- // Start watching the number of baseband links.
- TInt err = iLinkCount.Attach( KPropertyUidBluetoothCategory,
- KPropertyKeyBluetoothGetPHYCount );
- // There is not much point to continue if we can't attach to
- // the link count key.
- User::LeaveIfError( err );
- iLinkCountActive = CBtSimpleActive::NewL( *this, KLinkCountWatcher );
- iLinkCount.Subscribe( iLinkCountActive->RequestStatus() );
- iLinkCountActive->GoActive();
// Open a handle to the registry server
User::LeaveIfError( iBTRegistrySession.Connect() );
// Open a handle to the socket server
User::LeaveIfError( iSockServ.Connect() );
- iPairingServ = new( ELeave ) RBluetoothPairingServer();
- if( iPairingServ->Connect() )
- {
- // Delete in case of error - there is no good other way to keep track.
- delete iPairingServ;
- iPairingServ = NULL;
- }
- else
- {
- iSspResultActive = CBtSimpleActive::NewL( *this, KSspResultWatcher );
- User::LeaveIfError( iSspResultSession.Open( *iPairingServ ) );
- iSspResultSession.SimplePairingResult( iSspResultAddr, iSspResultActive->RequestStatus() );
- iSspResultActive->GoActive();
- }
- iConnMan = CBTEngConnMan::NewL( this );
- iPhyLinks = CBluetoothPhysicalLinks::NewL( *this, iSockServ );
-// ToDo: remove this when registry notifications API is available!!
- err = iRegistryChange.Attach( KPropertyUidBluetoothCategory, KPropertyKeyBluetoothRegistryTableChange );
- User::LeaveIfError( err );
- iRegistryActive = CBtSimpleActive::NewL( *this, KRegistryWatcher );
- iRegistryChange.Subscribe( iRegistryActive->RequestStatus() );
- iRegistryActive->GoActive();
-// End ToDo
+ iPairingManager = CBTNotifPairingManager::NewL(*this, iServer->DevRepository() );
BOstraceFunctionExit0( DUMMY_DEVLIST );
}
@@ -145,92 +88,24 @@
CBTNotifConnectionTracker::~CBTNotifConnectionTracker()
{
BOstraceFunctionEntry0( DUMMY_DEVLIST );
- iConnArray.ResetAndDestroy();
- iConnArray.Close();
iDeniedRequests.Close();
- delete iLinkCountActive;
- iLinkCount.Close();
-
- delete iConnMan;
- delete iPhyLinks;
+ delete iPairingManager;
iSockServ.Close();
- delete iSspResultActive;
- iSspResultSession.Close();
- if( iPairingServ )
- {
- iPairingServ->Close();
- delete iPairingServ;
- }
- delete iRegistryActive;
- iRegistryChange.Close();
iBTRegistrySession.Close();
BOstraceFunctionExit0( DUMMY_DEVLIST );
}
// ---------------------------------------------------------------------------
-// Process a client message related to notifiers.
+// Process notifier message related to pairing notifiers.
// ---------------------------------------------------------------------------
//
-void CBTNotifConnectionTracker::DispatchNotifierMessageL( const RMessage2& aMessage )
+void CBTNotifConnectionTracker::HandlePairingNotifierRequestL( const RMessage2& aMessage )
{
BOstraceFunctionEntryExt ( DUMMY_LIST, this, aMessage.Function() );
- TInt opcode = aMessage.Function();
- TInt uid = aMessage.Int0();
- const RMessage2* message = &aMessage;
- // Use a pointer to the original message, so that we don't duplicate it.
- // Then we avoid any bookkeeping for keeping them in sync.
- if( opcode == EBTNotifCancelNotifier )
- {
- // We only accept a cancel message from the same session as the original
- // request (this is enforced by the RNotifier backend). So we use the
- // session of the cancel request (if this would change, the same way as
- // for updates can be followed).
- // We need to find the original request to identify the handler of the
- // connection; the uid points to the original request.
- message = ( (CBTNotifSession *) aMessage.Session() )->FindMessageFromUid( uid );
- }
- else if( opcode == EBTNotifUpdateNotifier )
- {
- // We accept a update messages from any client, although in practice,
- // they will all come from the same session (through RNotifier).
- // We need to find the original request to identify the handler of the
- // connection (the uid points to the original request). Through the
- // server, we get it from any session.
- message = iServer->FindMessageFromUid( uid );
- }
- if( !message )
- {
- // It's hard to continue if we don't know where to route the message.
- User::Leave( KErrDisconnected );
- }
- TBuf8<0x250> paramsBuf; // Size needs to be long enough to read all possible parameter sizes.
- CBTNotifConnection* connection = FindConnectionFromMessageL( opcode, *message, paramsBuf );
- if( !connection )
- {
- User::Leave( KErrDisconnected );
- }
- switch( opcode )
- {
- case EBTNotifStartSyncNotifier:
- case EBTNotifStartAsyncNotifier:
- connection->HandleNotifierRequestL( paramsBuf, aMessage );
- break;
- case EBTNotifUpdateNotifier:
- connection->HandleNotifierUpdateL( paramsBuf, aMessage );
- break;
- case EBTNotifCancelNotifier:
- // Complete the cancel message already here, so that the caller can
- // continue, and the next operation can close sessions with the caller.
- aMessage.Complete( KErrNone );
- connection->CancelNotifierRequestL( *message );
- break;
- default:
- break;
- }
+ iPairingManager->HandlePairingNotifierRequestL(aMessage);
BOstraceFunctionExit1( DUMMY_DEVLIST, this );
}
-
// ---------------------------------------------------------------------------
// Handle a request related to pairing.
// ---------------------------------------------------------------------------
@@ -238,145 +113,10 @@
void CBTNotifConnectionTracker::HandleBondingRequestL( const RMessage2& aMessage )
{
BOstraceFunctionEntryExt ( DUMMY_LIST, this, aMessage.Function() );
- // Bonding is an infrequently occurring operation, so we don't waste memory
- // to keep a copy of the parameters. Instead we read them again when needed.
- TPckgBuf<TBTDevAddr> addrBuf;
- TInt opcode = aMessage.Function();
- if( opcode == EBTEngPairDevice )
- {
- aMessage.ReadL( EBTNotifSrvParamSlot, addrBuf );
- }
- else if( opcode == EBTEngCancelPairDevice )
- {
- const RMessage2* message =
- ( (CBTNotifSession *) aMessage.Session() )->FindMessageFromUid( EBTEngPairDevice );
- message->ReadL( EBTNotifSrvParamSlot, addrBuf );
- }
- BtTraceBtAddr1( TRACE_DEBUG, DUMMY_LIST, "CBTNotifConnectionTracker::HandleBondingRequestL() addr=", addrBuf() );
- TInt err = KErrNotFound;
- CBTNotifConnection* connection = FindConnectionHandler( addrBuf() );
- if( opcode == EBTEngPairDevice )
- {
- if( !connection )
- {
- // Create a connection first, then tell it to bond.
- err = iPhyLinks->CreateConnection( addrBuf() );
- connection = CBTNotifConnection::NewLC( addrBuf(), this );
- iConnArray.AppendL( connection );
- CleanupStack::Pop( connection );
- }
- else
- {
- // There is an existing connection. Care must be taken, the connection
- // _should_ be disconnect first if this device is already paired, so that
- // we are sure that we don't mix up the state of the connection.
- RBTPhysicalLinkAdapter link;
- err = link.Open( iSockServ, addrBuf() );
- TUint32 linkState = 0;
- if( !err )
- {
- err = link.PhysicalLinkState( linkState );
- }
- if( !err && linkState & ( ENotifyAuthenticationComplete | ENotifyEncryptionChangeOn ) )
- {
- // For now, we just reject the request.
- err = KErrAlreadyExists;
- }
- link.Close();
- }
- if( !err )
- {
- // Start bonding immediately so that the connection object is in the right state.
- connection->StartBondingL( aMessage );
- }
- }
- else if( opcode == EBTEngCancelPairDevice && connection )
- {
- connection->CancelBondingL();
- err = KErrNone;
- aMessage.Complete( err );
- }
- // KErrNotFound is returned for a request to cancel pairing that has no connection.
- if( err )
- {
- aMessage.Complete( err );
- }
+ iPairingManager->HandleBondingRequestL(aMessage);
BOstraceFunctionExit1( DUMMY_DEVLIST, this );
}
-
-// ---------------------------------------------------------------------------
-// Handle a change in the number of connections.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::HandleLinkCountChangeL()
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- TInt linkCount = 0;
- User::LeaveIfError( iLinkCount.Get( linkCount ) );
- if( linkCount )
- {
- RBTDevAddrArray links;
- CleanupClosePushL( links );
- User::LeaveIfError( iPhyLinks->Enumerate( links, 10 ) );
- __ASSERT_ALWAYS( links.Count(), PanicServer( EBTNotifPanicBadState ) );
- for( TInt i = iConnArray.Count() -1; i >= 0 ; i-- )
- {
- // Loop backwards, as we may remove entries from the array.
-
- // First check the existing connections, and
- // remove disconnected links
- TBTDevAddr addr = iConnArray[i]->Address();
- TInt pos = links.Find( addr );
- if( pos > KErrNotFound )
- {
- // The link we know is still connected,
- // remove the watceher from the array.
- links.Remove( pos );
- // ToDo: see comment below!
- }
- else if( iConnArray[i]->CurrentOperation() == CBTNotifConnection::EIdle )
- {
- // This link is no more connected and idle, remove.
- CBTNotifConnection* connection = iConnArray[i];
- iConnArray.Remove( i ); // Does not delete the object.
- delete connection;
- }
- // else we wait for the link to complete its operations.
- }
- // Now we have an array with only the new connections.
- // Add new watchers.
- for( TInt i = 0; i < links.Count(); i++ )
- {
- CBTNotifConnection* connection = CBTNotifConnection::NewLC( links[i], this );
- iConnArray.AppendL( connection );
- CleanupStack::Pop( connection );
- }
- // Close the links RBTDevAddrArray, needed before going out of scope.
- CleanupStack::PopAndDestroy();
- }
- else
- {
- for( TInt i = iConnArray.Count() -1; i >= 0 ; i-- )
- {
- if( iConnArray[i]->CurrentOperation() == CBTNotifConnection::EIdle )
- {
- // This link is now idle, so we can remove it safely.
- CBTNotifConnection* connection = iConnArray[i];
- iConnArray.Remove( i ); // Does not delete the object.
- delete connection;
- }
- }
- if( !iConnArray.Count() )
- {
- // The array is idle, clean up the array resources.
- iConnArray.Reset();
- }
- }
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
// ---------------------------------------------------------------------------
// Check if this device has been denied a connection already before.
// Also check if a previous connection attempt has just been rejected.
@@ -415,276 +155,6 @@
return result;
}
-
-// ---------------------------------------------------------------------------
-// From class MBluetoothPhysicalLinksNotifier.
-// Handle baseband connection completion.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::HandleCreateConnectionCompleteL( TInt aErr )
- {
- BOstraceFunctionEntryExt ( DUMMY_LIST, this, aErr );
- // We only connect links for starting outgoing bonding.
- const RMessage2* message = iServer->FindMessageFromUid( (TInt) EBTEngPairDevice );
- if( message )
- {
- TPckgBuf<TBTDevAddr> addrBuf;
- message->ReadL( EBTNotifSrvParamSlot, addrBuf );
- CBTNotifConnection* connection = FindConnectionHandler( addrBuf() );
- __ASSERT_ALWAYS( connection, PanicServer( EBTNotifPanicBadState ) );
- if( !aErr && connection->CurrentOperation() == CBTNotifConnection::EIdle )
- {
- TRAP( aErr, connection->StartBondingL( *message ) );
- }
- if( aErr && connection->CurrentOperation() == CBTNotifConnection::EBonding )
- {
- connection->PairingResult( aErr ); // Launch error note
- }
- }
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBluetoothPhysicalLinksNotifier.
-// Handle baseband disconnection.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::HandleDisconnectCompleteL( TInt aErr )
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- // We only disconnect links for starting outgoing bonding.
- const RMessage2* message = iServer->FindMessageFromUid( (TInt) EBTEngPairDevice );
- if( message )
- {
- TPckgBuf<TBTDevAddr> addrBuf;
- message->ReadL( EBTNotifSrvParamSlot, addrBuf );
- if( !aErr )
- {
- aErr = iPhyLinks->CreateConnection( addrBuf() );
- }
- if( aErr )
- {
- iServer->CompleteMessage( message->Handle(), aErr, KNullDesC8 );
- CBTNotifConnection* connection = FindConnectionHandler( addrBuf() );
- __ASSERT_ALWAYS( connection, PanicServer( EBTNotifPanicBadState ) );
- connection->PairingResult( aErr ); // Launch error note
- }
- }
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBluetoothPhysicalLinksNotifier.
-// Handle disconnection of all links.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::HandleDisconnectAllCompleteL( TInt aErr )
- {
- (void) aErr;
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBTEngConnObserver.
-// Handle service-level connection completion.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::ConnectComplete( TBTDevAddr& aAddr,
- TInt aErr, RBTDevAddrArray* aConflicts )
- {
- (void) aAddr;
- (void) aErr;
- (void) aConflicts;
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBTEngConnObserver.
-// Handle service-level disconnection.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr )
- {
- (void) aAddr;
- (void) aErr;
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBtSimpleActiveObserver.
-// Handle the active object completion.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::RequestCompletedL( CBtSimpleActive* aActive,
- TInt aStatus )
- {
- BOstraceFunctionEntryExt ( DUMMY_LIST, this, aActive->RequestId() );
- BOstraceExt2( TRACE_DEBUG, DUMMY_DEVLIST,
- "CBTNotifConnectionTracker::MBAORequestCompletedL() requestid=%d status=%d",
- aActive->RequestId(), aStatus);
- if( aActive->RequestId() == KLinkCountWatcher )
- {
- iLinkCount.Subscribe( aActive->RequestStatus() );
- aActive->GoActive();
- if( !aStatus )
- {
- // HandleLinkCountChangeL();
- }
- }
-// ToDo: remove this when registry notifications API is available!!
- else if( aActive->RequestId() == KRegistryWatcher )
- {
- // BTRegistry notifies of a change. Check which one.
- iRegistryChange.Subscribe( aActive->RequestStatus() );
- aActive->GoActive();
- TInt tableChanged = 0;
- if( !aStatus && !iRegistryChange.Get( tableChanged ) &&
- tableChanged == KRegistryChangeRemoteTable )
- {
- // A record for a remote device has changed. Tell all
- // connections to update their record.
- for( TInt i = 0; i < iConnArray.Count(); i++ )
- {
- // Reuse the functionality in the connection
- if( iConnArray[i]->CurrentOperation() < CBTNotifConnection::EReadingRegistry )
- {
- iConnArray[i]->RequestCompletedL( aActive, aStatus );
- }
- }
- }
- }
-// End ToDo
- else if( aActive->RequestId() == KSspResultWatcher )
- {
- iSspResultSession.SimplePairingResult( iSspResultAddr, iSspResultActive->RequestStatus() );
- iSspResultActive->GoActive();
- CBTNotifConnection* connection = FindConnectionHandler( iSspResultAddr );
- // ToDo: how to handle a result of a link that already disconnected?
- if( connection )
- {
- connection->PairingResult( aStatus );
- }
- }
- BOstraceFunctionExit1( DUMMY_DEVLIST, this );
- }
-
-
-// ---------------------------------------------------------------------------
-// From class MBtSimpleActiveObserver.
-// Cancel and clean up all requests related to the active object.
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::CancelRequest( TInt aRequestId )
- {
- BOstraceFunctionEntry0( DUMMY_DEVLIST );
- if( aRequestId == KLinkCountWatcher )
- {
- iLinkCount.Cancel();
- }
- else if( aRequestId == KSspResultWatcher )
- {
- iSspResultSession.CancelSimplePairingResult();
- }
- else if ( aRequestId == KRegistryWatcher )
- {
- iRegistryChange.Cancel();
- }
- BOstraceFunctionExit0( DUMMY_DEVLIST );
- }
-
-// ---------------------------------------------------------------------------
-// From class MBtSimpleActiveObserver.
-//
-// ---------------------------------------------------------------------------
-//
-void CBTNotifConnectionTracker::HandleError( CBtSimpleActive* aActive,
- TInt aError )
- {
- (void) aActive;
- (void) aError;
- }
-
-// ---------------------------------------------------------------------------
-// Parse the details from a client message and find the associated handler.
-// ---------------------------------------------------------------------------
-//
-CBTNotifConnection* CBTNotifConnectionTracker::FindConnectionFromMessageL(
- TInt aOpcode, const RMessage2& aMessage, TDes8& aBuffer )
- {
- BOstraceFunctionEntry1( DUMMY_DEVLIST, this );
- TInt uid = aMessage.Int0();
- aMessage.ReadL( EBTNotifSrvParamSlot, aBuffer );
- TBTDevAddr addr = ParseAddressL( uid, aBuffer );
- // If this is a
- CBTNotifConnection* connection = FindConnectionHandler( addr );
- if( !connection && IsStackSecmanNotifier( uid ) &&
- ( aOpcode == EBTNotifStartAsyncNotifier || aOpcode == EBTNotifStartSyncNotifier ) )
- {
- // A notifier from stack. This happens if e.g. the pairing
- // request comes in before the link count changes (like security
- // mode 3). Create the handler and queue the request.
- // And note that
- connection = CBTNotifConnection::NewLC( addr, this );
- iConnArray.AppendL( connection );
- CleanupStack::Pop( connection );
- }
- BOstraceFunctionExitExt( DUMMY_DEVLIST, this, connection );
- return connection;
- }
-
-
-// ---------------------------------------------------------------------------
-// read the address from a client message.
-// ---------------------------------------------------------------------------
-//
-TBTDevAddr CBTNotifConnectionTracker::ParseAddressL( TInt aUid,
- const TDesC8& aParamsBuf ) const
- {
- BOstraceFunctionEntry1( DUMMY_DEVLIST, this );
- TBTDevAddr addr;
- if( IsStackSecmanNotifier( aUid ) )
- {
- // For all these, the address is the first data member,
- // so can be read using the TBTNotifierParams data structure.
- TBTNotifierParams params;
- TPckgC<TBTNotifierParams> paramsPckg( params );
- paramsPckg.Set( aParamsBuf );
- addr = paramsPckg().iBDAddr;
- }
- //else if( ) other notifier types
- BOstraceFunctionExitExt( DUMMY_DEVLIST, this, &addr );
- return addr;
- }
-
-
-// ---------------------------------------------------------------------------
-// Find a specific connection.
-// ---------------------------------------------------------------------------
-//
-CBTNotifConnection* CBTNotifConnectionTracker::FindConnectionHandler(
- const TBTDevAddr& aAddr ) const
- {
- BOstraceFunctionEntry1( DUMMY_DEVLIST, this );
- CBTNotifConnection* conn = NULL;
- if( aAddr != TBTDevAddr() )
- {
- // This may be replaced by RArray::Find with appropriate key
- for( TInt i = 0; i < iConnArray.Count(); i++ )
- {
- if( iConnArray[i]->Address() == aAddr )
- {
- conn = iConnArray[i];
- break;
- }
- }
- }
- BOstraceFunctionExitExt( DUMMY_DEVLIST, this, conn );
- return conn;
- }
-
-
// ---------------------------------------------------------------------------
// Record and check the time between connection attempts.
// ---------------------------------------------------------------------------
@@ -719,3 +189,4 @@
BOstraceFunctionExitExt( DUMMY_DEVLIST, this, result );
return result;
}
+