diff -r 16e4b9007960 -r f5508c13dfe0 bluetoothappprofiles/avrcp/remconbeareravrcp/src/avrcpbrowsingcommandhandler.cpp --- a/bluetoothappprofiles/avrcp/remconbeareravrcp/src/avrcpbrowsingcommandhandler.cpp Wed Oct 13 13:15:31 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,489 +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: -// avrcpincomingcommandhandler.cpp -// - - - -/** - @file - @internalComponent - @released -*/ -#include -#include -#include - -#include "browsecommand.h" -#include "avrcpbrowsingcommandhandler.h" -#include "avrcpinternalinterface.h" -#include "avrcplog.h" -#include "avrcprouter.h" -#include "avrcputils.h" -#include "browsingframe.h" -#include "bulkbearer.h" -#include "mediabrowse.h" -#include "remconcommandinterface.h" - -//------------------------------------------------------------------------------------ -// Construction/Destruction -//------------------------------------------------------------------------------------ - -/** Factory function. - -@param aCommandInterface The interface for providing commands that have been handled. -@param aRouter A CRcpRouter to use for communication with remote devices. -@param aPlayerInfoManager The central manager for player information. -@param aAddr The Bluetooth device address for the remote device handled by this handler. -@return A fully constructed CRcpBrowsingCommandHandler. -@leave System wide error codes. -*/ -CRcpBrowsingCommandHandler* CRcpBrowsingCommandHandler::NewL(MRemConBulkCommandInterface& aCommandInterface, - CBulkRouter& aRouter, - CAvrcpPlayerInfoManager& aPlayerInfoManager, - const TBTDevAddr& aAddr) - { - LOG_STATIC_FUNC - CRcpBrowsingCommandHandler* handler = new(ELeave) CRcpBrowsingCommandHandler(aCommandInterface, aRouter, aPlayerInfoManager, aAddr); - return handler; - } - -/** -@param aCommandInterface The interface for providing commands that have been handled. -@param aRouter A CRcpRouter to use for communication with remote devices. -@param aPlayerInfoManager The central manager for player information. -@param aAddr The Bluetooth device address for the remote device handled by this handler. -@return A partially constructed CRcpBrowsingCommandHandler. -*/ -CRcpBrowsingCommandHandler::CRcpBrowsingCommandHandler(MRemConBulkCommandInterface& aCommandInterface, - CBulkRouter& aRouter, - CAvrcpPlayerInfoManager& aPlayerInfoManager, - const TBTDevAddr& aAddr) - : iCommandQueue(_FOFF(CBrowseCommand, iHandlingLink)) - , iInternalCommandQueue(_FOFF(CBrowseCommand, iHandlingLink)) - , iCommandInterface(aCommandInterface) - , iRouter(aRouter) - , iMtu(335) // initialise to min for browse channel - , iPlayerInfoManager(aPlayerInfoManager) - , iAddr(aAddr) - { - LOG_FUNC - } - -CRcpBrowsingCommandHandler::~CRcpBrowsingCommandHandler() - { - LOG_FUNC - - while (!iCommandQueue.IsEmpty()) - { - CBrowseCommand *command = iCommandQueue.First(); - HandledCommand(*command); - } - - TRemConAddress remConAddr; - AvrcpUtils::BTToRemConAddr(iAddr, remConAddr); - iCommandInterface.MrcbciRemoveAddressing(remConAddr); - } - -//--------------------------------------------------------------------- -// Called from the bearer -//--------------------------------------------------------------------- - -/** Tell the handler to gracefully shutdown. - -*/ -void CRcpBrowsingCommandHandler::Disconnect() - { - LOG_FUNC - - while (!iCommandQueue.IsEmpty()) - { - CBrowseCommand* command = iCommandQueue.First(); - iRouter.RemoveFromSendQueue(*command); - - HandledCommand(*command); - } - } - -//------------------------------------------------------------------------------------ -// Called by router -//------------------------------------------------------------------------------------ - -/** Receive an incoming AVRCP browse command. - -@param aMessageInformation The command data from the AVCTP message. -@param aTransactionLabel AVCTP transaction label for this command. -@param aAddr The bluetooth device from which this command originated. -@leave System Wide Error code -*/ -void CRcpBrowsingCommandHandler::ReceiveCommandL(const TDesC8& aMessageInformation, - SymbianAvctp::TTransactionLabel aTransactionLabel, - const TBTDevAddr& aAddr) - { - LOG_FUNC - - // If there's nothing beyond a header this is bobs. Dump it now. - AvrcpBrowsing::BrowsingFrame::VerifyFrameL(aMessageInformation); - - TUint id = iCommandInterface.MrcciNewTransactionId(); - CBrowseCommand* command = CBrowseCommand::NewL(aMessageInformation, id, aTransactionLabel, aAddr, &iPlayerInfoManager); - CleanupStack::PushL(command); - - TInt result = command->ProcessIncomingCommandL(iMtu); - CleanupStack::Pop(command); - - command->IncrementUsers(); - - switch(result) - { - case KErrAvrcpFurtherProcessingRequired: - { - // The only command that we need to check out before sending on is - // SetBrowsedPlayer. Although it's been parsed to verify that it's - // a syntactically valid command we need to ensure that the selected - // player is available before sending it on. - - __ASSERT_DEBUG(command->RemConInterfaceUid() == TUid::Uid(KRemConMediaBrowseApiUid) && command->RemConOperationId() == ESetBrowsedPlayerOperationId, AVRCP_PANIC(EFurtherProcessingRequiredForNonSetBrowsedPlayer)); - TBool valid = HandleSetBrowsedPlayer(*command); - - if(!valid) - { - Respond(*command, result); - command->DecrementUsers(); - break; - } - else - { - result = KErrNone; - } - // valid case fallsthrough to be handled as normal - } - case KErrAvrcpHandledInternallyInformRemCon: // this case falls through - case KErrNone: - { - iCommandQueue.AddLast(*command); - iCommandInterface.MrcciNewCommand(*command); - - if (result == KErrNone) - { - break; - } - // KErrAvrcpHandledInternallyInformRemCon fallsthrough here - } - case KErrAvrcpHandledInternallyRespondNow: - { - // If the command has already set payload, just sent the command - iRouter.AddToSendQueue(*command); - command->DecrementUsers(); - break; - } - case KErrAvrcpInternalCommand: - { - iInternalCommandQueue.AddLast(*command); - HandleInternalCommand(*command); - break; - } - default: - { - Respond(*command, result); - command->DecrementUsers(); - break; - } - }; - } - -/** Called from the router to indicate send completion. - -@param aCommand The command that has been sent. -@param aSendResult KErrNone if the command was sent successfully. System wide - error code otherwise. -*/ -void CRcpBrowsingCommandHandler::MessageSent(CAvrcpCommand& /*aCommand*/, TInt /*aSendResult*/) - { - LOG_FUNC - // We try and send the response, but if we fail there's not a lot we can do about - // it. Just let the remote assume the response. - } - -void CRcpBrowsingCommandHandler::MaxPacketSize(TInt aMtu) - { - iMtu = aMtu-AvrcpBrowsing::KHeaderLength; - } - -//------------------------------------------------------------------------------------ -// Called by bearer -//------------------------------------------------------------------------------------ - -/** Send a response. - -@param aInterfaceUid The RemCon interface this response is from. -@param aId The RemCon transaction label of the command to respond to. -@param aData The command response data. -@return KErrNotFound if the command was not found on the queue. - System wide error codes. -*/ -TInt CRcpBrowsingCommandHandler::SendRemConResponse(TUid /*aInterfaceUid*/, TUint aId, RBuf8& aData) - { - LOG_FUNC - - return SendResponse(iCommandQueue, aId, aData); - } - -//------------------------------------------------------------------------------------ -// Internal command handling functions -//------------------------------------------------------------------------------------ - - -/** Sends a response to the remote device. - -@param aCommand The command to respond to. -@param aErr The result of handling the command. -*/ -void CRcpBrowsingCommandHandler::Respond(CBrowseCommand& aCommand, TInt aErr) - { - LOG_FUNC - aCommand.SetResult(aErr); - iRouter.AddToSendQueue(aCommand); - } - -/** To be called on completion of command handling. - -This aggregates the handler's tidying up of a finished -command. - -@param aCommand The command to tidy up. -*/ -void CRcpBrowsingCommandHandler::HandledCommand(CBrowseCommand& aCommand) - { - LOG_FUNC - - aCommand.iHandlingLink.Deque(); - aCommand.DecrementUsers(); - } - -void CRcpBrowsingCommandHandler::HandleInternalCommand(CBrowseCommand& aCommand) - { - LOG_FUNC - - TUid interfaceUid; - TUint id; - TUint operationId; - RBuf8 commandData; - TBTDevAddr addr; - - aCommand.GetCommandInfo(interfaceUid, id, operationId, commandData, addr); - - __ASSERT_DEBUG(interfaceUid == TUid::Uid(KUidAvrcpInternalInterface), AvrcpUtils::Panic(EAvrcpInternalHandlingRequestedOnWrongInterface)); - - TInt err = KErrNone; - switch(operationId) - { - case EAvrcpInternalGetFolderItems: - { - err = HandleGetFolderItems(id, commandData); - break; - } - }; - - if(err) - { - HandledCommand(aCommand); - } - - commandData.Close(); - } - -TInt CRcpBrowsingCommandHandler::HandleGetFolderItems(TUint aId, RBuf8& aCommandData) - { - LOG_FUNC - - RBuf8 responseBuf; - TRAPD(err, DoHandleGetFolderItemsL(aCommandData, responseBuf)); - - if(!err) - { - err = SendInternalResponse(aId, responseBuf); - } - - return err; - } - -void CRcpBrowsingCommandHandler::DoHandleGetFolderItemsL(RBuf8& aCommandData, RBuf8& aResponseData) - { - LOG_FUNC - - __ASSERT_DEBUG( &iPlayerInfoManager != NULL, AvrcpUtils::Panic(EAvrcpNotFullyConstructed)); - RAvrcpGetFolderItemsRequest request; - CleanupClosePushL(request); - request.ReadL(aCommandData); - - // Use 4 bytes even though player ids are 2 bytes becuase of - // restrictions on RArray preventing use of non-word aligned types - RArray players; - TInt err = iPlayerInfoManager.PlayerListing(request.iStartItem, request.iEndItem, players); - CleanupStack::PopAndDestroy(&request); - - RRemConMediaErrorResponse errResponse; - if(err != KErrNone) - { - CleanupClosePushL(players); - errResponse.iPduId = AvrcpBrowsing::EGetFolderItems; - errResponse.iStatus = (err == KErrArgument) ? AvrcpStatus::ERangeOutOfBounds : AvrcpStatus::EInternalError; - aResponseData.CreateL(KBrowseResponseBaseLength); - CleanupClosePushL(aResponseData); - errResponse.WriteL(aResponseData); - CleanupStack::Pop(&aResponseData); - CleanupStack::PopAndDestroy(&players); - return; - } - - RAvrcpGetFolderItemsResponse response; - CleanupClosePushL(response); - CleanupClosePushL(players); - for(TInt i = 0; i < players.Count(); i++) - { - RMediaPlayerItem item; - CleanupClosePushL(item); - iPlayerInfoManager.MediaPlayerItemL(players[i], item); - response.iItems.AppendL(item); - CleanupStack::Pop(&item); - } - - response.iPduId = AvrcpBrowsing::EGetFolderItems; - response.iStatus = AvrcpStatus::ESuccess; - response.iUidCounter = KMediaPlayerListUidCounter; - response.iNumberItems = players.Count(); - CleanupStack::PopAndDestroy(&players); - - //check this fits within MTU, Leave if the response size is bigger than max size - CleanupClosePushL(aResponseData); - if(response.Size() > iMtu) - { - - errResponse.iPduId = AvrcpBrowsing::EGetFolderItems; - errResponse.iStatus = AvrcpStatus::EInternalError; - aResponseData.CreateL(KBrowseResponseBaseLength); - errResponse.WriteL(aResponseData); - } - else - { - aResponseData.CreateL(response.Size()); - response.WriteL(aResponseData); - } - CleanupStack::Pop(&aResponseData); - CleanupStack::PopAndDestroy(&response); - } - -TInt CRcpBrowsingCommandHandler::SendInternalResponse(TUint aId, RBuf8& aData) - { - LOG_FUNC - - return SendResponse(iInternalCommandQueue, aId, aData); - } - -TInt CRcpBrowsingCommandHandler::SendResponse(TDblQue& aCommandQueue, TUint aId, RBuf8& aData) - { - LOG_FUNC - - TInt err = KErrNotFound; - - TDblQueIter iter(aCommandQueue); - CBrowseCommand* command = NULL; - - while (iter) - { - command = iter++; - if(command->RemConCommandId() == aId) - { - err = KErrNone; - command->ProcessOutgoingResponse(aData); - - Respond(*command, err); - aData.Close(); - HandledCommand(*command); - - break; - } - } - - return err; - } - -void CRcpBrowsingCommandHandler::SendReject(TUid /*aInterfaceUid*/, TUint aTransactionId) - { - LOG_FUNC; - - TDblQueIter iter(iCommandQueue); - CBrowseCommand* command = NULL; - - while (iter) - { - command = iter++; - if(command->RemConCommandId() == aTransactionId) - { - Respond(*command, KErrAvrcpAirInternalError); - HandledCommand(*command); - } - } - } - -const TBTDevAddr& CRcpBrowsingCommandHandler::BtAddr() const - { - return iAddr; - } - -TBool CRcpBrowsingCommandHandler::HandleSetBrowsedPlayer(CBrowseCommand& aCommand) - { - TInt err = KErrNone; - RRemConSetBrowsedPlayerRequest request; - - TRAP(err, request.ReadL(aCommand.CommandData())); - __ASSERT_DEBUG(err == KErrNone, AvrcpUtils::Panic(ESetBrowsePlayerRequestCorruptedLocally)); - - // Check if selected player exists - TUint16 playerId = request.iPlayerId; - TRemConClientId clientId; - TRAP(err, clientId = iPlayerInfoManager.ClientL(playerId)); - - if(err == KErrNone) - { - // Selected player exists, check with RemCon if we can use it - TRemConAddress remConAddr; - AvrcpUtils::BTToRemConAddr(iAddr, remConAddr); - - TInt err = iCommandInterface.MrcbciSetAddressedClient(remConAddr, clientId); - } - - if(err != KErrNone) - { - // Either the player was incorrect or is already in use, form a RemCon - // format response, then ask the command to process it for sending out - // on the air. - RBuf8 buf; - TInt bufErr = buf.Create(KMediaBrowseOutBufMaxLength); - - if(bufErr == KErrNone) - { - RRemConMediaErrorResponse response; - response.iPduId = 0x70; - response.iStatus = RAvrcpIPC::SymbianErrToStatus(KErrAvrcpAirInvalidPlayerId); - TRAP(bufErr, response.WriteL(buf)); - aCommand.ProcessOutgoingResponse(buf); - buf.Close(); - } - } - // else we will continue processing this command as normal - - return err == KErrNone ? ETrue : EFalse; - }