bluetooth/btstack/avdtp/avdtpSignallingChannel.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2003-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 // Implements the avdtp signalling channel
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include <bluetooth/logger.h>
       
    24 #include "avdtpSignallingChannel.h"
       
    25 #include "avdtp.h"
       
    26 #include "avdtputil.h"
       
    27 #include "avdtpSignallingTransaction.h"
       
    28 
       
    29 #ifdef __FLOG_ACTIVE
       
    30 _LIT8(KLogComponent, LOG_COMPONENT_AVDTP);
       
    31 #endif
       
    32 
       
    33 //Macro to just return (and enter debugger in debug builds) if we get an unsolicited response packet
       
    34 #define RETURN_IF_NO_TRANSACTION(transaction) 	if (!transaction) {	LOG(_L("No transaction found"));return;}
       
    35 #define RETURN_IF_SIGNAL_BAD(transaction, signal) if (!CheckSignal(*transaction, signal)) {LOG1(_L("Transaction has different signal (%d)"), signal); return;}
       
    36 
       
    37 // check that sessions have replied with an AVDTP error in error cases
       
    38 #define	CHECK_ERROR(result) if (!(result<=KErrAvdtpSignallingErrorBase || result==KErrNone || result==KErrNotFound)) __DEBUGGER();
       
    39 
       
    40 CSignallingChannel* CSignallingChannel::NewL(CAvdtpProtocol& aProtocol,
       
    41 											 CLogicalChannelFactory& aChannelFactory,
       
    42 											 const TBTDevAddr& aRemoteAddress)
       
    43 	{
       
    44 	LOG_STATIC_FUNC
       
    45 	CSignallingChannel* s = CSignallingChannel::NewLC(aProtocol, aChannelFactory, aRemoteAddress);
       
    46 	CleanupStack::Pop();
       
    47 	return s;
       
    48 	}
       
    49 
       
    50 CSignallingChannel* CSignallingChannel::NewLC(CAvdtpProtocol& aProtocol,
       
    51 											  CLogicalChannelFactory& aChannelFactory,
       
    52 											  const TBTDevAddr& aRemoteAddress)
       
    53 	{
       
    54 	LOG_STATIC_FUNC
       
    55 	CSignallingChannel* s = new(ELeave)	CSignallingChannel(aProtocol, aChannelFactory, aRemoteAddress);
       
    56 	CleanupStack::PushL(s);
       
    57 	s->ConstructL();
       
    58 	return s;
       
    59 	}
       
    60 	
       
    61 CSignallingChannel::CSignallingChannel(CAvdtpProtocol& aProtocol,
       
    62 									   CLogicalChannelFactory& aChannelFactory,
       
    63 									   const TBTDevAddr& aRemoteAddress)
       
    64 : iProtocol(aProtocol),
       
    65   iLogicalChannelFactory(aChannelFactory),
       
    66   iPermanentUsers(_FOFF(XAvdtpSignalReceiver,iSignalReceiverEmbeddedLink)),
       
    67   iTransactions(_FOFF(CSignallingTransaction,iLink)),
       
    68   iRemoteAddress(aRemoteAddress),
       
    69   iInboundMessage(*this),
       
    70   iDraftMessages(_FOFF(CAvdtpOutboundSignallingMessage,iLink)),
       
    71   iQueuedMessages(_FOFF(CAvdtpOutboundSignallingMessage,iLink))
       
    72 	{
       
    73 	LOG_FUNC
       
    74 	SetBlocked(EFalse);
       
    75 	
       
    76 	TCallBack cb(TryToClose, this);
       
    77 	iIdleTimerEntry.Set(cb);
       
    78 	}
       
    79 	
       
    80 void CSignallingChannel::ConstructL()
       
    81 	{
       
    82 	LOG_FUNC
       
    83 	TCallBack cb(CSignallingChannel::TryToSendCallback, this);
       
    84 	iTryToSendCallback = new (ELeave)CAsyncCallBack(cb, CActive::EPriorityStandard);
       
    85 	}
       
    86 
       
    87 CSignallingChannel::~CSignallingChannel()
       
    88 	{
       
    89 	LOG_FUNC
       
    90 	CancelIdleTimer();
       
    91 
       
    92 	// cancel possible outstanding factory request
       
    93 	iLogicalChannelFactory.Cancel(iLogicalChannelRequest);
       
    94 	
       
    95 	// remove from protocol's knowledge
       
    96 	iProtocol.SignallingChannelDown(*this);
       
    97 	
       
    98 	// any preauthorisation for device this represents is now void
       
    99 	if (!IsListening())
       
   100 		{
       
   101 		iProtocol.RemoteSEPCache().InvalidateSEPs(iRemoteAddress);
       
   102 		(void)iProtocol.SetPreauthorisation(iRemoteAddress, EFalse);
       
   103 		}
       
   104 		
       
   105 	if (iBearer)
       
   106 		{
       
   107 		// tell l2cap
       
   108 		iBearer->Shutdown(CServProviderBase::EImmediate);
       
   109 		}
       
   110 		
       
   111 	delete iBearer;
       
   112 	delete iTryToSendCallback;
       
   113 	}
       
   114 
       
   115 void CSignallingChannel::StartTryToSendCallback()
       
   116 	{
       
   117 	LOG_FUNC
       
   118 	if (!iTryToSendCallback->IsActive())
       
   119 		{
       
   120 		iTryToSendCallback->CallBack();
       
   121 		}
       
   122 	// else already running and will callback anyway
       
   123 	}
       
   124 
       
   125 void CSignallingChannel::CancelTryToSendCallback()
       
   126 	{
       
   127 	LOG_FUNC
       
   128 	iTryToSendCallback->Cancel();
       
   129 	}
       
   130 
       
   131 /*static*/ TInt CSignallingChannel::TryToSendCallback(TAny *aSigCh)
       
   132 	{
       
   133 	LOG_STATIC_FUNC
       
   134 	return (reinterpret_cast<CSignallingChannel*>(aSigCh))->TryToSendCallback();
       
   135 	}
       
   136 
       
   137 void CSignallingChannel::ObtainMTU()
       
   138 	{
       
   139 	LOG_FUNC
       
   140 	TPckg<TInt> mtubuf(iBearerMTU);
       
   141 	TInt err=iBearer->GetOption(KSolBtL2CAP,KL2CAPOutboundMTUForBestPerformance,mtubuf);
       
   142 	if (err!=KErrNone)
       
   143 		{
       
   144 		Error(err);
       
   145 		}
       
   146 	}
       
   147 
       
   148 /*
       
   149 Does post-packet-send processing
       
   150 */
       
   151 void CSignallingChannel::PacketSent(CSignallingTransaction& aTransaction)
       
   152 	{
       
   153 	LOG_FUNC
       
   154 	// We can't delete the transaction yet, because it looks after timer.
       
   155 		
       
   156 	switch (aTransaction.SentAction())
       
   157 		{
       
   158 		case EKeepSetRTX:
       
   159 			{
       
   160 			aTransaction.StartTimer();
       
   161 			break;
       
   162 			}
       
   163 		case EDiscard:
       
   164 			{
       
   165 			// these transactions can be cleared up now
       
   166 			// we don't support caching of responses if they get lost - they'll be regenerated if needed
       
   167 			aTransaction.iLink.Deque();
       
   168 			delete &aTransaction;
       
   169 			break;
       
   170 			}
       
   171 		case EKeepDontSetRTX:
       
   172 		// do nothing!
       
   173 			break;
       
   174 		default:
       
   175 			__ASSERT_DEBUG(0, Panic(EAvdtpUnknownPostSendAction));
       
   176 		}
       
   177 	}
       
   178 	
       
   179 void CSignallingChannel::CheckOutboundQueue()
       
   180 	{
       
   181 	// check to see if the outbound queue is empty but we have an outstanding
       
   182 	// request to service it
       
   183 	if (iQueuedMessages.IsEmpty() && iTryToSendCallback->IsActive())
       
   184 		{
       
   185 		CancelTryToSendCallback();
       
   186 		}				
       
   187 	}
       
   188 	
       
   189 void CSignallingChannel::ServiceOutboundQueue()
       
   190 	{
       
   191 	LOG_FUNC
       
   192 	if (!Blocked())
       
   193 		{
       
   194 		// we can send!
       
   195 		// get fragments to send if we don't have any from before
       
   196 		if(iOutgoingSignallingMessage.IsEmpty())
       
   197 			{
       
   198 			// get the head message
       
   199 			CAvdtpOutboundSignallingMessage& message = *iQueuedMessages.First();
       
   200 			
       
   201 			// find the transaction pertaining to it (and make it the current transaction)
       
   202 			iCurrentTransaction = FindTransaction(message.TransactionLabel());
       
   203 			
       
   204 			__ASSERT_DEBUG(iCurrentTransaction!=NULL, Panic(EAvdtpSignallingChannelDrainingFaulty));
       
   205 			
       
   206 			// see whether this requires fragmenting, and get next fragment
       
   207 			// note reference return parameter
       
   208 			TRAPD(ret, iMoreFrags = message.GetNextOutboundFragmentL(iOutgoingSignallingMessage, iBearerMTU));
       
   209 			if (ret!=KErrNone)
       
   210 				{
       
   211 				iMoreFrags = EFalse;
       
   212 				iOutgoingSignallingMessage.Free();
       
   213 				// error the user
       
   214 				iCurrentTransaction->Error(ret);
       
   215 				return;
       
   216 				}
       
   217 			}
       
   218 			
       
   219 
       
   220 		// write outgoing fragments to bearer
       
   221 		TInt sent = iBearer->Write(iOutgoingSignallingMessage,NULL);
       
   222 		
       
   223 		if (!sent)
       
   224 			{
       
   225 			// leave fragment there for next time writing
       
   226 			SetBlocked(ETrue);
       
   227 			}
       
   228 		else
       
   229 			{
       
   230 			iOutgoingSignallingMessage.Free();
       
   231 			if (!iMoreFrags)
       
   232 				{
       
   233 				// that message has been completely sent
       
   234 				PacketSent(*iCurrentTransaction);
       
   235 				}
       
   236 			}
       
   237 
       
   238 		if (!iQueuedMessages.IsEmpty())
       
   239 			{
       
   240 			// more to send, send asynchronously.
       
   241 			StartTryToSendCallback();
       
   242 			}
       
   243 		else if (iTryToSendCallback->Priority()==KAvdtpReleaseAcceptPriority)
       
   244             {
       
   245             // cancel the Release send boost (actually might want to use boosting
       
   246             // to clear remaining fragments of partially sent commands)
       
   247             iTryToSendCallback->SetPriority(CActive::EPriorityStandard);
       
   248             }
       
   249    		}
       
   250 	}
       
   251 
       
   252 /*static*/ TInt CSignallingChannel::TryToSendCallback()
       
   253 	{
       
   254 	LOG_STATIC_FUNC
       
   255 	ServiceOutboundQueue();
       
   256 	return EFalse;
       
   257 	}
       
   258 
       
   259 TBTDevAddr CSignallingChannel::RemoteAddress()
       
   260 	{
       
   261 	LOG_FUNC
       
   262 	if (iBearer && IsListening())
       
   263 		{
       
   264 		TL2CAPSockAddr remote;
       
   265 		iBearer->RemName(remote);		
       
   266 		iRemoteAddress = remote.BTAddr();
       
   267 		}
       
   268 	if (iBearer)
       
   269 		{
       
   270 		return iRemoteAddress;
       
   271 		}
       
   272 	else
       
   273 		{
       
   274 		return TBTDevAddr(0);
       
   275 		}
       
   276 	}
       
   277 
       
   278 void CSignallingChannel::LogicalChannelFactoryRequestComplete(TLogicalChannelFactoryTicket aTicket, TInt aError)
       
   279 	{
       
   280 	LOG_FUNC
       
   281 	
       
   282 	if (aError == KErrNone)
       
   283 		{
       
   284 		iLogicalChannelRequest = aTicket;
       
   285 
       
   286 		TLogicalChannelRecord rec = aTicket.GetLogicalChannel();
       
   287 		
       
   288 		// we take this "out" of the logical channel for performance reasons
       
   289 		// (the pending logical channel will then die at some point later)
       
   290 		iBearer = rec.iLogicalChannelSAP;
       
   291 		iBearer->SetNotify(this);
       
   292 		
       
   293 		// get the MTU now
       
   294 		ObtainMTU();
       
   295 
       
   296 		// decide on our address (we may have been passive)
       
   297 		// to let clients know we signal all the Signal Receivers
       
   298 		TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   299 	
       
   300 		while (iter)
       
   301 			{
       
   302 			iter++->SignallingChannelReady(*this);
       
   303 			}
       
   304 			
       
   305 		// migrate all the current listening sessions, to this new channel
       
   306 		// if their clients not happy they can detach and relisten for new connection
       
   307 		// just as if they got an inbound connection - which this is like
       
   308 		// whether it really is passive l2cap, or was initiated by any one session
       
   309 		
       
   310 		iProtocol.ConnectSignallingListeners(*this);
       
   311 		
       
   312 		// process any already received inbound data
       
   313 		if (rec.iDataCount)
       
   314 			{
       
   315 			NewData(rec.iDataCount);
       
   316 			}
       
   317 		if (rec.iEndOfData)
       
   318 			{
       
   319 			NewData(KNewDataEndofData);
       
   320 			Disconnect();
       
   321 			}
       
   322 		}
       
   323 	else
       
   324 		{
       
   325 		// to let clients know we signal all the Signal Receivers
       
   326 		TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   327 	
       
   328 		while (iter)
       
   329 			{
       
   330 			iter++->SignallingChannelError(aError);
       
   331 			}
       
   332 		if (IsIdle())
       
   333 			{
       
   334 			IdledD();
       
   335 			}
       
   336 		}
       
   337 	}
       
   338 	
       
   339 TInt CSignallingChannel::AttachSignallingUser(XAvdtpSignalReceiver& aUser)
       
   340 	{
       
   341 	LOG_FUNC
       
   342 	// must check they're not already in the queue
       
   343 #ifdef _DEBUG
       
   344 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   345 	while (iter)
       
   346 		{
       
   347 		if (iter++ == &aUser)
       
   348 			{
       
   349 			Panic(EAvdtpBadSignallingUserQueue);
       
   350 			}
       
   351 		}
       
   352 #endif
       
   353 
       
   354 	TBool isFirstUser = iPermanentUsers.IsEmpty();
       
   355 	TInt ret = KErrNone;
       
   356 	
       
   357 	iPermanentUsers.AddFirst(aUser);
       
   358 	if (iBearer)
       
   359 		{
       
   360 		aUser.SignallingChannelReady(*this);
       
   361 		}
       
   362 	else if(isFirstUser)
       
   363 		{
       
   364 		// kick off the need for a signalling channel - we have a user
       
   365 		
       
   366 		// form a request
       
   367 		if (!IsListening())
       
   368 			{
       
   369 			TRAP(ret, iLogicalChannelRequest = iLogicalChannelFactory.CreateSignallingLogicalChannelL(iRemoteAddress, *this));
       
   370 			}
       
   371 		else
       
   372 			{
       
   373 			TRAP(ret, iLogicalChannelRequest = iLogicalChannelFactory.ExpectSignallingLogicalChannelL(*this));
       
   374 			}
       
   375 		}
       
   376 	
       
   377 	return ret;
       
   378 	}
       
   379 
       
   380 void CSignallingChannel::DetachSignallingUser(XAvdtpSignalReceiver& aUser)
       
   381 	{
       
   382 	LOG_FUNC
       
   383 	aUser.iSignalReceiverEmbeddedLink.Deque();
       
   384 	
       
   385 	// cleanup any requests they had outstanding
       
   386 	RemoveTransactions(aUser);
       
   387 
       
   388 	if (IsIdle())
       
   389 		{
       
   390 		if(!IsListening())
       
   391 			{
       
   392 			QueIdleTimer();
       
   393 			}
       
   394 		else
       
   395 			{
       
   396 			//listener just dies
       
   397 			IdledD();
       
   398 			}
       
   399 		}
       
   400 	}
       
   401 
       
   402 TBool CSignallingChannel::IsIdle() const
       
   403 	{
       
   404 	LOG_FUNC
       
   405 
       
   406 	// idle if permanent users empty, and transient users haven't got stuff queued
       
   407 	return (iPermanentUsers.IsEmpty() && iTransactions.IsEmpty());
       
   408 	}
       
   409 	
       
   410 void CSignallingChannel::QueIdleTimer()
       
   411 	{
       
   412 	LOG_FUNC
       
   413 	CancelIdleTimer();
       
   414 	iIdleTimerActive = ETrue;	
       
   415 	BTSocketTimer::Queue(KAvdtpSignallingChannelIdleTimeout, iIdleTimerEntry);
       
   416 	}
       
   417 	
       
   418 void CSignallingChannel::CancelIdleTimer()
       
   419 	{
       
   420 	LOG_FUNC
       
   421 	if(iIdleTimerActive)
       
   422 		{
       
   423 		// there's something to cancel
       
   424 		iIdleTimerActive = EFalse;
       
   425 		BTSocketTimer::Remove(iIdleTimerEntry);
       
   426 		}
       
   427 	}
       
   428 
       
   429 /*static*/ TInt CSignallingChannel::TryToClose(TAny* aSignallingChannel)
       
   430 	{
       
   431 	LOG_STATIC_FUNC
       
   432 	// check if still idle
       
   433 	CSignallingChannel* sigch = reinterpret_cast<CSignallingChannel*>(aSignallingChannel);
       
   434 	if (sigch->IsIdle())
       
   435 		{
       
   436 		sigch->IdledD();
       
   437 		}
       
   438 	return EFalse;
       
   439 	}
       
   440 
       
   441 void CSignallingChannel::IdledD()
       
   442 	{
       
   443 	LOG_FUNC
       
   444 	// we are till idle
       
   445 	__ASSERT_ALWAYS(iDraftMessages.IsEmpty(), Panic(EAvdtpSignallingChannelDyingWithDraftMessagesOnQueue));
       
   446 	__ASSERT_ALWAYS(iTransactions.IsEmpty(), Panic(EAvdtpSignallingChannelDyingWithTransactionsOnQueue));
       
   447 	__ASSERT_ALWAYS(iQueuedMessages.IsEmpty(), Panic(EAvdtpSignallingChannelDyingWithMessagesOnQueue));
       
   448 
       
   449 	delete this;
       
   450 	}
       
   451 	
       
   452 /*
       
   453 Remove transactions held by a user
       
   454 */
       
   455 void CSignallingChannel::RemoveTransactions(XAvdtpSignalReceiver& aUser)
       
   456 	{
       
   457 	LOG_FUNC
       
   458 	TDblQueIter<CSignallingTransaction> iter(iTransactions);
       
   459 	while (iter)
       
   460 		{
       
   461 		CSignallingTransaction* transaction = iter++;
       
   462 		if (transaction->User() == &aUser)
       
   463 			{
       
   464 			transaction->iLink.Deque();
       
   465 			delete transaction;
       
   466 			
       
   467 			// outbound queue may now be empty
       
   468 			CheckOutboundQueue();			
       
   469 			}
       
   470 		}
       
   471 	}
       
   472 
       
   473 void CSignallingChannel::NewData(TUint aCount)
       
   474 	{
       
   475 	LOG_FUNC
       
   476 	// read out now (could make this async though)
       
   477 	// just give to inbound message
       
   478 	TInt res = iInboundMessage.NewData(aCount);
       
   479 	
       
   480 	if (res!=KErrNone)
       
   481 		{
       
   482 		// have to error this channel
       
   483 		Error(res);
       
   484 		}
       
   485 	}
       
   486 	
       
   487 
       
   488 /**
       
   489 Called by packet as it builds itself up - get stuff out of bearer now
       
   490 The service provided is always to fetch an MTU's worth
       
   491 */
       
   492 TInt CSignallingChannel::GetData(RMBufChain& aData, TUint aOptions, TSockAddr* aAddr)
       
   493 	{
       
   494 	LOG_FUNC
       
   495 	return iBearer->GetData(aData,iBearerMTU,aOptions,aAddr);
       
   496 	}
       
   497 	
       
   498 
       
   499 /**
       
   500 Upcall from L2CAP - it is now ready to send
       
   501 */	
       
   502 void CSignallingChannel::CanSend()
       
   503 	{
       
   504 	LOG_FUNC
       
   505 	SetBlocked(EFalse);
       
   506 	StartTryToSendCallback();
       
   507 	}
       
   508 	
       
   509 void CSignallingChannel::ConnectComplete()
       
   510 	{
       
   511 	LOG_FUNC
       
   512 	// the factory would have done this by now
       
   513 	}
       
   514 	
       
   515 void CSignallingChannel::ConnectComplete(const TDesC8& /*aConnectData*/)
       
   516 	{
       
   517 	LOG_FUNC
       
   518 	// the factory would have done this by now
       
   519 	}
       
   520 	
       
   521 void CSignallingChannel::ConnectComplete(CServProviderBase& /*aSSP*/)
       
   522 	{
       
   523 	LOG_FUNC
       
   524 	// the factory would have done this by now
       
   525 	}
       
   526 	
       
   527 void CSignallingChannel::ConnectComplete(CServProviderBase& /*aSSP*/,const TDesC8& /*aConnectData*/)
       
   528 	{
       
   529 	LOG_FUNC
       
   530 	// the factory would have done this by now
       
   531 	}
       
   532 	
       
   533 void CSignallingChannel::CanClose(TDelete /*aDelete*/)
       
   534 	{
       
   535 	LOG_FUNC
       
   536 	// only support immediate shutdown so shouldnt be called
       
   537 	}
       
   538 	
       
   539 void CSignallingChannel::CanClose(const TDesC8& /*aDisconnectData*/,TDelete aDelete)
       
   540 	{
       
   541 	LOG_FUNC
       
   542 	// l2cap shouldnt upcall this, but just in case
       
   543 	CanClose(aDelete);
       
   544 	}
       
   545 	
       
   546 void CSignallingChannel::Error(TInt aError,TUint /*aOperationMask*/)
       
   547 	{
       
   548 	LOG_FUNC
       
   549 	// from logical channel
       
   550 	ErrorPermanentUsers(aError);
       
   551 	ErrorServiceRequesters(aError);
       
   552 	delete this;
       
   553 	}
       
   554 	
       
   555 void CSignallingChannel::ErrorPermanentUsers(TInt aError)
       
   556 	{
       
   557 	LOG_FUNC
       
   558 	// error all users
       
   559 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   560 	while (iter)
       
   561 		{
       
   562 		iter++->SignallingChannelError(aError);
       
   563 		}
       
   564 	}
       
   565 
       
   566 void CSignallingChannel::ErrorServiceRequesters(TInt aError)
       
   567 	{
       
   568 	LOG_FUNC
       
   569 	// complete all outstanding services
       
   570 	TDblQueIter<CSignallingTransaction> iter(iTransactions);
       
   571 	while (iter)
       
   572 		{
       
   573 		CSignallingTransaction* transaction = iter++;
       
   574 
       
   575 		if (transaction->User())
       
   576 			{
       
   577 			// it was a command, tell the user it failed
       
   578 			// This will cause the transaction to be tidied
       
   579 			// up.
       
   580 			transaction->Error(aError);
       
   581 			}
       
   582 		else
       
   583 			{
       
   584 			// Just tidy up, there's no user to inform.
       
   585 			RemoveTransaction(*transaction);
       
   586 			}					
       
   587 		}
       
   588 	}
       
   589 	
       
   590 void CSignallingChannel::CancelTransactions(XAvdtpSignalReceiver& aUser)
       
   591 	{
       
   592 	LOG_FUNC
       
   593 	RemoveTransactions(aUser);
       
   594 	}
       
   595 	
       
   596 void CSignallingChannel::Disconnect()
       
   597 	{
       
   598 	LOG_FUNC
       
   599 	Error(KErrDisconnected);
       
   600 	}
       
   601 	
       
   602 void CSignallingChannel::Disconnect(TDesC8& /*aDisconnectData*/)
       
   603 	{
       
   604 	LOG_FUNC
       
   605 	// shouldnt be supported by l2cap, but just in case
       
   606 	Disconnect();
       
   607 	}
       
   608 	
       
   609 void CSignallingChannel::IoctlComplete(TDesC8* /*aBuf*/)
       
   610 	{
       
   611 	LOG_FUNC
       
   612 	// we don't issue ioctls - drop
       
   613 	}
       
   614 	
       
   615 void CSignallingChannel::NoBearer(const TDesC8& /*aConnectionInfo*/)
       
   616 	{
       
   617 	LOG_FUNC
       
   618 	// do nothing
       
   619 	}
       
   620 	
       
   621 void CSignallingChannel::Bearer(const TDesC8& /*aConnectionInfo*/)
       
   622 	{
       
   623 	LOG_FUNC
       
   624 	// do nothing	
       
   625 	}
       
   626 		
       
   627 /**
       
   628 Find a transaction given a transaction label - there shuold be one
       
   629 @param aLabel the transaction label in the packet for which a transaction is required
       
   630 @internalComponent
       
   631 */
       
   632 CSignallingTransaction* CSignallingChannel::FindTransaction(TAvdtpTransactionLabel aLabel)
       
   633 	{
       
   634 	LOG_FUNC
       
   635 	TDblQueIter<CSignallingTransaction> iter(iTransactions);
       
   636 	while (iter)
       
   637 		{
       
   638 		CSignallingTransaction* t = iter;
       
   639 		if (t->Label() == aLabel)
       
   640 			{
       
   641 			return t;
       
   642 			}
       
   643 		iter++;
       
   644 		}
       
   645 	//__DEBUGGER();// FLOG
       
   646 	return NULL;
       
   647 	}
       
   648 
       
   649 /**
       
   650 Relinquish a transaction - may not be found if race with client cancelling
       
   651 @param aLabel the label of the transaction to relinquish
       
   652 @internalComponent
       
   653 **/	
       
   654 void CSignallingChannel::RemoveTransaction(CSignallingTransaction& aTransaction)
       
   655 	{
       
   656 	LOG_FUNC
       
   657 
       
   658 	// This will cancel the timer and remove the transaction from the queue
       
   659 	delete &aTransaction;
       
   660 
       
   661 	// outbound queue may now be empty
       
   662 	CheckOutboundQueue();			
       
   663 	
       
   664 	if (IsIdle())
       
   665 		{
       
   666 		QueIdleTimer();
       
   667 		}
       
   668 	}
       
   669 	
       
   670 void CSignallingChannel::DiscoverIndication(TAvdtpTransactionLabel aLabel)
       
   671 	{
       
   672 	LOG_FUNC
       
   673 	// create transaction ready for the response
       
   674 	CSignallingTransaction* transaction = PrepareSignallingResponse(EResponseAccept, EAvdtpDiscover, aLabel);
       
   675 	
       
   676 	if (transaction)
       
   677 		{
       
   678 		// go and ask sessions to contribute to packet
       
   679 		TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   680 		
       
   681 		while (iter)
       
   682 			{
       
   683 			// sessions MUST process this synchronously.
       
   684 			(void)(iter++)->DiscoverIndication(aLabel, transaction->Message());
       
   685 			}
       
   686 		
       
   687 		// ..as we now deem the packet constructed, and ready to send
       
   688 		(void)EnqueueMessage(*transaction);
       
   689 		// if Enque failed (it can't at present for Responses) remote would timeout
       
   690 		}
       
   691 	}
       
   692 	
       
   693 	
       
   694 
       
   695 void CSignallingChannel::DiscoverConfirm(TAvdtpTransactionLabel aLabel,
       
   696 										  TInt aResult,
       
   697 										  const TAvdtpInternalDiscoverConfirm* const aConfirm)
       
   698 	{
       
   699 	LOG_FUNC
       
   700 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
   701 	RETURN_IF_NO_TRANSACTION(transaction);	
       
   702 	RETURN_IF_SIGNAL_BAD(transaction, EAvdtpDiscover);
       
   703 		
       
   704 	transaction->User()->DiscoverConfirm(aResult, aConfirm);
       
   705 	
       
   706 	RemoveTransaction(*transaction); //clears RTX timer
       
   707 	}
       
   708 
       
   709 void CSignallingChannel::GetCapsIndication(TAvdtpTransactionLabel aLabel, TSEID aSEID)
       
   710 	{
       
   711 	LOG_FUNC
       
   712 	// create transaction ready for the response
       
   713 	CSignallingTransaction* transaction = PrepareSignallingResponse(EResponseAccept, EAvdtpGetCapabilities, aLabel);
       
   714 	if (transaction)
       
   715 		{
       
   716 		// go and ask sessions to contribute to packet
       
   717 		TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   718 		TInt result = KErrNotFound;
       
   719 
       
   720 		while (iter)
       
   721 			{
       
   722 			// sessions MUST process this synchronously.
       
   723 			result = (iter++)->GetCapsIndication(aLabel, aSEID, transaction->Message());
       
   724 			if (result!=KErrNotFound)
       
   725 				{
       
   726 				// some error occured that meant we need not bother asking other sessions
       
   727 				break;
       
   728 				}
       
   729 			}
       
   730 	
       
   731 		// ..as we now deem the packet constructed, and ready to send
       
   732 		if (result==KErrNone)
       
   733 			{
       
   734 			(void)EnqueueMessage(*transaction);
       
   735 			// if Enque failed (it can't at present for Responses) remote would timeout
       
   736 			}
       
   737 		else
       
   738 			{
       
   739 			delete transaction;
       
   740 			
       
   741 			if (result==KErrNotFound)
       
   742 				{
       
   743 				SendReject(aLabel, EAvdtpGetCapabilities, EAvdtpBadACPSEID);
       
   744 				}
       
   745 			// else dump, and leave to time out				
       
   746 			}
       
   747 		}
       
   748 	else
       
   749 		{
       
   750 		// leave to timeout - no apt error
       
   751 		}
       
   752 	}
       
   753 
       
   754 void CSignallingChannel::GetCapsConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, const HBufC8* aCaps/*=NULL*/)
       
   755 	{
       
   756 	LOG_FUNC
       
   757 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
   758 	RETURN_IF_NO_TRANSACTION(transaction);
       
   759 	RETURN_IF_SIGNAL_BAD(transaction, EAvdtpGetCapabilities);
       
   760 	
       
   761 	TSEID seid(reinterpret_cast<TUint>(transaction->Cookie()));
       
   762 	if (aResult==KErrNone)
       
   763 		{
       
   764 		//Parse the SEID info, updating the protocol's sep cache and
       
   765 		//generating a descriptor to pass to the client.
       
   766 		
       
   767 		// tricky to get this to be efficient
       
   768 		// we just tell cache - it'll parse if it chooses to :o)
       
   769 		iProtocol.RemoteSEPCache().SetCapabilities(iRemoteAddress,
       
   770 												   seid,
       
   771 												   const_cast<HBufC8*>(aCaps));
       
   772 														   	
       
   773 			
       
   774 		// to make life for the user we tell the the categories we did see
       
   775 		// if they do want to investigate more they can begin a deep parse
       
   776 		TAvdtpServiceCategories  cats;
       
   777 		TRAPD(err, cats = iProtocol.RemoteSEPCache().GetCapabilitiesL(
       
   778 											iRemoteAddress,
       
   779 											seid));
       
   780 											
       
   781 		transaction->User()->GetCapsConfirm(err, seid,cats());
       
   782 		}
       
   783 	else
       
   784 		{
       
   785 		transaction->User()->GetCapsConfirm(aResult,seid, NULL);
       
   786 		}
       
   787 	RemoveTransaction(*transaction); //clears RTX timer
       
   788 	}
       
   789 
       
   790 
       
   791 void CSignallingChannel::SetConfigIndication(TAvdtpTransactionLabel aLabel,
       
   792 											  TSEID aACPSEID,
       
   793 											  TSEID aINTSEID,
       
   794 											  RBuf8& aConfigData)
       
   795 	{		
       
   796 	LOG_FUNC
       
   797 	// ownership of aConfigData transferred
       
   798 	// a consuming session will take owership
       
   799 	// if it is unclaimed we tidyup
       
   800 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   801 	TInt result = KErrNotFound;
       
   802 	
       
   803 	while (iter)
       
   804 		{
       
   805 		result = (iter++)->SetConfigIndication(aLabel, aACPSEID, aINTSEID, aConfigData);
       
   806 		if (result!=KErrNotFound)
       
   807 			{
       
   808 			break;
       
   809 			}
       
   810 		}
       
   811 			
       
   812 	if (result!=KErrNone && result!=KErrNoMemory)
       
   813 		{
       
   814 		CHECK_ERROR(result);
       
   815 		TAvdtpSignallingErrorCode code = AvdtpInternalUtils::SymbianErrorToAvdtpError(result);
       
   816 		
       
   817 		// as per contract, the session has given extended info back to us
       
   818 		SendSetConfigurationReject(aLabel, code, static_cast<TAvdtpServiceCategory>(aConfigData[0]));
       
   819 		
       
   820 		aConfigData.Close();
       
   821 		}
       
   822 	else if (result == KErrNoMemory)
       
   823 		{
       
   824 		// if no memory then leave for remote to timeout
       
   825 		aConfigData.Close();
       
   826 		}
       
   827 	}
       
   828 		
       
   829 
       
   830 void CSignallingChannel::SetConfigConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, TAvdtpServiceCategory aErrorCategory)
       
   831 	{
       
   832 	LOG_FUNC
       
   833 	ConfigConfirm(aLabel, aResult, aErrorCategory, EFalse);
       
   834 	}
       
   835 
       
   836 
       
   837 void CSignallingChannel::GetConfigIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID)
       
   838 	{	
       
   839 	LOG_FUNC
       
   840 	// create transaction ready for the response
       
   841 	CSignallingTransaction* transaction = PrepareSignallingResponse(EResponseAccept, EAvdtpGetConfiguration, aLabel);
       
   842 	
       
   843 	if(transaction)
       
   844 		{
       
   845 		// go and ask sessions to contribute to packet
       
   846 		TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   847 		TInt result = KErrNotFound;
       
   848 
       
   849 		while (iter)
       
   850 			{
       
   851 			// sessions MUST process this synchronously.
       
   852 			result = (iter++)->GetConfigIndication(aLabel, aACPSEID, transaction->Message());
       
   853 			if (result!=KErrNotFound)
       
   854 				{
       
   855 				break;
       
   856 				}
       
   857 			}
       
   858 		
       
   859 		// ..as we now deem the packet constructed, and ready to send
       
   860 		if (result==KErrNone)
       
   861 			{
       
   862 			(void)EnqueueMessage(*transaction);
       
   863 			// leave remote to timeout
       
   864 			}
       
   865 		else if (result!=KErrNoMemory)
       
   866 			{
       
   867 			delete transaction;
       
   868 			SendReject(aLabel, EAvdtpGetConfiguration, AvdtpInternalUtils::SymbianErrorToAvdtpError(result));
       
   869 			}
       
   870 		// else leave to timeout, no suitable response to send
       
   871 		}
       
   872 	// else leave to timeout, no suitable response to send
       
   873 	}
       
   874 
       
   875 
       
   876 void CSignallingChannel::GetConfigConfirm(TAvdtpTransactionLabel /*aLabel*/, TInt /*aResult*/)
       
   877 	{
       
   878 	LOG_FUNC
       
   879 	// shouldnt get one of these as we wont send GetConf yet
       
   880 	// drop
       
   881 	}
       
   882 
       
   883 
       
   884 void CSignallingChannel::ReconfigIndication(TAvdtpTransactionLabel aLabel,
       
   885 										TSEID aACPSEID,
       
   886 										 RBuf8& aConfigData)
       
   887 	{
       
   888 	LOG_FUNC
       
   889 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   890 	TInt result = KErrNotFound;
       
   891 		
       
   892 	while (iter)
       
   893 		{
       
   894 		result = (iter++)->ReconfigIndication(aLabel, aACPSEID, aConfigData);
       
   895 		if (result==KErrNone)
       
   896 			{
       
   897 			break;
       
   898 			}
       
   899 		}
       
   900 	
       
   901 	if (result!=KErrNone && result!=KErrNoMemory)
       
   902 		{
       
   903 		CHECK_ERROR(result);
       
   904 	
       
   905 		TAvdtpSignallingErrorCode code = AvdtpInternalUtils::SymbianErrorToAvdtpError(result);
       
   906 		// as per contract, the session has given extended info back to us
       
   907 		SendReconfigureReject(aLabel, code, static_cast<TAvdtpServiceCategory>(aConfigData[0]));
       
   908 		
       
   909 		aConfigData.Close();
       
   910 		}
       
   911 	else if (result != KErrNone)
       
   912 		{
       
   913 		// clean up the config data if we failed - it hasn't been passed on
       
   914 		aConfigData.Close();
       
   915 		}
       
   916 	// else leave remote to timeout
       
   917 	}
       
   918 
       
   919 void CSignallingChannel::ReconfigConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, TAvdtpServiceCategory aErrorCategory)
       
   920 	{
       
   921 	LOG_FUNC
       
   922 	ConfigConfirm(aLabel, aResult, aErrorCategory, ETrue);
       
   923 	}
       
   924 
       
   925 TInt CSignallingChannel::SendOpenStream(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID)
       
   926 	{
       
   927 	LOG_FUNC
       
   928 	if (!iBearer)
       
   929 		{
       
   930 		return KErrNotReady;
       
   931 		}
       
   932 
       
   933 	TInt result = KErrNoMemory;
       
   934 	CSignallingTransaction* transaction = PrepareSignallingCommand(aReceiver, EAvdtpOpen);
       
   935 	
       
   936 	if (transaction)
       
   937 		{
       
   938 		result = AvdtpSignallingMessageOpen::Command::Format(transaction->Message(), aACPSEID);
       
   939 		if (result==KErrNone)
       
   940 			{
       
   941 			transaction->SetCookie(reinterpret_cast<TAny*>(aACPSEID.Value()));
       
   942 			result=EnqueueMessage(*transaction);
       
   943 			}
       
   944 		if (result!=KErrNone)
       
   945 			{
       
   946 			delete transaction;
       
   947 			}
       
   948 		}
       
   949 	return result;
       
   950 	}
       
   951 	
       
   952 void CSignallingChannel::OpenIndication(TAvdtpTransactionLabel aLabel, TSEID aSEID)
       
   953 	{
       
   954 	LOG_FUNC
       
   955 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
   956 	TInt result = KErrNotFound;
       
   957 		
       
   958 	while (iter)
       
   959 		{
       
   960 		result = (iter++)->OpenIndication(aSEID); 
       
   961 		if (result!=KErrNotFound)
       
   962 			{
       
   963 			break;
       
   964 			}
       
   965 		}	
       
   966 	
       
   967 	if (result==KErrNone)
       
   968 		{
       
   969 		result = SendAccept(aLabel, EAvdtpOpen);
       
   970 		}
       
   971 	else if (result!=KErrNone && result!=KErrNoMemory)
       
   972 		{
       
   973 		SendReject(aLabel, EAvdtpOpen, AvdtpInternalUtils::SymbianErrorToAvdtpError(result));
       
   974 		}
       
   975 
       
   976 	if (result==KErrNone)
       
   977 		{
       
   978 		// now we are happy to pre-authorise remote for more incoming logical channels
       
   979 		iProtocol.SetPreauthorisation(iRemoteAddress, ETrue);
       
   980 		}
       
   981 //#pragma message("would be nice to error session that consumed")
       
   982 	}
       
   983 
       
   984 
       
   985 void CSignallingChannel::OpenConfirm(TAvdtpTransactionLabel aLabel, TInt aResult)
       
   986 	{
       
   987 	LOG_FUNC
       
   988 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
   989 	RETURN_IF_NO_TRANSACTION(transaction);
       
   990 	RETURN_IF_SIGNAL_BAD(transaction, EAvdtpOpen);
       
   991 			
       
   992 	transaction->User()->OpenConfirm(aResult, TSEID(reinterpret_cast<TUint>(transaction->Cookie())));
       
   993 	RemoveTransaction(*transaction); //clears RTX timer
       
   994 	}
       
   995 
       
   996 
       
   997 void CSignallingChannel::StartIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID)
       
   998 	{
       
   999 	LOG_FUNC
       
  1000 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
  1001 	TInt result = KErrNotFound;
       
  1002 	
       
  1003 	while (iter)
       
  1004 		{
       
  1005 		result = (iter++)->StartIndication(aLabel, aACPSEID);
       
  1006 		if (result!=KErrNotFound)
       
  1007 			{
       
  1008 			break;
       
  1009 			}
       
  1010 		}
       
  1011 
       
  1012 	if (result != KErrNone && result!=KErrNoMemory)
       
  1013 		{
       
  1014 		CHECK_ERROR(result);		
       
  1015 		
       
  1016 		// this one has to error slightly differently - we tell remote of the first bad SEID
       
  1017 		// which would be this one.
       
  1018 		TPckg<TUint8> seidPckg(aACPSEID.PacketValue());
       
  1019 		SendReject(aLabel, EAvdtpStart, AvdtpInternalUtils::SymbianErrorToAvdtpError(result), &seidPckg);
       
  1020 		}
       
  1021 	//else leave remote to timeout
       
  1022 	}
       
  1023 
       
  1024 void CSignallingChannel::StartConfirm(TAvdtpTransactionLabel aLabel, TInt aResult)
       
  1025 	{
       
  1026 	LOG_FUNC
       
  1027 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
  1028 	RETURN_IF_NO_TRANSACTION(transaction);
       
  1029 	RETURN_IF_SIGNAL_BAD(transaction, EAvdtpStart);
       
  1030 	
       
  1031 	transaction->User()->StartConfirm(aResult, TSEID(reinterpret_cast<TUint>(transaction->Cookie())));
       
  1032 	RemoveTransaction(*transaction); //clears RTX timer
       
  1033 	}
       
  1034 
       
  1035 void CSignallingChannel::SuspendConfirm(TAvdtpTransactionLabel aLabel, TInt aResult)
       
  1036 	{
       
  1037 	LOG_FUNC
       
  1038 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
  1039 	RETURN_IF_NO_TRANSACTION(transaction);
       
  1040 	RETURN_IF_SIGNAL_BAD(transaction, EAvdtpSuspend);
       
  1041 		
       
  1042 	transaction->User()->SuspendConfirm(aResult, TSEID(reinterpret_cast<TUint>(transaction->Cookie())));
       
  1043 	RemoveTransaction(*transaction); //clears RTX timer
       
  1044 	}
       
  1045 
       
  1046 
       
  1047 void CSignallingChannel::ReleaseIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID)
       
  1048 	{
       
  1049 	LOG_FUNC
       
  1050 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
  1051 	TInt result = KErrNotFound;
       
  1052 	
       
  1053 	while (iter)
       
  1054 		{
       
  1055 		result = (iter++)->ReleaseIndication(aLabel, aACPSEID);
       
  1056 		if (result!=KErrNotFound)
       
  1057 			{
       
  1058 			break;
       
  1059 			}
       
  1060 		}
       
  1061 
       
  1062 	// session must send accept otherwise we may send OK after it has released transport channels	
       
  1063 	if (result!=KErrNone && result!=KErrNoMemory)
       
  1064 		{
       
  1065 		result = SendReject(aLabel, EAvdtpRelease, AvdtpInternalUtils::SymbianErrorToAvdtpError(result));
       
  1066 		}
       
  1067 	// else leave remote to timeout
       
  1068 	if (result!=KErrNone)
       
  1069 		{
       
  1070 //	#pragma message("would be nice to just error the session that consumed")
       
  1071 //			iSignallingChannelError(err);
       
  1072 		}
       
  1073 	}
       
  1074 
       
  1075 void CSignallingChannel::ReleaseConfirm(TAvdtpTransactionLabel aLabel, TInt aResult)
       
  1076 	{
       
  1077 	LOG_FUNC
       
  1078 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
  1079 	RETURN_IF_NO_TRANSACTION(transaction);
       
  1080 	RETURN_IF_SIGNAL_BAD(transaction, EAvdtpRelease);
       
  1081 	
       
  1082 	// We take the details we need and remove transaction before
       
  1083 	// passing the signal on for processing as ReleaseConfirm may
       
  1084 	// lead to the stream, and all its transactions, being 
       
  1085 	// destroyed.
       
  1086 	XAvdtpSignalReceiver* user = transaction->User();
       
  1087 	TSEID seid(reinterpret_cast<TUint>(transaction->Cookie()));
       
  1088 	RemoveTransaction(*transaction); //clears RTX timer
       
  1089 
       
  1090 	if (user)
       
  1091 		{
       
  1092 		// it was an "normal" Release - forward confirm
       
  1093 		user->ReleaseConfirm(aResult, seid);
       
  1094 		}
       
  1095 	}
       
  1096 
       
  1097 
       
  1098 void CSignallingChannel::SuspendIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID)
       
  1099 	{
       
  1100 	LOG_FUNC
       
  1101 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
  1102 	TInt result = KErrNotFound;
       
  1103 	
       
  1104 	while (iter)
       
  1105 		{
       
  1106 		result = (iter++)->SuspendIndication(aLabel, aACPSEID);
       
  1107 		/* if we've found and suspended we don't need to go round again
       
  1108 		   if we've run out of memory or anything then...
       
  1109 		*/
       
  1110 		if (result!=KErrNotFound)
       
  1111 			{
       
  1112 			break;
       
  1113 			}
       
  1114 		}
       
  1115 
       
  1116 	/* if we've not broken out then we will come out with notfound
       
  1117 	   which is a bad sepid */
       
  1118 	if (result!=KErrNone && result!=KErrNoMemory)
       
  1119 		{
       
  1120 		CHECK_ERROR(result);		
       
  1121 		
       
  1122 		// this one has to error slightly differently - we tell remote of the first bad SEID
       
  1123 		// which would be this one.
       
  1124 		TPckg<TUint8> seidPckg(aACPSEID.PacketValue());
       
  1125 		SendReject(aLabel, EAvdtpSuspend, AvdtpInternalUtils::SymbianErrorToAvdtpError(result), &seidPckg);
       
  1126 		}
       
  1127 	// else leave remote to timeout
       
  1128 	}
       
  1129 
       
  1130 
       
  1131 void CSignallingChannel::AbortIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID)
       
  1132 	{
       
  1133 	LOG_FUNC
       
  1134 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
  1135 	TInt result = KErrNotFound;
       
  1136 	
       
  1137 	while (iter)
       
  1138 		{
       
  1139 		result = (iter++)->AbortIndication(aLabel, aACPSEID);
       
  1140 		if (result!=KErrNotFound)
       
  1141 			{
       
  1142 			break;
       
  1143 			}
       
  1144 		}
       
  1145 		
       
  1146 	if (result == KErrNone)
       
  1147 		{
       
  1148 		(void)SendAccept(aLabel, EAvdtpAbort);
       
  1149 		}
       
  1150 	// else no error path for Abort. Just ignore.			
       
  1151 	}
       
  1152 
       
  1153 void CSignallingChannel::AbortConfirm(TAvdtpTransactionLabel aLabel)
       
  1154 	{
       
  1155 	LOG_FUNC
       
  1156 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
  1157 	RETURN_IF_NO_TRANSACTION(transaction);
       
  1158 	RETURN_IF_SIGNAL_BAD(transaction, EAvdtpAbort);
       
  1159 
       
  1160 	// We take the details we need and remove transaction before
       
  1161 	// passing the signal on for processing as AbortConfirm may
       
  1162 	// lead to the stream, and all its transactions, being 
       
  1163 	// destroyed.
       
  1164 	XAvdtpSignalReceiver* user = transaction->User();
       
  1165 	TSEID seid(reinterpret_cast<TUint>(transaction->Cookie()));
       
  1166 	RemoveTransaction(*transaction); //clears RTX timer
       
  1167 
       
  1168 	if (user)
       
  1169 		{
       
  1170 		// it was an "immediate" Abort - noone wants confirm
       
  1171 		user->AbortConfirm(seid);
       
  1172 		}
       
  1173 	}
       
  1174 
       
  1175 
       
  1176 void CSignallingChannel::SecurityControlIndication(TAvdtpTransactionLabel aLabel, TSEID aACPSEID, const HBufC8* aSecurityData)
       
  1177 	{
       
  1178 	LOG_FUNC
       
  1179 	TDblQueIter<XAvdtpSignalReceiver> iter(iPermanentUsers);
       
  1180 	TInt result = KErrNotFound;
       
  1181 	
       
  1182 	while (iter)
       
  1183 		{
       
  1184 		result = (iter++)->SecurityControlIndication(aLabel, aACPSEID, aSecurityData);
       
  1185 		if (result!=KErrNotFound)
       
  1186 			{
       
  1187 			break;
       
  1188 			}
       
  1189 		}
       
  1190 
       
  1191 	if (result!=KErrNone && result!=KErrNoMemory)
       
  1192 		{
       
  1193 		CHECK_ERROR(result);		
       
  1194 		
       
  1195 		// destroy HBuf
       
  1196 		delete (const_cast<HBufC8*>(aSecurityData));
       
  1197 		SendReject(aLabel, EAvdtpSecurityControl, AvdtpInternalUtils::SymbianErrorToAvdtpError(result));
       
  1198 		}
       
  1199 	// else ownership of HBufC8 transferred
       
  1200 	}
       
  1201 
       
  1202 void CSignallingChannel::SecurityControlConfirm(TAvdtpTransactionLabel aLabel, TInt aResult, const TDesC8& aResponseData)
       
  1203 	{
       
  1204 	LOG_FUNC
       
  1205 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
  1206 	RETURN_IF_NO_TRANSACTION(transaction);	
       
  1207 	RETURN_IF_SIGNAL_BAD(transaction, EAvdtpSecurityControl);
       
  1208 
       
  1209 	transaction->User()->SecurityControlConfirm(aResult, TSEID(reinterpret_cast<TUint>(transaction->Cookie())), aResponseData);
       
  1210 	RemoveTransaction(*transaction); //clears RTX timer
       
  1211 	}
       
  1212 
       
  1213 
       
  1214 /**
       
  1215 Send primitives
       
  1216 **/
       
  1217 
       
  1218 
       
  1219 TInt CSignallingChannel::SendDiscoverSEPs(XAvdtpSignalReceiver& aReceiver)
       
  1220 	{
       
  1221 	LOG_FUNC
       
  1222 	if (!iBearer)
       
  1223 		{
       
  1224 		return KErrNotReady;
       
  1225 		}
       
  1226 		
       
  1227 	CSignallingTransaction*	transaction = PrepareSignallingCommand(aReceiver, EAvdtpDiscover);
       
  1228 	TInt result = KErrNoMemory;
       
  1229 	
       
  1230 	if (transaction)
       
  1231 		{
       
  1232 		result=EnqueueMessage(*transaction);
       
  1233 		}
       
  1234 	if (result!=KErrNone)
       
  1235 		{
       
  1236 		delete transaction;
       
  1237 		}
       
  1238 		
       
  1239 	return result;
       
  1240 	}
       
  1241 	
       
  1242 TInt CSignallingChannel::SendGetCapabilities(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID)
       
  1243 	{
       
  1244 	LOG_FUNC
       
  1245 	if (!aACPSEID.IsValid() || aACPSEID.IsLocal())
       
  1246 		{
       
  1247 		return KErrArgument;
       
  1248 		}
       
  1249 	if (!iBearer)
       
  1250 		{
       
  1251 		return KErrNotReady;
       
  1252 		}
       
  1253 
       
  1254 	CSignallingTransaction* transaction = PrepareSignallingCommand(aReceiver, EAvdtpGetCapabilities);
       
  1255 	TInt result = KErrNoMemory;
       
  1256 
       
  1257 	if (transaction)
       
  1258 		{
       
  1259 		result = AvdtpSignallingMessageGetCapabilities::Command::Format(transaction->Message(), aACPSEID);
       
  1260 		if (result==KErrNone)
       
  1261 			{
       
  1262 			//Stuff the seid in the CSignallingTransaction as AVDTP spec forgets it
       
  1263 			transaction->SetCookie(reinterpret_cast<TAny*>(aACPSEID.Value()));			
       
  1264 			result=EnqueueMessage(*transaction);
       
  1265 			}
       
  1266 		if (result!=KErrNone)
       
  1267 			{
       
  1268 			delete transaction;
       
  1269 			}
       
  1270 		}
       
  1271 	return result;
       
  1272 	}
       
  1273 	
       
  1274 TInt CSignallingChannel::SendReleaseAccept(TAvdtpTransactionLabel aLabel)
       
  1275 	{
       
  1276 	LOG_FUNC
       
  1277     // want to turn this around asap to avoid remote hanging, and races with local l2cap shutting down
       
  1278     // so one-shot bump the priority
       
  1279 
       
  1280  	if(!iTryToSendCallback->IsActive())
       
  1281  	    {
       
  1282 		iTryToSendCallback->SetPriority(KAvdtpReleaseAcceptPriority);	
       
  1283     	}
       
  1284     else if(iTryToSendCallback->Priority()!=KAvdtpReleaseAcceptPriority)
       
  1285    		{
       
  1286    		//Callback is active trying to send a low priority item
       
  1287    		//Cancel it and set the priority to high. The priority will remain high until the
       
  1288    		//callback has run enough times to empty the message queue.
       
  1289    		iTryToSendCallback->Cancel();
       
  1290     	iTryToSendCallback->SetPriority(KAvdtpReleaseAcceptPriority);
       
  1291     	}
       
  1292     //Else, do nothing. The priority will remain high until the message queue has been
       
  1293     //cleared, so the EAvdtpRelease about to be added should be sent whilst the priority
       
  1294     //is still high
       
  1295     	
       
  1296     return SendAccept(aLabel, EAvdtpRelease);
       
  1297 	}
       
  1298 	
       
  1299 	
       
  1300 TInt CSignallingChannel::SendSetConfigurationAccept(TAvdtpTransactionLabel aLabel)
       
  1301 	{
       
  1302 	LOG_FUNC
       
  1303 	return SendAccept(aLabel, EAvdtpSetConfiguration);
       
  1304 	}
       
  1305 									  
       
  1306 TInt CSignallingChannel::SendSetConfigurationReject(TAvdtpTransactionLabel aLabel,
       
  1307 											TBluetoothAvDistributionError aResult,
       
  1308 									  		TAvdtpServiceCategory aCategory)
       
  1309 	{
       
  1310 	LOG_FUNC
       
  1311 	// packet size of errored category is 8bits
       
  1312 	TPckg<TUint8> cat(static_cast<TUint8>(aCategory));
       
  1313 	return SendReject(aLabel, EAvdtpSetConfiguration, aResult, &cat);
       
  1314 	}
       
  1315 
       
  1316 TInt CSignallingChannel::SendReconfigureAccept(TAvdtpTransactionLabel aLabel)
       
  1317 	{
       
  1318 	LOG_FUNC
       
  1319 	return SendAccept(aLabel, EAvdtpReconfigure);
       
  1320 	}
       
  1321 	
       
  1322 TInt CSignallingChannel::SendReconfigureReject(TAvdtpTransactionLabel aLabel,
       
  1323 											TBluetoothAvDistributionError aResult,
       
  1324 									  		TAvdtpServiceCategory aCategory)
       
  1325 	{
       
  1326 	LOG_FUNC
       
  1327 	// packet size of errored category is 8bits
       
  1328 	TPckg<TUint8> cat(static_cast<TUint8>(aCategory));
       
  1329 	return SendReject(aLabel, EAvdtpReconfigure, aResult, &cat);
       
  1330 	}
       
  1331 
       
  1332 TInt CSignallingChannel::SendSecurityControlAccept(TAvdtpTransactionLabel aLabel, const TDesC8* aOptionalData)
       
  1333 	{
       
  1334 	LOG_FUNC
       
  1335 	return SendAccept(aLabel, EAvdtpSecurityControl, aOptionalData);	
       
  1336 	}
       
  1337 	
       
  1338 TInt CSignallingChannel::SendSecurityControlReject(TAvdtpTransactionLabel aLabel, TBluetoothAvDistributionError aResult)
       
  1339 	{
       
  1340 	LOG_FUNC
       
  1341 	return SendReject(aLabel, EAvdtpSecurityControl, aResult, NULL);
       
  1342 	}
       
  1343 	
       
  1344 TInt CSignallingChannel::SendRelease(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID)
       
  1345 	{
       
  1346 	LOG_FUNC
       
  1347 	if (!aACPSEID.IsValid())
       
  1348 		{
       
  1349 		return KErrArgument;
       
  1350 		}
       
  1351 	if (!iBearer)
       
  1352 		{
       
  1353 		return KErrNotReady;
       
  1354 		}
       
  1355 
       
  1356 	// create transaction
       
  1357 	TInt result = KErrNoMemory;
       
  1358 	CSignallingTransaction* transaction = PrepareSignallingCommand(aReceiver, EAvdtpRelease);
       
  1359 	
       
  1360 	if (transaction)
       
  1361 		{
       
  1362 		result = AvdtpSignallingMessageStreamRelease::Command::Format(transaction->Message(), aACPSEID);
       
  1363 		if (result==KErrNone)
       
  1364 			{
       
  1365 			transaction->SetCookie(reinterpret_cast<TAny*>(aACPSEID.Value()));
       
  1366 			result=EnqueueMessage(*transaction);
       
  1367 			}
       
  1368 		if (result!=KErrNone)
       
  1369 			{
       
  1370 			delete transaction;
       
  1371 			}
       
  1372 		}
       
  1373 			
       
  1374 	// create packet
       
  1375 	return result;	
       
  1376 	}
       
  1377 	
       
  1378 TInt CSignallingChannel::SendSetConfiguration(XAvdtpSignalReceiver& aReceiver,
       
  1379 										  TSEID aINTSEID,
       
  1380 										  TSEID aACPSEID,
       
  1381 										  const RBuf8& aConfiguration)
       
  1382 	{
       
  1383 	LOG_FUNC
       
  1384 	if (!aACPSEID.IsValid() || !aINTSEID.IsValid())
       
  1385 		{
       
  1386 		return KErrArgument;
       
  1387 		}
       
  1388 
       
  1389 	if (!iBearer)
       
  1390 		{
       
  1391 		return KErrNotReady;
       
  1392 		}
       
  1393 
       
  1394 	// create transaction
       
  1395 	CSignallingTransaction* transaction = PrepareSignallingCommand(aReceiver, EAvdtpSetConfiguration);
       
  1396 	TInt result = KErrNoMemory;
       
  1397 	
       
  1398 	if (transaction)
       
  1399 		{
       
  1400 		result = AvdtpSignallingMessageSetConfiguration::Command::Format(transaction->Message(), aACPSEID, aINTSEID, aConfiguration);
       
  1401 		if (result==KErrNone)
       
  1402 			{
       
  1403 			transaction->SetCookie(reinterpret_cast<TAny*>(aACPSEID.Value()));
       
  1404 			result=EnqueueMessage(*transaction);
       
  1405 			}
       
  1406 		if (result!=KErrNone)
       
  1407 			{
       
  1408 			delete transaction;
       
  1409 			}
       
  1410 		}
       
  1411 			
       
  1412 	// create packet
       
  1413 	return result;	
       
  1414 	}
       
  1415 
       
  1416 
       
  1417 TInt CSignallingChannel::SendReconfigure(XAvdtpSignalReceiver& aReceiver,
       
  1418 										  TSEID aACPSEID,
       
  1419 										  const RBuf8& aConfiguration)
       
  1420 	{
       
  1421 	LOG_FUNC
       
  1422 	if (!aACPSEID.IsValid())
       
  1423 		{
       
  1424 		return KErrArgument;
       
  1425 		}
       
  1426 	if (!iBearer)
       
  1427 		{
       
  1428 		return KErrNotReady;
       
  1429 		}
       
  1430 
       
  1431 	// create transaction
       
  1432 	CSignallingTransaction* transaction = PrepareSignallingCommand(aReceiver, EAvdtpReconfigure);
       
  1433 	TInt result = KErrNoMemory;
       
  1434 	
       
  1435 	if (transaction)
       
  1436 		{
       
  1437 		result = AvdtpSignallingMessageReconfigure::Command::Format(transaction->Message(), aACPSEID, aConfiguration);
       
  1438 		
       
  1439 		if (result==KErrNone)
       
  1440 			{
       
  1441 			transaction->SetCookie(reinterpret_cast<TAny*>(aACPSEID.Value()));
       
  1442 			result=EnqueueMessage(*transaction);
       
  1443 			}
       
  1444 		
       
  1445 		if (result!=KErrNone)
       
  1446 			{
       
  1447 			delete transaction;
       
  1448 			}
       
  1449 		}
       
  1450 			
       
  1451 	// create packet
       
  1452 	return result;	
       
  1453 	}
       
  1454 
       
  1455 
       
  1456 TInt CSignallingChannel::SendStartStream(XAvdtpSignalReceiver& aReceiver, TSEID aRemoteSEID)
       
  1457 	{
       
  1458 	LOG_FUNC
       
  1459 	if (!iBearer)
       
  1460 		{
       
  1461 		return KErrNotReady;
       
  1462 		}
       
  1463 
       
  1464 	// create transaction
       
  1465 	CSignallingTransaction* transaction = PrepareSignallingCommand(aReceiver, EAvdtpStart);
       
  1466 	TInt result = KErrNoMemory;
       
  1467 	
       
  1468 	if (transaction)
       
  1469 		{
       
  1470 		result = AvdtpSignallingMessageStart::Command::Format(transaction->Message(), aRemoteSEID);
       
  1471 		if (result==KErrNone)
       
  1472 			{
       
  1473 			transaction->SetCookie(reinterpret_cast<TAny*>(aRemoteSEID.Value()));
       
  1474 			result=EnqueueMessage(*transaction);
       
  1475 			}
       
  1476 		if (result!=KErrNone)
       
  1477 			{
       
  1478 			delete transaction;
       
  1479 			}
       
  1480 		}
       
  1481 			
       
  1482 	// create packet
       
  1483 	return result;	
       
  1484 	}
       
  1485 
       
  1486 
       
  1487 TInt CSignallingChannel::SendSuspendStream(XAvdtpSignalReceiver& aReceiver, TSEID aACPSEID)
       
  1488 	{
       
  1489 	LOG_FUNC
       
  1490 	if (!iBearer)
       
  1491 		{
       
  1492 		return KErrNotReady;
       
  1493 		}
       
  1494 
       
  1495 	// create transaction
       
  1496 	CSignallingTransaction* transaction = PrepareSignallingCommand(aReceiver, EAvdtpSuspend);
       
  1497 	TInt result = KErrNoMemory;
       
  1498 	
       
  1499 	if (transaction)
       
  1500 		{
       
  1501 		result=AvdtpSignallingMessageSuspend::Command::Format(transaction->Message(), aACPSEID);
       
  1502 		if (result==KErrNone)
       
  1503 			{
       
  1504 			transaction->SetCookie(reinterpret_cast<TAny*>(aACPSEID.Value()));
       
  1505 			result=EnqueueMessage(*transaction);
       
  1506 			}
       
  1507 		if (result!=KErrNone)
       
  1508 			{
       
  1509 			delete transaction;
       
  1510 			}
       
  1511 		}
       
  1512 			
       
  1513 	// create packet
       
  1514 	return result;	
       
  1515 	}
       
  1516 		
       
  1517 
       
  1518 
       
  1519 TInt CSignallingChannel::SendAbort(XAvdtpSignalReceiver& aReceiver, TSEID aRemoteSEID)
       
  1520 	{
       
  1521 	LOG_FUNC
       
  1522 	if (!aRemoteSEID.IsValid())
       
  1523 		{
       
  1524 		return KErrArgument;
       
  1525 		}
       
  1526 	if (!iBearer)
       
  1527 		{
       
  1528 		return KErrNotReady;
       
  1529 		}
       
  1530 
       
  1531 	CSignallingTransaction*	transaction = PrepareSignallingCommand(aReceiver, EAvdtpAbort);
       
  1532 	TInt result = KErrNoMemory;
       
  1533 	
       
  1534 	if (transaction)
       
  1535 		{
       
  1536 		result = AvdtpSignallingMessageAbort::Command::Format(transaction->Message(), aRemoteSEID);
       
  1537 		if (result==KErrNone)
       
  1538 			{
       
  1539 			//Stuff the seid in the CSignallingTransaction as AVDTP forgets it
       
  1540 			transaction->SetCookie(reinterpret_cast<TAny*>(aRemoteSEID.Value()));
       
  1541 			result=EnqueueMessage(*transaction);
       
  1542 			}
       
  1543 		if (result!=KErrNone)
       
  1544 			{
       
  1545 			delete transaction;
       
  1546 			}
       
  1547 		}
       
  1548 	return result;
       
  1549 	}
       
  1550 	
       
  1551 
       
  1552 TInt CSignallingChannel::SendSecurityControl(XAvdtpSignalReceiver& aReceiver, 
       
  1553 									    TSEID aRemoteSEID,
       
  1554 									    const TDesC8& aSecurityData)
       
  1555 	{
       
  1556 	LOG_FUNC
       
  1557 	if (!aRemoteSEID.IsValid())
       
  1558 		{
       
  1559 		return KErrArgument;
       
  1560 		}
       
  1561 	if (!iBearer)
       
  1562 		{
       
  1563 		return KErrNotReady;
       
  1564 		}
       
  1565 
       
  1566 	CSignallingTransaction* transaction = PrepareSignallingCommand(aReceiver, EAvdtpSecurityControl);
       
  1567 	TInt result = KErrNoMemory;
       
  1568 	
       
  1569 	if (transaction)
       
  1570 		{
       
  1571 		result = AvdtpSignallingMessageSecurityControl::Command::Format(transaction->Message(), aRemoteSEID, aSecurityData);
       
  1572 			
       
  1573 		if (result==KErrNone)
       
  1574 			{
       
  1575 			//Stuff the seid in the CSignallingTransaction as AVDTP spec forgets it
       
  1576 			transaction->SetCookie(reinterpret_cast<TAny*>(aRemoteSEID.Value()));
       
  1577 			result=EnqueueMessage(*transaction);
       
  1578 			}
       
  1579 		if (result!=KErrNone)
       
  1580 			{
       
  1581 			delete transaction;
       
  1582 			}
       
  1583 		}
       
  1584 		
       
  1585 	return result;
       
  1586 	}
       
  1587 	
       
  1588 	
       
  1589 TInt CSignallingChannel::SendStartAccept(TAvdtpTransactionLabel aLabel)
       
  1590 	{
       
  1591 	LOG_FUNC
       
  1592 	return SendAccept(aLabel, EAvdtpStart);
       
  1593 	}
       
  1594 	
       
  1595 TInt CSignallingChannel::SendStartReject(TAvdtpTransactionLabel aLabel,
       
  1596 											TBluetoothAvDistributionError aResult,
       
  1597 											TSEID aBadSEID)
       
  1598 	{
       
  1599 	LOG_FUNC
       
  1600 	TPckg<TUint8> badSEID(aBadSEID.PacketValue());
       
  1601 	return SendReject(aLabel, EAvdtpStart, aResult, &badSEID);
       
  1602 	}
       
  1603 	
       
  1604 TInt CSignallingChannel::SendSuspendAccept(TAvdtpTransactionLabel aLabel)
       
  1605 	{
       
  1606 	LOG_FUNC
       
  1607 	return SendAccept(aLabel, EAvdtpSuspend);
       
  1608 	}
       
  1609 
       
  1610 TInt CSignallingChannel::SendSuspendReject(TAvdtpTransactionLabel aLabel,
       
  1611 											TBluetoothAvDistributionError aResult,
       
  1612 											TSEID aBadSEID)
       
  1613 	{
       
  1614 	LOG_FUNC
       
  1615 	TPckg<TUint8> badSEID(aBadSEID.PacketValue());
       
  1616 	return SendReject(aLabel, EAvdtpSuspend, aResult, &badSEID);
       
  1617 	}
       
  1618 	
       
  1619 /**
       
  1620 Places a message (defined by the transaction) into the outbound queue
       
  1621 At this point the transaction label for commands is determined
       
  1622 Certain commands (such as Abort) may be placed at the head of the queue - it is this function that decides
       
  1623 If a packet is added to the queue, and the bearer is not blocked, then async send callback is kicked
       
  1624 @internalComponent
       
  1625 **/
       
  1626 TInt CSignallingChannel::EnqueueMessage(CSignallingTransaction& aTransaction)
       
  1627 	{
       
  1628 	LOG_FUNC
       
  1629 	// from transaction get the message
       
  1630 	CAvdtpOutboundSignallingMessage& message = aTransaction.Message();
       
  1631 	
       
  1632 	TInt result=KErrNone;
       
  1633 
       
  1634 	//OutBound Signalling message should never be EReserved
       
  1635 	__ASSERT_DEBUG(message.iSignal!= EReserved,Panic(EAvdtpInvalidReservedValueInOutboundSignallingMessage));
       
  1636 	if (message.iMessageType==ECommand)
       
  1637 		{
       
  1638 		result = message.AllocateTransactionLabel(iLabelGen);
       
  1639 		LOG1(_L("Allocated label %d"), message.TransactionLabel());
       
  1640 		}
       
  1641 	
       
  1642 	// remove from draft que, whether error occurred or not
       
  1643 	message.Deque(); 					
       
  1644 	
       
  1645 	if (result==KErrNone)
       
  1646 		{
       
  1647 		// remember the packet label in the transaction object
       
  1648 		aTransaction.SetLabel(message.TransactionLabel());
       
  1649 		// ok to send, figure out priority		
       
  1650 		if (aTransaction.Signal()==EAvdtpAbort)
       
  1651 			{
       
  1652 			// add to outbound queue (high priority)
       
  1653 			iQueuedMessages.AddFirst(message);
       
  1654 			}
       
  1655 		else
       
  1656 			{
       
  1657 			// add to outbound queue	
       
  1658 			iQueuedMessages.AddLast(message);
       
  1659 			}
       
  1660 		// kick off sending
       
  1661 		if (!Blocked())
       
  1662 			{
       
  1663 			StartTryToSendCallback();
       
  1664 			}	
       
  1665 		}
       
  1666 	
       
  1667 	return result;	
       
  1668 	}
       
  1669 
       
  1670 /**
       
  1671 Creates a reponse packet
       
  1672 @param aMessageType whether accept or reject
       
  1673 @param aMessage the signalling response to be put in the packet
       
  1674 @param aLabel the transaction label - typically that used in the inbound command
       
  1675 @internalComponent
       
  1676 **/
       
  1677 CSignallingTransaction* CSignallingChannel::PrepareSignallingResponse(
       
  1678 												TAvdtpMessageType aMessageType,
       
  1679 												TAvdtpMessage aMessage,
       
  1680 												TAvdtpTransactionLabel aLabel)
       
  1681 	{
       
  1682 	LOG_FUNC
       
  1683 	CSignallingTransaction* transaction = PrepareSignallingPacket(aMessageType, aMessage);
       
  1684 	if (transaction)
       
  1685 		{		
       
  1686 		transaction->Message().SetTransactionLabel(aLabel);
       
  1687 		}
       
  1688 	return transaction;
       
  1689 	}
       
  1690 
       
  1691 /**
       
  1692 Creates a command packet and returns a transaction to the caller
       
  1693 @param aReceiver a reference to the caller - used for determining who sent the packet
       
  1694 @param aMessage the signalling command to be put in the packet
       
  1695 @internalComponent
       
  1696 **/
       
  1697 CSignallingTransaction* CSignallingChannel::PrepareSignallingCommand(
       
  1698 												XAvdtpSignalReceiver& aReceiver,
       
  1699 												TAvdtpMessage aMessage)
       
  1700 	{
       
  1701 	LOG_FUNC
       
  1702 	CSignallingTransaction* transaction = PrepareSignallingPacket(ECommand, aMessage);
       
  1703 	if (transaction)
       
  1704 		{
       
  1705 		transaction->SetUser(&aReceiver);
       
  1706 		}
       
  1707 	return transaction;
       
  1708 	}
       
  1709 
       
  1710 
       
  1711 /*
       
  1712 common private method
       
  1713 ownership not returned - transaction remains in signalling channel transaction queue
       
  1714 @internalComponent
       
  1715 */
       
  1716 CSignallingTransaction* CSignallingChannel::PrepareSignallingPacket(TAvdtpMessageType aMessageType,
       
  1717 													TAvdtpMessage aMessage)
       
  1718 	{
       
  1719 	LOG_FUNC
       
  1720 	//todo: KErrInUse if SAP already preparing a message?
       
  1721 	CSignallingTransaction* transaction = CSignallingTransaction::New(*this,
       
  1722 												aMessage,
       
  1723 												aMessageType);
       
  1724 	
       
  1725 	if (transaction)
       
  1726 		{
       
  1727 		// until the packet is finalised, set to be on draft message queue
       
  1728 		iDraftMessages.AddLast(transaction->Message());
       
  1729 		iTransactions.AddLast(*transaction);
       
  1730 	
       
  1731 		// see what post-send action is required (timer etc - see GAVDP spec)
       
  1732 		transaction->SetSentAction();
       
  1733 		}
       
  1734 	return transaction;
       
  1735 	}
       
  1736 
       
  1737 /*
       
  1738 Helper that factors similarity between SetConfiguration and Reconfigure confirms
       
  1739 @param aCategory this may be meaningless if aResult==KErrNone
       
  1740 @internalComponent
       
  1741 */
       
  1742 void CSignallingChannel::ConfigConfirm(TAvdtpTransactionLabel aLabel,
       
  1743 											  TInt aResult,
       
  1744 											  TAvdtpServiceCategory aCategory,
       
  1745 											  TBool aReconfigure)
       
  1746 	{	
       
  1747 	LOG_FUNC
       
  1748 	CSignallingTransaction* transaction = FindTransaction(aLabel);
       
  1749 	RETURN_IF_NO_TRANSACTION(transaction);
       
  1750 	RETURN_IF_SIGNAL_BAD(transaction, aReconfigure ? EAvdtpReconfigure : EAvdtpSetConfiguration);
       
  1751 	
       
  1752 	// get acp seid from cookie
       
  1753 	TSEID seid(reinterpret_cast<TUint>(transaction->Cookie()));
       
  1754 	
       
  1755 	if (!aReconfigure)
       
  1756 		{
       
  1757 		transaction->User()->SetConfigConfirm(aResult, seid, aCategory);
       
  1758    		// return label back to pool
       
  1759    		// for error the setconfigconfirm will destroy the stream which in turn clears the transaction already
       
  1760    		// don't want to try a double clean up - it doesn't work well :-)
       
  1761  		// It is possible that SetConfigConfirm was an error and causes stream release
       
  1762  		// which deletes all the streams transactions - including the one we
       
  1763  		// just found. To guard against that check it exists (again)
       
  1764  		transaction = FindTransaction(aLabel);
       
  1765  		if ((transaction) && (aResult == KErrNone))
       
  1766 			{
       
  1767 			RemoveTransaction(*transaction); //clears RTX timer
       
  1768 			}
       
  1769 		}
       
  1770 	else
       
  1771 		{
       
  1772 		transaction->User()->ReconfigConfirm(aResult, seid, aCategory);
       
  1773 		// return label back to pool
       
  1774 		RemoveTransaction(*transaction); //clears RTX timer
       
  1775 		}	
       
  1776 	}
       
  1777 
       
  1778 
       
  1779 /**
       
  1780 Sends a rejection response
       
  1781 The response can be to any of the signalling messages.
       
  1782 @param aError The error code to place in the packet
       
  1783 @param aRejectionData Trailing extended error information
       
  1784 @internalComponent
       
  1785 */
       
  1786 TInt CSignallingChannel::SendReject(TAvdtpTransactionLabel aLabel,
       
  1787 									TAvdtpMessage aMessage,
       
  1788 									TBluetoothAvDistributionError aError,
       
  1789 									const TDesC8* aRejectionData)
       
  1790 	{
       
  1791 	LOG_FUNC
       
  1792 	__ASSERT_DEBUG(iBearer, Panic(EAvdtpSignallingChannelLogicalChannelNotReady));	
       
  1793 	__ASSERT_DEBUG(!(aMessage==EAvdtpDiscover && aError==EAvdtpBadACPSEID), Panic(EAvdtpBadErrorCase));
       
  1794 	
       
  1795 	if (!iBearer)
       
  1796 		{
       
  1797 		return KErrNotReady;
       
  1798 		}
       
  1799 	
       
  1800 	CSignallingTransaction* transaction = NULL;
       
  1801 	TInt result = KErrNone;
       
  1802 	
       
  1803 	//If its a valid signal identifier then send the 'Reject Response' otherwise send 'General Reject' 
       
  1804 	if (aMessage < EAvdtpLargestValidSignalIndentifier)
       
  1805 		{
       
  1806 		transaction = PrepareSignallingResponse(EResponseReject, aMessage, aLabel);	
       
  1807 		// now need to append more data for certain packets													 
       
  1808 		switch (aMessage)
       
  1809 			{
       
  1810 			// those that just have error code
       
  1811 			case EAvdtpDiscover:
       
  1812 			case EAvdtpGetCapabilities:
       
  1813 			case EAvdtpGetConfiguration:
       
  1814 			case EAvdtpOpen:
       
  1815 			case EAvdtpRelease:
       
  1816 			case EAvdtpSecurityControl:
       
  1817 				{
       
  1818 				__ASSERT_DEBUG(aRejectionData == NULL, Panic(EAvdtpSignallingMessageResponseNoTrailingDataExpected));
       
  1819 				result = transaction ? AvdtpSignallingMessage::Reject::Format(transaction->Message(), aError) : KErrNoMemory;
       
  1820 				}
       
  1821 			break;
       
  1822 			
       
  1823 			// those with extra rejection info
       
  1824 			case EAvdtpSetConfiguration:
       
  1825 			case EAvdtpReconfigure:
       
  1826 			case EAvdtpSuspend:
       
  1827 			case EAvdtpStart:
       
  1828 				{
       
  1829 				__ASSERT_DEBUG(aRejectionData != NULL, Panic(EAvdtpSignallingMessageResponseTrailingDataExpected));
       
  1830 				// need to append data to the packet (SEID etc)
       
  1831 				result = transaction ? AvdtpSignallingMessage::Reject::Format(transaction->Message(), aError, aRejectionData) : KErrNoMemory;
       
  1832 				}
       
  1833 			break;
       
  1834 			default:
       
  1835 				break;			// unsupported, just leave to time out
       
  1836 			}
       
  1837 		}
       
  1838 	else
       
  1839 		{
       
  1840 		__ASSERT_DEBUG(aRejectionData == NULL, Panic(EAvdtpSignallingMessageResponseNoTrailingDataExpected));
       
  1841 		//For General Reject send the invalid signal identifier which is causing this general reject	
       
  1842 		transaction = PrepareSignallingResponse(EGeneralReject, aMessage, aLabel);
       
  1843 		}
       
  1844 
       
  1845 	if (!transaction)
       
  1846 		{
       
  1847 		result = KErrNoMemory;
       
  1848 		}
       
  1849 
       
  1850 	if (result==KErrNone)
       
  1851 		{
       
  1852 		(void)EnqueueMessage(*transaction);
       
  1853 		}
       
  1854 	else
       
  1855 		{
       
  1856 		delete transaction;
       
  1857 		}
       
  1858 	return result;
       
  1859 	}
       
  1860 
       
  1861 TInt CSignallingChannel::SendAccept(TAvdtpTransactionLabel aLabel, TAvdtpMessage aMessage, const TDesC8* aOptionalData /*= NULL*/)
       
  1862 	{
       
  1863 	LOG_FUNC
       
  1864 	if (!iBearer)
       
  1865 		{
       
  1866 		return KErrNotReady;
       
  1867 		}
       
  1868 	
       
  1869 	TInt result = KErrNone;
       
  1870 	CSignallingTransaction*	transaction = PrepareSignallingResponse(EResponseAccept, aMessage, aLabel);
       
  1871 	if (transaction)
       
  1872 		{
       
  1873 		if (aOptionalData)
       
  1874 			{
       
  1875 			// no other messages have data in accept in avdtp 1.0
       
  1876 			__ASSERT_DEBUG(aMessage==EAvdtpSecurityControl, Panic(EAvdtpSignallingMessageResponseNoTrailingDataExpected));
       
  1877 			result = AvdtpSignallingMessageSecurityControl::Accept::Format(transaction->Message(), aOptionalData);
       
  1878 			}
       
  1879 		}
       
  1880 	else
       
  1881 		{
       
  1882 		result = KErrNoMemory;
       
  1883 		}
       
  1884 	
       
  1885 	if (result == KErrNone)
       
  1886 		{
       
  1887 		result=EnqueueMessage(*transaction);
       
  1888 		}
       
  1889 	else
       
  1890 		{
       
  1891 		delete transaction;
       
  1892 		}
       
  1893 		
       
  1894 	return result;	
       
  1895 	}
       
  1896 
       
  1897 TBool CSignallingChannel::CheckSignal(const CSignallingTransaction& aTransaction, TAvdtpMessage aSignal) const
       
  1898 	{
       
  1899 	LOG_FUNC
       
  1900 	return aTransaction.Signal() == aSignal;
       
  1901 	}
       
  1902 
       
  1903