devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp
changeset 0 40261b775718
child 8 bc06d8566074
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,2253 @@
+// Copyright (c) 2006-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:
+//
+
+#include <s32mem.h>
+#include "mmfaudioclientserver.h"
+#include "mmfaudioserver.h"
+#include "mmfdevsoundserver.h"
+#include "mmfdevsoundsession.h"
+#include <mmf/plugin/mmfdevsoundcustominterface.hrh>
+#include <mm/mmpluginutils.h>
+#ifdef _DEBUG
+#include "e32debug.h"
+
+#define SYMBIAN_DEBPRN0(str)                RDebug::Print(str, this)
+#define SYMBIAN_DEBPRN1(str, val1)          RDebug::Print(str, this, val1)
+#define SYMBIAN_DEBPRN2(str, val1, val2)    RDebug::Print(str, this, val1, val2)
+#else
+#define SYMBIAN_DEBPRN0(str)
+#define SYMBIAN_DEBPRN1(str, val1)
+#define SYMBIAN_DEBPRN2(str, val1, val2)
+#endif //_DEBUG
+
+//Assume that we can have two user request and one callback request
+//at the same time (maximum).
+const TInt KMaxQueueRequest = 3;
+
+//	MEMBER FUNCTIONS 
+
+TMMFDevSoundRequest::TMMFDevSoundRequest() 
+	: iMessageCompleted(EFalse), 
+	iRequestType(EUndefinedType),
+	iCallBackPF(KCallbackNone)
+	{
+	}
+
+TMMFDevSoundRequest::TMMFDevSoundRequest(TInt aIsCallBack)
+	: iMessageCompleted(EFalse), 
+	iRequestType(ECallBackType),
+	iCallBackPF(aIsCallBack)
+	{
+	}
+
+TMMFDevSoundRequest::TMMFDevSoundRequest(const TMMFDevSoundRequest& aRequest)
+	: iMessageCompleted(EFalse), 
+	iMessage(aRequest.iMessage),
+	iCallBackPF(aRequest.iCallBackPF)
+	{
+	iRequestType = ResolveType();
+	}
+
+TBool TMMFDevSoundRequest::operator==(const TMMFDevSoundRequest& aRequest) const
+	{
+	TBool retval = EFalse;
+	if ( aRequest.Function() == Function() )
+		{
+		retval = ETrue;
+		}
+	else
+		{
+		retval = EFalse;
+		}
+	return retval;
+	}
+
+const RMmfIpcMessage& TMMFDevSoundRequest::Message() 
+	{ 
+	return iMessage; 
+	}
+
+void TMMFDevSoundRequest::SetMessage(const RMmfIpcMessage& aMessage) 
+	{
+	iMessageCompleted = EFalse;
+	iMessage = aMessage;
+	iRequestType = ResolveType();
+	}
+	
+void TMMFDevSoundRequest::SetMessageCallback() 
+	{
+	iMessageCompleted = EFalse;
+	iRequestType = ECallBackType;
+	}	
+
+TInt TMMFDevSoundRequest::IsCallBack() const
+	{
+	return iCallBackPF;	
+	}
+
+TMMFDevSoundRequest::TA3FDevSoundRequestType TMMFDevSoundRequest::ResolveType()
+	{
+	TA3FDevSoundRequestType type = EUndefinedType;
+	switch(iMessage.Function())
+		{
+		case EMMFDevSoundProxyInitialize1:
+		case EMMFDevSoundProxyInitialize2:
+		case EMMFDevSoundProxyInitialize4:
+		case EMMFDevSoundProxyPlayInit:
+		case EMMFDevSoundProxyRecordInit:
+		case EMMFDevSoundProxyPlayTone:
+		case EMMFDevSoundProxyPlayDualTone:
+		case EMMFDevSoundProxyPlayDTMFString:
+		case EMMFDevSoundProxyPlayToneSequence:
+		case EMMFDevSoundProxyPlayFixedSequence:
+			type = EAction_PseudoAsynchronous;
+			break;
+
+		case EMMFDevSoundProxyStop:
+		case EMMFDevSoundProxyPause:
+		case EMMFDevSoundProxyClose:
+		case EMMFDevSoundProxyCancelInitialize:
+		case EMMFDevSoundProxyResume:
+		case EMMFDevSoundProxyEmptyBuffers:
+			type = EAction_Asynchronous;
+			break;
+
+		case EMMFDevSoundProxySetConfig:
+		case EMMFDevSoundProxyPostOpen: // Although this is not a configure operation technically, it has same calling pattern.
+		case EMMFDevSoundProxySetVolume:
+		case EMMFDevSoundProxySetGain:
+		case EMMFDevSoundProxySetPlayBalance:
+		case EMMFDevSoundProxySetRecordBalance:
+		case EMMFDevSoundProxySetVolumeRamp:
+		case EMMFDevSoundProxySetPrioritySettings:
+			type = EConfigure_Asynchronous;
+			break;
+			
+		case EMMFDevSoundProxySetDTMFLengths:
+		case EMMFDevSoundProxySetToneRepeats:
+			type = EConfigure_Synchronous;	
+			break;
+		case EMMFDevSoundProxyCapabilities:
+			type = EQuery_Asynchronous;
+			break;
+		case EMMFDevSoundProxyMaxVolume:
+		case EMMFDevSoundProxyMaxGain:
+		case EMMFDevSoundProxyConfig:
+		case EMMFDevSoundProxyVolume:
+		case EMMFDevSoundProxyGain:
+		case EMMFDevSoundProxyPlayBalance:
+		case EMMFDevSoundProxyRecordBalance:
+		case EMMFDevSoundProxyGetSupportedInputDataTypes:
+		case EMMFDevSoundProxyGetSupportedOutputDataTypes:
+		case EMMFDevSoundProxyFixedSequenceName:
+		case EMMFDevSoundProxyFixedSequenceCount:
+		case EMMFDevSoundProxySamplesRecorded:
+		case EMMFDevSoundProxySamplesPlayed:
+		case EMMFDevSoundProxyCopyFourCCArrayData:
+		case EMMFDevSoundProxyGetTimePlayed:
+		case EMMFDevSoundProxyIsResumeSupported:
+			type = EQuery_Synchronous;
+			break;
+		
+		case EMMFDevSoundProxyBTBFData:
+		case EMMFDevSoundProxyBTBEData:
+		case EMMFDevSoundProxyPlayData:
+		case EMMFDevSoundProxyRecordData:
+			type = EBufferExchangeRelated;
+			break;
+
+		// Custom Interfaces
+		case EMMFDevSoundProxySyncCustomCommand:
+		case EMMFDevSoundProxySyncCustomCommandResult:
+		case EMMFDevSoundProxyAsyncCustomCommand:
+		case EMMFDevSoundProxyAsyncCustomCommandResult:
+		case EMMFDevSoundProxyCustomInterface:
+			type = ECustomInterfacesRelated;
+			break;
+		case RMessage2::EDisConnect:
+			type = ESessionEvents;
+			break;
+		default:
+			break;
+		}
+	return type;
+	}
+
+
+void TMMFDevSoundRequest::Complete(TInt aError)	
+	{
+	if(!iMessageCompleted && iRequestType != EUndefinedType && iRequestType != ECallBackType)	
+		{
+		iMessage.Complete(aError);
+		iMessageCompleted = ETrue;
+		iRequestType = EUndefinedType;
+		}
+	}
+
+TInt TMMFDevSoundRequest::Function() const 
+	{
+	return iMessage.Function(); 
+	}
+
+TMMFDevSoundRequest::TA3FDevSoundRequestType TMMFDevSoundRequest::Type() const
+	{
+	return iRequestType;
+	}
+
+
+// 
+// CMMFDevSoundSession::CreateL
+// Creates a new object
+// 
+void CMMFDevSoundSession::CreateL(const CMmfIpcServer& aServer)
+	{
+	CMmfIpcSession::CreateL(aServer);
+	CMMFDevSoundServer& server =
+	const_cast<CMMFDevSoundServer&>(
+			static_cast<const CMMFDevSoundServer&>(aServer));
+	server.IncrementSessionId();
+	iDevSoundSessionId = server.DevSoundSessionId();
+	}
+
+//
+// CMMFDevSoundSession::ServiceL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::ServiceL(const RMmfIpcMessage& aMessage)
+	{
+	SYMBIAN_DEBPRN2(_L("\nCMMFDevSoundSession[0x%x] NEW REQUEST %02x while pending=%d"), aMessage.Function(), iOperationCompletePending);
+	if( iOperationCompletePending || iAsyncQueueStart->IsActive())
+		{
+		// if not possible to service now, then queue request
+		EnqueueRequest(aMessage);
+		}
+	else
+		{
+		// If there is no oustanding operation service inmediately
+		DoServiceRequestL(aMessage);
+		}
+	}
+	
+//
+// CMMFDevSoundSession::DoServiceL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DoServiceRequestL(const RMmfIpcMessage& aMessage)
+	{
+	iAsyncQueueStart->Cancel(); // just in case.
+	TMMFMessageDestinationPckg destinationPckg;
+	MmfMessageUtil::ReadL(aMessage, 0, destinationPckg);
+	if ((destinationPckg().DestinationHandle() == KMMFObjectHandleDevSound) &&
+	    (destinationPckg().InterfaceId() == KUidInterfaceMMFDevSound))
+		{
+		TBool complete = EFalse;
+		switch(aMessage.Function())
+			{
+			case EMMFDevSoundProxyPostOpen:
+				complete = DoPostOpenL(aMessage);
+				break;
+			case EMMFDevSoundProxyInitialize1:
+				complete = DoInitialize1L(aMessage);
+				break;
+			case EMMFDevSoundProxyInitialize2:
+				complete = DoInitialize2L(aMessage);
+				break;
+			case EMMFDevSoundProxyInitialize4:
+				complete = DoInitialize4L(aMessage);
+				break;
+			case EMMFDevSoundProxyCapabilities:
+				complete = DoCapabilitiesL(aMessage);
+				break;
+			case EMMFDevSoundProxyConfig:
+				complete = DoConfigL(aMessage);
+				break;
+			case EMMFDevSoundProxySetConfig:
+				complete = DoSetConfigL(aMessage);
+				break;
+			case EMMFDevSoundProxyMaxVolume:
+				complete = DoMaxVolumeL(aMessage);
+				break;
+			case EMMFDevSoundProxyVolume:
+				complete = DoVolumeL(aMessage);
+				break;
+			case EMMFDevSoundProxySetVolume:
+				complete = DoSetVolumeL(aMessage);
+				break;
+			case EMMFDevSoundProxyMaxGain:
+				complete = DoMaxGainL(aMessage);
+				break;
+			case EMMFDevSoundProxyGain:
+				complete = DoGainL(aMessage);
+				break;
+			case EMMFDevSoundProxySetGain:
+				complete = DoSetGainL(aMessage);
+				break;
+			case EMMFDevSoundProxyPlayBalance:
+				complete = DoGetPlayBalanceL(aMessage);
+				break;
+			case EMMFDevSoundProxySetPlayBalance:
+				complete = DoSetPlayBalanceL(aMessage);
+				break;
+			case EMMFDevSoundProxyRecordBalance:
+				complete = DoGetRecordBalanceL(aMessage);
+				break;
+			case EMMFDevSoundProxySetRecordBalance:
+				complete = DoSetRecordBalanceL(aMessage);
+				break;
+			case EMMFDevSoundProxyBTBFData:
+				complete = DoBufferToBeFilledDataL(aMessage);
+				break;
+			case EMMFDevSoundProxyBTBEData:
+				complete = DoBufferToBeEmptiedDataL(aMessage);
+				break;
+			case EMMFDevSoundProxyPlayInit:
+				complete = DoPlayInitL(aMessage);
+				break;
+			case EMMFDevSoundProxyRecordInit:
+				complete = DoRecordInitL(aMessage);
+				break;
+			case EMMFDevSoundProxyPlayData:
+				complete = DoPlayDataL(aMessage);
+				break;
+			case EMMFDevSoundProxyRecordData:
+				complete = DoRecordDataL(aMessage);
+				break;
+			case EMMFDevSoundProxyStop:
+				complete = DoStopL(aMessage);
+				break;
+			case EMMFDevSoundProxyPause:
+				complete = DoPauseL(aMessage);
+				break;
+			case EMMFDevSoundProxyPlayTone:
+				complete = DoPlayToneL(aMessage);
+				break;
+			case EMMFDevSoundProxyPlayDualTone:
+				complete = DoPlayDualToneL(aMessage);
+				break;
+			case EMMFDevSoundProxyPlayDTMFString:
+				complete = DoPlayDTMFStringL(aMessage);
+				break;
+			case EMMFDevSoundProxyPlayToneSequence:
+				complete = DoPlayToneSequenceL(aMessage);
+				break;
+			case EMMFDevSoundProxyPlayFixedSequence:
+				complete = DoPlayFixedSequenceL(aMessage);
+				break;
+			case EMMFDevSoundProxySetDTMFLengths:
+				complete = DoSetDTMFLengthsL(aMessage);
+				break;
+			case EMMFDevSoundProxySetVolumeRamp:
+				complete = DoSetVolumeRampL(aMessage);
+				break;
+			case EMMFDevSoundProxyGetSupportedInputDataTypes:
+				complete = DoGetSupportedInputDataTypesL(aMessage);
+				break;
+			case EMMFDevSoundProxyGetSupportedOutputDataTypes:
+				complete = DoGetSupportedOutputDataTypesL(aMessage);
+				break;
+			case EMMFDevSoundProxyCopyFourCCArrayData:
+				complete = DoCopyFourCCArrayDataL(aMessage);
+				break;
+			case EMMFDevSoundProxySamplesRecorded:
+				complete = DoSamplesRecordedL(aMessage);
+				break;
+			case EMMFDevSoundProxySamplesPlayed:
+				complete = DoSamplesPlayedL(aMessage);
+				break;
+			case EMMFDevSoundProxySetToneRepeats:
+				complete = DoSetToneRepeatsL(aMessage);
+				break;
+			case EMMFDevSoundProxySetPrioritySettings:
+				complete = DoSetPrioritySettingsL(aMessage);
+				break;
+			case EMMFDevSoundProxyFixedSequenceCount:
+				complete = DoFixedSequenceCountL(aMessage);
+				break;
+			case EMMFDevSoundProxyCancelInitialize:
+				complete = DoCancelInitializeL(aMessage);
+				break;
+			case EMMFDevSoundProxyEmptyBuffers:
+				complete = DoEmptyBuffersL(aMessage);
+				break;
+			case EMMFDevSoundProxyGetTimePlayed:
+				complete = DoGetTimePlayedL(aMessage);
+				break;
+			case EMMFDevSoundProxyIsResumeSupported:
+				complete = DoQueryResumeSupportedL(aMessage);
+				break;
+			case EMMFDevSoundProxyResume:
+				complete = DoResumeL(aMessage);
+				break;
+
+			// DevSound custom command support
+			case EMMFDevSoundProxySyncCustomCommand:
+			case EMMFDevSoundProxySyncCustomCommandResult:
+			case EMMFDevSoundProxyAsyncCustomCommand:
+			case EMMFDevSoundProxyAsyncCustomCommandResult:
+				complete = DoCustomCommandL(aMessage);
+				break;
+			case EMMFDevSoundProxyClose:
+				complete = DoPrepareCloseL(aMessage);
+				break;
+			case EMMFDevSoundProxyRequestResourceNotification:
+				complete = DoRegisterAsClientL(aMessage);
+				break;
+			case EMMFDevSoundProxyCancelRequestResourceNotification:
+				complete = DoCancelRegisterAsClientL(aMessage);
+				break;
+			case EMMFDevSoundProxyGetResourceNotificationData:
+				complete = DoGetResourceNotificationDataL(aMessage);
+				break;
+			case EMMFDevSoundProxyWillResumePlay:
+				complete = DoWillResumePlayL(aMessage);
+				break;
+			case EMMFDevSoundProxySetClientThreadInfo:
+				complete = DoSetClientThreadInfoL(aMessage);
+				break;						
+			default:
+				User::Leave(KErrNotSupported);
+				break;
+			}
+
+		// Check if can complete the message now
+		if (complete)
+			{
+			// Complete the message
+			// Synchronous requests & Pseudo-asynchronous
+			aMessage.Complete(KErrNone);
+			}
+		// Note: There are operations that not complete the message using the following flag
+		// So if the message is not completed, cannot be assumed that there is an operation pending
+		
+		if(iOperationCompletePending)
+			{
+			// Keep a copy of the message for Asynchronous requests & Pseudo-asynchronous
+			iRequestBeingServiced.SetMessage(aMessage);
+			}
+		}
+	else
+		{
+		// If there's a CI extension, see if that handles this request
+		TInt err = KErrNotSupported;
+		if (iCIExtension)
+			{
+			iOperationCompletePending = ETrue;
+			TRAPD(err2, err = iCIExtension->HandleMessageL(aMessage));
+			if (err2)
+				{
+				err = err2;
+				}
+			iOperationCompletePending = EFalse;
+			}
+
+		if (err != KErrNone)
+			{
+			// Not been handled, the request is not supported
+			aMessage.Complete(KErrNotSupported);
+			}
+		}
+	}
+
+
+void CMMFDevSoundSession::EnqueueRequest(const RMmfIpcMessage& aMessage)
+	{
+	// Encapsule the request
+	TMMFDevSoundRequest request;
+	request.SetMessage(aMessage);
+	// Append
+	TInt error = iQueuedRequests.Append(request);
+	__ASSERT_DEBUG(error == KErrNone, Panic(EQueueRequestsFailedToAppend)); 
+	}
+
+//
+// CMMFDevSoundSession::DoPostOpenL
+//
+TBool CMMFDevSoundSession::DoPostOpenL(const RMmfIpcMessage& /*aMessage*/)
+	{
+	iAdapter->PostOpenL();
+	iOperationCompletePending = ETrue;
+	return EFalse;
+	}
+
+//
+// CMMFDevSoundSession::DoInitialize1L
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoInitialize1L(const RMmfIpcMessage& aMessage)
+	{
+	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
+	User::LeaveIfError(err);
+	DoSetClientConfigL();// added here instead of the CreateL()
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	MmfMessageUtil::ReadL(aMessage,1,devSoundBuf);
+	TMMFState mode = devSoundBuf().iMode;
+	iAdapter->InitializeL(mode);
+	iBufferPlay = NULL;
+	iPlayErrorOccured = EFalse;
+	// Flag to queue any further request 
+	// but the message can be completed now
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoInitialize2L
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoInitialize2L(const RMmfIpcMessage& aMessage)
+	{
+	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
+	User::LeaveIfError(err);
+	DoSetClientConfigL();// added here instead of the CreateL()
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	MmfMessageUtil::ReadL(aMessage,1,devSoundBuf);
+	TUid HWDev = devSoundBuf().iHWDev;
+	TMMFState mode = devSoundBuf().iMode;
+	iAdapter->InitializeL(HWDev, mode);
+	iBufferPlay = NULL;
+	iPlayErrorOccured = EFalse;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoInitialize4L
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoInitialize4L(const RMmfIpcMessage& aMessage)
+	{
+	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
+	User::LeaveIfError(err);
+	DoSetClientConfigL();// added here instead of the CreateL()
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TFourCC desiredFourCC = devSoundBuf().iDesiredFourCC;
+	TMMFState mode = devSoundBuf().iMode;
+	iAdapter->InitializeL(desiredFourCC, mode);
+	iBufferPlay = NULL;
+	iPlayErrorOccured = EFalse;
+	// Flag to queue any further request 
+	// but the message can be completed now
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoCancelInitialize
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoCancelInitializeL(const RMmfIpcMessage& aMessage)
+	{
+	TInt err=iAdapter->CancelInitialize();
+
+	if (err != KErrNone)
+		{
+		aMessage.Complete(err);
+		iOperationCompletePending = EFalse;
+		return ETrue;
+		}
+	else
+		{
+		iOperationCompletePending = ETrue;
+		}
+	return EFalse;
+	}
+
+//
+// CMMFDevSoundSession::DoCapabilitiesL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoCapabilitiesL(const RMmfIpcMessage& aMessage)
+	{
+	TInt err = iAdapter->Capabilities(iDevSoundCapabilities);
+	if(err != KErrNone)
+		{
+		aMessage.Complete(err);
+		iOperationCompletePending = EFalse;
+		}
+	else
+		{
+		iOperationCompletePending = ETrue;
+		}
+	return EFalse;
+	}
+
+//
+// CMMFDevSoundSession::DoConfigL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoConfigL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettings devSoundSet;
+	devSoundSet.iConfig = iAdapter->Config();
+	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetConfigL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetConfigL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TMMFCapabilities config = devSoundBuf().iConfig;
+	iAdapter->SetConfigL(config);
+	iOperationCompletePending = ETrue;
+	return EFalse;
+	}
+
+//
+// CMMFDevSoundSession::axVolumeL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoMaxVolumeL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettings devSoundSet;
+	devSoundSet.iMaxVolume = iAdapter->MaxVolume();
+	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoVolumeL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoVolumeL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettings devSoundSet;
+	devSoundSet.iVolume = iAdapter->Volume();
+	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetVolumeL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetVolumeL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TInt volume = devSoundBuf().iVolume;
+	TBool asyncOperation;
+	User::LeaveIfError(iAdapter->SetVolume(volume, asyncOperation));
+	iOperationCompletePending = asyncOperation;
+	return !asyncOperation;
+	}
+
+//
+// CMMFDevSoundSession::DoMaxGainL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoMaxGainL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettings devSoundSet;
+	devSoundSet.iMaxGain = iAdapter->MaxGain();
+	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoGainL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoGainL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettings devSoundSet;
+	devSoundSet.iGain = iAdapter->Gain();
+	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetGainL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetGainL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TInt gain = devSoundBuf().iGain;
+	TBool asyncOperation;
+	User::LeaveIfError(iAdapter->SetGain(gain, asyncOperation));
+	iOperationCompletePending = asyncOperation;
+	return !asyncOperation;
+	}
+
+//
+// CMMFDevSoundSession::DoGetPlayBalanceL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoGetPlayBalanceL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettings devSoundSet;
+	iAdapter->GetPlayBalanceL(devSoundSet.iLeftPercentage, devSoundSet.iRightPercentage);
+	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetPlayBalanceL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetPlayBalanceL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TInt leftPercentage = devSoundBuf().iLeftPercentage;
+	TInt rightPercentage = devSoundBuf().iRightPercentage;
+	TBool asyncOperation;
+	iAdapter->SetPlayBalanceL(leftPercentage, rightPercentage, asyncOperation);
+	iOperationCompletePending = asyncOperation;
+	return !asyncOperation;
+	}
+
+//
+// CMMFDevSoundSession::DoGetRecordBalanceL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoGetRecordBalanceL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettings devSoundSet;
+	iAdapter->GetRecordBalanceL(devSoundSet.iLeftPercentage, devSoundSet.iRightPercentage);
+	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetRecordBalanceL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetRecordBalanceL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TInt leftPercentage = devSoundBuf().iLeftPercentage;
+	TInt rightPercentage = devSoundBuf().iRightPercentage;
+	TBool asyncOperation;
+	iAdapter->SetRecordBalanceL(leftPercentage, rightPercentage, asyncOperation);
+	iOperationCompletePending = asyncOperation;
+	return !asyncOperation;
+	}
+
+//
+// CMMFDevSoundSession::DoPlayInitL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoPlayInitL(const RMmfIpcMessage& /*aMessage*/)
+	{
+	iAdapter->PlayInitL();
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoRecordInitL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoRecordInitL(const RMmfIpcMessage& /*aMessage*/)
+	{
+	iAdapter->RecordInitL();
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoPlayDataL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoPlayDataL(const RMmfIpcMessage& aMessage)
+	{
+	SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Enter"));
+
+	if( iPlayErrorOccured )
+		{
+		SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Ignore and Exit"));
+		return ETrue;
+		}
+
+	TMMFDevSoundProxyHwBufPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	iBufferPlay->SetLastBuffer(devSoundBuf().iLastBuffer);
+
+	TPtr8 dataPtr(iChunk.Base(), devSoundBuf().iBufferSize, devSoundBuf().iBufferSize);
+	// Copy data over from chunk
+	iBufferPlay->Data().Copy(dataPtr);
+	iAdapter->PlayData();
+	SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Exit"));
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoRecordDataL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoRecordDataL(const RMmfIpcMessage& /*aMessage*/)
+	{
+	iAdapter->RecordData();
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoStopL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoStopL(const RMmfIpcMessage& /*aMessage*/)
+	{
+	// Sometimes Stop is not involved on a commit cycle
+	TBool completed = iAdapter->Stop();
+	if (completed)
+		{
+		iQueuedRequests.Reset();
+		FlushEventQueue(); // completed returned here means we were idle to start with. TODO could possibly skip this flush
+		iChunk.Close();
+		}
+	iOperationCompletePending = !completed;
+	return completed;
+	}
+
+//
+// CMMFDevSoundSession::DoPauseL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoPauseL(const RMmfIpcMessage& /*aMessage*/)
+	{
+	User::LeaveIfError(iAdapter->Pause());
+	iOperationCompletePending = ETrue;
+	return EFalse;
+	}
+
+//
+// CMMFDevSoundSession::DoPlayToneL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoPlayToneL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TInt frequency = devSoundBuf().iFrequencyOne;
+	TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration);
+	iAdapter->PlayToneL(frequency, duration);
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoPlayDualToneL
+// (other items were commented in a header).	
+//
+TBool CMMFDevSoundSession::DoPlayDualToneL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TInt frequencyOne = devSoundBuf().iFrequencyOne;
+	TInt frequencyTwo = devSoundBuf().iFrequencyTwo;
+	TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration);
+	iAdapter->PlayDualToneL(frequencyOne, frequencyTwo, duration);
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoPlayDTMFStringL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoPlayDTMFStringL(const RMmfIpcMessage& aMessage)
+	{
+	TInt dtmfLength = aMessage.GetDesLength(2);
+	
+	if(iDtmfString)
+		{
+		delete iDtmfString;
+		iDtmfString = NULL;
+		}
+
+	iDtmfString = HBufC::NewL(dtmfLength);
+	TPtr dtmfPtr = iDtmfString->Des();
+	aMessage.ReadL(TInt(2), dtmfPtr);
+
+	iAdapter->PlayDTMFStringL(*iDtmfString);
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoPlayToneSequenceL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoPlayToneSequenceL(const RMmfIpcMessage& aMessage)
+	{
+	TInt toneLength = aMessage.GetDesLength(1);
+
+	if(iToneSeqBuf)
+		{
+		delete iToneSeqBuf;
+		iToneSeqBuf = NULL;
+		}
+
+	iToneSeqBuf = HBufC8::NewL(toneLength);
+	TPtr8 toneSeqPtr = iToneSeqBuf->Des();
+	aMessage.ReadL(TInt(1), toneSeqPtr);
+
+	iAdapter->PlayToneSequenceL(*iToneSeqBuf);
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoPlayFixedSequenceL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoPlayFixedSequenceL(const RMmfIpcMessage& aMessage)
+	{
+	TPckgBuf<TInt> buf;
+	aMessage.ReadL(TInt(1),buf);
+	TInt seqNum = buf();
+
+	iAdapter->PlayFixedSequenceL(seqNum);
+	iOperationCompletePending = ETrue;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetDTMFLengthsL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetDTMFLengthsL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TTimeIntervalMicroSeconds32 toneOnLength = devSoundBuf().iToneOnLength;
+	TTimeIntervalMicroSeconds32 toneOffLength = devSoundBuf().iToneOffLength;
+	TTimeIntervalMicroSeconds32 pauseLength = devSoundBuf().iPauseLength;
+	User::LeaveIfError(iAdapter->SetDTMFLengths(toneOnLength, toneOffLength, pauseLength));
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetVolumeRampL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetVolumeRampL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg devSoundBuf;
+	aMessage.ReadL(TInt(1),devSoundBuf);
+	TTimeIntervalMicroSeconds duration = devSoundBuf().iDuration;
+	User::LeaveIfError(iAdapter->SetVolumeRamp(duration));
+	iOperationCompletePending = EFalse; // Volume ramp doesn't result on commit
+	return ETrue; // operation complete
+	}
+
+//
+// CMMFDevSoundSession::DoGetSupportedInputDataTypesL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoGetSupportedInputDataTypesL(
+							const RMmfIpcMessage& aMessage)
+	{
+	iArray.Reset();
+
+	TMMFPrioritySettingsPckg prioritySetBuf;
+	aMessage.ReadL(TInt(1),prioritySetBuf);
+	TMMFPrioritySettings prioritySet = prioritySetBuf();
+
+	iAdapter->GetSupportedInputDataTypesL(iArray, prioritySet);
+
+	TPckgBuf<TInt> pckg;
+	pckg() = iArray.Count();
+	aMessage.WriteL(TInt(2),pckg);
+
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoGetSupportedOutputDataTypesL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoGetSupportedOutputDataTypesL(
+							const RMmfIpcMessage& aMessage)
+	{
+	iArray.Reset();
+
+	TMMFPrioritySettingsPckg prioritySetBuf;
+	aMessage.ReadL(TInt(1),prioritySetBuf);
+	TMMFPrioritySettings prioritySet = prioritySetBuf();
+
+	iAdapter->GetSupportedOutputDataTypesL(iArray, prioritySet);
+
+	TPckgBuf<TInt> pckg;
+	pckg() = iArray.Count();
+	aMessage.WriteL(TInt(2),pckg);
+
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSamplesRecordedL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSamplesRecordedL(const RMmfIpcMessage& aMessage)
+	{
+	TPckgBuf<TInt> pckg;
+	pckg() = iAdapter->SamplesRecorded();
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSamplesPlayedL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSamplesPlayedL(const RMmfIpcMessage& aMessage)
+	{
+	TPckgBuf<TInt> pckg;
+	pckg() = iAdapter->SamplesPlayed();
+	aMessage.WriteL(TInt(2),pckg);
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetToneRepeatsL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetToneRepeatsL(const RMmfIpcMessage& aMessage)
+	{
+	TPckgBuf<TInt> countRepeat;
+	aMessage.ReadL(TInt(1),countRepeat);
+
+	TPckgBuf<TTimeIntervalMicroSeconds> repeatTS;
+	aMessage.ReadL(TInt(2),repeatTS);
+	User::LeaveIfError(iAdapter->SetToneRepeats(countRepeat(), repeatTS()));
+	
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoSetPrioritySettingsL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoSetPrioritySettingsL(
+						const RMmfIpcMessage& aMessage)
+	{
+	TPckgBuf<TMMFPrioritySettings> prioritySet;
+	aMessage.ReadL(TInt(1),prioritySet);
+
+	User::LeaveIfError(iAdapter->SetPrioritySettings(prioritySet()));
+	iOperationCompletePending = EFalse;
+	return ETrue;
+	}
+
+//
+// CMMFDevSoundSession::DoFixedSequenceCountL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoFixedSequenceCountL(
+					const RMmfIpcMessage& aMessage)
+	{
+	TPckgBuf<TInt> fixSeqCountPckg;
+	TInt fixSeqCount = iAdapter->FixedSequenceCount();
+	fixSeqCountPckg = fixSeqCount;
+
+	aMessage.WriteL(TInt(2),fixSeqCountPckg);
+	return ETrue;
+	}
+
+
+//
+// CMMFDevSoundSession::DoCopyFourCCArrayDataL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoCopyFourCCArrayDataL(
+						const RMmfIpcMessage& aMessage)
+	{
+	const TInt KBufExpandSize8 = 8;//two TInts
+	CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
+	CleanupStack::PushL(dataCopyBuffer);
+	RBufWriteStream stream;
+	stream.Open(*dataCopyBuffer);
+	CleanupClosePushL(stream);
+	
+	TInt i = 0;
+	TInt count = iArray.Count();
+	
+	while (i < count)
+		{
+		stream.WriteInt32L(iArray[i].FourCC());
+		i++;
+		}
+	aMessage.WriteL(TInt(2), dataCopyBuffer->Ptr(0));
+	stream.Close();
+	CleanupStack::PopAndDestroy(&stream);
+	CleanupStack::PopAndDestroy(dataCopyBuffer);
+	return ETrue;
+	}
+
+
+//
+// CMMFDevSoundSession::DoBufferToBeFilledDataL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoBufferToBeFilledDataL(
+							const RMmfIpcMessage& aMessage)
+	{
+	// if CMMFDevSoundSession::PlayError() has been called, RChunk would have got closed.
+	// Need to check if Chunk Handle is still valid. If it is not,complete the message immediately and send a error to the Client.
+	if(!iChunk.Handle())
+		{
+		aMessage.Complete(KErrBadHandle);
+		return EFalse;	
+		}
+	TPckgBuf<TInt> requestChunkBuf;
+	MmfMessageUtil::Read(aMessage, TInt(1), requestChunkBuf);
+	TBool requestChunk = requestChunkBuf();
+	if (requestChunk)
+		{
+		// if the client requests, always do EOpen
+		iHwBufPckgFill().iChunkOp = EOpen;
+		}
+	TInt err = MmfMessageUtil::Write(aMessage, TInt(2), iHwBufPckgFill);
+	if ( (err == KErrNone) && (iHwBufPckgFill().iChunkOp == EOpen) )
+		{
+		aMessage.Complete(iChunk);
+		}
+	else
+		{
+		aMessage.Complete(err);
+		}
+	return EFalse;
+	}
+
+// CMMFDevSoundSession::DoBufferToBeEmptiedDataL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoBufferToBeEmptiedDataL(
+						const RMmfIpcMessage& aMessage)
+	{
+	// if CMMFDevSoundSession::RecordError() has been called, RChunk would have got closed.
+	// Need to check if Chunk Handle is still valid. If it is not,complete the message immediately and send a error to the Client.
+	if(!iChunk.Handle())
+		{
+		aMessage.Complete(KErrBadHandle);
+		return EFalse;	
+		}
+	
+	TInt err = MmfMessageUtil::Write(aMessage, TInt(2), iHwBufPckgEmpty);
+	if ( (err == KErrNone) && (iHwBufPckgEmpty().iChunkOp == EOpen) )
+		{
+		aMessage.Complete(iChunk);
+		}
+	else
+		{
+		aMessage.Complete(err);
+		}
+	return EFalse;
+	}
+
+//
+// CMMFDevSoundSession::DoEmptyBuffersL
+// (other items were commented in a header).
+//
+
+TBool CMMFDevSoundSession::DoEmptyBuffersL(const RMmfIpcMessage& aMessage)
+	{
+	TInt err = KErrNone;
+	FilterQueueEvent(EMMFDevSoundProxyBTBFEvent);
+	// This is now asynchronous
+	err = iAdapter->EmptyBuffers();
+	if (err != KErrNone)
+		{
+		aMessage.Complete(err);
+		return EFalse;
+		}
+	iOperationCompletePending = ETrue;
+	return EFalse;
+	}
+//
+// CMMFDevSoundSession::DoGetTimePlayedL
+// (other items were commented in a header).
+//
+TBool CMMFDevSoundSession::DoGetTimePlayedL(const RMmfIpcMessage& aMessage)
+	{
+	TInt err = KErrNone;
+	TTimeIntervalMicroSeconds time(0);
+	TPckgBuf<TTimeIntervalMicroSeconds> timePckg(time);
+	err = iAdapter->GetTimePlayed(timePckg());
+	if (err != KErrNone)
+		{
+		aMessage.Complete(err);
+		return EFalse;		
+		}
+	aMessage.WriteL(TInt(2),timePckg);
+	return ETrue;
+	}
+
+TBool CMMFDevSoundSession::DoQueryResumeSupportedL(const RMmfIpcMessage& aMessage)
+	{
+	TBool isSupported = EFalse;
+	TPckgBuf<TBool> isSupportedPckg(isSupported);
+	isSupportedPckg() = iAdapter->IsResumeSupported();
+	aMessage.WriteL(TInt(2),isSupportedPckg);
+	return ETrue;
+	}
+
+TBool CMMFDevSoundSession::DoResumeL(const RMmfIpcMessage& /*aMessage*/)
+	{
+	User::LeaveIfError( iAdapter->Resume() );
+	iOperationCompletePending = ETrue;
+	FilterQueueEvent(EMMFDevSoundProxyPausedRecordCompleteEvent);
+	return EFalse;
+	}
+
+TBool CMMFDevSoundSession::DoPrepareCloseL(const RMmfIpcMessage& /*aMessage*/)
+	{
+	TBool complete = iAdapter->CloseDevSound();
+	if(!complete)
+		{
+		iOperationCompletePending = ETrue;	
+		}
+	return complete;
+	}
+
+
+TBool CMMFDevSoundSession::DoCustomCommandL(const RMmfIpcMessage& aMessage)
+	{
+	TInt retVal = KErrNone;
+	TRAPD(err, retVal = iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
+	if (err != KErrNone)
+		{
+		// the framework left with an error condition
+		// so we complete the message with this error
+		// irrespective of whether its a Sync or Async custom command
+		aMessage.Complete(err);
+		}
+	else
+		{
+		TInt messageType = aMessage.Function();
+		if ((messageType == EMMFDevSoundProxySyncCustomCommand) ||
+			(messageType == EMMFDevSoundProxySyncCustomCommandResult))
+			{
+			// If its a sync custom command
+			// we can pass back valid values here since command
+			// has been handled by the DeMux framework
+			aMessage.Complete(retVal);	
+			}
+		}
+	
+	// we complete our own message so don't need the framework to do so
+	return EFalse;
+	}
+	
+
+//
+// CMMFDevSoundSession::CMMFDevSoundSession
+// (other items were commented in a header).
+//
+CMMFDevSoundSession::CMMFDevSoundSession() :
+	iSetClientConfigApplied (EFalse)
+	{
+	}
+
+//
+// CMMFDevSoundSession::~CMMFDevSoundSession
+// (other items were commented in a header).
+//
+CMMFDevSoundSession::~CMMFDevSoundSession()
+	{
+	delete iAsyncQueueStart;
+	// clear the array of custom interfaces
+	TInt count = iCustomInterfaceArray.Count();
+	for (TInt i = 0; i < count; i++)
+		{
+		// we could have already deleted interfaces without
+		// removing them from the array so check for this
+		// and only delete release plugin if non-null
+		MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface;
+		if (ptr)
+			{
+			iCustomInterfaceArray[i].iInterface->Release();	
+			}
+		}
+	iCustomInterfaceArray.Reset();
+	iCustomInterfaceArray.Close();
+		
+	delete iDeMuxUtility;
+	
+	if (iCIExtension)
+		{
+		iCIExtension->Release();
+		iCIExtension = NULL;
+		}
+
+	iMsgQueue.Close();
+	iArray.Close();
+	iQueuedRequests.Close();
+	delete iDtmfString;
+	delete iToneSeqBuf;
+	delete iAdapter;
+	delete iClosingWait;
+
+	CMMFDevSoundServer* server =
+			const_cast<CMMFDevSoundServer*>(
+			static_cast<const CMMFDevSoundServer*>(Server()));
+
+	if (server)
+		{
+		server->DecrementSessionId();
+		}
+
+//	delete iCustomCommandParserManager;
+//	delete iMMFObjectContainer;
+
+	// Close chunk
+	iChunk.Close();
+	}
+
+//
+// CMMFDevSoundSession::FlushEventQueue()
+//
+void CMMFDevSoundSession::FlushEventQueue()
+	{
+	if(iMsgQueue.Handle() != 0)
+		{
+		TMMFDevSoundQueueItem queueItem;
+		TInt err = KErrNone;
+		while(err != KErrUnderflow)
+			{
+			err = iMsgQueue.Receive(queueItem);
+			}
+		}	
+	}
+
+void CMMFDevSoundSession::FilterQueueEvent(TMMFDevSoundProxyRequest aRequest)
+	{
+	if(iMsgQueue.Handle() != 0)
+		{
+		// Pop and push events result at the queue 
+		// can be seen as "circular list"
+		// set a mark to traverse it safely 
+		TMMFDevSoundQueueItem markItem;
+		markItem.iRequest = EMMFDevSoundProxyMarkEvent;
+		// assumes sufficient space in the queue
+		TInt err = iMsgQueue.Send(markItem);
+		__ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg));
+		
+		while(ETrue)
+			{
+			// At least the markEvent is at the queue so ignore the error
+			TMMFDevSoundQueueItem queueItem;
+			err = iMsgQueue.Receive(queueItem);
+			if(queueItem.iRequest == EMMFDevSoundProxyMarkEvent)
+				{
+				break;
+				}
+			// Look for the specific event
+			else if(queueItem.iRequest != aRequest)
+				{
+				// assumes sufficient space in the queue
+				err = iMsgQueue.Send(queueItem);
+				}
+			}
+		}
+	}
+
+//
+// CMMFDevSoundSession::Disconnect
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::Disconnect(const RMessage2& aMessage)
+	{
+	TBool complete = iAdapter->CloseDevSound();
+	if(!complete)
+		{
+		iRequestBeingServiced.SetMessage(aMessage);
+		iOperationCompletePending = ETrue;
+		iClosingWait->Start();
+		}
+	CSession2::Disconnect(aMessage);
+	}
+
+
+//
+// CMMFDevSoundSession::NewL
+// (other items were commented in a header).
+//
+CMMFDevSoundSession* CMMFDevSoundSession::NewL(MGlobalProperties& aGlobalProperties)
+	{
+	CMMFDevSoundSession* self = new (ELeave) CMMFDevSoundSession;
+	CleanupStack::PushL(self);
+	self->ConstructL(aGlobalProperties);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+//
+// CMMFDevSoundSession::ConstructL
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::ConstructL(MGlobalProperties& aGlobalProperties)
+	{
+	iAdapter = CMMFDevSoundAdaptation::NewL(*this, aGlobalProperties);
+
+	iClosingWait = new(ELeave) CActiveSchedulerWait();
+	
+	// Create the Custom Interface DeMux Utility
+	iDeMuxUtility = CMMFDevSoundCIDeMuxUtility::NewL(this);
+	
+	// Create the Custom Interface extension
+	TUid implUid = {KMmfUidCIServerExtensionImpl};
+	TInt uidAsInteger = implUid.iUid;
+	const TInt KCIExtTempBufferSize = 20;
+	TBuf8<KCIExtTempBufferSize> tempBuffer;
+	tempBuffer.Num(uidAsInteger, EHex);
+	TUid interfaceUid = {KUidDevSoundCIServerExtension};
+	TUid destructorKey;
+	TRAPD(err, iCIExtension = static_cast<MDevSoundCIServerExtension*>
+		 (MmPluginUtils::CreateImplementationL(interfaceUid, destructorKey, tempBuffer, KRomOnlyResolverUid)));
+	if (KErrNotSupported == err)
+		{
+		iCIExtension = NULL;
+		}
+	else
+		{
+		User::LeaveIfError(err);
+		}
+	if (iCIExtension)
+		{
+		// Extension exists. Complete the setup
+		iCIExtension->PassDestructorKey(destructorKey);
+		User::LeaveIfError(iCIExtension->Setup(*this));
+		}
+
+	iQueuedRequests.ReserveL(KMaxQueueRequest);
+	iAsyncQueueStart = new (ELeave) CAsyncCallBack(CActive::EPriorityStandard);
+	TCallBack asyncCallback(AsyncQueueStartCallback, this);
+	iAsyncQueueStart->Set(asyncCallback);
+	}
+
+// CMMFDevSoundSession::InitializeComplete
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::InitializeComplete(TInt aError)
+	{
+	// this may be a re-initialization and so we need to
+	// re-get our custom interfaces on the DeMux plugins
+	TInt count = iCustomInterfaceArray.Count();
+	for (TInt i = 0; i < count; i++)
+		{
+		// we could have already deleted interfaces without
+		// removing them from the array so check for this
+		// and only refresh plugin if non-null
+		MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface;
+		if (ptr)
+			{
+			// we can't keep track of..
+			// 1. where a custom interface is implemented
+			// 2. the uid of the custom interface to be refreshed
+			// so assume all have to be refreshed
+			TRAPD(err, ptr->RefreshL());	
+			
+			// Error indicates this is no longer a valid interface
+			if (err != KErrNone)
+				{
+				TMMFEvent event;
+				TMMFDevSoundQueueItem item;
+				item.iRequest = EMMFDevSoundCustomCommandCloseMuxDemuxPair;
+				item.iErrorCode = err;
+				event.iEventType.iUid = i+1;
+				item.iEventPckg() = event;
+				TInt lErr = iMsgQueue.Send(item);
+				__ASSERT_DEBUG(lErr == KErrNone, Panic(EMsgQueueFailedToSendMsg));
+
+// NB proper panic code required here for this part.
+				}
+			}
+		}
+	TMMFDevSoundQueueItem item;
+	item.iRequest = EMMFDevSoundProxyICEvent;
+	item.iErrorCode = aError;
+	// assumes sufficient space in the queue so ignores the return value
+	iMsgQueue.Send(item); 
+	}
+
+// 
+// CMMFDevSoundSession::ToneFinished
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::ToneFinished(TInt aError)
+	{
+	TMMFDevSoundQueueItem item;
+	item.iRequest = EMMFDevSoundProxyTFEvent;
+	item.iErrorCode = aError;
+	// assumes sufficient space in the queue so ignores the return value
+	iMsgQueue.Send(item);
+	}
+
+//
+// CMMFDevSoundSession::BufferToBeFilled
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::BufferToBeFilled(CMMFBuffer* aBuffer)
+	{
+	SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::BufferToBeFilled - Enter"));
+
+	// Set play error flag to false 
+	iPlayErrorOccured = EFalse;
+
+	// Store pointer to the buffer to use it later with PlayData
+	iBufferPlay = reinterpret_cast<CMMFDataBuffer*>(aBuffer);
+	TInt status = CreateChunk(iHwBufPckgFill, iBufferPlay->RequestSize());
+	iHwBufPckgFill().iRequestSize = iBufferPlay->RequestSize();
+	iHwBufPckgFill().iBufferSize = iBufferPlay->Data().MaxLength();
+	iHwBufPckgFill().iLastBuffer = iBufferPlay->LastBuffer();
+	TMMFDevSoundQueueItem queueItem;
+	if ( status != KErrNone )
+		{
+		BufferErrorEvent();
+		PlayError(status);
+		}
+	else
+		{
+		queueItem.iRequest = EMMFDevSoundProxyBTBFEvent;
+		// assumes sufficient space in the queue so ignores the return value
+		status = iMsgQueue.Send(queueItem);
+		}
+
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::BufferToBeFilled - Exit [%d]"), status);
+	}
+
+//
+// CMMFDevSoundSession::PlayError
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::PlayError(TInt aError)
+	{
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::PlayError [%d]"), aError);
+
+	// Set play error flag to ignore following PlayData requests
+	iPlayErrorOccured = ETrue;
+
+	TMMFDevSoundQueueItem item;
+	item.iRequest = EMMFDevSoundProxyPEEvent;
+	item.iErrorCode = aError;
+	iChunk.Close();
+	// assumes sufficient space in the queue so ignores the return value
+	iMsgQueue.Send(item);
+	}
+
+//
+// CMMFDevSoundSession::BufferToBeEmptied
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::BufferToBeEmptied(CMMFBuffer* aBuffer)
+	{
+	// Store pointer to the buffer to use it later with RecordData
+	iBufferRecord = reinterpret_cast<CMMFDataBuffer*>(aBuffer);
+	TInt status = CreateChunk(iHwBufPckgEmpty, iBufferRecord->RequestSize());
+	
+	if ( status != KErrNone )
+		{
+		BufferErrorEvent();
+		RecordError(status);
+		}
+	else
+		{
+		iHwBufPckgEmpty().iRequestSize = iBufferRecord->RequestSize();
+		iHwBufPckgEmpty().iBufferSize = iBufferRecord->Data().MaxLength();
+		iHwBufPckgEmpty().iLastBuffer = iBufferRecord->LastBuffer();
+		//copy the data into the chunk    
+		Mem::Copy(iChunk.Base(),iBufferRecord->Data().Ptr(),iBufferRecord->RequestSize());
+	    TMMFDevSoundQueueItem queueItem;
+		queueItem.iRequest = EMMFDevSoundProxyBTBEEvent;
+		// assumes sufficient space in the queue so ignores the return value
+		iMsgQueue.Send(queueItem);
+		}
+	}
+
+// CMMFDevSoundSession::RecordError
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::RecordError(TInt aError)
+	{
+	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::Record Error [%d]"), aError);
+	TMMFDevSoundQueueItem item;
+	item.iRequest = EMMFDevSoundProxyREEvent;
+	item.iErrorCode = aError;
+	iChunk.Close();
+	// assumes sufficient space in the queue so ignores the return value
+	iMsgQueue.Send(item);
+	}
+
+//
+// CMMFDevSoundSession::DeviceMessage
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::DeviceMessage(TUid /*aMessageType*/,
+									const TDesC8& /*aMsg*/)
+	{
+	// Not used
+	}
+
+void CMMFDevSoundSession::InterfaceDeleted(TUid aInterfaceId)
+	{
+	MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = InterfaceFromUid(aInterfaceId);
+	if (ptr == NULL)
+		{
+		// Not found
+		return;
+		}
+	TRAPD(err, ptr->RefreshL());
+	if (err != KErrNone)
+		{
+		// Refresh failed, so tear down Mux/DeMux pair
+		TMMFEvent event;
+		TMMFDevSoundQueueItem item;
+		item.iRequest = EMMFDevSoundCustomCommandCloseMuxDemuxPair;
+		item.iErrorCode = err;
+		event.iEventType = aInterfaceId;
+		item.iEventPckg() = event;
+		iMsgQueue.Send(item);
+		}
+	}
+
+//
+// CMMFDevSoundSession::CallbackFromAdaptorReceived
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::CallbackFromAdaptorReceived(TInt aType, TInt aError)
+	{
+	
+	if(aType == KCallbackRecordPauseComplete)
+		{
+		TMMFDevSoundQueueItem item;
+		item.iRequest = EMMFDevSoundProxyPausedRecordCompleteEvent;
+		item.iErrorCode = KErrNone;
+		TInt status = iMsgQueue.Send(item);
+		}
+	else if(aType == KCallbackAutoPauseResume)
+		{
+		TMMFEvent event;
+		event.iErrorCode = KErrNone;
+		event.iEventType = KMMFEventCategoryAudioResourceAvailable;
+		SendEventToClient(event);
+		//coverity[uninit_use_in_call]
+		// Disabled Coverity warning, since it complains about iReserved1 member in TMMFEvent being uninitialised
+		}
+	else if (aType == KCallbackFlushComplete)
+		{
+		iRequestBeingServiced.Complete(aError);
+		iOperationCompletePending = EFalse;
+		}
+	else
+		{
+		if( iOperationCompletePending )
+			{
+			// If not possible to service now, then queue request
+			// Encapsule the request
+			TMMFDevSoundRequest request(aType);
+			// assumes sufficient space in the queue so ignores the return value
+			iQueuedRequests.Insert(request, 0);
+			}
+		else
+			{
+			// If there is no oustanding operation service inmediately
+			if (aType == KCallbackProcessingFinished)
+				{
+				DoProcessingFinished();
+				}
+			else if(aType == KCallbackProcessingUnitError)
+				{
+				DoProcessingError();
+				}
+			}
+		}
+	}
+
+
+//
+// CMMFDevSoundSession::PreemptionStartedCallbackReceived
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::PreemptionStartedCallbackReceived()
+	{
+	// Solution: Enqueue any request that arrives before preemption is completed
+	iOperationCompletePending = ETrue;
+	}
+
+//
+// CMMFDevSoundSession::PreemptionFinishedCallbackReceived
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::PreemptionFinishedCallbackReceived(TBool aCanStartNewOperation)
+	{
+	iOperationCompletePending = EFalse;
+	if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 )
+		{
+		DequeueRequest();
+		}
+	}
+
+
+MMMFDevSoundCustomInterfaceDeMuxPlugin* CMMFDevSoundSession::InterfaceFromUid(TUid aUid)
+	{
+	TInt count = iCustomInterfaceArray.Count();
+	TInt id = aUid.iUid;
+	MMMFDevSoundCustomInterfaceDeMuxPlugin* interface = NULL;
+	for (TInt i = 0; i < count; i++)
+		{
+		if (id == iCustomInterfaceArray[i].iId.iUid)
+			{
+			interface = iCustomInterfaceArray[i].iInterface;
+			break;
+			}
+		}
+	return interface;
+	}
+
+//
+// CMMFDevSoundSession::SendEventToClient
+// (other items were commented in a header).
+//
+void CMMFDevSoundSession::SendEventToClient(const TMMFEvent& aEvent)
+	{
+	TMMFDevSoundQueueItem item;
+	item.iRequest = EMMFDevSoundProxySETCEvent;
+	item.iErrorCode = KErrNone;
+	item.iEventPckg() = aEvent;
+	// assumes sufficient space in the queue so ignores the return value
+	TInt err = iMsgQueue.Send(item);
+	__ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg));
+	}
+
+void CMMFDevSoundSession::AsynchronousOperationComplete(TInt aError, TBool aCanStartNewOperation)
+	{
+	switch (iRequestBeingServiced.Type())
+		{
+		case TMMFDevSoundRequest::ESessionEvents:
+			{
+			SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x] ==== ClosingDueException ==== "));
+			iOperationCompletePending = EFalse;
+			if(iClosingWait->IsStarted())
+				{
+				iClosingWait->AsyncStop();
+				}
+			return;
+			}
+		// Complete the message for asynchronous requests
+		case TMMFDevSoundRequest::EConfigure_Asynchronous:
+		case TMMFDevSoundRequest::EAction_Asynchronous:
+		case TMMFDevSoundRequest::EQuery_Asynchronous:
+		case TMMFDevSoundRequest::ECustomInterfacesRelated:
+			{
+			if(iOperationCompletePending && aCanStartNewOperation)
+				{
+				if (iRequestBeingServiced.Function()==EMMFDevSoundProxyStop)
+					{
+					// flush the queue - will have removed any stale items added between initial call and MMRC's reaction
+					iQueuedRequests.Reset();
+					FlushEventQueue();
+					iChunk.Close();
+					}
+					
+				if(iRequestBeingServiced.Function()==EMMFDevSoundProxyCapabilities)
+					{
+					TMMFDevSoundProxySettings devSoundSet;
+					devSoundSet.iCaps = iDevSoundCapabilities;
+					TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
+					iRequestBeingServiced.Message().Write(TInt(2),pckg);
+					}
+				
+				if(iRequestBeingServiced.Function()==EMMFDevSoundProxyCancelInitialize)
+					{
+					FlushEventQueue();
+					}
+				
+				iRequestBeingServiced.Complete(aError);
+				iOperationCompletePending = EFalse;
+				}
+			}
+			break;
+		case TMMFDevSoundRequest::EAction_PseudoAsynchronous:
+			{
+			if(iOperationCompletePending && aCanStartNewOperation)
+				{
+				iOperationCompletePending = EFalse;
+				}
+			}
+			break;
+		case TMMFDevSoundRequest::EQuery_Synchronous:
+		case TMMFDevSoundRequest::EConfigure_Synchronous:
+		case TMMFDevSoundRequest::EBufferExchangeRelated:
+			break;
+		case TMMFDevSoundRequest::ECallBackType:
+			{
+			if(iOperationCompletePending && aCanStartNewOperation)
+				{
+				iOperationCompletePending = EFalse;
+				}	
+			}
+			break;
+		default:
+			break;
+		}
+
+	SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete %x pending=%d"),iRequestBeingServiced.Function(), iOperationCompletePending );
+
+	if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 )
+		{
+		DequeueRequest();
+		}
+	}
+
+void CMMFDevSoundSession::DequeueRequest()
+	{
+	TMMFDevSoundRequest msg = iQueuedRequests[0];
+
+	if (msg.IsCallBack() > 0)
+		{
+		iRequestBeingServiced.SetMessageCallback();
+		//Call iPf function
+		SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x] ======== Service a queued request\n"));
+		if (msg.IsCallBack() == KCallbackProcessingFinished)
+			{
+			iQueuedRequests.Remove(0);
+			DoProcessingFinished();
+			}
+		else if(msg.IsCallBack() == KCallbackProcessingUnitError)
+		    {
+		    iQueuedRequests.Remove(0);
+		    DoProcessingError();
+		    }
+
+		}
+	else
+		{
+		// Some rules about what request can be followed
+		SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Flag can service new request\n"));
+		iAsyncQueueStart->CallBack();
+		}
+	}
+	
+// 	AsyncQueueStartCallback
+
+
+TInt CMMFDevSoundSession::AsyncQueueStartCallback(TAny* aPtr)
+	{
+	CMMFDevSoundSession* self = static_cast<CMMFDevSoundSession*>(aPtr);
+	self->AsyncQueueStartCallback();
+	return KErrNone;
+	}
+	
+void CMMFDevSoundSession::AsyncQueueStartCallback()
+	{
+	SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Service a queued request\n"));
+	TMMFDevSoundRequest msg = iQueuedRequests[0];
+	iQueuedRequests.Remove(0);
+	TRAPD(err,DoServiceRequestL(msg.Message()));
+    if(err != KErrNone)
+        {
+        msg.Complete(err);      
+        }
+	if (!iOperationCompletePending && iQueuedRequests.Count() != 0)
+		{
+		//dequeue next
+		DequeueRequest();
+		}
+	}
+
+// CMMFDevSoundSession::CustomInterface()
+// Returns a pointer reference to custom interface implementation returned by
+// adaptation::CustomInterface method.
+// Note this method is called indirectly by CI server-side plugins - both DeMux and 
+// CIServerExtension call this variously via MMMFDevSoundCustomInterfaceTarget or MCustomInterface 
+//
+TAny* CMMFDevSoundSession::CustomInterface(TUid aInterfaceId)
+	{
+	TInt err = DoSetClientConfig(); // if required, this will connect to MMRC etc
+	if (err)
+		{
+		return NULL; // on any error, return NULL - not much more we can do
+		}
+	return iAdapter->CustomInterface(aInterfaceId);
+	}
+
+//
+// CMMFDevSoundSession::DoProcessingFinished()
+//
+void CMMFDevSoundSession::DoProcessingFinished()
+	{
+	TBool asyncOperation = EFalse;
+	//ProcessingFinished should never fail
+	__ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingFinishedReceived(asyncOperation));
+	iOperationCompletePending = asyncOperation;
+	if (iOperationCompletePending)
+		{
+		iRequestBeingServiced.SetMessageCallback();
+		}
+	}
+
+//
+// CMMFDevSoundSession::DoProcessingError()
+//
+void CMMFDevSoundSession::DoProcessingError()
+    {
+    TBool asyncOperation = EFalse;
+    //ProcessingFinished should never fail
+    __ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingError(asyncOperation));
+    iOperationCompletePending = asyncOperation;
+    if (iOperationCompletePending)
+        {
+        iRequestBeingServiced.SetMessageCallback();
+        }
+    }
+
+//
+// CMMFDevSoundSession::DoSetClientConfigL()
+// Sets client configuration information to Adaptation.
+//
+TInt CMMFDevSoundSession::DoSetClientConfig()
+	{
+	TInt err = KErrNone;
+	if(!iSetClientConfigApplied)
+		{
+		CMMFDevSoundServer* server =
+			const_cast<CMMFDevSoundServer*>(
+				static_cast<const CMMFDevSoundServer*>(Server()));
+			
+		ASSERT(server); // session should always have a server!
+
+		TMMFClientConfig clientConfig;
+		clientConfig.iProcessId = server->ActualProcessId();
+
+		err = iAdapter->SetClientConfig(clientConfig);
+		if (!err)
+			{
+			iSetClientConfigApplied = ETrue;
+			}
+		}
+	return err;
+	}
+
+// CMMFDevSoundSession::DoSetClientConfigL()
+// Sets client configuration information to Adaptation.
+//
+void CMMFDevSoundSession::DoSetClientConfigL()
+	{
+	User::LeaveIfError(DoSetClientConfig());
+	}
+
+// 
+// CMMFDevSoundSession::CreateChunk()
+// Requests kernel to create global RChunk
+// 
+TInt CMMFDevSoundSession::CreateChunk(TMMFDevSoundProxyHwBufPckg& aBufPckg, TInt aRequestedSize)
+	{
+	TInt status(KErrNone);
+	
+	if ( iChunk.Handle() )
+		{
+		// If the DevSound Adaptation component requests a buffer size
+		// that can fit into current chunk's size, then re-use chunk.
+		if ( aRequestedSize <= iChunk.Size() )
+			{
+			if (iForceSendOfChunkHandle)
+				{
+				iForceSendOfChunkHandle = EFalse;
+				aBufPckg().iChunkOp = EOpen;
+				}
+			else
+				{
+				aBufPckg().iChunkOp = ENull;
+				}
+			return status;
+			}
+		// The new request size exceeds the current chunk's area, close it. We
+		// will be creating new one in the following sequences. Note we could
+		// try to Adjust() the chunk, and see if the existing chunk could be
+		// extended instead, but this is assumed too rare an event for this 
+		// optimisation
+		else
+			{
+			iChunk.Close();
+			}
+		}
+	
+	// Request kernel to create global RChunk if needed
+	if ( !iChunk.Handle() )
+		{
+		status = iChunk.CreateGlobal(KNullDesC, aRequestedSize, aRequestedSize);
+		if ( status == KErrNone )
+			{
+			aBufPckg().iChunkOp = EOpen;
+			}
+		else
+			{
+			aBufPckg().iChunkOp = ENull;
+			}
+		}
+	iForceSendOfChunkHandle = EFalse;
+	return status;
+	}
+
+
+// Custom Interface //
+TInt CMMFDevSoundSession::DoOpenSlaveL(TUid aInterface, const TDesC8& aPackageBuf)
+	{
+	// it shouldn't be necessary to check if we have already instantiated this
+	// interface since the client would already know - however this is something
+	// that a licensee could implement if they required additional functionality
+	// e.g. many : 1 mappings between client and DevSound.
+
+	MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = NULL;
+		
+	// try and instantiate a plugin tunnelling
+	// pair to support this Custom Interface
+	ptr = iDeMuxUtility->CreateCustomInterfaceDeMuxL(aInterface);
+	
+	TInt handle = KNullHandle;
+	
+	if (ptr)
+		{
+		TMMFDevSoundCustomInterfaceDeMuxData data;
+		data.iInterface = ptr;
+		data.iId = aInterface;
+			
+		CleanupReleasePushL(*ptr);
+			
+		// setup demux plugin
+		ptr->SetInterfaceTarget(this);
+			
+		// try and open interface
+		// this will fetch the interface from the svr implementation
+		ptr->DoOpenSlaveL(aInterface, aPackageBuf);
+		User::LeaveIfError(iCustomInterfaceArray.Append(data));
+			
+		CleanupStack::Pop();	// ptr
+			
+		handle = iCustomInterfaceArray.Count();
+		return handle;
+		}
+
+	// we couldn't set up the interface correctly so return a NULL
+	// handle to the client
+	return KNullHandle;
+	}
+	
+void CMMFDevSoundSession::DoCloseSlaveL(TInt aHandle)
+	{
+	if (aHandle==KNullHandle)
+		{
+		// null-handle -> NOP
+		return;
+		}
+		
+	if (aHandle<KNullHandle || aHandle > iCustomInterfaceArray.Count())
+		{
+		// handle out of range - should not happen, but leave to show error
+		User::Leave(KErrBadHandle);
+		}
+		
+	TMMFDevSoundCustomInterfaceDeMuxData& data = iCustomInterfaceArray[aHandle-1];
+	
+	// close and delete the plugin
+	MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = data.iInterface;
+	ptr->DoCloseSlaveL(aHandle);
+	ptr->Release();
+	
+	// clear the entry
+	data.iInterface = NULL;
+	data.iId.iUid = 0;
+	}
+	
+TInt CMMFDevSoundSession::DoSendSlaveSyncCommandL(const RMmfIpcMessage& aMessage)
+	{
+	// use the demux utility to get the handle
+	TMMFDevSoundCIMessageData data;
+	iDeMuxUtility->GetSyncMessageDataL(aMessage, data);
+	
+	TInt handle = data.iHandle;
+	
+	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
+		{
+		
+		User::Leave(KErrBadHandle);
+		}
+	
+	// call on demux plugin
+	return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandL(aMessage);	
+	}
+	
+TInt CMMFDevSoundSession::DoSendSlaveSyncCommandResultL(const RMmfIpcMessage& aMessage)
+	{
+	// use the demux utility to get the handle
+	TMMFDevSoundCIMessageData data;
+	iDeMuxUtility->GetSyncMessageDataL(aMessage, data);
+	
+	TInt handle = data.iHandle;
+	
+	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
+		{
+		
+		User::Leave(KErrBadHandle);
+		}
+	
+	// call on demux plugin
+	return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandResultL(aMessage);	
+	}
+	
+void CMMFDevSoundSession::DoSendSlaveAsyncCommandL(const RMmfIpcMessage& aMessage)
+	{
+	// use the demux utility to get the handle
+	TMMFDevSoundCIMessageData data;
+	iDeMuxUtility->GetAsyncMessageDataL(aMessage, data);
+	
+	TInt handle = data.iHandle;
+	
+	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
+		{
+		User::Leave(KErrBadHandle);
+		}
+	
+	// call on demux plugin
+	iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandL(aMessage);	
+	}
+	
+void CMMFDevSoundSession::DoSendSlaveAsyncCommandResultL(const RMmfIpcMessage& aMessage)
+	{
+	// use the demux utility to get the handle
+	TMMFDevSoundCIMessageData data;
+	iDeMuxUtility->GetAsyncMessageDataL(aMessage, data);
+	
+	TInt handle = data.iHandle;
+	
+	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
+		{
+		User::Leave(KErrBadHandle);
+		}
+	
+	// call on demux plugin
+	iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandResultL(aMessage);	
+	}
+
+
+TBool CMMFDevSoundSession::DoRegisterAsClientL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg buf;
+	aMessage.ReadL(0,buf);
+	HBufC8* notificationRegistrationData = NULL;
+	notificationRegistrationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLengthL(1)));
+	TPtr8 dataPtr(notificationRegistrationData->Des());  	
+	aMessage.ReadL(1,dataPtr);
+	DoSetClientConfigL();// added here instead of the CreateL()
+	TInt err = KErrNone;
+	err = iAdapter->RegisterAsClient(buf().iNotificationEventUid,dataPtr);
+	CleanupStack::PopAndDestroy(1); // Notification Registeration data
+	if (err != KErrNone)
+		{
+		aMessage.Complete(err);
+		return EFalse;		
+		}
+	return ETrue;
+	}
+	
+TBool CMMFDevSoundSession::DoCancelRegisterAsClientL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg buf;
+	aMessage.ReadL(0,buf);
+	TInt err = KErrNone;
+	err = iAdapter->CancelRegisterAsClient(buf().iNotificationEventUid);
+	if (err != KErrNone)
+		{
+		aMessage.Complete(err);
+		return EFalse;		
+		}
+	return ETrue;
+	}
+
+TBool CMMFDevSoundSession::DoGetResourceNotificationDataL(const RMmfIpcMessage& aMessage)
+	{
+	TMMFDevSoundProxySettingsPckg buf;
+	aMessage.ReadL(0,buf);
+	HBufC8* notificationData = NULL;
+	notificationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLengthL(2)));
+	TPtr8 dataPtr(notificationData->Des());  	
+	aMessage.ReadL(2,dataPtr);
+	TInt err = KErrNone;
+	err = iAdapter->GetResourceNotificationData(buf().iNotificationEventUid,dataPtr);
+	aMessage.WriteL(2,*notificationData);
+	CleanupStack::PopAndDestroy(1); // Notification data
+	if (err != KErrNone)
+		{
+		aMessage.Complete(err);
+		return EFalse;		
+		}
+	return ETrue;
+	}
+
+TBool CMMFDevSoundSession::DoWillResumePlayL(const RMmfIpcMessage& aMessage)
+	{
+	TInt err = KErrNone;
+	err = iAdapter->WillResumePlay();
+	if (err != KErrNone)
+		{
+		aMessage.Complete(err);
+		return EFalse;		
+		}
+	return ETrue;
+	}
+
+TBool CMMFDevSoundSession::DoSetClientThreadInfoL(const RMmfIpcMessage& aMessage)
+	{
+	if(!iSetClientConfigApplied)
+		{
+		if (aMessage.HasCapability(ECapabilityMultimediaDD) && aMessage.HasCapability(ECapabilityUserEnvironment))
+			{
+			TPckgBuf<TThreadId> threadId;
+			aMessage.ReadL(1, threadId);
+			
+			CMMFDevSoundServer* server = 
+				const_cast<CMMFDevSoundServer*>(static_cast<const CMMFDevSoundServer*>(Server()));
+			server->SetClientProcessIdL(threadId()); 
+			}
+		else
+			{
+			User::Leave(KErrPermissionDenied);
+			}
+		}
+	else
+		{
+		User::Leave(KErrNotReady);
+		}
+	return ETrue;
+	}
+	
+void CMMFDevSoundSession::Panic(TMMFDevSoundSessionPanicCodes aCode)
+	{
+	User::Panic(KMMFDevSoundSessionPanicCategory, aCode);
+	}
+
+void CMMFDevSoundSession::BufferErrorEvent()
+	{
+	// this will generate an processing error event and callback
+	iAdapter->BufferErrorEvent();
+	}
+// End of file