diff -r 000000000000 -r 4e1aa6a622a0 accessoryservices/accessoryserver/src/Server/AccSrvSubAudioControl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/accessoryservices/accessoryserver/src/Server/AccSrvSubAudioControl.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,601 @@ +/* +* Copyright (c) 2002-2008 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: Server-side sub-session of Accessory Audio Control +* +*/ + + + +// INCLUDE FILES +#include "AccSrvSubAudioControl.h" +#include "acc_debug.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::CAccSrvSubAudioControl +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CAccSrvSubAudioControl::CAccSrvSubAudioControl( + CASYProxyAPI* aProxy, + CAccSrvConnectionController* aConnectionController, + CAccSrvServerModel* aServerModel, + TUint aCallerThreadID ) + : CAccSrvSubControl ( aProxy, aConnectionController, aServerModel ), + iCallerThreadID( aCallerThreadID ) + { + } +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::ConstructL() + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::ConstructL()" ); + + CAccSrvSubControl::ConstructL(); + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::ConstructL() - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// + +CAccSrvSubAudioControl* CAccSrvSubAudioControl::NewL( + CASYProxyAPI* aProxy, + CAccSrvConnectionController* aConnectionController, + CAccSrvServerModel* aServerModel, + TUint aCallerThreadID ) + { + if ( !aProxy ) + { + User::Leave( KErrArgument ); + } + + CAccSrvSubAudioControl* self = new (ELeave) CAccSrvSubAudioControl( aProxy, + aConnectionController, + aServerModel, + aCallerThreadID ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// Destructor +CAccSrvSubAudioControl::~CAccSrvSubAudioControl() + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::~CAccSrvSubAudioControl()" ); + + RMessage2 dummy; + + CAccSrvSubAudioControl::CancelAccessoryAudioLinkOpen( dummy );//For iAccessoryAudioLinkOpenMsg + CAccSrvSubAudioControl::CancelAccessoryAudioLinkClose( dummy );//For iAccessoryAudioLinkCloseMsg + CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkOpened( dummy );//For iNotifyAccessoryAudioLinkOpenedMsg + CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkClosed( dummy );//For iNotifyAccessoryAudioLinkClosedMsg + + if ( iServerModel ) + { + iServerModel->SetAudioLinkOpenCancelled( EFalse ); + iServerModel->SetAudioLinkCloseCancelled( EFalse ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::~CAccSrvSubAudioControl - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::NotifyAccessoryAudioLinkOpened +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::NotifyAccessoryAudioLinkOpened( const RMessage2& aMessage ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::NotifyAccessoryAudioLinkOpened()" ); + + iConnectionController->NotificationQueue().RegisterControlMessage( EAccessoryAudioLinkOpened, + this ); + + iNotifyAccessoryAudioLinkOpenedMsg = aMessage;//Store RMessage2 for future completion + + // If message is null, there is no pending request and no filtering needed + if ( !iAccessoryAudioLinkOpenMsg.IsNull() ) + { + //NotifyAccessoryAudioLinkOpened() notification is filtered + //for AccessoryAudioLinkOpen() caller thread. + //In this case NotifyAccessoryAudioLinkOpened() notification + //is ordered after AccessoryAudioLinkOpen() is sent. + iConnectionController->ServerModel().SetMsgThreadIDFilter( iCallerThreadID, + EAccessoryAudioLinkOpened ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::NotifyAccessoryAudioLinkOpened - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::NotifyAccessoryAudioLinkClosed +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::NotifyAccessoryAudioLinkClosed( const RMessage2& aMessage ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::NotifyAccessoryAudioLinkClosed()" ); + + iConnectionController->NotificationQueue().RegisterControlMessage( EAccessoryAudioLinkClosed, + this ); + iNotifyAccessoryAudioLinkClosedMsg = aMessage;//Store RMessage2 for future completion + + // If message is null, there is no pending request and no filtering needed + if ( !iAccessoryAudioLinkCloseMsg.IsNull() ) + { + //NotifyAccessoryAudioLinkClosed() notification is filtered + //for AccessoryAudioLinkClose() caller thread. + //In this case NotifyAccessoryAudioLinkClosed() notification + //is ordered after AccessoryAudioLinkClose() is sent. + iConnectionController->ServerModel().SetMsgThreadIDFilter( iCallerThreadID, + EAccessoryAudioLinkClosed ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::NotifyAccessoryAudioLinkClosed - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::AccessoryAudioLinkOpenL +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::AccessoryAudioLinkOpenL( const RMessage2& aMessage ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::AccessoryAudioLinkOpenL()" ); + + TAccPolGenericID genericID; + TAccSrvGenericIDPckg genericIDPckg( genericID ); + TAccAudioType audioType( EAccMonoAudio ); // Initialization value + TAccSrvAudioTypePckg audioTypePckg( audioType ); + + aMessage.ReadL( KAccServParamPosFirst, genericIDPckg ); + aMessage.ReadL( KAccServParamPosSecond, audioTypePckg ); + + //Precondition + iServerModel->IsConnectedL( genericID );//Leaves with KErrArgument if the accessory is not connected + + iServerModel->SetAudioType( audioType );//Notice, This works for single client (Server model can store only one value) + + iConnectionController->NotificationQueue().RegisterControlMessage( EAccessoryAudioLinkOpen, + this ); + + TInt bluetoothAudioLinkOpenReqs( iConnectionController->NotificationQueue().ControlMessagesWaiting( EBluetoothAudioLinkOpenReq ) ); + if ( bluetoothAudioLinkOpenReqs > 0 ) + { + //Send bluetooth audio link notification now. + iServerModel->SetBluetoothAudioLinkOpenReqPostponed( EFalse ); + iConnectionController->NotificationQueue().CompleteControlMessageL( EBluetoothAudioLinkOpenReq, + KErrNone, + genericID.UniqueID() ); + } + else + { + //There was not any bluetooth audio link notification waiting at the moment. + //Bluetooth audio link will be opened immediately when bluetooth audio link notification is set. + //See EAccSrvNotifyBluetoothAudioLinkOpenReq handling from the control. + iServerModel->SetBluetoothAudioLinkOpenReqPostponed( ETrue ); + } + + iAccessoryAudioLinkOpenMsg = aMessage;//Store RMessage2 for future completion + + // If message is null, there is no pending request and no filtering needed + if ( !iNotifyAccessoryAudioLinkOpenedMsg.IsNull() ) + { + //NotifyAccessoryAudioLinkOpened notification() is filtered + //for AccessoryAudioLinkOpen() caller thread + iConnectionController->ServerModel().SetMsgThreadIDFilter( iCallerThreadID, + EAccessoryAudioLinkOpened ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::AccessoryAudioLinkOpenL - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::AccessoryAudioLinkCloseL +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::AccessoryAudioLinkCloseL( const RMessage2& aMessage ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubBaseConnection::AccessoryAudioLinkCloseL()" ); + + TAccPolGenericID genericID; + TAccSrvGenericIDPckg genericIDPckg( genericID ); + TAccAudioType audioType( EAccMonoAudio ); // Initialization value + TAccSrvAudioTypePckg audioTypePckg( audioType ); + + aMessage.ReadL( KAccServParamPosFirst, genericIDPckg ); + aMessage.ReadL( KAccServParamPosSecond, audioTypePckg ); + + //Precondition + iServerModel->IsConnectedL( genericID );//Leaves with KErrArgument if the accessory is not connected + + iServerModel->SetAudioType( audioType );//Notice, This works for single client (Server model can store only one value) + + iConnectionController->NotificationQueue().RegisterControlMessage( + EAccessoryAudioLinkClose, + this ); + + iConnectionController->NotificationQueue().CompleteControlMessageL( + EBluetoothAudioLinkCloseReq, + KErrNone, + genericID.UniqueID() ); + + iAccessoryAudioLinkCloseMsg = aMessage;//Store RMessage2 for future completion + + // If message is null, there is no pending request and no filtering needed + if ( !iNotifyAccessoryAudioLinkClosedMsg.IsNull() ) + { + //NotifyAccessoryAudioLinkClosed() notification is filtered + //for AccessoryAudioLinkClose() caller thread + iConnectionController->ServerModel().SetMsgThreadIDFilter( + iCallerThreadID, + EAccessoryAudioLinkClosed ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubBaseConnection::AccessoryAudioLinkCloseL - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::AudioRoutingStatusNotifyL +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::AudioRoutingStatusNotifyL( const RMessage2& aMessage ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::AudioRoutingStatusNotifyL()" ); + + TAccPolGenericID genericID; + TPckgBuf activeAudioPckgBuf; + TAccSrvGenericIDPckg genericIDPckg( genericID ); + + aMessage.ReadL( KAccServParamPosFirst, activeAudioPckgBuf ); + aMessage.ReadL( KAccServParamPosSecond, genericIDPckg ); + + iConnectionController->HandleAccessoryModeChangedL( genericID.UniqueID(), + activeAudioPckgBuf() ); + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::AudioRoutingStatusNotifyL - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::CancelAccessoryAudioLinkOpen +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::CancelAccessoryAudioLinkOpen( + const RMessage2& /*aMessage*/ ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::CancelAccessoryAudioLinkOpen()" ); + + // If message is null, there is nothing to cancel + if ( !iAccessoryAudioLinkOpenMsg.IsNull() ) + { + iConnectionController->NotificationQueue().CancelControlMessage( + EAccessoryAudioLinkOpen, + this ); + + //AccessoryAudioLinkOpen() request is cancelled + //-> NO filtering needed for NotifyAccessoryAudioLinkOpened() + iConnectionController->ServerModel().FindAndDeleteMsgThreadIDFilter( + iCallerThreadID, + EAccessoryAudioLinkOpened ); + + Write( iAccessoryAudioLinkOpenMsg, KAccSrvAccessoryAudioLinkOpenBit ); + iAccessoryAudioLinkOpenMsg.Complete( KErrCancel ); + iServerModel->SetAudioLinkOpenCancelled( ETrue ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::CancelAccessoryAudioLinkOpen - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::CancelAccessoryAudioLinkClose +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::CancelAccessoryAudioLinkClose( + const RMessage2& /*aMessage*/ ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::CancelAccessoryAudioLinkClose()" ); + + // If message is null, there is nothing to cancel + if ( !iAccessoryAudioLinkCloseMsg.IsNull() ) + { + iConnectionController->NotificationQueue().CancelControlMessage( EAccessoryAudioLinkClose, + this ); + + //AccessoryAudioLinkClose() request is cancelled + //-> NO filtering needed for NotifyAccessoryAudioLinkClosed() + iConnectionController->ServerModel().FindAndDeleteMsgThreadIDFilter( + iCallerThreadID, EAccessoryAudioLinkClosed ); + + Write( iAccessoryAudioLinkCloseMsg, KAccSrvAccessoryAudioLinkCloseBit ); + iAccessoryAudioLinkCloseMsg.Complete( KErrCancel ); + iServerModel->SetAudioLinkCloseCancelled( ETrue ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::CancelAccessoryAudioLinkClose - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkOpened +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkOpened( + const RMessage2& /*aMessage*/ ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkOpened()" ); + + // If message is null, there is nothing to cancel + if( !iNotifyAccessoryAudioLinkOpenedMsg.IsNull() ) + { + iConnectionController->NotificationQueue().CancelControlMessage( + EAccessoryAudioLinkOpened, this ); + + //NotifyAccessoryAudioLinkOpened() notification order is cancelled + //-> NO filtering needed for that message + iConnectionController->ServerModel().FindAndDeleteMsgThreadIDFilter( + iCallerThreadID, EAccessoryAudioLinkOpened ); + + Write( iNotifyAccessoryAudioLinkOpenedMsg, KAccSrvNotifyAccessoryAudioLinkOpenedBit ); + iNotifyAccessoryAudioLinkOpenedMsg.Complete( KErrCancel ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkOpened - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkClosed +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkClosed( + const RMessage2& /*aMessage*/ ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkClosed()" ); + + // If message is null, there is nothing to cancel + if( !iNotifyAccessoryAudioLinkClosedMsg.IsNull() ) + { + iConnectionController->NotificationQueue().CancelControlMessage( + EAccessoryAudioLinkClosed, this ); + + //NotifyAccessoryAudioLinkClosed() notification order is cancelled + //-> NO filtering needed for that message + iConnectionController->ServerModel().FindAndDeleteMsgThreadIDFilter( + iCallerThreadID, EAccessoryAudioLinkClosed ); + + Write( iNotifyAccessoryAudioLinkClosedMsg, KAccSrvNotifyAccessoryAudioLinkClosedBit ); + iNotifyAccessoryAudioLinkClosedMsg.Complete( KErrCancel ); + } + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::CancelNotifyAccessoryAudioLinkClosed - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::DispatchMessageL +// Handles client request. If request is not handled here, it is passed to +// parent class for handling +// ----------------------------------------------------------------------------- +// +void CAccSrvSubAudioControl::DispatchMessageL( const RMessage2& aMessage ) + { + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::DispatchMessageL()" ); + + TInt function = aMessage.Function(); + + switch ( function ) + { + case EAccSrvNotifyAccessoryAudioLinkOpened: + { + NotifyAccessoryAudioLinkOpened( aMessage ); + break; + } + case EAccSrvNotifyAccessoryAudioLinkClosed: + { + NotifyAccessoryAudioLinkClosed( aMessage ); + break; + } + case EAccSrvAccessoryAudioLinkOpen: + { + AccessoryAudioLinkOpenL( aMessage ); + break; + } + case EAccSrvAccessoryAudioLinkClose: + { + AccessoryAudioLinkCloseL( aMessage ); + break; + } + case EAccSrvAudioRoutingStatusNotify: + { + AudioRoutingStatusNotifyL( aMessage ); + break; + } + case EAccSrvCancelAccessoryAudioLinkOpen: + { + CancelAccessoryAudioLinkOpen( aMessage ); + break; + } + case EAccSrvCancelAccessoryAudioLinkClose: + { + CancelAccessoryAudioLinkClose( aMessage ); + break; + } + case EAccSrvCancelNotifyAccessoryAudioLinkOpened: + { + CancelNotifyAccessoryAudioLinkOpened( aMessage ); + break; + } + case EAccSrvCancelNotifyAccessoryAudioLinkClosed: + { + CancelNotifyAccessoryAudioLinkClosed( aMessage ); + break; + } + default: + { + // Not handled here, pass to base class + CAccSrvSubControl::DispatchMessageL( aMessage ); + break; + } + } // switch( function ) + + COM_TRACE_( "[AccFW:AccServer] CAccSrvSubAudioControl::DispatchMessageL - return void" ); + } + +// ----------------------------------------------------------------------------- +// CAccSrvSubAudioControl::CompleteMessageL +// ----------------------------------------------------------------------------- +// +TBool CAccSrvSubAudioControl::CompleteMessageL( TMsgID aMsgID, + TInt aErrorCode, + TInt aUniqueID ) + { + COM_TRACE_3( "[AccFW:AccServer] CAccSrvSubAudioControl::CompleteMessageL(MsgID=%d Err=%d UniqueID=%d)", aMsgID, aErrorCode, aUniqueID ); + + TBool messageConsumption( EFalse );// Return value tells should this subsession be removed from the queue + + switch ( aMsgID ) + { + case EAccessoryAudioLinkOpen: + { + if( KErrNone != aErrorCode ) + { + //Release NotifyAccessoryAudioLinkOpened() filtering in error case. + //BluetoothAudioLinkOpenedNotify() message is never sent in error case + iConnectionController->ServerModel().FindAndDeleteMsgThreadIDFilter( + iCallerThreadID, + EAccessoryAudioLinkOpened ); + } + //Complete outstanding AccessoryAudioLinkOpen request + Write( iAccessoryAudioLinkOpenMsg, KAccSrvAccessoryAudioLinkOpenBit ); + iAccessoryAudioLinkOpenMsg.Complete( aErrorCode ); + messageConsumption = ETrue; + } + break; + + case EAccessoryAudioLinkClose: + { + if( KErrNone != aErrorCode ) + { + //Release NotifyAccessoryAudioLinkClosed() filtering in error case. + //BluetoothAudioLinkClosedNotify() message is never sent in error case + iConnectionController->ServerModel().FindAndDeleteMsgThreadIDFilter( + iCallerThreadID, + EAccessoryAudioLinkClosed ); + } + //Complete outstanding AccessoryAudioLinkClose request + Write( iAccessoryAudioLinkCloseMsg, KAccSrvAccessoryAudioLinkCloseBit ); + iAccessoryAudioLinkCloseMsg.Complete( aErrorCode ); + messageConsumption = ETrue; + } + break; + + case EAccessoryAudioLinkOpened: + { + // Nothing is done here if filter is set, i.e. NotifyAccessoryAudioLinkOpened() + // notification was ordered from the same thread that AccessoryAudioLinkOpen() was called + if ( !iConnectionController->ServerModel().FindAndDeleteMsgThreadIDFilter( + iCallerThreadID, + EAccessoryAudioLinkOpened ) ) + { + //Complete outstanding NotifyAccessoryAudioLinkOpened request + //Notice, This works for single client (Server model can store only one value) + TAccAudioType audioType( iConnectionController->ServerModel().AudioType() ); + TAccPolGenericID genericID; + iConnectionController->ServerModel().FindWithUniqueIDL( aUniqueID, genericID ); + TAccSrvGenericIDPckg genericIDPckg( genericID ); + TAccSrvAudioTypePckg audioTypePckg( audioType ); + + COM_TRACE_1( "[AccFW:AccServer] CAccSrvSubAudioControl::CompleteMessageL - Opened AudioType=%d)", audioType ); + + iNotifyAccessoryAudioLinkOpenedMsg.WriteL( KAccServParamPosFirst, genericIDPckg ); + iNotifyAccessoryAudioLinkOpenedMsg.WriteL( KAccServParamPosSecond, audioTypePckg ); + Write( iNotifyAccessoryAudioLinkOpenedMsg, + KAccSrvNotifyAccessoryAudioLinkOpenedBit ); + + iNotifyAccessoryAudioLinkOpenedMsg.Complete( aErrorCode ); + messageConsumption = ETrue; + } + } + break; + + case EAccessoryAudioLinkClosed: + { + // Nothing is done here if filter is set, i.e. NotifyAccessoryAudioLinkClosed() + // notification was ordered from the same thread that AccessoryAudioLinkClose() was called + if ( !iConnectionController->ServerModel().FindAndDeleteMsgThreadIDFilter( + iCallerThreadID, + EAccessoryAudioLinkClosed ) ) + { + //Complete outstanding NotifyAccessoryAudioLinkClosed request + //Notice, This works for single client (Server model can store only one value) + TAccAudioType audioType( iConnectionController->ServerModel().AudioType() ); + TAccPolGenericID genericID; + iConnectionController->ServerModel().FindWithUniqueIDL( aUniqueID, genericID ); + TAccSrvGenericIDPckg genericIDPckg( genericID ); + TAccSrvAudioTypePckg audioTypePckg( audioType ); + + COM_TRACE_1( "[AccFW:AccServer] CAccSrvSubAudioControl::CompleteMessageL - Closed AudioType=%d)", audioType ); + + iNotifyAccessoryAudioLinkClosedMsg.WriteL( KAccServParamPosFirst, genericIDPckg ); + iNotifyAccessoryAudioLinkClosedMsg.WriteL( KAccServParamPosSecond, audioTypePckg ); + Write( iNotifyAccessoryAudioLinkClosedMsg, + KAccSrvNotifyAccessoryAudioLinkClosedBit ); + + iNotifyAccessoryAudioLinkClosedMsg.Complete( aErrorCode ); + messageConsumption = ETrue; + } + } + break; + + default: + { + //Pass handling to parent class + messageConsumption = CAccSrvSubControl::CompleteMessageL( aMsgID, + aErrorCode, + aUniqueID ); + } + } + + COM_TRACE_1( "[AccFW:AccServer] CAccSrvSubAudioControl::CompleteMessageL - return 0x%x", messageConsumption ); + + return messageConsumption; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File