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 // RDesReadStream sl@0: sl@0: #include "A2dpBTHeadsetAudioIfClient.h" sl@0: #include "A2dpBTHeadsetAudioIfClientServer.h" sl@0: #include "A2dpBTHeadsetAudioIfServerStart.h" sl@0: #include "MMFBtRoutingSoundDevice.h" sl@0: sl@0: const TInt KBluetoothAddressBufferLength = 32; sl@0: sl@0: EXPORT_C RA2dpBTHeadsetAudioInterface::RA2dpBTHeadsetAudioInterface() sl@0: { sl@0: } sl@0: sl@0: EXPORT_C TInt RA2dpBTHeadsetAudioInterface::Connect() sl@0: { sl@0: TRAPD(err, iBufAddr = HBufC::NewL(KBluetoothAddressBufferLength)); sl@0: if (err) sl@0: { sl@0: delete iBufAddr; sl@0: iBufAddr = NULL; sl@0: return err; sl@0: } sl@0: sl@0: TRAP(err, iPckgBuf = new(ELeave)TPckgBuf); sl@0: if (err) sl@0: { sl@0: delete iPckgBuf; sl@0: iPckgBuf = NULL; sl@0: return err; sl@0: } sl@0: sl@0: TVersion version(KBTAudioServerMajorVersionNumber, sl@0: KBTAudioServerMinorVersionNumber, sl@0: KBTAudioServerBuildVersionNumber); sl@0: // Assume the server is already running and attempt to create a session sl@0: return CreateSession(KA2DPAudioServerName, version); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::Close() sl@0: { sl@0: // Call the base class sl@0: RMmfSessionBase::Close(); sl@0: sl@0: delete iPckgBuf; sl@0: iPckgBuf = NULL; sl@0: sl@0: delete iBufAddr; sl@0: iBufAddr = NULL; sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::Initialize(const TBTDevAddr& aRemoteAddress, sl@0: TRequestStatus& aStatus) sl@0: { sl@0: if (iPckgBuf) sl@0: { sl@0: (*iPckgBuf)() = aRemoteAddress; sl@0: SendReceiveResult(EBTAudioServerInitialize, *iPckgBuf, aStatus); sl@0: } sl@0: else sl@0: { sl@0: // iPckgBuf not created => Connect() wasn't called or the returned error code was ignored. sl@0: TRequestStatus* status = &aStatus; sl@0: User::RequestComplete(status, KErrDisconnected); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::CancelInitialize() sl@0: { sl@0: SendReceive(EBTAudioServerCancelInitialize); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::GetSupportedDataTypesL(RArray& aSupportedDataTypes) const sl@0: { sl@0: aSupportedDataTypes.Reset(); sl@0: TPckgBuf numberOfElementsPckg; sl@0: TInt err = SendReceiveResult(EBTAudioServerGetSupportedDataTypes, numberOfElementsPckg); sl@0: User::LeaveIfError(err); sl@0: sl@0: HBufC8* buf = HBufC8::NewLC(numberOfElementsPckg() * sizeof(TFourCC)); sl@0: TPtr8 ptr = buf->Des(); sl@0: err = SendReceiveResult(EBTAudioServerCopyFourCCArrayData, ptr); sl@0: User::LeaveIfError(err); sl@0: sl@0: RDesReadStream stream(ptr); sl@0: CleanupClosePushL(stream); sl@0: sl@0: for (TInt i = 0; i < numberOfElementsPckg(); i++) sl@0: { sl@0: err = aSupportedDataTypes.Append(stream.ReadInt32L()); sl@0: if (err) sl@0: {//note we don't destroy array because we don't own it sl@0: //but we do reset it as it is incomplete sl@0: aSupportedDataTypes.Reset(); sl@0: User::Leave(err); sl@0: } sl@0: } sl@0: CleanupStack::PopAndDestroy(2, buf); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::GetSupportedSampleRatesL(RArray& aSupportedDiscreteRates, sl@0: RArray& aSupportedRateRanges) const sl@0: { sl@0: aSupportedDiscreteRates.Reset(); sl@0: TPckgBuf numberOfElementsPckg; sl@0: sl@0: TInt err = SendReceiveResult(EBTAudioServerGetSupportedSampleRates, numberOfElementsPckg); sl@0: User::LeaveIfError(err); sl@0: sl@0: HBufC8* buf = HBufC8::NewLC(numberOfElementsPckg().iDiscrete * sizeof(TUint)); sl@0: TPtr8 ptr = buf->Des(); sl@0: err = SendReceiveResult(EBTAudioServerGetSupportedSampleRatesDiscrete, ptr); sl@0: User::LeaveIfError(err); sl@0: sl@0: RDesReadStream stream(ptr); sl@0: CleanupClosePushL(stream); sl@0: sl@0: // Populate the discrete rates array sl@0: for (TInt i = 0; i < numberOfElementsPckg().iDiscrete; i++) sl@0: { sl@0: err = aSupportedDiscreteRates.Append(stream.ReadInt32L()); sl@0: if (err) sl@0: {//note we don't destroy array because we don't own it sl@0: //but we do reset it as it is incomplete sl@0: aSupportedDiscreteRates.Reset(); sl@0: User::Leave(err); sl@0: } sl@0: } sl@0: sl@0: ptr.SetLength(0); //clear out exiting data sl@0: // Get the rates range array (# of elements and the elements themselves) sl@0: buf = buf->ReAllocL(numberOfElementsPckg().iRange * sizeof(TRange)); sl@0: ptr = buf->Des(); sl@0: stream.Close(); sl@0: stream.Open(ptr); sl@0: err = SendReceiveResult(EBTAudioServerGetSupportedSampleRatesRange, ptr); sl@0: User::LeaveIfError(err); sl@0: TRange range; sl@0: for (TInt i = 0; i < numberOfElementsPckg().iRange; i++) sl@0: { sl@0: range.iLow = stream.ReadInt32L(); sl@0: range.iHigh = stream.ReadInt32L(); sl@0: err = aSupportedRateRanges.Append(range); sl@0: if (err) sl@0: { sl@0: aSupportedRateRanges.Reset(); sl@0: User::Leave(err); sl@0: } sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(2, buf);//stream, buf sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::GetSupportedChannelsL(RArray& aSupportedChannels, sl@0: TMMFStereoSupport& aStereoSupport) const sl@0: sl@0: { sl@0: aSupportedChannels.Reset(); sl@0: TChannelsSupport channelsSupport; sl@0: channelsSupport.iElementCount = 0; sl@0: channelsSupport.iSupport = EMMFNone; sl@0: TPckgBuf channelsSupportPckg(channelsSupport); sl@0: sl@0: TInt err = SendReceiveResult(EBTAudioServerGetSupportedChannels, channelsSupportPckg); sl@0: User::LeaveIfError(err); sl@0: sl@0: aStereoSupport = channelsSupportPckg().iSupport; sl@0: HBufC8* buf = HBufC8::NewLC(channelsSupportPckg().iElementCount * sizeof(TUint)); sl@0: TPtr8 ptr = buf->Des(); sl@0: err = SendReceiveResult(EBTAudioServerCopyChannelsArrayData, ptr); sl@0: User::LeaveIfError(err); sl@0: sl@0: RDesReadStream stream(ptr); sl@0: CleanupClosePushL(stream); sl@0: sl@0: // Populate the stereo support array sl@0: for (TInt i = 0; i < channelsSupportPckg().iElementCount; i++) sl@0: { sl@0: err = aSupportedChannels.Append(stream.ReadInt32L()); sl@0: if (err) sl@0: {//note we don't destroy array because we don't own it sl@0: //but we do reset it as it is incomplete sl@0: aSupportedChannels.Reset(); sl@0: User::Leave(err); sl@0: } sl@0: } sl@0: CleanupStack::PopAndDestroy(2, buf); //stream, buf sl@0: } sl@0: sl@0: EXPORT_C TInt RA2dpBTHeadsetAudioInterface::SetDataType(const TFourCC& aDataType) sl@0: { sl@0: TPckgBuf dataTypePckg(aDataType); sl@0: return SendReceiveResult(EBTAudioServerSetDataType, dataTypePckg); sl@0: } sl@0: sl@0: EXPORT_C TInt RA2dpBTHeadsetAudioInterface::SetSampleRate(TUint aSampleRate) sl@0: { sl@0: TPckgBuf sampleRatePckg(aSampleRate); sl@0: return SendReceiveResult(EBTAudioServerSetSampleRate, sampleRatePckg); sl@0: } sl@0: sl@0: EXPORT_C TInt RA2dpBTHeadsetAudioInterface::SetChannels(TUint aChannels, sl@0: TMMFStereoSupport aStereoSupport) sl@0: { sl@0: TChannelsSupport channelsSupport; sl@0: channelsSupport.iElementCount = aChannels; sl@0: channelsSupport.iSupport = aStereoSupport; sl@0: TPckgBuf pckgBuf(channelsSupport); sl@0: return SendReceiveResult(EBTAudioServerSetChannels, pckgBuf); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::OpenDevice(TRequestStatus& aStatus) sl@0: { sl@0: aStatus = KRequestPending; sl@0: SendReceive(EBTAudioServerOpenDevice, aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::CancelOpenDevice() sl@0: { sl@0: SendReceive(EBTAudioServerCancelOpenDevice); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::CloseDevice(TRequestStatus& aStatus) sl@0: { sl@0: aStatus = KRequestPending; sl@0: SendReceive(EBTAudioServerCloseDevice, aStatus); sl@0: } sl@0: sl@0: EXPORT_C TUint RA2dpBTHeadsetAudioInterface::Volume() const sl@0: { sl@0: TUint volume = 0; sl@0: TPckgBuf volumePckg(volume); sl@0: SendReceiveResult(EBTAudioServerVolume, volumePckg); sl@0: return volumePckg(); sl@0: } sl@0: sl@0: EXPORT_C TInt RA2dpBTHeadsetAudioInterface::SetVolume(TUint aVolume) sl@0: { sl@0: TPckgBuf volumePckg(aVolume); sl@0: return SendReceiveResult(EBTAudioServerSetVolume, volumePckg); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::PlayData(const TDesC8& aData, TRequestStatus& aStatus) sl@0: { sl@0: aStatus = KRequestPending; sl@0: SendReceive(EBTAudioServerPlayData, aData, aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::CancelPlayData() sl@0: { sl@0: SendReceive(EBTAudioServerCancelPlayData); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::FlushBuffer() sl@0: { sl@0: SendReceive(EBTAudioServerFlushBuffer); sl@0: } sl@0: sl@0: EXPORT_C TUint RA2dpBTHeadsetAudioInterface::BytesPlayed() const sl@0: { sl@0: TUint bytes = 0; sl@0: TPckgBuf bytesPlayedPckg(bytes); sl@0: SendReceive(EBTAudioServerBytesPlayed, bytesPlayedPckg); sl@0: return bytesPlayedPckg(); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::ResetBytesPlayed() sl@0: { sl@0: SendReceive(EBTAudioServerResetBytesPlayed); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::PauseBuffer() sl@0: { sl@0: SendReceive(EBTAudioServerPauseBuffer); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::ResumePlaying() sl@0: { sl@0: SendReceive(EBTAudioServerResumePlaying); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::NotifyError(TRequestStatus& aStatus) sl@0: { sl@0: aStatus = KRequestPending; sl@0: SendReceive(EBTAudioServerNotifyError, aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RA2dpBTHeadsetAudioInterface::CancelNotifyError() sl@0: { sl@0: SendReceive(EBTAudioServerCancelNotifyError); sl@0: } sl@0: sl@0: