--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/accessoryservices/accessoryserver/src/Server/AccSrvConnectionHandler.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,1223 @@
+/*
+* Copyright (c) 2002-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.
+*
+* Contributors:
+*
+* Description: Connection Handler
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "AccSrvConnectionHandler.h"
+#include "AccSrvConnectionController.h" //MAccSrvConnectionControllerObserver
+#include "AccPolSubblockNameArrayAccessor.h"
+#include "AccPolAccessoryPolicy.h"
+#include "AccSrvASYProxyHandler.h"
+#include "AccSrvServerModel.h"
+#include "AccPolGenericIDAccessor.h"
+#include "AccPolicyDB.h"
+#include "acc_debug.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+const TUid KAccFwUiDialogNotifierUid = { 0x10205062 };
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::CAccSrvConnectionHandler
+// -----------------------------------------------------------------------------
+//
+CAccSrvConnectionHandler::CAccSrvConnectionHandler(
+ MAccSrvConnectionControllerObserver* aCallback,
+ CAccSrvServerModel * aModel,
+ CAccPolAccessoryPolicy* aPolicy )
+ : CAccSrvHandlerBase (aCallback),
+ iPolicy( aPolicy ),
+ iModel( aModel),
+ iReplyValue(0),
+ iReplyPck( iReplyValue)
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::CAccSrvConnectionHandler()" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::ConstructL()
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ConstructL()" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CAccSrvConnectionHandler* CAccSrvConnectionHandler::NewL(
+ MAccSrvConnectionControllerObserver* aCallback,
+ CAccSrvServerModel* aModel,
+ CAccPolAccessoryPolicy* aPolicy )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::NewL()" );
+
+ CAccSrvConnectionHandler* self = new( ELeave ) CAccSrvConnectionHandler(
+ aCallback, aModel, aPolicy );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::NewL - return self" );
+ return self;
+ }
+
+// Destructor
+CAccSrvConnectionHandler::~CAccSrvConnectionHandler()
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::~CAccSrvConnectionHandler()" );
+
+ //closes notfier connection
+ iNotifier.Close();
+ iRequestDataArray.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::RunL
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::RunL()
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::RunL()" );
+
+ switch ( iState )
+ {
+ /*
+ Get response from the user (the notifier completes asyncronous command). Send
+ accessory update command to ASY.
+ */
+
+ case EGetSelectionFromUser:
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::RunL() - Get selection from user" );
+
+ if ( iReplyValue )
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::RunL() - User selection %d", iReplyValue );
+
+ //update generic id
+ iPolicy->UpdateGenericIDL( iGenericID, iReplyValue);
+
+ TASYCommandParamRecord asyCommandParamRecord;
+ asyCommandParamRecord.iCmdValue = 0;//Not used in update command
+ asyCommandParamRecord.iGenericID = iGenericID;
+
+ //Send request to ASY Proxy Handler
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::RunL() - Send update request");
+ TInt trId = iCallback->HandleASYCommsL( ECmdAccessoryUpdated,
+ asyCommandParamRecord );
+
+ //Stored request data is used when response is received from ASY
+ //(i.e. HandleValueMessageL)
+ StoreRequestData( asyCommandParamRecord.iNameRecord, trId, ETrue );
+
+ //Store this object to queue to be able to receive response from ASY
+ iCallback->RegisterControlMessageL( ESetValue, this );
+
+ //closes notfier connection
+ iNotifier.Close();
+ }
+ else
+ {
+ // If this is KErrCancel, cancel is already done. Handle only if user has cancelled the dialog
+ if ( KErrNone == iStatus.Int() )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::RunL() - User cancel");
+ iCallback->ConnectionHandlingCancel( this);
+ }
+ }
+
+ }
+ break;
+
+ case EInitializeConnection:
+ {
+ if( iCallback->ServerModelHandle().ASYsLoadCompleted() )
+ {
+ if ( iConnectionUpdate )
+ {
+ //get new capabilities to use
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::RunL() - Connection update, set new capabilities");
+ iModel->CapabilityStorage().UseUpdatedGenericIDL( iGenericID);
+ }
+
+ if ( InitializeCriticalCapsL() )
+ {
+ //ASY query started
+ }
+ else
+ {
+ if ( iConnectionUpdate )
+ {
+ //No critical caps, continue connection handling
+ TAccPolGenericID oldGenericId;
+ iModel->FindWithUniqueIDL( iGenericID.UniqueID(), oldGenericId);
+ iCallback->HandleConnectionUpdateValidationL(
+ iGenericID, oldGenericId, this, KErrNone );
+ }
+ else
+ {
+ //No critical caps, continue connection handling
+ iCallback->HandleConnectValidationL( iGenericID, this, KErrNone );
+ }
+ }
+ }
+ else
+ {
+ //ASY is not ready yet, wait for an another RunL-loop
+ CAccSrvHandlerBase::IssueRequest();
+ }
+ }
+ break;
+
+ case EWaitForUINotifier:
+ {
+ // If cancelled, do not show dialog
+ if ( KErrCancel != iStatus.Int() )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::RunL() - Change in boot state, try again open selection dialog" );
+ OpenSelectionDialogL();
+ }
+ }
+ break;
+
+ default:
+ TRACE_ASSERT_ALWAYS;
+ break;
+ }
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::RunL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::StartConnectionHandling
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::StartConnectionHandlingL(
+ TAccPolGenericID& aGenericID,
+ TBool aEvaluateConnectionRules,
+ TBool aUpdatedConnection )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::StartConnectionHandling()" );
+
+ iGenericID = aGenericID;
+ iConnectionUpdate = aUpdatedConnection;
+
+ //evaluate connection rules
+ if ( aEvaluateConnectionRules )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::StartConnectionHandling() - Evaluate connection rules" );
+
+ //check rules
+ TUint32 selectionListBitmask( 0 );
+ iPolicy->EvaluateConnectionRulesL( iGenericID, selectionListBitmask );
+
+ if ( selectionListBitmask )
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::StartConnectionHandling() - Selection bitmask: 0x%bb", selectionListBitmask);
+
+ //remove not supported items...
+ selectionListBitmask = selectionListBitmask & iModel->SupportedDevicesL();
+
+ //Check default selection
+ TInt defaultSelection( iModel->DeviceType() );
+
+ if ( selectionListBitmask == ( KASTTY | KASHeadset ) )
+ {
+ if ( defaultSelection != KASTTY )
+ {
+ defaultSelection = KASHeadset;
+ }
+ else
+ {
+ defaultSelection = KASTTY;
+ }
+ }
+ else
+ {
+ if ( defaultSelection == KASHeadset )
+ {
+ defaultSelection = 0;
+ }
+
+ defaultSelection = selectionListBitmask & defaultSelection;
+ }
+
+ if ( defaultSelection )
+ {
+ iReplyValue = defaultSelection;
+ iCallback->SetDefaultAccessoryInformation( iGenericID, defaultSelection );
+ CAccSrvHandlerBase::IssueRequest();
+ }
+ else
+ {
+ //check that more than one accessories in the selection list
+ TUint32 bitmask( 1 );
+ TInt accCount( 0 );
+ for ( TInt i( 0 ); i < 32; i++ )
+ {
+ if ( selectionListBitmask & bitmask )
+ {
+ if ( ++accCount > 1 )
+ {
+ //more than one accessories, stop the loop
+ break;
+ }
+ }
+ bitmask <<= 1;
+ }
+
+ if ( accCount > 1 )
+ {
+ //if there is possible selection show UI
+ SetupSelectionDialogL( selectionListBitmask );
+ }
+ else
+ {
+ //only one selection, don't show selection dialog
+ iState = EGetSelectionFromUser;
+ iReplyValue = selectionListBitmask;
+ iCallback->SetDefaultAccessoryInformation( iGenericID, selectionListBitmask );
+ CAccSrvHandlerBase::IssueRequest();
+ }
+ }
+
+ }
+ else
+ {
+ iState = EInitializeConnection;
+ }
+
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::StartConnectionHandling() - No connection rules" );
+ iState = EInitializeConnection;
+ }
+
+
+ // Atleas one Asynchronous request is made for ourselves,
+ // clients ConnectAccessory asynchronous request will be completed
+ // during it.
+ if ( iState == EInitializeConnection )
+ {
+ CAccSrvHandlerBase::IssueRequest();
+ }
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::StartConnectionHandling- return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::OpenSelectionDialogL
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::OpenSelectionDialogL()
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::OpenSelectionDialogL() - start" );
+
+
+ if ( !iModel->IdleDetected() )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::OpenSelectionDialogL() - Idle is not detected" );
+
+ //boot is ongoing, wait for that ui notifier is ready
+ iState = EWaitForUINotifier;
+
+ //wait for idle
+ Cancel();
+ iStatus = KRequestPending;
+ iModel->WaitForIdle( &iStatus );
+ SetActive();
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::OpenSelectionDialogL() - Boot ok, connect notifier" );
+
+ iState = EGetSelectionFromUser;
+
+ //selection bit mask package
+ TPckg<TUint32> selectionBitmaskPackage( iSelectionListBitmask );
+
+ //activate active object
+ Cancel();
+ iStatus = KRequestPending;
+
+ //open ui
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::OpenSelectionDialogL() - Open selection dialog" );
+ User::LeaveIfError( iNotifier.Connect() );
+ iNotifier.StartNotifierAndGetResponse(
+ iStatus,
+ KAccFwUiDialogNotifierUid,
+ selectionBitmaskPackage,
+ iReplyPck);
+ SetActive();
+ }
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::OpenSelectionDialogL() - end" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::OpenSelectionDialogL
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::SetupSelectionDialogL( TUint32 aSelectionListBitmask )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::SetupSelectionDialogL() - start" );
+ iSelectionListBitmask = aSelectionListBitmask;
+ //open dialog
+ OpenSelectionDialogL();
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::SetupSelectionDialogL() - end" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::UniqueIDForConnectionHandler
+// -----------------------------------------------------------------------------
+//
+TInt CAccSrvConnectionHandler::UniqueIDForConnectionHandler()
+ {
+ return iGenericID.UniqueID();
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::CancelConnectionHandling
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::CancelConnectionHandling()
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::CancelConnectionHandling() - start" );
+
+ if ( iNotifier.Handle() )
+ {
+ // If notifier exists, it must be cancelled
+ iNotifier.CancelNotifier( KAccFwUiDialogNotifierUid );
+ iNotifier.Close();
+ // No need to cancel notifier request, cancel comes from notifier
+ }
+
+ else if ( IsActive() )
+ {
+ if ( EWaitForUINotifier == iState )
+ {
+ // Internal request, cancel in different way
+ iModel->CancelWaitForIdle();
+ }
+ else
+ {
+ Cancel();
+ }
+ }
+
+ // remove this from NotificationQueue
+ iCallback->CancelControlMessage( ESetValue, this );
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::CancelConnectionHandling() - end" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::ResetHandler
+// Resets member variables and is free to handle next connection
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::ResetHandler()
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResetHandler() - start" );
+ // Reset member variables related to connection
+ iSelectionListBitmask = 0;
+ iReplyValue = 0;
+ iState = EGetSelectionFromUser;
+ iRequestDataArray.Reset();
+ // Reset generic id. This also indicates that this hander has no connection
+ TAccPolGenericID temp;
+ iGenericID = temp;
+ // No need to reset iPolicy, iModel or iGenericID
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResetHandler() - end" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::IsFree
+// -----------------------------------------------------------------------------
+//
+TBool CAccSrvConnectionHandler::IsFree()
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::IsFree() - UniqueID(%i)", iGenericID.UniqueID() );
+ return ( KErrNotFound == iGenericID.UniqueID() );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::InitializeCriticalCapsL
+// -----------------------------------------------------------------------------
+//
+TBool CAccSrvConnectionHandler::InitializeCriticalCapsL()
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::InitializeCriticalCapsL()" );
+
+ TBool ASYqueryStarted( EFalse );
+ TAccPolNameRecord nameRecord;
+ TUint32 name( 0 );
+ TASYCommandParamRecord asyCommandParamRecord;
+
+ CAccPolSubblockNameArray* criticalCapabilities = CAccPolSubblockNameArray::NewL();
+ CleanupStack::PushL( criticalCapabilities );
+
+ //After this query, criticalCapabilities contains all critical capabilities from iGenericID
+ iPolicy->ResolveCriticalCapabilitiesL( iGenericID, *criticalCapabilities );
+
+ TInt nameCount( TAccPolSubblockNameArrayAccessor::GetCount( *criticalCapabilities ) );
+
+ for ( TInt i( 0 ) ; i<nameCount ; ++i )
+ {
+ TAccPolSubblockNameArrayAccessor::GetName( *criticalCapabilities,
+ i,
+ name );
+ nameRecord.SetName( name );
+ asyCommandParamRecord.iNameRecord = nameRecord;
+ asyCommandParamRecord.iCmdValue = 0;//Not used in Getters
+ asyCommandParamRecord.iGenericID = iGenericID;
+
+ CCapValue* capValue = iModel->CapabilityStorage().GetCapability( iGenericID, name );
+
+ if ( !capValue)
+ {
+ User::Leave( KErrArgument );
+ }
+
+ if ( capValue->Type() == EAPVBool ||
+ capValue->Type() == EAPVUInt ||
+ capValue->Type() == EAPVInt )
+ {
+ TInt32 value( 0 );
+ TInt err( capValue->ValueInt( value ) );
+
+ if ( value == KErrUnknown && err == KErrNone )
+ {
+ StartASYCommandHandlingL( capValue->Type(), asyCommandParamRecord );
+ ASYqueryStarted = ETrue;
+ }
+ }
+ else
+ {
+ StartASYCommandHandlingL( capValue->Type(), asyCommandParamRecord );
+ ASYqueryStarted = ETrue;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( criticalCapabilities );
+
+ //In case of BT, query supported BT-profiles from BT-ASY
+ if ( iGenericID.PhysicalConnectionCaps( KPCBluetooth ) )
+ {
+ TAccPolNameRecord emptyNameRecord;
+
+ asyCommandParamRecord.iNameRecord = emptyNameRecord;
+ asyCommandParamRecord.iCmdValue = iGenericID.DeviceAddress();
+ asyCommandParamRecord.iGenericID = iGenericID;
+
+ StartASYCommandHandlingL( EAPVDes8, asyCommandParamRecord );
+
+ ASYqueryStarted = ETrue;
+ }
+
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::InitializeCriticalCapsL - return %d", ASYqueryStarted );
+ return ( ASYqueryStarted );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::StartASYCommandHandlingL
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::StartASYCommandHandlingL(
+ TAccPolValueType aValueType,
+ TASYCommandParamRecord& aASYCommandParam )
+ {
+ TProcessCmdId command( ECmdBadFunction );
+ TInt trId( 0 );
+
+ switch ( aValueType )
+ {
+ case EAPVBool:
+ {
+ command = ECmdGetValueBool;
+ }
+ break;
+
+ case EAPVInt:
+ {
+ command = ECmdGetValueTInt;
+ }
+ break;
+
+ case EAPVDes8:
+ {
+ if ( aASYCommandParam.iGenericID.PhysicalConnectionCaps( KPCBluetooth ) )
+ {
+ //Supported profiles are queried from BT-ASY
+ command = ECmdGetSupportedBTProfiles;
+ }
+ else
+ {
+ command = ECmdGetValueTDes8;
+ }
+ }
+ break;
+
+ default:
+ {
+ TRACE_ASSERT_ALWAYS;
+ }
+ break;
+ }
+
+ //Send request to ASY Proxy Handler
+ trId = iCallback->HandleASYCommsL( command, aASYCommandParam );
+
+ //Stored request data is used when response is received from ASY
+ //(i.e. HandleValueMessageL)
+ StoreRequestData( aASYCommandParam.iNameRecord, trId, EFalse );
+
+ //Store this object to queue to be able to receive response from ASY
+ iCallback-> RegisterControlMessageL( EGetValue, this );
+
+ }
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::StoreRequestData
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::StoreRequestData( TAccPolNameRecord aName,
+ TInt aTrId,
+ TBool aUpdateConnectionNotification )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::StoreRequestData()" );
+
+ TAccSrvRequestData requestData;
+ requestData.iName = aName;
+ requestData.iTrId = aTrId;
+ requestData.iUpdateNotification = aUpdateConnectionNotification;
+
+ iRequestDataArray.Append( requestData );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::StoreRequestData - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::FindRequestData
+//
+// Find the location of aTrId from iRequestDataArray
+// -----------------------------------------------------------------------------
+//
+TInt CAccSrvConnectionHandler::FindRequestData( TInt aTrId )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::FindRequestData()" );
+
+ TInt index( KErrNotFound );
+ TInt count( iRequestDataArray.Count() );
+
+ for ( TInt i( 0 ); i < count ; ++i )
+ {
+ if( iRequestDataArray.operator[]( i ).iTrId == aTrId )
+ {
+ index = i;//match found
+ }
+ }
+
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::FindRequestData - return %d", index );
+ return index;
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::HandleValueMessageL (From MQueueObserver)
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::HandleValueMessageL( TMsgID aMsgID,
+ TAccValueTypeTBool aValue,
+ TInt aErrorCode,
+ TInt aTrId )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessageL() - TBool" );
+
+ HandleValueMessagesL( aMsgID, aValue.iValue, aErrorCode, aTrId );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessageL - TBool - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::HandleValueMessageL (From MQueueObserver)
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::HandleValueMessageL( TMsgID aMsgID,
+ TAccValueTypeTInt aValue,
+ TInt aErrorCode,
+ TInt aTrId )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessageL() - TInt" );
+
+ HandleValueMessagesL( aMsgID, aValue.iValue, aErrorCode, aTrId );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessageL - TInt - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::HandleValueMessagesL
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::HandleValueMessagesL( TMsgID /*aMsgID*/,
+ TInt aValue,
+ TInt aErrorCode,
+ TInt aTrId )
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessagesL(value=%d)", aValue );
+
+ TInt index( FindRequestData( aTrId ) );
+ TAccSrvRequestData requestData;
+ TBool isUpdate( EFalse );
+
+ if ( KErrNotFound != index )
+ {
+ requestData.iName = iRequestDataArray.operator[]( index ).iName;
+ requestData.iTrId = iRequestDataArray.operator[]( index ).iTrId;
+ requestData.iUpdateNotification =
+ iRequestDataArray.operator[]( index ).iUpdateNotification;
+
+ if ( KErrNone == aErrorCode )
+ {
+
+ if ( requestData.iUpdateNotification )
+ {
+ //ASY response to accessory update command, continue connection process....
+ iState = EInitializeConnection;
+ IssueRequest();
+ isUpdate = ETrue;
+ }
+ else
+ {
+ //Store value to capability storage
+ TUint32 name;
+ requestData.iName.GetName( name );
+
+ CCapValue* value = iModel->CapabilityStorage().GetCapability( iGenericID, name );
+
+ if ( !value)
+ {
+ User::Leave( KErrArgument );
+ }
+ value->SetValueL( aValue );
+ }
+ }
+ else
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessagesL - Error response received(err=%d)", aErrorCode );
+ }
+
+ iRequestDataArray.Remove( index );//Remove this request from iRequestDataArray
+ }
+ else
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessagesL - Unidentified response received(TrID=%d)", aTrId );
+ TRACE_ASSERT_ALWAYS;
+ }
+
+ if ( 0 == iRequestDataArray.Count() && !isUpdate )
+ {
+ //No more pending requests
+ iCallback->HandleConnectValidationL( iGenericID, this, KErrNone );
+ }
+ else
+ {
+ //Wait next response
+ }
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessagesL - return void " );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::HandleValueMessageL (From MQueueObserver)
+//
+// Resolve the Generic ID according to the profile information
+// received from BT-ASY.
+//
+// TASYBTAccInfo type is only supported object in aValue. Its assumed that ASY
+// uses package buffer to make type safe transfer for that object i.e.
+// TASYBTAccInfo btInfo
+// TASYBTAccInfoPckgC btInfoPckgC( btInfo )
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::HandleValueMessageL( TMsgID /*aMsgID*/,
+ TDesC8& aValue,
+ TInt aErrorCode,
+ TInt aTrId )
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessageL(err=%d) - TDesC8", aErrorCode );
+
+ TInt index( FindRequestData( aTrId ) );
+
+ if ( KErrNotFound != index)
+ {
+ iRequestDataArray.Remove( index );//Remove this request from iRequestDataArray
+ //RequestData was not used in this case
+ }
+ else
+ {
+ TRACE_ASSERT_ALWAYS;//iRequestDataArray is out of sync
+ }
+
+ if ( KErrNone == aErrorCode )
+ {
+ ResolveGenericIDL( aValue );
+ }
+
+ if ( 0 == iRequestDataArray.Count() )
+ {
+ //No more pending requests
+ iCallback->HandleConnectValidationL( iGenericID, this, aErrorCode );
+ }
+ else
+ {
+ //Wait next response
+ }
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::HandleValueMessageL - TDesC8 - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::HandleValueMessagesL
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::HandleValueMessageL( TMsgID /*aMsgID*/,
+ TInt /*aTrId*/,
+ TPtr8* /*aPtrBuf*/,
+ TInt /*aErrorCode*/ )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::ResolveGenericIDL
+//
+// Fill Generic ID according supported profiles received from BT-ASY.
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::ResolveGenericIDL( TDesC8& aValue )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveGenericIDL()" );
+
+ TPckg<TASYBTAccInfo> btInfoPckg( *static_cast<TPckg<TASYBTAccInfo> *>( &aValue ) );
+
+ COM_TRACE_3( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveGenericIDL - model=%d type=%d prof=%d", btInfoPckg().iDeviceInfo, btInfoPckg().iDeviceType, btInfoPckg().iProfiles );
+ COM_TRACE_4( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveGenericIDL - HSP=%d HFP=%d AVRCP=%d A2DP=%d", btInfoPckg().iSupportedFeatures[0], btInfoPckg().iSupportedFeatures[1], btInfoPckg().iSupportedFeatures[2], btInfoPckg().iSupportedFeatures[3]);
+
+ TAccPolGenericIDAccessor::SetHWDeviceID( iGenericID,
+ btInfoPckg().iDeviceInfo );
+ TAccPolGenericIDAccessor::SetFeatureAttributeL( iGenericID,
+ KAccPolDTDeviceType,
+ btInfoPckg().iDeviceType );
+
+ if ( btInfoPckg().iReserved & KAccInfoDRM )
+ {
+ //If accessory have recording possibility, KAccNoDRMOutput capability is set.
+ //i.e. Capturing Major Service Class is indicated by accessory.
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveGenericIDL - DRM output not allowed" );
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccNoDRMOutput );
+ }
+
+ if ( btInfoPckg().iReserved & KAccInfoLatency )
+ {
+ //If accessory provides latency information, KAccAudioLatency capability is set.
+ //Initialize capability value as 0. Will be updated via notification.
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveGenericIDL - Latency set" );
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccAudioLatency, EAPVAccessory, EAPVInt, 0 );
+ }
+
+ ResolveGidL();
+
+ // Fill the Audio subblock and Bluetooth subblock
+ if ( KAccInfoHSP & btInfoPckg().iProfiles )//Headset Profile (HSP)
+ {
+ ResolveHSPSpecificGidL( btInfoPckg().iSupportedFeatures.At( EAccInfoHSPIndex ) );
+ }
+
+ if ( KAccInfoHFP & btInfoPckg().iProfiles )//Handsfree Profile (HFP)
+ {
+ ResolveHFPSpecificGidL( btInfoPckg().iSupportedFeatures.At( EAccInfoHFPIndex ) );
+ }
+
+ if ( KAccInfoAVRCP & btInfoPckg().iProfiles )//Audio Video Remote Control Profile (AVRCP)
+ {
+ ResolveAVRCPSpecificGidL( btInfoPckg().iSupportedFeatures.At( EAccInfoAVRCPIndex ) );
+ }
+
+ if ( KAccInfoA2DP & btInfoPckg().iProfiles )//Advanced Audio Distribution Profile (A2DP)
+ {
+ ResolveA2DPSpecificGidL( btInfoPckg().iSupportedFeatures.At( EAccInfoA2DPIndex ) );
+ }
+
+ //Update GenericID to CapabilityStorage
+ iModel->CapabilityStorage().SetGenericIDHeaderL(
+ *( reinterpret_cast<TAccPolGIDHeader*>( &iGenericID ) ) );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveGenericIDL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::ResolveGidL
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::ResolveGidL()
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveGidL()" );
+ TInt value;
+
+ //Set Audio Output Type capability. For CarKits its public, otherwise private.
+ if ( iGenericID.DeviceTypeCaps( KDTCarKit ) )
+ {
+ value = EAccAudioOutPutTypePublic;
+ }
+ else
+ {
+ value = EAccAudioOutPutTypePrivate;
+ }
+
+ //Set KAccAudioOutputType capability
+ iModel->CapabilityStorage().SetCapabilityL(
+ iGenericID, KAccAudioOutputType, EAPVPolicy, EAPVInt, value );
+
+ //Set KAccSetVolumeLevel capability with zero value.
+ //Real values are filled according to supported features.
+ iModel->CapabilityStorage().SetCapabilityL(
+ iGenericID, KAccSetVolumeLevel, EAPVPolicy, EAPVInt, 0 );
+
+ //Set KSBAudioSubblock capability group
+ TAccPolGenericIDAccessor::SetFeatureAttributeL( iGenericID,
+ KAccPolSBCapabilities,
+ iGenericID.SubblockCaps() |
+ KSBAudioSubblock );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveGidL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::ResolveHSPSpecificGidL
+//
+// HEADSET PROFILE 1.1 / supported features:
+// Remote audio volume control
+// -Boolean
+// -Optional
+// -Default=False
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::ResolveHSPSpecificGidL( TUint16 aSupportedFeatures )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveHSPSpecificGidL()" );
+
+ /******************
+ * Audio subblock *
+ ******************/
+ //following capabilities are fixed (because of Headset profile is supported)
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccMonoAudio );
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccIntegratedAudioInput );//i.e. all HSP accessories has microphone
+
+ if ( aSupportedFeatures )
+ {
+ //Remote audio volume control is supported.
+ UpdateSetVolumeLevelCapabilityL( KAccSetVolumeLevelHSP );
+ }
+
+ //KSBAudioSubblock capability group is allready set in CAccSrvConnectionHandler::ResolveGidL()
+
+ /**********************
+ * Bluetooth subblock *
+ **********************/
+ //Set KAccBTHSP capability and KSBBluetoothSubblock capability group
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccBTHSP);
+ TAccPolGenericIDAccessor::SetFeatureAttributeL( iGenericID,
+ KAccPolSBCapabilities,
+ iGenericID.SubblockCaps() |
+ KSBBluetoothSubblock );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveHSPSpecificGidL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::ResolveHFPSpecificGidL
+//
+// Accessory device type is resolved according to this table:
+// Profile supported Accessory type
+// ----------------- --------------
+// both headset and handsfree headset
+// headset headset
+// handsfree carkit
+//
+// Hands-Free Profile 1.0 / supported features bitmap:
+// 000000
+// ^^^^^^
+// ||||||
+// ||||||--Bit 0----- EC and/or NR function
+// |||||---Bit 1----- Call waiting and 3-way calling
+// ||||----Bit 2----- CLI presentation capability
+// |||-----Bit 3----- Voice recognition activation
+// ||------Bit 4----- Remote volume control
+// |-------Bit 5-31-- Unused (available for PAP and other extensibility)
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::ResolveHFPSpecificGidL( TUint16 aSupportedFeatures )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccBTConnectionHandler::ResolveHFPSpecificGidL()" );
+
+ /******************
+ * Audio subblock *
+ ******************/
+ // The default value for supported features of a HF device according to the
+ // HF profile specification is 0.
+ if ( aSupportedFeatures & 0x1 )//Bit 0 -> EC and/or NR function
+ {
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID,
+ KAccAcousticEchoControl,
+ EAPVAccessory,
+ EAPVBool,
+ EFalse );
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID,
+ KAccNoiseReduction,
+ EAPVAccessory,
+ EAPVBool,
+ EFalse );
+ }
+
+
+ if ( aSupportedFeatures & 0x8 )//Bit 3 -> Voice recognition
+ {
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID,
+ KAccBTVoiceRecognition );
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveHFPSpecificGidL - KAccVoiceRecognition supported." );
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveHFPSpecificGidL - KAccVoiceRecognition not supported." );
+ }
+
+
+ if ( aSupportedFeatures & 0x10 )//Bit 4 -> Remote volume control
+ {
+ //Remote audio volume control is supported.
+ UpdateSetVolumeLevelCapabilityL( KAccSetVolumeLevelHFP );
+ }
+
+ //following capabilities are fixed (because of Handsfree profile is supported)
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccMonoAudio );
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccIntegratedAudioInput );//i.e. all HFP accessories has microphone
+
+ //KSBAudioSubblock capability group is allready set in CAccSrvConnectionHandler::ResolveGidL()
+
+ /**********************
+ * Bluetooth subblock *
+ **********************/
+ //Set KAccBTHSP capability and KSBBluetoothSubblock capability group
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccBTHFP );
+ TAccPolGenericIDAccessor::SetFeatureAttributeL( iGenericID,
+ KAccPolSBCapabilities,
+ iGenericID.SubblockCaps() |
+ KSBBluetoothSubblock );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveHFPSpecificGidL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::ResolveAVRCPSpecificGidL
+//
+// AUDIO/VIDEO REMOTE CONTROL PROFILE 1.0 / supported features bitmap:
+// AVRCP
+// Service Record for TG (Accessory is TG)
+// Bit 0 = Category 1
+// Bit 1 = Category 2
+// Bit 2 = Category 3
+// Bit 3 = Category 4
+// Bit 4-15 = Reserved for Future Additions
+//
+// Service Record for CT
+// Bit 0 = Category 1
+// Bit 1 = Category 2
+// Bit 2 = Category 3
+// Bit 3 = Category 4
+// Bit 4-15 = Reserved for Future Additions
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::ResolveAVRCPSpecificGidL(
+ TUint16 /*aSupportedFeatures*/ )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveAVRCPSpecificGidL()" );
+
+ /******************
+ * Audio subblock *
+ ******************/
+ //AVRCP doesn't support remote audio volume control.
+
+ /**********************
+ * Bluetooth subblock *
+ **********************/
+ //Set KAccBTAVRCP capability and KSBBluetoothSubblock capability group
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccBTAVRCP );
+ TAccPolGenericIDAccessor::SetFeatureAttributeL( iGenericID,
+ KAccPolSBCapabilities,
+ iGenericID.SubblockCaps() |
+ KSBBluetoothSubblock );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveAVRCPSpecificGidL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::ResolveA2DPSpecificGidL
+//
+// ADVANCED AUDIO DISTRIBUTION PROFILE SPECIFICATION 1.0 / supported features bitmap:
+// A2DP
+//
+// Service Record for Sink (Accessory is sink)
+// Bit 0 = Headphone
+// Bit 1 = Speaker
+// Bit 2 = Recorder
+// Bit 3 = Amplifier
+// Bit 4-15 = Reserved for Future Additions
+//
+// Service Record for Source
+// Bit 0 = Player
+// Bit 1 = Microphone
+// Bit 2 = Tuner
+// Bit 3 = Mixer
+// Bit 4-15 = Reserved for Future Additions
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::ResolveA2DPSpecificGidL( TUint16 /*aSupportedFeatures*/ )
+ {
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveA2DPSpecificGidL()" );
+
+ /******************
+ * Audio subblock *
+ ******************/
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccStereoAudio );
+ //KSBAudioSubblock capability group is allready set in CAccSrvConnectionHandler::ResolveGidL()
+
+ /**********************
+ * Bluetooth subblock *
+ **********************/
+ //Set KAccBTA2DP capability and KSBBluetoothSubblock capability group
+ iModel->CapabilityStorage().SetCapabilityL( iGenericID, KAccBTA2DP );
+ TAccPolGenericIDAccessor::SetFeatureAttributeL( iGenericID,
+ KAccPolSBCapabilities,
+ iGenericID.SubblockCaps() |
+ KSBBluetoothSubblock );
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::ResolveA2DPSpecificGidL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::UpdateSetVolumeLevelCapabilityL
+//
+// Read the existing KAccSetVolumeLevel capability value and update it
+// according to the aCapability parameter.
+// -----------------------------------------------------------------------------
+//
+void CAccSrvConnectionHandler::UpdateSetVolumeLevelCapabilityL( TInt32 aCapability )
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::UpdateSetVolumeLevelCapabilityL(%d)", aCapability );
+
+ CCapValue* capValue = iModel->CapabilityStorage().GetCapability(
+ iGenericID, KAccSetVolumeLevel );
+
+ if ( capValue )
+ {
+ TInt32 currentValue( 0 );
+ if( KErrNone == capValue->ValueInt( currentValue ) )
+ {
+ currentValue = currentValue | aCapability;
+ iModel->CapabilityStorage().SetCapabilityL(
+ iGenericID,
+ KAccSetVolumeLevel,
+ EAPVPolicy,
+ EAPVInt,
+ currentValue );
+ }
+ }
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::UpdateSetVolumeLevelCapabilityL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::RunError
+//
+// Called if RunL Leaves
+// -----------------------------------------------------------------------------
+//
+TInt CAccSrvConnectionHandler::RunError( TInt aError )
+ {
+ COM_TRACE_1( "[AccFW:AccServer] CAccSrvConnectionHandler::RunError(%d)", aError );
+
+ aError = KErrNone;// Avoid Panic in CActiveScheduler
+
+ COM_TRACE_( "[AccFW:AccServer] CAccSrvConnectionHandler::RunError - return KErrNone" );
+
+ return aError;
+ }
+
+// -----------------------------------------------------------------------------
+// CAccSrvConnectionHandler::CompleteMessageL (From MQueueObserver)
+// -----------------------------------------------------------------------------
+//
+TBool CAccSrvConnectionHandler::CompleteMessageL( TMsgID /*aMsgID*/,
+ TInt /*aErrorCode*/,
+ TInt /*aUniqueID*/ )
+ {
+ //Not used, must define it here because pure virtual in base class (MQueueObserver)
+ TRACE_ASSERT_ALWAYS;
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+//CAccSrvConnectionHandler::CompleteProcessCommandL
+// -----------------------------------------------------------------------------
+//
+TBool CAccSrvConnectionHandler::CompleteProcessCommandL(
+ TProcessCmdId /*aCmdn*/,
+ TInt /*aTrId*/,
+ TASYCommandParamRecord& /*aASYCommandParamRecord*/,
+ TPtr8* /*aPtrBuf*/ )
+ {
+ //Not used, must define it here because pure virtual in base class (MQueueObserver)
+ TRACE_ASSERT_ALWAYS;
+ return EFalse;
+ }
+// End of File