bluetoothappprofiles/avrcp/remconbeareravrcp/src/bulkbearer.cpp
changeset 70 f5508c13dfe0
parent 67 16e4b9007960
child 71 083fd884d7dd
equal deleted inserted replaced
67:16e4b9007960 70:f5508c13dfe0
     1 // Copyright (c) 2008-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 
       
    24 #include <remconaddress.h>
       
    25 #include <remconbeareravrcp.h>
       
    26 #include <remcon/remconbearerbulkobserver.h>
       
    27 
       
    28 #include "avrcpbrowsingcommandhandler.h"
       
    29 #include "avrcprouter.h"
       
    30 #include "avrcputils.h"
       
    31 #include "browsecommand.h"
       
    32 #include "bulkbearer.h"
       
    33 #include "playerstatewatcher.h"
       
    34 
       
    35 #include "avrcplog.h"
       
    36 
       
    37 #ifdef _DEBUG
       
    38 PANICCATEGORY("avrcpbulk");
       
    39 #endif // _DEBUG
       
    40 
       
    41 CAvrcpBulkBearer* CAvrcpBulkBearer::NewL(RAvctp& aAvctp, CAvrcpPlayerInfoManager& aPlayerInfoManager)
       
    42 	{
       
    43 	LOG_STATIC_FUNC
       
    44 	CAvrcpBulkBearer* bulkBearer = new(ELeave) CAvrcpBulkBearer(aPlayerInfoManager, aAvctp);
       
    45 	return bulkBearer;
       
    46 	}
       
    47 
       
    48 CAvrcpBulkBearer::~CAvrcpBulkBearer()
       
    49 	{
       
    50 	LOG_FUNC
       
    51 	ASSERT_DEBUG(!iRouter); // Should already be stopped...
       
    52 	}
       
    53 
       
    54 CAvrcpBulkBearer::CAvrcpBulkBearer(CAvrcpPlayerInfoManager& aPlayerInfoManager, RAvctp& aAvctp)
       
    55 	: iPlayerInfoManager(aPlayerInfoManager)
       
    56 	, iAvctp(aAvctp)
       
    57 	, iReadyBrowseCommands(_FOFF(CAvrcpCommand, iReadyLink))
       
    58 	{
       
    59 	LOG_FUNC
       
    60 	}
       
    61 
       
    62 MIncomingCommandHandler* CAvrcpBulkBearer::IncomingHandler(const TBTDevAddr& aAddr)
       
    63 	{
       
    64 	LOG_FUNC
       
    65 	
       
    66 	MIncomingCommandHandler* handler = NULL;
       
    67 	TInt ix = iBrowseHandlers.Find(aAddr, CAvrcpBulkBearer::CompareBrowsingCommandHandlerByBDAddr);
       
    68 	if(ix >= 0)
       
    69 		{
       
    70 		handler = iBrowseHandlers[ix];
       
    71 		}
       
    72 
       
    73 	return handler;
       
    74 	}
       
    75 
       
    76 MOutgoingCommandHandler* CAvrcpBulkBearer::OutgoingHandler(const TBTDevAddr& /*aAddr*/)
       
    77 	{
       
    78 	LOG_FUNC
       
    79 	// We've received a response, but we haven't sent a command.  Naughty remote,
       
    80 	// just ignore it.
       
    81 	return NULL;
       
    82 	}
       
    83 
       
    84 void CAvrcpBulkBearer::DoConnectIndicateL(const TBTDevAddr& aBTDevice)
       
    85 	{
       
    86 	LOG_FUNC
       
    87 	ASSERT_BULK_THREAD;
       
    88 	
       
    89 	ASSERT_DEBUG(Operational());
       
    90 	
       
    91 	CRcpBrowsingCommandHandler* handler = CRcpBrowsingCommandHandler::NewL(*this, *iRouter, iPlayerInfoManager, aBTDevice);
       
    92 	CleanupStack::PushL(handler);
       
    93 	
       
    94 	iBrowseHandlers.AppendL(handler);
       
    95 	
       
    96 	CleanupStack::Pop(handler);
       
    97 	}
       
    98 	
       
    99 void CAvrcpBulkBearer::ConnectIndicate(const TBTDevAddr& aBTDevice)
       
   100 	{
       
   101 	LOG_FUNC
       
   102 	// If we failed to allocate a handler for this connection the router will
       
   103 	// not be able to find it when it checks, and will tell AVCTP that we're 
       
   104 	// not interested in this connection.
       
   105 	TRAP_IGNORE(DoConnectIndicateL(aBTDevice));
       
   106 	}
       
   107 
       
   108 void CAvrcpBulkBearer::ConnectConfirm(const TBTDevAddr& IF_FLOGGING(aBTDevice), TInt IF_FLOGGING(aError))
       
   109 	{
       
   110 	LOG_FUNC
       
   111 	LOGBTDEVADDR(aBTDevice);
       
   112 	LOG1(_L("\taError = %d"), aError);
       
   113 	
       
   114 	// Outlandish!  We did not ask for this!
       
   115 	__ASSERT_DEBUG(EFalse, AVRCP_PANIC(EAvrcpConnectConfirmOnBrowseChannel));
       
   116 	}
       
   117 
       
   118 void CAvrcpBulkBearer::DisconnectIndicate(const TBTDevAddr& aBTDevice)
       
   119 	{
       
   120 	LOG_FUNC
       
   121 	ASSERT_BULK_THREAD;
       
   122 	
       
   123 	CRcpBrowsingCommandHandler* handler = NULL;
       
   124 	TInt ix = iBrowseHandlers.Find(aBTDevice, CAvrcpBulkBearer::CompareBrowsingCommandHandlerByBDAddr);
       
   125 	if(ix >= 0)
       
   126 		{
       
   127 		handler = iBrowseHandlers[ix];
       
   128 		delete handler;
       
   129 		iBrowseHandlers.Remove(ix);
       
   130 		}
       
   131 	else
       
   132 		{
       
   133 		ASSERT_DEBUG(EFalse);
       
   134 		}
       
   135 	}
       
   136 
       
   137 void CAvrcpBulkBearer::DisconnectConfirm(const TBTDevAddr& IF_FLOGGING(aBTDevice), TInt IF_FLOGGING(aError))
       
   138 	{
       
   139 	LOG_FUNC
       
   140 	LOGBTDEVADDR(aBTDevice);
       
   141 	LOG1(_L("\taError = %d"), aError);
       
   142 	
       
   143 	// Also outlandish!  Connections on browse channel are all passive.
       
   144 	__ASSERT_DEBUG(EFalse, AVRCP_PANIC(EAvrcpDisconnectConfirmOnBrowseChannel));
       
   145 	}
       
   146 
       
   147 void CAvrcpBulkBearer::MrcciNewCommand(CAvrcpCommand& aCommand)
       
   148 	{
       
   149 	LOG_FUNC
       
   150 
       
   151 	DoNewCommand(aCommand, KNullClientId);
       
   152 	}
       
   153 
       
   154 // This overload is used when we want to address a stateless command that may
       
   155 // be interleaved with commands from other controllers.  The only command
       
   156 // this is currently used for is the internal UidCounterUpdate command.
       
   157 void CAvrcpBulkBearer::MrcciNewCommand(CAvrcpCommand& aCommand, const TRemConClientId& aClientId)
       
   158 	{
       
   159 	LOG_FUNC
       
   160 	// Verify that it's an internal command
       
   161 	__ASSERT_DEBUG(aCommand.RemoteAddress() == TBTDevAddr(0), AvrcpUtils::Panic(ESpecificAddressUsedForBrowsingCommand));
       
   162 		
       
   163 	DoNewCommand(aCommand, aClientId);
       
   164 	}
       
   165 
       
   166 void CAvrcpBulkBearer::DoNewCommand(CAvrcpCommand& aCommand, const TRemConClientId& aClientId)
       
   167 	{
       
   168 	LOG_FUNC
       
   169 
       
   170 	// Need to put the command on the queue straight
       
   171 	// away in case RemCon collects it synchronously
       
   172 	iReadyBrowseCommands.AddLast(aCommand);
       
   173 	aCommand.IncrementUsers();
       
   174 	
       
   175 	TRemConAddress remAddr;
       
   176 	AvrcpUtils::BTToRemConAddr(aCommand.RemoteAddress(), remAddr);
       
   177 	
       
   178 	TInt err = (aClientId == KNullClientId) ? iObserver->NewCommand(remAddr) : iObserver->NewCommand(remAddr, aClientId);
       
   179 		
       
   180 	if(err != KErrNone)
       
   181 		{
       
   182 		TUid interfaceUid;
       
   183 		TUint remconId, operationId;
       
   184 		RBuf8 commandData;
       
   185 		TBTDevAddr btAddr;
       
   186 		
       
   187 		// Calling GetCommandInfo transfers ownership of the command data.  
       
   188 		aCommand.GetCommandInfo(interfaceUid, remconId, operationId, commandData, btAddr);
       
   189 		MrcbbiSendReject(interfaceUid, operationId, remconId, remAddr);
       
   190 		commandData.Close();
       
   191 
       
   192 		// RemCon is not going to pick this command up
       
   193 		aCommand.iReadyLink.Deque();
       
   194 		aCommand.DecrementUsers();
       
   195 		}
       
   196 	}
       
   197 
       
   198 TUint CAvrcpBulkBearer::MrcciNewTransactionId()
       
   199 	{
       
   200 	LOG_FUNC
       
   201 	return iObserver->NewTransactionId();
       
   202 	}
       
   203 
       
   204 void CAvrcpBulkBearer::MrcciCommandExpired(TUint aTransactionId)
       
   205     {
       
   206     LOG_FUNC
       
   207     iObserver->CommandExpired(aTransactionId);
       
   208     }
       
   209 
       
   210 TInt CAvrcpBulkBearer::MrcbciSetAddressedClient(const TRemConAddress& aAddr, const TRemConClientId& aClient)
       
   211 	{
       
   212 	LOG_FUNC
       
   213 	return iObserver->SetAddressedClient(aAddr, aClient);
       
   214 	}
       
   215 
       
   216 void CAvrcpBulkBearer::MrcbciRemoveAddressing(const TRemConAddress& aAddr)
       
   217 	{
       
   218 	LOG_FUNC
       
   219 	iObserver->RemoveAddressing(aAddr);
       
   220 	}
       
   221 
       
   222 TInt CAvrcpBulkBearer::MrcbbiGetCommand(TUid& aInterfaceUid, 
       
   223 	TUint& aTransactionId, 
       
   224 	TUint& aOperationId, 
       
   225 	RBuf8& aData, 
       
   226 	TRemConAddress& aAddr)
       
   227 	{
       
   228 	LOG_FUNC
       
   229 	TInt result = KErrNotFound;
       
   230 	
       
   231 	if(!iReadyBrowseCommands.IsEmpty())
       
   232 		{
       
   233 		CAvrcpCommand* command = iReadyBrowseCommands.First();
       
   234 
       
   235 		// Calling GetCommandInfo transfers the command data to RemCon.  This means
       
   236 		// once we have called it we are committed to returning KErrNone.
       
   237 		TBTDevAddr btAddr;
       
   238 		command->GetCommandInfo(aInterfaceUid, aTransactionId, aOperationId, aData, btAddr);
       
   239 		AvrcpUtils::BTToRemConAddr(btAddr, aAddr);
       
   240 		
       
   241 		// Remove command from queue first because calling
       
   242 		// DecrementUsers() may delete command
       
   243 		command->iReadyLink.Deque();
       
   244 		command->DecrementUsers();
       
   245 		result = KErrNone;
       
   246 		}
       
   247 	else
       
   248 		{
       
   249 		__DEBUGGER();
       
   250 		}
       
   251 	
       
   252 	return result;
       
   253 	}
       
   254 
       
   255 TInt CAvrcpBulkBearer::MrcbbiSendResponse(TUid aInterfaceUid, 
       
   256 	TUint /*aOperationId*/, 
       
   257 	TUint aTransactionId, 
       
   258 	RBuf8& aData, 
       
   259 	const TRemConAddress& aAddr)
       
   260 	{
       
   261 	LOG_FUNC
       
   262 	TBTDevAddr btAddr;
       
   263 	TInt err = KErrNone;
       
   264 	
       
   265 	err = AvrcpUtils::RemConToBTAddr(aAddr, btAddr);
       
   266 	__ASSERT_DEBUG(err == KErrNone, AvrcpUtils::Panic(EInvalidBtAddrInResponse));
       
   267 	
       
   268 	if(btAddr != TBTDevAddr(0))
       
   269 		{
       
   270 		MIncomingCommandHandler* handler = IncomingHandler(btAddr);
       
   271 		__ASSERT_ALWAYS(handler, AVRCP_PANIC(EAvrcpNotConnected));
       
   272 
       
   273 		err = handler->SendRemConResponse(aInterfaceUid, aTransactionId, aData);
       
   274 		}
       
   275 	else
       
   276 		{
       
   277 		err = iInternalHandler->SendRemConResponse(aInterfaceUid, aTransactionId, aData);
       
   278 		}
       
   279 		
       
   280 	return err;
       
   281 	}
       
   282 
       
   283 void CAvrcpBulkBearer::MrcbbiSendReject(TUid aInterfaceUid, 
       
   284 	TUint /*aOperationId*/, 
       
   285 	TUint aTransactionId, 
       
   286 	const TRemConAddress& aAddr)
       
   287 	{
       
   288 	LOG_FUNC
       
   289 	
       
   290 	TBTDevAddr btAddr;
       
   291 	TInt err = AvrcpUtils::RemConToBTAddr(aAddr, btAddr);
       
   292 	__ASSERT_DEBUG(err == KErrNone, AvrcpUtils::Panic(EInvalidBtAddrInResponse));
       
   293 
       
   294 	if(btAddr != TBTDevAddr(0))
       
   295 		{
       
   296 		IncomingHandler(btAddr)->SendReject(aInterfaceUid, aTransactionId);
       
   297 		}
       
   298 	else
       
   299 		{
       
   300 		iInternalHandler->SendReject(aInterfaceUid, aTransactionId);
       
   301 		}
       
   302 	}
       
   303 
       
   304 TInt CAvrcpBulkBearer::MrcbbiStartBulk(MRemConBearerBulkObserver& aObserver)
       
   305 	{
       
   306 	LOG_FUNC
       
   307 	iObserver = &aObserver;
       
   308 	TRAPD(err, DoStartBulkL());
       
   309 	if(err != KErrNone)
       
   310 		{
       
   311 		MrcbbiStopBulk();
       
   312 		}
       
   313 	return err;
       
   314 	}
       
   315 
       
   316 void CAvrcpBulkBearer::DoStartBulkL()
       
   317 	{
       
   318 	LOG_FUNC
       
   319 	LEAVEIFERRORL(Dll::SetTls(reinterpret_cast<TAny*>(EBulkThread)));
       
   320 	iInternalHandler = iPlayerInfoManager.BulkStartedL(*this);
       
   321 	iRouter = CBulkRouter::NewL(iAvctp, *this);
       
   322 	}
       
   323 
       
   324 void CAvrcpBulkBearer::MrcbbiStopBulk()
       
   325 	{
       
   326 	LOG_FUNC
       
   327 	WEAK_ASSERT_BULK_THREAD;
       
   328 	
       
   329 	iPlayerInfoManager.BulkStopped();
       
   330 	iInternalHandler = NULL;
       
   331 	
       
   332 	delete iRouter;
       
   333 	iRouter = NULL;
       
   334 	
       
   335 	iBrowseHandlers.ResetAndDestroy();
       
   336 	
       
   337 	iObserver = NULL; // the observer is no longer valid.
       
   338 	
       
   339 	Dll::FreeTls();
       
   340 	}
       
   341 
       
   342 TBool CAvrcpBulkBearer::Operational() const
       
   343 	{
       
   344 	LOG_FUNC
       
   345 	ASSERT_DEBUG(!iRouter == !iObserver); // internal consistency check
       
   346 	return !!iRouter;
       
   347 	}
       
   348 
       
   349 void CAvrcpBulkBearer::MrcbbiBulkClientAvailable(const TRemConClientId& aId)
       
   350 	{
       
   351 	LOG_FUNC
       
   352 	iPlayerInfoManager.BulkClientAvailable(aId);
       
   353 	}
       
   354 
       
   355 void CAvrcpBulkBearer::MrcbbiBulkClientNotAvailable(const TRemConClientId& aId)
       
   356 	{
       
   357 	LOG_FUNC
       
   358 	iPlayerInfoManager.BulkClientNotAvailable(aId);
       
   359 	}
       
   360 
       
   361 
       
   362 TBool CAvrcpBulkBearer::CompareBrowsingCommandHandlerByBDAddr(const TBTDevAddr* aKey, const CRcpBrowsingCommandHandler& aHandler)
       
   363 	{
       
   364 	LOG_STATIC_FUNC
       
   365 	return aKey && aHandler.BtAddr() == *aKey;
       
   366 	}
       
   367 
       
   368 
       
   369