devsound/a3fdevsound/src/mmfdevsoundserver/mmfdevsoundsession.cpp
changeset 0 40261b775718
child 8 bc06d8566074
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <s32mem.h>
       
    17 #include "mmfaudioclientserver.h"
       
    18 #include "mmfaudioserver.h"
       
    19 #include "mmfdevsoundserver.h"
       
    20 #include "mmfdevsoundsession.h"
       
    21 #include <mmf/plugin/mmfdevsoundcustominterface.hrh>
       
    22 #include <mm/mmpluginutils.h>
       
    23 #ifdef _DEBUG
       
    24 #include "e32debug.h"
       
    25 
       
    26 #define SYMBIAN_DEBPRN0(str)                RDebug::Print(str, this)
       
    27 #define SYMBIAN_DEBPRN1(str, val1)          RDebug::Print(str, this, val1)
       
    28 #define SYMBIAN_DEBPRN2(str, val1, val2)    RDebug::Print(str, this, val1, val2)
       
    29 #else
       
    30 #define SYMBIAN_DEBPRN0(str)
       
    31 #define SYMBIAN_DEBPRN1(str, val1)
       
    32 #define SYMBIAN_DEBPRN2(str, val1, val2)
       
    33 #endif //_DEBUG
       
    34 
       
    35 //Assume that we can have two user request and one callback request
       
    36 //at the same time (maximum).
       
    37 const TInt KMaxQueueRequest = 3;
       
    38 
       
    39 //	MEMBER FUNCTIONS 
       
    40 
       
    41 TMMFDevSoundRequest::TMMFDevSoundRequest() 
       
    42 	: iMessageCompleted(EFalse), 
       
    43 	iRequestType(EUndefinedType),
       
    44 	iCallBackPF(KCallbackNone)
       
    45 	{
       
    46 	}
       
    47 
       
    48 TMMFDevSoundRequest::TMMFDevSoundRequest(TInt aIsCallBack)
       
    49 	: iMessageCompleted(EFalse), 
       
    50 	iRequestType(ECallBackType),
       
    51 	iCallBackPF(aIsCallBack)
       
    52 	{
       
    53 	}
       
    54 
       
    55 TMMFDevSoundRequest::TMMFDevSoundRequest(const TMMFDevSoundRequest& aRequest)
       
    56 	: iMessageCompleted(EFalse), 
       
    57 	iMessage(aRequest.iMessage),
       
    58 	iCallBackPF(aRequest.iCallBackPF)
       
    59 	{
       
    60 	iRequestType = ResolveType();
       
    61 	}
       
    62 
       
    63 TBool TMMFDevSoundRequest::operator==(const TMMFDevSoundRequest& aRequest) const
       
    64 	{
       
    65 	TBool retval = EFalse;
       
    66 	if ( aRequest.Function() == Function() )
       
    67 		{
       
    68 		retval = ETrue;
       
    69 		}
       
    70 	else
       
    71 		{
       
    72 		retval = EFalse;
       
    73 		}
       
    74 	return retval;
       
    75 	}
       
    76 
       
    77 const RMmfIpcMessage& TMMFDevSoundRequest::Message() 
       
    78 	{ 
       
    79 	return iMessage; 
       
    80 	}
       
    81 
       
    82 void TMMFDevSoundRequest::SetMessage(const RMmfIpcMessage& aMessage) 
       
    83 	{
       
    84 	iMessageCompleted = EFalse;
       
    85 	iMessage = aMessage;
       
    86 	iRequestType = ResolveType();
       
    87 	}
       
    88 	
       
    89 void TMMFDevSoundRequest::SetMessageCallback() 
       
    90 	{
       
    91 	iMessageCompleted = EFalse;
       
    92 	iRequestType = ECallBackType;
       
    93 	}	
       
    94 
       
    95 TInt TMMFDevSoundRequest::IsCallBack() const
       
    96 	{
       
    97 	return iCallBackPF;	
       
    98 	}
       
    99 
       
   100 TMMFDevSoundRequest::TA3FDevSoundRequestType TMMFDevSoundRequest::ResolveType()
       
   101 	{
       
   102 	TA3FDevSoundRequestType type = EUndefinedType;
       
   103 	switch(iMessage.Function())
       
   104 		{
       
   105 		case EMMFDevSoundProxyInitialize1:
       
   106 		case EMMFDevSoundProxyInitialize2:
       
   107 		case EMMFDevSoundProxyInitialize4:
       
   108 		case EMMFDevSoundProxyPlayInit:
       
   109 		case EMMFDevSoundProxyRecordInit:
       
   110 		case EMMFDevSoundProxyPlayTone:
       
   111 		case EMMFDevSoundProxyPlayDualTone:
       
   112 		case EMMFDevSoundProxyPlayDTMFString:
       
   113 		case EMMFDevSoundProxyPlayToneSequence:
       
   114 		case EMMFDevSoundProxyPlayFixedSequence:
       
   115 			type = EAction_PseudoAsynchronous;
       
   116 			break;
       
   117 
       
   118 		case EMMFDevSoundProxyStop:
       
   119 		case EMMFDevSoundProxyPause:
       
   120 		case EMMFDevSoundProxyClose:
       
   121 		case EMMFDevSoundProxyCancelInitialize:
       
   122 		case EMMFDevSoundProxyResume:
       
   123 		case EMMFDevSoundProxyEmptyBuffers:
       
   124 			type = EAction_Asynchronous;
       
   125 			break;
       
   126 
       
   127 		case EMMFDevSoundProxySetConfig:
       
   128 		case EMMFDevSoundProxyPostOpen: // Although this is not a configure operation technically, it has same calling pattern.
       
   129 		case EMMFDevSoundProxySetVolume:
       
   130 		case EMMFDevSoundProxySetGain:
       
   131 		case EMMFDevSoundProxySetPlayBalance:
       
   132 		case EMMFDevSoundProxySetRecordBalance:
       
   133 		case EMMFDevSoundProxySetVolumeRamp:
       
   134 		case EMMFDevSoundProxySetPrioritySettings:
       
   135 			type = EConfigure_Asynchronous;
       
   136 			break;
       
   137 			
       
   138 		case EMMFDevSoundProxySetDTMFLengths:
       
   139 		case EMMFDevSoundProxySetToneRepeats:
       
   140 			type = EConfigure_Synchronous;	
       
   141 			break;
       
   142 		case EMMFDevSoundProxyCapabilities:
       
   143 			type = EQuery_Asynchronous;
       
   144 			break;
       
   145 		case EMMFDevSoundProxyMaxVolume:
       
   146 		case EMMFDevSoundProxyMaxGain:
       
   147 		case EMMFDevSoundProxyConfig:
       
   148 		case EMMFDevSoundProxyVolume:
       
   149 		case EMMFDevSoundProxyGain:
       
   150 		case EMMFDevSoundProxyPlayBalance:
       
   151 		case EMMFDevSoundProxyRecordBalance:
       
   152 		case EMMFDevSoundProxyGetSupportedInputDataTypes:
       
   153 		case EMMFDevSoundProxyGetSupportedOutputDataTypes:
       
   154 		case EMMFDevSoundProxyFixedSequenceName:
       
   155 		case EMMFDevSoundProxyFixedSequenceCount:
       
   156 		case EMMFDevSoundProxySamplesRecorded:
       
   157 		case EMMFDevSoundProxySamplesPlayed:
       
   158 		case EMMFDevSoundProxyCopyFourCCArrayData:
       
   159 		case EMMFDevSoundProxyGetTimePlayed:
       
   160 		case EMMFDevSoundProxyIsResumeSupported:
       
   161 			type = EQuery_Synchronous;
       
   162 			break;
       
   163 		
       
   164 		case EMMFDevSoundProxyBTBFData:
       
   165 		case EMMFDevSoundProxyBTBEData:
       
   166 		case EMMFDevSoundProxyPlayData:
       
   167 		case EMMFDevSoundProxyRecordData:
       
   168 			type = EBufferExchangeRelated;
       
   169 			break;
       
   170 
       
   171 		// Custom Interfaces
       
   172 		case EMMFDevSoundProxySyncCustomCommand:
       
   173 		case EMMFDevSoundProxySyncCustomCommandResult:
       
   174 		case EMMFDevSoundProxyAsyncCustomCommand:
       
   175 		case EMMFDevSoundProxyAsyncCustomCommandResult:
       
   176 		case EMMFDevSoundProxyCustomInterface:
       
   177 			type = ECustomInterfacesRelated;
       
   178 			break;
       
   179 		case RMessage2::EDisConnect:
       
   180 			type = ESessionEvents;
       
   181 			break;
       
   182 		default:
       
   183 			break;
       
   184 		}
       
   185 	return type;
       
   186 	}
       
   187 
       
   188 
       
   189 void TMMFDevSoundRequest::Complete(TInt aError)	
       
   190 	{
       
   191 	if(!iMessageCompleted && iRequestType != EUndefinedType && iRequestType != ECallBackType)	
       
   192 		{
       
   193 		iMessage.Complete(aError);
       
   194 		iMessageCompleted = ETrue;
       
   195 		iRequestType = EUndefinedType;
       
   196 		}
       
   197 	}
       
   198 
       
   199 TInt TMMFDevSoundRequest::Function() const 
       
   200 	{
       
   201 	return iMessage.Function(); 
       
   202 	}
       
   203 
       
   204 TMMFDevSoundRequest::TA3FDevSoundRequestType TMMFDevSoundRequest::Type() const
       
   205 	{
       
   206 	return iRequestType;
       
   207 	}
       
   208 
       
   209 
       
   210 // 
       
   211 // CMMFDevSoundSession::CreateL
       
   212 // Creates a new object
       
   213 // 
       
   214 void CMMFDevSoundSession::CreateL(const CMmfIpcServer& aServer)
       
   215 	{
       
   216 	CMmfIpcSession::CreateL(aServer);
       
   217 	CMMFDevSoundServer& server =
       
   218 	const_cast<CMMFDevSoundServer&>(
       
   219 			static_cast<const CMMFDevSoundServer&>(aServer));
       
   220 	server.IncrementSessionId();
       
   221 	iDevSoundSessionId = server.DevSoundSessionId();
       
   222 	}
       
   223 
       
   224 //
       
   225 // CMMFDevSoundSession::ServiceL
       
   226 // (other items were commented in a header).
       
   227 //
       
   228 void CMMFDevSoundSession::ServiceL(const RMmfIpcMessage& aMessage)
       
   229 	{
       
   230 	SYMBIAN_DEBPRN2(_L("\nCMMFDevSoundSession[0x%x] NEW REQUEST %02x while pending=%d"), aMessage.Function(), iOperationCompletePending);
       
   231 	if( iOperationCompletePending || iAsyncQueueStart->IsActive())
       
   232 		{
       
   233 		// if not possible to service now, then queue request
       
   234 		EnqueueRequest(aMessage);
       
   235 		}
       
   236 	else
       
   237 		{
       
   238 		// If there is no oustanding operation service inmediately
       
   239 		DoServiceRequestL(aMessage);
       
   240 		}
       
   241 	}
       
   242 	
       
   243 //
       
   244 // CMMFDevSoundSession::DoServiceL
       
   245 // (other items were commented in a header).
       
   246 //
       
   247 void CMMFDevSoundSession::DoServiceRequestL(const RMmfIpcMessage& aMessage)
       
   248 	{
       
   249 	iAsyncQueueStart->Cancel(); // just in case.
       
   250 	TMMFMessageDestinationPckg destinationPckg;
       
   251 	MmfMessageUtil::ReadL(aMessage, 0, destinationPckg);
       
   252 	if ((destinationPckg().DestinationHandle() == KMMFObjectHandleDevSound) &&
       
   253 	    (destinationPckg().InterfaceId() == KUidInterfaceMMFDevSound))
       
   254 		{
       
   255 		TBool complete = EFalse;
       
   256 		switch(aMessage.Function())
       
   257 			{
       
   258 			case EMMFDevSoundProxyPostOpen:
       
   259 				complete = DoPostOpenL(aMessage);
       
   260 				break;
       
   261 			case EMMFDevSoundProxyInitialize1:
       
   262 				complete = DoInitialize1L(aMessage);
       
   263 				break;
       
   264 			case EMMFDevSoundProxyInitialize2:
       
   265 				complete = DoInitialize2L(aMessage);
       
   266 				break;
       
   267 			case EMMFDevSoundProxyInitialize4:
       
   268 				complete = DoInitialize4L(aMessage);
       
   269 				break;
       
   270 			case EMMFDevSoundProxyCapabilities:
       
   271 				complete = DoCapabilitiesL(aMessage);
       
   272 				break;
       
   273 			case EMMFDevSoundProxyConfig:
       
   274 				complete = DoConfigL(aMessage);
       
   275 				break;
       
   276 			case EMMFDevSoundProxySetConfig:
       
   277 				complete = DoSetConfigL(aMessage);
       
   278 				break;
       
   279 			case EMMFDevSoundProxyMaxVolume:
       
   280 				complete = DoMaxVolumeL(aMessage);
       
   281 				break;
       
   282 			case EMMFDevSoundProxyVolume:
       
   283 				complete = DoVolumeL(aMessage);
       
   284 				break;
       
   285 			case EMMFDevSoundProxySetVolume:
       
   286 				complete = DoSetVolumeL(aMessage);
       
   287 				break;
       
   288 			case EMMFDevSoundProxyMaxGain:
       
   289 				complete = DoMaxGainL(aMessage);
       
   290 				break;
       
   291 			case EMMFDevSoundProxyGain:
       
   292 				complete = DoGainL(aMessage);
       
   293 				break;
       
   294 			case EMMFDevSoundProxySetGain:
       
   295 				complete = DoSetGainL(aMessage);
       
   296 				break;
       
   297 			case EMMFDevSoundProxyPlayBalance:
       
   298 				complete = DoGetPlayBalanceL(aMessage);
       
   299 				break;
       
   300 			case EMMFDevSoundProxySetPlayBalance:
       
   301 				complete = DoSetPlayBalanceL(aMessage);
       
   302 				break;
       
   303 			case EMMFDevSoundProxyRecordBalance:
       
   304 				complete = DoGetRecordBalanceL(aMessage);
       
   305 				break;
       
   306 			case EMMFDevSoundProxySetRecordBalance:
       
   307 				complete = DoSetRecordBalanceL(aMessage);
       
   308 				break;
       
   309 			case EMMFDevSoundProxyBTBFData:
       
   310 				complete = DoBufferToBeFilledDataL(aMessage);
       
   311 				break;
       
   312 			case EMMFDevSoundProxyBTBEData:
       
   313 				complete = DoBufferToBeEmptiedDataL(aMessage);
       
   314 				break;
       
   315 			case EMMFDevSoundProxyPlayInit:
       
   316 				complete = DoPlayInitL(aMessage);
       
   317 				break;
       
   318 			case EMMFDevSoundProxyRecordInit:
       
   319 				complete = DoRecordInitL(aMessage);
       
   320 				break;
       
   321 			case EMMFDevSoundProxyPlayData:
       
   322 				complete = DoPlayDataL(aMessage);
       
   323 				break;
       
   324 			case EMMFDevSoundProxyRecordData:
       
   325 				complete = DoRecordDataL(aMessage);
       
   326 				break;
       
   327 			case EMMFDevSoundProxyStop:
       
   328 				complete = DoStopL(aMessage);
       
   329 				break;
       
   330 			case EMMFDevSoundProxyPause:
       
   331 				complete = DoPauseL(aMessage);
       
   332 				break;
       
   333 			case EMMFDevSoundProxyPlayTone:
       
   334 				complete = DoPlayToneL(aMessage);
       
   335 				break;
       
   336 			case EMMFDevSoundProxyPlayDualTone:
       
   337 				complete = DoPlayDualToneL(aMessage);
       
   338 				break;
       
   339 			case EMMFDevSoundProxyPlayDTMFString:
       
   340 				complete = DoPlayDTMFStringL(aMessage);
       
   341 				break;
       
   342 			case EMMFDevSoundProxyPlayToneSequence:
       
   343 				complete = DoPlayToneSequenceL(aMessage);
       
   344 				break;
       
   345 			case EMMFDevSoundProxyPlayFixedSequence:
       
   346 				complete = DoPlayFixedSequenceL(aMessage);
       
   347 				break;
       
   348 			case EMMFDevSoundProxySetDTMFLengths:
       
   349 				complete = DoSetDTMFLengthsL(aMessage);
       
   350 				break;
       
   351 			case EMMFDevSoundProxySetVolumeRamp:
       
   352 				complete = DoSetVolumeRampL(aMessage);
       
   353 				break;
       
   354 			case EMMFDevSoundProxyGetSupportedInputDataTypes:
       
   355 				complete = DoGetSupportedInputDataTypesL(aMessage);
       
   356 				break;
       
   357 			case EMMFDevSoundProxyGetSupportedOutputDataTypes:
       
   358 				complete = DoGetSupportedOutputDataTypesL(aMessage);
       
   359 				break;
       
   360 			case EMMFDevSoundProxyCopyFourCCArrayData:
       
   361 				complete = DoCopyFourCCArrayDataL(aMessage);
       
   362 				break;
       
   363 			case EMMFDevSoundProxySamplesRecorded:
       
   364 				complete = DoSamplesRecordedL(aMessage);
       
   365 				break;
       
   366 			case EMMFDevSoundProxySamplesPlayed:
       
   367 				complete = DoSamplesPlayedL(aMessage);
       
   368 				break;
       
   369 			case EMMFDevSoundProxySetToneRepeats:
       
   370 				complete = DoSetToneRepeatsL(aMessage);
       
   371 				break;
       
   372 			case EMMFDevSoundProxySetPrioritySettings:
       
   373 				complete = DoSetPrioritySettingsL(aMessage);
       
   374 				break;
       
   375 			case EMMFDevSoundProxyFixedSequenceCount:
       
   376 				complete = DoFixedSequenceCountL(aMessage);
       
   377 				break;
       
   378 			case EMMFDevSoundProxyCancelInitialize:
       
   379 				complete = DoCancelInitializeL(aMessage);
       
   380 				break;
       
   381 			case EMMFDevSoundProxyEmptyBuffers:
       
   382 				complete = DoEmptyBuffersL(aMessage);
       
   383 				break;
       
   384 			case EMMFDevSoundProxyGetTimePlayed:
       
   385 				complete = DoGetTimePlayedL(aMessage);
       
   386 				break;
       
   387 			case EMMFDevSoundProxyIsResumeSupported:
       
   388 				complete = DoQueryResumeSupportedL(aMessage);
       
   389 				break;
       
   390 			case EMMFDevSoundProxyResume:
       
   391 				complete = DoResumeL(aMessage);
       
   392 				break;
       
   393 
       
   394 			// DevSound custom command support
       
   395 			case EMMFDevSoundProxySyncCustomCommand:
       
   396 			case EMMFDevSoundProxySyncCustomCommandResult:
       
   397 			case EMMFDevSoundProxyAsyncCustomCommand:
       
   398 			case EMMFDevSoundProxyAsyncCustomCommandResult:
       
   399 				complete = DoCustomCommandL(aMessage);
       
   400 				break;
       
   401 			case EMMFDevSoundProxyClose:
       
   402 				complete = DoPrepareCloseL(aMessage);
       
   403 				break;
       
   404 			case EMMFDevSoundProxyRequestResourceNotification:
       
   405 				complete = DoRegisterAsClientL(aMessage);
       
   406 				break;
       
   407 			case EMMFDevSoundProxyCancelRequestResourceNotification:
       
   408 				complete = DoCancelRegisterAsClientL(aMessage);
       
   409 				break;
       
   410 			case EMMFDevSoundProxyGetResourceNotificationData:
       
   411 				complete = DoGetResourceNotificationDataL(aMessage);
       
   412 				break;
       
   413 			case EMMFDevSoundProxyWillResumePlay:
       
   414 				complete = DoWillResumePlayL(aMessage);
       
   415 				break;
       
   416 			case EMMFDevSoundProxySetClientThreadInfo:
       
   417 				complete = DoSetClientThreadInfoL(aMessage);
       
   418 				break;						
       
   419 			default:
       
   420 				User::Leave(KErrNotSupported);
       
   421 				break;
       
   422 			}
       
   423 
       
   424 		// Check if can complete the message now
       
   425 		if (complete)
       
   426 			{
       
   427 			// Complete the message
       
   428 			// Synchronous requests & Pseudo-asynchronous
       
   429 			aMessage.Complete(KErrNone);
       
   430 			}
       
   431 		// Note: There are operations that not complete the message using the following flag
       
   432 		// So if the message is not completed, cannot be assumed that there is an operation pending
       
   433 		
       
   434 		if(iOperationCompletePending)
       
   435 			{
       
   436 			// Keep a copy of the message for Asynchronous requests & Pseudo-asynchronous
       
   437 			iRequestBeingServiced.SetMessage(aMessage);
       
   438 			}
       
   439 		}
       
   440 	else
       
   441 		{
       
   442 		// If there's a CI extension, see if that handles this request
       
   443 		TInt err = KErrNotSupported;
       
   444 		if (iCIExtension)
       
   445 			{
       
   446 			iOperationCompletePending = ETrue;
       
   447 			TRAPD(err2, err = iCIExtension->HandleMessageL(aMessage));
       
   448 			if (err2)
       
   449 				{
       
   450 				err = err2;
       
   451 				}
       
   452 			iOperationCompletePending = EFalse;
       
   453 			}
       
   454 
       
   455 		if (err != KErrNone)
       
   456 			{
       
   457 			// Not been handled, the request is not supported
       
   458 			aMessage.Complete(KErrNotSupported);
       
   459 			}
       
   460 		}
       
   461 	}
       
   462 
       
   463 
       
   464 void CMMFDevSoundSession::EnqueueRequest(const RMmfIpcMessage& aMessage)
       
   465 	{
       
   466 	// Encapsule the request
       
   467 	TMMFDevSoundRequest request;
       
   468 	request.SetMessage(aMessage);
       
   469 	// Append
       
   470 	TInt error = iQueuedRequests.Append(request);
       
   471 	__ASSERT_DEBUG(error == KErrNone, Panic(EQueueRequestsFailedToAppend)); 
       
   472 	}
       
   473 
       
   474 //
       
   475 // CMMFDevSoundSession::DoPostOpenL
       
   476 //
       
   477 TBool CMMFDevSoundSession::DoPostOpenL(const RMmfIpcMessage& /*aMessage*/)
       
   478 	{
       
   479 	iAdapter->PostOpenL();
       
   480 	iOperationCompletePending = ETrue;
       
   481 	return EFalse;
       
   482 	}
       
   483 
       
   484 //
       
   485 // CMMFDevSoundSession::DoInitialize1L
       
   486 // (other items were commented in a header).
       
   487 //
       
   488 TBool CMMFDevSoundSession::DoInitialize1L(const RMmfIpcMessage& aMessage)
       
   489 	{
       
   490 	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
       
   491 	User::LeaveIfError(err);
       
   492 	DoSetClientConfigL();// added here instead of the CreateL()
       
   493 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   494 	MmfMessageUtil::ReadL(aMessage,1,devSoundBuf);
       
   495 	TMMFState mode = devSoundBuf().iMode;
       
   496 	iAdapter->InitializeL(mode);
       
   497 	iBufferPlay = NULL;
       
   498 	iPlayErrorOccured = EFalse;
       
   499 	// Flag to queue any further request 
       
   500 	// but the message can be completed now
       
   501 	iOperationCompletePending = ETrue;
       
   502 	return ETrue;
       
   503 	}
       
   504 
       
   505 //
       
   506 // CMMFDevSoundSession::DoInitialize2L
       
   507 // (other items were commented in a header).
       
   508 //
       
   509 TBool CMMFDevSoundSession::DoInitialize2L(const RMmfIpcMessage& aMessage)
       
   510 	{
       
   511 	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
       
   512 	User::LeaveIfError(err);
       
   513 	DoSetClientConfigL();// added here instead of the CreateL()
       
   514 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   515 	MmfMessageUtil::ReadL(aMessage,1,devSoundBuf);
       
   516 	TUid HWDev = devSoundBuf().iHWDev;
       
   517 	TMMFState mode = devSoundBuf().iMode;
       
   518 	iAdapter->InitializeL(HWDev, mode);
       
   519 	iBufferPlay = NULL;
       
   520 	iPlayErrorOccured = EFalse;
       
   521 	return ETrue;
       
   522 	}
       
   523 
       
   524 //
       
   525 // CMMFDevSoundSession::DoInitialize4L
       
   526 // (other items were commented in a header).
       
   527 //
       
   528 TBool CMMFDevSoundSession::DoInitialize4L(const RMmfIpcMessage& aMessage)
       
   529 	{
       
   530 	TInt err = iMsgQueue.Open(aMessage, 2); // a global queue.
       
   531 	User::LeaveIfError(err);
       
   532 	DoSetClientConfigL();// added here instead of the CreateL()
       
   533 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   534 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   535 	TFourCC desiredFourCC = devSoundBuf().iDesiredFourCC;
       
   536 	TMMFState mode = devSoundBuf().iMode;
       
   537 	iAdapter->InitializeL(desiredFourCC, mode);
       
   538 	iBufferPlay = NULL;
       
   539 	iPlayErrorOccured = EFalse;
       
   540 	// Flag to queue any further request 
       
   541 	// but the message can be completed now
       
   542 	iOperationCompletePending = ETrue;
       
   543 	return ETrue;
       
   544 	}
       
   545 
       
   546 //
       
   547 // CMMFDevSoundSession::DoCancelInitialize
       
   548 // (other items were commented in a header).
       
   549 //
       
   550 TBool CMMFDevSoundSession::DoCancelInitializeL(const RMmfIpcMessage& aMessage)
       
   551 	{
       
   552 	TInt err=iAdapter->CancelInitialize();
       
   553 
       
   554 	if (err != KErrNone)
       
   555 		{
       
   556 		aMessage.Complete(err);
       
   557 		iOperationCompletePending = EFalse;
       
   558 		return ETrue;
       
   559 		}
       
   560 	else
       
   561 		{
       
   562 		iOperationCompletePending = ETrue;
       
   563 		}
       
   564 	return EFalse;
       
   565 	}
       
   566 
       
   567 //
       
   568 // CMMFDevSoundSession::DoCapabilitiesL
       
   569 // (other items were commented in a header).
       
   570 //
       
   571 TBool CMMFDevSoundSession::DoCapabilitiesL(const RMmfIpcMessage& aMessage)
       
   572 	{
       
   573 	TInt err = iAdapter->Capabilities(iDevSoundCapabilities);
       
   574 	if(err != KErrNone)
       
   575 		{
       
   576 		aMessage.Complete(err);
       
   577 		iOperationCompletePending = EFalse;
       
   578 		}
       
   579 	else
       
   580 		{
       
   581 		iOperationCompletePending = ETrue;
       
   582 		}
       
   583 	return EFalse;
       
   584 	}
       
   585 
       
   586 //
       
   587 // CMMFDevSoundSession::DoConfigL
       
   588 // (other items were commented in a header).
       
   589 //
       
   590 TBool CMMFDevSoundSession::DoConfigL(const RMmfIpcMessage& aMessage)
       
   591 	{
       
   592 	TMMFDevSoundProxySettings devSoundSet;
       
   593 	devSoundSet.iConfig = iAdapter->Config();
       
   594 	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
       
   595 	aMessage.WriteL(TInt(2),pckg);
       
   596 	return ETrue;
       
   597 	}
       
   598 
       
   599 //
       
   600 // CMMFDevSoundSession::DoSetConfigL
       
   601 // (other items were commented in a header).
       
   602 //
       
   603 TBool CMMFDevSoundSession::DoSetConfigL(const RMmfIpcMessage& aMessage)
       
   604 	{
       
   605 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   606 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   607 	TMMFCapabilities config = devSoundBuf().iConfig;
       
   608 	iAdapter->SetConfigL(config);
       
   609 	iOperationCompletePending = ETrue;
       
   610 	return EFalse;
       
   611 	}
       
   612 
       
   613 //
       
   614 // CMMFDevSoundSession::axVolumeL
       
   615 // (other items were commented in a header).
       
   616 //
       
   617 TBool CMMFDevSoundSession::DoMaxVolumeL(const RMmfIpcMessage& aMessage)
       
   618 	{
       
   619 	TMMFDevSoundProxySettings devSoundSet;
       
   620 	devSoundSet.iMaxVolume = iAdapter->MaxVolume();
       
   621 	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
       
   622 	aMessage.WriteL(TInt(2),pckg);
       
   623 	return ETrue;
       
   624 	}
       
   625 
       
   626 //
       
   627 // CMMFDevSoundSession::DoVolumeL
       
   628 // (other items were commented in a header).
       
   629 //
       
   630 TBool CMMFDevSoundSession::DoVolumeL(const RMmfIpcMessage& aMessage)
       
   631 	{
       
   632 	TMMFDevSoundProxySettings devSoundSet;
       
   633 	devSoundSet.iVolume = iAdapter->Volume();
       
   634 	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
       
   635 	aMessage.WriteL(TInt(2),pckg);
       
   636 	return ETrue;
       
   637 	}
       
   638 
       
   639 //
       
   640 // CMMFDevSoundSession::DoSetVolumeL
       
   641 // (other items were commented in a header).
       
   642 //
       
   643 TBool CMMFDevSoundSession::DoSetVolumeL(const RMmfIpcMessage& aMessage)
       
   644 	{
       
   645 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   646 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   647 	TInt volume = devSoundBuf().iVolume;
       
   648 	TBool asyncOperation;
       
   649 	User::LeaveIfError(iAdapter->SetVolume(volume, asyncOperation));
       
   650 	iOperationCompletePending = asyncOperation;
       
   651 	return !asyncOperation;
       
   652 	}
       
   653 
       
   654 //
       
   655 // CMMFDevSoundSession::DoMaxGainL
       
   656 // (other items were commented in a header).
       
   657 //
       
   658 TBool CMMFDevSoundSession::DoMaxGainL(const RMmfIpcMessage& aMessage)
       
   659 	{
       
   660 	TMMFDevSoundProxySettings devSoundSet;
       
   661 	devSoundSet.iMaxGain = iAdapter->MaxGain();
       
   662 	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
       
   663 	aMessage.WriteL(TInt(2),pckg);
       
   664 	return ETrue;
       
   665 	}
       
   666 
       
   667 //
       
   668 // CMMFDevSoundSession::DoGainL
       
   669 // (other items were commented in a header).
       
   670 //
       
   671 TBool CMMFDevSoundSession::DoGainL(const RMmfIpcMessage& aMessage)
       
   672 	{
       
   673 	TMMFDevSoundProxySettings devSoundSet;
       
   674 	devSoundSet.iGain = iAdapter->Gain();
       
   675 	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
       
   676 	aMessage.WriteL(TInt(2),pckg);
       
   677 	return ETrue;
       
   678 	}
       
   679 
       
   680 //
       
   681 // CMMFDevSoundSession::DoSetGainL
       
   682 // (other items were commented in a header).
       
   683 //
       
   684 TBool CMMFDevSoundSession::DoSetGainL(const RMmfIpcMessage& aMessage)
       
   685 	{
       
   686 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   687 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   688 	TInt gain = devSoundBuf().iGain;
       
   689 	TBool asyncOperation;
       
   690 	User::LeaveIfError(iAdapter->SetGain(gain, asyncOperation));
       
   691 	iOperationCompletePending = asyncOperation;
       
   692 	return !asyncOperation;
       
   693 	}
       
   694 
       
   695 //
       
   696 // CMMFDevSoundSession::DoGetPlayBalanceL
       
   697 // (other items were commented in a header).
       
   698 //
       
   699 TBool CMMFDevSoundSession::DoGetPlayBalanceL(const RMmfIpcMessage& aMessage)
       
   700 	{
       
   701 	TMMFDevSoundProxySettings devSoundSet;
       
   702 	iAdapter->GetPlayBalanceL(devSoundSet.iLeftPercentage, devSoundSet.iRightPercentage);
       
   703 	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
       
   704 	aMessage.WriteL(TInt(2),pckg);
       
   705 	return ETrue;
       
   706 	}
       
   707 
       
   708 //
       
   709 // CMMFDevSoundSession::DoSetPlayBalanceL
       
   710 // (other items were commented in a header).
       
   711 //
       
   712 TBool CMMFDevSoundSession::DoSetPlayBalanceL(const RMmfIpcMessage& aMessage)
       
   713 	{
       
   714 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   715 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   716 	TInt leftPercentage = devSoundBuf().iLeftPercentage;
       
   717 	TInt rightPercentage = devSoundBuf().iRightPercentage;
       
   718 	TBool asyncOperation;
       
   719 	iAdapter->SetPlayBalanceL(leftPercentage, rightPercentage, asyncOperation);
       
   720 	iOperationCompletePending = asyncOperation;
       
   721 	return !asyncOperation;
       
   722 	}
       
   723 
       
   724 //
       
   725 // CMMFDevSoundSession::DoGetRecordBalanceL
       
   726 // (other items were commented in a header).
       
   727 //
       
   728 TBool CMMFDevSoundSession::DoGetRecordBalanceL(const RMmfIpcMessage& aMessage)
       
   729 	{
       
   730 	TMMFDevSoundProxySettings devSoundSet;
       
   731 	iAdapter->GetRecordBalanceL(devSoundSet.iLeftPercentage, devSoundSet.iRightPercentage);
       
   732 	TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
       
   733 	aMessage.WriteL(TInt(2),pckg);
       
   734 	return ETrue;
       
   735 	}
       
   736 
       
   737 //
       
   738 // CMMFDevSoundSession::DoSetRecordBalanceL
       
   739 // (other items were commented in a header).
       
   740 //
       
   741 TBool CMMFDevSoundSession::DoSetRecordBalanceL(const RMmfIpcMessage& aMessage)
       
   742 	{
       
   743 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   744 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   745 	TInt leftPercentage = devSoundBuf().iLeftPercentage;
       
   746 	TInt rightPercentage = devSoundBuf().iRightPercentage;
       
   747 	TBool asyncOperation;
       
   748 	iAdapter->SetRecordBalanceL(leftPercentage, rightPercentage, asyncOperation);
       
   749 	iOperationCompletePending = asyncOperation;
       
   750 	return !asyncOperation;
       
   751 	}
       
   752 
       
   753 //
       
   754 // CMMFDevSoundSession::DoPlayInitL
       
   755 // (other items were commented in a header).
       
   756 //
       
   757 TBool CMMFDevSoundSession::DoPlayInitL(const RMmfIpcMessage& /*aMessage*/)
       
   758 	{
       
   759 	iAdapter->PlayInitL();
       
   760 	iOperationCompletePending = ETrue;
       
   761 	return ETrue;
       
   762 	}
       
   763 
       
   764 //
       
   765 // CMMFDevSoundSession::DoRecordInitL
       
   766 // (other items were commented in a header).
       
   767 //
       
   768 TBool CMMFDevSoundSession::DoRecordInitL(const RMmfIpcMessage& /*aMessage*/)
       
   769 	{
       
   770 	iAdapter->RecordInitL();
       
   771 	iOperationCompletePending = ETrue;
       
   772 	return ETrue;
       
   773 	}
       
   774 
       
   775 //
       
   776 // CMMFDevSoundSession::DoPlayDataL
       
   777 // (other items were commented in a header).
       
   778 //
       
   779 TBool CMMFDevSoundSession::DoPlayDataL(const RMmfIpcMessage& aMessage)
       
   780 	{
       
   781 	SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Enter"));
       
   782 
       
   783 	if( iPlayErrorOccured )
       
   784 		{
       
   785 		SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Ignore and Exit"));
       
   786 		return ETrue;
       
   787 		}
       
   788 
       
   789 	TMMFDevSoundProxyHwBufPckg devSoundBuf;
       
   790 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   791 	iBufferPlay->SetLastBuffer(devSoundBuf().iLastBuffer);
       
   792 
       
   793 	TPtr8 dataPtr(iChunk.Base(), devSoundBuf().iBufferSize, devSoundBuf().iBufferSize);
       
   794 	// Copy data over from chunk
       
   795 	iBufferPlay->Data().Copy(dataPtr);
       
   796 	iAdapter->PlayData();
       
   797 	SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::DoPlayDataL - Exit"));
       
   798 	return ETrue;
       
   799 	}
       
   800 
       
   801 //
       
   802 // CMMFDevSoundSession::DoRecordDataL
       
   803 // (other items were commented in a header).
       
   804 //
       
   805 TBool CMMFDevSoundSession::DoRecordDataL(const RMmfIpcMessage& /*aMessage*/)
       
   806 	{
       
   807 	iAdapter->RecordData();
       
   808 	return ETrue;
       
   809 	}
       
   810 
       
   811 //
       
   812 // CMMFDevSoundSession::DoStopL
       
   813 // (other items were commented in a header).
       
   814 //
       
   815 TBool CMMFDevSoundSession::DoStopL(const RMmfIpcMessage& /*aMessage*/)
       
   816 	{
       
   817 	// Sometimes Stop is not involved on a commit cycle
       
   818 	TBool completed = iAdapter->Stop();
       
   819 	if (completed)
       
   820 		{
       
   821 		iQueuedRequests.Reset();
       
   822 		FlushEventQueue(); // completed returned here means we were idle to start with. TODO could possibly skip this flush
       
   823 		iChunk.Close();
       
   824 		}
       
   825 	iOperationCompletePending = !completed;
       
   826 	return completed;
       
   827 	}
       
   828 
       
   829 //
       
   830 // CMMFDevSoundSession::DoPauseL
       
   831 // (other items were commented in a header).
       
   832 //
       
   833 TBool CMMFDevSoundSession::DoPauseL(const RMmfIpcMessage& /*aMessage*/)
       
   834 	{
       
   835 	User::LeaveIfError(iAdapter->Pause());
       
   836 	iOperationCompletePending = ETrue;
       
   837 	return EFalse;
       
   838 	}
       
   839 
       
   840 //
       
   841 // CMMFDevSoundSession::DoPlayToneL
       
   842 // (other items were commented in a header).
       
   843 //
       
   844 TBool CMMFDevSoundSession::DoPlayToneL(const RMmfIpcMessage& aMessage)
       
   845 	{
       
   846 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   847 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   848 	TInt frequency = devSoundBuf().iFrequencyOne;
       
   849 	TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration);
       
   850 	iAdapter->PlayToneL(frequency, duration);
       
   851 	iOperationCompletePending = ETrue;
       
   852 	return ETrue;
       
   853 	}
       
   854 
       
   855 //
       
   856 // CMMFDevSoundSession::DoPlayDualToneL
       
   857 // (other items were commented in a header).	
       
   858 //
       
   859 TBool CMMFDevSoundSession::DoPlayDualToneL(const RMmfIpcMessage& aMessage)
       
   860 	{
       
   861 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   862 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   863 	TInt frequencyOne = devSoundBuf().iFrequencyOne;
       
   864 	TInt frequencyTwo = devSoundBuf().iFrequencyTwo;
       
   865 	TTimeIntervalMicroSeconds duration(devSoundBuf().iDuration);
       
   866 	iAdapter->PlayDualToneL(frequencyOne, frequencyTwo, duration);
       
   867 	iOperationCompletePending = ETrue;
       
   868 	return ETrue;
       
   869 	}
       
   870 
       
   871 //
       
   872 // CMMFDevSoundSession::DoPlayDTMFStringL
       
   873 // (other items were commented in a header).
       
   874 //
       
   875 TBool CMMFDevSoundSession::DoPlayDTMFStringL(const RMmfIpcMessage& aMessage)
       
   876 	{
       
   877 	TInt dtmfLength = aMessage.GetDesLength(2);
       
   878 	
       
   879 	if(iDtmfString)
       
   880 		{
       
   881 		delete iDtmfString;
       
   882 		iDtmfString = NULL;
       
   883 		}
       
   884 
       
   885 	iDtmfString = HBufC::NewL(dtmfLength);
       
   886 	TPtr dtmfPtr = iDtmfString->Des();
       
   887 	aMessage.ReadL(TInt(2), dtmfPtr);
       
   888 
       
   889 	iAdapter->PlayDTMFStringL(*iDtmfString);
       
   890 	iOperationCompletePending = ETrue;
       
   891 	return ETrue;
       
   892 	}
       
   893 
       
   894 //
       
   895 // CMMFDevSoundSession::DoPlayToneSequenceL
       
   896 // (other items were commented in a header).
       
   897 //
       
   898 TBool CMMFDevSoundSession::DoPlayToneSequenceL(const RMmfIpcMessage& aMessage)
       
   899 	{
       
   900 	TInt toneLength = aMessage.GetDesLength(1);
       
   901 
       
   902 	if(iToneSeqBuf)
       
   903 		{
       
   904 		delete iToneSeqBuf;
       
   905 		iToneSeqBuf = NULL;
       
   906 		}
       
   907 
       
   908 	iToneSeqBuf = HBufC8::NewL(toneLength);
       
   909 	TPtr8 toneSeqPtr = iToneSeqBuf->Des();
       
   910 	aMessage.ReadL(TInt(1), toneSeqPtr);
       
   911 
       
   912 	iAdapter->PlayToneSequenceL(*iToneSeqBuf);
       
   913 	iOperationCompletePending = ETrue;
       
   914 	return ETrue;
       
   915 	}
       
   916 
       
   917 //
       
   918 // CMMFDevSoundSession::DoPlayFixedSequenceL
       
   919 // (other items were commented in a header).
       
   920 //
       
   921 TBool CMMFDevSoundSession::DoPlayFixedSequenceL(const RMmfIpcMessage& aMessage)
       
   922 	{
       
   923 	TPckgBuf<TInt> buf;
       
   924 	aMessage.ReadL(TInt(1),buf);
       
   925 	TInt seqNum = buf();
       
   926 
       
   927 	iAdapter->PlayFixedSequenceL(seqNum);
       
   928 	iOperationCompletePending = ETrue;
       
   929 	return ETrue;
       
   930 	}
       
   931 
       
   932 //
       
   933 // CMMFDevSoundSession::DoSetDTMFLengthsL
       
   934 // (other items were commented in a header).
       
   935 //
       
   936 TBool CMMFDevSoundSession::DoSetDTMFLengthsL(const RMmfIpcMessage& aMessage)
       
   937 	{
       
   938 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   939 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   940 	TTimeIntervalMicroSeconds32 toneOnLength = devSoundBuf().iToneOnLength;
       
   941 	TTimeIntervalMicroSeconds32 toneOffLength = devSoundBuf().iToneOffLength;
       
   942 	TTimeIntervalMicroSeconds32 pauseLength = devSoundBuf().iPauseLength;
       
   943 	User::LeaveIfError(iAdapter->SetDTMFLengths(toneOnLength, toneOffLength, pauseLength));
       
   944 	return ETrue;
       
   945 	}
       
   946 
       
   947 //
       
   948 // CMMFDevSoundSession::DoSetVolumeRampL
       
   949 // (other items were commented in a header).
       
   950 //
       
   951 TBool CMMFDevSoundSession::DoSetVolumeRampL(const RMmfIpcMessage& aMessage)
       
   952 	{
       
   953 	TMMFDevSoundProxySettingsPckg devSoundBuf;
       
   954 	aMessage.ReadL(TInt(1),devSoundBuf);
       
   955 	TTimeIntervalMicroSeconds duration = devSoundBuf().iDuration;
       
   956 	User::LeaveIfError(iAdapter->SetVolumeRamp(duration));
       
   957 	iOperationCompletePending = EFalse; // Volume ramp doesn't result on commit
       
   958 	return ETrue; // operation complete
       
   959 	}
       
   960 
       
   961 //
       
   962 // CMMFDevSoundSession::DoGetSupportedInputDataTypesL
       
   963 // (other items were commented in a header).
       
   964 //
       
   965 TBool CMMFDevSoundSession::DoGetSupportedInputDataTypesL(
       
   966 							const RMmfIpcMessage& aMessage)
       
   967 	{
       
   968 	iArray.Reset();
       
   969 
       
   970 	TMMFPrioritySettingsPckg prioritySetBuf;
       
   971 	aMessage.ReadL(TInt(1),prioritySetBuf);
       
   972 	TMMFPrioritySettings prioritySet = prioritySetBuf();
       
   973 
       
   974 	iAdapter->GetSupportedInputDataTypesL(iArray, prioritySet);
       
   975 
       
   976 	TPckgBuf<TInt> pckg;
       
   977 	pckg() = iArray.Count();
       
   978 	aMessage.WriteL(TInt(2),pckg);
       
   979 
       
   980 	return ETrue;
       
   981 	}
       
   982 
       
   983 //
       
   984 // CMMFDevSoundSession::DoGetSupportedOutputDataTypesL
       
   985 // (other items were commented in a header).
       
   986 //
       
   987 TBool CMMFDevSoundSession::DoGetSupportedOutputDataTypesL(
       
   988 							const RMmfIpcMessage& aMessage)
       
   989 	{
       
   990 	iArray.Reset();
       
   991 
       
   992 	TMMFPrioritySettingsPckg prioritySetBuf;
       
   993 	aMessage.ReadL(TInt(1),prioritySetBuf);
       
   994 	TMMFPrioritySettings prioritySet = prioritySetBuf();
       
   995 
       
   996 	iAdapter->GetSupportedOutputDataTypesL(iArray, prioritySet);
       
   997 
       
   998 	TPckgBuf<TInt> pckg;
       
   999 	pckg() = iArray.Count();
       
  1000 	aMessage.WriteL(TInt(2),pckg);
       
  1001 
       
  1002 	return ETrue;
       
  1003 	}
       
  1004 
       
  1005 //
       
  1006 // CMMFDevSoundSession::DoSamplesRecordedL
       
  1007 // (other items were commented in a header).
       
  1008 //
       
  1009 TBool CMMFDevSoundSession::DoSamplesRecordedL(const RMmfIpcMessage& aMessage)
       
  1010 	{
       
  1011 	TPckgBuf<TInt> pckg;
       
  1012 	pckg() = iAdapter->SamplesRecorded();
       
  1013 	aMessage.WriteL(TInt(2),pckg);
       
  1014 	return ETrue;
       
  1015 	}
       
  1016 
       
  1017 //
       
  1018 // CMMFDevSoundSession::DoSamplesPlayedL
       
  1019 // (other items were commented in a header).
       
  1020 //
       
  1021 TBool CMMFDevSoundSession::DoSamplesPlayedL(const RMmfIpcMessage& aMessage)
       
  1022 	{
       
  1023 	TPckgBuf<TInt> pckg;
       
  1024 	pckg() = iAdapter->SamplesPlayed();
       
  1025 	aMessage.WriteL(TInt(2),pckg);
       
  1026 	return ETrue;
       
  1027 	}
       
  1028 
       
  1029 //
       
  1030 // CMMFDevSoundSession::DoSetToneRepeatsL
       
  1031 // (other items were commented in a header).
       
  1032 //
       
  1033 TBool CMMFDevSoundSession::DoSetToneRepeatsL(const RMmfIpcMessage& aMessage)
       
  1034 	{
       
  1035 	TPckgBuf<TInt> countRepeat;
       
  1036 	aMessage.ReadL(TInt(1),countRepeat);
       
  1037 
       
  1038 	TPckgBuf<TTimeIntervalMicroSeconds> repeatTS;
       
  1039 	aMessage.ReadL(TInt(2),repeatTS);
       
  1040 	User::LeaveIfError(iAdapter->SetToneRepeats(countRepeat(), repeatTS()));
       
  1041 	
       
  1042 	return ETrue;
       
  1043 	}
       
  1044 
       
  1045 //
       
  1046 // CMMFDevSoundSession::DoSetPrioritySettingsL
       
  1047 // (other items were commented in a header).
       
  1048 //
       
  1049 TBool CMMFDevSoundSession::DoSetPrioritySettingsL(
       
  1050 						const RMmfIpcMessage& aMessage)
       
  1051 	{
       
  1052 	TPckgBuf<TMMFPrioritySettings> prioritySet;
       
  1053 	aMessage.ReadL(TInt(1),prioritySet);
       
  1054 
       
  1055 	User::LeaveIfError(iAdapter->SetPrioritySettings(prioritySet()));
       
  1056 	iOperationCompletePending = EFalse;
       
  1057 	return ETrue;
       
  1058 	}
       
  1059 
       
  1060 //
       
  1061 // CMMFDevSoundSession::DoFixedSequenceCountL
       
  1062 // (other items were commented in a header).
       
  1063 //
       
  1064 TBool CMMFDevSoundSession::DoFixedSequenceCountL(
       
  1065 					const RMmfIpcMessage& aMessage)
       
  1066 	{
       
  1067 	TPckgBuf<TInt> fixSeqCountPckg;
       
  1068 	TInt fixSeqCount = iAdapter->FixedSequenceCount();
       
  1069 	fixSeqCountPckg = fixSeqCount;
       
  1070 
       
  1071 	aMessage.WriteL(TInt(2),fixSeqCountPckg);
       
  1072 	return ETrue;
       
  1073 	}
       
  1074 
       
  1075 
       
  1076 //
       
  1077 // CMMFDevSoundSession::DoCopyFourCCArrayDataL
       
  1078 // (other items were commented in a header).
       
  1079 //
       
  1080 TBool CMMFDevSoundSession::DoCopyFourCCArrayDataL(
       
  1081 						const RMmfIpcMessage& aMessage)
       
  1082 	{
       
  1083 	const TInt KBufExpandSize8 = 8;//two TInts
       
  1084 	CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
       
  1085 	CleanupStack::PushL(dataCopyBuffer);
       
  1086 	RBufWriteStream stream;
       
  1087 	stream.Open(*dataCopyBuffer);
       
  1088 	CleanupClosePushL(stream);
       
  1089 	
       
  1090 	TInt i = 0;
       
  1091 	TInt count = iArray.Count();
       
  1092 	
       
  1093 	while (i < count)
       
  1094 		{
       
  1095 		stream.WriteInt32L(iArray[i].FourCC());
       
  1096 		i++;
       
  1097 		}
       
  1098 	aMessage.WriteL(TInt(2), dataCopyBuffer->Ptr(0));
       
  1099 	stream.Close();
       
  1100 	CleanupStack::PopAndDestroy(&stream);
       
  1101 	CleanupStack::PopAndDestroy(dataCopyBuffer);
       
  1102 	return ETrue;
       
  1103 	}
       
  1104 
       
  1105 
       
  1106 //
       
  1107 // CMMFDevSoundSession::DoBufferToBeFilledDataL
       
  1108 // (other items were commented in a header).
       
  1109 //
       
  1110 TBool CMMFDevSoundSession::DoBufferToBeFilledDataL(
       
  1111 							const RMmfIpcMessage& aMessage)
       
  1112 	{
       
  1113 	// if CMMFDevSoundSession::PlayError() has been called, RChunk would have got closed.
       
  1114 	// Need to check if Chunk Handle is still valid. If it is not,complete the message immediately and send a error to the Client.
       
  1115 	if(!iChunk.Handle())
       
  1116 		{
       
  1117 		aMessage.Complete(KErrBadHandle);
       
  1118 		return EFalse;	
       
  1119 		}
       
  1120 	TPckgBuf<TInt> requestChunkBuf;
       
  1121 	MmfMessageUtil::Read(aMessage, TInt(1), requestChunkBuf);
       
  1122 	TBool requestChunk = requestChunkBuf();
       
  1123 	if (requestChunk)
       
  1124 		{
       
  1125 		// if the client requests, always do EOpen
       
  1126 		iHwBufPckgFill().iChunkOp = EOpen;
       
  1127 		}
       
  1128 	TInt err = MmfMessageUtil::Write(aMessage, TInt(2), iHwBufPckgFill);
       
  1129 	if ( (err == KErrNone) && (iHwBufPckgFill().iChunkOp == EOpen) )
       
  1130 		{
       
  1131 		aMessage.Complete(iChunk);
       
  1132 		}
       
  1133 	else
       
  1134 		{
       
  1135 		aMessage.Complete(err);
       
  1136 		}
       
  1137 	return EFalse;
       
  1138 	}
       
  1139 
       
  1140 // CMMFDevSoundSession::DoBufferToBeEmptiedDataL
       
  1141 // (other items were commented in a header).
       
  1142 //
       
  1143 TBool CMMFDevSoundSession::DoBufferToBeEmptiedDataL(
       
  1144 						const RMmfIpcMessage& aMessage)
       
  1145 	{
       
  1146 	// if CMMFDevSoundSession::RecordError() has been called, RChunk would have got closed.
       
  1147 	// Need to check if Chunk Handle is still valid. If it is not,complete the message immediately and send a error to the Client.
       
  1148 	if(!iChunk.Handle())
       
  1149 		{
       
  1150 		aMessage.Complete(KErrBadHandle);
       
  1151 		return EFalse;	
       
  1152 		}
       
  1153 	
       
  1154 	TInt err = MmfMessageUtil::Write(aMessage, TInt(2), iHwBufPckgEmpty);
       
  1155 	if ( (err == KErrNone) && (iHwBufPckgEmpty().iChunkOp == EOpen) )
       
  1156 		{
       
  1157 		aMessage.Complete(iChunk);
       
  1158 		}
       
  1159 	else
       
  1160 		{
       
  1161 		aMessage.Complete(err);
       
  1162 		}
       
  1163 	return EFalse;
       
  1164 	}
       
  1165 
       
  1166 //
       
  1167 // CMMFDevSoundSession::DoEmptyBuffersL
       
  1168 // (other items were commented in a header).
       
  1169 //
       
  1170 
       
  1171 TBool CMMFDevSoundSession::DoEmptyBuffersL(const RMmfIpcMessage& aMessage)
       
  1172 	{
       
  1173 	TInt err = KErrNone;
       
  1174 	FilterQueueEvent(EMMFDevSoundProxyBTBFEvent);
       
  1175 	// This is now asynchronous
       
  1176 	err = iAdapter->EmptyBuffers();
       
  1177 	if (err != KErrNone)
       
  1178 		{
       
  1179 		aMessage.Complete(err);
       
  1180 		return EFalse;
       
  1181 		}
       
  1182 	iOperationCompletePending = ETrue;
       
  1183 	return EFalse;
       
  1184 	}
       
  1185 //
       
  1186 // CMMFDevSoundSession::DoGetTimePlayedL
       
  1187 // (other items were commented in a header).
       
  1188 //
       
  1189 TBool CMMFDevSoundSession::DoGetTimePlayedL(const RMmfIpcMessage& aMessage)
       
  1190 	{
       
  1191 	TInt err = KErrNone;
       
  1192 	TTimeIntervalMicroSeconds time(0);
       
  1193 	TPckgBuf<TTimeIntervalMicroSeconds> timePckg(time);
       
  1194 	err = iAdapter->GetTimePlayed(timePckg());
       
  1195 	if (err != KErrNone)
       
  1196 		{
       
  1197 		aMessage.Complete(err);
       
  1198 		return EFalse;		
       
  1199 		}
       
  1200 	aMessage.WriteL(TInt(2),timePckg);
       
  1201 	return ETrue;
       
  1202 	}
       
  1203 
       
  1204 TBool CMMFDevSoundSession::DoQueryResumeSupportedL(const RMmfIpcMessage& aMessage)
       
  1205 	{
       
  1206 	TBool isSupported = EFalse;
       
  1207 	TPckgBuf<TBool> isSupportedPckg(isSupported);
       
  1208 	isSupportedPckg() = iAdapter->IsResumeSupported();
       
  1209 	aMessage.WriteL(TInt(2),isSupportedPckg);
       
  1210 	return ETrue;
       
  1211 	}
       
  1212 
       
  1213 TBool CMMFDevSoundSession::DoResumeL(const RMmfIpcMessage& /*aMessage*/)
       
  1214 	{
       
  1215 	User::LeaveIfError( iAdapter->Resume() );
       
  1216 	iOperationCompletePending = ETrue;
       
  1217 	FilterQueueEvent(EMMFDevSoundProxyPausedRecordCompleteEvent);
       
  1218 	return EFalse;
       
  1219 	}
       
  1220 
       
  1221 TBool CMMFDevSoundSession::DoPrepareCloseL(const RMmfIpcMessage& /*aMessage*/)
       
  1222 	{
       
  1223 	TBool complete = iAdapter->CloseDevSound();
       
  1224 	if(!complete)
       
  1225 		{
       
  1226 		iOperationCompletePending = ETrue;	
       
  1227 		}
       
  1228 	return complete;
       
  1229 	}
       
  1230 
       
  1231 
       
  1232 TBool CMMFDevSoundSession::DoCustomCommandL(const RMmfIpcMessage& aMessage)
       
  1233 	{
       
  1234 	TInt retVal = KErrNone;
       
  1235 	TRAPD(err, retVal = iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
       
  1236 	if (err != KErrNone)
       
  1237 		{
       
  1238 		// the framework left with an error condition
       
  1239 		// so we complete the message with this error
       
  1240 		// irrespective of whether its a Sync or Async custom command
       
  1241 		aMessage.Complete(err);
       
  1242 		}
       
  1243 	else
       
  1244 		{
       
  1245 		TInt messageType = aMessage.Function();
       
  1246 		if ((messageType == EMMFDevSoundProxySyncCustomCommand) ||
       
  1247 			(messageType == EMMFDevSoundProxySyncCustomCommandResult))
       
  1248 			{
       
  1249 			// If its a sync custom command
       
  1250 			// we can pass back valid values here since command
       
  1251 			// has been handled by the DeMux framework
       
  1252 			aMessage.Complete(retVal);	
       
  1253 			}
       
  1254 		}
       
  1255 	
       
  1256 	// we complete our own message so don't need the framework to do so
       
  1257 	return EFalse;
       
  1258 	}
       
  1259 	
       
  1260 
       
  1261 //
       
  1262 // CMMFDevSoundSession::CMMFDevSoundSession
       
  1263 // (other items were commented in a header).
       
  1264 //
       
  1265 CMMFDevSoundSession::CMMFDevSoundSession() :
       
  1266 	iSetClientConfigApplied (EFalse)
       
  1267 	{
       
  1268 	}
       
  1269 
       
  1270 //
       
  1271 // CMMFDevSoundSession::~CMMFDevSoundSession
       
  1272 // (other items were commented in a header).
       
  1273 //
       
  1274 CMMFDevSoundSession::~CMMFDevSoundSession()
       
  1275 	{
       
  1276 	delete iAsyncQueueStart;
       
  1277 	// clear the array of custom interfaces
       
  1278 	TInt count = iCustomInterfaceArray.Count();
       
  1279 	for (TInt i = 0; i < count; i++)
       
  1280 		{
       
  1281 		// we could have already deleted interfaces without
       
  1282 		// removing them from the array so check for this
       
  1283 		// and only delete release plugin if non-null
       
  1284 		MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface;
       
  1285 		if (ptr)
       
  1286 			{
       
  1287 			iCustomInterfaceArray[i].iInterface->Release();	
       
  1288 			}
       
  1289 		}
       
  1290 	iCustomInterfaceArray.Reset();
       
  1291 	iCustomInterfaceArray.Close();
       
  1292 		
       
  1293 	delete iDeMuxUtility;
       
  1294 	
       
  1295 	if (iCIExtension)
       
  1296 		{
       
  1297 		iCIExtension->Release();
       
  1298 		iCIExtension = NULL;
       
  1299 		}
       
  1300 
       
  1301 	iMsgQueue.Close();
       
  1302 	iArray.Close();
       
  1303 	iQueuedRequests.Close();
       
  1304 	delete iDtmfString;
       
  1305 	delete iToneSeqBuf;
       
  1306 	delete iAdapter;
       
  1307 	delete iClosingWait;
       
  1308 
       
  1309 	CMMFDevSoundServer* server =
       
  1310 			const_cast<CMMFDevSoundServer*>(
       
  1311 			static_cast<const CMMFDevSoundServer*>(Server()));
       
  1312 
       
  1313 	if (server)
       
  1314 		{
       
  1315 		server->DecrementSessionId();
       
  1316 		}
       
  1317 
       
  1318 //	delete iCustomCommandParserManager;
       
  1319 //	delete iMMFObjectContainer;
       
  1320 
       
  1321 	// Close chunk
       
  1322 	iChunk.Close();
       
  1323 	}
       
  1324 
       
  1325 //
       
  1326 // CMMFDevSoundSession::FlushEventQueue()
       
  1327 //
       
  1328 void CMMFDevSoundSession::FlushEventQueue()
       
  1329 	{
       
  1330 	if(iMsgQueue.Handle() != 0)
       
  1331 		{
       
  1332 		TMMFDevSoundQueueItem queueItem;
       
  1333 		TInt err = KErrNone;
       
  1334 		while(err != KErrUnderflow)
       
  1335 			{
       
  1336 			err = iMsgQueue.Receive(queueItem);
       
  1337 			}
       
  1338 		}	
       
  1339 	}
       
  1340 
       
  1341 void CMMFDevSoundSession::FilterQueueEvent(TMMFDevSoundProxyRequest aRequest)
       
  1342 	{
       
  1343 	if(iMsgQueue.Handle() != 0)
       
  1344 		{
       
  1345 		// Pop and push events result at the queue 
       
  1346 		// can be seen as "circular list"
       
  1347 		// set a mark to traverse it safely 
       
  1348 		TMMFDevSoundQueueItem markItem;
       
  1349 		markItem.iRequest = EMMFDevSoundProxyMarkEvent;
       
  1350 		// assumes sufficient space in the queue
       
  1351 		TInt err = iMsgQueue.Send(markItem);
       
  1352 		__ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg));
       
  1353 		
       
  1354 		while(ETrue)
       
  1355 			{
       
  1356 			// At least the markEvent is at the queue so ignore the error
       
  1357 			TMMFDevSoundQueueItem queueItem;
       
  1358 			err = iMsgQueue.Receive(queueItem);
       
  1359 			if(queueItem.iRequest == EMMFDevSoundProxyMarkEvent)
       
  1360 				{
       
  1361 				break;
       
  1362 				}
       
  1363 			// Look for the specific event
       
  1364 			else if(queueItem.iRequest != aRequest)
       
  1365 				{
       
  1366 				// assumes sufficient space in the queue
       
  1367 				err = iMsgQueue.Send(queueItem);
       
  1368 				}
       
  1369 			}
       
  1370 		}
       
  1371 	}
       
  1372 
       
  1373 //
       
  1374 // CMMFDevSoundSession::Disconnect
       
  1375 // (other items were commented in a header).
       
  1376 //
       
  1377 void CMMFDevSoundSession::Disconnect(const RMessage2& aMessage)
       
  1378 	{
       
  1379 	TBool complete = iAdapter->CloseDevSound();
       
  1380 	if(!complete)
       
  1381 		{
       
  1382 		iRequestBeingServiced.SetMessage(aMessage);
       
  1383 		iOperationCompletePending = ETrue;
       
  1384 		iClosingWait->Start();
       
  1385 		}
       
  1386 	CSession2::Disconnect(aMessage);
       
  1387 	}
       
  1388 
       
  1389 
       
  1390 //
       
  1391 // CMMFDevSoundSession::NewL
       
  1392 // (other items were commented in a header).
       
  1393 //
       
  1394 CMMFDevSoundSession* CMMFDevSoundSession::NewL(MGlobalProperties& aGlobalProperties)
       
  1395 	{
       
  1396 	CMMFDevSoundSession* self = new (ELeave) CMMFDevSoundSession;
       
  1397 	CleanupStack::PushL(self);
       
  1398 	self->ConstructL(aGlobalProperties);
       
  1399 	CleanupStack::Pop(self);
       
  1400 	return self;
       
  1401 	}
       
  1402 
       
  1403 //
       
  1404 // CMMFDevSoundSession::ConstructL
       
  1405 // (other items were commented in a header).
       
  1406 //
       
  1407 void CMMFDevSoundSession::ConstructL(MGlobalProperties& aGlobalProperties)
       
  1408 	{
       
  1409 	iAdapter = CMMFDevSoundAdaptation::NewL(*this, aGlobalProperties);
       
  1410 
       
  1411 	iClosingWait = new(ELeave) CActiveSchedulerWait();
       
  1412 	
       
  1413 	// Create the Custom Interface DeMux Utility
       
  1414 	iDeMuxUtility = CMMFDevSoundCIDeMuxUtility::NewL(this);
       
  1415 	
       
  1416 	// Create the Custom Interface extension
       
  1417 	TUid implUid = {KMmfUidCIServerExtensionImpl};
       
  1418 	TInt uidAsInteger = implUid.iUid;
       
  1419 	const TInt KCIExtTempBufferSize = 20;
       
  1420 	TBuf8<KCIExtTempBufferSize> tempBuffer;
       
  1421 	tempBuffer.Num(uidAsInteger, EHex);
       
  1422 	TUid interfaceUid = {KUidDevSoundCIServerExtension};
       
  1423 	TUid destructorKey;
       
  1424 	TRAPD(err, iCIExtension = static_cast<MDevSoundCIServerExtension*>
       
  1425 		 (MmPluginUtils::CreateImplementationL(interfaceUid, destructorKey, tempBuffer, KRomOnlyResolverUid)));
       
  1426 	if (KErrNotSupported == err)
       
  1427 		{
       
  1428 		iCIExtension = NULL;
       
  1429 		}
       
  1430 	else
       
  1431 		{
       
  1432 		User::LeaveIfError(err);
       
  1433 		}
       
  1434 	if (iCIExtension)
       
  1435 		{
       
  1436 		// Extension exists. Complete the setup
       
  1437 		iCIExtension->PassDestructorKey(destructorKey);
       
  1438 		User::LeaveIfError(iCIExtension->Setup(*this));
       
  1439 		}
       
  1440 
       
  1441 	iQueuedRequests.ReserveL(KMaxQueueRequest);
       
  1442 	iAsyncQueueStart = new (ELeave) CAsyncCallBack(CActive::EPriorityStandard);
       
  1443 	TCallBack asyncCallback(AsyncQueueStartCallback, this);
       
  1444 	iAsyncQueueStart->Set(asyncCallback);
       
  1445 	}
       
  1446 
       
  1447 // CMMFDevSoundSession::InitializeComplete
       
  1448 // (other items were commented in a header).
       
  1449 //
       
  1450 void CMMFDevSoundSession::InitializeComplete(TInt aError)
       
  1451 	{
       
  1452 	// this may be a re-initialization and so we need to
       
  1453 	// re-get our custom interfaces on the DeMux plugins
       
  1454 	TInt count = iCustomInterfaceArray.Count();
       
  1455 	for (TInt i = 0; i < count; i++)
       
  1456 		{
       
  1457 		// we could have already deleted interfaces without
       
  1458 		// removing them from the array so check for this
       
  1459 		// and only refresh plugin if non-null
       
  1460 		MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface;
       
  1461 		if (ptr)
       
  1462 			{
       
  1463 			// we can't keep track of..
       
  1464 			// 1. where a custom interface is implemented
       
  1465 			// 2. the uid of the custom interface to be refreshed
       
  1466 			// so assume all have to be refreshed
       
  1467 			TRAPD(err, ptr->RefreshL());	
       
  1468 			
       
  1469 			// Error indicates this is no longer a valid interface
       
  1470 			if (err != KErrNone)
       
  1471 				{
       
  1472 				TMMFEvent event;
       
  1473 				TMMFDevSoundQueueItem item;
       
  1474 				item.iRequest = EMMFDevSoundCustomCommandCloseMuxDemuxPair;
       
  1475 				item.iErrorCode = err;
       
  1476 				event.iEventType.iUid = i+1;
       
  1477 				item.iEventPckg() = event;
       
  1478 				TInt lErr = iMsgQueue.Send(item);
       
  1479 				__ASSERT_DEBUG(lErr == KErrNone, Panic(EMsgQueueFailedToSendMsg));
       
  1480 
       
  1481 // NB proper panic code required here for this part.
       
  1482 				}
       
  1483 			}
       
  1484 		}
       
  1485 	TMMFDevSoundQueueItem item;
       
  1486 	item.iRequest = EMMFDevSoundProxyICEvent;
       
  1487 	item.iErrorCode = aError;
       
  1488 	// assumes sufficient space in the queue so ignores the return value
       
  1489 	iMsgQueue.Send(item); 
       
  1490 	}
       
  1491 
       
  1492 // 
       
  1493 // CMMFDevSoundSession::ToneFinished
       
  1494 // (other items were commented in a header).
       
  1495 //
       
  1496 void CMMFDevSoundSession::ToneFinished(TInt aError)
       
  1497 	{
       
  1498 	TMMFDevSoundQueueItem item;
       
  1499 	item.iRequest = EMMFDevSoundProxyTFEvent;
       
  1500 	item.iErrorCode = aError;
       
  1501 	// assumes sufficient space in the queue so ignores the return value
       
  1502 	iMsgQueue.Send(item);
       
  1503 	}
       
  1504 
       
  1505 //
       
  1506 // CMMFDevSoundSession::BufferToBeFilled
       
  1507 // (other items were commented in a header).
       
  1508 //
       
  1509 void CMMFDevSoundSession::BufferToBeFilled(CMMFBuffer* aBuffer)
       
  1510 	{
       
  1511 	SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x]::BufferToBeFilled - Enter"));
       
  1512 
       
  1513 	// Set play error flag to false 
       
  1514 	iPlayErrorOccured = EFalse;
       
  1515 
       
  1516 	// Store pointer to the buffer to use it later with PlayData
       
  1517 	iBufferPlay = reinterpret_cast<CMMFDataBuffer*>(aBuffer);
       
  1518 	TInt status = CreateChunk(iHwBufPckgFill, iBufferPlay->RequestSize());
       
  1519 	iHwBufPckgFill().iRequestSize = iBufferPlay->RequestSize();
       
  1520 	iHwBufPckgFill().iBufferSize = iBufferPlay->Data().MaxLength();
       
  1521 	iHwBufPckgFill().iLastBuffer = iBufferPlay->LastBuffer();
       
  1522 	TMMFDevSoundQueueItem queueItem;
       
  1523 	if ( status != KErrNone )
       
  1524 		{
       
  1525 		BufferErrorEvent();
       
  1526 		PlayError(status);
       
  1527 		}
       
  1528 	else
       
  1529 		{
       
  1530 		queueItem.iRequest = EMMFDevSoundProxyBTBFEvent;
       
  1531 		// assumes sufficient space in the queue so ignores the return value
       
  1532 		status = iMsgQueue.Send(queueItem);
       
  1533 		}
       
  1534 
       
  1535 	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::BufferToBeFilled - Exit [%d]"), status);
       
  1536 	}
       
  1537 
       
  1538 //
       
  1539 // CMMFDevSoundSession::PlayError
       
  1540 // (other items were commented in a header).
       
  1541 //
       
  1542 void CMMFDevSoundSession::PlayError(TInt aError)
       
  1543 	{
       
  1544 	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::PlayError [%d]"), aError);
       
  1545 
       
  1546 	// Set play error flag to ignore following PlayData requests
       
  1547 	iPlayErrorOccured = ETrue;
       
  1548 
       
  1549 	TMMFDevSoundQueueItem item;
       
  1550 	item.iRequest = EMMFDevSoundProxyPEEvent;
       
  1551 	item.iErrorCode = aError;
       
  1552 	iChunk.Close();
       
  1553 	// assumes sufficient space in the queue so ignores the return value
       
  1554 	iMsgQueue.Send(item);
       
  1555 	}
       
  1556 
       
  1557 //
       
  1558 // CMMFDevSoundSession::BufferToBeEmptied
       
  1559 // (other items were commented in a header).
       
  1560 //
       
  1561 void CMMFDevSoundSession::BufferToBeEmptied(CMMFBuffer* aBuffer)
       
  1562 	{
       
  1563 	// Store pointer to the buffer to use it later with RecordData
       
  1564 	iBufferRecord = reinterpret_cast<CMMFDataBuffer*>(aBuffer);
       
  1565 	TInt status = CreateChunk(iHwBufPckgEmpty, iBufferRecord->RequestSize());
       
  1566 	
       
  1567 	if ( status != KErrNone )
       
  1568 		{
       
  1569 		BufferErrorEvent();
       
  1570 		RecordError(status);
       
  1571 		}
       
  1572 	else
       
  1573 		{
       
  1574 		iHwBufPckgEmpty().iRequestSize = iBufferRecord->RequestSize();
       
  1575 		iHwBufPckgEmpty().iBufferSize = iBufferRecord->Data().MaxLength();
       
  1576 		iHwBufPckgEmpty().iLastBuffer = iBufferRecord->LastBuffer();
       
  1577 		//copy the data into the chunk    
       
  1578 		Mem::Copy(iChunk.Base(),iBufferRecord->Data().Ptr(),iBufferRecord->RequestSize());
       
  1579 	    TMMFDevSoundQueueItem queueItem;
       
  1580 		queueItem.iRequest = EMMFDevSoundProxyBTBEEvent;
       
  1581 		// assumes sufficient space in the queue so ignores the return value
       
  1582 		iMsgQueue.Send(queueItem);
       
  1583 		}
       
  1584 	}
       
  1585 
       
  1586 // CMMFDevSoundSession::RecordError
       
  1587 // (other items were commented in a header).
       
  1588 //
       
  1589 void CMMFDevSoundSession::RecordError(TInt aError)
       
  1590 	{
       
  1591 	SYMBIAN_DEBPRN1(_L("CMMFDevSoundSession[0x%x]::Record Error [%d]"), aError);
       
  1592 	TMMFDevSoundQueueItem item;
       
  1593 	item.iRequest = EMMFDevSoundProxyREEvent;
       
  1594 	item.iErrorCode = aError;
       
  1595 	iChunk.Close();
       
  1596 	// assumes sufficient space in the queue so ignores the return value
       
  1597 	iMsgQueue.Send(item);
       
  1598 	}
       
  1599 
       
  1600 //
       
  1601 // CMMFDevSoundSession::DeviceMessage
       
  1602 // (other items were commented in a header).
       
  1603 //
       
  1604 void CMMFDevSoundSession::DeviceMessage(TUid /*aMessageType*/,
       
  1605 									const TDesC8& /*aMsg*/)
       
  1606 	{
       
  1607 	// Not used
       
  1608 	}
       
  1609 
       
  1610 void CMMFDevSoundSession::InterfaceDeleted(TUid aInterfaceId)
       
  1611 	{
       
  1612 	MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = InterfaceFromUid(aInterfaceId);
       
  1613 	if (ptr == NULL)
       
  1614 		{
       
  1615 		// Not found
       
  1616 		return;
       
  1617 		}
       
  1618 	TRAPD(err, ptr->RefreshL());
       
  1619 	if (err != KErrNone)
       
  1620 		{
       
  1621 		// Refresh failed, so tear down Mux/DeMux pair
       
  1622 		TMMFEvent event;
       
  1623 		TMMFDevSoundQueueItem item;
       
  1624 		item.iRequest = EMMFDevSoundCustomCommandCloseMuxDemuxPair;
       
  1625 		item.iErrorCode = err;
       
  1626 		event.iEventType = aInterfaceId;
       
  1627 		item.iEventPckg() = event;
       
  1628 		iMsgQueue.Send(item);
       
  1629 		}
       
  1630 	}
       
  1631 
       
  1632 //
       
  1633 // CMMFDevSoundSession::CallbackFromAdaptorReceived
       
  1634 // (other items were commented in a header).
       
  1635 //
       
  1636 void CMMFDevSoundSession::CallbackFromAdaptorReceived(TInt aType, TInt aError)
       
  1637 	{
       
  1638 	
       
  1639 	if(aType == KCallbackRecordPauseComplete)
       
  1640 		{
       
  1641 		TMMFDevSoundQueueItem item;
       
  1642 		item.iRequest = EMMFDevSoundProxyPausedRecordCompleteEvent;
       
  1643 		item.iErrorCode = KErrNone;
       
  1644 		TInt status = iMsgQueue.Send(item);
       
  1645 		}
       
  1646 	else if(aType == KCallbackAutoPauseResume)
       
  1647 		{
       
  1648 		TMMFEvent event;
       
  1649 		event.iErrorCode = KErrNone;
       
  1650 		event.iEventType = KMMFEventCategoryAudioResourceAvailable;
       
  1651 		SendEventToClient(event);
       
  1652 		//coverity[uninit_use_in_call]
       
  1653 		// Disabled Coverity warning, since it complains about iReserved1 member in TMMFEvent being uninitialised
       
  1654 		}
       
  1655 	else if (aType == KCallbackFlushComplete)
       
  1656 		{
       
  1657 		iRequestBeingServiced.Complete(aError);
       
  1658 		iOperationCompletePending = EFalse;
       
  1659 		}
       
  1660 	else
       
  1661 		{
       
  1662 		if( iOperationCompletePending )
       
  1663 			{
       
  1664 			// If not possible to service now, then queue request
       
  1665 			// Encapsule the request
       
  1666 			TMMFDevSoundRequest request(aType);
       
  1667 			// assumes sufficient space in the queue so ignores the return value
       
  1668 			iQueuedRequests.Insert(request, 0);
       
  1669 			}
       
  1670 		else
       
  1671 			{
       
  1672 			// If there is no oustanding operation service inmediately
       
  1673 			if (aType == KCallbackProcessingFinished)
       
  1674 				{
       
  1675 				DoProcessingFinished();
       
  1676 				}
       
  1677 			else if(aType == KCallbackProcessingUnitError)
       
  1678 				{
       
  1679 				DoProcessingError();
       
  1680 				}
       
  1681 			}
       
  1682 		}
       
  1683 	}
       
  1684 
       
  1685 
       
  1686 //
       
  1687 // CMMFDevSoundSession::PreemptionStartedCallbackReceived
       
  1688 // (other items were commented in a header).
       
  1689 //
       
  1690 void CMMFDevSoundSession::PreemptionStartedCallbackReceived()
       
  1691 	{
       
  1692 	// Solution: Enqueue any request that arrives before preemption is completed
       
  1693 	iOperationCompletePending = ETrue;
       
  1694 	}
       
  1695 
       
  1696 //
       
  1697 // CMMFDevSoundSession::PreemptionFinishedCallbackReceived
       
  1698 // (other items were commented in a header).
       
  1699 //
       
  1700 void CMMFDevSoundSession::PreemptionFinishedCallbackReceived(TBool aCanStartNewOperation)
       
  1701 	{
       
  1702 	iOperationCompletePending = EFalse;
       
  1703 	if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 )
       
  1704 		{
       
  1705 		DequeueRequest();
       
  1706 		}
       
  1707 	}
       
  1708 
       
  1709 
       
  1710 MMMFDevSoundCustomInterfaceDeMuxPlugin* CMMFDevSoundSession::InterfaceFromUid(TUid aUid)
       
  1711 	{
       
  1712 	TInt count = iCustomInterfaceArray.Count();
       
  1713 	TInt id = aUid.iUid;
       
  1714 	MMMFDevSoundCustomInterfaceDeMuxPlugin* interface = NULL;
       
  1715 	for (TInt i = 0; i < count; i++)
       
  1716 		{
       
  1717 		if (id == iCustomInterfaceArray[i].iId.iUid)
       
  1718 			{
       
  1719 			interface = iCustomInterfaceArray[i].iInterface;
       
  1720 			break;
       
  1721 			}
       
  1722 		}
       
  1723 	return interface;
       
  1724 	}
       
  1725 
       
  1726 //
       
  1727 // CMMFDevSoundSession::SendEventToClient
       
  1728 // (other items were commented in a header).
       
  1729 //
       
  1730 void CMMFDevSoundSession::SendEventToClient(const TMMFEvent& aEvent)
       
  1731 	{
       
  1732 	TMMFDevSoundQueueItem item;
       
  1733 	item.iRequest = EMMFDevSoundProxySETCEvent;
       
  1734 	item.iErrorCode = KErrNone;
       
  1735 	item.iEventPckg() = aEvent;
       
  1736 	// assumes sufficient space in the queue so ignores the return value
       
  1737 	TInt err = iMsgQueue.Send(item);
       
  1738 	__ASSERT_DEBUG(err == KErrNone, Panic(EMsgQueueFailedToSendMsg));
       
  1739 	}
       
  1740 
       
  1741 void CMMFDevSoundSession::AsynchronousOperationComplete(TInt aError, TBool aCanStartNewOperation)
       
  1742 	{
       
  1743 	switch (iRequestBeingServiced.Type())
       
  1744 		{
       
  1745 		case TMMFDevSoundRequest::ESessionEvents:
       
  1746 			{
       
  1747 			SYMBIAN_DEBPRN0(_L("CMMFDevSoundSession[0x%x] ==== ClosingDueException ==== "));
       
  1748 			iOperationCompletePending = EFalse;
       
  1749 			if(iClosingWait->IsStarted())
       
  1750 				{
       
  1751 				iClosingWait->AsyncStop();
       
  1752 				}
       
  1753 			return;
       
  1754 			}
       
  1755 		// Complete the message for asynchronous requests
       
  1756 		case TMMFDevSoundRequest::EConfigure_Asynchronous:
       
  1757 		case TMMFDevSoundRequest::EAction_Asynchronous:
       
  1758 		case TMMFDevSoundRequest::EQuery_Asynchronous:
       
  1759 		case TMMFDevSoundRequest::ECustomInterfacesRelated:
       
  1760 			{
       
  1761 			if(iOperationCompletePending && aCanStartNewOperation)
       
  1762 				{
       
  1763 				if (iRequestBeingServiced.Function()==EMMFDevSoundProxyStop)
       
  1764 					{
       
  1765 					// flush the queue - will have removed any stale items added between initial call and MMRC's reaction
       
  1766 					iQueuedRequests.Reset();
       
  1767 					FlushEventQueue();
       
  1768 					iChunk.Close();
       
  1769 					}
       
  1770 					
       
  1771 				if(iRequestBeingServiced.Function()==EMMFDevSoundProxyCapabilities)
       
  1772 					{
       
  1773 					TMMFDevSoundProxySettings devSoundSet;
       
  1774 					devSoundSet.iCaps = iDevSoundCapabilities;
       
  1775 					TMMFDevSoundProxySettingsPckg pckg(devSoundSet);
       
  1776 					iRequestBeingServiced.Message().Write(TInt(2),pckg);
       
  1777 					}
       
  1778 				
       
  1779 				if(iRequestBeingServiced.Function()==EMMFDevSoundProxyCancelInitialize)
       
  1780 					{
       
  1781 					FlushEventQueue();
       
  1782 					}
       
  1783 				
       
  1784 				iRequestBeingServiced.Complete(aError);
       
  1785 				iOperationCompletePending = EFalse;
       
  1786 				}
       
  1787 			}
       
  1788 			break;
       
  1789 		case TMMFDevSoundRequest::EAction_PseudoAsynchronous:
       
  1790 			{
       
  1791 			if(iOperationCompletePending && aCanStartNewOperation)
       
  1792 				{
       
  1793 				iOperationCompletePending = EFalse;
       
  1794 				}
       
  1795 			}
       
  1796 			break;
       
  1797 		case TMMFDevSoundRequest::EQuery_Synchronous:
       
  1798 		case TMMFDevSoundRequest::EConfigure_Synchronous:
       
  1799 		case TMMFDevSoundRequest::EBufferExchangeRelated:
       
  1800 			break;
       
  1801 		case TMMFDevSoundRequest::ECallBackType:
       
  1802 			{
       
  1803 			if(iOperationCompletePending && aCanStartNewOperation)
       
  1804 				{
       
  1805 				iOperationCompletePending = EFalse;
       
  1806 				}	
       
  1807 			}
       
  1808 			break;
       
  1809 		default:
       
  1810 			break;
       
  1811 		}
       
  1812 
       
  1813 	SYMBIAN_DEBPRN2(_L("CMMFDevSoundSession[0x%x] AsynchronousOperationComplete %x pending=%d"),iRequestBeingServiced.Function(), iOperationCompletePending );
       
  1814 
       
  1815 	if ( aCanStartNewOperation && iQueuedRequests.Count() != 0 )
       
  1816 		{
       
  1817 		DequeueRequest();
       
  1818 		}
       
  1819 	}
       
  1820 
       
  1821 void CMMFDevSoundSession::DequeueRequest()
       
  1822 	{
       
  1823 	TMMFDevSoundRequest msg = iQueuedRequests[0];
       
  1824 
       
  1825 	if (msg.IsCallBack() > 0)
       
  1826 		{
       
  1827 		iRequestBeingServiced.SetMessageCallback();
       
  1828 		//Call iPf function
       
  1829 		SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x] ======== Service a queued request\n"));
       
  1830 		if (msg.IsCallBack() == KCallbackProcessingFinished)
       
  1831 			{
       
  1832 			iQueuedRequests.Remove(0);
       
  1833 			DoProcessingFinished();
       
  1834 			}
       
  1835 		else if(msg.IsCallBack() == KCallbackProcessingUnitError)
       
  1836 		    {
       
  1837 		    iQueuedRequests.Remove(0);
       
  1838 		    DoProcessingError();
       
  1839 		    }
       
  1840 
       
  1841 		}
       
  1842 	else
       
  1843 		{
       
  1844 		// Some rules about what request can be followed
       
  1845 		SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Flag can service new request\n"));
       
  1846 		iAsyncQueueStart->CallBack();
       
  1847 		}
       
  1848 	}
       
  1849 	
       
  1850 // 	AsyncQueueStartCallback
       
  1851 
       
  1852 
       
  1853 TInt CMMFDevSoundSession::AsyncQueueStartCallback(TAny* aPtr)
       
  1854 	{
       
  1855 	CMMFDevSoundSession* self = static_cast<CMMFDevSoundSession*>(aPtr);
       
  1856 	self->AsyncQueueStartCallback();
       
  1857 	return KErrNone;
       
  1858 	}
       
  1859 	
       
  1860 void CMMFDevSoundSession::AsyncQueueStartCallback()
       
  1861 	{
       
  1862 	SYMBIAN_DEBPRN0(_L("\n CMMFDevSoundSession[0x%x]======== Service a queued request\n"));
       
  1863 	TMMFDevSoundRequest msg = iQueuedRequests[0];
       
  1864 	iQueuedRequests.Remove(0);
       
  1865 	TRAPD(err,DoServiceRequestL(msg.Message()));
       
  1866     if(err != KErrNone)
       
  1867         {
       
  1868         msg.Complete(err);      
       
  1869         }
       
  1870 	if (!iOperationCompletePending && iQueuedRequests.Count() != 0)
       
  1871 		{
       
  1872 		//dequeue next
       
  1873 		DequeueRequest();
       
  1874 		}
       
  1875 	}
       
  1876 
       
  1877 // CMMFDevSoundSession::CustomInterface()
       
  1878 // Returns a pointer reference to custom interface implementation returned by
       
  1879 // adaptation::CustomInterface method.
       
  1880 // Note this method is called indirectly by CI server-side plugins - both DeMux and 
       
  1881 // CIServerExtension call this variously via MMMFDevSoundCustomInterfaceTarget or MCustomInterface 
       
  1882 //
       
  1883 TAny* CMMFDevSoundSession::CustomInterface(TUid aInterfaceId)
       
  1884 	{
       
  1885 	TInt err = DoSetClientConfig(); // if required, this will connect to MMRC etc
       
  1886 	if (err)
       
  1887 		{
       
  1888 		return NULL; // on any error, return NULL - not much more we can do
       
  1889 		}
       
  1890 	return iAdapter->CustomInterface(aInterfaceId);
       
  1891 	}
       
  1892 
       
  1893 //
       
  1894 // CMMFDevSoundSession::DoProcessingFinished()
       
  1895 //
       
  1896 void CMMFDevSoundSession::DoProcessingFinished()
       
  1897 	{
       
  1898 	TBool asyncOperation = EFalse;
       
  1899 	//ProcessingFinished should never fail
       
  1900 	__ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingFinishedReceived(asyncOperation));
       
  1901 	iOperationCompletePending = asyncOperation;
       
  1902 	if (iOperationCompletePending)
       
  1903 		{
       
  1904 		iRequestBeingServiced.SetMessageCallback();
       
  1905 		}
       
  1906 	}
       
  1907 
       
  1908 //
       
  1909 // CMMFDevSoundSession::DoProcessingError()
       
  1910 //
       
  1911 void CMMFDevSoundSession::DoProcessingError()
       
  1912     {
       
  1913     TBool asyncOperation = EFalse;
       
  1914     //ProcessingFinished should never fail
       
  1915     __ASSERT_ALWAYS(KErrNone, iAdapter->ProcessingError(asyncOperation));
       
  1916     iOperationCompletePending = asyncOperation;
       
  1917     if (iOperationCompletePending)
       
  1918         {
       
  1919         iRequestBeingServiced.SetMessageCallback();
       
  1920         }
       
  1921     }
       
  1922 
       
  1923 //
       
  1924 // CMMFDevSoundSession::DoSetClientConfigL()
       
  1925 // Sets client configuration information to Adaptation.
       
  1926 //
       
  1927 TInt CMMFDevSoundSession::DoSetClientConfig()
       
  1928 	{
       
  1929 	TInt err = KErrNone;
       
  1930 	if(!iSetClientConfigApplied)
       
  1931 		{
       
  1932 		CMMFDevSoundServer* server =
       
  1933 			const_cast<CMMFDevSoundServer*>(
       
  1934 				static_cast<const CMMFDevSoundServer*>(Server()));
       
  1935 			
       
  1936 		ASSERT(server); // session should always have a server!
       
  1937 
       
  1938 		TMMFClientConfig clientConfig;
       
  1939 		clientConfig.iProcessId = server->ActualProcessId();
       
  1940 
       
  1941 		err = iAdapter->SetClientConfig(clientConfig);
       
  1942 		if (!err)
       
  1943 			{
       
  1944 			iSetClientConfigApplied = ETrue;
       
  1945 			}
       
  1946 		}
       
  1947 	return err;
       
  1948 	}
       
  1949 
       
  1950 // CMMFDevSoundSession::DoSetClientConfigL()
       
  1951 // Sets client configuration information to Adaptation.
       
  1952 //
       
  1953 void CMMFDevSoundSession::DoSetClientConfigL()
       
  1954 	{
       
  1955 	User::LeaveIfError(DoSetClientConfig());
       
  1956 	}
       
  1957 
       
  1958 // 
       
  1959 // CMMFDevSoundSession::CreateChunk()
       
  1960 // Requests kernel to create global RChunk
       
  1961 // 
       
  1962 TInt CMMFDevSoundSession::CreateChunk(TMMFDevSoundProxyHwBufPckg& aBufPckg, TInt aRequestedSize)
       
  1963 	{
       
  1964 	TInt status(KErrNone);
       
  1965 	
       
  1966 	if ( iChunk.Handle() )
       
  1967 		{
       
  1968 		// If the DevSound Adaptation component requests a buffer size
       
  1969 		// that can fit into current chunk's size, then re-use chunk.
       
  1970 		if ( aRequestedSize <= iChunk.Size() )
       
  1971 			{
       
  1972 			if (iForceSendOfChunkHandle)
       
  1973 				{
       
  1974 				iForceSendOfChunkHandle = EFalse;
       
  1975 				aBufPckg().iChunkOp = EOpen;
       
  1976 				}
       
  1977 			else
       
  1978 				{
       
  1979 				aBufPckg().iChunkOp = ENull;
       
  1980 				}
       
  1981 			return status;
       
  1982 			}
       
  1983 		// The new request size exceeds the current chunk's area, close it. We
       
  1984 		// will be creating new one in the following sequences. Note we could
       
  1985 		// try to Adjust() the chunk, and see if the existing chunk could be
       
  1986 		// extended instead, but this is assumed too rare an event for this 
       
  1987 		// optimisation
       
  1988 		else
       
  1989 			{
       
  1990 			iChunk.Close();
       
  1991 			}
       
  1992 		}
       
  1993 	
       
  1994 	// Request kernel to create global RChunk if needed
       
  1995 	if ( !iChunk.Handle() )
       
  1996 		{
       
  1997 		status = iChunk.CreateGlobal(KNullDesC, aRequestedSize, aRequestedSize);
       
  1998 		if ( status == KErrNone )
       
  1999 			{
       
  2000 			aBufPckg().iChunkOp = EOpen;
       
  2001 			}
       
  2002 		else
       
  2003 			{
       
  2004 			aBufPckg().iChunkOp = ENull;
       
  2005 			}
       
  2006 		}
       
  2007 	iForceSendOfChunkHandle = EFalse;
       
  2008 	return status;
       
  2009 	}
       
  2010 
       
  2011 
       
  2012 // Custom Interface //
       
  2013 TInt CMMFDevSoundSession::DoOpenSlaveL(TUid aInterface, const TDesC8& aPackageBuf)
       
  2014 	{
       
  2015 	// it shouldn't be necessary to check if we have already instantiated this
       
  2016 	// interface since the client would already know - however this is something
       
  2017 	// that a licensee could implement if they required additional functionality
       
  2018 	// e.g. many : 1 mappings between client and DevSound.
       
  2019 
       
  2020 	MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = NULL;
       
  2021 		
       
  2022 	// try and instantiate a plugin tunnelling
       
  2023 	// pair to support this Custom Interface
       
  2024 	ptr = iDeMuxUtility->CreateCustomInterfaceDeMuxL(aInterface);
       
  2025 	
       
  2026 	TInt handle = KNullHandle;
       
  2027 	
       
  2028 	if (ptr)
       
  2029 		{
       
  2030 		TMMFDevSoundCustomInterfaceDeMuxData data;
       
  2031 		data.iInterface = ptr;
       
  2032 		data.iId = aInterface;
       
  2033 			
       
  2034 		CleanupReleasePushL(*ptr);
       
  2035 			
       
  2036 		// setup demux plugin
       
  2037 		ptr->SetInterfaceTarget(this);
       
  2038 			
       
  2039 		// try and open interface
       
  2040 		// this will fetch the interface from the svr implementation
       
  2041 		ptr->DoOpenSlaveL(aInterface, aPackageBuf);
       
  2042 		User::LeaveIfError(iCustomInterfaceArray.Append(data));
       
  2043 			
       
  2044 		CleanupStack::Pop();	// ptr
       
  2045 			
       
  2046 		handle = iCustomInterfaceArray.Count();
       
  2047 		return handle;
       
  2048 		}
       
  2049 
       
  2050 	// we couldn't set up the interface correctly so return a NULL
       
  2051 	// handle to the client
       
  2052 	return KNullHandle;
       
  2053 	}
       
  2054 	
       
  2055 void CMMFDevSoundSession::DoCloseSlaveL(TInt aHandle)
       
  2056 	{
       
  2057 	if (aHandle==KNullHandle)
       
  2058 		{
       
  2059 		// null-handle -> NOP
       
  2060 		return;
       
  2061 		}
       
  2062 		
       
  2063 	if (aHandle<KNullHandle || aHandle > iCustomInterfaceArray.Count())
       
  2064 		{
       
  2065 		// handle out of range - should not happen, but leave to show error
       
  2066 		User::Leave(KErrBadHandle);
       
  2067 		}
       
  2068 		
       
  2069 	TMMFDevSoundCustomInterfaceDeMuxData& data = iCustomInterfaceArray[aHandle-1];
       
  2070 	
       
  2071 	// close and delete the plugin
       
  2072 	MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = data.iInterface;
       
  2073 	ptr->DoCloseSlaveL(aHandle);
       
  2074 	ptr->Release();
       
  2075 	
       
  2076 	// clear the entry
       
  2077 	data.iInterface = NULL;
       
  2078 	data.iId.iUid = 0;
       
  2079 	}
       
  2080 	
       
  2081 TInt CMMFDevSoundSession::DoSendSlaveSyncCommandL(const RMmfIpcMessage& aMessage)
       
  2082 	{
       
  2083 	// use the demux utility to get the handle
       
  2084 	TMMFDevSoundCIMessageData data;
       
  2085 	iDeMuxUtility->GetSyncMessageDataL(aMessage, data);
       
  2086 	
       
  2087 	TInt handle = data.iHandle;
       
  2088 	
       
  2089 	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
       
  2090 		{
       
  2091 		
       
  2092 		User::Leave(KErrBadHandle);
       
  2093 		}
       
  2094 	
       
  2095 	// call on demux plugin
       
  2096 	return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandL(aMessage);	
       
  2097 	}
       
  2098 	
       
  2099 TInt CMMFDevSoundSession::DoSendSlaveSyncCommandResultL(const RMmfIpcMessage& aMessage)
       
  2100 	{
       
  2101 	// use the demux utility to get the handle
       
  2102 	TMMFDevSoundCIMessageData data;
       
  2103 	iDeMuxUtility->GetSyncMessageDataL(aMessage, data);
       
  2104 	
       
  2105 	TInt handle = data.iHandle;
       
  2106 	
       
  2107 	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
       
  2108 		{
       
  2109 		
       
  2110 		User::Leave(KErrBadHandle);
       
  2111 		}
       
  2112 	
       
  2113 	// call on demux plugin
       
  2114 	return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandResultL(aMessage);	
       
  2115 	}
       
  2116 	
       
  2117 void CMMFDevSoundSession::DoSendSlaveAsyncCommandL(const RMmfIpcMessage& aMessage)
       
  2118 	{
       
  2119 	// use the demux utility to get the handle
       
  2120 	TMMFDevSoundCIMessageData data;
       
  2121 	iDeMuxUtility->GetAsyncMessageDataL(aMessage, data);
       
  2122 	
       
  2123 	TInt handle = data.iHandle;
       
  2124 	
       
  2125 	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
       
  2126 		{
       
  2127 		User::Leave(KErrBadHandle);
       
  2128 		}
       
  2129 	
       
  2130 	// call on demux plugin
       
  2131 	iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandL(aMessage);	
       
  2132 	}
       
  2133 	
       
  2134 void CMMFDevSoundSession::DoSendSlaveAsyncCommandResultL(const RMmfIpcMessage& aMessage)
       
  2135 	{
       
  2136 	// use the demux utility to get the handle
       
  2137 	TMMFDevSoundCIMessageData data;
       
  2138 	iDeMuxUtility->GetAsyncMessageDataL(aMessage, data);
       
  2139 	
       
  2140 	TInt handle = data.iHandle;
       
  2141 	
       
  2142 	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
       
  2143 		{
       
  2144 		User::Leave(KErrBadHandle);
       
  2145 		}
       
  2146 	
       
  2147 	// call on demux plugin
       
  2148 	iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandResultL(aMessage);	
       
  2149 	}
       
  2150 
       
  2151 
       
  2152 TBool CMMFDevSoundSession::DoRegisterAsClientL(const RMmfIpcMessage& aMessage)
       
  2153 	{
       
  2154 	TMMFDevSoundProxySettingsPckg buf;
       
  2155 	aMessage.ReadL(0,buf);
       
  2156 	HBufC8* notificationRegistrationData = NULL;
       
  2157 	notificationRegistrationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLengthL(1)));
       
  2158 	TPtr8 dataPtr(notificationRegistrationData->Des());  	
       
  2159 	aMessage.ReadL(1,dataPtr);
       
  2160 	DoSetClientConfigL();// added here instead of the CreateL()
       
  2161 	TInt err = KErrNone;
       
  2162 	err = iAdapter->RegisterAsClient(buf().iNotificationEventUid,dataPtr);
       
  2163 	CleanupStack::PopAndDestroy(1); // Notification Registeration data
       
  2164 	if (err != KErrNone)
       
  2165 		{
       
  2166 		aMessage.Complete(err);
       
  2167 		return EFalse;		
       
  2168 		}
       
  2169 	return ETrue;
       
  2170 	}
       
  2171 	
       
  2172 TBool CMMFDevSoundSession::DoCancelRegisterAsClientL(const RMmfIpcMessage& aMessage)
       
  2173 	{
       
  2174 	TMMFDevSoundProxySettingsPckg buf;
       
  2175 	aMessage.ReadL(0,buf);
       
  2176 	TInt err = KErrNone;
       
  2177 	err = iAdapter->CancelRegisterAsClient(buf().iNotificationEventUid);
       
  2178 	if (err != KErrNone)
       
  2179 		{
       
  2180 		aMessage.Complete(err);
       
  2181 		return EFalse;		
       
  2182 		}
       
  2183 	return ETrue;
       
  2184 	}
       
  2185 
       
  2186 TBool CMMFDevSoundSession::DoGetResourceNotificationDataL(const RMmfIpcMessage& aMessage)
       
  2187 	{
       
  2188 	TMMFDevSoundProxySettingsPckg buf;
       
  2189 	aMessage.ReadL(0,buf);
       
  2190 	HBufC8* notificationData = NULL;
       
  2191 	notificationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLengthL(2)));
       
  2192 	TPtr8 dataPtr(notificationData->Des());  	
       
  2193 	aMessage.ReadL(2,dataPtr);
       
  2194 	TInt err = KErrNone;
       
  2195 	err = iAdapter->GetResourceNotificationData(buf().iNotificationEventUid,dataPtr);
       
  2196 	aMessage.WriteL(2,*notificationData);
       
  2197 	CleanupStack::PopAndDestroy(1); // Notification data
       
  2198 	if (err != KErrNone)
       
  2199 		{
       
  2200 		aMessage.Complete(err);
       
  2201 		return EFalse;		
       
  2202 		}
       
  2203 	return ETrue;
       
  2204 	}
       
  2205 
       
  2206 TBool CMMFDevSoundSession::DoWillResumePlayL(const RMmfIpcMessage& aMessage)
       
  2207 	{
       
  2208 	TInt err = KErrNone;
       
  2209 	err = iAdapter->WillResumePlay();
       
  2210 	if (err != KErrNone)
       
  2211 		{
       
  2212 		aMessage.Complete(err);
       
  2213 		return EFalse;		
       
  2214 		}
       
  2215 	return ETrue;
       
  2216 	}
       
  2217 
       
  2218 TBool CMMFDevSoundSession::DoSetClientThreadInfoL(const RMmfIpcMessage& aMessage)
       
  2219 	{
       
  2220 	if(!iSetClientConfigApplied)
       
  2221 		{
       
  2222 		if (aMessage.HasCapability(ECapabilityMultimediaDD) && aMessage.HasCapability(ECapabilityUserEnvironment))
       
  2223 			{
       
  2224 			TPckgBuf<TThreadId> threadId;
       
  2225 			aMessage.ReadL(1, threadId);
       
  2226 			
       
  2227 			CMMFDevSoundServer* server = 
       
  2228 				const_cast<CMMFDevSoundServer*>(static_cast<const CMMFDevSoundServer*>(Server()));
       
  2229 			server->SetClientProcessIdL(threadId()); 
       
  2230 			}
       
  2231 		else
       
  2232 			{
       
  2233 			User::Leave(KErrPermissionDenied);
       
  2234 			}
       
  2235 		}
       
  2236 	else
       
  2237 		{
       
  2238 		User::Leave(KErrNotReady);
       
  2239 		}
       
  2240 	return ETrue;
       
  2241 	}
       
  2242 	
       
  2243 void CMMFDevSoundSession::Panic(TMMFDevSoundSessionPanicCodes aCode)
       
  2244 	{
       
  2245 	User::Panic(KMMFDevSoundSessionPanicCategory, aCode);
       
  2246 	}
       
  2247 
       
  2248 void CMMFDevSoundSession::BufferErrorEvent()
       
  2249 	{
       
  2250 	// this will generate an processing error event and callback
       
  2251 	iAdapter->BufferErrorEvent();
       
  2252 	}
       
  2253 // End of file