remotecontrol/avrcp/remconbeareravrcp/src/avrcpoutgoingcommandhandler.cpp
author hgs
Wed, 13 Oct 2010 16:20:29 +0300
changeset 51 20ac952a623c
permissions -rw-r--r--
201040_02
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51
20ac952a623c 201040_02
hgs
parents:
diff changeset
     1
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
20ac952a623c 201040_02
hgs
parents:
diff changeset
     2
// All rights reserved.
20ac952a623c 201040_02
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
20ac952a623c 201040_02
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
20ac952a623c 201040_02
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
20ac952a623c 201040_02
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
20ac952a623c 201040_02
hgs
parents:
diff changeset
     7
//
20ac952a623c 201040_02
hgs
parents:
diff changeset
     8
// Initial Contributors:
20ac952a623c 201040_02
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    10
//
20ac952a623c 201040_02
hgs
parents:
diff changeset
    11
// Contributors:
20ac952a623c 201040_02
hgs
parents:
diff changeset
    12
//
20ac952a623c 201040_02
hgs
parents:
diff changeset
    13
// Description:
20ac952a623c 201040_02
hgs
parents:
diff changeset
    14
//
20ac952a623c 201040_02
hgs
parents:
diff changeset
    15
20ac952a623c 201040_02
hgs
parents:
diff changeset
    16
20ac952a623c 201040_02
hgs
parents:
diff changeset
    17
20ac952a623c 201040_02
hgs
parents:
diff changeset
    18
/**
20ac952a623c 201040_02
hgs
parents:
diff changeset
    19
 @file
20ac952a623c 201040_02
hgs
parents:
diff changeset
    20
 @internalComponent
20ac952a623c 201040_02
hgs
parents:
diff changeset
    21
 @released
20ac952a623c 201040_02
hgs
parents:
diff changeset
    22
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
    23
20ac952a623c 201040_02
hgs
parents:
diff changeset
    24
#include <remconcoreapi.h>
20ac952a623c 201040_02
hgs
parents:
diff changeset
    25
20ac952a623c 201040_02
hgs
parents:
diff changeset
    26
#include "avcpanel.h"
20ac952a623c 201040_02
hgs
parents:
diff changeset
    27
#include "controlcommand.h"
20ac952a623c 201040_02
hgs
parents:
diff changeset
    28
#include "avrcpoutgoingcommandhandler.h"
20ac952a623c 201040_02
hgs
parents:
diff changeset
    29
#include "avrcplog.h"
20ac952a623c 201040_02
hgs
parents:
diff changeset
    30
#include "avrcprouter.h"
20ac952a623c 201040_02
hgs
parents:
diff changeset
    31
#include "avrcptimer.h"
20ac952a623c 201040_02
hgs
parents:
diff changeset
    32
#include "avrcputils.h"
20ac952a623c 201040_02
hgs
parents:
diff changeset
    33
#include "controlbearer.h"
20ac952a623c 201040_02
hgs
parents:
diff changeset
    34
20ac952a623c 201040_02
hgs
parents:
diff changeset
    35
//---------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
    36
// Construction/Destruction
20ac952a623c 201040_02
hgs
parents:
diff changeset
    37
//---------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
    38
20ac952a623c 201040_02
hgs
parents:
diff changeset
    39
/** Factory function.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    40
20ac952a623c 201040_02
hgs
parents:
diff changeset
    41
@param aBearer	The CRemConBearerAvrcp this is to handle commands for.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    42
@param aObserver The observer of the bearer. Used to aquire converters.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    43
@param aRouter	A CRcpRouter to use for communication with remote devices.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    44
@param aTimer	CDeltaTimer to use for queuing timed events.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    45
@return A fully constructed CRcpOutgoingCommandHandler.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    46
@leave System wide error codes.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    47
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
    48
CRcpOutgoingCommandHandler* CRcpOutgoingCommandHandler::NewL(MRemConControlCommandInterface& aCommandInterface, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
    49
	MRemConBearerObserver& aObserver,
20ac952a623c 201040_02
hgs
parents:
diff changeset
    50
	CRcpRouter& aRouter,
20ac952a623c 201040_02
hgs
parents:
diff changeset
    51
	CDeltaTimer& aTimer)
20ac952a623c 201040_02
hgs
parents:
diff changeset
    52
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
    53
	LOG_STATIC_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
    54
	CRcpOutgoingCommandHandler* handler = new(ELeave)CRcpOutgoingCommandHandler(aCommandInterface, aObserver, aRouter, aTimer);
20ac952a623c 201040_02
hgs
parents:
diff changeset
    55
	return handler;
20ac952a623c 201040_02
hgs
parents:
diff changeset
    56
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
    57
20ac952a623c 201040_02
hgs
parents:
diff changeset
    58
/** Constructor.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    59
20ac952a623c 201040_02
hgs
parents:
diff changeset
    60
@param aBearer	The CRemConBearerAvrcp this is to handle commands for.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    61
@param aObserver The observer of the bearer. Used to aquire converters.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    62
@param aRouter	A CRcpRouter to use for communication with remote devices.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    63
@param aTimer	CDeltaTimer to use for queuing timed events.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    64
@return A partially constructed CRcpIncomingCommandHandler.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    65
@leave System wide error codes.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    66
*/		
20ac952a623c 201040_02
hgs
parents:
diff changeset
    67
CRcpOutgoingCommandHandler::CRcpOutgoingCommandHandler(MRemConControlCommandInterface& aCommandInterface, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
    68
	MRemConBearerObserver& aObserver,
20ac952a623c 201040_02
hgs
parents:
diff changeset
    69
	CRcpRouter& aRouter,
20ac952a623c 201040_02
hgs
parents:
diff changeset
    70
	CDeltaTimer& aTimer) : iCommandQueue(_FOFF(CControlCommand, iHandlingLink)),
20ac952a623c 201040_02
hgs
parents:
diff changeset
    71
	iNotifyCommandQueue(_FOFF(CControlCommand, iHandlingLink)),
20ac952a623c 201040_02
hgs
parents:
diff changeset
    72
	iCommandInterface(aCommandInterface), iObserver(aObserver), iRouter(aRouter), iTimer(aTimer)
20ac952a623c 201040_02
hgs
parents:
diff changeset
    73
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
    74
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
    75
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
    76
20ac952a623c 201040_02
hgs
parents:
diff changeset
    77
/** Destructor.
20ac952a623c 201040_02
hgs
parents:
diff changeset
    78
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
    79
CRcpOutgoingCommandHandler::~CRcpOutgoingCommandHandler()
20ac952a623c 201040_02
hgs
parents:
diff changeset
    80
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
    81
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
    82
20ac952a623c 201040_02
hgs
parents:
diff changeset
    83
	ClearQueue(iCommandQueue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
    84
	ClearQueue(iNotifyCommandQueue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
    85
	}	
20ac952a623c 201040_02
hgs
parents:
diff changeset
    86
20ac952a623c 201040_02
hgs
parents:
diff changeset
    87
void CRcpOutgoingCommandHandler::ClearQueue(TDblQue<CControlCommand>& aQue)
20ac952a623c 201040_02
hgs
parents:
diff changeset
    88
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
    89
	while(!aQue.IsEmpty())
20ac952a623c 201040_02
hgs
parents:
diff changeset
    90
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
    91
		CControlCommand* command = aQue.First();
20ac952a623c 201040_02
hgs
parents:
diff changeset
    92
		command->CancelTimer(iTimer);
20ac952a623c 201040_02
hgs
parents:
diff changeset
    93
		command->iHandlingLink.Deque();
20ac952a623c 201040_02
hgs
parents:
diff changeset
    94
		command->DecrementUsers();
20ac952a623c 201040_02
hgs
parents:
diff changeset
    95
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
    96
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
    97
//---------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
    98
// Called from the bearer
20ac952a623c 201040_02
hgs
parents:
diff changeset
    99
//---------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
   100
20ac952a623c 201040_02
hgs
parents:
diff changeset
   101
/** Tell the handler to gracefully shutdown.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   102
20ac952a623c 201040_02
hgs
parents:
diff changeset
   103
@param aClearQueue Whether to clear the queue without handling the things 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   104
					on it.  If this is true the commands will be deleted.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   105
					If this is false then pending commands will have responses
20ac952a623c 201040_02
hgs
parents:
diff changeset
   106
					generated to RemCon.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   107
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   108
void CRcpOutgoingCommandHandler::Disconnect(TBool aClearQueue)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   109
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   110
	LOG_FUNC	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   111
	ProcessDisconnect(iCommandQueue, aClearQueue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   112
	ProcessDisconnect(iNotifyCommandQueue, aClearQueue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   113
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   114
20ac952a623c 201040_02
hgs
parents:
diff changeset
   115
void CRcpOutgoingCommandHandler::ProcessDisconnect(TDblQue<CControlCommand>& aQue, TBool aClearQueue)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   116
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   117
	while(!aQue.IsEmpty())
20ac952a623c 201040_02
hgs
parents:
diff changeset
   118
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   119
		CControlCommand* command = aQue.First();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   120
		iRouter.RemoveFromSendQueue(*command);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   121
		command->CancelTimer(iTimer);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   122
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   123
		if(aClearQueue)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   124
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   125
			GenerateFailureResult(*command, KErrDisconnected);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   126
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   127
20ac952a623c 201040_02
hgs
parents:
diff changeset
   128
		command->iHandlingLink.Deque();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   129
		command->DecrementUsers();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   130
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   131
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   132
/** Sends a new command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   133
20ac952a623c 201040_02
hgs
parents:
diff changeset
   134
@param aInterfaceUid	The RemCon client interface this command is from.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   135
@param aCommand			The operation id within aInterfaceUid.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   136
@param aId				A unique identifier provided by RemCon.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   137
@param aCommandData		Data associated with this command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   138
@param aAddr			Bluetooth address of device to send this command to.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   139
@leave KErrNoMemory or system wide error code.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   140
@leave Command parsing error.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   141
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   142
void CRcpOutgoingCommandHandler::SendCommandL(TUid aInterfaceUid, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   143
		TUint aCommand, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   144
		TUint aId,  
20ac952a623c 201040_02
hgs
parents:
diff changeset
   145
		RBuf8& aCommandData, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   146
		const TBTDevAddr& aAddr)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   147
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   148
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   149
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   150
	if(aInterfaceUid.iUid == KRemConCoreApiUid)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   151
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   152
		// Passthrough commands are stateful, so we need to examine the
20ac952a623c 201040_02
hgs
parents:
diff changeset
   153
		// history - we can't just blindly wham it on the queue.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   154
		HandleCoreApiCommandL(aCommand, aId, aCommandData, aAddr);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   155
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   156
	else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   157
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   158
		SendCommandL(aInterfaceUid, aCommand, aId, aCommandData, EFalse, aAddr, ETrue, EFalse);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   159
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   160
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   161
20ac952a623c 201040_02
hgs
parents:
diff changeset
   162
/** Sends a new notify command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   163
20ac952a623c 201040_02
hgs
parents:
diff changeset
   164
@param aInterfaceUid	The RemCon client interface this command is from.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   165
@param aCommand			The operation id within aInterfaceUid.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   166
@param aId				A unique identifier provided by RemCon, the transaction ID.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   167
@param aCommandData		Data associated with this command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   168
@param aAddr			Bluetooth address of device to send this command to.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   169
@leave KErrNoMemory or system wide error code.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   170
@leave Command parsing error.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   171
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   172
void CRcpOutgoingCommandHandler::SendNotifyCommandL(TUid aInterfaceUid, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   173
		TUint aCommand, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   174
		TUint aId,  
20ac952a623c 201040_02
hgs
parents:
diff changeset
   175
		RBuf8& aCommandData, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   176
		const TBTDevAddr& aAddr)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   177
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   178
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   179
	SendCommandL(aInterfaceUid, aCommand, aId, aCommandData, EFalse, aAddr, ETrue, ETrue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   180
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   181
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   182
//---------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
   183
// Data notifications from the router
20ac952a623c 201040_02
hgs
parents:
diff changeset
   184
//---------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
   185
20ac952a623c 201040_02
hgs
parents:
diff changeset
   186
/** Called by the router to provide a new response.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   187
20ac952a623c 201040_02
hgs
parents:
diff changeset
   188
@param aFrame The AV/C frame for this response. Ownership is taken.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   189
@param aTransLabel The AVCTP transaction id of this response. This is used
20ac952a623c 201040_02
hgs
parents:
diff changeset
   190
				to match it with its command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   191
@param aAddr The remote from which this response originated
20ac952a623c 201040_02
hgs
parents:
diff changeset
   192
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   193
void CRcpOutgoingCommandHandler::ReceiveResponse(const TDesC8& aMessageInformation, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   194
	SymbianAvctp::TTransactionLabel aTransLabel, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   195
	TBool aIpidBitSet)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   196
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   197
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   198
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   199
	CAVCFrame* frame = NULL;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   200
	TInt err = KErrNone;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   201
	if(!aIpidBitSet)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   202
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   203
		TRAP(err, frame = CAVCFrame::NewL(aMessageInformation, AVC::EResponse));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   204
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   205
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   206
	if(!err)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   207
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   208
		CControlCommand* command = NULL;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   209
		command = FindInQueue(iCommandQueue, aTransLabel);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   210
		if ( command != NULL )
20ac952a623c 201040_02
hgs
parents:
diff changeset
   211
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   212
			//Found, so it is a normal command response.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   213
			ProcessReceiveResponse(frame, aIpidBitSet, command, EFalse);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   214
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   215
		else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   216
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   217
			//Try to find in the notify command queue.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   218
			command = FindInQueue(iNotifyCommandQueue, aTransLabel);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   219
			if( command != NULL )
20ac952a623c 201040_02
hgs
parents:
diff changeset
   220
			    {
20ac952a623c 201040_02
hgs
parents:
diff changeset
   221
			    //Found, so it is a notify command response.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   222
			    ProcessReceiveResponse(frame, aIpidBitSet, command, ETrue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   223
			    }
20ac952a623c 201040_02
hgs
parents:
diff changeset
   224
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   225
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   226
		delete frame;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   227
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   228
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   229
20ac952a623c 201040_02
hgs
parents:
diff changeset
   230
CControlCommand* CRcpOutgoingCommandHandler::FindInQueue(TDblQue<CControlCommand>& aQue, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   231
		SymbianAvctp::TTransactionLabel aTransLabel)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   232
	{	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   233
	CControlCommand* command = NULL;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   234
	TDblQueIter<CControlCommand> iter(aQue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   235
	while (iter)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   236
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   237
		command = iter++;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   238
		if(command->TransactionLabel() == aTransLabel)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   239
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   240
			return command;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   241
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   242
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   243
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   244
	return NULL;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   245
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   246
20ac952a623c 201040_02
hgs
parents:
diff changeset
   247
void CRcpOutgoingCommandHandler::ProcessReceiveResponse(CAVCFrame* aFrame, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   248
		TBool aIpidBitSet,
20ac952a623c 201040_02
hgs
parents:
diff changeset
   249
		CControlCommand* aCommand, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   250
		TBool aNotify)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   251
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   252
	aCommand->CancelTimer(iTimer);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   253
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   254
	TInt err = KErrNone;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   255
	// Inform the bearer if this is something it knows about
20ac952a623c 201040_02
hgs
parents:
diff changeset
   256
	// ie not a click release
20ac952a623c 201040_02
hgs
parents:
diff changeset
   257
	if(aCommand->KnownToBearer())
20ac952a623c 201040_02
hgs
parents:
diff changeset
   258
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   259
		if(!aIpidBitSet)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   260
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   261
			if(aFrame->Data().Length() < KAVCFrameHeaderLength)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   262
				{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   263
				// Drop corrupt frames
20ac952a623c 201040_02
hgs
parents:
diff changeset
   264
				return;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   265
				}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   266
20ac952a623c 201040_02
hgs
parents:
diff changeset
   267
			err = aCommand->ParseIncomingResponse(iObserver, *aFrame);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   268
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   269
		else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   270
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   271
			// If aIpidBitSet is true that means AVRCP is not supported
20ac952a623c 201040_02
hgs
parents:
diff changeset
   272
			// by the remote end.  We handle this in the same way as not
20ac952a623c 201040_02
hgs
parents:
diff changeset
   273
			// supported commands, passing them up to RemCon as not 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   274
			// supported, so just map the ctype here, rather than setting
20ac952a623c 201040_02
hgs
parents:
diff changeset
   275
			// up another path for ipid handling, but we need pass as the
20ac952a623c 201040_02
hgs
parents:
diff changeset
   276
			// frame the original because we don't get one from AVCTP if
20ac952a623c 201040_02
hgs
parents:
diff changeset
   277
			// ipid is set.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   278
			aCommand->SetResponseType(KErrNotSupported);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   279
			err = aCommand->ParseIncomingResponse(iObserver, aCommand->Frame());
20ac952a623c 201040_02
hgs
parents:
diff changeset
   280
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   281
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   282
		if ( aNotify )
20ac952a623c 201040_02
hgs
parents:
diff changeset
   283
		    {//This is a notify command
20ac952a623c 201040_02
hgs
parents:
diff changeset
   284
		    iCommandInterface.MrccciNewNotifyResponse(*aCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   285
		    }
20ac952a623c 201040_02
hgs
parents:
diff changeset
   286
		else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   287
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   288
			iCommandInterface.MrccciNewResponse(*aCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   289
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   290
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   291
20ac952a623c 201040_02
hgs
parents:
diff changeset
   292
	TBool doDeque = ETrue;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   293
	if ( (!aIpidBitSet) && (err == KErrNone) && (aNotify) && (aFrame->Type() == AVC::EInterim))
20ac952a623c 201040_02
hgs
parents:
diff changeset
   294
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   295
		doDeque = EFalse;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   296
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   297
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   298
	// If this a passthrough press that hasn't yet been released, we need 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   299
	// to wait for a release before getting rid of this, otherwise we're done.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   300
	if(aCommand == iUnreleasedCommand)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   301
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   302
		iUnreleasedHasResponse = ETrue;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   303
		StartReleaseTimer(*iUnreleasedCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   304
		doDeque = EFalse;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   305
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   306
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   307
	if ( doDeque )
20ac952a623c 201040_02
hgs
parents:
diff changeset
   308
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   309
		aCommand->iHandlingLink.Deque();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   310
		aCommand->DecrementUsers();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   311
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   312
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   313
/** Called by the router to complete a send.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   314
20ac952a623c 201040_02
hgs
parents:
diff changeset
   315
@param aCommand The command which has been sent.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   316
@param aSendResult The result of the send. KErrNone if successful.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   317
*/	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   318
void CRcpOutgoingCommandHandler::MessageSent(CAvrcpCommand& aCommand, TInt aSendResult)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   319
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   320
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   321
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   322
	if(aSendResult == KErrNone)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   323
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   324
		// Set off response timer
20ac952a623c 201040_02
hgs
parents:
diff changeset
   325
		StartResponseTimer(static_cast<CControlCommand&>(aCommand));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   326
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   327
	else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   328
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   329
		CControlCommand* command = FindInQueue(iNotifyCommandQueue, aCommand.TransactionLabel());
20ac952a623c 201040_02
hgs
parents:
diff changeset
   330
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   331
		if(command)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   332
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   333
			command->SetNotifyVolumeChangeResult(command->Frame());
20ac952a623c 201040_02
hgs
parents:
diff changeset
   334
			iCommandInterface.MrccciNewNotifyResponse(*command);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   335
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   336
		else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   337
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   338
			command = FindInQueue(iCommandQueue, aCommand.TransactionLabel());
20ac952a623c 201040_02
hgs
parents:
diff changeset
   339
			
20ac952a623c 201040_02
hgs
parents:
diff changeset
   340
			// Generate error response up to RemCon
20ac952a623c 201040_02
hgs
parents:
diff changeset
   341
			// if this is a core command we can set the result, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   342
			// otherwise we just return it as we got it.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   343
			if(command->Frame().Opcode() == AVC::EPassThrough)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   344
				{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   345
				// Need to insert before setting the button action so we have
20ac952a623c 201040_02
hgs
parents:
diff changeset
   346
				// long enough data
20ac952a623c 201040_02
hgs
parents:
diff changeset
   347
				if (!command->InsertCoreResult(aSendResult))
20ac952a623c 201040_02
hgs
parents:
diff changeset
   348
					{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   349
					if(command->Click())
20ac952a623c 201040_02
hgs
parents:
diff changeset
   350
						{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   351
						command->SetCoreButtonAction(ERemConCoreApiButtonClick, ETrue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   352
						}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   353
					}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   354
				}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   355
			
20ac952a623c 201040_02
hgs
parents:
diff changeset
   356
			iCommandInterface.MrccciNewResponse(*command);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   357
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   358
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   359
		command->iHandlingLink.Deque();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   360
		command->DecrementUsers();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   361
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   362
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   363
20ac952a623c 201040_02
hgs
parents:
diff changeset
   364
//---------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
   365
// Internal Utility functions
20ac952a623c 201040_02
hgs
parents:
diff changeset
   366
//---------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
   367
20ac952a623c 201040_02
hgs
parents:
diff changeset
   368
void CRcpOutgoingCommandHandler::CleanupUnreleased()
20ac952a623c 201040_02
hgs
parents:
diff changeset
   369
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   370
	iUnreleasedCommand->CancelTimer(iTimer);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   371
	iUnreleasedCommand->iHandlingLink.Deque();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   372
	iUnreleasedCommand->DecrementUsers();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   373
	iUnreleasedHasResponse = EFalse;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   374
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   375
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   376
/** Handle a command that is part of the Core API.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   377
20ac952a623c 201040_02
hgs
parents:
diff changeset
   378
@param aCommand			The operation id within aInterfaceUid.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   379
@param aId				A unique identifier provided by RemCon.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   380
@param aCommandData		Data associated with this command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   381
@param aAddr			Bluetooth address of device to send this command to.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   382
@leave KErrNoMemory or system wide error code.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   383
@leave Command parsing error.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   384
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   385
void CRcpOutgoingCommandHandler::HandleCoreApiCommandL(TUint aCommand, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   386
		TUint aId,  
20ac952a623c 201040_02
hgs
parents:
diff changeset
   387
		RBuf8& aCommandData, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   388
		const TBTDevAddr& aAddr)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   389
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   390
	if(aCommandData.Length() < KRemConCoreApiButtonDataLength)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   391
   		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   392
   		User::Leave(KErrCorrupt);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   393
   		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   394
20ac952a623c 201040_02
hgs
parents:
diff changeset
   395
	TInt buttonData;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   396
	AvrcpUtils::ReadCommandDataToInt(aCommandData, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   397
   		KRemConCoreApiButtonDataOffset, KRemConCoreApiButtonDataLength, buttonData);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   398
 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   399
 	// First check if there's anything we need to do before sending this command,
20ac952a623c 201040_02
hgs
parents:
diff changeset
   400
 	// mainly releasing a previous press.  	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   401
	if(iUnreleasedCommand)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   402
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   403
		TUint prevOpId = iUnreleasedCommand->RemConOperationId();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   404
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   405
		if(aCommand == prevOpId)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   406
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   407
			// Either we've received a release, or we've refreshed the press.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   408
			// If the unreleased press has already been responded too we can
20ac952a623c 201040_02
hgs
parents:
diff changeset
   409
			// dispose of it now.  
20ac952a623c 201040_02
hgs
parents:
diff changeset
   410
			// If the unreleased press has not been responded too we can 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   411
			// treat it like a normal command on reception of response, so just
20ac952a623c 201040_02
hgs
parents:
diff changeset
   412
			// set iUnreleased to NULL.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   413
			if(iUnreleasedHasResponse)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   414
				{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   415
				CleanupUnreleased();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   416
				}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   417
20ac952a623c 201040_02
hgs
parents:
diff changeset
   418
			iUnreleasedCommand = NULL;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   419
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   420
		else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   421
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   422
			// A new operation!
20ac952a623c 201040_02
hgs
parents:
diff changeset
   423
			if(buttonData != ERemConCoreApiButtonRelease)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   424
				{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   425
				// Try and generate the release for the previous command, if
20ac952a623c 201040_02
hgs
parents:
diff changeset
   426
				// if fails then the remote will just have to assume it.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   427
				// There's no point leaving this to the release timer, because
20ac952a623c 201040_02
hgs
parents:
diff changeset
   428
				// we want to send another command now, so even if we send the
20ac952a623c 201040_02
hgs
parents:
diff changeset
   429
				// release later the remote should ignore it.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   430
				TRAP_IGNORE(GenerateCommandL(*iUnreleasedCommand, ERemConCoreApiButtonRelease));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   431
				
20ac952a623c 201040_02
hgs
parents:
diff changeset
   432
				if(iUnreleasedHasResponse)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   433
					{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   434
					CleanupUnreleased();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   435
					}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   436
20ac952a623c 201040_02
hgs
parents:
diff changeset
   437
				iUnreleasedCommand = NULL;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   438
				}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   439
			else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   440
				{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   441
				// A release for a command other than iUnreleased.  We can't 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   442
				// send this now.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   443
				User::Leave(KErrNotReady);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   444
				}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   445
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   446
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   447
	else if(buttonData == ERemConCoreApiButtonRelease)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   448
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   449
		// We don't have an unreleased command.  We must have already 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   450
		// released this, either via the timer, or because we've sent
20ac952a623c 201040_02
hgs
parents:
diff changeset
   451
		// another command in the meantime.  We can't send this now.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   452
		// Leaving synchronously means we don't need to worry about generating
20ac952a623c 201040_02
hgs
parents:
diff changeset
   453
		// a fake response, which may mislead the application.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   454
		User::Leave(KErrNotReady);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   455
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   456
   	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   457
   	if(buttonData == ERemConCoreApiButtonClick)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   458
   		{	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   459
		// aCommandData is still owned by RemCon until we return successfully.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   460
		// If we try the operations with the new data first we won't end up 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   461
		// in a situation where the new CControlCommand thinks that it owns 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   462
		// aCommandData, then the release operation leaves, so RemCon also
20ac952a623c 201040_02
hgs
parents:
diff changeset
   463
		// thinks it owns aCommandData.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   464
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   465
		RBuf8 pressBuf;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   466
		pressBuf.CreateL(aCommandData);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   467
		CleanupClosePushL(pressBuf);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   468
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   469
		AvrcpUtils::SetCommandDataFromInt(pressBuf, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   470
			KRemConCoreApiButtonDataOffset, KRemConCoreApiButtonDataLength, ERemConCoreApiButtonPress);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   471
		SendCommandL(TUid::Uid(KRemConCoreApiUid), aCommand, aId, pressBuf, ETrue, aAddr, ETrue, EFalse);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   472
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   473
		// Data has been taken ownership of by SendCommandL, so can just let 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   474
		// pressbuf go out of scope.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   475
		CleanupStack::Pop(&pressBuf);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   476
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   477
		AvrcpUtils::SetCommandDataFromInt(aCommandData, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   478
			KRemConCoreApiButtonDataOffset, KRemConCoreApiButtonDataLength, ERemConCoreApiButtonRelease);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   479
		SendCommandL(TUid::Uid(KRemConCoreApiUid), aCommand, aId, aCommandData, ETrue, aAddr, EFalse, EFalse);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   480
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   481
	else if(buttonData == ERemConCoreApiButtonPress)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   482
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   483
		iUnreleasedCommand = &SendCommandL(TUid::Uid(KRemConCoreApiUid), aCommand, aId, aCommandData, EFalse, aAddr, ETrue, EFalse);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   484
		iReleaseTimerExpiryCount = 0;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   485
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   486
	else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   487
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   488
		// Must be release
20ac952a623c 201040_02
hgs
parents:
diff changeset
   489
		__ASSERT_DEBUG(buttonData == ERemConCoreApiButtonRelease, AvrcpUtils::Panic(EAvrcpUnknownButtonAction));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   490
		SendCommandL(TUid::Uid(KRemConCoreApiUid), aCommand, aId, aCommandData, EFalse, aAddr, ETrue, EFalse);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   491
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   492
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   493
20ac952a623c 201040_02
hgs
parents:
diff changeset
   494
/** Creates a command from the RemCon data.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   495
20ac952a623c 201040_02
hgs
parents:
diff changeset
   496
This is an internal utility function.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   497
20ac952a623c 201040_02
hgs
parents:
diff changeset
   498
A CControlCommand will be created.  Calling ProcessOutgoingCommandL on
20ac952a623c 201040_02
hgs
parents:
diff changeset
   499
this creates a CAVCFrame from the provided data.  If an AV/C frame
20ac952a623c 201040_02
hgs
parents:
diff changeset
   500
can be created the command will be added to the outgoing queue to
20ac952a623c 201040_02
hgs
parents:
diff changeset
   501
wait a response from the remote.  Otherwise this function will
20ac952a623c 201040_02
hgs
parents:
diff changeset
   502
leave.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   503
20ac952a623c 201040_02
hgs
parents:
diff changeset
   504
@param aInterfaceUid	The RemCon client interface this command is from.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   505
@param aCommand			The operation id within aInterfaceUid.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   506
@param aId				A unique identifier provided by RemCon.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   507
@param aCommandData		Data associated with this command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   508
@param aIsClick			Whether this is a button click.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   509
@param aAddr			Bluetooth address of device to send this command to.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   510
@return The generated command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   511
@leave KErrNoMemory or system wide error code.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   512
@leave Command parsing error.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   513
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   514
CControlCommand& CRcpOutgoingCommandHandler::SendCommandL(TUid aInterfaceUid,
20ac952a623c 201040_02
hgs
parents:
diff changeset
   515
	TUint aCommand, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   516
	TUint aId, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   517
	RBuf8& aCommandData, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   518
	TBool aIsClick, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   519
	const TBTDevAddr& aAddr,
20ac952a623c 201040_02
hgs
parents:
diff changeset
   520
	TBool aKnownToBearer,
20ac952a623c 201040_02
hgs
parents:
diff changeset
   521
	TBool aNotify)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   522
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   523
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   524
	// Create a command and wham it on our queue, so we can match it up with its response
20ac952a623c 201040_02
hgs
parents:
diff changeset
   525
	// CControlCommand::NewL takes ownership of the data in aCommandData then NULLs aCommandData
20ac952a623c 201040_02
hgs
parents:
diff changeset
   526
	// so a leave later in the function won't cause double deletion.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   527
	CControlCommand* command = CControlCommand::NewL(aInterfaceUid, aCommand, aId, iCurrentTrans, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   528
			aCommandData, aIsClick, aAddr, aKnownToBearer);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   529
	CleanupStack::PushL(command);	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   530
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   531
	command->ProcessOutgoingCommandL(iObserver);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   532
	CleanupStack::Pop(command);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   533
	command->IncrementUsers();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   534
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   535
	if ( aNotify )
20ac952a623c 201040_02
hgs
parents:
diff changeset
   536
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   537
		iNotifyCommandQueue.AddLast(*command);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   538
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   539
	else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   540
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   541
		iCommandQueue.AddLast(*command);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   542
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   543
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   544
	// Increment our transaction id
20ac952a623c 201040_02
hgs
parents:
diff changeset
   545
	iCurrentTrans = (iCurrentTrans + 1) % SymbianAvctp::KMaxTransactionLabel;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   546
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   547
	// Command stays on the queue till we've got the response
20ac952a623c 201040_02
hgs
parents:
diff changeset
   548
	iRouter.AddToSendQueue(*command);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   549
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   550
	return *command;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   551
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   552
20ac952a623c 201040_02
hgs
parents:
diff changeset
   553
/** Generate a failure response to RemCon.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   554
20ac952a623c 201040_02
hgs
parents:
diff changeset
   555
This sets the result for a passthrough command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   556
It informs the bearer of the new response.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   557
20ac952a623c 201040_02
hgs
parents:
diff changeset
   558
@param aCommand The command to finish off.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   559
@param aResult The result (only valid for passthrough)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   560
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   561
void CRcpOutgoingCommandHandler::GenerateFailureResult(CControlCommand& aCommand, TInt aResult)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   562
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   563
	// Response is only necessary if the bearer knows about this command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   564
	if(aCommand.KnownToBearer() && (aCommand.Frame().Opcode() == AVC::EPassThrough))
20ac952a623c 201040_02
hgs
parents:
diff changeset
   565
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   566
		if (aCommand.InsertCoreResult(aResult) == KErrNone)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   567
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   568
			if(aCommand.Click())
20ac952a623c 201040_02
hgs
parents:
diff changeset
   569
				{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   570
				aCommand.SetCoreButtonAction(ERemConCoreApiButtonClick, ETrue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   571
				}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   572
			else if(aCommand.ButtonAct() == AVCPanel::EButtonPress)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   573
				{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   574
				aCommand.SetCoreButtonAction(ERemConCoreApiButtonPress, ETrue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   575
				}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   576
			else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   577
				{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   578
				aCommand.SetCoreButtonAction(ERemConCoreApiButtonRelease, ETrue);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   579
				}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   580
20ac952a623c 201040_02
hgs
parents:
diff changeset
   581
			iCommandInterface.MrccciNewResponse(aCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   582
           }
20ac952a623c 201040_02
hgs
parents:
diff changeset
   583
		}	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   584
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   585
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   586
/** Generate a command to the remote.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   587
20ac952a623c 201040_02
hgs
parents:
diff changeset
   588
This is needed in situations where the application has not met the avrcp
20ac952a623c 201040_02
hgs
parents:
diff changeset
   589
button refresh requirements so we need to internally generate something
20ac952a623c 201040_02
hgs
parents:
diff changeset
   590
to stop the remote getting a bad impression of us.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   591
20ac952a623c 201040_02
hgs
parents:
diff changeset
   592
@param aCommand The command to be issue again.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   593
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   594
void CRcpOutgoingCommandHandler::GenerateCommandL(CControlCommand& aCommand, TRemConCoreApiButtonAction aButtonAct)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   595
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   596
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   597
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   598
	RBuf8 commandData;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   599
	commandData.CreateMaxL(KRemConCoreApiButtonDataLength);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   600
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   601
	AvrcpUtils::SetCommandDataFromInt(commandData, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   602
		KRemConCoreApiButtonDataOffset, KRemConCoreApiButtonDataLength, aButtonAct);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   603
20ac952a623c 201040_02
hgs
parents:
diff changeset
   604
	// This will not leave before taking ownership of commandData.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   605
	SendCommandL(aCommand.RemConInterfaceUid(), aCommand.RemConOperationId(), aCommand.RemConCommandId(), commandData, EFalse, 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   606
		aCommand.RemoteAddress(), EFalse, EFalse);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   607
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   608
20ac952a623c 201040_02
hgs
parents:
diff changeset
   609
//------------------------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
   610
// Timer functions
20ac952a623c 201040_02
hgs
parents:
diff changeset
   611
//------------------------------------------------------------------------------------
20ac952a623c 201040_02
hgs
parents:
diff changeset
   612
20ac952a623c 201040_02
hgs
parents:
diff changeset
   613
/** Starts the response timer.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   614
20ac952a623c 201040_02
hgs
parents:
diff changeset
   615
AVRCP mandates a remote respond within 100ms of receiving a command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   616
This is the timer for that, and is started when a command has 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   617
successfully been sent.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   618
20ac952a623c 201040_02
hgs
parents:
diff changeset
   619
@param aCommand The command to start the timer for.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   620
*/		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   621
void CRcpOutgoingCommandHandler::StartResponseTimer(CControlCommand& aCommand)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   622
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   623
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   624
	// These use placement new, so cannot fail
20ac952a623c 201040_02
hgs
parents:
diff changeset
   625
	TAvrcpTimerExpiryInfo* timerInfo = new(aCommand.TimerExpiryInfo())TAvrcpTimerExpiryInfo(this, aCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   626
20ac952a623c 201040_02
hgs
parents:
diff changeset
   627
	TCallBack callback(ResponseExpiry, timerInfo);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   628
	TDeltaTimerEntry* timerEntry = new(aCommand.TimerEntry())TDeltaTimerEntry(callback);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   629
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   630
	iTimer.Queue(KRcpResponseTimeOut, *timerEntry);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   631
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   632
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   633
/** Callback when response timer expires.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   634
20ac952a623c 201040_02
hgs
parents:
diff changeset
   635
This is a static forwarding function.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   636
20ac952a623c 201040_02
hgs
parents:
diff changeset
   637
@param aExpiryInfo The information used by the real ResponseExpiry to
20ac952a623c 201040_02
hgs
parents:
diff changeset
   638
					deal with the timer expiry.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   639
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   640
TInt CRcpOutgoingCommandHandler::ResponseExpiry(TAny* aExpiryInfo)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   641
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   642
	LOG_STATIC_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   643
	TAvrcpTimerExpiryInfo *timerInfo = reinterpret_cast<TAvrcpTimerExpiryInfo*>(aExpiryInfo);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   644
	(reinterpret_cast<CRcpOutgoingCommandHandler*>(timerInfo->iHandler))->ResponseExpiry(timerInfo->iCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   645
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   646
	return KErrNone;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   647
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   648
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   649
/** Deals with response timeout.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   650
20ac952a623c 201040_02
hgs
parents:
diff changeset
   651
This sends a timeout response to RemCon.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   652
20ac952a623c 201040_02
hgs
parents:
diff changeset
   653
@param aCommand	The CControlCommand that has expired.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   654
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   655
void CRcpOutgoingCommandHandler::ResponseExpiry(CControlCommand& aCommand)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   656
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   657
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   658
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   659
	GenerateFailureResult(aCommand, KErrTimedOut);	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   660
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   661
	// Failed to get a response to this, don't bother about trying
20ac952a623c 201040_02
hgs
parents:
diff changeset
   662
	// to release it.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   663
	if(iUnreleasedCommand == &aCommand)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   664
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   665
		iUnreleasedCommand = NULL;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   666
		__ASSERT_DEBUG(!iUnreleasedHasResponse, AvrcpUtils::Panic(EAvrcpPressHasPhantomResponse));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   667
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   668
20ac952a623c 201040_02
hgs
parents:
diff changeset
   669
	aCommand.iHandlingLink.Deque();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   670
	aCommand.DecrementUsers();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   671
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   672
20ac952a623c 201040_02
hgs
parents:
diff changeset
   673
/** Starts the release timer.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   674
20ac952a623c 201040_02
hgs
parents:
diff changeset
   675
AVRCP requires a press to be refreshed less than 2s after the first
20ac952a623c 201040_02
hgs
parents:
diff changeset
   676
press, if it is not to be assumed to have been released.  We pass 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   677
this requirement on to RemCon clients as we don't know when they might
20ac952a623c 201040_02
hgs
parents:
diff changeset
   678
go away and we don't want to keep buttons pressed forever.  If the 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   679
release timer expires we will assume a release, and generate it to
20ac952a623c 201040_02
hgs
parents:
diff changeset
   680
the remote.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   681
20ac952a623c 201040_02
hgs
parents:
diff changeset
   682
@param aCommand The command to start the timer for.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   683
*/	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   684
void CRcpOutgoingCommandHandler::StartReleaseTimer(CControlCommand& aCommand)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   685
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   686
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   687
20ac952a623c 201040_02
hgs
parents:
diff changeset
   688
	// These cannot fail as we use placement new
20ac952a623c 201040_02
hgs
parents:
diff changeset
   689
	TAvrcpTimerExpiryInfo* timerInfo = new(aCommand.TimerExpiryInfo())TAvrcpTimerExpiryInfo(this, aCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   690
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   691
	TCallBack callback(ReleaseExpiry, timerInfo);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   692
	TDeltaTimerEntry* timerEntry = new(aCommand.TimerEntry())TDeltaTimerEntry(callback);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   693
20ac952a623c 201040_02
hgs
parents:
diff changeset
   694
	iTimer.Queue(KRcpOutgoingButtonReleaseTimeout, *timerEntry);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   695
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   696
20ac952a623c 201040_02
hgs
parents:
diff changeset
   697
/** Callback when release timer expires.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   698
20ac952a623c 201040_02
hgs
parents:
diff changeset
   699
This is a static forwarding function.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   700
20ac952a623c 201040_02
hgs
parents:
diff changeset
   701
@param aExpiryInfo The information used by the real ReleaseExpiry to
20ac952a623c 201040_02
hgs
parents:
diff changeset
   702
					deal with the timer expiry.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   703
*/	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   704
TInt CRcpOutgoingCommandHandler::ReleaseExpiry(TAny* aExpiryInfo)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   705
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   706
	LOG_STATIC_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   707
	TAvrcpTimerExpiryInfo *timerInfo = reinterpret_cast<TAvrcpTimerExpiryInfo*>(aExpiryInfo);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   708
	(reinterpret_cast<CRcpOutgoingCommandHandler*>(timerInfo->iHandler))->ReleaseExpiry(timerInfo->iCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   709
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   710
	return KErrNone;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   711
	}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   712
20ac952a623c 201040_02
hgs
parents:
diff changeset
   713
/** Deals with expiry of release timer.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   714
20ac952a623c 201040_02
hgs
parents:
diff changeset
   715
1) Generate release for this command.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   716
2) Send release to remote.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   717
20ac952a623c 201040_02
hgs
parents:
diff changeset
   718
@param aCommand	The CControlCommand that has expired.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   719
*/
20ac952a623c 201040_02
hgs
parents:
diff changeset
   720
void CRcpOutgoingCommandHandler::ReleaseExpiry(CControlCommand& aCommand)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   721
	{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   722
	LOG_FUNC
20ac952a623c 201040_02
hgs
parents:
diff changeset
   723
	__ASSERT_DEBUG((aCommand.ButtonAct() == AVCPanel::EButtonPress), AvrcpUtils::Panic(EAvrcpReleaseExpiryForRelease));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   724
	__ASSERT_DEBUG(&aCommand == iUnreleasedCommand, AvrcpUtils::Panic(EAvrcpReleaseExpiryForOldCommand));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   725
	__ASSERT_DEBUG(iUnreleasedHasResponse, AvrcpUtils::Panic(EAvrcpReleaseTimerStartedWithoutResponse));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   726
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   727
	iReleaseTimerExpiryCount++;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   728
	
20ac952a623c 201040_02
hgs
parents:
diff changeset
   729
	TBool commandCompleted = ETrue;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   730
	// If the client is not yet obliged to refresh this, then send another press.  Otherwise generate
20ac952a623c 201040_02
hgs
parents:
diff changeset
   731
	// the release for them.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   732
	if((iReleaseTimerExpiryCount * KRcpOutgoingButtonReleaseTimeout) < KRemConCoreApiPressRefreshInterval)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   733
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   734
		// This will try and generate a press that is identical to the original
20ac952a623c 201040_02
hgs
parents:
diff changeset
   735
		// aCommand, but with a new AVCTP transaction id.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   736
		TRAPD(err, GenerateCommandL(aCommand, ERemConCoreApiButtonPress));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   737
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   738
		if(!err)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   739
			{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   740
			// Start the timer again on the original command
20ac952a623c 201040_02
hgs
parents:
diff changeset
   741
			StartReleaseTimer(aCommand);
20ac952a623c 201040_02
hgs
parents:
diff changeset
   742
			commandCompleted = EFalse;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   743
			}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   744
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   745
	else
20ac952a623c 201040_02
hgs
parents:
diff changeset
   746
		{
20ac952a623c 201040_02
hgs
parents:
diff changeset
   747
		// Try an generate a release, but if it fails we just have to let the 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   748
		// remote assume it.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   749
		TRAP_IGNORE(GenerateCommandL(aCommand, ERemConCoreApiButtonRelease));
20ac952a623c 201040_02
hgs
parents:
diff changeset
   750
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   751
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   752
	// This condition may be true because
20ac952a623c 201040_02
hgs
parents:
diff changeset
   753
	// -  we have failed to generate a press, in which case the remote is entitled 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   754
	//    to assume this is released, so we just give up on it.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   755
	// or
20ac952a623c 201040_02
hgs
parents:
diff changeset
   756
	// -  the client has not met its press refresh obligation (whether we've 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   757
	//    successfully generated a release or not.
20ac952a623c 201040_02
hgs
parents:
diff changeset
   758
	// In either case we won't do anything more with this command. 
20ac952a623c 201040_02
hgs
parents:
diff changeset
   759
	if(commandCompleted)
20ac952a623c 201040_02
hgs
parents:
diff changeset
   760
		{				
20ac952a623c 201040_02
hgs
parents:
diff changeset
   761
		aCommand.iHandlingLink.Deque();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   762
		aCommand.DecrementUsers();
20ac952a623c 201040_02
hgs
parents:
diff changeset
   763
		
20ac952a623c 201040_02
hgs
parents:
diff changeset
   764
		iUnreleasedCommand = NULL;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   765
		iUnreleasedHasResponse = EFalse;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   766
		iReleaseTimerExpiryCount = 0;
20ac952a623c 201040_02
hgs
parents:
diff changeset
   767
		}
20ac952a623c 201040_02
hgs
parents:
diff changeset
   768
	}