sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "MmfDevSoundCIDeMuxUtility.h" sl@0: #include "MmfDevSoundCIMuxUtility.h" // included for command definitions sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: sl@0: CMMFDevSoundCIDeMuxUtility* CMMFDevSoundCIDeMuxUtility::NewL(MMMFDevSoundCustomInterfaceDeMuxInterface* aInterface) sl@0: { sl@0: CMMFDevSoundCIDeMuxUtility* self = new (ELeave) CMMFDevSoundCIDeMuxUtility(aInterface); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: void CMMFDevSoundCIDeMuxUtility::ConstructL() sl@0: { sl@0: // nothing to do in this plugin sl@0: } sl@0: sl@0: CMMFDevSoundCIDeMuxUtility::~CMMFDevSoundCIDeMuxUtility() sl@0: { sl@0: sl@0: } sl@0: sl@0: const TInt KDeMuxTempBufferSize = 20; sl@0: sl@0: // create a custom interface Mux implementation sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* CMMFDevSoundCIDeMuxUtility::CreateCustomInterfaceDeMuxL(TUid aInterfaceId) sl@0: { sl@0: // The Uid of the plugin will be the match string sl@0: TInt uidAsInteger = aInterfaceId.iUid; sl@0: sl@0: TBuf8 tempBuffer; sl@0: tempBuffer.Num(uidAsInteger, EHex); // has value sl@0: TUid interfaceUid = {KUidDevSoundCustomInterfaceDeMux}; sl@0: sl@0: TUid destructorKey; sl@0: MMMFDevSoundCustomInterfaceDeMuxPlugin* self = sl@0: static_cast sl@0: (MmPluginUtils::CreateImplementationL(interfaceUid, destructorKey, tempBuffer, KRomOnlyResolverUid)); sl@0: sl@0: // pass the destructor key so class can destroy itself sl@0: self->PassDestructorKey(destructorKey); sl@0: CleanupReleasePushL(*self); sl@0: sl@0: // attempt to construct the plugin sl@0: self->CompleteConstructL(this); sl@0: CleanupStack::Pop(); // self sl@0: sl@0: return self; sl@0: } sl@0: sl@0: sl@0: // this will leave if the command is not a supported custom interface command sl@0: // the integer being returned is not an error code per-se it is the return code sl@0: // from the message being handled and so it makes sense here to have the function sl@0: // returning an integer but also able to leave if there is a problem sl@0: TInt CMMFDevSoundCIDeMuxUtility::ProcessCustomInterfaceCommandL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf commandBuf; sl@0: MmfMessageUtil::ReadL(aMessage, 1, commandBuf); sl@0: CMMFDevSoundCIMuxUtility::TMMFDevSoundCustomCommand commandType = commandBuf().iType; sl@0: TInt handle = commandBuf().iHandle; sl@0: TInt retVal = KErrNotFound; sl@0: sl@0: switch (commandType) sl@0: { sl@0: case CMMFDevSoundCIMuxUtility::EMMFDevSoundCustomCommandCIOpenSlave: sl@0: { sl@0: // get a local copy of descriptor sl@0: RBuf8 tempBuf; sl@0: tempBuf.CleanupClosePushL(); sl@0: TInt len = InputDesLength(aMessage); sl@0: if (len < 0) sl@0: { sl@0: User::Leave(KErrBadDescriptor); sl@0: } sl@0: else sl@0: { sl@0: tempBuf.CreateL(len); sl@0: } sl@0: ReadFromInputDesL(aMessage, &tempBuf); sl@0: sl@0: TUid interfaceUid(KNullUid); sl@0: interfaceUid.iUid = handle; sl@0: TPckgBuf idBuffer(interfaceUid); sl@0: sl@0: retVal = iInterface->DoOpenSlaveL(idBuffer(), tempBuf); sl@0: CleanupStack::PopAndDestroy(&tempBuf); sl@0: break; sl@0: } sl@0: case CMMFDevSoundCIMuxUtility::EMMFDevSoundCustomCommandCICloseSlave: sl@0: { sl@0: TPckgBuf handleBuffer(handle); sl@0: iInterface->DoCloseSlaveL(handleBuffer()); sl@0: retVal = KErrNone; // no return from CloseSlave sl@0: break; sl@0: } sl@0: case CMMFDevSoundCIMuxUtility::EMMFDevSoundCustomCommandCISendSlaveSyncCommand: sl@0: { sl@0: retVal = iInterface->DoSendSlaveSyncCommandL(aMessage); sl@0: break; sl@0: } sl@0: case CMMFDevSoundCIMuxUtility::EMMFDevSoundCustomCommandCISendSlaveSyncCommandResult: sl@0: { sl@0: retVal = iInterface->DoSendSlaveSyncCommandResultL(aMessage); sl@0: break; sl@0: } sl@0: case CMMFDevSoundCIMuxUtility::EMMFDevSoundCustomCommandCISendSlaveAsyncCommand: sl@0: { sl@0: iInterface->DoSendSlaveAsyncCommandL(aMessage); sl@0: retVal = KErrNone; // no return from async sl@0: break; sl@0: } sl@0: case CMMFDevSoundCIMuxUtility::EMMFDevSoundCustomCommandCISendSlaveAsyncCommandResult: sl@0: { sl@0: iInterface->DoSendSlaveAsyncCommandResultL(aMessage); sl@0: retVal = KErrNone; // no return from async sl@0: break; sl@0: } sl@0: default: sl@0: User::Leave(retVal); sl@0: } sl@0: sl@0: return retVal; sl@0: } sl@0: sl@0: sl@0: // at the moment these two functions are the same but this may change on different platforms sl@0: // so separate sync and async message data functions have been defined sl@0: void CMMFDevSoundCIDeMuxUtility::GetSyncMessageDataL(const RMmfIpcMessage& aMessage, TMMFDevSoundCIMessageData& aData) sl@0: { sl@0: // data is stored as destination, custom command info, inbuf, outbuf sl@0: TPckgBuf comBuffer; sl@0: aMessage.ReadL(1, comBuffer); sl@0: sl@0: // get command and handle sl@0: aData.iCommand = comBuffer().iCommand; sl@0: aData.iHandle = comBuffer().iHandle; sl@0: } sl@0: sl@0: void CMMFDevSoundCIDeMuxUtility::GetAsyncMessageDataL(const RMmfIpcMessage& aMessage, TMMFDevSoundCIMessageData& aData) sl@0: { sl@0: // data is stored as destination, custom command info, inbuf, outbuf,status sl@0: TPckgBuf comBuffer; sl@0: aMessage.ReadL(1, comBuffer); sl@0: sl@0: // get command and handle sl@0: aData.iCommand = comBuffer().iCommand; sl@0: aData.iHandle = comBuffer().iHandle; sl@0: } sl@0: sl@0: sl@0: TInt CMMFDevSoundCIDeMuxUtility::InputDesLength(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // input descriptor is at offset 2 sl@0: TInt len = aMessage.GetDesLength(2); sl@0: return len; sl@0: } sl@0: sl@0: void CMMFDevSoundCIDeMuxUtility::ReadFromInputDesL(const RMmfIpcMessage& aMessage, TDes8* aBufToFill) sl@0: { sl@0: // check if the descriptor is large enough sl@0: TInt len = InputDesLength(aMessage); sl@0: if (len > aBufToFill->MaxLength()) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: // input descriptor is at offset 2 sl@0: aMessage.ReadL(2, *aBufToFill); sl@0: } sl@0: sl@0: void CMMFDevSoundCIDeMuxUtility::WriteToOutputDesL(const RMmfIpcMessage& aMessage, TDesC8& aBufToWrite) sl@0: { sl@0: // output descriptor is at offset 3 sl@0: aMessage.WriteL(3, aBufToWrite); sl@0: } sl@0: sl@0: sl@0: void CMMFDevSoundCIDeMuxUtility::CompleteMessage(const RMmfIpcMessage& aMessage, TInt aError) sl@0: { sl@0: aMessage.Complete(aError); sl@0: } sl@0: sl@0: CMMFDevSoundCIDeMuxUtility::CMMFDevSoundCIDeMuxUtility(MMMFDevSoundCustomInterfaceDeMuxInterface* aInterface) sl@0: : iInterface(aInterface) sl@0: { sl@0: } sl@0: