diff -r 43824b19ee35 -r 837dcc42fd6a bluetoothengine/btnotif/btnotifsrv/src/btnotifsession.cpp --- a/bluetoothengine/btnotif/btnotifsrv/src/btnotifsession.cpp Fri May 14 16:01:46 2010 +0300 +++ b/bluetoothengine/btnotif/btnotifsrv/src/btnotifsession.cpp Thu May 27 13:01:44 2010 +0300 @@ -1,27 +1,25 @@ /* -* ============================================================================ -* Name : btnotifsession.cpp -* Part of : bluetoothengine / btnotif -* Description : Session class for handling commands from clients. +* 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: Session class for handling commands from clients. +* */ #include "btnotifsession.h" #include +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#endif #include "btnotifclientserver.h" #include "btnotifsettingstracker.h" #include "btnotifconnectiontracker.h" @@ -81,12 +79,8 @@ // CBTNotifSession::~CBTNotifSession() { - for( TInt i = 0; i < iMessageQ.Count(); i++ ) - { - // Complete all outstanding messages with error code - iMessageQ[i].Complete( KErrSessionClosed ); - } - iMessageQ.Close(); // Cleans up all message objects. + // clients must complete the message they are responsible for + // we do not complete any message here Server()->RemoveSession(); } @@ -97,59 +91,71 @@ // void CBTNotifSession::ServiceL( const RMessage2& aMessage ) { + CBTNotifConnectionTracker* connTracker = Server()->ConnectionTracker(); TInt opCode = aMessage.Function(); - if ( opCode == EBTNotifCancelNotifier || - opCode == EBTNotifStartSyncNotifier || - opCode == EBTNotifStartAsyncNotifier || - opCode == EBTNotifUpdateNotifier ) - { - TInt uid = aMessage.Int0(); - if( uid == KDeviceSelectionNotifierUid.iUid ) - { - // Note for implementers: - // message queue is not used in this notifier handling (due - // to its drawbacks for exception handlings in various situations). - // implementations using message queue will be migrated step - // by step. - - TRAPD( err, { - CBTNotifDeviceSelector& selector = Server()->DeviceSelectorL(); - selector.DispatchNotifierMessageL( aMessage ); } - ); + TInt uid = aMessage.Int0(); + TInt err( KErrNotReady ); + switch(opCode){ + case EBTNotifCancelNotifier: + case EBTNotifStartSyncNotifier: + case EBTNotifStartAsyncNotifier: + case EBTNotifUpdateNotifier: + if( uid == KDeviceSelectionNotifierUid.iUid ) + { + TRAP( err, { + CBTNotifDeviceSelector& selector = Server()->DeviceSelectorL(); + selector.DispatchNotifierMessageL( aMessage ); } + ); + if ( err ) + { + aMessage.Complete( err ); + } + // deviceselector takes the ownership of aMessage. + } + else + { + // PIN/ SSP pairing notifiers from BT stack: + // ***** Note for implementers: + // message queue is not used for this notifier handling. + if ( uid == KBTManAuthNotifierUid.iUid || + uid == KBTManPinNotifierUid.iUid || + uid == KBTPinCodeEntryNotifierUid.iUid || + uid == KBTNumericComparisonNotifierUid.iUid || + uid == KBTPasskeyDisplayNotifierUid.iUid || + uid == KBTUserConfirmationNotifierUid.iUid ) + { + if( connTracker ) + { + // Pass it to the connection tracker. + TRAP( err, + connTracker->HandlePairingNotifierRequestL( aMessage ) ); + } + if ( err ) + { + // tracker not available, can't do this now. + aMessage.Complete( err ); + } + } + } + break; + case EBTNotifPairDevice: + case EBTNotifCancelPairDevice: + // Pairing requests from clients: + if ( connTracker ) + { + TRAP( err, connTracker->HandleBondingRequestL( aMessage ) ); + } if ( err ) { - aMessage.Complete( err ); + // tracker not available, can't do this now. + aMessage.Complete( err ); } - // deviceselector takes the ownership of aMessage. - return; - } - } - - // Messages are completed by message handlers, not here. - // Queue the message already so that handlers can find it from the queue. - iMessageQ.AppendL( aMessage ); - // The position is assumed to not change during the execution of this function. - TInt handle = aMessage.Handle(); // Store the handle for de-queueing - TRAPD( err, DispatchMessageL( aMessage ) ); - if( err || ( aMessage.IsNull() && FindMessageFromHandle( handle ) ) ) - { - // If the message has been completed by now (handle is null and the message - // still in the queue), we remove it again from the queue. Otherwise it - // will be completed by the handling handler when it has handled the handling. - for( TInt i = 0; i < iMessageQ.Count(); i++ ) - { - // This may be replaced by RArray::Find with appropriate key - if( iMessageQ[i].Handle() == handle ) - { - iMessageQ.Remove( i ); - } - } - } - if( err && !aMessage.IsNull() ) - { - aMessage.Complete( err ); - } + break; + default: + aMessage.Complete( KErrNotSupported ); + break; } +} // --------------------------------------------------------------------------- @@ -162,143 +168,3 @@ Server()->AddSession(); } -// --------------------------------------------------------------------------- -// Complete a client message from a message handle with given data. -// If a zero-length descriptor is passed, no data will be written back. -// --------------------------------------------------------------------------- -// -TInt CBTNotifSession::CompleteMessage( TInt aHandle, TInt aReason, const TDesC8& aReply ) - { - TInt err = KErrNotFound; - // This may be replaced by RArray::Find with appropriate key - for( TInt i = 0; i < iMessageQ.Count(); i++ ) - { - if( iMessageQ[i].Handle() == aHandle ) - { - err = KErrNone; - if( aReply.Length() ) - { - // For now, assume a fixed index for the result. - // Change this if a the client can pass more arguments! - // ToDo: replace with constant! - err = iMessageQ[i].Write( EBTNotifSrvReplySlot, aReply ); - // Should the result be passed back to the calller, - // or used to complete the message? - } - iMessageQ[i].Complete( aReason ); - iMessageQ.Remove( i ); - break; - } - } - return err; - } - - -// --------------------------------------------------------------------------- -// Find a client message from an RMessage2 handle. -// --------------------------------------------------------------------------- -// -const RMessage2* CBTNotifSession::FindMessageFromHandle( TInt aHandle ) const - { - // This may be replaced by RArray::Find with appropriate key - for( TInt i = 0; i < iMessageQ.Count(); i++ ) - { - if( iMessageQ[i].Handle() == aHandle ) - { - return &iMessageQ[i]; - } - } - return NULL; - } - - -// --------------------------------------------------------------------------- -// Process a client message. -// The processing here relies on RNotifier backend server for queueing -// notifiers on the same channel. Therefore pairing (SSP and legacy) and -// authorization notifiers arrive in order, not simultaneously, even if -// they use arrive on different session instances. -// --------------------------------------------------------------------------- -// -void CBTNotifSession::DispatchMessageL( const RMessage2& aMessage ) - { - BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, aMessage.Function() ); - CBTNotifSettingsTracker* settTracker = Server()->SettingsTracker(); - CBTNotifConnectionTracker* connTracker = Server()->ConnectionTracker(); - LeaveIfNullL( settTracker, KErrNotReady ); - TInt opcode = aMessage.Function(); - if( opcode < EBTNotifMinValue ) - { - User::Leave( KErrArgument ); - } - switch( opcode ) - { - case EBTNotifCancelNotifier: - case EBTNotifStartSyncNotifier: - case EBTNotifStartAsyncNotifier: - case EBTNotifUpdateNotifier: - { - // All these messages get the same treatment: forward - // to settings and connection tracker, who will deal with it appropriately. - // First the settings tracker handles the message. - settTracker->DispatchNotifierMessageL( aMessage ); - if( connTracker && !aMessage.IsNull() ) - { - // Pass it on to the connection tracker, if it hasn't been completed yet. - connTracker->DispatchNotifierMessageL( aMessage ); - } - else - { - // Power is off, can't do this now. - LeaveIfNullL( connTracker, KErrNotReady ); - } - if( opcode != EBTNotifStartAsyncNotifier && !aMessage.IsNull() ) - { - // Nobody has yet completed the message, and it is a synchronous - // one so we'll do it here to allow the notifier to keep on going. - aMessage.Complete( KErrNone ); - } - } - break; - case EBTEngPrepareDiscovery: - { - // This is functionality only related to existing connections. - // Can't do when power is off though. - LeaveIfNullL( connTracker, KErrNotReady ); - //connTracker->HandlePairingRequestL( aMessage ); - } - break; - case EBTEngPairDevice: - case EBTEngCancelPairDevice: - { - // This is functionality only related to connections. - // Can't do when power is off though. - LeaveIfNullL( connTracker, KErrNotReady ); - connTracker->HandleBondingRequestL( aMessage ); - } - break; - default: - // Communicate result back. - User::Leave( KErrNotSupported ); - break; - } - BOstraceFunctionExit1( DUMMY_DEVLIST, this ); - } - - -// --------------------------------------------------------------------------- -// Find a client message from an RNotifier UID. -// --------------------------------------------------------------------------- -// -const RMessage2* CBTNotifSession::FindMessageFromUid( TInt aUid ) const - { - // This may be replaced by RArray::Find with appropriate key - for( TInt i = 0; i < iMessageQ.Count(); i++ ) - { - if( iMessageQ[i].Int0() == aUid ) - { - return &iMessageQ[i]; - } - } - return NULL; - }