bluetoothappprofiles/avrcp/remconbeareravrcp/src/controlcommand.cpp
changeset 0 f63038272f30
child 11 a42ed326b458
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 // Copyright (c) 2004-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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21  @released
       
    22 */
       
    23 #include <avcframe.h>
       
    24 #include <e32base.h>
       
    25 #include <remcon/remconbearerobserver.h>
       
    26 #include <remcon/remconconverterplugin.h>
       
    27 #include <remcon/messagetype.h>
       
    28 #include <remconbeareravrcp.h>
       
    29 
       
    30 #include <absolutevolumeapi.h>
       
    31 #include <absolutevolumeutils.h>
       
    32 #include <remcon/avrcpspec.h>
       
    33 #include "controlcommand.h"
       
    34 #include "avrcpcommandframer.h"
       
    35 #include "avrcpfragmenter.h"
       
    36 #include "avrcpinternalinterface.h"
       
    37 #include "avrcpipc.h"
       
    38 #include "avrcplog.h"
       
    39 #include "avrcputils.h"
       
    40 #include "avrcpincomingcommandhandler.h"
       
    41 #include "avrcp.h"
       
    42 #include "mediabrowse.h"
       
    43 #include "mediainformation.h"
       
    44 #include "nowplaying.h"
       
    45 #include "playerinformation.h"
       
    46 #include "remconbattery.h"
       
    47 #include "remcongroupnavigation.h"
       
    48 
       
    49 //---------------------------------------------------------------------
       
    50 // Outgoing command construction
       
    51 //---------------------------------------------------------------------
       
    52 
       
    53 /** Factory function.
       
    54 
       
    55 @param aInterfaceUid The RemCon interface uid of this command.
       
    56 @param aCommand The operation id of this command within the interface defined
       
    57 				by aInterface Uid.
       
    58 @param aRemConId The RemCon transaction label.
       
    59 @param aTransactionLabel The AVCTP transaction label.
       
    60 @param aCommandData The RemCon command data associated with this command.
       
    61 @param aIsClick Whether this command is a button click (ie RemCon believes
       
    62 				that this and the other part of the click constitute one
       
    63 				command.
       
    64 @param aAddr The bluetooth address to send this command to.
       
    65 @return A fully constructed CControlCommand.
       
    66 @leave System wide error codes.
       
    67 */
       
    68 CControlCommand* CControlCommand::NewL(TUid aInterfaceUid,
       
    69 	TUint aCommand, 
       
    70 	TUint aRemConId, 
       
    71 	SymbianAvctp::TTransactionLabel aTransactionLabel, 
       
    72 	RBuf8& aCommandData, 
       
    73 	TBool aIsClick, 
       
    74 	const TBTDevAddr& aAddr,
       
    75 	TBool aKnownToBearer)
       
    76 	{
       
    77 	LOG_STATIC_FUNC
       
    78 	CControlCommand* command = new (ELeave) CControlCommand(aInterfaceUid, aCommand, 
       
    79 			aRemConId, aTransactionLabel, aCommandData, aIsClick, aAddr, aKnownToBearer);
       
    80 	CleanupStack::PushL(command);
       
    81 	command->ConstructL();
       
    82 	CleanupStack::Pop(command);
       
    83 	return command;
       
    84 	}
       
    85 
       
    86 /** Constructor.
       
    87 
       
    88 @param aInterfaceUid The RemCon interface uid of this command.
       
    89 @param aCommand The operation id of this command within the interface defined
       
    90 				by aInterface Uid.
       
    91 @param aRemConId The RemCon transaction label.
       
    92 @param aTransactionLabel The AVCTP transaction label.
       
    93 @param aCommandData The RemCon command data associated with this command.
       
    94 @param aIsClick Whether this command is a button click (ie RemCon believes
       
    95 				that this and the other part of the click constitute one
       
    96 				command.
       
    97 @param aAddr The bluetooth address to send this command to.
       
    98 @return A constructed CControlCommand.
       
    99 @leave System wide error codes.
       
   100 */
       
   101 CControlCommand::CControlCommand(TUid aInterfaceUid,
       
   102 	TUint aCommand,
       
   103 	TUint aRemConId, 
       
   104 	SymbianAvctp::TTransactionLabel aTransactionLabel, 
       
   105 	RBuf8& aCommandData,
       
   106 	TBool aIsClick,
       
   107 	const TBTDevAddr& aAddr,
       
   108 	TBool aKnownToBearer) 
       
   109 	: CAvrcpCommand(aRemConId, aTransactionLabel, aAddr)
       
   110 	{
       
   111 	LOG_FUNC
       
   112 	
       
   113 	iIsClick = aIsClick;
       
   114 	iInterfaceUid = aInterfaceUid;
       
   115 	iOperationId = aCommand;
       
   116 	iKnownToBearer = aKnownToBearer;
       
   117 	
       
   118 	iCommandData.Assign(aCommandData);
       
   119 	aCommandData.Assign(NULL);
       
   120 	iPlayerInfoManager = NULL;
       
   121 	}
       
   122 	
       
   123 //---------------------------------------------------------------------
       
   124 // Incoming command construction
       
   125 //---------------------------------------------------------------------
       
   126 
       
   127 /** Factory function.
       
   128 
       
   129 @param aMessageInformation A buffer containing AV/C frame this command is to represent.
       
   130 @param aRemConId The RemCon transaction label.
       
   131 @param aTransLabel The AVCTP transaction label.
       
   132 @param aAddr The bluetooth address to send the response to.
       
   133 @param aClientId The RemCon client that should receive this command
       
   134 @return A fully constructed CControlCommand.
       
   135 @leave System wide error codes.
       
   136 */
       
   137 CControlCommand* CControlCommand::NewL(CAVCFrame* aFrame, 
       
   138 	TUint aRemConId, 
       
   139 	SymbianAvctp::TTransactionLabel aTransLabel, 
       
   140 	const TBTDevAddr& aAddr,
       
   141 	const TRemConClientId& aClientId,
       
   142 	CAvrcpPlayerInfoManager* aPlayerInfoManager)
       
   143 	{
       
   144 	LOG_STATIC_FUNC
       
   145 	CControlCommand* command = new(ELeave)CControlCommand(aFrame, aRemConId, aTransLabel, aAddr, aClientId, aPlayerInfoManager);
       
   146 	CleanupStack::PushL(command);
       
   147 	command->ConstructL();
       
   148 	CleanupStack::Pop(command);
       
   149 	return command;
       
   150 	}
       
   151 
       
   152 /** Constructor.
       
   153 
       
   154 @param aRemConId The RemCon transaction label.
       
   155 @param aTransLabel The AVCTP transaction label.
       
   156 @param aAddr The bluetooth address to send the response to.
       
   157 @param aClientId The RemCon client that should receive this command
       
   158 @return A partially constructed CControlCommand.
       
   159 @leave System wide error codes.
       
   160 */	
       
   161 CControlCommand::CControlCommand(CAVCFrame* aFrame, 
       
   162 	TUint aRemConId, 
       
   163 	SymbianAvctp::TTransactionLabel aTransLabel, 
       
   164 	const TBTDevAddr& aAddr,
       
   165 	const TRemConClientId& aClientId,
       
   166 	CAvrcpPlayerInfoManager* aPlayerInfoManager) 
       
   167 	: CAvrcpCommand(aRemConId, aTransLabel, aAddr)
       
   168 	, iFrame(aFrame)
       
   169 	, iClientId(aClientId)
       
   170 	{
       
   171 	LOG_FUNC
       
   172 
       
   173 	iIsClick = ETrue; // Assume click until we know otherwise
       
   174 	iPlayerInfoManager = aPlayerInfoManager;
       
   175 	}
       
   176 
       
   177 //---------------------------------------------------------------------
       
   178 // Generic construction/destruction
       
   179 //---------------------------------------------------------------------
       
   180 
       
   181 /** Destructor.
       
   182 */
       
   183 CControlCommand::~CControlCommand()
       
   184 	{
       
   185 	LOG_FUNC
       
   186 	__ASSERT_DEBUG(iUsers == 0, AvrcpUtils::Panic(EAvrcpCommandStillInUse));
       
   187 	__ASSERT_ALWAYS(!iHandlingLink.IsQueued(), AvrcpUtils::Panic(EAvrcpCommandStillQueuedForHandling));
       
   188 	__ASSERT_ALWAYS(!iReadyLink.IsQueued(), AvrcpUtils::Panic(EAvrcpCommandStillQueuedAsReady));
       
   189 	__ASSERT_ALWAYS(!iSendLink.IsQueued(), AvrcpUtils::Panic(EAvrcpCommandStillQueuedForSending));
       
   190 	delete iFrame;
       
   191 	iCommandData.Close();
       
   192 	delete iTimerEntry;
       
   193 	delete iTimerExpiryInfo;
       
   194 	}
       
   195 	
       
   196 /** Second phase construction.
       
   197 
       
   198 @leave System wide error codes.
       
   199 */
       
   200 void CControlCommand::ConstructL()
       
   201 	{
       
   202 	LOG_FUNC
       
   203 
       
   204 	// Allocate these now so we know we have the memory.  Info is
       
   205 	// irrelevant as we won't add to the timer's queue without 
       
   206 	// setting the true info.
       
   207 	TCallBack callback(DummyCallback, NULL);
       
   208 	iTimerEntry = new(ELeave)TDeltaTimerEntry(callback);
       
   209 	iTimerExpiryInfo = new(ELeave)TAvrcpTimerExpiryInfo(NULL, *this);
       
   210 	}
       
   211 	
       
   212 //------------------------------------------------------------------------------------
       
   213 // From MRcpTimerNotify
       
   214 //------------------------------------------------------------------------------------	
       
   215 
       
   216 /** Get the timer entry.
       
   217 
       
   218 @return Timer entry.
       
   219 */
       
   220 TDeltaTimerEntry* CControlCommand::TimerEntry()
       
   221 	{
       
   222 	return iTimerEntry;
       
   223 	}
       
   224 	
       
   225 /** Get the timer expiry info.
       
   226 
       
   227 @return Timer expiry info.
       
   228 */
       
   229 TAvrcpTimerExpiryInfo* CControlCommand::TimerExpiryInfo()
       
   230 	{
       
   231 	return iTimerExpiryInfo;
       
   232 	}
       
   233 
       
   234 /** Remove this command's timer entry from the queue.
       
   235 
       
   236 @param aTimer The timer queue to remove this from.
       
   237 */	
       
   238 void CControlCommand::CancelTimer(CDeltaTimer& aTimer)
       
   239 	{
       
   240 	LOG_FUNC
       
   241 
       
   242 	aTimer.Remove(*iTimerEntry);
       
   243 	}
       
   244 	
       
   245 //------------------------------------------------------------------------------------
       
   246 // Called by bearer
       
   247 //------------------------------------------------------------------------------------
       
   248 
       
   249 const TRemConClientId& CControlCommand::ClientId() const
       
   250 	{
       
   251 	return iClientId;
       
   252 	}
       
   253 //------------------------------------------------------------------------------------
       
   254 // Called by handlers
       
   255 //------------------------------------------------------------------------------------
       
   256 
       
   257 /** Creates iFrame.
       
   258 
       
   259 This function must be called between creating this command and using it.
       
   260 
       
   261 @param aInterfaceUid	The RemCon interface this command came from.
       
   262 @param aCommand			The command id within the interface identified by aInterfaceUid.
       
   263 @param aCommandData		Data supplied with this command by RemCon.  The format of this
       
   264 						data is defined by RemCon and is dependent on aInterfaceUid and 
       
   265 						aCommand.
       
   266 @leave System wide error code if parsing could not complete.
       
   267 */
       
   268 void CControlCommand::ProcessOutgoingCommandL(MRemConBearerObserver& aObserver)
       
   269 	{
       
   270 	LOG_FUNC
       
   271 			
       
   272 	switch(iInterfaceUid.iUid)
       
   273 		{
       
   274 		//Process the absolute volume controller api
       
   275 		case KRemConAbsoluteVolumeControllerApiUid:
       
   276 			{
       
   277 			switch (iOperationId)
       
   278 			    {
       
   279 			    //Registers absolute volume changed
       
   280 			    case KRemConAbsoluteVolumeNotification:
       
   281 			        {
       
   282 					iFrame = AvrcpCommandFramer::NotifyVolumeChangeCommandL();
       
   283 			        break;
       
   284 			        }
       
   285 			    //Sets absolute volume.
       
   286 			    case KRemConSetAbsoluteVolume:
       
   287 			    	{
       
   288 			    	//Gets the absolute volume to be set.
       
   289 			    	RRemConAbsoluteVolumeRequest setAbsVol;
       
   290 			    	CleanupClosePushL(setAbsVol);
       
   291 					setAbsVol.ReadL(iCommandData);
       
   292 					
       
   293 					__ASSERT_ALWAYS(setAbsVol.iVolume <= setAbsVol.iMaxVolume, 
       
   294 							AvrcpUtils::Panic(EAvrcpVolumeBeyondMaxVolume));
       
   295 					
       
   296 					TUint8 absVol = KAvrcpMaxAbsoluteVolume * setAbsVol.iVolume / setAbsVol.iMaxVolume;
       
   297 					iFrame = AvrcpCommandFramer::SetAbsoluteVolumeCommandL(absVol);	
       
   298 					CleanupStack::PopAndDestroy(&setAbsVol);					
       
   299 			    	break;
       
   300 			    	}
       
   301 			    default:
       
   302 			    	{
       
   303 			    	User::Leave(KErrNotSupported);
       
   304 			    	}
       
   305 			    
       
   306 			    }			
       
   307 			break;
       
   308 			}
       
   309 		case KRemConCoreApiUid:
       
   310 			{
       
   311 			// Default interface - all commands are passthrough
       
   312 			AVCPanel::TOperationId avrcpOp;
       
   313 			
       
   314 			if((RemConToAvrcpOperation(iOperationId, avrcpOp) != KErrNone) ||
       
   315 			   (iCommandData.Length() < KRemConCoreApiButtonDataLength))
       
   316 				{
       
   317 				User::Leave(KErrCorrupt);
       
   318 				}
       
   319 			else
       
   320 				{
       
   321 				TInt remConButtonAct;
       
   322 				AvrcpUtils::ReadCommandDataToInt(iCommandData, 
       
   323 					KRemConCoreApiCommandDataOffset + KRemConCoreApiButtonDataOffset,
       
   324 					KRemConCoreApiButtonDataLength, remConButtonAct);
       
   325 		
       
   326 				AVCPanel::TButtonAction buttonAct = (remConButtonAct == ERemConCoreApiButtonPress) ? 
       
   327 					AVCPanel::EButtonPress : AVCPanel::EButtonRelease;
       
   328 
       
   329 				iFrame = AvrcpCommandFramer::PassthroughL(avrcpOp, buttonAct);
       
   330 				if(iIsClick)
       
   331 					{
       
   332 					// restore our mangled command data
       
   333 					AvrcpUtils::SetCommandDataFromInt(iCommandData, 
       
   334 						KRemConCoreApiCommandDataOffset + KRemConCoreApiButtonDataOffset,
       
   335 						KRemConCoreApiButtonDataLength, ERemConCoreApiButtonClick);
       
   336 					}
       
   337 				}
       
   338 			break;
       
   339 			}	
       
   340 		default:
       
   341 			{
       
   342 			RBuf8 buf;
       
   343 			buf.CreateMaxL(KAVCFrameMaxLength);
       
   344 			User::LeaveIfError(aObserver.InterfaceToBearer(TUid::Uid(KRemConBearerAvrcpImplementationUid), 
       
   345 				iInterfaceUid, iOperationId, iCommandData, ERemConCommand, buf));
       
   346 
       
   347 			CleanupClosePushL(buf);
       
   348 			iFrame = CAVCFrame::NewL(buf, AVC::ECommand);
       
   349 			CleanupStack::PopAndDestroy(&buf);
       
   350 			break;
       
   351 			}
       
   352 		};
       
   353 	}
       
   354 	
       
   355 /** Fills in command info from iFrame.
       
   356 
       
   357 This must be called by the command handler before handling this
       
   358 command.
       
   359 
       
   360 This functions sets iInterfaceUid, iOperationId and iCommandData
       
   361 to the correct values according to iFrame.  The format of iCommandData
       
   362 is defined by RemCon and is dependent on iInterfaceUid and iOperationId.
       
   363 
       
   364 @return KErrNone				If the frame has been parsed successfully.
       
   365 @return KErrNotSupported		This frame represents a command for which a
       
   366 								RemCon converter or client side interface
       
   367 								cannot be found.
       
   368 @return KErrAvrcpInvalidCType	The CType specified in this frame is invalid.
       
   369 @return KErrAvrcpMetadataInvalidCommand		The AVRCP command is invalid.
       
   370 @return KErrAvrcpMetadataInvalidParameter	The AVRCP parameter is invalid.
       
   371 @return KErrAvrcpMetadataParameterNotFound	The AVRCP parameter was not found.
       
   372 @return KErrAvrcpMetadataInternalError		An AVRCP internal error occurred (such as out-of-memory,
       
   373 											or an inter-process communication error)
       
   374 @return KErrCorrupt	        	If the frame is corrupted(e.g invalid Operation Id).
       
   375 @return	System wide error code.
       
   376 */
       
   377 TInt CControlCommand::ParseIncomingCommandL(MRemConBearerObserver& aObserver, CAVRCPFragmenter& aFragmenter)
       
   378 	{
       
   379 	LOG_FUNC
       
   380 	TInt err = KErrNotSupported;
       
   381 	
       
   382 	switch(iFrame->Type())
       
   383 		{
       
   384 		// check it isn't a reponse
       
   385 		case AVC::ENotImplemented:
       
   386 		case AVC::EAccepted:
       
   387 		case AVC::ERejected:
       
   388 		case AVC::EInTransition:
       
   389 		case AVC::EImplemented:
       
   390 		case AVC::EChanged:
       
   391 		case AVC::EInterim:
       
   392 		case 0x0E:	// not given a enum for SC reasons; reserved response code in spec
       
   393 			{
       
   394 			// We were told this was a command, can't go using response
       
   395 			// CTypes here matey
       
   396 			err = KErrAvrcpInvalidCType;
       
   397 			break;
       
   398 			}
       
   399 		case AVC::EGeneralEnquiry:
       
   400 		case AVC::ESpecificEnquiry:
       
   401 			{
       
   402 			err = KErrNotSupported;
       
   403 			break;
       
   404 			}
       
   405 		default:
       
   406 			if (iFrame->Opcode() == AVC::EVendorDependent)
       
   407 				{
       
   408 				err = ParseIncomingVendorCommandL(aObserver, aFragmenter);
       
   409 				}
       
   410 			
       
   411 			else
       
   412 				{
       
   413 				// give off to the regular processor
       
   414 				err = ParseIncomingKnownOpcodeL(aObserver);
       
   415 				}
       
   416 			break;
       
   417 		};
       
   418 
       
   419 
       
   420 	return err;
       
   421 	}
       
   422 	
       
   423 /** Processes an incoming response.
       
   424 
       
   425 This function may not fail.  We always need to generate something
       
   426 to RemCon.
       
   427 
       
   428 @param aObserver Observer to use for retrieving converter.
       
   429 @param aFrame The AV/C frame containing the response.
       
   430 */
       
   431 TInt CControlCommand::ParseIncomingResponse(MRemConBearerObserver& aObserver, const CAVCFrame& aFrame)
       
   432 	{
       
   433 	LOG_FUNC	
       
   434 	TInt error = KErrNone;
       
   435 	
       
   436 	// Compare Opcode with that of the sent frame rather than the
       
   437 	// received one because we trust that more.  Should be the same
       
   438 	// as this is matched by AVCTP transaction label, but who knows
       
   439 	// what those illicit remote devices could be up to.
       
   440 	if(iFrame->Opcode() == AVC::EPassThrough)
       
   441 		{
       
   442 		switch(aFrame.Type())
       
   443 			{		
       
   444 			case AVC::EAccepted:
       
   445 				{
       
   446 				InsertCoreResult(KErrNone);
       
   447 				break;
       
   448 				}
       
   449 			case AVC::ENotImplemented:
       
   450 				{
       
   451 				InsertCoreResult(KErrNotSupported);
       
   452 				break;
       
   453 				}
       
   454 			default:
       
   455 				{
       
   456 				InsertCoreResult(KErrGeneral);
       
   457 				break;
       
   458 				}
       
   459 			}
       
   460 		}	
       
   461 	else if (iFrame->Opcode() == AVC::EVendorDependent)
       
   462 		{
       
   463 		TPtrC8 payloadData;
       
   464 		AVC::TAVCVendorId vID;
       
   465 		//Get the PDU ID with that of the sent frame rather than the received one,
       
   466 		//the reason is the same to above comments.
       
   467 		payloadData.Set(CAVCVendorDependentCommand::GetPayloadAndVID(*iFrame, vID));
       
   468 		if (vID == KBluetoothSIGVendorId)
       
   469 			{
       
   470 			TMetadataTransferPDUID metadataPDUID = MetadataTransferParser::GetPDUID(payloadData);
       
   471 			switch ( metadataPDUID )
       
   472 			    {
       
   473 			    case ESetAbsoluteVolume://Response for setting absolute volume.
       
   474 			    	{
       
   475 			    	error = SetSetAbsoluteVolumeResult(aFrame);
       
   476 			    	break;
       
   477 			    	}
       
   478 			    case ERegisterNotification:
       
   479 			    	{
       
   480 			    	//Get notify event ID with the sent frame rather than the received one
       
   481 			    	//because there is a big possibility that the received one is an error response, e.g. rejected,notimplemented.
       
   482 			    	//In order to make sure this is an absolute volume response even if the response is an error response, 
       
   483 			    	//we have to use the sent frame, and then we can process absolute volume specifically.
       
   484 			    	TMetadataTransferNotifyEventID eventID = MetadataTransferParser::GetNotifyEventID(payloadData);
       
   485 			    	
       
   486 			    	__ASSERT_ALWAYS(eventID == ERegisterNotificationVolumeChanged,
       
   487 			    			AvrcpUtils::Panic(EAvrcpInvalidEventId));
       
   488 			    	
       
   489 			    	if (eventID == ERegisterNotificationVolumeChanged)
       
   490 			    		{
       
   491 			    		error = SetNotifyVolumeChangeResult(aFrame);
       
   492 			    		}
       
   493 			    	break;
       
   494 			    	}
       
   495 			    default:
       
   496 			    	{
       
   497 			    	// Should never hit here
       
   498 			    	AvrcpUtils::Panic(EAvrcpResponseToUnknownCommand);
       
   499 			        break;
       
   500 			    	}
       
   501 			    }
       
   502 			}
       
   503 		else
       
   504 			{
       
   505 			ParseIncomingUnknownResponse(aObserver, aFrame);
       
   506 			}
       
   507 		}
       
   508 	else
       
   509 		{
       
   510 		ParseIncomingUnknownResponse(aObserver, aFrame);
       
   511 		}
       
   512 	
       
   513 	return error;
       
   514 	}
       
   515 
       
   516 /** Processes an outgoing response.
       
   517 
       
   518 This should only be called for vendor dependent commands as
       
   519 we respond to passthrough commands internally.
       
   520 
       
   521 @param aObserver Observer to use for retrieving converter.
       
   522 @param aFrame The command data for the response.
       
   523 */
       
   524 TInt CControlCommand::ProcessOutgoingResponse(MRemConBearerObserver& aObserver,
       
   525 //											TRemConMessageType aMessageType,
       
   526 											RBuf8& aResponseData,
       
   527 											CAVRCPFragmenter& aFragmenter)
       
   528 	{
       
   529 	TRAPD(err, DoProcessOutgoingResponseL(aObserver,aResponseData, aFragmenter));
       
   530 	return err;
       
   531 	}
       
   532 
       
   533 void CControlCommand::DoProcessOutgoingResponseL(MRemConBearerObserver& aObserver,
       
   534 											 RBuf8& aResponseData,
       
   535 											 CAVRCPFragmenter& aFragmenter)
       
   536 	{
       
   537 	LOG_FUNC
       
   538 	
       
   539 	// Payload size may be increased in GenerateMetadataResponsePayload
       
   540 	// if there's a very large response which needs fragmenting
       
   541 	RBuf8 payload;
       
   542 	payload.CreateL(KAVCFrameMaxLength);
       
   543 	CleanupClosePushL(payload);
       
   544 
       
   545 	if(( iInterfaceUid.iUid == KRemConMediaInformationApiUid ) 
       
   546 		|| ( iInterfaceUid.iUid == KRemConPlayerInformationUid )
       
   547 		|| ( iInterfaceUid.iUid == KRemConAbsoluteVolumeTargetApiUid )
       
   548 		|| ( iInterfaceUid.iUid == KRemConNowPlayingApiUid )
       
   549 		|| ( iInterfaceUid.iUid == KUidAvrcpInternalInterface))
       
   550 		{
       
   551 		// metadata
       
   552 		// "this" is the command for which the response lurks in aCommandData
       
   553 		// GenerateMetadataResponsePayload() MUST set PDU id, fragmentation stauts
       
   554 		// and paramlen (4 bytes total) - check this in ASSERT_DEBUG
       
   555 		User::LeaveIfError(GenerateMetadataResponsePayload(aObserver, payload, aResponseData));
       
   556 		__ASSERT_DEBUG(payload.Length() >= KAVRCPMinVendorDependentResponseLen, AvrcpUtils::Panic(EAvrcpFunnyLengthData));
       
   557 		aResponseData.Close();
       
   558 		
       
   559 		if (payload.Length() > KAVCMaxVendorDependentPayload)
       
   560 			{
       
   561 			// Fragment response (in payload) and queue fragments ready
       
   562 			// for sending when CT sends a CONTINUE request. If any other
       
   563 			// request is received (other than pass-through) then throw
       
   564 			// away our fragmented packet, as the CT has aborted.
       
   565 			aFragmenter.AssignPayload(payload);
       
   566 			payload.Assign(NULL);
       
   567 			payload.Close();
       
   568 			
       
   569 			// Re-allocate this back to a sensible size
       
   570 			// from the much larger size, which has now been
       
   571 			// assigned to fragmenter (avoids copying payload)
       
   572 			payload.CreateL(KAVCFrameMaxLength);
       
   573 			payload.Append(aFragmenter.GetNextFragmentHeader());
       
   574 			payload.Append(aFragmenter.GetNextFragment());
       
   575 			}
       
   576 			
       
   577 		CAVCFrame* frame = CAVCVendorDependentResponse::NewL(KBluetoothSIGVendorId);
       
   578 		frame->Append(payload);
       
   579 		frame->SetType(iFrame->Type());
       
   580 		delete iFrame;
       
   581 		iFrame = frame;
       
   582 		}
       
   583 	else
       
   584 		{
       
   585 		User::LeaveIfError(aObserver.InterfaceToBearer(TUid::Uid(KRemConBearerAvrcpImplementationUid),
       
   586 							iInterfaceUid, iOperationId,
       
   587 							aResponseData, /*ERemConCommand*/ERemConResponse, payload));
       
   588 		aResponseData.Close();
       
   589 		CAVCFrame* frame = CAVCFrame::NewL(payload, AVC::EResponse);
       
   590 		delete iFrame;
       
   591 		iFrame = frame;
       
   592 		}
       
   593 		
       
   594 	CleanupStack::PopAndDestroy(&payload);
       
   595 	}
       
   596 
       
   597 /** Set the response type in the AV/C frame.
       
   598 
       
   599 @param aErr The result of processing the operation. KErrNone if 
       
   600 			successful. KErrNotsupported if this operation is not
       
   601 			implemented, eg because no converter was found.
       
   602 */
       
   603 void CControlCommand::SetResponseType(TInt aErr)
       
   604 	{
       
   605 	LOG_FUNC
       
   606 	AVC::TCType cType = iFrame->Type();
       
   607 	switch(aErr)
       
   608 		{
       
   609 		case KErrNone:
       
   610 		case KErrCompletion:
       
   611 			if (cType == AVC::EControl)
       
   612 				{
       
   613 				iFrame->SetType(AVC::EAccepted);
       
   614 				}
       
   615 			else if (cType == AVC::ENotify)
       
   616 				{
       
   617 				iFrame->SetType(AVC::EInterim);
       
   618 				}
       
   619 			else if (cType == AVC::EInterim)
       
   620 				{
       
   621 				iFrame->SetType(AVC::EChanged);
       
   622 				}
       
   623 			else if (cType == AVC::EStatus)
       
   624 				{
       
   625 				iFrame->SetType(AVC::EStable);
       
   626 				}
       
   627 			else 
       
   628 				{
       
   629 				iFrame->SetType(AVC::EImplemented);
       
   630 				}
       
   631 			break;
       
   632 		case KErrAvrcpMetadataInvalidCommand:
       
   633 		case KErrAvrcpMetadataInvalidParameter:
       
   634 		case KErrAvrcpMetadataParameterNotFound:
       
   635 		case KErrAvrcpMetadataInternalError:
       
   636 		case KErrAvrcpAirInvalidCommand:
       
   637 		case KErrAvrcpAirInvalidParameter:
       
   638 		case KErrAvrcpAirParameterNotFound:
       
   639 		case KErrAvrcpAirInternalError:
       
   640 		case KErrAvrcpAirSuccess:
       
   641 		case KErrAvrcpAirUidChanged:
       
   642 		case KErrAvrcpAirReserved:
       
   643 		case KErrAvrcpAirInvalidDirection:
       
   644 		case KErrAvrcpAirNotADirectory:
       
   645 		case KErrAvrcpAirDoesNotExist:
       
   646 		case KErrAvrcpAirInvalidScope:
       
   647 		case KErrAvrcpAirRangeOutOfBounds:
       
   648 		case KErrAvrcpAirUidIsADirectory:
       
   649 		case KErrAvrcpAirMediaInUse:
       
   650 		case KErrAvrcpAirNowPlayingListFull:
       
   651 		case KErrAvrcpAirSearchNotSupported:
       
   652 		case KErrAvrcpAirSearchInProgress:
       
   653 		case KErrAvrcpAirInvalidPlayerId:
       
   654 		case KErrAvrcpAirPlayerNotBrowesable:
       
   655 		case KErrAvrcpAirPlayerNotAddressed:
       
   656 		case KErrAvrcpAirNoValidSearchResults:
       
   657 		case KErrAvrcpAirNoAvailablePlayers:
       
   658 		case KErrAvrcpAirAddressedPlayerChanged:
       
   659 			{
       
   660 			// If this fails, we're OOM (it only contains a NewL)
       
   661 			// so we can't send the error response - just give up
       
   662 			TRAPD(err, GenerateMetadataRejectPayloadL(aErr));
       
   663 			err = err;  // avoid warning about not using this
       
   664 			break;
       
   665 			}
       
   666 		default:
       
   667 			iFrame->SetType(AVC::ENotImplemented);
       
   668 		}
       
   669 	iFrame->SetFrameType(AVC::EResponse);	
       
   670 	}
       
   671 
       
   672 /** Gets this command's AV/C frame.
       
   673 @return the AV/C frame for this command
       
   674 */	
       
   675 const CAVCFrame& CControlCommand::Frame() const
       
   676 	{
       
   677 	LOG_FUNC
       
   678 	return *iFrame;
       
   679 	}
       
   680 
       
   681 const TDesC8& CControlCommand::Data() const
       
   682 	{
       
   683 	LOG_FUNC
       
   684 	return iFrame->Data();
       
   685 	}
       
   686 
       
   687 SymbianAvctp::TMessageType CControlCommand::MessageType() const
       
   688 	{
       
   689 	LOG_FUNC
       
   690 	return (iFrame->FrameType() == AVC::ECommand) ? SymbianAvctp::ECommand : SymbianAvctp::EResponse;
       
   691 	}
       
   692 
       
   693 /** Gets the button action from this command's AV/C frame.
       
   694 This is only valid on passthrough commands.
       
   695 
       
   696 @return The button action.
       
   697 */
       
   698 AVCPanel::TButtonAction CControlCommand::ButtonAct() const
       
   699 	{
       
   700 	LOG_FUNC
       
   701 	AVCPanel::TButtonAction act;
       
   702 	iFrame->ButtonAct(act);
       
   703 	return act;
       
   704 	}
       
   705 
       
   706 /** Gets whether this command is currently assumed to be a click.
       
   707 
       
   708 This is used to support the click facility offered by RemCon, which
       
   709 is not offered by AVRCP.  As such AVRCP internally simulates outgoing
       
   710 clicks by generating a press and release for one RemCon click.  When
       
   711 responses are received we know that if a command is a click we should
       
   712 send only one response up to RemCon.
       
   713 
       
   714 Incoming passthrough press commands are assumed to be click until
       
   715 the hold timer expires.  When a matching release is received we can
       
   716 then tell whether we need to send a single click up to RemCon, or 
       
   717 a release to match the press that was sent when the hold timer expired.
       
   718 
       
   719 @return ETrue is this is a click. EFalse if not.
       
   720 */
       
   721 TBool CControlCommand::Click() const
       
   722 	{
       
   723 	LOG_FUNC
       
   724 	return iIsClick;
       
   725 	}
       
   726 
       
   727 /** Sets whether this command is currently assumed to be a click
       
   728 or not.
       
   729 
       
   730 @see CRcpcommand::Click()
       
   731 @param aIsClick ETrue to set this as click. EFalse to set this as 
       
   732 				not click.
       
   733 */	
       
   734 void CControlCommand::SetClick(TBool aIsClick)
       
   735 	{
       
   736 	LOG_FUNC
       
   737 	iIsClick = aIsClick;
       
   738 	}
       
   739 
       
   740 /** Sets the RemCon data to indicate what button action this 
       
   741 command is.  This function is only valid for commands in the
       
   742 core api.
       
   743 
       
   744 @param aButtonAct The RemCon button action for this command.
       
   745 @param aCommand Whether this is a command. This is needed
       
   746 				because the command data is at a different offset for
       
   747 				commands and responses.
       
   748 */
       
   749 void CControlCommand::SetCoreButtonAction(TRemConCoreApiButtonAction aButtonAct, TBool aCommand)
       
   750 	{
       
   751 	LOG_FUNC
       
   752 	
       
   753 	TInt offset = aCommand ? KRemConCoreApiButtonDataOffset + KRemConCoreApiCommandDataOffset
       
   754 						   : KRemConCoreApiButtonDataOffset + KRemConCoreApiResponseDataOffset;
       
   755 						   
       
   756 	AvrcpUtils::SetCommandDataFromInt(iCommandData, offset, 
       
   757 						  KRemConCoreApiButtonDataLength, aButtonAct);
       
   758 	}
       
   759 /** ReSets the RemCon data to indicate what button action this 
       
   760 command is. This function is called when we the command is being re-used to generate a 
       
   761 new command to remconServ.
       
   762 
       
   763 @param aButtonAct The RemCon button action for this command.
       
   764 @param aCommand Whether this is a command. This is needed
       
   765 				because the command data is at a different offset for
       
   766 				commands and responses.
       
   767 */
       
   768 void CControlCommand::ReSetCoreButtonActionL(TRemConCoreApiButtonAction aButtonAct, TBool aCommand)
       
   769 	{
       
   770 	LOG_FUNC
       
   771 	
       
   772 	if (iCommandData.MaxLength() < KRemConCoreApiButtonDataLength)
       
   773 		{
       
   774 		iCommandData.Close();
       
   775 		iCommandData.CreateMaxL(KRemConCoreApiButtonDataLength);
       
   776 		}
       
   777 	
       
   778 	SetCoreButtonAction(aButtonAct, aCommand);
       
   779 	}
       
   780 
       
   781 /** Inserts the results at the beginning of this command's data.
       
   782 If the data buffer is not large enough it will be ReAlloced to 
       
   783 allow the insertion.
       
   784 
       
   785 @return The result to pass to RemCon. KErrNone for an AV/C accepted.
       
   786 		KErrNotSupported for an AV/C not implemented. KErrGeneral
       
   787 		for an AV/C rejected. 
       
   788 */
       
   789 TInt CControlCommand::InsertCoreResult(TInt aResult)
       
   790 	{
       
   791 	LOG_FUNC
       
   792 	TInt err = KErrNone;
       
   793 	TInt requiredLength = KRemConCoreApiResultDataLength + iCommandData.Length();
       
   794 	
       
   795 	if(iCommandData.Length() >= requiredLength)
       
   796 		{
       
   797 		// Insert data to write result into
       
   798 		iCommandData.Insert(0, KRemConCoreApiResultPad);
       
   799 		}
       
   800 	else
       
   801 		{
       
   802 		// need longer buffer
       
   803 		err = iCommandData.ReAlloc(requiredLength);
       
   804 		if(!err)
       
   805 			{
       
   806 			iCommandData.Insert(0, KRemConCoreApiResultPad);
       
   807 			}
       
   808 		else
       
   809 			{
       
   810 			return err;
       
   811 			}
       
   812 		}
       
   813 
       
   814 	AvrcpUtils::SetCommandDataFromInt(iCommandData, 0, 
       
   815 						  KRemConCoreApiResultDataLength, aResult);
       
   816 	return err;
       
   817 	}
       
   818 
       
   819 /**
       
   820 Sets the result of set absolute volume response into this command's data
       
   821 */
       
   822 TInt CControlCommand::SetSetAbsoluteVolumeResult(const CAVCFrame& aFrame)
       
   823 	{
       
   824 	TInt err = KErrNone;
       
   825     TRAP(err, DoSetAbsoluteVolumeResultL(aFrame));
       
   826     if (err != KErrNone)
       
   827     	{
       
   828     	// Ensure the client can receive an error in case of 
       
   829     	// DoSetAbsoluteVolumeResultL leaves out.
       
   830     	iCommandData.Zero();
       
   831     	TPckgBuf<TInt> errBuf(err);
       
   832     	iCommandData.Append(errBuf);
       
   833     	iCommandData.SetLength(iCommandData.MaxLength());
       
   834     	}
       
   835     return err;
       
   836 	}
       
   837 
       
   838 void CControlCommand::DoSetAbsoluteVolumeResultL(const CAVCFrame& aFrame)
       
   839 	{
       
   840 	RRemConAbsoluteVolumeResponse absVol;	
       
   841 	absVol.iError = KErrGeneral;
       
   842 	absVol.iMaxVolume = KAvrcpMaxAbsoluteVolume;
       
   843 	
       
   844 	CleanupClosePushL(absVol);	
       
   845 	
       
   846 	switch(aFrame.Type())
       
   847         {
       
   848         case AVC::EAccepted:
       
   849 	        {
       
   850 	        if (aFrame.Data().Length() == KLengthSetAbsoluteVolumeResponse)
       
   851 		        {
       
   852 		        absVol.iError = KErrNone;
       
   853 		        TUint volumeOffset = KLengthSetAbsoluteVolumeResponse - 1;
       
   854 		        absVol.iVolume = KAbsoluteVolumeMask & aFrame.Data()[volumeOffset];
       
   855 		        }
       
   856 		    break;
       
   857 		    }
       
   858         case AVC::ERejected: // fall through
       
   859         case AVC::ENotImplemented:
       
   860         	break;
       
   861 	    default:
       
   862 	    	break;
       
   863         }
       
   864 	
       
   865 	absVol.WriteL(iCommandData);
       
   866 	CleanupStack::PopAndDestroy(&absVol);
       
   867 	}
       
   868 /**
       
   869 Sets the result of volume changed notification response into this command's 
       
   870 data.
       
   871 */
       
   872 TInt CControlCommand::SetNotifyVolumeChangeResult(const CAVCFrame& aFrame)
       
   873 	{
       
   874 	TInt err = KErrNone;
       
   875 	TRAP(err, DoSetNotifyVolumeChangeResultL(aFrame));
       
   876     if (err == KErrNone)
       
   877     	{
       
   878     	// Through AVC::TCType the RemCon sever can know whether the response
       
   879     	// is an Interim or Changed or any other responses, so the RemCon 
       
   880     	// server can decide to remove the notify command from its 
       
   881     	// outgoingsent queue or not.
       
   882     	iFrame->SetType(aFrame.Type());
       
   883     	}
       
   884     else
       
   885     	{
       
   886     	// Ensure the client can receive an error in case of 
       
   887     	// DoSetNotifyVolumeChangeResultL leaves out.
       
   888     	iCommandData.Zero();
       
   889     	TPckgBuf<TInt> errBuf(KErrGeneral);
       
   890     	iCommandData.Append(errBuf);
       
   891     	iCommandData.SetLength(iCommandData.MaxLength());
       
   892     	
       
   893     	// Setting AVC::TCType to ERejected is intended to let the RemCon
       
   894     	// server to remove the notify command from its outgoingsent queue
       
   895     	// in case of DoSetNotifyVolumeChangeResultL leaves out.
       
   896     	iFrame->SetType(AVC::ERejected);
       
   897     	}
       
   898     
       
   899     return err;
       
   900 	}
       
   901 
       
   902 void CControlCommand::DoSetNotifyVolumeChangeResultL(const CAVCFrame& aFrame)
       
   903 	{
       
   904 	if (iCommandData.MaxLength() < KAbsoluteVolumeResponseDataSize)
       
   905 		{
       
   906 		iCommandData.Close();
       
   907 		iCommandData.CreateL(KAbsoluteVolumeResponseDataSize);
       
   908 		}
       
   909 	
       
   910 	RRemConAbsoluteVolumeResponse absVol;
       
   911 	absVol.iError = KErrGeneral;
       
   912 	absVol.iMaxVolume = KAvrcpMaxAbsoluteVolume;
       
   913 	
       
   914 	CleanupClosePushL(absVol);	
       
   915 	
       
   916 	switch(aFrame.Type())
       
   917         {
       
   918 	    case AVC::EInterim:
       
   919 	    case AVC::EChanged:
       
   920 		    {
       
   921 		    if (aFrame.Data().Length() == KLengthNotifyVolumeChangeResponse)
       
   922 		    	{
       
   923 		    	absVol.iError = KErrNone;
       
   924 		    	TUint volumeOffset = KLengthNotifyVolumeChangeResponse - 1;
       
   925 		    	absVol.iVolume = KAbsoluteVolumeMask & aFrame.Data()[volumeOffset];			    	
       
   926 		    	}		    
       
   927 		    break;
       
   928 		    }
       
   929 	    case AVC::ERejected: // fall through
       
   930 	    case AVC::ENotImplemented:
       
   931 	    	break;
       
   932 	    default:
       
   933 	    	break;
       
   934         }
       
   935 	absVol.WriteL(iCommandData);
       
   936 	CleanupStack::PopAndDestroy(&absVol);
       
   937 	}
       
   938 //------------------------------------------------------------------------------------
       
   939 // Internal utility functions
       
   940 //------------------------------------------------------------------------------------
       
   941 
       
   942 /** Fills in command info from an AVC Control.
       
   943 
       
   944 This functions sets iInterfaceUid, iOperationId and iCommandData
       
   945 to the correct values according to iFrame.  The format of iCommandData
       
   946 is defined by RemCon and is dependent on iInterfaceUid and iOperationId.
       
   947 
       
   948 @return KErrNone				If the frame has been parsed successfully.
       
   949 @return KErrNotSupported		This frame represents a command for which a
       
   950 								RemCon converter or client side interface
       
   951 								cannot be found.
       
   952 @return	System wide error code.
       
   953 */
       
   954 TInt CControlCommand::ParseIncomingKnownOpcodeL(MRemConBearerObserver& aObserver)
       
   955 	{
       
   956 	LOG_FUNC
       
   957 	TInt err = KErrNotSupported;
       
   958 	
       
   959 	AVC::TCType cType = iFrame->Type();
       
   960 	
       
   961 	switch(iFrame->Opcode())
       
   962 		{
       
   963 		case AVC::EPassThrough:
       
   964 			{
       
   965 			if(iFrame->Data().Length() < KAVCPassthroughFrameLength)
       
   966 				{
       
   967 				LEAVEL(KErrCorrupt);
       
   968 				}
       
   969 			if (iFrame->SubunitType() != AVC::EPanel)
       
   970 				{
       
   971 				LEAVEL(KErrNotSupported);
       
   972 				}
       
   973 	
       
   974 			TUint8 avrcpOp;			
       
   975 			if (cType != AVC::EGeneralEnquiry && cType == AVC::EControl)
       
   976 				{
       
   977 				iCommandData.CreateMaxL(KRemConCoreApiButtonDataLength);
       
   978 				err = iFrame->OperationId(avrcpOp);
       
   979 				if (err == KErrNone)
       
   980 					{
       
   981 					if (avrcpOp!=AVCPanel::EVendorUnique)
       
   982 						{
       
   983 						err = AvrcpToRemConOperation(avrcpOp, iOperationId, iInterfaceUid);
       
   984 						}
       
   985 					else
       
   986 						{
       
   987 						err = ParseVendorUniquePassthroughCommand(aObserver);
       
   988 						}
       
   989 					}
       
   990 				
       
   991 				if (err!=KErrNone)
       
   992 					{
       
   993 					err = KErrAvrcpInvalidOperationId;
       
   994 					}
       
   995 				}
       
   996 			else
       
   997 				{
       
   998 				iCommandData.Close();
       
   999 				iCommandData.CreateL(KAVCFrameMaxLength);
       
  1000 				TRemConMessageType message = ERemConCommand;
       
  1001 				err = aObserver.BearerToInterface(TUid::Uid(KRemConBearerAvrcpImplementationUid),
       
  1002 													iFrame->Data(),
       
  1003 													iFrame->Data(),
       
  1004 													iInterfaceUid,
       
  1005 													iOperationId,
       
  1006 													message,
       
  1007 													iCommandData);
       
  1008 				}
       
  1009 			break;
       
  1010 			}
       
  1011 		case AVC::EUnitInfo:
       
  1012 			{
       
  1013 			if (iFrame->Type() == AVC::EStatus)
       
  1014 				{
       
  1015 				CAVCFrame* resp = AvrcpCommandFramer::UnitInfoResponseL();
       
  1016 				delete iFrame;
       
  1017 				iFrame = resp;
       
  1018 				err = KErrCompletion; // since bearer has done its job without client needed
       
  1019 				}
       
  1020 			else
       
  1021 				{
       
  1022 				err = KErrAvrcpInvalidCType;
       
  1023 				}
       
  1024 			break;
       
  1025 			}
       
  1026 		case AVC::ESubunitInfo:
       
  1027 			{
       
  1028 			if (iFrame->Type() == AVC::EStatus)
       
  1029 				{
       
  1030 				CAVCFrame* resp = AvrcpCommandFramer::SubunitInfoResponseL();
       
  1031 				delete iFrame;
       
  1032 				iFrame = resp;
       
  1033 				err = KErrCompletion; // since bearer has done its job without client needed
       
  1034 				}
       
  1035 			else
       
  1036 				{
       
  1037 				err = KErrAvrcpInvalidCType;
       
  1038 				}
       
  1039 			break;
       
  1040 			}
       
  1041 
       
  1042 		default:
       
  1043 			{
       
  1044 			iCommandData.Close();
       
  1045 			iCommandData.CreateL(KAVCFrameMaxLength);
       
  1046 			TRemConMessageType message = ERemConCommand;
       
  1047 			err = aObserver.BearerToInterface(TUid::Uid(KRemConBearerAvrcpImplementationUid),
       
  1048 												iFrame->Data(),
       
  1049 												iFrame->Data(),
       
  1050 												iInterfaceUid,
       
  1051 												iOperationId,
       
  1052 												message,
       
  1053 												iCommandData);
       
  1054 			break;
       
  1055 			}
       
  1056 		}
       
  1057 		
       
  1058 	return err;
       
  1059 	}
       
  1060 	
       
  1061 
       
  1062 /** Fills in command info from an AVC Vendor Dependent message.
       
  1063 
       
  1064 This functions sets iInterfaceUid, iOperationId and iCommandData
       
  1065 to the correct values according to iFrame.  The format of iCommandData
       
  1066 is defined by RemCon and is dependent on iInterfaceUid and iOperationId.
       
  1067 The AVC frame's length is checked that it at least contains the vendor id.
       
  1068 
       
  1069 @param aObserver An observer to be used to obtain a converter.
       
  1070 @return KErrNone				If the frame has been parsed successfully.
       
  1071 @return KErrNotSupported		This frame represents a command for which a
       
  1072 								RemCon converter or client side interface
       
  1073 								cannot be found.
       
  1074 @return KErrAvrcpInvalidCType	The CType specified in this frame is invalid.
       
  1075 @return KErrAvrcpMetadataInvalidCommand		The AVRCP command is invalid.
       
  1076 @return KErrAvrcpMetadataInvalidParameter	The AVRCP parameter is invalid.
       
  1077 @return KErrAvrcpMetadataParameterNotFound	The AVRCP parameter was not found.
       
  1078 @return KErrAvrcpMetadataInternalError		An AVRCP internal error occurred (such as out-of-memory,
       
  1079 											or an inter-process communication error)
       
  1080 @return	System wide error code.
       
  1081 */	
       
  1082 TInt CControlCommand::ParseIncomingVendorCommandL(MRemConBearerObserver& aObserver, CAVRCPFragmenter& aFragmenter)
       
  1083 	{
       
  1084 	LOG_FUNC
       
  1085 	TInt err = KErrNone;
       
  1086 
       
  1087 	SetVendorInfoL(EFalse); // set id and payload; leaves if not enough space available
       
  1088 	
       
  1089 	if (iVendorId!=KBluetoothSIGVendorId)
       
  1090 		{
       
  1091 		iCommandData.Close();
       
  1092 		iCommandData.CreateL(KAVCFrameMaxLength);
       
  1093 	
       
  1094 		TRemConMessageType message = ERemConCommand;
       
  1095 		
       
  1096 		err = aObserver.BearerToInterface(TUid::Uid(KRemConBearerAvrcpImplementationUid),
       
  1097 											iFrame->Data(),
       
  1098 											iFrame->Data(),
       
  1099 											iInterfaceUid,
       
  1100 											iOperationId,
       
  1101 											message,
       
  1102 											iCommandData);
       
  1103 		}
       
  1104 	else
       
  1105 		{
       
  1106 		// process v>1.0 version of AVRCP
       
  1107 		// which use vendor dependent frames to extend v1.0 of AVRCP
       
  1108 		// the vendor code has the value for the BT SIG
       
  1109 		if (iFrame->SubunitType() != AVC::EPanel)
       
  1110 			{
       
  1111 			// this is for Control not Metadata
       
  1112 			return KErrNotSupported;
       
  1113 			}
       
  1114 		
       
  1115 		err = ParseMetadataTransferVendorCommand(aFragmenter);
       
  1116 		if (err == KErrNone)
       
  1117 			{
       
  1118 			// Check that the interface UID is non-zero
       
  1119 			__ASSERT_DEBUG(iInterfaceUid != TUid::Uid(0), AvrcpUtils::Panic(EAvrcpInterfaceUidNotSet));
       
  1120 			}
       
  1121 		}
       
  1122 	return err;
       
  1123 	}
       
  1124 
       
  1125 
       
  1126 /** Creates RemCon command information from iFrame.
       
  1127 
       
  1128 This functions sets iInterfaceUid, iOperationId and iCommandData
       
  1129 to the correct values according to iFrame.  The format of iCommandData
       
  1130 is defined by the interface, iInterfaceUid and is dependent on 
       
  1131 iOperationId.  A converter should be able to be found as this response
       
  1132 is a result of an outgoing command on this interface.
       
  1133 
       
  1134 @param aObserver An observer used to get a converter.
       
  1135 @param aFrame The AV/C frame for this command.
       
  1136 */
       
  1137 void CControlCommand::ParseIncomingUnknownResponse(MRemConBearerObserver& aObserver, 
       
  1138 	const CAVCFrame& aFrame)
       
  1139 	{
       
  1140 	LOG_FUNC
       
  1141 	// We need to pass a response up to RemCon even if we can't get a
       
  1142 	// converter to generate a decent response so we don't 
       
  1143 
       
  1144 	iCommandData.Close();
       
  1145 	TInt err = iCommandData.Create(KAVCFrameMaxLength);
       
  1146 	if(!err)
       
  1147 		{
       
  1148 		TRemConMessageType type = ERemConResponse; // output param
       
  1149 		err = aObserver.BearerToInterface(TUid::Uid(KRemConBearerAvrcpImplementationUid),
       
  1150 			aFrame.Data(), aFrame.Data(), iInterfaceUid, iOperationId, type, iCommandData);
       
  1151 		}
       
  1152 	}
       
  1153 
       
  1154 /** Translates from an AVC operation id to RemCon's core interface.
       
  1155 
       
  1156 @param aAvrcpOp		The AVC passthrough operation id.
       
  1157 @param aRemConOp	On return the RemCon operation id within the core interface.
       
  1158 @return KErrNone	If the operation has been translated successfully.
       
  1159 @return KErrNotSupported	If the operation does not correspond to one
       
  1160 							in the RemCon core interface.
       
  1161 */
       
  1162 TInt CControlCommand::AvrcpToRemConOperation(TUint aAvrcpOp, TUint& aRemConOp, TUid& aRemConIf)
       
  1163 	{
       
  1164 	LOG_STATIC_FUNC
       
  1165 	TInt err = KErrNone;
       
  1166 
       
  1167 	//TBH setting here as most are for the Core API
       
  1168 	//some cases will override
       
  1169 	aRemConIf = TUid::Uid(KRemConCoreApiUid);
       
  1170 
       
  1171 	switch(aAvrcpOp)	
       
  1172 		{
       
  1173 		case AVCPanel::ESelect:
       
  1174 			aRemConOp = ERemConCoreApiSelect;
       
  1175 			break;
       
  1176 		case AVCPanel::EUp:
       
  1177 			aRemConOp = ERemConCoreApiUp;
       
  1178 			break;
       
  1179 		case AVCPanel::EDown:
       
  1180 			aRemConOp = ERemConCoreApiDown;
       
  1181 			break;
       
  1182 		case AVCPanel::ELeft:
       
  1183 			aRemConOp = ERemConCoreApiLeft;
       
  1184 			break;
       
  1185 		case AVCPanel::ERight:
       
  1186 			aRemConOp = ERemConCoreApiRight;
       
  1187 			break;
       
  1188 		case AVCPanel::ERightUp:
       
  1189 			aRemConOp = ERemConCoreApiRightUp;
       
  1190 			break;
       
  1191 		case AVCPanel::ERightDown:
       
  1192 			aRemConOp = ERemConCoreApiRightDown;
       
  1193 			break;
       
  1194 		case AVCPanel::ELeftUp:
       
  1195 			aRemConOp = ERemConCoreApiLeftUp;
       
  1196 			break;
       
  1197 		case AVCPanel::ELeftDown:
       
  1198 			aRemConOp = ERemConCoreApiLeftDown;
       
  1199 			break;
       
  1200 		case AVCPanel::ERootMenu:
       
  1201 			aRemConOp = ERemConCoreApiRootMenu;
       
  1202 			break;
       
  1203 		case AVCPanel::ESetupMenu:
       
  1204 			aRemConOp = ERemConCoreApiSetupMenu;
       
  1205 			break;
       
  1206 		case AVCPanel::EContentsMenu:
       
  1207 			aRemConOp = ERemConCoreApiContentsMenu;
       
  1208 			break;
       
  1209 		case AVCPanel::EFavoriteMenu:
       
  1210 			aRemConOp = ERemConCoreApiFavoriteMenu;
       
  1211 			break;
       
  1212 		case AVCPanel::EExit:
       
  1213 			aRemConOp = ERemConCoreApiExit;
       
  1214 			break;
       
  1215 		case AVCPanel::E0:
       
  1216 			aRemConOp = ERemConCoreApi0;
       
  1217 			break;
       
  1218 		case AVCPanel::E1:
       
  1219 			aRemConOp = ERemConCoreApi1;
       
  1220 			break;
       
  1221 		case AVCPanel::E2:
       
  1222 			aRemConOp = ERemConCoreApi2;
       
  1223 			break;
       
  1224 		case AVCPanel::E3:
       
  1225 			aRemConOp = ERemConCoreApi3;
       
  1226 			break;
       
  1227 		case AVCPanel::E4:
       
  1228 			aRemConOp = ERemConCoreApi4;
       
  1229 			break;
       
  1230 		case AVCPanel::E5:
       
  1231 			aRemConOp = ERemConCoreApi5;
       
  1232 			break;
       
  1233 		case AVCPanel::E6:
       
  1234 			aRemConOp = ERemConCoreApi6;
       
  1235 			break;
       
  1236 		case AVCPanel::E7:
       
  1237 			aRemConOp = ERemConCoreApi7;
       
  1238 			break;
       
  1239 		case AVCPanel::E8:
       
  1240 			aRemConOp = ERemConCoreApi8;
       
  1241 			break;
       
  1242 		case AVCPanel::E9:
       
  1243 			aRemConOp = ERemConCoreApi9;
       
  1244 			break;
       
  1245 		case AVCPanel::EDot:
       
  1246 			aRemConOp = ERemConCoreApiDot;
       
  1247 			break;
       
  1248 		case AVCPanel::EEnter:
       
  1249 			aRemConOp = ERemConCoreApiEnter;
       
  1250 			break;
       
  1251 		case AVCPanel::EClear:
       
  1252 			aRemConOp = ERemConCoreApiClear;
       
  1253 			break;
       
  1254 		case AVCPanel::EChannelUp:
       
  1255 			aRemConOp = ERemConCoreApiChannelUp;
       
  1256 			break;
       
  1257 		case AVCPanel::EChannelDown:
       
  1258 			aRemConOp = ERemConCoreApiChannelDown;
       
  1259 			break;
       
  1260 		case AVCPanel::EPreviousChannel:
       
  1261 			aRemConOp = ERemConCoreApiPreviousChannel;
       
  1262 			break;
       
  1263 		case AVCPanel::ESoundSelect:
       
  1264 			aRemConOp = ERemConCoreApiSoundSelect;
       
  1265 			break;
       
  1266 		case AVCPanel::EInputSelect:
       
  1267 			aRemConOp = ERemConCoreApiInputSelect;
       
  1268 			break;
       
  1269 		case AVCPanel::EDisplayInformation:
       
  1270 			aRemConOp = ERemConCoreApiDisplayInformation;
       
  1271 			break;
       
  1272 		case AVCPanel::EHelp:
       
  1273 			aRemConOp = ERemConCoreApiHelp;
       
  1274 			break;
       
  1275 		case AVCPanel::EPageUp:
       
  1276 			aRemConOp = ERemConCoreApiPageUp;
       
  1277 			break;
       
  1278 		case AVCPanel::EPageDown:
       
  1279 			aRemConOp = ERemConCoreApiPageDown;
       
  1280 			break;
       
  1281 		case AVCPanel::EPower:
       
  1282 			aRemConOp = ERemConCoreApiPower;
       
  1283 			break;
       
  1284 		case AVCPanel::EVolumeUp:
       
  1285 			aRemConOp = ERemConCoreApiVolumeUp;
       
  1286 			break;
       
  1287 		case AVCPanel::EVolumeDown:
       
  1288 			aRemConOp = ERemConCoreApiVolumeDown;
       
  1289 			break;
       
  1290 		case AVCPanel::EMute:
       
  1291 			aRemConOp = ERemConCoreApiMute;
       
  1292 			break;
       
  1293 		case AVCPanel::EPlay:
       
  1294 			aRemConOp = ERemConCoreApiPlay;
       
  1295 			break;
       
  1296 		case AVCPanel::EStop:
       
  1297 			aRemConOp = ERemConCoreApiStop;
       
  1298 			break;
       
  1299 		case AVCPanel::EPause:
       
  1300 			aRemConOp = ERemConCoreApiPause;
       
  1301 			break;
       
  1302 		case AVCPanel::ERecord:
       
  1303 			aRemConOp = ERemConCoreApiRecord;
       
  1304 			break;
       
  1305 		case AVCPanel::ERewind:
       
  1306 			aRemConOp = ERemConCoreApiRewind;
       
  1307 			break;
       
  1308 		case AVCPanel::EFastForward:
       
  1309 			aRemConOp = ERemConCoreApiFastForward;
       
  1310 			break;
       
  1311 		case AVCPanel::EEject:
       
  1312 			aRemConOp = ERemConCoreApiEject;
       
  1313 			break;
       
  1314 		case AVCPanel::EForward:
       
  1315 			aRemConOp = ERemConCoreApiForward;
       
  1316 			break;
       
  1317 		case AVCPanel::EBackward:
       
  1318 			aRemConOp = ERemConCoreApiBackward;
       
  1319 			break;
       
  1320 		case AVCPanel::EAngle:
       
  1321 			aRemConOp = ERemConCoreApiAngle;
       
  1322 			break;
       
  1323 		case AVCPanel::ESubpicture:
       
  1324 			aRemConOp = ERemConCoreApiSubpicture;
       
  1325 			break;
       
  1326 		case AVCPanel::EF1:
       
  1327 			aRemConOp = ERemConCoreApiF1;
       
  1328 			break;
       
  1329 		case AVCPanel::EF2:
       
  1330 			aRemConOp = ERemConCoreApiF2;
       
  1331 			break;
       
  1332 		case AVCPanel::EF3:
       
  1333 			aRemConOp = ERemConCoreApiF3;
       
  1334 			break;
       
  1335 		case AVCPanel::EF4:
       
  1336 			aRemConOp = ERemConCoreApiF4;
       
  1337 			break;
       
  1338 		case AVCPanel::EF5:
       
  1339 			aRemConOp = ERemConCoreApiF5;
       
  1340 			break;
       
  1341 		case AVCPanel::EVendorUnique:
       
  1342 		default:
       
  1343 			err = KErrNotSupported;
       
  1344 		}
       
  1345 		
       
  1346 	return err;
       
  1347 	}
       
  1348 	
       
  1349 
       
  1350 TInt CControlCommand::ParseVendorUniquePassthroughCommand(MRemConBearerObserver& aObserver)
       
  1351 	{
       
  1352 	TInt err = KErrNone;
       
  1353 	TRAP(err, SetVendorInfoL(ETrue)); // set id and payload; leaves if not enough space available
       
  1354 	
       
  1355 	if (err == KErrNone && iVendorId == KBluetoothSIGVendorId)
       
  1356 		{
       
  1357 		// it's one of the v1.3 (or later!) MT commands
       
  1358 		err = ParseMetadataTransferPassthroughCommand();
       
  1359 		}
       
  1360 	else
       
  1361 		{
       
  1362 		iCommandData.Close();
       
  1363 		TRAP(err, iCommandData.CreateL(KAVCFrameMaxLength));
       
  1364 		if(err == KErrNone)
       
  1365 			{
       
  1366 			TRemConMessageType message = ERemConCommand;
       
  1367 			err = aObserver.BearerToInterface(TUid::Uid(KRemConBearerAvrcpImplementationUid),
       
  1368 											  iFrame->Data(),
       
  1369 											  iFrame->Data(),
       
  1370 											  iInterfaceUid,
       
  1371 											  iOperationId,
       
  1372 											  message,
       
  1373 											  iCommandData);
       
  1374 			}
       
  1375 		}
       
  1376 
       
  1377 	return err;
       
  1378 	}
       
  1379 	
       
  1380 /** Translates from RemCon's core interface to an AVC operation id.
       
  1381 
       
  1382 @param aRemConOp	The RemCon operation id within the core interface.
       
  1383 @param aAvrcpOp		On return the AVC passthrough operation id.
       
  1384 @return KErrNone	If the operation has been translated successfully.
       
  1385 @return KErrNotSupported	If the operation does not correspond to one
       
  1386 							provided by AVRCP.
       
  1387 */
       
  1388 TInt CControlCommand::RemConToAvrcpOperation(TUint aRemConOp, AVCPanel::TOperationId& aAvrcpOp)
       
  1389 	{
       
  1390 	LOG_STATIC_FUNC
       
  1391 	TInt err = KErrNone;
       
  1392 	switch(aRemConOp)	
       
  1393 		{
       
  1394 		case ERemConCoreApiSelect:
       
  1395 			aAvrcpOp = AVCPanel::ESelect;
       
  1396 			break;
       
  1397 		case ERemConCoreApiUp:
       
  1398 			aAvrcpOp = AVCPanel::EUp;
       
  1399 			break;
       
  1400 		case ERemConCoreApiDown:
       
  1401 			aAvrcpOp = AVCPanel::EDown;
       
  1402 			break;
       
  1403 		case ERemConCoreApiLeft:
       
  1404 			aAvrcpOp = AVCPanel::ELeft;
       
  1405 			break;
       
  1406 		case ERemConCoreApiRight:
       
  1407 			aAvrcpOp = AVCPanel::ERight;
       
  1408 			break;
       
  1409 		case ERemConCoreApiRightUp:
       
  1410 			aAvrcpOp = AVCPanel::ERightUp;
       
  1411 			break;
       
  1412 		case ERemConCoreApiRightDown:
       
  1413 			aAvrcpOp = AVCPanel::ERightDown;
       
  1414 			break;
       
  1415 		case ERemConCoreApiLeftUp:
       
  1416 			aAvrcpOp = AVCPanel::ELeftUp;
       
  1417 			break;
       
  1418 		case ERemConCoreApiLeftDown:
       
  1419 			aAvrcpOp = AVCPanel::ELeftDown;
       
  1420 			break;
       
  1421 		case ERemConCoreApiRootMenu:
       
  1422 			aAvrcpOp = AVCPanel::ERootMenu;
       
  1423 			break;
       
  1424 		case ERemConCoreApiSetupMenu:
       
  1425 			aAvrcpOp = AVCPanel::ESetupMenu;
       
  1426 			break;
       
  1427 		case ERemConCoreApiContentsMenu:
       
  1428 			aAvrcpOp = AVCPanel::EContentsMenu;
       
  1429 			break;
       
  1430 		case ERemConCoreApiFavoriteMenu:
       
  1431 			aAvrcpOp = AVCPanel::EFavoriteMenu;
       
  1432 			break;
       
  1433 		case ERemConCoreApiExit:
       
  1434 			aAvrcpOp = AVCPanel::EExit;
       
  1435 			break;
       
  1436 		case ERemConCoreApi0:
       
  1437 			aAvrcpOp = AVCPanel::E0;
       
  1438 			break;
       
  1439 		case ERemConCoreApi1:
       
  1440 			aAvrcpOp = AVCPanel::E1;
       
  1441 			break;
       
  1442 		case ERemConCoreApi2:
       
  1443 			aAvrcpOp = AVCPanel::E2;
       
  1444 			break;
       
  1445 		case ERemConCoreApi3:
       
  1446 			aAvrcpOp = AVCPanel::E3;
       
  1447 			break;
       
  1448 		case ERemConCoreApi4:
       
  1449 			aAvrcpOp = AVCPanel::E4;
       
  1450 			break;
       
  1451 		case ERemConCoreApi5:
       
  1452 			aAvrcpOp = AVCPanel::E5;
       
  1453 			break;
       
  1454 		case ERemConCoreApi6:
       
  1455 			aAvrcpOp = AVCPanel::E6;
       
  1456 			break;
       
  1457 		case ERemConCoreApi7:
       
  1458 			aAvrcpOp = AVCPanel::E7;
       
  1459 			break;
       
  1460 		case ERemConCoreApi8:
       
  1461 			aAvrcpOp = AVCPanel::E8;
       
  1462 			break;
       
  1463 		case ERemConCoreApi9:
       
  1464 			aAvrcpOp = AVCPanel::E9;
       
  1465 			break;
       
  1466 		case ERemConCoreApiDot:
       
  1467 			aAvrcpOp = AVCPanel::EDot;
       
  1468 			break;
       
  1469 		case ERemConCoreApiEnter:
       
  1470 			aAvrcpOp = AVCPanel::EEnter;
       
  1471 			break;
       
  1472 		case ERemConCoreApiClear:
       
  1473 			aAvrcpOp = AVCPanel::EClear;
       
  1474 			break;
       
  1475 		case ERemConCoreApiChannelUp:
       
  1476 			aAvrcpOp = AVCPanel::EChannelUp;
       
  1477 			break;
       
  1478 		case ERemConCoreApiChannelDown:
       
  1479 			aAvrcpOp = AVCPanel::EChannelDown;
       
  1480 			break;
       
  1481 		case ERemConCoreApiPreviousChannel:
       
  1482 			aAvrcpOp = AVCPanel::EPreviousChannel;
       
  1483 			break;
       
  1484 		case ERemConCoreApiSoundSelect:
       
  1485 			aAvrcpOp = AVCPanel::ESoundSelect;
       
  1486 			break;
       
  1487 		case ERemConCoreApiInputSelect:
       
  1488 			aAvrcpOp = AVCPanel::EInputSelect;
       
  1489 			break;
       
  1490 		case ERemConCoreApiDisplayInformation:
       
  1491 			aAvrcpOp = AVCPanel::EDisplayInformation;
       
  1492 			break;
       
  1493 		case ERemConCoreApiHelp:
       
  1494 			aAvrcpOp = AVCPanel::EHelp;
       
  1495 			break;
       
  1496 		case ERemConCoreApiPageUp:
       
  1497 			aAvrcpOp = AVCPanel::EPageUp;
       
  1498 			break;
       
  1499 		case ERemConCoreApiPageDown:
       
  1500 			aAvrcpOp = AVCPanel::EPageDown;
       
  1501 			break;
       
  1502 		case ERemConCoreApiPower:
       
  1503 			aAvrcpOp = AVCPanel::EPower;
       
  1504 			break;
       
  1505 		case ERemConCoreApiVolumeUp:
       
  1506 			aAvrcpOp = AVCPanel::EVolumeUp;
       
  1507 			break;
       
  1508 		case ERemConCoreApiVolumeDown:
       
  1509 			aAvrcpOp = AVCPanel::EVolumeDown;
       
  1510 			break;
       
  1511 		case ERemConCoreApiMute:
       
  1512 			aAvrcpOp = AVCPanel::EMute;
       
  1513 			break;
       
  1514 		case ERemConCoreApiPlay:
       
  1515 			aAvrcpOp = AVCPanel::EPlay;
       
  1516 			break;
       
  1517 		case ERemConCoreApiStop:
       
  1518 			aAvrcpOp = AVCPanel::EStop;
       
  1519 			break;
       
  1520 		case ERemConCoreApiPause:
       
  1521 			aAvrcpOp = AVCPanel::EPause;
       
  1522 			break;
       
  1523 		case ERemConCoreApiRecord:
       
  1524 			aAvrcpOp = AVCPanel::ERecord;
       
  1525 			break;
       
  1526 		case ERemConCoreApiRewind:
       
  1527 			aAvrcpOp = AVCPanel::ERewind;
       
  1528 			break;
       
  1529 		case ERemConCoreApiFastForward:
       
  1530 			aAvrcpOp = AVCPanel::EFastForward;
       
  1531 			break;
       
  1532 		case ERemConCoreApiEject:
       
  1533 			aAvrcpOp = AVCPanel::EEject;
       
  1534 			break;
       
  1535 		case ERemConCoreApiForward:
       
  1536 			aAvrcpOp = AVCPanel::EForward;
       
  1537 			break;
       
  1538 		case ERemConCoreApiBackward:
       
  1539 			aAvrcpOp = AVCPanel::EBackward;
       
  1540 			break;
       
  1541 		case ERemConCoreApiAngle:
       
  1542 			aAvrcpOp = AVCPanel::EAngle;
       
  1543 			break;
       
  1544 		case ERemConCoreApiSubpicture:
       
  1545 			aAvrcpOp = AVCPanel::ESubpicture;
       
  1546 			break;
       
  1547 		case ERemConCoreApiF1:
       
  1548 			aAvrcpOp = AVCPanel::EF1;
       
  1549 			break;
       
  1550 		case ERemConCoreApiF2:
       
  1551 			aAvrcpOp = AVCPanel::EF2;
       
  1552 			break;
       
  1553 		case ERemConCoreApiF3:
       
  1554 			aAvrcpOp = AVCPanel::EF3;
       
  1555 			break;
       
  1556 		case ERemConCoreApiF4:
       
  1557 			aAvrcpOp = AVCPanel::EF4;
       
  1558 			break;
       
  1559 		case ERemConCoreApiF5:
       
  1560 			aAvrcpOp = AVCPanel::EF5;
       
  1561 			break;
       
  1562 		default:
       
  1563 			err = KErrNotSupported;
       
  1564 		}
       
  1565 	return err;
       
  1566 	}
       
  1567 
       
  1568 TUint16 CControlCommand::Get16(const TPtrC8& aPtr)
       
  1569 	{
       
  1570 	return (aPtr[0]<<8) | aPtr[1];
       
  1571 	}
       
  1572 
       
  1573 TInt CControlCommand::DummyCallback(TAny*)
       
  1574 	{
       
  1575 	// Should never be called- should be overwritten by a non-dummy callback 
       
  1576 	// before it's ever requested let alone called.
       
  1577 	AvrcpUtils::Panic(EAvrcpDummyCallbackCalled);
       
  1578 	return KErrNone;
       
  1579 	}
       
  1580 
       
  1581 void CControlCommand::SetVendorInfoL(TBool aIsPassthrough)
       
  1582 	{
       
  1583 	if (aIsPassthrough)
       
  1584 		{
       
  1585 		if (iFrame->DataLength() < KAVCVendorUniquePassthroughHeader)
       
  1586 			{
       
  1587 			User::Leave(KErrCorrupt);
       
  1588 			}
       
  1589 		iVendorPayloadData.Set(CAVCVendorUniquePassthroughCommand::GetPayloadAndVID(*iFrame, iVendorId));
       
  1590 		}
       
  1591 	else
       
  1592 		{
       
  1593 		if (iFrame->DataLength() < KAVCVendorIdLength)
       
  1594 			{
       
  1595 			User::Leave(KErrCorrupt);
       
  1596 			}
       
  1597 		iVendorPayloadData.Set(CAVCVendorDependentCommand::GetPayloadAndVID(*iFrame, iVendorId));
       
  1598 		}
       
  1599 	}
       
  1600 
       
  1601 TBool CControlCommand::IsAvrcpPassthrough() const
       
  1602 	{
       
  1603 	TBool isAvrcpPassthrough = EFalse;
       
  1604 	
       
  1605 	if(iInterfaceUid.iUid == KRemConCoreApiUid || iInterfaceUid.iUid == KRemConGroupNavigationApiUid)
       
  1606 		{
       
  1607 		isAvrcpPassthrough = ETrue;
       
  1608 		}
       
  1609 	
       
  1610 	return isAvrcpPassthrough;
       
  1611 	}
       
  1612 
       
  1613 TBool CControlCommand::IsPassthrough() const
       
  1614 	{
       
  1615 	return ((iFrame->Opcode() == AVC::EPassThrough) && (iFrame->SubunitType() == AVC::EPanel));
       
  1616 	}
       
  1617 
       
  1618 TBool CControlCommand::PlayerSpecificNotify() const
       
  1619 	{
       
  1620 	TRegisterNotificationEvent eventId = RAvrcpIPC::GetEventIdFromIPCOperationId(iOperationId);
       
  1621 	TMetadataTransferPDU pduId = RAvrcpIPC::GetPDUIdFromIPCOperationId(iOperationId);
       
  1622 
       
  1623 	if(pduId != ERegisterNotification)
       
  1624 		{
       
  1625 		return EFalse;
       
  1626 		}
       
  1627 	
       
  1628 	if(iInterfaceUid == TUid::Uid(KRemConPlayerInformationUid))
       
  1629 		{
       
  1630 		if((eventId == ERegisterNotificationPlaybackStatusChanged) ||
       
  1631 		  (eventId == ERegisterNotificationTrackChanged) ||
       
  1632 		  (eventId == ERegisterNotificationTrackReachedEnd) ||
       
  1633 		  (eventId == ERegisterNotificationTrackReachedStart) ||
       
  1634 		  (eventId == ERegisterNotificationPlaybackPosChanged) ||
       
  1635 		  (eventId == ERegisterNotificationPlayerApplicationSettingChanged))
       
  1636 			{
       
  1637 			return ETrue;
       
  1638 			}
       
  1639 		}
       
  1640 	else if(iInterfaceUid == TUid::Uid(KRemConNowPlayingApiUid))
       
  1641 		{
       
  1642 		if (eventId == ERegisterNotificationNowPlayingContentChanged)
       
  1643 			{
       
  1644 			return ETrue;
       
  1645 			}
       
  1646 		}
       
  1647 	else 
       
  1648 		{
       
  1649 		return EFalse;
       
  1650 		}
       
  1651 	return EFalse;
       
  1652 	}
       
  1653 
       
  1654 TBool CControlCommand::NormalCommand()
       
  1655 	{
       
  1656 	TBool ret = ETrue;
       
  1657 	TRegisterNotificationEvent eventId = RAvrcpIPC::GetEventIdFromIPCOperationId(iOperationId);
       
  1658 	TMetadataTransferPDU pduId = RAvrcpIPC::GetPDUIdFromIPCOperationId(iOperationId);
       
  1659 	
       
  1660 	if((eventId == ERegisterNotificationAvailablePlayersChanged) ||
       
  1661 	    (eventId == ERegisterNotificationAddressedPlayerChanged))
       
  1662 		{
       
  1663 		ret = EFalse;
       
  1664 		}
       
  1665 	return ret;
       
  1666 	}
       
  1667 /**
       
  1668 @return Ownership of a CControlCommand representing an interim response to this command
       
  1669  */
       
  1670 CControlCommand* CControlCommand::InterimResponseL()
       
  1671 	{
       
  1672 	CAVCFrame* frame = CAVCFrame::NewL(iFrame->Data(), AVC::EResponse);
       
  1673 	CleanupStack::PushL(frame);
       
  1674 	frame->SetType(AVC::EInterim);
       
  1675 	
       
  1676 	CControlCommand* finalResponse = CControlCommand::NewL(frame, iRemConId,
       
  1677 			iTransactionLabel, iRemoteAddr, iClientId, iPlayerInfoManager);
       
  1678 	CleanupStack::Pop(frame);
       
  1679 	
       
  1680 	finalResponse->iInterfaceUid = iInterfaceUid;
       
  1681 	finalResponse->iOperationId = iOperationId;
       
  1682 	
       
  1683 	return finalResponse;
       
  1684 	}
       
  1685