os/mm/devsound/devsoundrefplugin/src/platsec/server/AudioServer/MmfDevSoundSession.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2004-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 "MmfDevSoundSession.h"
    18 #include "MmfDevSoundSessionXtnd.h"
    19 #include "MmfDevSoundSessionBody.h"
    20 
    21 #include "MmfAudioClientServer.h"
    22 #include "MmfAudioServer.h"
    23 #include "MmfDevSoundServer.h"
    24 
    25 void CMMFDevSoundSession::CreateL(const CMmfIpcServer& aServer)
    26 	{
    27 	CMmfIpcSession::CreateL(aServer);
    28 	CMMFDevSoundServer& server = 
    29 		const_cast<CMMFDevSoundServer&>(static_cast<const CMMFDevSoundServer&>(aServer));
    30 	server.IncrementSessionId();
    31 	iDevSoundSessionId = server.DevSoundSessionId();
    32 	iClientHasCaps = server.CheckClientCapabilities();
    33 	}
    34 
    35 TBool CMMFDevSoundSession::CheckClientCapabilities()
    36 	{
    37 	return iClientHasCaps;
    38 	}
    39 
    40 void CMMFDevSoundSession::ServiceL(const RMmfIpcMessage& aMessage)
    41 	{
    42 	TBool complete = EFalse;
    43 	switch(aMessage.Function())
    44 		{
    45 	case EMMFDevSoundProxyInitialize1:
    46 		complete = DoInitialize1L(aMessage);
    47 		break;
    48 	case EMMFDevSoundProxyInitialize2:
    49 		complete = DoInitialize2L(aMessage);
    50 		break;
    51 	case EMMFDevSoundProxyInitialize3:
    52 		complete = DoInitialize3L(aMessage);
    53 		break;
    54 	case EMMFDevSoundProxyInitialize4:
    55 		complete = DoInitialize4L(aMessage);
    56 		break;
    57 	case EMMFDevSoundProxyCapabilities:
    58 		complete = DoCapabilitiesL(aMessage);
    59 		break;
    60 	case EMMFDevSoundProxyConfig:
    61 		complete = DoConfigL(aMessage);
    62 		break;
    63 	case EMMFDevSoundProxySetConfig:
    64 		complete = DoSetConfigL(aMessage);
    65 		break;
    66 	case EMMFDevSoundProxyMaxVolume:
    67 		complete = DoMaxVolumeL(aMessage);
    68 		break;
    69 	case EMMFDevSoundProxyVolume:
    70 		complete = DoVolumeL(aMessage);
    71 		break;
    72 	case EMMFDevSoundProxySetVolume:
    73 		complete = DoSetVolumeL(aMessage);
    74 		break;
    75 	case EMMFDevSoundProxyMaxGain:
    76 		complete = DoMaxGainL(aMessage);
    77 		break;
    78 	case EMMFDevSoundProxyGain:
    79 		complete = DoGainL(aMessage);
    80 		break;
    81 	case EMMFDevSoundProxySetGain:
    82 		complete = DoSetGainL(aMessage);
    83 		break;
    84 	case EMMFDevSoundProxyPlayBalance:
    85 		complete = DoGetPlayBalanceL(aMessage);
    86 		break;
    87 	case EMMFDevSoundProxySetPlayBalance:
    88 		complete = DoSetPlayBalanceL(aMessage);
    89 		break;
    90 	case EMMFDevSoundProxyRecordBalance:
    91 		complete = DoGetRecordBalanceL(aMessage);
    92 		break;
    93 	case EMMFDevSoundProxySetRecordBalance:
    94 		complete = DoSetRecordBalanceL(aMessage);
    95 		break;
    96 	case EMMFDevSoundProxyBTBFData:
    97 		complete = DoBufferToBeFilledDataL(aMessage);
    98 		break;
    99 	case EMMFDevSoundProxyBTBEData:
   100 		complete = DoBufferToBeEmptiedDataL(aMessage);
   101 		break;
   102 	case EMMFDevSoundProxyPlayInit:
   103 		complete = DoPlayInitL(aMessage);
   104 		break;
   105 	case EMMFDevSoundProxyRecordInit:
   106 		complete = DoRecordInitL(aMessage);
   107 		break;
   108 	case EMMFDevSoundProxyPlayData:
   109 		complete = DoPlayDataL(aMessage);
   110 		break;
   111 	case EMMFDevSoundProxyRecordData:
   112 		complete = DoRecordDataL(aMessage);
   113 		break;
   114 	case EMMFDevSoundProxyStop:
   115 		complete = DoStopL(aMessage);
   116 		break;
   117 	case EMMFDevSoundProxyPause:
   118 		complete = DoPauseL(aMessage);
   119 		break;
   120 	case EMMFDevSoundProxyPlayTone:
   121 		complete = DoPlayToneL(aMessage);
   122 		break;
   123 	case EMMFDevSoundProxyPlayDualTone:
   124 		complete = DoPlayDualToneL(aMessage);
   125 		break;
   126 	case EMMFDevSoundProxyPlayDTMFString:
   127 		complete = DoPlayDTMFStringL(aMessage);
   128 		break;
   129 	case EMMFDevSoundProxyPlayToneSequence:
   130 		complete = DoPlayToneSequenceL(aMessage);
   131 		break;
   132 	case EMMFDevSoundProxyPlayFixedSequence:
   133 		complete = DoPlayFixedSequenceL(aMessage);
   134 		break;
   135 	case EMMFDevSoundProxySetDTMFLengths:
   136 		complete = DoSetDTMFLengthsL(aMessage);
   137 		break;
   138 	case EMMFDevSoundProxySetVolumeRamp:
   139 		complete = DoSetVolumeRampL(aMessage);
   140 		break;
   141 	case EMMFDevSoundProxyGetSupportedInputDataTypes:
   142 		complete = DoGetSupportedInputDataTypesL(aMessage);
   143 		break;
   144 	case EMMFDevSoundProxyGetSupportedOutputDataTypes:
   145 		complete = DoGetSupportedOutputDataTypesL(aMessage);
   146 		break;
   147 	case EMMFDevSoundProxyCopyFourCCArrayData:
   148 		complete = DoCopyFourCCArrayDataL(aMessage);
   149 		break;
   150 	case EMMFDevSoundProxyGetRecordedBuffer:
   151 		complete = DoGetRecordedBufferL(aMessage);
   152 		break;
   153 	case EMMFDevSoundProxySamplesRecorded:
   154 		complete = DoSamplesRecordedL(aMessage);
   155 		break;
   156 	case EMMFDevSoundProxySamplesPlayed:
   157 		complete = DoSamplesPlayedL(aMessage);
   158 		break;
   159 	case EMMFDevSoundProxySetToneRepeats:
   160 		complete = DoSetToneRepeatsL(aMessage);
   161 		break;
   162 	case EMMFDevSoundProxySetPrioritySettings:
   163 		complete = DoSetPrioritySettingsL(aMessage);
   164 		break;
   165 	case EMMFDevSoundProxyFixedSequenceName:
   166 		complete = DoFixedSequenceNameL(aMessage);
   167 		break;
   168 	case EMMFDevSoundProxyFixedSequenceCount:
   169 		complete = DoFixedSequenceCountL(aMessage);
   170 		break;
   171 	case EMMFDevSoundProxyRequestResourceNotification:
   172 		complete = DoRegisterAsClientL(aMessage);
   173 		break;
   174 	case EMMFDevSoundProxyCancelRequestResourceNotification:
   175 		complete = DoCancelRegisterAsClientL(aMessage);
   176 		break;
   177 	case EMMFDevSoundProxyGetResourceNotificationData:
   178 		complete = DoGetResourceNotificationDataL(aMessage);
   179 		break;
   180 	case EMMFDevSoundProxyWillResumePlay:
   181 		complete = DoWillResumePlayL(aMessage);
   182 		break;
   183 	case EMMFDevSoundProxySetClientThreadInfo:
   184 		complete = DoSetClientThreadInfoL(aMessage);
   185 		break;
   186 	case EMMFDevSoundProxyGetTimePlayed:
   187 		complete = DoGetTimePlayedL(aMessage);
   188 		break;
   189 
   190 	// custom command support
   191 	case EMMFDevSoundProxySyncCustomCommand:
   192 		complete = DoSyncCustomCommandL(aMessage);
   193 		break;
   194 	case EMMFDevSoundProxySyncCustomCommandResult:
   195 		complete = DoSyncCustomCommandResultL(aMessage);
   196 		break;
   197 	case EMMFDevSoundProxyAsyncCustomCommand:
   198 		complete = DoAsyncCustomCommandL(aMessage);
   199 		break;
   200 	case EMMFDevSoundProxyAsyncCustomCommandResult:
   201 		complete = DoAsyncCustomCommandResultL(aMessage);
   202 		break;
   203 	case EMMFDevSoundProxyEmptyBuffers:
   204 		complete = DoEmptyBuffersL(aMessage);
   205 		break;
   206 	default:
   207 		User::Leave(KErrNotSupported);
   208 		break;
   209 		}
   210 	if (complete)
   211 		aMessage.Complete(KErrNone);
   212 	}
   213 
   214 TBool CMMFDevSoundSession::DoInitialize1L(const RMmfIpcMessage& aMessage)
   215 	{
   216 	if(iMsgQueue.Handle() == 0)
   217 		{
   218 		TInt err = iMsgQueue.Open(aMessage, 1);	// a global queue.
   219 		User::LeaveIfError(err);
   220 		}
   221 	TMMFDevSoundProxySettingsPckg buf;
   222 	MmfMessageUtil::ReadL(aMessage,0,buf);
   223 	TMMFState mode = buf().iMode;
   224 	iBody->InitializeL(*this, mode);
   225 	iBufferPlay = NULL;
   226 	return ETrue;
   227 	}
   228 
   229 TBool CMMFDevSoundSession::DoInitialize2L(const RMmfIpcMessage& aMessage)
   230 	{
   231 	if(iMsgQueue.Handle() == 0)
   232 		{
   233 		TInt err = iMsgQueue.Open(aMessage, 1);	// a global queue.
   234 		User::LeaveIfError(err);
   235 		}
   236 	TMMFDevSoundProxySettingsPckg buf;
   237 	MmfMessageUtil::ReadL(aMessage,0,buf);
   238 	TUid HWDev = buf().iHWDev;
   239 	TMMFState mode = buf().iMode;
   240 	iBody->InitializeL(*this, HWDev, mode);
   241 	iBufferPlay = NULL;
   242 	return ETrue;
   243 	}
   244 
   245 TBool CMMFDevSoundSession::DoInitialize3L(const RMmfIpcMessage& /*aMessage*/)
   246 	{
   247 	User::Leave(KErrNotSupported);
   248 	return ETrue;
   249 	}
   250 
   251 TBool CMMFDevSoundSession::DoInitialize4L(const RMmfIpcMessage& aMessage)
   252 	{
   253 	if(iMsgQueue.Handle() == 0)
   254 		{
   255 		TInt err = iMsgQueue.Open(aMessage, 1);	// a global queue.
   256 		User::LeaveIfError(err);
   257 		}
   258 	TMMFDevSoundProxySettingsPckg buf;
   259 	aMessage.ReadL(TInt(0),buf);
   260 	TFourCC desiredFourCC = buf().iDesiredFourCC;
   261 	TMMFState mode = buf().iMode;
   262 	iBody->InitializeL(*this, desiredFourCC, mode);
   263 	iBufferPlay = NULL;
   264 	return ETrue;
   265 	}
   266 
   267 TBool CMMFDevSoundSession::DoCapabilitiesL(const RMmfIpcMessage& aMessage)
   268 	{
   269 	TMMFDevSoundProxySettings set;
   270 	set.iCaps = iBody->Capabilities();
   271 	TMMFDevSoundProxySettingsPckg pckg(set);
   272 	aMessage.WriteL(TInt(2),pckg);
   273 	return ETrue;
   274 	}
   275 
   276 TBool CMMFDevSoundSession::DoConfigL(const RMmfIpcMessage& aMessage)
   277 	{
   278 	TMMFDevSoundProxySettings set;
   279 	set.iConfig = iBody->Config();
   280 	TMMFDevSoundProxySettingsPckg pckg(set);
   281 	aMessage.WriteL(TInt(2),pckg);
   282 	return ETrue;
   283 	}
   284 
   285 TBool CMMFDevSoundSession::DoSetConfigL(const RMmfIpcMessage& aMessage)
   286 	{
   287 	TMMFDevSoundProxySettingsPckg buf;
   288 	aMessage.ReadL(TInt(0),buf);
   289 	TMMFCapabilities config = buf().iConfig;
   290 	iBody->SetConfigL(config);
   291 	return ETrue;
   292 	}
   293 
   294 TBool CMMFDevSoundSession::DoMaxVolumeL(const RMmfIpcMessage& aMessage)
   295 	{
   296 	TMMFDevSoundProxySettings set;
   297 	set.iMaxVolume = iBody->MaxVolume();
   298 	TMMFDevSoundProxySettingsPckg pckg(set);
   299 	aMessage.WriteL(TInt(2),pckg);
   300 	return ETrue;
   301 	}
   302 
   303 TBool CMMFDevSoundSession::DoVolumeL(const RMmfIpcMessage& aMessage)
   304 	{
   305 	TMMFDevSoundProxySettings set;
   306 	set.iVolume = iBody->Volume();
   307 	TMMFDevSoundProxySettingsPckg pckg(set);
   308 	aMessage.WriteL(TInt(2),pckg);
   309 	return ETrue;
   310 	}
   311 
   312 TBool CMMFDevSoundSession::DoSetVolumeL(const RMmfIpcMessage& aMessage)
   313 	{
   314 	TMMFDevSoundProxySettingsPckg buf;
   315 	aMessage.ReadL(TInt(0),buf);
   316 	TInt volume = buf().iVolume;
   317 	iBody->SetVolume(volume);
   318 	return ETrue;
   319 	}
   320 
   321 TBool CMMFDevSoundSession::DoMaxGainL(const RMmfIpcMessage& aMessage)
   322 	{
   323 	TMMFDevSoundProxySettings set;
   324 	set.iMaxGain = iBody->MaxGain();
   325 	TMMFDevSoundProxySettingsPckg pckg(set);
   326 	aMessage.WriteL(TInt(2),pckg);
   327 	return ETrue;
   328 	}
   329 
   330 TBool CMMFDevSoundSession::DoGainL(const RMmfIpcMessage& aMessage)
   331 	{
   332 	TMMFDevSoundProxySettings set;
   333 	set.iGain = iBody->Gain();
   334 	TMMFDevSoundProxySettingsPckg pckg(set);
   335 	aMessage.WriteL(TInt(2),pckg);
   336 	return ETrue;
   337 	}
   338 
   339 TBool CMMFDevSoundSession::DoSetGainL(const RMmfIpcMessage& aMessage)
   340 	{
   341 	TMMFDevSoundProxySettingsPckg buf;
   342 	aMessage.ReadL(TInt(0),buf);
   343 	TInt gain = buf().iGain;
   344 	iBody->SetGain(gain);
   345 	return ETrue;
   346 	}
   347 
   348 TBool CMMFDevSoundSession::DoGetPlayBalanceL(const RMmfIpcMessage& aMessage)
   349 	{
   350 	TMMFDevSoundProxySettings set;
   351 	iBody->GetPlayBalanceL(set.iLeftPercentage, set.iRightPercentage);
   352 	TMMFDevSoundProxySettingsPckg pckg(set);
   353 	aMessage.WriteL(TInt(2),pckg);
   354 	return ETrue;
   355 	}
   356 
   357 TBool CMMFDevSoundSession::DoSetPlayBalanceL(const RMmfIpcMessage& aMessage)
   358 	{
   359 	TMMFDevSoundProxySettingsPckg buf;
   360 	aMessage.ReadL(TInt(0),buf);
   361 	TInt leftPercentage = buf().iLeftPercentage;
   362 	TInt rightPercentage = buf().iRightPercentage;
   363 	iBody->SetPlayBalanceL(leftPercentage, rightPercentage);
   364 	return ETrue;
   365 	}
   366 
   367 TBool CMMFDevSoundSession::DoGetRecordBalanceL(const RMmfIpcMessage& aMessage)
   368 	{
   369 	TMMFDevSoundProxySettings set;
   370 	iBody->GetRecordBalanceL(set.iLeftPercentage, set.iRightPercentage);
   371 	TMMFDevSoundProxySettingsPckg pckg(set);
   372 	aMessage.WriteL(TInt(2),pckg);
   373 	return ETrue;
   374 	}
   375 
   376 TBool CMMFDevSoundSession::DoSetRecordBalanceL(const RMmfIpcMessage& aMessage)
   377 	{
   378 	TMMFDevSoundProxySettingsPckg buf;
   379 	aMessage.ReadL(TInt(0),buf);
   380 	TInt leftPercentage = buf().iLeftPercentage;
   381 	TInt rightPercentage = buf().iRightPercentage;
   382 	iBody->SetRecordBalanceL(leftPercentage, rightPercentage);
   383 	return ETrue;
   384 	}
   385 
   386 TBool CMMFDevSoundSession::DoPlayInitL(const RMmfIpcMessage& /*aMessage*/)
   387 	{
   388 	iBody->PlayInitL();
   389 	return ETrue;
   390 	}
   391 
   392 TBool CMMFDevSoundSession::DoRecordInitL(const RMmfIpcMessage& aMessage)
   393 	{
   394 	iBody->RecordInitL(aMessage);
   395 	return ETrue;
   396 	}
   397 
   398 TBool CMMFDevSoundSession::DoPlayDataL(const RMmfIpcMessage& aMessage)
   399 	{
   400 	TMMFDevSoundProxyHwBufPckg buf;
   401 	aMessage.ReadL(TInt(0),buf);
   402 	iBufferPlay->SetLastBuffer(buf().iLastBuffer);
   403 
   404 	aMessage.ReadL(TInt(1),iBufferPlay->Data());
   405 	return iBody->PlayData(aMessage);
   406 	}
   407 
   408 TBool CMMFDevSoundSession::DoRecordDataL(const RMmfIpcMessage& aMessage)
   409 	{
   410 	return iBody->RecordData(aMessage);
   411 	}
   412 
   413 TBool CMMFDevSoundSession::DoStopL(const RMmfIpcMessage& /*aMessage*/)
   414 	{
   415 	if(iMsgQueue.Handle() != 0)
   416 		{
   417 		TMMFDevSoundQueueItem queueItem;
   418 		TInt err = KErrNone;
   419 		while(err != KErrUnderflow)
   420 			{
   421 			err = iMsgQueue.Receive(queueItem);
   422 			}		
   423 		}
   424 	iBody->Stop();
   425 	return ETrue;
   426 	}
   427 
   428 TBool CMMFDevSoundSession::DoPauseL(const RMmfIpcMessage& /*aMessage*/)
   429 	{
   430 	iBody->Pause();
   431 	return ETrue;
   432 	}
   433 
   434 TBool CMMFDevSoundSession::DoPlayToneL(const RMmfIpcMessage& aMessage)
   435 	{
   436 	TMMFDevSoundProxySettingsPckg buf;
   437 	aMessage.ReadL(TInt(0),buf);
   438 	TInt frequency = buf().iFrequencyOne;
   439 	TTimeIntervalMicroSeconds duration(buf().iDuration);
   440 	iBody->PlayToneL(frequency, duration);
   441 	return ETrue;
   442 	}
   443 
   444 TBool CMMFDevSoundSession::DoPlayDualToneL(const RMmfIpcMessage& aMessage)
   445 	{
   446 	TMMFDevSoundProxySettingsPckg buf;
   447 	aMessage.ReadL(TInt(0),buf);
   448 	TInt frequencyOne = buf().iFrequencyOne;
   449 	TInt frequencyTwo = buf().iFrequencyTwo;
   450 	TTimeIntervalMicroSeconds duration(buf().iDuration);
   451 	iBody->PlayDualToneL(frequencyOne, frequencyTwo, duration);
   452 	return ETrue;
   453 	}
   454 
   455 TBool CMMFDevSoundSession::DoPlayDTMFStringL(const RMmfIpcMessage& aMessage)
   456 	{
   457 	TInt DTMFLength = User::LeaveIfError(aMessage.GetDesLength(0));
   458 
   459 	if(iDTMFString)
   460 		{
   461 		delete iDTMFString;
   462 		iDTMFString = NULL;
   463 		}
   464 
   465 	iDTMFString = HBufC::NewL(DTMFLength);
   466 	TPtr DTMFPtr = iDTMFString->Des();
   467 	aMessage.ReadL(TInt(0), DTMFPtr);
   468 
   469 	iBody->PlayDTMFStringL(*iDTMFString);
   470 	return ETrue;
   471 	}
   472 
   473 TBool CMMFDevSoundSession::DoPlayToneSequenceL(const RMmfIpcMessage& aMessage)
   474 	{
   475 	TInt toneLength = User::LeaveIfError(aMessage.GetDesLength(0));
   476 
   477 	if(iToneSeqBuf)
   478 		{
   479 		delete iToneSeqBuf;
   480 		iToneSeqBuf = NULL;
   481 		}
   482 
   483 	iToneSeqBuf = HBufC8::NewL(toneLength);
   484 	TPtr8 toneSeqPtr = iToneSeqBuf->Des();
   485 	aMessage.ReadL(TInt(0), toneSeqPtr);
   486 
   487 	iBody->PlayToneSequenceL(*iToneSeqBuf);
   488 	return ETrue;
   489 	}
   490 
   491 TBool CMMFDevSoundSession::DoPlayFixedSequenceL(const RMmfIpcMessage& aMessage)
   492 	{
   493 	TPckgBuf<TInt> buf;
   494 	aMessage.ReadL(TInt(0),buf);
   495 	TInt seqNum = buf();
   496 
   497 	iBody->PlayFixedSequenceL(seqNum);
   498 	return ETrue;
   499 	}
   500 
   501 TBool CMMFDevSoundSession::DoSetDTMFLengthsL(const RMmfIpcMessage& aMessage)
   502 	{
   503 	TMMFDevSoundProxySettingsPckg buf;
   504 	aMessage.ReadL(TInt(0),buf);
   505 	TTimeIntervalMicroSeconds32 toneOnLength = buf().iToneOnLength;
   506 	TTimeIntervalMicroSeconds32 toneOffLength = buf().iToneOffLength;
   507 	TTimeIntervalMicroSeconds32 pauseLength = buf().iPauseLength;
   508 	iBody->SetDTMFLengths(toneOnLength, toneOffLength, pauseLength);
   509 	return ETrue;
   510 	}
   511 
   512 TBool CMMFDevSoundSession::DoSetVolumeRampL(const RMmfIpcMessage& aMessage)
   513 	{
   514 	TMMFDevSoundProxySettingsPckg buf;
   515 	aMessage.ReadL(TInt(0),buf);
   516 	TTimeIntervalMicroSeconds duration = buf().iDuration;
   517 	iBody->SetVolumeRamp(duration);
   518 	return ETrue;
   519 	}
   520 
   521 TBool CMMFDevSoundSession::DoGetSupportedInputDataTypesL(const RMmfIpcMessage& aMessage)
   522 	{
   523 	iArray.Reset();
   524 
   525 	TMMFPrioritySettingsPckg buf;
   526 	aMessage.ReadL(TInt(0),buf);
   527 	TMMFPrioritySettings prioritySet = buf();
   528 
   529 	iBody->GetSupportedInputDataTypesL(iArray, prioritySet);
   530 
   531 	TPckgBuf<TInt> pckg;
   532 	pckg() = iArray.Count();
   533 	aMessage.WriteL(TInt(2),pckg);
   534 
   535 	return ETrue;
   536 	}
   537 
   538 TBool CMMFDevSoundSession::DoGetSupportedOutputDataTypesL(const RMmfIpcMessage& aMessage)
   539 	{
   540 	iArray.Reset();
   541 
   542 	TMMFPrioritySettingsPckg buf;
   543 	aMessage.ReadL(TInt(0),buf);
   544 	TMMFPrioritySettings prioritySet = buf();
   545 
   546 	iBody->GetSupportedOutputDataTypesL(iArray, prioritySet);
   547 
   548 	TPckgBuf<TInt> pckg;
   549 	pckg() = iArray.Count();
   550 	aMessage.WriteL(TInt(2),pckg);
   551 
   552 	return ETrue;
   553 	}
   554 
   555 TBool CMMFDevSoundSession::DoSamplesRecordedL(const RMmfIpcMessage& aMessage)
   556 	{
   557 	TPckgBuf<TInt> pckg;
   558 	pckg() = iBody->SamplesRecorded();
   559 	aMessage.WriteL(TInt(2),pckg);
   560 	return ETrue;
   561 	}
   562 
   563 TBool CMMFDevSoundSession::DoSamplesPlayedL(const RMmfIpcMessage& aMessage)
   564 	{
   565 	TPckgBuf<TInt> pckg;
   566 	pckg() = iBody->SamplesPlayed();
   567 	aMessage.WriteL(TInt(2),pckg);
   568 	return ETrue;
   569 	}
   570 
   571 TBool CMMFDevSoundSession::DoSetToneRepeatsL(const RMmfIpcMessage& aMessage)
   572 	{
   573 	TPckgBuf<TInt> countRepeat;
   574 	aMessage.ReadL(TInt(0),countRepeat);
   575 
   576 	TPckgBuf<TTimeIntervalMicroSeconds> repeatTS;
   577 	aMessage.ReadL(TInt(1),repeatTS);
   578 
   579 	iBody->SetToneRepeats(countRepeat(), repeatTS());
   580 	return ETrue;
   581 	}
   582 
   583 TBool CMMFDevSoundSession::DoSetPrioritySettingsL(const RMmfIpcMessage& aMessage)
   584 	{
   585 	TPckgBuf<TMMFPrioritySettings> prioritySet;
   586 	aMessage.ReadL(TInt(0),prioritySet);
   587 
   588 	iBody->SetPrioritySettings(prioritySet());
   589 	return ETrue;
   590 	}
   591 
   592 TBool CMMFDevSoundSession::DoFixedSequenceNameL(const RMmfIpcMessage& aMessage)
   593 	{
   594 	TPckgBuf<TInt> seqNum;
   595 	aMessage.ReadL(0, seqNum);
   596 	aMessage.WriteL(2, iBody->FixedSequenceName(seqNum()).Left(KMaxFixedSequenceNameLength));
   597 	return ETrue;
   598 	}
   599 
   600 TBool CMMFDevSoundSession::DoFixedSequenceCountL(const RMmfIpcMessage& aMessage)
   601 	{
   602 	TPckgBuf<TInt> fixSeqCountPckg;
   603 	TInt fixSeqCount = iBody->FixedSequenceCount();
   604 	fixSeqCountPckg = fixSeqCount;
   605 
   606 	aMessage.WriteL(TInt(0),fixSeqCountPckg);
   607 	return ETrue;
   608 	}
   609 
   610 
   611 TBool CMMFDevSoundSession::DoCopyFourCCArrayDataL(const RMmfIpcMessage& aMessage)
   612 	{
   613 	const TInt KBufExpandSize8 = 8;//two TInts
   614 	CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
   615 	CleanupStack::PushL(dataCopyBuffer);
   616 	RBufWriteStream stream;
   617 	stream.Open(*dataCopyBuffer);
   618 	CleanupClosePushL(stream);
   619 	for (TInt i=0;i<iArray.Count();i++)
   620 		{
   621 		stream.WriteInt32L(iArray[i].FourCC());
   622 		}
   623 	aMessage.WriteL(TInt(2), dataCopyBuffer->Ptr(0));
   624 	CleanupStack::PopAndDestroy(2);//iDataCopyBuffer, stream
   625 	return ETrue;
   626 	}
   627 
   628 
   629 TBool CMMFDevSoundSession::DoGetRecordedBufferL(const RMmfIpcMessage& aMessage)
   630 	{
   631 	MmfMessageUtil::Write(aMessage, TInt(0), iBufferRecord->Data());
   632 	return ETrue;
   633 	}
   634 
   635 TBool CMMFDevSoundSession::DoBufferToBeFilledDataL(const RMmfIpcMessage& aMessage)
   636 	{
   637 	TInt err = MmfMessageUtil::Write(aMessage, 0, iHwBufPckgFill);
   638 	aMessage.Complete(err);
   639 	return EFalse;
   640 	}
   641 
   642 TBool CMMFDevSoundSession::DoBufferToBeEmptiedDataL(const RMmfIpcMessage& aMessage)
   643 	{
   644 	TInt err = MmfMessageUtil::Write(aMessage, 0, iHwBufPckgEmpty);
   645 	aMessage.Complete(err);
   646 	return EFalse;
   647 	}
   648 
   649 TBool CMMFDevSoundSession::DoRegisterAsClientL(const RMmfIpcMessage& aMessage)
   650 	{
   651 	TMMFDevSoundProxySettingsPckg buf;
   652 	aMessage.ReadL(0,buf);
   653 	HBufC8* notificationRegistrationData = NULL;
   654 	notificationRegistrationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLengthL(1)));
   655 	TPtr8 dataPtr(notificationRegistrationData->Des());  	
   656 	aMessage.ReadL(1,dataPtr);
   657 	TInt err = KErrNone;
   658 	err = iBody->RegisterAsClient(buf().iNotificationEventUid,dataPtr);
   659 	CleanupStack::PopAndDestroy(1); // Notification Registeration data
   660 	if (err != KErrNone)
   661 		{
   662 		aMessage.Complete(err);
   663 		return EFalse;		
   664 		}
   665 	return ETrue;
   666 	}
   667 	
   668 TBool CMMFDevSoundSession::DoCancelRegisterAsClientL(const RMmfIpcMessage& aMessage)
   669 	{
   670 	TMMFDevSoundProxySettingsPckg buf;
   671 	aMessage.ReadL(0,buf);
   672 	TInt err = KErrNone;
   673 	err = iBody->CancelRegisterAsClient(buf().iNotificationEventUid);
   674 	if (err != KErrNone)
   675 		{
   676 		aMessage.Complete(err);
   677 		return EFalse;		
   678 		}
   679 	return ETrue;
   680 	}
   681 
   682 TBool CMMFDevSoundSession::DoGetResourceNotificationDataL(const RMmfIpcMessage& aMessage)
   683 	{
   684 	TMMFDevSoundProxySettingsPckg buf;
   685 	aMessage.ReadL(0,buf);
   686 	HBufC8* notificationData = NULL;
   687 	notificationData = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesMaxLengthL(2)));
   688 	TPtr8 dataPtr(notificationData->Des());  	
   689 	aMessage.ReadL(2,dataPtr);
   690 	TInt err = KErrNone;
   691 	err = iBody->GetResourceNotificationData(buf().iNotificationEventUid,dataPtr);
   692 	aMessage.WriteL(2,*notificationData);
   693 	CleanupStack::PopAndDestroy(1); // Notification data
   694 	if (err != KErrNone)
   695 		{
   696 		aMessage.Complete(err);
   697 		return EFalse;		
   698 		}
   699 	return ETrue;
   700 	}
   701 
   702 TBool CMMFDevSoundSession::DoWillResumePlayL(const RMmfIpcMessage& aMessage)
   703 	{
   704 	TInt err = KErrNone;
   705 	if(CheckClientCapabilities())
   706 		{
   707 		err = iBody->WillResumePlay();
   708 		}
   709 	else
   710 		{
   711 		err = KErrPermissionDenied;
   712 		}
   713 		
   714 	if (err != KErrNone)
   715 		{
   716 		aMessage.Complete(err);
   717 		return EFalse;		
   718 		}
   719 	return ETrue;
   720 	}
   721 	
   722 TBool CMMFDevSoundSession::DoEmptyBuffersL(const RMmfIpcMessage& aMessage)
   723 	{
   724 	TInt err = KErrNone;
   725 	err = iBody->EmptyBuffers();
   726 	if (err != KErrNone)
   727 		{
   728 		aMessage.Complete(err);
   729 		return EFalse;		
   730 		}
   731 	return ETrue;
   732 	}
   733 
   734 TBool CMMFDevSoundSession::DoSetClientThreadInfoL(const RMmfIpcMessage& aMessage)
   735 	{
   736 	if (aMessage.HasCapability(ECapabilityMultimediaDD))
   737 		{
   738 		TPckgBuf<TThreadId> threadId;
   739 		aMessage.ReadL(0, threadId);
   740 		
   741 		CMMFDevSoundServer* server = 
   742 			const_cast<CMMFDevSoundServer*>(static_cast<const CMMFDevSoundServer*>(Server()));
   743 		server->SetClientCapabilitiesL(threadId());
   744 		iClientHasCaps = server->CheckClientCapabilities();	
   745 		}
   746 	else
   747 		{
   748 		User::Leave(KErrPermissionDenied);
   749 		}
   750 	return ETrue;
   751 	}
   752 	
   753 TBool CMMFDevSoundSession::DoGetTimePlayedL(const RMmfIpcMessage& aMessage)
   754 	{
   755 	TInt err = KErrNone;
   756 	TPckgBuf<TTimeIntervalMicroSeconds> timePckg;
   757 	err = iBody->GetTimePlayed(timePckg());
   758 	if (err != KErrNone)
   759 		{
   760 		aMessage.Complete(err);
   761 		return EFalse;		
   762 		}
   763 	aMessage.WriteL(TInt(2),timePckg);
   764 	return ETrue;
   765 	}
   766 
   767 TBool CMMFDevSoundSession::DoSyncCustomCommandL(const RMmfIpcMessage& aMessage)
   768 	{
   769 	// check whether these are custom interface commands
   770 	// if so then send them into the demux pipeline
   771 	TInt retVal = KErrNone;
   772 	
   773 	// try and process this as a custom interface
   774 	TRAPD(err, retVal = iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
   775 	if (err == KErrNone)
   776 		{
   777 		// we can pass back valid values here since command
   778 		// has been handled by the DeMux framework
   779 		aMessage.Complete(retVal);	
   780 		}
   781 	else if (err != KErrNotFound)
   782 		{
   783 		// the framework left with an error condition
   784 		// so we complete the message with this error
   785 		aMessage.Complete(err);
   786 		}
   787 	else 
   788 		{
   789 		// commmand was not found inside the Custom Interface framework
   790 		// so we can pass onto the DevSound server implementation
   791 		// assume that this will either leave or complete the message
   792 		iBody->DoSyncCustomCommandL(aMessage);
   793 		}
   794 	
   795 	// we complete our own message so don't need the framework to do so
   796 	return EFalse;		
   797 	}
   798 	
   799 TBool CMMFDevSoundSession::DoSyncCustomCommandResultL(const RMmfIpcMessage& aMessage)
   800 	{	
   801 	// check whether these are custom interface commands
   802 	TInt retVal = KErrNone;
   803 	TRAPD(err, retVal = iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
   804 	if (err == KErrNone)
   805 		{
   806 		// we can pass back valid values here since command
   807 		// has been handled by the DeMux framework
   808 		aMessage.Complete(retVal);	
   809 		}
   810 	else if (err != KErrNotFound)
   811 		{
   812 		// the framework left with an error condition
   813 		// so we complete the message with this error
   814 		aMessage.Complete(err);
   815 		}
   816 	else 
   817 		{
   818 		// commmand was not found inside the Custom Interface framework
   819 		// so we can pass onto the DevSound server implementation
   820 		// assume that this will either leave or complete the message
   821 		iBody->DoSyncCustomCommandResultL(aMessage);
   822 		}
   823 	// we complete our own message so don't need the framework to do so
   824 	return EFalse;		
   825 	}
   826 	
   827 TBool CMMFDevSoundSession::DoAsyncCustomCommandL(const RMmfIpcMessage& aMessage)
   828 	{
   829 	// check whether these are custom interface commands
   830 	// async message will complete later
   831 	TRAPD(err, iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
   832 	if ((err != KErrNotFound) && (err != KErrNone))
   833 		{
   834 		// the framework left with an error condition
   835 		// so we complete the message with this error
   836 		aMessage.Complete(err);
   837 		}
   838 	else if (err == KErrNotFound)
   839 		{
   840 		// commmand was not found inside the Custom Interface framework
   841 		// so we can pass onto the DevSound server implementation
   842 		// assume that this will either leave or complete the message
   843 		iBody->DoAsyncCustomCommandL(aMessage);
   844 		}
   845 	return EFalse;
   846 	}
   847 	
   848 TBool CMMFDevSoundSession::DoAsyncCustomCommandResultL(const RMmfIpcMessage& aMessage)
   849 	{
   850 	// check whether these are custom interface commands
   851 	// async message will complete later
   852 	TRAPD(err, iDeMuxUtility->ProcessCustomInterfaceCommandL(aMessage));
   853 	if ((err != KErrNotFound) && (err != KErrNone))
   854 		{
   855 		// the framework left with an error condition
   856 		// so we complete the message with this error
   857 		aMessage.Complete(err);
   858 		}
   859 	else if (err == KErrNotFound)
   860 		{
   861 		// commmand was not found inside the Custom Interface framework
   862 		// so we can pass onto the DevSound server implementation
   863 		// assume that this will either leave or complete the message
   864 		iBody->DoAsyncCustomCommandL(aMessage);
   865 		}
   866 	return EFalse;
   867 	}
   868 
   869 
   870 
   871 void CMMFDevSoundSession::SendEventToClient(/*TMMFAudioPolicyEvent& aEvent*/)
   872 	{
   873 	}
   874 
   875 
   876 /*
   877  *
   878  *	Default Constructor.
   879  *
   880  *
   881  */
   882 CMMFDevSoundSession::CMMFDevSoundSession()
   883 	{
   884 	}
   885 
   886 CMMFDevSoundSession::~CMMFDevSoundSession()
   887 	{
   888 	// clear the array of custom interfaces
   889 	for (TInt i = 0; i < iCustomInterfaceArray.Count(); i++)
   890 		{
   891 		// we could have already deleted interfaces without
   892 		// removing them from the array so check for this
   893 		// and only delete release plugin if non-null
   894 		MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface;
   895 		if (ptr)
   896 			{
   897 			iCustomInterfaceArray[i].iInterface->Release();	
   898 			}
   899 		}
   900 	iCustomInterfaceArray.Reset();
   901 	iCustomInterfaceArray.Close();
   902 		
   903 	delete iDeMuxUtility;
   904 
   905 	iMsgQueue.Close();
   906 	iArray.Close();
   907 	delete iDTMFString;
   908 	delete iToneSeqBuf;
   909 	delete iBody;
   910 
   911 	CMMFDevSoundServer* server = 
   912 		const_cast<CMMFDevSoundServer*>(static_cast<const CMMFDevSoundServer*>(Server()));
   913 	if (server)
   914 		{
   915 		server->DecrementSessionId();		
   916 		}
   917 	}
   918 
   919 /*
   920  *  -doxygen comments moved to header-
   921  *
   922  *	Constructs, and returns a pointer to, a new CMMFDevSoundProxy object.
   923  *
   924  *	Leaves on failure.
   925  *
   926  */
   927 CMMFDevSoundSession* CMMFDevSoundSession::NewL(RServer2& aPolicyServerHandle)
   928 	{
   929 	CMMFDevSoundSession* self = new (ELeave) CMMFDevSoundSessionXtnd;
   930 	CleanupStack::PushL(self);
   931 	self->ConstructL(aPolicyServerHandle);
   932 	CleanupStack::Pop();
   933 	return self;
   934 	}
   935 
   936 /*
   937  *  -doxygen comments moved to header-
   938  *
   939  *	Second phase constructor.
   940  *
   941  */
   942 void CMMFDevSoundSession::ConstructL(RServer2& aPolicyServerHandle)
   943 	{
   944 	iBody = CMMFDevSoundSvrImp::NewL(static_cast<CMMFDevSoundSessionXtnd*>(this));
   945 	iBody->Construct3L(aPolicyServerHandle);
   946 	
   947 	iDeMuxUtility = CMMFDevSoundCIDeMuxUtility::NewL(this);
   948 	}
   949 
   950 //callbacks
   951 void CMMFDevSoundSession::InitializeComplete(TInt aError)
   952 	{
   953 	// this may be a re-initialization and so we need to
   954 	// re-get our custom interfaces on the DeMux plugins
   955 	for (TInt i = 0; i < iCustomInterfaceArray.Count(); i++)
   956 		{
   957 		// we could have already deleted interfaces without
   958 		// removing them from the array so check for this
   959 		// and only delete release plugin if non-null
   960 		MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = iCustomInterfaceArray[i].iInterface;
   961 		if (ptr)
   962 			{
   963 			// we can't keep track of..
   964 			// 1. where a custom interface is implemented
   965 			// 2. the uid of the custom interface to be refreshed
   966 			// so assume all have to be refreshed
   967 			TRAPD(err, iCustomInterfaceArray[i].iInterface->RefreshL());	
   968 			
   969 			// if there is an error then this is no longer a 
   970 			// valid interface so could be deleted this from the array
   971 			// but this would involve notifying the client side
   972 			//
   973 			// since we have no way of notifying the client in this
   974 			// implementation and the fact that this is a prototype 
   975 			// implementation and we will leave this up to the licensee 
   976 			// to implement as required
   977 			if (err != KErrNone)
   978 				{
   979 				TMMFEvent event;
   980 				TMMFDevSoundQueueItem item;
   981 				item.iRequest = EMMFDevSoundCustomCommandCloseMuxDemuxPair;
   982 				item.iErrorCode = err;
   983 				event.iEventType.iUid = i+1;
   984 				item.iEventPckg() = event;
   985 				iMsgQueue.Send(item);
   986 				}
   987 			}
   988 		}
   989 	
   990 	// The previous implementation was commented out,
   991 	// so add a new commented out implementation :)
   992 	TMMFDevSoundQueueItem item;
   993 	item.iRequest = EMMFDevSoundProxyICEvent;
   994 	item.iErrorCode = aError;
   995 	iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
   996 	}
   997 
   998 void CMMFDevSoundSession::ToneFinished(TInt aError)
   999 	{
  1000 	TMMFDevSoundQueueItem item;
  1001 	item.iRequest = EMMFDevSoundProxyTFEvent;
  1002 	item.iErrorCode = aError;
  1003 	iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
  1004 	}
  1005 
  1006 void CMMFDevSoundSession::BufferToBeFilled(CMMFBuffer* aBuffer)
  1007 	{
  1008 	// Package up the data for retrieval later (using a two stage process
  1009 	// as this payload is too large to be sent via the queue in one message)	
  1010 	iBufferPlay = reinterpret_cast<CMMFDataBuffer*>(aBuffer);
  1011 	iHwBufPckgFill().iBufferType = iBufferPlay->Type();
  1012 	iHwBufPckgFill().iRequestSize = iBufferPlay->RequestSize();
  1013 	iHwBufPckgFill().iBufferSize = iBufferPlay->Data().MaxLength();
  1014 	iHwBufPckgFill().iLastBuffer = iBufferPlay->LastBuffer();	
  1015 	
  1016 	TMMFDevSoundQueueItem item;
  1017 	item.iRequest = EMMFDevSoundProxyBTBFEvent;
  1018 	iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
  1019 	}
  1020 
  1021 void CMMFDevSoundSession::PlayError(TInt aError)
  1022 	{
  1023 	TMMFDevSoundQueueItem item;
  1024 	item.iRequest = EMMFDevSoundProxyPEEvent;
  1025 	item.iErrorCode = aError;
  1026 	iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
  1027 	}
  1028 
  1029 void CMMFDevSoundSession::BufferToBeEmptied(CMMFBuffer* aBuffer)
  1030 	{
  1031 	iBufferRecord = reinterpret_cast<CMMFDataBuffer*>(aBuffer);
  1032 
  1033 	iHwBufPckgEmpty().iBufferType = iBufferRecord->Type();
  1034 	iHwBufPckgEmpty().iRequestSize = iBufferRecord->RequestSize();
  1035 	iHwBufPckgEmpty().iBufferSize = iBufferRecord->Data().MaxLength();
  1036 	iHwBufPckgEmpty().iLastBuffer = iBufferRecord->LastBuffer();
  1037 	
  1038 	TMMFDevSoundQueueItem item;
  1039 	item.iRequest = EMMFDevSoundProxyBTBEEvent;
  1040 	iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
  1041 	}
  1042 
  1043 void CMMFDevSoundSession::RecordError(TInt aError)
  1044 	{
  1045 	TMMFDevSoundQueueItem item;
  1046 	item.iRequest = EMMFDevSoundProxyREEvent;
  1047 	item.iErrorCode = aError;
  1048 	iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
  1049 	}
  1050 
  1051 void CMMFDevSoundSession::ConvertError(TInt /*aError*/)
  1052 	{
  1053 	}
  1054 
  1055 void CMMFDevSoundSession::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /*aMsg*/)
  1056 	{
  1057 	}
  1058 
  1059 void CMMFDevSoundSession::SendEventToClient(const TMMFEvent& aEvent)
  1060 	{
  1061 	TMMFDevSoundQueueItem item;
  1062 	item.iRequest = EMMFDevSoundProxySETCEvent;
  1063 	item.iEventPckg() = aEvent;
  1064 	iMsgQueue.Send(item); // assumes sufficient space in the queue so ignores the return value
  1065     }
  1066 
  1067 /********************************************************************************
  1068  *				Non Exported public functions begins here						*
  1069  ********************************************************************************/
  1070 
  1071 //
  1072 //				Audio Policy specific implementation begins here				//
  1073 //
  1074 
  1075 /**
  1076  *
  1077  *	Sets Id for this instance of DevSound
  1078  *
  1079  *	@param	"TInt aDevSoundId"
  1080  *			Integer value assigned by Audio Policy Server
  1081  *
  1082  */
  1083 void CMMFDevSoundSessionXtnd::SetDevSoundId(TInt aDevSoundId)
  1084 	{
  1085 	iBody->SetDevSoundId(aDevSoundId);
  1086 	}
  1087 
  1088 /**
  1089  *
  1090  *	Returns information about this DevSound instance.
  1091  *
  1092  *	This method is used by Audio Policy Server to make audio policy decisions.
  1093  *
  1094  *	@return	"TMMFDevSoundinfo"
  1095  *			A reference to TMMFDevSoundinfo object holding the current settings
  1096  *			of this DevSound instance.
  1097  *
  1098  */
  1099 TMMFDevSoundInfo CMMFDevSoundSessionXtnd::DevSoundInfo()
  1100 	{
  1101  	return iBody->DevSoundInfo();
  1102 	}
  1103 
  1104 /**
  1105  *
  1106  *	Called by Audio Policy Server when a request to play is approved by the 
  1107  *	Audio Policy Server.
  1108  *
  1109  *	Leaves on failure.
  1110  *
  1111  */
  1112 void CMMFDevSoundSessionXtnd::StartPlayDataL()
  1113 	{
  1114 	iBody->StartPlayDataL();
  1115 	}
  1116 
  1117 /**
  1118  *
  1119  *	Called by Audio Policy Server when a request to record is approved by the 
  1120  *	Audio Policy Server.
  1121  *
  1122  *	Leaves on failure.
  1123  *
  1124  */
  1125 void CMMFDevSoundSessionXtnd::StartRecordDataL()
  1126 	{
  1127 	iBody->StartRecordDataL();
  1128 	}
  1129 
  1130 /**
  1131  *
  1132  *	Called by Audio Policy Server when a request to play tone is approved by
  1133  *	the Audio Policy Server.
  1134  *
  1135  *	Leaves on failure.
  1136  *
  1137  */
  1138 void CMMFDevSoundSessionXtnd::StartPlayToneL()
  1139 	{
  1140 	iBody->StartPlayToneL();
  1141 	}
  1142 
  1143 /**
  1144  *
  1145  *	Called by Audio Policy Server when a request to play a dual tone is approved by
  1146  *	the Audio Policy Server.
  1147  *
  1148  */
  1149 void CMMFDevSoundSessionXtnd::StartPlayDualToneL()
  1150 	{
  1151 	iBody->StartPlayDualToneL();
  1152 	}
  1153 
  1154 /**
  1155  *
  1156  *	Called by Audio Policy Server when a request to play DTMF String is approved
  1157  *	by the Audio Policy Server.
  1158  *
  1159  *	Leaves on failure.
  1160  *
  1161  */
  1162 void CMMFDevSoundSessionXtnd::StartPlayDTMFStringL()
  1163 	{
  1164 	iBody->StartPlayDTMFStringL();
  1165 	}
  1166 
  1167 /**
  1168  *
  1169  *	Called by Audio Policy Server when a request to play tone sequence is
  1170  *	approved by the Audio Policy Server.
  1171  *
  1172  *	Leaves on failure.
  1173  *
  1174  */
  1175 void CMMFDevSoundSessionXtnd::StartPlayToneSequenceL()
  1176 	{
  1177 	iBody->StartPlayToneSequenceL();
  1178 	}
  1179 
  1180 /**
  1181  *
  1182  *	Called by Audio Policy Server when the current DevSound instance looses the
  1183  *	policy because of another instance with a higher priority wants the device.
  1184  *
  1185  */
  1186 void CMMFDevSoundSessionXtnd::SendEvent(const TMMFEvent& aEvent)
  1187 	{
  1188 	iBody->SendEventToClient(aEvent);
  1189 	}
  1190 
  1191 
  1192 //
  1193 //				Audio Policy specific implementation begins here				//
  1194 //
  1195 
  1196 /**
  1197  *
  1198  *	Updates the total bytes played.
  1199  *
  1200  */
  1201 void CMMFDevSoundSessionXtnd::UpdateBytesPlayed()
  1202 	{
  1203 	iBody->UpdateBytesPlayed();
  1204 	}
  1205 
  1206 
  1207 // Custom Interface //
  1208 TInt CMMFDevSoundSession::DoOpenSlaveL(TUid aInterface, const TDesC8& aPackageBuf)
  1209 	{
  1210 	// it shouldn't be necessary to check if we have already instantiated this
  1211 	// interface since the client would already know - however this is something
  1212 	// that a licensee could implement if they required additional functionality
  1213 	// e.g. many : 1 mappings between client and DevSound.
  1214 
  1215 	MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = NULL;
  1216 		
  1217 	// try and instantiate a plugin tunnelling
  1218 	// pair to support this Custom Interface
  1219 	ptr = iDeMuxUtility->CreateCustomInterfaceDeMuxL(aInterface);
  1220 	
  1221 	TInt handle = KNullHandle;
  1222 	
  1223 	if (ptr)
  1224 		{
  1225 		TMMFDevSoundCustomInterfaceDeMuxData data;
  1226 		data.iInterface = ptr;
  1227 		data.iId = aInterface;
  1228 			
  1229 		CleanupReleasePushL(*ptr);
  1230 			
  1231 		// setup demux plugin
  1232 		ptr->SetInterfaceTarget(iBody);
  1233 			
  1234 		// try and open interface
  1235 		// this will fetch the interface from the svr implementation
  1236 		ptr->DoOpenSlaveL(aInterface, aPackageBuf);
  1237 		User::LeaveIfError(iCustomInterfaceArray.Append(data));
  1238 			
  1239 		CleanupStack::Pop();	// ptr
  1240 			
  1241 		handle = iCustomInterfaceArray.Count();
  1242 		return handle;
  1243 		}
  1244 
  1245 	// we couldn't set up the interface correctly so return a NULL
  1246 	// handle to the client
  1247 	return KNullHandle;
  1248 	}
  1249 	
  1250 void CMMFDevSoundSession::DoCloseSlaveL(TInt aHandle)
  1251 	{
  1252 	if (aHandle==KNullHandle)
  1253 		{
  1254 		// null-handle -> NOP
  1255 		return;
  1256 		}
  1257 		
  1258 	if (aHandle<KNullHandle || aHandle > iCustomInterfaceArray.Count())
  1259 		{
  1260 		// handle out of range - should not happen, but leave to show error
  1261 		User::Leave(KErrBadHandle);
  1262 		}
  1263 		
  1264 	// set the current handle location to NULL
  1265 	// can't re-compress array because this will alter handles
  1266 	// we could change this to a list type structure but this 
  1267 	// seems overkill for the current prototype
  1268 	TMMFDevSoundCustomInterfaceDeMuxData& data = iCustomInterfaceArray[aHandle-1];
  1269 	
  1270 	// close and delete the plugin
  1271 	MMMFDevSoundCustomInterfaceDeMuxPlugin* ptr = data.iInterface;
  1272 	ptr->DoCloseSlaveL(aHandle);
  1273 	ptr->Release();
  1274 	
  1275 	// clear the entry
  1276 	data.iInterface = NULL;
  1277 	data.iId.iUid = 0;
  1278 	}
  1279 	
  1280 TInt CMMFDevSoundSession::DoSendSlaveSyncCommandL(const RMmfIpcMessage& aMessage)
  1281 	{
  1282 	// use the demux utility to get the handle
  1283 	TMMFDevSoundCIMessageData data;
  1284 	iDeMuxUtility->GetSyncMessageDataL(aMessage, data);
  1285 	
  1286 	TInt handle = data.iHandle;
  1287 	
  1288 	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
  1289 		{
  1290 		
  1291 		User::Leave(KErrBadHandle);
  1292 		}
  1293 	
  1294 	// call on demux plugin
  1295 	return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandL(aMessage);	
  1296 	}
  1297 	
  1298 TInt CMMFDevSoundSession::DoSendSlaveSyncCommandResultL(const RMmfIpcMessage& aMessage)
  1299 	{
  1300 	// use the demux utility to get the handle
  1301 	TMMFDevSoundCIMessageData data;
  1302 	iDeMuxUtility->GetSyncMessageDataL(aMessage, data);
  1303 	
  1304 	TInt handle = data.iHandle;
  1305 	
  1306 	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
  1307 		{
  1308 		
  1309 		User::Leave(KErrBadHandle);
  1310 		}
  1311 	
  1312 	// call on demux plugin
  1313 	return iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveSyncCommandResultL(aMessage);	
  1314 	}
  1315 	
  1316 void CMMFDevSoundSession::DoSendSlaveAsyncCommandL(const RMmfIpcMessage& aMessage)
  1317 	{
  1318 	// use the demux utility to get the handle
  1319 	TMMFDevSoundCIMessageData data;
  1320 	iDeMuxUtility->GetAsyncMessageDataL(aMessage, data);
  1321 	
  1322 	TInt handle = data.iHandle;
  1323 	
  1324 	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
  1325 		{
  1326 		User::Leave(KErrBadHandle);
  1327 		}
  1328 	
  1329 	// call on demux plugin
  1330 	iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandL(aMessage);	
  1331 	}
  1332 	
  1333 void CMMFDevSoundSession::DoSendSlaveAsyncCommandResultL(const RMmfIpcMessage& aMessage)
  1334 	{
  1335 	// use the demux utility to get the handle
  1336 	TMMFDevSoundCIMessageData data;
  1337 	iDeMuxUtility->GetAsyncMessageDataL(aMessage, data);
  1338 	
  1339 	TInt handle = data.iHandle;
  1340 	
  1341 	if ((handle <= 0) || (handle > (iCustomInterfaceArray.Count())))
  1342 		{
  1343 		User::Leave(KErrBadHandle);
  1344 		}
  1345 	
  1346 	// call on demux plugin
  1347 	iCustomInterfaceArray[handle-1].iInterface->DoSendSlaveAsyncCommandResultL(aMessage);	
  1348 	}
  1349 
  1350 
  1351