os/mm/devsound/sounddevbt/src/A2dpBlueTooth/server/A2dpBTHeadsetAudioIfServer.cpp
First public contribution.
1 // Copyright (c) 2005-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "A2dpBTHeadsetAudioIfServer.h"
18 #include "A2dpBTHeadsetAudioIfServerStart.h"
19 #include "A2dpBTheadsetAudioIf.h"
20 #include "MMFBtRoutingSoundDevice.h" // for TRange
23 CA2dpBTHeadsetAudioIfServer* CA2dpBTHeadsetAudioIfServer::NewL()
25 CA2dpBTHeadsetAudioIfServer* self = new(ELeave) CA2dpBTHeadsetAudioIfServer();
26 CleanupStack::PushL(self);
32 CA2dpBTHeadsetAudioIfServer::~CA2dpBTHeadsetAudioIfServer()
34 delete iBTAudioInterface;
37 CMmfIpcSession* CA2dpBTHeadsetAudioIfServer::NewSessionL(const TVersion &aVersion) const
39 TVersion version( KBTAudioServerMajorVersionNumber,
40 KBTAudioServerMinorVersionNumber,
41 KBTAudioServerBuildVersionNumber);
43 if(!User::QueryVersionSupported(version, aVersion))
45 User::Leave(KErrNotSupported);
48 CA2dpBTHeadsetAudioIfSession* session = CA2dpBTHeadsetAudioIfSession::NewL(iBTAudioInterface);
52 CA2dpBTHeadsetAudioIfServer::CA2dpBTHeadsetAudioIfServer() :
53 CMmfIpcServer(EPriorityStandard)
57 void CA2dpBTHeadsetAudioIfServer::ConstructL()
59 // Create the interface to the BT headset
60 iBTAudioInterface = CA2dpBTHeadsetAudioInterface::NewL();
62 // Call base class to Start server
63 TName name(RThread().Name());
69 Session implementation.
71 CA2dpBTHeadsetAudioIfSession* CA2dpBTHeadsetAudioIfSession::NewL( CA2dpBTHeadsetAudioInterface*
74 CA2dpBTHeadsetAudioIfSession* self = new(ELeave) CA2dpBTHeadsetAudioIfSession(aBTAudioInterface);
75 CleanupStack::PushL(self);
77 CleanupStack::Pop(self);
81 CA2dpBTHeadsetAudioIfSession::CA2dpBTHeadsetAudioIfSession(CA2dpBTHeadsetAudioInterface* aBTAudioInterface) :
82 iBTAudioInterface(aBTAudioInterface)
86 void CA2dpBTHeadsetAudioIfSession::ConstructL()
88 // Create the AO event handlers
89 iInitHandler = CA2dpBTHeadsetIfEventHandler::NewL();
90 iOpenDeviceHandler = CA2dpBTHeadsetIfEventHandler::NewL();
91 iCloseDeviceHandler = CA2dpBTHeadsetIfEventHandler::NewL();
92 iPlayDataHandler = CA2dpBTHeadsetIfEventHandler::NewL();
93 iNotifyErrorHandler = CA2dpBTHeadsetIfEventHandler::NewL();
96 CA2dpBTHeadsetAudioIfSession::~CA2dpBTHeadsetAudioIfSession()
99 delete iOpenDeviceHandler;
100 delete iCloseDeviceHandler;
101 delete iPlayDataHandler;
102 delete iNotifyErrorHandler;
105 void CA2dpBTHeadsetAudioIfSession::ServiceL(const RMessage2& aMessage)
107 // Service the message
108 TBool complete = EFalse;
110 switch(aMessage.Function())
112 case EBTAudioServerInitialize:
113 complete = DoInitializeL(aMessage);
115 case EBTAudioServerCancelInitialize:
116 complete = DoCancelInitializeL(aMessage);
118 case EBTAudioServerCopyFourCCArrayData:
119 complete = DoCopyFourCCArrayDataL(aMessage);
121 case EBTAudioServerCopyChannelsArrayData:
122 complete = DoCopyChannelsArrayDataL(aMessage);
124 case EBTAudioServerGetSupportedDataTypes:
125 err = DoGetSupportedDataTypesL(aMessage);
126 aMessage.Complete(err);
128 case EBTAudioServerGetSupportedSampleRates:
129 err = DoGetSupportedSampleRatesL(aMessage);
130 aMessage.Complete(err);
132 case EBTAudioServerGetSupportedSampleRatesDiscrete:
133 complete = DoGetSupportedSampleRatesDiscreteL(aMessage);
135 case EBTAudioServerGetSupportedSampleRatesRange:
136 complete = DoGetSupportedSampleRatesRangeL(aMessage);
138 case EBTAudioServerGetSupportedChannels:
139 err = DoGetSupportedChannelsL(aMessage);
140 aMessage.Complete(err);
142 case EBTAudioServerSetDataType:
143 err = DoSetDataTypeL(aMessage);
144 aMessage.Complete(err);
146 case EBTAudioServerSetSampleRate:
147 err = DoSetSampleRateL(aMessage);
148 aMessage.Complete(err);
150 case EBTAudioServerSetChannels:
151 err = DoSetChannelsL(aMessage);
152 aMessage.Complete(err);
154 case EBTAudioServerOpenDevice:
155 complete = DoOpenDeviceL(aMessage);
157 case EBTAudioServerCancelOpenDevice:
158 complete = DoCancelOpenDevice(aMessage);
160 case EBTAudioServerCloseDevice:
161 complete = DoCloseDeviceL(aMessage);
163 case EBTAudioServerVolume:
164 complete = DoVolumeL(aMessage);
166 case EBTAudioServerSetVolume:
167 err = DoSetVolumeL(aMessage);
168 aMessage.Complete(err);
170 case EBTAudioServerPlayData:
171 complete = DoPlayDataL(aMessage);
173 case EBTAudioServerCancelPlayData:
174 complete = DoCancelPlayDataL(aMessage);
176 case EBTAudioServerFlushBuffer:
177 complete = DoFlushBufferL(aMessage);
179 case EBTAudioServerBytesPlayed:
180 complete = DoBytesPlayedL(aMessage);
182 case EBTAudioServerResetBytesPlayed:
183 complete = DoResetBytesPlayedL(aMessage);
185 case EBTAudioServerPauseBuffer:
186 complete = DoPauseBufferL(aMessage);
188 case EBTAudioServerResumePlaying:
189 complete = DoResumePlayingL(aMessage);
191 case EBTAudioServerNotifyError:
192 complete = DoNotifyErrorL(aMessage);
194 case EBTAudioServerCancelNotifyError:
195 complete = DoCancelNotifyErrorL(aMessage);
198 User::Leave(KErrNotSupported);
204 aMessage.Complete(KErrNone);
208 TBool CA2dpBTHeadsetAudioIfSession::DoInitializeL(const RMmfIpcMessage& aMessage)
210 // Get the address from the message
211 TPckgBuf<TBTDevAddr> btAddrPckg;
212 aMessage.ReadL(0, btAddrPckg);
213 TBTDevAddr& devAddr = btAddrPckg();
214 iInitHandler->StartL(aMessage);
215 iBTAudioInterface->Initialize(devAddr, iInitHandler->iStatus);
220 TBool CA2dpBTHeadsetAudioIfSession::DoCancelInitializeL(const RMmfIpcMessage& /*aMessage*/)
222 iBTAudioInterface->CancelInitialize();
223 iInitHandler->Stop();
227 TBool CA2dpBTHeadsetAudioIfSession::DoCopyFourCCArrayDataL(const RMmfIpcMessage& aMessage)
229 const TInt KBufExpandSize8 = 8;//two TInts
230 CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
231 CleanupStack::PushL(dataCopyBuffer);
232 RBufWriteStream stream;
233 stream.Open(*dataCopyBuffer);
234 CleanupClosePushL(stream);
235 for (TInt i = 0; i < iFourCCArray.Count(); i++)
237 stream.WriteInt32L(iFourCCArray[i].FourCC());
239 aMessage.WriteL(0, dataCopyBuffer->Ptr(0));
241 CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream
245 TBool CA2dpBTHeadsetAudioIfSession::DoCopyUintArrayDataL(const RMmfIpcMessage& aMessage, RArray<TUint> aArray)
247 const TInt KBufExpandSize8 = 8;//two TInts
248 CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
249 CleanupStack::PushL(dataCopyBuffer);
250 RBufWriteStream stream;
251 stream.Open(*dataCopyBuffer);
252 CleanupClosePushL(stream);
253 for (TInt i = 0; i < aArray.Count(); i++)
255 stream.WriteInt32L(aArray[i]);
257 aMessage.WriteL(0, dataCopyBuffer->Ptr(0));
259 CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream
263 TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedDataTypesL(const RMmfIpcMessage& aMessage)
265 iFourCCArray.Reset();
267 TInt err = iBTAudioInterface->GetSupportedDataTypes(iFourCCArray);
270 pckg() = iFourCCArray.Count();
271 aMessage.WriteL(TInt(0),pckg);
276 TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesL(const RMmfIpcMessage& aMessage)
278 iDiscreteArray.Reset();
281 TInt err = iBTAudioInterface->GetSupportedSampleRates(iDiscreteArray, iRangeArray);
283 TPckgBuf<TRatesArrayElements> pckg;
284 pckg().iDiscrete = iDiscreteArray.Count();
285 pckg().iRange = iRangeArray.Count();
287 aMessage.WriteL(0, pckg);
292 TBool CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesDiscreteL(const RMmfIpcMessage& aMessage)
294 return DoCopyUintArrayDataL(aMessage, iDiscreteArray);
297 TBool CA2dpBTHeadsetAudioIfSession::DoGetSupportedSampleRatesRangeL(const RMmfIpcMessage& aMessage)
299 const TInt KBufExpandSize8 = 8;//two TInts
300 CBufFlat* dataCopyBuffer = CBufFlat::NewL(KBufExpandSize8);
301 CleanupStack::PushL(dataCopyBuffer);
302 RBufWriteStream stream;
303 stream.Open(*dataCopyBuffer);
304 CleanupClosePushL(stream);
305 for (TInt i = 0; i < iRangeArray.Count(); i++)
307 stream.WriteInt32L(iRangeArray[i].iLow);
308 stream.WriteInt32L(iRangeArray[i].iHigh);
310 aMessage.WriteL(0, dataCopyBuffer->Ptr(0));
312 CleanupStack::PopAndDestroy(2);//dataCopyBuffer, stream
316 TInt CA2dpBTHeadsetAudioIfSession::DoGetSupportedChannelsL(const RMmfIpcMessage& aMessage)
319 iStereoSupportArray.Reset();
320 TMMFStereoSupport stereoSupport;
322 TInt err = iBTAudioInterface->GetSupportedChannels(iStereoSupportArray, stereoSupport);
324 TPckgBuf<TChannelsSupport> pckg;
325 pckg().iElementCount = iStereoSupportArray.Count();
326 pckg().iSupport = stereoSupport;
328 aMessage.WriteL(0, pckg);
333 TBool CA2dpBTHeadsetAudioIfSession::DoCopyChannelsArrayDataL(const RMmfIpcMessage& aMessage)
335 return DoCopyUintArrayDataL(aMessage, iStereoSupportArray);
338 TInt CA2dpBTHeadsetAudioIfSession::DoSetDataTypeL(const RMmfIpcMessage& aMessage)
340 TPckgBuf<TFourCC> dataTypePckg;
341 aMessage.ReadL(0, dataTypePckg);
342 TFourCC dataType = dataTypePckg();
343 return iBTAudioInterface->SetDataType(dataType);
346 TInt CA2dpBTHeadsetAudioIfSession::DoSetSampleRateL(const RMmfIpcMessage& aMessage)
348 TPckgBuf<TUint> ratePckg;
349 aMessage.ReadL(0, ratePckg);
350 TUint rate = ratePckg();
351 return iBTAudioInterface->SetSampleRate(rate);
354 TInt CA2dpBTHeadsetAudioIfSession::DoSetChannelsL(const RMmfIpcMessage& aMessage)
356 TPckgBuf<TChannelsSupport> pckgBuf;
357 aMessage.ReadL(0, pckgBuf);
358 TChannelsSupport support = pckgBuf();
359 return iBTAudioInterface->SetChannels(support.iElementCount, support.iSupport);
362 TBool CA2dpBTHeadsetAudioIfSession::DoOpenDeviceL(const RMmfIpcMessage& aMessage)
364 iOpenDeviceHandler->StartL(aMessage);
365 iBTAudioInterface->OpenDevice(iOpenDeviceHandler->iStatus);
369 TBool CA2dpBTHeadsetAudioIfSession::DoCancelOpenDevice(const RMmfIpcMessage& /*aMessage*/)
371 iBTAudioInterface->CancelOpenDevice();
375 TBool CA2dpBTHeadsetAudioIfSession::DoCloseDeviceL(const RMmfIpcMessage& aMessage)
377 iCloseDeviceHandler->StartL(aMessage);
378 iBTAudioInterface->CloseDevice(iCloseDeviceHandler->iStatus);
382 TBool CA2dpBTHeadsetAudioIfSession::DoVolumeL(const RMmfIpcMessage& aMessage)
384 TUint volume = iBTAudioInterface->Volume();
385 TPckgBuf<TUint> pckg(volume);
386 aMessage.WriteL(0, pckg);
390 TInt CA2dpBTHeadsetAudioIfSession::DoSetVolumeL(const RMmfIpcMessage& aMessage)
392 TPckgBuf<TUint> pckg;
393 aMessage.ReadL(0, pckg);
394 TUint volume = pckg();
395 return iBTAudioInterface->SetVolume(volume);
398 TBool CA2dpBTHeadsetAudioIfSession::DoPlayDataL(const RMmfIpcMessage& aMessage)
400 // Client's in the same process so access the buffer directly
401 const TPtr8* ptr = static_cast<const TPtr8*>(aMessage.Ptr0());
402 iPlayDataHandler->StartL(aMessage);
403 iBTAudioInterface->PlayData(*ptr, iPlayDataHandler->iStatus);
407 TBool CA2dpBTHeadsetAudioIfSession::DoCancelPlayDataL(const RMmfIpcMessage& /*aMessage*/)
409 iBTAudioInterface->CancelPlayData();
410 iPlayDataHandler->Stop();
414 TBool CA2dpBTHeadsetAudioIfSession::DoFlushBufferL(const RMmfIpcMessage& /*aMessage*/)
416 iBTAudioInterface->FlushBuffer();
420 TBool CA2dpBTHeadsetAudioIfSession::DoBytesPlayedL(const RMmfIpcMessage& aMessage)
422 TUint bytesPlayed = iBTAudioInterface->BytesPlayed();
423 TPckgBuf<TUint> pckg(bytesPlayed);
424 aMessage.WriteL(0, pckg);
428 TBool CA2dpBTHeadsetAudioIfSession::DoResetBytesPlayedL(const RMmfIpcMessage& /*aMessage*/)
430 iBTAudioInterface->ResetBytesPlayed();
434 TBool CA2dpBTHeadsetAudioIfSession::DoPauseBufferL(const RMmfIpcMessage& /*aMessage*/)
436 iBTAudioInterface->PauseBuffer();
440 TBool CA2dpBTHeadsetAudioIfSession::DoResumePlayingL(const RMmfIpcMessage& /*aMessage*/)
442 iBTAudioInterface->ResumePlaying();
446 TBool CA2dpBTHeadsetAudioIfSession::DoNotifyErrorL(const RMmfIpcMessage& aMessage)
448 iNotifyErrorHandler->StartL(aMessage);
449 iBTAudioInterface->NotifyError(iNotifyErrorHandler->iStatus);
453 TBool CA2dpBTHeadsetAudioIfSession::DoCancelNotifyErrorL(const RMmfIpcMessage& /*aMessage*/)
455 iBTAudioInterface->CancelNotifyError();
456 iNotifyErrorHandler->Stop();
461 * Implementation of Active Object to handle asynch requests to the Bluetooth interface.
463 CA2dpBTHeadsetIfEventHandler* CA2dpBTHeadsetIfEventHandler::NewL()
465 CA2dpBTHeadsetIfEventHandler* self = new(ELeave) CA2dpBTHeadsetIfEventHandler();
466 CleanupStack::PushL(self);
468 CleanupStack::Pop(self);
472 CA2dpBTHeadsetIfEventHandler::~CA2dpBTHeadsetIfEventHandler()
478 void CA2dpBTHeadsetIfEventHandler::RunL()
480 TInt err = iStatus.Int();
481 // Complete the message
482 iMessage->Complete(err);
487 void CA2dpBTHeadsetIfEventHandler::DoCancel()
491 iMessage->Complete(KErrCancel);
495 CA2dpBTHeadsetIfEventHandler::CA2dpBTHeadsetIfEventHandler() : CActive(EPriorityStandard)
497 CActiveScheduler::Add(this);
500 void CA2dpBTHeadsetIfEventHandler::ConstructL()
504 void CA2dpBTHeadsetIfEventHandler::StartL(const RMmfIpcMessage& aMessage)
506 // take a copy of the message to complete later
507 delete iMessage; // ensure we only have one message!
509 iMessage = new(ELeave) RMmfIpcMessage(aMessage);
517 void CA2dpBTHeadsetIfEventHandler::Stop()