diff -r 16e4b9007960 -r f5508c13dfe0 bluetoothappprofiles/avrcp/remconbeareravrcp/src/avrcputils.cpp --- a/bluetoothappprofiles/avrcp/remconbeareravrcp/src/avrcputils.cpp Wed Oct 13 13:15:31 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,360 +0,0 @@ -// Copyright (c) 2004-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 -#include -#include -#include -#include -#include "avrcplog.h" -#include "avrcputils.h" - -/** -@file -@internalComponent -@released -*/ - -/** Utility AVRCP panic function. - -@param aPanic The panic number. -*/ -void AvrcpUtils::Panic(TAvrcpPanic aPanic) - { - User::Panic(KAvrcpPanicName, aPanic); - } - - -/** Set the command data. This overwrites the current -contents of the data buffer. - -@param aCommandData The buffer in which to set the data. -@param aOffset The offset within aCommandData to set the data. -@param aLength The length of data to replace. -@param aValue The new value for the replaced data. -*/ -void AvrcpUtils::SetCommandDataFromInt(RBuf8& aCommandData, - TInt aOffset, TInt aLength, TInt aValue) - { - LOG_STATIC_FUNC - __ASSERT_DEBUG(aLength <= 4, Panic(EAvrcpCommandDataTooLong)); - - for(TInt i = 0; i < aLength; i++) - { - aCommandData[aOffset+i] = aValue >> (8*i); - } - } - -/** Reads command data from the buffer to an int. - -@param aCommandData The buffer from which to read the data. -@param aOffset The offset within aCommandData read from. -@param aLength The length of data to read. This must not be - more than 4. -@param aValue On return, the value of the specified data section. -*/ -void AvrcpUtils::ReadCommandDataToInt(const RBuf8& aCommandData, - TInt aOffset, TInt aLength, TInt& aValue) - { - LOG_STATIC_FUNC - __ASSERT_DEBUG(aLength <= 4, Panic(EAvrcpCommandDataTooLong)); - - aValue = 0; - - for(TInt i = 0 ; i < aLength; i++) - { - aValue |= aCommandData[aOffset+i]<<(8*i); - } - } - -/** Convert from a RemCon address to a bluetooth device address. - -@param aRemoteAddress The RemCon format address to convert. -@param aBTAddr On return, the bluetooth device address. -@return Whether the conversion could be performed successfully. -*/ -TInt AvrcpUtils::RemConToBTAddr(const TRemConAddress& aRemoteAddress, TBTDevAddr& aBTAddr) - { - LOG_STATIC_FUNC - TInt err = KErrArgument; - - // Check client has provided us a valid address - if(aRemoteAddress.Addr().Length() == KBTDevAddrSize) - { - aBTAddr = TBTDevAddr(aRemoteAddress.Addr()); - err = KErrNone; - } - else - { - __ASSERT_DEBUG(EFalse, AvrcpUtils::Panic(EAvrcpBadBTAddr)); - } - - return err; - } - -/** Convert from a bluetooth device address to a RemCon address. - -We assume this cannot fail, as bluetooth addresses are generated -internally rather than by a client, so they should always be -valid, and so convertible. - -@param aBTAddr The bluetooth device address to convert. -@param aRemoteAddress On return, the RemCon format address. -*/ -void AvrcpUtils::BTToRemConAddr(const TBTDevAddr& aBTAddr, TRemConAddress& aRemConAddress) - { - LOG_STATIC_FUNC - aRemConAddress.Addr() = aBTAddr.Des(); - aRemConAddress.BearerUid() = TUid::Uid(KRemConBearerAvrcpImplementationUid); - } - -NONSHARABLE_CLASS(CSpecificThreadCallBackBody) - : public CActive - { -public: - static CSpecificThreadCallBackBody* NewL(const TCallBack& aCallBack, TInt aPriority); - ~CSpecificThreadCallBackBody(); - - TInt Start(); - TInt CallBack(); - void HandleCancel(); - -private: - CSpecificThreadCallBackBody(const TCallBack& aCallBack, TInt aPriority); - void ConstructL(); - - TInt AsyncMessage(TInt aParam); - -private: // from CActive - void RunL(); - void DoCancel(); - -private: - TCallBack iCallBack; - - RThread iLocalThread; - - RMsgQueue iInbound; - RMsgQueue iOutbound; - }; - -RSpecificThreadCallBack::RSpecificThreadCallBack() - : iBody(NULL) - { - LOG_FUNC - } - -TInt RSpecificThreadCallBack::Create(const TCallBack& aCallBack, TInt aPriority) - { - TRAPD(err, iBody = CSpecificThreadCallBackBody::NewL(aCallBack, aPriority)); - return err; - } - -void RSpecificThreadCallBack::Close() - { - LOG_FUNC - delete iBody; - iBody = NULL; - } - -TInt RSpecificThreadCallBack::Start() - { - return iBody->Start(); - } - -TInt RSpecificThreadCallBack::CallBack() - { - return iBody->CallBack(); - } - -void RSpecificThreadCallBack::Cancel() - { - return iBody->HandleCancel(); - } - -CSpecificThreadCallBackBody* CSpecificThreadCallBackBody::NewL(const TCallBack& aCallBack, TInt aPriority) - { - CSpecificThreadCallBackBody* self = new(ELeave) CSpecificThreadCallBackBody(aCallBack, aPriority); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - -CSpecificThreadCallBackBody::CSpecificThreadCallBackBody(const TCallBack& aCallBack, TInt aPriority) - : CActive(aPriority) - , iCallBack(aCallBack) - { - LOG_FUNC - } - -void CSpecificThreadCallBackBody::ConstructL() - { - User::LeaveIfError(iInbound.CreateLocal(1)); - User::LeaveIfError(iOutbound.CreateLocal(1)); - } - -CSpecificThreadCallBackBody::~CSpecificThreadCallBackBody() - { - LOG_FUNC - HandleCancel(); - iInbound.Close(); - iOutbound.Close(); - iLocalThread.Close(); - } - -TInt CSpecificThreadCallBackBody::Start() - { - TInt err = KErrNone; - if(!IsAdded()) - { - err = iLocalThread.Duplicate(RThread()); - if(err == KErrNone) - { - CActiveScheduler::Add(this); - iInbound.NotifyDataAvailable(iStatus); - SetActive(); - } - } - return err; - } - -TInt CSpecificThreadCallBackBody::CallBack() - { - TInt err = KErrUnknown; - if(iLocalThread.Id() == RThread().Id()) - { - // Simple synchronous case. - err = iCallBack.CallBack(); - } - else - { - RThread thisThread; - err = thisThread.Duplicate(RThread()); - if(err == KErrNone) - { - err = AsyncMessage(thisThread.Handle()); - } - } - return err; - } - -TInt CSpecificThreadCallBackBody::AsyncMessage(TInt aParam) - { - TInt err = KErrNone; - TRequestStatus logonStatus; - iLocalThread.Logon(logonStatus); - if(logonStatus == KErrNoMemory) - { - // This seems kludgy, but I think it is the most reliable way. - User::WaitForRequest(logonStatus); // Ensure the all requests are correct... - err = KErrNoMemory; - } - else - { - iInbound.SendBlocking(aParam); - TRequestStatus status; - iOutbound.NotifyDataAvailable(status); - User::WaitForRequest(status, logonStatus); - if(status == KRequestPending) - { - // Remote thread is dead - iOutbound.CancelDataAvailable(); - User::WaitForRequest(status); - err = KErrDied; - } - else - { - // Success (the thread may have subsequently died, but we are only concerned with this call). - iLocalThread.LogonCancel(logonStatus); - User::WaitForRequest(logonStatus); - err = status.Int(); - if(err == KErrNone) - { - iOutbound.ReceiveBlocking(err); - } - } - } - return err; - } - - -void CSpecificThreadCallBackBody::RunL() - { - TInt threadHandle; - iInbound.ReceiveBlocking(threadHandle); - if(threadHandle == 0) - { - // 0 is a cancel message - // therefore don't do anything - iOutbound.SendBlocking(KErrNone); - } - else - { - RThread remoteThread; - remoteThread.SetHandleNC(threadHandle); - - TInt result = iCallBack.CallBack(); - - // There doesn't seem to be a safe way of handling when the other thread - // dies...... - iOutbound.SendBlocking(result); - - remoteThread.Close(); - - iInbound.NotifyDataAvailable(iStatus); - SetActive(); - } - } - -void CSpecificThreadCallBackBody::DoCancel() - { - if(RThread().Id() == iLocalThread.Id()) - { - iInbound.CancelDataAvailable(); - } - else - { - // other thread cancelling - so just complete the - // request - TRequestStatus* status = &iStatus; - User::RequestComplete(status, KErrCancel); - } - } - -void CSpecificThreadCallBackBody::HandleCancel() - { - if(IsAdded()) - { - if(RThread().Id() == iLocalThread.Id()) - { - Cancel(); // synchronous cancel is fine in same thread... - } - else - { - // In a different thread - this is more interesting... - TInt err = AsyncMessage(0); // 0 is special as it means cancel. - if(err == KErrDied && IsActive()) - { - // Remote thread has already died so we need to tidy up the - // active object ourselves. - Cancel(); - } - } - } - // else shouldn't be active... - } - -