--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/devsound/sounddevbt/src/A2dpBlueTooth/server/A2dpBTHeadsetAudioIfServer.cpp Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,520 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <s32mem.h>
+#include "A2dpBTHeadsetAudioIfServer.h"
+#include "A2dpBTHeadsetAudioIfServerStart.h"
+#include "A2dpBTheadsetAudioIf.h"
+#include "MMFBtRoutingSoundDevice.h" // for TRange
+
+
+CA2dpBTHeadsetAudioIfServer* CA2dpBTHeadsetAudioIfServer::NewL()
+ {
+ CA2dpBTHeadsetAudioIfServer* self = new(ELeave) CA2dpBTHeadsetAudioIfServer();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CA2dpBTHeadsetAudioIfServer::~CA2dpBTHeadsetAudioIfServer()
+ {
+ delete iBTAudioInterface;
+ }
+
+CMmfIpcSession* CA2dpBTHeadsetAudioIfServer::NewSessionL(const TVersion &aVersion) const
+ {
+ TVersion version( KBTAudioServerMajorVersionNumber,
+ KBTAudioServerMinorVersionNumber,
+ KBTAudioServerBuildVersionNumber);
+
+ if(!User::QueryVersionSupported(version, aVersion))
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ CA2dpBTHeadsetAudioIfSession* session = CA2dpBTHeadsetAudioIfSession::NewL(iBTAudioInterface);
+ return session;
+ }
+
+CA2dpBTHeadsetAudioIfServer::CA2dpBTHeadsetAudioIfServer() :
+ CMmfIpcServer(EPriorityStandard)
+ {
+ }
+
+void CA2dpBTHeadsetAudioIfServer::ConstructL()
+ {
+ // Create the interface to the BT headset
+ iBTAudioInterface = CA2dpBTHeadsetAudioInterface::NewL();
+
+ // Call base class to Start server
+ TName name(RThread().Name());
+ StartL(name);
+ }
+
+
+/*
+ Session implementation.
+ */
+CA2dpBTHeadsetAudioIfSession* CA2dpBTHeadsetAudioIfSession::NewL( CA2dpBTHeadsetAudioInterface*
+ aBTAudioInterface)
+ {
+ CA2dpBTHeadsetAudioIfSession* self = new(ELeave) CA2dpBTHeadsetAudioIfSession(aBTAudioInterface);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CA2dpBTHeadsetAudioIfSession::CA2dpBTHeadsetAudioIfSession(CA2dpBTHeadsetAudioInterface* aBTAudioInterface) :
+ iBTAudioInterface(aBTAudioInterface)
+ {
+ }
+
+void CA2dpBTHeadsetAudioIfSession::ConstructL()
+ {
+ // Create the AO event handlers
+ iInitHandler = CA2dpBTHeadsetIfEventHandler::NewL();
+ iOpenDeviceHandler = CA2dpBTHeadsetIfEventHandler::NewL();
+ iCloseDeviceHandler = CA2dpBTHeadsetIfEventHandler::NewL();
+ iPlayDataHandler = CA2dpBTHeadsetIfEventHandler::NewL();
+ iNotifyErrorHandler = CA2dpBTHeadsetIfEventHandler::NewL();
+ }
+
+CA2dpBTHeadsetAudioIfSession::~CA2dpBTHeadsetAudioIfSession()
+ {
+ delete iInitHandler;
+ delete iOpenDeviceHandler;
+ delete iCloseDeviceHandler;
+ delete iPlayDataHandler;
+ delete iNotifyErrorHandler;
+ }
+
+void CA2dpBTHeadsetAudioIfSession::ServiceL(const RMessage2& aMessage)
+ {
+ // Service the message
+ TBool complete = EFalse;
+ TInt err = KErrNone;
+ switch(aMessage.Function())
+ {
+ case EBTAudioServerInitialize:
+ complete = DoInitializeL(aMessage);
+ break;
+ case EBTAudioServerCancelInitialize:
+ complete = DoCancelInitializeL(aMessage);
+ break;
+ case EBTAudioServerCopyFourCCArrayData:
+ complete = DoCopyFourCCArrayDataL(aMessage);
+ break;
+ case EBTAudioServerCopyChannelsArrayData:
+ complete = DoCopyChannelsArrayDataL(aMessage);
+ break;
+ case EBTAudioServerGetSupportedDataTypes:
+ err = DoGetSupportedDataTypesL(aMessage);
+ aMessage.Complete(err);
+ break;
+ case EBTAudioServerGetSupportedSampleRates:
+ err = DoGetSupportedSampleRatesL(aMessage);
+ aMessage.Complete(err);
+ break;
+ case EBTAudioServerGetSupportedSampleRatesDiscrete:
+ complete = DoGetSupportedSampleRatesDiscreteL(aMessage);
+ break;
+ case EBTAudioServerGetSupportedSampleRatesRange:
+ complete = DoGetSupportedSampleRatesRangeL(aMessage);
+ break;
+ case EBTAudioServerGetSupportedChannels:
+ err = DoGetSupportedChannelsL(aMessage);
+ aMessage.Complete(err);
+ break;
+ case EBTAudioServerSetDataType:
+ err = DoSetDataTypeL(aMessage);
+ aMessage.Complete(err);
+ break;
+ case EBTAudioServerSetSampleRate:
+ err = DoSetSampleRateL(aMessage);
+ aMessage.Complete(err);
+ break;
+ case EBTAudioServerSetChannels:
+ err = DoSetChannelsL(aMessage);
+ aMessage.Complete(err);
+ break;
+ case EBTAudioServerOpenDevice:
+ complete = DoOpenDeviceL(aMessage);
+ break;
+ case EBTAudioServerCancelOpenDevice:
+ complete = DoCancelOpenDevice(aMessage);
+ break;
+ case EBTAudioServerCloseDevice:
+ complete = DoCloseDeviceL(aMessage);
+ break;
+ case EBTAudioServerVolume:
+ complete = DoVolumeL(aMessage);
+ break;
+ case EBTAudioServerSetVolume:
+ err = DoSetVolumeL(aMessage);
+ aMessage.Complete(err);
+ break;
+ case EBTAudioServerPlayData:
+ complete = DoPlayDataL(aMessage);
+ break;
+ case EBTAudioServerCancelPlayData:
+ complete = DoCancelPlayDataL(aMessage);
+ break;
+ case EBTAudioServerFlushBuffer:
+ complete = DoFlushBufferL(aMessage);
+ break;
+ case EBTAudioServerBytesPlayed:
+ complete = DoBytesPlayedL(aMessage);
+ break;
+ case EBTAudioServerResetBytesPlayed:
+ complete = DoResetBytesPlayedL(aMessage);
+ break;
+ case EBTAudioServerPauseBuffer:
+ complete = DoPauseBufferL(aMessage);
+ break;
+ case EBTAudioServerResumePlaying:
+ complete = DoResumePlayingL(aMessage);
+ break;
+ case EBTAudioServerNotifyError:
+ complete = DoNotifyErrorL(aMessage);
+ break;
+ case EBTAudioServerCancelNotifyError:
+ complete = DoCancelNotifyErrorL(aMessage);
+ break;
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ }
+
+ if (complete)
+ {
+ aMessage.Complete(KErrNone);
+ }
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoInitializeL(const RMmfIpcMessage& aMessage)
+ {
+ // Get the address from the message
+ TPckgBuf<TBTDevAddr> btAddrPckg;
+ aMessage.ReadL(0, btAddrPckg);
+ TBTDevAddr& devAddr = btAddrPckg();
+ iInitHandler->StartL(aMessage);
+ iBTAudioInterface->Initialize(devAddr, iInitHandler->iStatus);
+
+ return EFalse;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoCancelInitializeL(const RMmfIpcMessage& /*aMessage*/)
+ {
+ iBTAudioInterface->CancelInitialize();
+ iInitHandler->Stop();
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoCopyFourCCArrayDataL(const RMmfIpcMessage& aMessage)
+ {
+ const TInt KBufExpandSize8 = 8;//two TInts
+ CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
+ CleanupStack::PushL(dataCopyBuffer);
+ RBufWriteStream stream;
+ stream.Open(*dataCopyBuffer);
+ CleanupClosePushL(stream);
+ for (TInt i = 0; i < iFourCCArray.Count(); i++)
+ {
+ stream.WriteInt32L(iFourCCArray[i].FourCC());
+ }
+ aMessage.WriteL(0, dataCopyBuffer->Ptr(0));
+ stream.Close();
+ CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoCopyUintArrayDataL(const RMmfIpcMessage& aMessage, RArray<TUint> aArray)
+ {
+ const TInt KBufExpandSize8 = 8;//two TInts
+ CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
+ CleanupStack::PushL(dataCopyBuffer);
+ RBufWriteStream stream;
+ stream.Open(*dataCopyBuffer);
+ CleanupClosePushL(stream);
+ for (TInt i = 0; i < aArray.Count(); i++)
+ {
+ stream.WriteInt32L(aArray[i]);
+ }
+ aMessage.WriteL(0, dataCopyBuffer->Ptr(0));
+ stream.Close();
+ CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream
+ return ETrue;
+ }
+
+TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedDataTypesL(const RMmfIpcMessage& aMessage)
+ {
+ iFourCCArray.Reset();
+
+ TInt err = iBTAudioInterface->GetSupportedDataTypes(iFourCCArray);
+
+ TPckgBuf<TInt> pckg;
+ pckg() = iFourCCArray.Count();
+ aMessage.WriteL(TInt(0),pckg);
+
+ return err;
+ }
+
+TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesL(const RMmfIpcMessage& aMessage)
+ {
+ iDiscreteArray.Reset();
+ iRangeArray.Reset();
+
+ TInt err = iBTAudioInterface->GetSupportedSampleRates(iDiscreteArray, iRangeArray);
+
+ TPckgBuf<TRatesArrayElements> pckg;
+ pckg().iDiscrete = iDiscreteArray.Count();
+ pckg().iRange = iRangeArray.Count();
+
+ aMessage.WriteL(0, pckg);
+
+ return err;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesDiscreteL(const RMmfIpcMessage& aMessage)
+ {
+ return DoCopyUintArrayDataL(aMessage, iDiscreteArray);
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesRangeL(const RMmfIpcMessage& aMessage)
+ {
+ const TInt KBufExpandSize8 = 8;//two TInts
+ CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
+ CleanupStack::PushL(dataCopyBuffer);
+ RBufWriteStream stream;
+ stream.Open(*dataCopyBuffer);
+ CleanupClosePushL(stream);
+ for (TInt i = 0; i < iRangeArray.Count(); i++)
+ {
+ stream.WriteInt32L(iRangeArray[i].iLow);
+ stream.WriteInt32L(iRangeArray[i].iHigh);
+ }
+ aMessage.WriteL(0, dataCopyBuffer->Ptr(0));
+ stream.Close();
+ CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream
+ return ETrue;
+ }
+
+TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedChannelsL(const RMmfIpcMessage& aMessage)
+ {
+ // Array of uints
+ iStereoSupportArray.Reset();
+ TMMFStereoSupport stereoSupport;
+
+ TInt err = iBTAudioInterface->GetSupportedChannels(iStereoSupportArray, stereoSupport);
+
+ TPckgBuf<TChannelsSupport> pckg;
+ pckg().iElementCount = iStereoSupportArray.Count();
+ pckg().iSupport = stereoSupport;
+
+ aMessage.WriteL(0, pckg);
+
+ return err;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoCopyChannelsArrayDataL(const RMmfIpcMessage& aMessage)
+ {
+ return DoCopyUintArrayDataL(aMessage, iStereoSupportArray);
+ }
+
+TInt CA2dpBTHeadsetAudioIfSession::DoSetDataTypeL(const RMmfIpcMessage& aMessage)
+ {
+ TPckgBuf<TFourCC> dataTypePckg;
+ aMessage.ReadL(0, dataTypePckg);
+ TFourCC dataType = dataTypePckg();
+ return iBTAudioInterface->SetDataType(dataType);
+ }
+
+TInt CA2dpBTHeadsetAudioIfSession::DoSetSampleRateL(const RMmfIpcMessage& aMessage)
+ {
+ TPckgBuf<TUint> ratePckg;
+ aMessage.ReadL(0, ratePckg);
+ TUint rate = ratePckg();
+ return iBTAudioInterface->SetSampleRate(rate);
+ }
+
+TInt CA2dpBTHeadsetAudioIfSession::DoSetChannelsL(const RMmfIpcMessage& aMessage)
+ {
+ TPckgBuf<TChannelsSupport> pckgBuf;
+ aMessage.ReadL(0, pckgBuf);
+ TChannelsSupport support = pckgBuf();
+ return iBTAudioInterface->SetChannels(support.iElementCount, support.iSupport);
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoOpenDeviceL(const RMmfIpcMessage& aMessage)
+ {
+ iOpenDeviceHandler->StartL(aMessage);
+ iBTAudioInterface->OpenDevice(iOpenDeviceHandler->iStatus);
+ return EFalse;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoCancelOpenDevice(const RMmfIpcMessage& /*aMessage*/)
+ {
+ iBTAudioInterface->CancelOpenDevice();
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoCloseDeviceL(const RMmfIpcMessage& aMessage)
+ {
+ iCloseDeviceHandler->StartL(aMessage);
+ iBTAudioInterface->CloseDevice(iCloseDeviceHandler->iStatus);
+ return EFalse;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoVolumeL(const RMmfIpcMessage& aMessage)
+ {
+ TUint volume = iBTAudioInterface->Volume();
+ TPckgBuf<TUint> pckg(volume);
+ aMessage.WriteL(0, pckg);
+ return ETrue;
+ }
+
+TInt CA2dpBTHeadsetAudioIfSession::DoSetVolumeL(const RMmfIpcMessage& aMessage)
+ {
+ TPckgBuf<TUint> pckg;
+ aMessage.ReadL(0, pckg);
+ TUint volume = pckg();
+ return iBTAudioInterface->SetVolume(volume);
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoPlayDataL(const RMmfIpcMessage& aMessage)
+ {
+ // Client's in the same process so access the buffer directly
+ const TPtr8* ptr = static_cast<const TPtr8*>(aMessage.Ptr0());
+ iPlayDataHandler->StartL(aMessage);
+ iBTAudioInterface->PlayData(*ptr, iPlayDataHandler->iStatus);
+ return EFalse;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoCancelPlayDataL(const RMmfIpcMessage& /*aMessage*/)
+ {
+ iBTAudioInterface->CancelPlayData();
+ iPlayDataHandler->Stop();
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoFlushBufferL(const RMmfIpcMessage& /*aMessage*/)
+ {
+ iBTAudioInterface->FlushBuffer();
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoBytesPlayedL(const RMmfIpcMessage& aMessage)
+ {
+ TUint bytesPlayed = iBTAudioInterface->BytesPlayed();
+ TPckgBuf<TUint> pckg(bytesPlayed);
+ aMessage.WriteL(0, pckg);
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoResetBytesPlayedL(const RMmfIpcMessage& /*aMessage*/)
+ {
+ iBTAudioInterface->ResetBytesPlayed();
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoPauseBufferL(const RMmfIpcMessage& /*aMessage*/)
+ {
+ iBTAudioInterface->PauseBuffer();
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoResumePlayingL(const RMmfIpcMessage& /*aMessage*/)
+ {
+ iBTAudioInterface->ResumePlaying();
+ return ETrue;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoNotifyErrorL(const RMmfIpcMessage& aMessage)
+ {
+ iNotifyErrorHandler->StartL(aMessage);
+ iBTAudioInterface->NotifyError(iNotifyErrorHandler->iStatus);
+ return EFalse;
+ }
+
+TBool CA2dpBTHeadsetAudioIfSession::DoCancelNotifyErrorL(const RMmfIpcMessage& /*aMessage*/)
+ {
+ iBTAudioInterface->CancelNotifyError();
+ iNotifyErrorHandler->Stop();
+ return ETrue;
+ }
+
+/**
+ * Implementation of Active Object to handle asynch requests to the Bluetooth interface.
+ */
+CA2dpBTHeadsetIfEventHandler* CA2dpBTHeadsetIfEventHandler::NewL()
+ {
+ CA2dpBTHeadsetIfEventHandler* self = new(ELeave) CA2dpBTHeadsetIfEventHandler();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CA2dpBTHeadsetIfEventHandler::~CA2dpBTHeadsetIfEventHandler()
+ {
+ Cancel();
+ delete iMessage;
+ }
+
+void CA2dpBTHeadsetIfEventHandler::RunL()
+ {
+ TInt err = iStatus.Int();
+ // Complete the message
+ iMessage->Complete(err);
+ delete iMessage;
+ iMessage = NULL;
+ }
+
+void CA2dpBTHeadsetIfEventHandler::DoCancel()
+ {
+ if (iMessage)
+ {
+ iMessage->Complete(KErrCancel);
+ }
+ }
+
+CA2dpBTHeadsetIfEventHandler::CA2dpBTHeadsetIfEventHandler() : CActive(EPriorityStandard)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CA2dpBTHeadsetIfEventHandler::ConstructL()
+ {
+ }
+
+void CA2dpBTHeadsetIfEventHandler::StartL(const RMmfIpcMessage& aMessage)
+ {
+ // take a copy of the message to complete later
+ delete iMessage; // ensure we only have one message!
+ iMessage = NULL;
+ iMessage = new(ELeave) RMmfIpcMessage(aMessage);
+
+ if (!IsActive())
+ {
+ SetActive();
+ }
+ }
+
+void CA2dpBTHeadsetIfEventHandler::Stop()
+ {
+ Cancel();
+ }