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 sl@0: #include "A2dpBTHeadsetAudioIfServer.h" sl@0: #include "A2dpBTHeadsetAudioIfServerStart.h" sl@0: #include "A2dpBTheadsetAudioIf.h" sl@0: #include "MMFBtRoutingSoundDevice.h" // for TRange sl@0: sl@0: sl@0: CA2dpBTHeadsetAudioIfServer* CA2dpBTHeadsetAudioIfServer::NewL() sl@0: { sl@0: CA2dpBTHeadsetAudioIfServer* self = new(ELeave) CA2dpBTHeadsetAudioIfServer(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CA2dpBTHeadsetAudioIfServer::~CA2dpBTHeadsetAudioIfServer() sl@0: { sl@0: delete iBTAudioInterface; sl@0: } sl@0: sl@0: CMmfIpcSession* CA2dpBTHeadsetAudioIfServer::NewSessionL(const TVersion &aVersion) const sl@0: { sl@0: TVersion version( KBTAudioServerMajorVersionNumber, sl@0: KBTAudioServerMinorVersionNumber, sl@0: KBTAudioServerBuildVersionNumber); sl@0: sl@0: if(!User::QueryVersionSupported(version, aVersion)) sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: sl@0: CA2dpBTHeadsetAudioIfSession* session = CA2dpBTHeadsetAudioIfSession::NewL(iBTAudioInterface); sl@0: return session; sl@0: } sl@0: sl@0: CA2dpBTHeadsetAudioIfServer::CA2dpBTHeadsetAudioIfServer() : sl@0: CMmfIpcServer(EPriorityStandard) sl@0: { sl@0: } sl@0: sl@0: void CA2dpBTHeadsetAudioIfServer::ConstructL() sl@0: { sl@0: // Create the interface to the BT headset sl@0: iBTAudioInterface = CA2dpBTHeadsetAudioInterface::NewL(); sl@0: sl@0: // Call base class to Start server sl@0: TName name(RThread().Name()); sl@0: StartL(name); sl@0: } sl@0: sl@0: sl@0: /* sl@0: Session implementation. sl@0: */ sl@0: CA2dpBTHeadsetAudioIfSession* CA2dpBTHeadsetAudioIfSession::NewL( CA2dpBTHeadsetAudioInterface* sl@0: aBTAudioInterface) sl@0: { sl@0: CA2dpBTHeadsetAudioIfSession* self = new(ELeave) CA2dpBTHeadsetAudioIfSession(aBTAudioInterface); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CA2dpBTHeadsetAudioIfSession::CA2dpBTHeadsetAudioIfSession(CA2dpBTHeadsetAudioInterface* aBTAudioInterface) : sl@0: iBTAudioInterface(aBTAudioInterface) sl@0: { sl@0: } sl@0: sl@0: void CA2dpBTHeadsetAudioIfSession::ConstructL() sl@0: { sl@0: // Create the AO event handlers sl@0: iInitHandler = CA2dpBTHeadsetIfEventHandler::NewL(); sl@0: iOpenDeviceHandler = CA2dpBTHeadsetIfEventHandler::NewL(); sl@0: iCloseDeviceHandler = CA2dpBTHeadsetIfEventHandler::NewL(); sl@0: iPlayDataHandler = CA2dpBTHeadsetIfEventHandler::NewL(); sl@0: iNotifyErrorHandler = CA2dpBTHeadsetIfEventHandler::NewL(); sl@0: } sl@0: sl@0: CA2dpBTHeadsetAudioIfSession::~CA2dpBTHeadsetAudioIfSession() sl@0: { sl@0: delete iInitHandler; sl@0: delete iOpenDeviceHandler; sl@0: delete iCloseDeviceHandler; sl@0: delete iPlayDataHandler; sl@0: delete iNotifyErrorHandler; sl@0: } sl@0: sl@0: void CA2dpBTHeadsetAudioIfSession::ServiceL(const RMessage2& aMessage) sl@0: { sl@0: // Service the message sl@0: TBool complete = EFalse; sl@0: TInt err = KErrNone; sl@0: switch(aMessage.Function()) sl@0: { sl@0: case EBTAudioServerInitialize: sl@0: complete = DoInitializeL(aMessage); sl@0: break; sl@0: case EBTAudioServerCancelInitialize: sl@0: complete = DoCancelInitializeL(aMessage); sl@0: break; sl@0: case EBTAudioServerCopyFourCCArrayData: sl@0: complete = DoCopyFourCCArrayDataL(aMessage); sl@0: break; sl@0: case EBTAudioServerCopyChannelsArrayData: sl@0: complete = DoCopyChannelsArrayDataL(aMessage); sl@0: break; sl@0: case EBTAudioServerGetSupportedDataTypes: sl@0: err = DoGetSupportedDataTypesL(aMessage); sl@0: aMessage.Complete(err); sl@0: break; sl@0: case EBTAudioServerGetSupportedSampleRates: sl@0: err = DoGetSupportedSampleRatesL(aMessage); sl@0: aMessage.Complete(err); sl@0: break; sl@0: case EBTAudioServerGetSupportedSampleRatesDiscrete: sl@0: complete = DoGetSupportedSampleRatesDiscreteL(aMessage); sl@0: break; sl@0: case EBTAudioServerGetSupportedSampleRatesRange: sl@0: complete = DoGetSupportedSampleRatesRangeL(aMessage); sl@0: break; sl@0: case EBTAudioServerGetSupportedChannels: sl@0: err = DoGetSupportedChannelsL(aMessage); sl@0: aMessage.Complete(err); sl@0: break; sl@0: case EBTAudioServerSetDataType: sl@0: err = DoSetDataTypeL(aMessage); sl@0: aMessage.Complete(err); sl@0: break; sl@0: case EBTAudioServerSetSampleRate: sl@0: err = DoSetSampleRateL(aMessage); sl@0: aMessage.Complete(err); sl@0: break; sl@0: case EBTAudioServerSetChannels: sl@0: err = DoSetChannelsL(aMessage); sl@0: aMessage.Complete(err); sl@0: break; sl@0: case EBTAudioServerOpenDevice: sl@0: complete = DoOpenDeviceL(aMessage); sl@0: break; sl@0: case EBTAudioServerCancelOpenDevice: sl@0: complete = DoCancelOpenDevice(aMessage); sl@0: break; sl@0: case EBTAudioServerCloseDevice: sl@0: complete = DoCloseDeviceL(aMessage); sl@0: break; sl@0: case EBTAudioServerVolume: sl@0: complete = DoVolumeL(aMessage); sl@0: break; sl@0: case EBTAudioServerSetVolume: sl@0: err = DoSetVolumeL(aMessage); sl@0: aMessage.Complete(err); sl@0: break; sl@0: case EBTAudioServerPlayData: sl@0: complete = DoPlayDataL(aMessage); sl@0: break; sl@0: case EBTAudioServerCancelPlayData: sl@0: complete = DoCancelPlayDataL(aMessage); sl@0: break; sl@0: case EBTAudioServerFlushBuffer: sl@0: complete = DoFlushBufferL(aMessage); sl@0: break; sl@0: case EBTAudioServerBytesPlayed: sl@0: complete = DoBytesPlayedL(aMessage); sl@0: break; sl@0: case EBTAudioServerResetBytesPlayed: sl@0: complete = DoResetBytesPlayedL(aMessage); sl@0: break; sl@0: case EBTAudioServerPauseBuffer: sl@0: complete = DoPauseBufferL(aMessage); sl@0: break; sl@0: case EBTAudioServerResumePlaying: sl@0: complete = DoResumePlayingL(aMessage); sl@0: break; sl@0: case EBTAudioServerNotifyError: sl@0: complete = DoNotifyErrorL(aMessage); sl@0: break; sl@0: case EBTAudioServerCancelNotifyError: sl@0: complete = DoCancelNotifyErrorL(aMessage); sl@0: break; sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: sl@0: if (complete) sl@0: { sl@0: aMessage.Complete(KErrNone); sl@0: } sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoInitializeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // Get the address from the message sl@0: TPckgBuf btAddrPckg; sl@0: aMessage.ReadL(0, btAddrPckg); sl@0: TBTDevAddr& devAddr = btAddrPckg(); sl@0: iInitHandler->StartL(aMessage); sl@0: iBTAudioInterface->Initialize(devAddr, iInitHandler->iStatus); sl@0: sl@0: return EFalse; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoCancelInitializeL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iBTAudioInterface->CancelInitialize(); sl@0: iInitHandler->Stop(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoCopyFourCCArrayDataL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: const TInt KBufExpandSize8 = 8;//two TInts sl@0: CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8); sl@0: CleanupStack::PushL(dataCopyBuffer); sl@0: RBufWriteStream stream; sl@0: stream.Open(*dataCopyBuffer); sl@0: CleanupClosePushL(stream); sl@0: for (TInt i = 0; i < iFourCCArray.Count(); i++) sl@0: { sl@0: stream.WriteInt32L(iFourCCArray[i].FourCC()); sl@0: } sl@0: aMessage.WriteL(0, dataCopyBuffer->Ptr(0)); sl@0: stream.Close(); sl@0: CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoCopyUintArrayDataL(const RMmfIpcMessage& aMessage, RArray aArray) sl@0: { sl@0: const TInt KBufExpandSize8 = 8;//two TInts sl@0: CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8); sl@0: CleanupStack::PushL(dataCopyBuffer); sl@0: RBufWriteStream stream; sl@0: stream.Open(*dataCopyBuffer); sl@0: CleanupClosePushL(stream); sl@0: for (TInt i = 0; i < aArray.Count(); i++) sl@0: { sl@0: stream.WriteInt32L(aArray[i]); sl@0: } sl@0: aMessage.WriteL(0, dataCopyBuffer->Ptr(0)); sl@0: stream.Close(); sl@0: CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream sl@0: return ETrue; sl@0: } sl@0: sl@0: TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedDataTypesL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iFourCCArray.Reset(); sl@0: sl@0: TInt err = iBTAudioInterface->GetSupportedDataTypes(iFourCCArray); sl@0: sl@0: TPckgBuf pckg; sl@0: pckg() = iFourCCArray.Count(); sl@0: aMessage.WriteL(TInt(0),pckg); sl@0: sl@0: return err; sl@0: } sl@0: sl@0: TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iDiscreteArray.Reset(); sl@0: iRangeArray.Reset(); sl@0: sl@0: TInt err = iBTAudioInterface->GetSupportedSampleRates(iDiscreteArray, iRangeArray); sl@0: sl@0: TPckgBuf pckg; sl@0: pckg().iDiscrete = iDiscreteArray.Count(); sl@0: pckg().iRange = iRangeArray.Count(); sl@0: sl@0: aMessage.WriteL(0, pckg); sl@0: sl@0: return err; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesDiscreteL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: return DoCopyUintArrayDataL(aMessage, iDiscreteArray); sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesRangeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: const TInt KBufExpandSize8 = 8;//two TInts sl@0: CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8); sl@0: CleanupStack::PushL(dataCopyBuffer); sl@0: RBufWriteStream stream; sl@0: stream.Open(*dataCopyBuffer); sl@0: CleanupClosePushL(stream); sl@0: for (TInt i = 0; i < iRangeArray.Count(); i++) sl@0: { sl@0: stream.WriteInt32L(iRangeArray[i].iLow); sl@0: stream.WriteInt32L(iRangeArray[i].iHigh); sl@0: } sl@0: aMessage.WriteL(0, dataCopyBuffer->Ptr(0)); sl@0: stream.Close(); sl@0: CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream sl@0: return ETrue; sl@0: } sl@0: sl@0: TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedChannelsL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // Array of uints sl@0: iStereoSupportArray.Reset(); sl@0: TMMFStereoSupport stereoSupport; sl@0: sl@0: TInt err = iBTAudioInterface->GetSupportedChannels(iStereoSupportArray, stereoSupport); sl@0: sl@0: TPckgBuf pckg; sl@0: pckg().iElementCount = iStereoSupportArray.Count(); sl@0: pckg().iSupport = stereoSupport; sl@0: sl@0: aMessage.WriteL(0, pckg); sl@0: sl@0: return err; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoCopyChannelsArrayDataL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: return DoCopyUintArrayDataL(aMessage, iStereoSupportArray); sl@0: } sl@0: sl@0: TInt CA2dpBTHeadsetAudioIfSession::DoSetDataTypeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf dataTypePckg; sl@0: aMessage.ReadL(0, dataTypePckg); sl@0: TFourCC dataType = dataTypePckg(); sl@0: return iBTAudioInterface->SetDataType(dataType); sl@0: } sl@0: sl@0: TInt CA2dpBTHeadsetAudioIfSession::DoSetSampleRateL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf ratePckg; sl@0: aMessage.ReadL(0, ratePckg); sl@0: TUint rate = ratePckg(); sl@0: return iBTAudioInterface->SetSampleRate(rate); sl@0: } sl@0: sl@0: TInt CA2dpBTHeadsetAudioIfSession::DoSetChannelsL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf pckgBuf; sl@0: aMessage.ReadL(0, pckgBuf); sl@0: TChannelsSupport support = pckgBuf(); sl@0: return iBTAudioInterface->SetChannels(support.iElementCount, support.iSupport); sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoOpenDeviceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iOpenDeviceHandler->StartL(aMessage); sl@0: iBTAudioInterface->OpenDevice(iOpenDeviceHandler->iStatus); sl@0: return EFalse; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoCancelOpenDevice(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iBTAudioInterface->CancelOpenDevice(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoCloseDeviceL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iCloseDeviceHandler->StartL(aMessage); sl@0: iBTAudioInterface->CloseDevice(iCloseDeviceHandler->iStatus); sl@0: return EFalse; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoVolumeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TUint volume = iBTAudioInterface->Volume(); sl@0: TPckgBuf pckg(volume); sl@0: aMessage.WriteL(0, pckg); sl@0: return ETrue; sl@0: } sl@0: sl@0: TInt CA2dpBTHeadsetAudioIfSession::DoSetVolumeL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TPckgBuf pckg; sl@0: aMessage.ReadL(0, pckg); sl@0: TUint volume = pckg(); sl@0: return iBTAudioInterface->SetVolume(volume); sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoPlayDataL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // Client's in the same process so access the buffer directly sl@0: const TPtr8* ptr = static_cast(aMessage.Ptr0()); sl@0: iPlayDataHandler->StartL(aMessage); sl@0: iBTAudioInterface->PlayData(*ptr, iPlayDataHandler->iStatus); sl@0: return EFalse; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoCancelPlayDataL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iBTAudioInterface->CancelPlayData(); sl@0: iPlayDataHandler->Stop(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoFlushBufferL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iBTAudioInterface->FlushBuffer(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoBytesPlayedL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: TUint bytesPlayed = iBTAudioInterface->BytesPlayed(); sl@0: TPckgBuf pckg(bytesPlayed); sl@0: aMessage.WriteL(0, pckg); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoResetBytesPlayedL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iBTAudioInterface->ResetBytesPlayed(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoPauseBufferL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iBTAudioInterface->PauseBuffer(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoResumePlayingL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iBTAudioInterface->ResumePlaying(); sl@0: return ETrue; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoNotifyErrorL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: iNotifyErrorHandler->StartL(aMessage); sl@0: iBTAudioInterface->NotifyError(iNotifyErrorHandler->iStatus); sl@0: return EFalse; sl@0: } sl@0: sl@0: TBool CA2dpBTHeadsetAudioIfSession::DoCancelNotifyErrorL(const RMmfIpcMessage& /*aMessage*/) sl@0: { sl@0: iBTAudioInterface->CancelNotifyError(); sl@0: iNotifyErrorHandler->Stop(); sl@0: return ETrue; sl@0: } sl@0: sl@0: /** sl@0: * Implementation of Active Object to handle asynch requests to the Bluetooth interface. sl@0: */ sl@0: CA2dpBTHeadsetIfEventHandler* CA2dpBTHeadsetIfEventHandler::NewL() sl@0: { sl@0: CA2dpBTHeadsetIfEventHandler* self = new(ELeave) CA2dpBTHeadsetIfEventHandler(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CA2dpBTHeadsetIfEventHandler::~CA2dpBTHeadsetIfEventHandler() sl@0: { sl@0: Cancel(); sl@0: delete iMessage; sl@0: } sl@0: sl@0: void CA2dpBTHeadsetIfEventHandler::RunL() sl@0: { sl@0: TInt err = iStatus.Int(); sl@0: // Complete the message sl@0: iMessage->Complete(err); sl@0: delete iMessage; sl@0: iMessage = NULL; sl@0: } sl@0: sl@0: void CA2dpBTHeadsetIfEventHandler::DoCancel() sl@0: { sl@0: if (iMessage) sl@0: { sl@0: iMessage->Complete(KErrCancel); sl@0: } sl@0: } sl@0: sl@0: CA2dpBTHeadsetIfEventHandler::CA2dpBTHeadsetIfEventHandler() : CActive(EPriorityStandard) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: void CA2dpBTHeadsetIfEventHandler::ConstructL() sl@0: { sl@0: } sl@0: sl@0: void CA2dpBTHeadsetIfEventHandler::StartL(const RMmfIpcMessage& aMessage) sl@0: { sl@0: // take a copy of the message to complete later sl@0: delete iMessage; // ensure we only have one message! sl@0: iMessage = NULL; sl@0: iMessage = new(ELeave) RMmfIpcMessage(aMessage); sl@0: sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: } sl@0: sl@0: void CA2dpBTHeadsetIfEventHandler::Stop() sl@0: { sl@0: Cancel(); sl@0: }