bluetooth/btstack/avdtp/avdtpStreamStates.cpp
changeset 0 29b1cd4cb562
child 8 2b6718f05bdb
child 16 0089b2f7ebd8
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 stream statemachine
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21 */
       
    22 
       
    23 #include <bluetooth/logger.h>
       
    24 #include "avdtpStream.h"
       
    25 #include "avdtp.h"
       
    26 #include "avdtpSignallingChannel.h"
       
    27 #include "avdtpSignallingSession.h"
       
    28 
       
    29 #ifdef __FLOG_ACTIVE
       
    30 _LIT8(KLogComponent, LOG_COMPONENT_AVDTP);
       
    31 #endif
       
    32 
       
    33 #ifdef _DEBUG
       
    34 #define DEBUGPANICINSTATE(aPanic) PanicInState(aPanic)
       
    35 #else
       
    36 #define DEBUGPANICINSTATE(aPanic)
       
    37 #endif
       
    38 
       
    39 // state ctors
       
    40 
       
    41 TAVStreamState::TAVStreamState(CAVStreamStateFactory& aFactory)
       
    42 : iFactory(aFactory)
       
    43 	{
       
    44 	STATENAME("BASE");
       
    45 	}
       
    46 
       
    47 TAVStreamStateIdle::TAVStreamStateIdle(CAVStreamStateFactory& aFactory)
       
    48 : TAVStreamState(aFactory)
       
    49 	{
       
    50 	STATENAME("Idle");
       
    51 	}
       
    52 	
       
    53 TAVStreamStateOpen::TAVStreamStateOpen(CAVStreamStateFactory& aFactory)
       
    54 : TAVStreamStateIdle(aFactory)
       
    55 	{
       
    56 	STATENAME("Open");
       
    57 	}
       
    58 
       
    59 TAVStreamStateReady::TAVStreamStateReady(CAVStreamStateFactory& aFactory)
       
    60 : TAVStreamStateOpen(aFactory)
       
    61 	{
       
    62 	STATENAME("Ready");
       
    63 	}
       
    64 
       
    65 TAVStreamStateWaitForSessions::TAVStreamStateWaitForSessions(CAVStreamStateFactory& aFactory)
       
    66 : TAVStreamStateIdle(aFactory)
       
    67 	{
       
    68 	STATENAME("WaitForSessions");
       
    69 	}
       
    70 
       
    71 TAVStreamStateWaitForSessionsStartReceived::TAVStreamStateWaitForSessionsStartReceived(CAVStreamStateFactory& aFactory)
       
    72 : TAVStreamStateWaitForSessions(aFactory)
       
    73 	{
       
    74 	STATENAME("WaitForSessionsStartReceived");
       
    75 	}
       
    76 
       
    77 TAVStreamStateConfiguring::TAVStreamStateConfiguring(CAVStreamStateFactory& aFactory)
       
    78 : TAVStreamStateIdle(aFactory)
       
    79 	{
       
    80 	STATENAME("Configuring");
       
    81 	}
       
    82 
       
    83 TAVStreamStateConfigured::TAVStreamStateConfigured(CAVStreamStateFactory& aFactory)
       
    84 : TAVStreamStateIdle(aFactory)
       
    85 	{
       
    86 	STATENAME("**Abstract** Configure");
       
    87 	}
       
    88 	
       
    89 TAVStreamStateINTConfigured::TAVStreamStateINTConfigured(CAVStreamStateFactory& aFactory)
       
    90 : TAVStreamStateConfigured(aFactory)
       
    91 	{
       
    92 	STATENAME("INTConfigured");
       
    93 	}
       
    94 	
       
    95 TAVStreamStateACPConfigured::TAVStreamStateACPConfigured(CAVStreamStateFactory& aFactory)
       
    96 : TAVStreamStateConfigured(aFactory)
       
    97 	{
       
    98 	STATENAME("ACPConfigured");
       
    99 	}	
       
   100 
       
   101 TAVStreamStateOpening::TAVStreamStateOpening(CAVStreamStateFactory& aFactory)
       
   102 : TAVStreamStateIdle(aFactory)
       
   103 	{
       
   104 	STATENAME("Opening");
       
   105 	}
       
   106 
       
   107 TAVStreamStateCreatingLogicalChannels::TAVStreamStateCreatingLogicalChannels(CAVStreamStateFactory& aFactory)
       
   108 : TAVStreamStateOpen(aFactory)
       
   109 	{
       
   110 	STATENAME("CreatingLogicalChannels");
       
   111 	}
       
   112 
       
   113 TAVStreamStateReleasing::TAVStreamStateReleasing(CAVStreamStateFactory& aFactory)
       
   114 : TAVStreamStateReady(aFactory)
       
   115 	{
       
   116 	STATENAME("Releasing");
       
   117 	}
       
   118 
       
   119 TAVStreamStateAborting::TAVStreamStateAborting(CAVStreamStateFactory& aFactory)
       
   120 : TAVStreamStateReady(aFactory)
       
   121 	{
       
   122 	STATENAME("Aborting");
       
   123 	}
       
   124 
       
   125 TAVStreamStateStreaming::TAVStreamStateStreaming(CAVStreamStateFactory& aFactory)
       
   126 : TAVStreamStateReady(aFactory)
       
   127 	{
       
   128 	STATENAME("Streaming");
       
   129 	}
       
   130 
       
   131 TAVStreamStateStarting::TAVStreamStateStarting(CAVStreamStateFactory& aFactory)
       
   132 : TAVStreamStateReady(aFactory)
       
   133 	{
       
   134 	STATENAME("Starting");
       
   135 	}
       
   136 
       
   137 TAVStreamStateSuspending::TAVStreamStateSuspending(CAVStreamStateFactory& aFactory)
       
   138 : TAVStreamStateReady(aFactory)
       
   139 	{
       
   140 	STATENAME("Suspending");
       
   141 	}
       
   142 
       
   143 TAVStreamStateWaitingForLogicalChannels::TAVStreamStateWaitingForLogicalChannels(CAVStreamStateFactory& aFactory)
       
   144 : TAVStreamStateOpen(aFactory)
       
   145 	{
       
   146 	STATENAME("WaitingForLogicalChannels");
       
   147 	}
       
   148 
       
   149 TAVStreamStateReconfiguring::TAVStreamStateReconfiguring(CAVStreamStateFactory& aFactory)
       
   150 : TAVStreamStateReady(aFactory)
       
   151 	{
       
   152 	STATENAME("Reconfiguring");
       
   153 	}
       
   154 
       
   155 
       
   156 // default state actions
       
   157 
       
   158 void TAVStreamState::Enter(CAVStream& /*aStream*/) const
       
   159 	{
       
   160 	LOG_FUNC
       
   161 	// do nothing by default
       
   162 	}
       
   163 	
       
   164 void TAVStreamState::Exit(CAVStream& /*aStream*/) const
       
   165 	{
       
   166 	LOG_FUNC
       
   167 	// do nothing by default
       
   168 	}
       
   169 	
       
   170 void TAVStreamState::Release(CAVStream& aStream) const
       
   171 	{
       
   172 	LOG_FUNC
       
   173 	// it already has been Released
       
   174 	aStream.Released();
       
   175 	}
       
   176 
       
   177 void TAVStreamState::AwaitLogicalChannelsL(CAVStream& /*aStream*/) const
       
   178 	{
       
   179 	LOG_FUNC
       
   180 	DEBUGPANICINSTATE(EAvdtpUnexpectedAwaitLogicalChannelsEvent);
       
   181 	}
       
   182 
       
   183 void TAVStreamState::LogicalChannelsAvailable(CAVStream& /*aStream*/, TLogicalChannelFactoryTicket /*aTicket*/, TInt /*aError*/) const
       
   184 	{
       
   185 	LOG_FUNC
       
   186 	DEBUGPANICINSTATE(EAvdtpUnexpectedLogicalChannelsAvailableEvent);
       
   187 	}
       
   188 
       
   189 void TAVStreamState::WatchdogFired(CAVStream& /*aStream*/) const
       
   190 	{
       
   191 	LOG_FUNC
       
   192 	DEBUGPANICINSTATE(EAvdtpUnexpectedWatchdogFiredEvent);
       
   193 	}
       
   194 
       
   195 void TAVStreamState::Configured(CAVStream& /*aStream*/) const
       
   196 	{
       
   197 	LOG_FUNC
       
   198 	DEBUGPANICINSTATE(EAvdtpUnexpectedConfiguredEvent);
       
   199 	}
       
   200 
       
   201 void TAVStreamState::SetConfigurationL(CAVStream& /*aStream*/, 
       
   202 										RBuf8& /*aPacketBuffer*/, CSignallingChannel& /*aSignallingChannel*/,
       
   203 										TBool /*aReportingConfigured*/,
       
   204 								  		TBool /*aRecoveryConfigured*/) const
       
   205 	{
       
   206 	LOG_FUNC
       
   207 	DEBUGPANICINSTATE(EAvdtpUnexpectedSetConfigurationEvent);
       
   208 	User::Leave(KErrNotReady);
       
   209 	}
       
   210 
       
   211 void TAVStreamState::SetConfigConfirm(CAVStream& /*aStream*/, TInt /*aResult*/, 
       
   212 									TSEID /*aRemoteSEID*/, TAvdtpServiceCategory /*aFailedCategory*/) const
       
   213 	{
       
   214 	// throw away
       
   215 	}
       
   216 
       
   217 void TAVStreamState::ReconfigConfirm(CAVStream& /*aStream*/, TInt /*aResult*/, 
       
   218 									TSEID /*aRemoteSEID*/, TAvdtpServiceCategory /*aFailedCategory*/) const
       
   219 	{
       
   220 	LOG_FUNC
       
   221 	// throw away
       
   222 	}
       
   223 		
       
   224 void TAVStreamState::StartConfirm(CAVStream& /*aStream*/, TInt /*aResult*/, TSEID /*aSEID*/) const
       
   225 	{
       
   226 	LOG_FUNC
       
   227 	// throw away
       
   228 	}
       
   229 		
       
   230 void TAVStreamState::AbortConfirm(CAVStream& /*aStream*/, TSEID /*aSEID*/) const
       
   231 	{
       
   232 	LOG_FUNC
       
   233 	// throw away
       
   234 	}
       
   235 	
       
   236 void TAVStreamState::OpenConfirm(CAVStream& /*aStream*/, TInt /*aResult*/, TSEID /*aSEID*/) const
       
   237 	{
       
   238 	LOG_FUNC
       
   239 	// default, throw away weirdo response from remote
       
   240 	}
       
   241 
       
   242 void TAVStreamState::ReleaseConfirm(CAVStream& /*aStream*/, TInt /*aResult*/, TSEID /*aSEID*/) const
       
   243 	{
       
   244 	LOG_FUNC
       
   245 	// throw away
       
   246 	}
       
   247 
       
   248 void TAVStreamState::SuspendConfirm(CAVStream& /*aStream*/, TInt /*aResult*/, TSEID /*aSEID*/) const
       
   249 	{
       
   250 	LOG_FUNC
       
   251 	// throw away
       
   252 	}	
       
   253 	
       
   254 TInt TAVStreamState::AddSession(CAVStream& /*aStream*/, 
       
   255 							TAvdtpTransportSessionType /*aType*/,
       
   256 							CUserPlaneTransportSession& /*aSession*/,
       
   257 							CTransportChannel*& /*aTransportChannel*/) const
       
   258 	{
       
   259 	LOG_FUNC
       
   260 	DEBUGPANICINSTATE(EAvdtpUnexpectedAddSessionEvent);
       
   261 	return KErrNotReady;
       
   262 	}
       
   263 								
       
   264 void TAVStreamState::DropSession(CAVStream& /*aStream*/, TAvdtpTransportSessionType /*aType*/,
       
   265 							 CUserPlaneTransportSession& /*aSession*/) const
       
   266 	{
       
   267 	LOG_FUNC
       
   268 	DEBUGPANICINSTATE(EAvdtpUnexpectedDropSession);
       
   269 	}
       
   270 
       
   271 TInt TAVStreamState::StartReceived(CAVStream& /*aStream*/) const
       
   272 	{
       
   273 	LOG_FUNC
       
   274 	return KErrNotReady;
       
   275 	}
       
   276 
       
   277 TBool TAVStreamState::IsStreaming(const CAVStream& /*aStream*/) const
       
   278 	{
       
   279 	LOG_FUNC
       
   280 	return EFalse;
       
   281 	}
       
   282 
       
   283 TInt TAVStreamState::Start(CAVStream& /*aStream*/) const
       
   284 	{
       
   285 	LOG_FUNC
       
   286 	return KErrNotReady;
       
   287 	}
       
   288 	
       
   289 TInt TAVStreamState::Suspend(CAVStream& /*aStream*/) const
       
   290 	{
       
   291 	LOG_FUNC
       
   292 	return KErrNotReady;
       
   293 	}
       
   294 
       
   295 void TAVStreamState::Started(CAVStream& /*aStream*/) const
       
   296 	{
       
   297 	LOG_FUNC
       
   298 	// signalling session should have sanity checked with previous StartReceived()
       
   299 	DEBUGPANICINSTATE(EAvdtpUnexpectedStartedEvent);
       
   300 	}
       
   301 	
       
   302 void TAVStreamState::Suspended(CAVStream& /*aStream*/) const
       
   303 	{
       
   304 	LOG_FUNC
       
   305 	// signalling session should have sanity checked with previous IsStreaming
       
   306 	DEBUGPANICINSTATE(EAvdtpUnexpectedSuspendedEvent);
       
   307 	}
       
   308 
       
   309 void TAVStreamState::ChangeState(CAVStream& aContext, CAVStreamStateFactory::TAVStreamStates aState) const
       
   310 	{
       
   311 	LOG_FUNC
       
   312 	aContext.iState->Exit(aContext);
       
   313 
       
   314 #ifdef __FLOG_ACTIVE
       
   315 	const TAVStreamState* const newState=&iFactory.GetState(aState);
       
   316 	LOG2(_L("Stream: State %S -> %S"), &aContext.iState->iName, &newState->iName);
       
   317 #endif //__FLOG_ACTIVE
       
   318 
       
   319 	aContext.iState=&iFactory.GetState(aState);
       
   320 	aContext.iState->Enter(aContext);
       
   321 	}
       
   322 
       
   323 void TAVStreamState::PanicInState(TAvdtpPanic aPanic) const
       
   324 	{
       
   325 	Panic(aPanic, iFactory.StateIndex(this));
       
   326 	}
       
   327 
       
   328 
       
   329 // derived states and state changes
       
   330 
       
   331 void TAVStreamStateIdle::Configured(CAVStream& aStream) const
       
   332 	{
       
   333 	// ah - going ACP
       
   334 	ChangeState(aStream, CAVStreamStateFactory::EStreamStateACPConfigured);
       
   335 	}
       
   336 	
       
   337 void TAVStreamStateIdle::SetConfigurationL(CAVStream& aStream, 
       
   338 											RBuf8& aPacketBuffer,
       
   339 											CSignallingChannel& aSignallingChannel,
       
   340 										  	TBool aReportingConfigured,
       
   341 								  			TBool aRecoveryConfigured) const
       
   342 	{
       
   343 	LOG_FUNC
       
   344 // An INT procedure to add in extra options the stack wishes to do, regardless of client
       
   345 // At present this is limited to mux&frag - which we do if local and remote have
       
   346 // the *capability* to do so, even if the proposed *configuration* doesnt mention it
       
   347 	
       
   348 // AVDTP is daft, so have to arrange for IDs before objects exist if muxing used
       
   349 
       
   350 // we also need to base this on the number of sessions we know we're going to run	
       
   351 // see 8.19.8
       
   352 // 5.4.6 allow fors no reporting session so it's not *obvious* when the 2nd element is
       
   353 // bit like not obvious what the 2nd L2cap channel will bear
       
   354 
       
   355 // further, if we're muxing, we need to see what optional sessions are proposed
       
   356 // in the configuration to see what to configure in the mux capability
       
   357 	
       
   358 	TBool canMux;
       
   359 	TBool canFrag;
       
   360 	aStream.CanMuxFrag(canMux, canFrag);
       
   361 
       
   362 	TInt err = KErrNone;
       
   363 	
       
   364 	if (canMux)
       
   365 		{
       
   366 		// muxing is awkward - must identify the TCs and TSs that are going to be used NOW
       
   367 		TAvdtpMultiplexingCapability* mux = aStream.CreateMuxCapabilityL(aReportingConfigured, aRecoveryConfigured, aSignallingChannel);
       
   368 
       
   369 		// ok to create packetstructure - only exchange IDs if do mux
       
   370 		err = mux->AsProtocol(aPacketBuffer);
       
   371 		}
       
   372 		
       
   373 	if (!err)
       
   374 		{
       
   375 		// First check that we are in a state to send a set configuration command as
       
   376 		// we don't want to send one unless we can commit the pending configuration
       
   377 		err = aStream.iLocalSEP->CheckConfigurationState(EFalse);
       
   378  
       
   379  		if (!err)
       
   380 			{
       
   381 			err = aSignallingChannel.SendSetConfiguration(aStream, 
       
   382 								aStream.LocalSEID(), aStream.RemoteSEID(), aPacketBuffer);
       
   383 			if (!err)
       
   384 				{
       
   385 				// tell SEP
       
   386 				err = aStream.iLocalSEP->SetPendingConfiguration(aPacketBuffer, EFalse); //takes ownership of RBuf
       
   387 			
       
   388 				// we should not get an error here as we called CheckConfigurationState above
       
   389 				__ASSERT_DEBUG(!err, PanicInState(EAvdtpInconsistentPendingConfigurationState));
       
   390 
       
   391 				if (!err)
       
   392 					{
       
   393 					aPacketBuffer.Assign(NULL); // since ownership transfer succeeded
       
   394 					ChangeState(aStream, CAVStreamStateFactory::EStreamStateConfiguring);
       
   395 					}
       
   396 				}
       
   397 			}
       
   398 		}
       
   399 
       
   400 	if (err)
       
   401 		{
       
   402 		// clean up and don't bother proceeding
       
   403 		aStream.DeallocateUnclaimedTransportSessionIDs();
       
   404 		User::Leave(err);
       
   405 		}
       
   406 	}
       
   407 
       
   408 void TAVStreamStateIdle::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
   409 	{
       
   410 	LOG_FUNC
       
   411 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
   412 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
   413 	}
       
   414 		
       
   415 
       
   416 void TAVStreamStateConfiguring::SetConfigConfirm(CAVStream& aStream, TInt aResult, 
       
   417 												TSEID /*aRemoteSEID*/, TAvdtpServiceCategory aFailedCategory) const
       
   418 	{
       
   419 	LOG_FUNC
       
   420 	//update our state before telling others
       
   421 	TRAPD(res, aStream.iLocalSEP->CommitPendingConfigurationL(aResult==KErrNone, EFalse));
       
   422 	
       
   423 	if (res!=KErrNone)
       
   424 		{
       
   425 		aResult = res;
       
   426 		}
       
   427 		
       
   428 	if (aResult==KErrNone)
       
   429 		{
       
   430 		TBool rp = aStream.CheckConfigured(EServiceCategoryReporting);
       
   431 		TBool rc = aStream.CheckConfigured(EServiceCategoryRecovery);
       
   432 		aStream.iNumSessionsRequired = AvdtpInternalUtils::NumberOfTransportObjects(rp, rc);
       
   433 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateINTConfigured);			
       
   434 		}
       
   435 
       
   436 	aStream.iStreamNotify.StreamConfigured(aStream.LocalSEID(), aResult, aFailedCategory);
       
   437 
       
   438 	if (aResult!=KErrNone)
       
   439 		{
       
   440 		// remove the stream as the configure failed the stream is invalid
       
   441 		aStream.Released();	// deletes stream
       
   442 		}
       
   443 	}
       
   444 
       
   445 void TAVStreamStateConfiguring::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
   446 	{
       
   447 	LOG_FUNC
       
   448 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
   449 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
   450 	}
       
   451 
       
   452 void TAVStreamStateConfigured::Release(CAVStream& aStream) const
       
   453 	{
       
   454 	// in this state to Release a stream object (cos it errored say)
       
   455 	// needs us to send an Abort rather than a Close to remote
       
   456 	// this is because the remote will need to mark its SEP as not in use,
       
   457 	// but we haven't yet sent an Open.
       
   458 	LOG_FUNC
       
   459 	CSignallingChannel* sigch = aStream.iProtocol.FindSignallingChannel(aStream.iRemoteAddress.BTAddr());
       
   460 	
       
   461 	if (sigch)
       
   462 		{
       
   463 		TInt err = sigch->SendAbort(aStream, aStream.RemoteSEID());
       
   464 		if (err==KErrNone)
       
   465 			{
       
   466 			ChangeState(aStream, CAVStreamStateFactory::EStreamStateAborting);
       
   467 			}
       
   468 		else
       
   469 			{
       
   470 			// just have to die
       
   471 			aStream.Released();
       
   472 			}
       
   473 		}	
       
   474 	}
       
   475 
       
   476 void TAVStreamStateConfigured::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
   477 	{
       
   478 	LOG_FUNC
       
   479 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
   480 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
   481 	}
       
   482 
       
   483 /**
       
   484 An INT primitive
       
   485 A session is adding itself to the stream.
       
   486 Record its details and find a channel for it to use.
       
   487 Record the binding between session and channel.
       
   488 Once all the required sessions are added the stream tries to open the remote
       
   489 */
       
   490 TInt TAVStreamStateINTConfigured::AddSession(CAVStream& aStream,
       
   491 									TAvdtpTransportSessionType aType,
       
   492 						   			CUserPlaneTransportSession& aSession,
       
   493 						   			CTransportChannel*& aChannel) const
       
   494 	{
       
   495 	LOG_FUNC
       
   496 	TInt ret = KErrNone;
       
   497 	// check GAVDP isn't being naughty and asking for an unconfigured session
       
   498 	if ((aType==EReporting && !aStream.CheckConfigured(EServiceCategoryReporting))
       
   499 		|| (aType==ERecovery && !aStream.CheckConfigured(EServiceCategoryRecovery)))
       
   500 		{
       
   501 		// gavdp is trying to use a session it has never configured
       
   502 		ret = KErrNotSupported;
       
   503 		}
       
   504 	
       
   505 	if (ret == KErrNone)
       
   506 		{
       
   507 		TBool useMux;
       
   508 		TBool useFrag;	//ignored
       
   509 		aStream.CanMuxFrag(useMux, useFrag);
       
   510 		
       
   511 		aChannel = aStream.iProtocol.GetTransportChannel(aStream.iRemoteAddress, useMux);
       
   512 		
       
   513 		if (aChannel)
       
   514 			{
       
   515 			// bind session to channel
       
   516 			ret = aChannel->AttachTransportSession(aSession, aType);
       
   517 			if (ret==KErrNone)
       
   518 				{
       
   519 				// keep a copy of this binding
       
   520 				TTransportBinding binding;
       
   521 				binding.iSession = &aSession;
       
   522 				binding.iChannel = aChannel;
       
   523 				
       
   524 				// keep object bindings
       
   525 				TTransportBinding* b = NULL;
       
   526 				
       
   527 				switch (aType)
       
   528 					{
       
   529 					case EMedia:
       
   530 						b = &aStream.iMediaBinding;
       
   531 						break;
       
   532 					case EReporting:
       
   533 						b = &aStream.iReportingBinding;
       
   534 						break;
       
   535 					case ERecovery:
       
   536 						b = &aStream.iRecoveryBinding;
       
   537 						break;
       
   538 					}
       
   539 		
       
   540 				__ASSERT_DEBUG(b, PanicInState(EAvdtpBadSessionAttachingToStream));
       
   541 				// remember binding
       
   542 				*b = binding;
       
   543 				}
       
   544 			TryToOpen(aStream);
       
   545 			}
       
   546 		else
       
   547 			{
       
   548 			ret = KErrNotReady; // TC went down...
       
   549 			}
       
   550 		}
       
   551 	return ret;
       
   552 	}
       
   553 
       
   554 /**
       
   555 One of the sessions in the stream is dropping from the stream.
       
   556 At this point the stream hadn't been opened, so don't Release stream
       
   557 Just cancel oustanding logical channel factory request
       
   558 */	
       
   559 void TAVStreamStateINTConfigured::DropSession(CAVStream& aStream, TAvdtpTransportSessionType /*aType*/, CUserPlaneTransportSession& /*aSession*/) const
       
   560 	{
       
   561 	LOG_FUNC
       
   562 	aStream.iProtocol.LogicalChannelFactory().Cancel(aStream.iFactoryJob);
       
   563 	}
       
   564 
       
   565 void TAVStreamStateINTConfigured::TryToOpen(CAVStream& aStream) const
       
   566 	{
       
   567 	LOG_FUNC
       
   568 	// check how many sessions we think we need
       
   569 	// if all have added to us then we find signalling ch and issue an open
       
   570 	
       
   571 	TInt numSessionsBound = (aStream.iMediaBinding.iSession ?1:0) +
       
   572 							(aStream.iReportingBinding.iSession ?1:0) +
       
   573 							(aStream.iRecoveryBinding.iSession ?1:0);
       
   574 
       
   575 
       
   576 	__ASSERT_DEBUG(numSessionsBound>=1 && numSessionsBound<=3, PanicInState(EAVDTPBadSessionCount));
       
   577 	if (numSessionsBound == aStream.iNumSessionsRequired)
       
   578 		{
       
   579 		// GO!
       
   580 		CSignallingChannel* sigch = aStream.iProtocol.FindSignallingChannel(aStream.DeviceAddress());
       
   581 		TInt err = sigch ? sigch->SendOpenStream(aStream, aStream.RemoteSEID()) : KErrNotReady;
       
   582 		if (err==KErrNone)
       
   583 			{
       
   584 			// all sessions joined - so Open
       
   585 			ChangeState(aStream, CAVStreamStateFactory::EStreamStateOpening);
       
   586 			}
       
   587 		else
       
   588 			{
       
   589 			aStream.NotifyUserPlaneTransportSessionsError(NULL, err);
       
   590 			// no need to release stream - leave gavdp client to decide
       
   591 			}
       
   592 		}
       
   593 	}
       
   594 
       
   595 void TAVStreamStateINTConfigured::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
   596 	{
       
   597 	LOG_FUNC
       
   598 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
   599 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
   600 	}
       
   601 
       
   602 void TAVStreamStateINTConfigured::SetConfigurationL(CAVStream& /*aStream*/, 
       
   603 									RBuf8& /*aPacketBuffer*/,
       
   604 									CSignallingChannel& /*aSignallingChannel*/,
       
   605 									TBool /*aReportingConfigured*/,
       
   606 									TBool /*aRecoveryConfigured*/) const
       
   607 	{
       
   608 	// GAVDP spec v1.1 sect4.1.5 forbids this - must be at OPEN state before reconfiguring
       
   609 	// in our implementation this means we need to be in Ready state (thus have transport channels)
       
   610 	// yes it is weird...
       
   611 	User::Leave(KErrAvdtpInvalidStateForReconfigure);
       
   612 	}
       
   613 
       
   614 /**
       
   615 ACP configured, now need to await the Open
       
   616 */
       
   617 	
       
   618 void TAVStreamStateACPConfigured::AwaitLogicalChannelsL(CAVStream& aStream) const
       
   619 	{
       
   620 	LOG_FUNC
       
   621 	const TBool requireReporting = aStream.CheckConfigured(EServiceCategoryReporting);
       
   622 	const TBool requireRecovery = aStream.CheckConfigured(EServiceCategoryRecovery);
       
   623 	
       
   624 	TAvdtpMultiplexingCapability* const muxCap = static_cast<TAvdtpMultiplexingCapability*>
       
   625 										(aStream.iLocalSEP->Configuration()[EServiceCategoryMultiplexing]);
       
   626 	
       
   627 	if (muxCap)
       
   628 		{
       
   629 		TAvdtpMultiplexingCapabilityHelper helper(*muxCap, requireReporting, requireRecovery);
       
   630 		DoAwaitMuxedChannelsL(aStream, helper, requireReporting, requireRecovery);
       
   631 		}
       
   632 	else
       
   633 		{
       
   634 		DoAwaitDirectChannelsL(aStream, requireReporting, requireRecovery);
       
   635 		}
       
   636 	}
       
   637 	
       
   638 	
       
   639 void TAVStreamStateACPConfigured::DoAwaitMuxedChannelsL(CAVStream& aStream,
       
   640 												TAvdtpMultiplexingCapabilityHelper& aHelper,
       
   641 												TBool aRequireReporting,
       
   642 												TBool aRequireRecovery) const
       
   643 	{
       
   644 	LOG_FUNC
       
   645 	TInt numExtraLogicalChannelsNeeded=0;
       
   646 	TAvdtpSockAddr address = aStream.iRemoteAddress;
       
   647 	// get TCIDs for the sessions in the mux record
       
   648 	// this will indicate the TCIDs that the INT has proposed
       
   649 	
       
   650 	// we look for mux channels with any TCIDs proposed
       
   651 	// and reduce thus reduce the number of TCs we expect
       
   652 	CTransportChannel** tcPtr = &aStream.iMediaBinding.iChannel;
       
   653 	
       
   654 	*tcPtr = aStream.iProtocol.FindMuxChannel(aHelper.MediaCID());
       
   655 	if (!*tcPtr)
       
   656 		{
       
   657 		address.SetSession(EMedia);	
       
   658 		*tcPtr = aStream.iProtocol.GetTransportChannel(address, ETrue, aHelper.MediaCID());
       
   659 		User::LeaveIfNull(*tcPtr);
       
   660 		numExtraLogicalChannelsNeeded++;
       
   661 		}
       
   662 
       
   663 	tcPtr = &aStream.iReportingBinding.iChannel;
       
   664 	if (aRequireReporting)
       
   665 		{
       
   666 		__ASSERT_DEBUG(aHelper.ReportingCID() != KInvalidTCID, PanicInState(EAVDTPBadMuxConfiguration));
       
   667 		*tcPtr = aStream.iProtocol.FindMuxChannel(aHelper.ReportingCID());
       
   668 		if (!*tcPtr)
       
   669 			{
       
   670 			// might need a new channel
       
   671 			if (aHelper.ReportingCID()!=aHelper.MediaCID())
       
   672 				{
       
   673 				address.SetSession(EReporting);	
       
   674 				*tcPtr = aStream.iProtocol.GetTransportChannel(address, ETrue, aHelper.ReportingCID());
       
   675 				User::LeaveIfNull(*tcPtr);
       
   676 				numExtraLogicalChannelsNeeded++;
       
   677 				}
       
   678 			// else remote has proposed putting reporting in same channel as media
       
   679 			}
       
   680 		}
       
   681 			
       
   682 	tcPtr = &aStream.iRecoveryBinding.iChannel;
       
   683 	if (aRequireRecovery)
       
   684 		{
       
   685 		__ASSERT_DEBUG(aHelper.RecoveryCID() != KInvalidTCID, PanicInState(EAVDTPBadMuxConfiguration));
       
   686 		*tcPtr = aStream.iProtocol.FindMuxChannel(aHelper.RecoveryCID());
       
   687 		if (!*tcPtr)
       
   688 			{
       
   689 			// might need a new channel
       
   690 			if (aHelper.RecoveryCID()!=aHelper.MediaCID() && aHelper.RecoveryCID()!=aHelper.ReportingCID())
       
   691 				{
       
   692 				address.SetSession(ERecovery);	
       
   693 				*tcPtr = aStream.iProtocol.GetTransportChannel(address, ETrue, aHelper.RecoveryCID());
       
   694 				User::LeaveIfNull(*tcPtr);
       
   695 				numExtraLogicalChannelsNeeded++;
       
   696 				}
       
   697 			else if (aHelper.RecoveryCID()==aHelper.MediaCID())
       
   698 				{
       
   699 				__DEBUGGER();
       
   700 				User::Leave(KErrCorrupt); // remote has contravened spec
       
   701 				}
       
   702 			}
       
   703 		}
       
   704 
       
   705 	if (!numExtraLogicalChannelsNeeded)
       
   706 		{
       
   707 		// everything we need is already here, kick state machine and wait for sessions to attach
       
   708 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateWaitForSessions);
       
   709 		// tell signalling session
       
   710 		aStream.iStreamNotify.StreamAccepted(aStream.LocalSEID(),
       
   711 												aStream.RemoteSEID(), aRequireReporting, aRequireRecovery);
       
   712 		}
       
   713 	else
       
   714 		{
       
   715 		// TCs were created above, now wait for appropriate logical channels	
       
   716 		aStream.iFactoryJob = aStream.iProtocol.LogicalChannelFactory().
       
   717 												ExpectSessionLogicalChannelsL(aStream,
       
   718 												numExtraLogicalChannelsNeeded);
       
   719 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateWaitingForLogicalChannels);
       
   720 		}
       
   721 	}
       
   722 	
       
   723 	
       
   724 void TAVStreamStateACPConfigured::DoAwaitDirectChannelsL(CAVStream& aStream,
       
   725 												TBool aRequireReporting,
       
   726 												TBool aRequireRecovery) const
       
   727 	{
       
   728 	LOG_FUNC
       
   729 	// create the necessary Transport Channels ready for the logical channels
       
   730 	// assume all inbound TCs are mux -our seps always do muxing, and allows for "upgrades"
       
   731 	// if others SEPs want to add sessions to them later
       
   732 	
       
   733 	TInt numExtraLogicalChannelsNeeded = 0;
       
   734 	TAvdtpSockAddr address = aStream.iRemoteAddress;
       
   735 	address.SetSession(EMedia);	
       
   736 
       
   737 #ifdef __SYMBIAN_AVDTP_HIDE_MUX 
       
   738     #define CAN_BECOME_MUX EFalse
       
   739 #else
       
   740 #pragma message("Not sure if this true - remember morgan, cannot upgrade as dont know which "direct" channel has which TCID")
       
   741     #define CAN_BECOME_MUX ETrue
       
   742 #endif   
       
   743 
       
   744 	aStream.iMediaBinding.iChannel = aStream.iProtocol.GetTransportChannel(address, CAN_BECOME_MUX);
       
   745 	User::LeaveIfNull(aStream.iMediaBinding.iChannel);
       
   746 	numExtraLogicalChannelsNeeded++;
       
   747 
       
   748 	if (aRequireReporting)
       
   749 		{
       
   750 		address.SetSession(EReporting);	
       
   751 		aStream.iReportingBinding.iChannel = aStream.iProtocol.GetTransportChannel(address, CAN_BECOME_MUX);
       
   752 		User::LeaveIfNull(aStream.iReportingBinding.iChannel);
       
   753 		numExtraLogicalChannelsNeeded++;
       
   754 		}
       
   755 	
       
   756 	if (aRequireRecovery)
       
   757 		{
       
   758 		address.SetSession(ERecovery);	
       
   759 		aStream.iRecoveryBinding.iChannel = aStream.iProtocol.GetTransportChannel(address, CAN_BECOME_MUX);
       
   760 		User::LeaveIfNull(aStream.iRecoveryBinding.iChannel);
       
   761 		numExtraLogicalChannelsNeeded++;
       
   762 		}
       
   763 
       
   764   	LOG1(_L8("Awaiting %d logical channels"), numExtraLogicalChannelsNeeded);
       
   765   
       
   766 	// wait for appropriate logical channels	
       
   767 	aStream.iFactoryJob = aStream.iProtocol.LogicalChannelFactory().
       
   768 												ExpectSessionLogicalChannelsL(aStream,
       
   769 												numExtraLogicalChannelsNeeded);
       
   770 
       
   771 	ChangeState(aStream, CAVStreamStateFactory::EStreamStateWaitingForLogicalChannels);
       
   772 	}
       
   773 	
       
   774 TInt TAVStreamStateACPConfigured::AddSession(CAVStream& /*aStream*/, 
       
   775 							TAvdtpTransportSessionType /*aType*/,
       
   776 							CUserPlaneTransportSession& /*aSession*/,
       
   777 							CTransportChannel*& /*aTransportChannel*/) const
       
   778 	{
       
   779 	LOG_FUNC
       
   780 	return KErrNotReady;
       
   781 	}
       
   782 
       
   783 void TAVStreamStateACPConfigured::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
   784 	{
       
   785 	LOG_FUNC
       
   786 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
   787 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
   788 	}
       
   789 
       
   790 
       
   791 void TAVStreamStateOpen::DropSession(CAVStream& aStream, TAvdtpTransportSessionType /*aType*/, CUserPlaneTransportSession& /*aSession*/) const
       
   792 	{	
       
   793 	LOG_FUNC
       
   794 	// if any session in the stream is shutdown
       
   795 	// we invalidate the stream, and thus send a Release
       
   796 			
       
   797 	// we leave the GC to actually shutdown the session saps
       
   798 	DoRelease(aStream);	
       
   799 	// leave unbinding transport objects until ReleaseConfirm	
       
   800 	}
       
   801 
       
   802 void TAVStreamStateOpen::Release(CAVStream& aStream) const
       
   803 	{
       
   804 	LOG_FUNC
       
   805 	// we need to Release this as the object is going
       
   806 	DoRelease(aStream);
       
   807 	}
       
   808 
       
   809 void TAVStreamStateOpen::DoRelease(CAVStream& aStream) const
       
   810 	{
       
   811 	LOG_FUNC
       
   812 	CSignallingChannel* sigch = aStream.iProtocol.FindSignallingChannel(aStream.iRemoteAddress.BTAddr());
       
   813 	
       
   814 	if (sigch)
       
   815 		{
       
   816 		sigch->SendRelease(aStream, aStream.RemoteSEID());
       
   817 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateReleasing);
       
   818 		}
       
   819 	}
       
   820 
       
   821 void TAVStreamStateOpen::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
   822 	{
       
   823 	LOG_FUNC
       
   824 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
   825 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
   826 	}
       
   827 
       
   828 TInt TAVStreamStateReady::AddSession(CAVStream& /*aStream*/, 
       
   829 		TAvdtpTransportSessionType /*aType*/,
       
   830 		CUserPlaneTransportSession& /*aSession*/,
       
   831 		CTransportChannel*& /*aTransportChannel*/) const
       
   832 {
       
   833 LOG_FUNC
       
   834 #ifdef _DEBUG
       
   835 return KErrPanicAvdtpOpenInBadState;
       
   836 #else
       
   837 return KErrNotReady;
       
   838 #endif
       
   839 }
       
   840 
       
   841 void TAVStreamStateReady::SetConfigurationL(CAVStream& aStream, 
       
   842 									RBuf8& aPacketBuffer,
       
   843 									CSignallingChannel& aSignallingChannel,
       
   844 									TBool __DEBUG_ONLY(aReportingConfigured),
       
   845 									TBool __DEBUG_ONLY(aRecoveryConfigured)) const
       
   846 	{
       
   847 	// this is a Reconfigure - see GAVDP spec
       
   848 	LOG_FUNC
       
   849 	__ASSERT_DEBUG(!aReportingConfigured && !aRecoveryConfigured, PanicInState(EAvdtpReconfigurationCapabilitiesNotChecked));
       
   850 
       
   851 	// First check that we are in a state to send a reconfigure command as
       
   852 	// we don't want to send one unless we can commit the pending configuration
       
   853 	TInt err = aStream.iLocalSEP->CheckConfigurationState(ETrue);
       
   854 	
       
   855 	if (!err)
       
   856 		{
       
   857 		err = aSignallingChannel.SendReconfigure(aStream, aStream.RemoteSEID(), aPacketBuffer);
       
   858 		
       
   859 		if (!err)
       
   860 			{
       
   861 			// tell SEP
       
   862 			err = aStream.iLocalSEP->SetPendingConfiguration(aPacketBuffer, ETrue); //takes ownership of RBuf
       
   863 
       
   864 			// we should not get an error here as we called CheckConfigurationState above
       
   865 			__ASSERT_DEBUG(!err, PanicInState(EAvdtpInconsistentPendingReconfigurationState));
       
   866 
       
   867 			if (!err)
       
   868 				{
       
   869 				aPacketBuffer.Assign(NULL); // since ownership transfer succeeded
       
   870 				// release configuration buffer as we own it in this state
       
   871 				ChangeState(aStream, CAVStreamStateFactory::EStreamStateReconfiguring);
       
   872 				}
       
   873 			}
       
   874 		}
       
   875 		
       
   876 	User::LeaveIfError(err);
       
   877 	}
       
   878 
       
   879 /**
       
   880  * Before the OpenStream returns, gavdp might get Cancel()ed. At this point we have an outstanding
       
   881  * request on the signalling channel. We can't issue a cancel on the individual request, and we
       
   882  * can't close sigch down as it's shared, but there should only be one outstanding for this stream,
       
   883  * so we can cancel all transactions for it.
       
   884  */
       
   885 void TAVStreamStateOpening::DropSession(CAVStream& aStream, TAvdtpTransportSessionType /*aType*/,
       
   886 		 CUserPlaneTransportSession& /*aSession*/) const
       
   887 	{
       
   888 		LOG_FUNC
       
   889 		CSignallingChannel* sigch = aStream.iProtocol.FindSignallingChannel(aStream.DeviceAddress());
       
   890 		__ASSERT_DEBUG(sigch, PanicInState(EAvdtpSignallingChannelShouldExist));
       
   891 		sigch->CancelTransactions(aStream);
       
   892 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateIdle);
       
   893 	}
       
   894 
       
   895 void TAVStreamStateOpening::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
   896 	{
       
   897 	LOG_FUNC
       
   898 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
   899 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
   900 	}
       
   901 
       
   902 void TAVStreamStateOpening::OpenConfirm(CAVStream& aStream, TInt aResult, TSEID __DEBUG_ONLY(aRemoteSEID)) const
       
   903 	{
       
   904 	LOG_FUNC
       
   905 	// good!
       
   906 	__ASSERT_DEBUG(aRemoteSEID == aStream.RemoteSEID(), PanicInState(EAvdtpConfirmAddressedToWrongRequester));
       
   907 	TInt ret = KErrNone;
       
   908 	
       
   909 // now we kick TCs into life
       
   910 	if (aResult)
       
   911 		{
       
   912 		// can return to Idle, user could try this operation again
       
   913 		// the way Open works means we have transport sessions interested in result of this
       
   914 		// they need to tell their sockets that their connects failed
       
   915 		
       
   916 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateIdle);
       
   917 		
       
   918 		// no need to tell signalling session as Opening is not available to RGavdp
       
   919 		// Opening is performed when the necessary sockets are created and connected in a stream
       
   920 		aStream.NotifyUserPlaneTransportSessionsError(NULL, aResult);
       
   921 		}
       
   922 	else
       
   923 		{
       
   924 		// create a job - see what logical channels need creating
       
   925 		TInt numLogicalChannelsRequired =
       
   926 				aStream.iMediaBinding.iChannel->IsConnected() ? 0 : 1;
       
   927 		
       
   928 		if (aStream.iReportingBinding.iChannel)
       
   929 			{
       
   930 			// a reporting transport channel is required - but is it available?
       
   931 			if (!aStream.iReportingBinding.iChannel->IsConnected())
       
   932 				{
       
   933 				// this is required, so add into job
       
   934 				numLogicalChannelsRequired++;
       
   935 				}
       
   936 			}
       
   937 			
       
   938 		if (aStream.iRecoveryBinding.iChannel)
       
   939 			{
       
   940 			// a recovery transport channel is required - but is it available?
       
   941 			if (!aStream.iRecoveryBinding.iChannel->IsConnected())
       
   942 				{
       
   943 				// this is required, so add into job
       
   944 				numLogicalChannelsRequired++;
       
   945 				}
       
   946 			}
       
   947 		
       
   948 		if (numLogicalChannelsRequired)
       
   949 			{
       
   950 			// if either required, kick off request...
       
   951 			ChangeState(aStream, CAVStreamStateFactory::EStreamStateCreatingLogicalChannels);
       
   952 			TLogicalChannelFactoryTicket ticket;
       
   953 			TRAP(ret, ticket=aStream.iProtocol.LogicalChannelFactory().CreateSessionLogicalChannelsL(
       
   954 												aStream.iRemoteAddress.BTAddr(),
       
   955 										  		aStream, numLogicalChannelsRequired));
       
   956 			if (ret==KErrNone)
       
   957 				{
       
   958 				aStream.iFactoryJob = ticket; // record this, so we can cancel if needed
       
   959 				}
       
   960 			else
       
   961 				{
       
   962 				// stay in same state
       
   963 				ChangeState(aStream, CAVStreamStateFactory::EStreamStateOpening);
       
   964 				}
       
   965 			}		
       
   966 		else
       
   967 			{
       
   968 			ChangeState(aStream, CAVStreamStateFactory::EStreamStateOpen);
       
   969 			// all TCs appear to be available without creating new ones
       
   970 			aStream.TransportChannelsReady();
       
   971 			}
       
   972 		}
       
   973 	}
       
   974 
       
   975 
       
   976 TInt TAVStreamStateReady::StartReceived(CAVStream& aStream) const
       
   977 	{
       
   978 	LOG_FUNC
       
   979 	
       
   980 	aStream.ReadyForStartIndication();
       
   981 	
       
   982 	return KErrNone;
       
   983 	}
       
   984 
       
   985 TInt TAVStreamStateReady::Start(CAVStream& aStream) const
       
   986 	{
       
   987 	LOG_FUNC
       
   988 	TInt retVal = KErrNone;
       
   989 	CSignallingChannel* sigch = aStream.iProtocol.FindSignallingChannel(aStream.iRemoteAddress.BTAddr());
       
   990 		
       
   991 	// should always have sigch here - hence function signature
       
   992 	__ASSERT_DEBUG(sigch, PanicInState(EAvdtpSignallingChannelShouldExist));
       
   993 	if (sigch)
       
   994 		{
       
   995 		retVal = sigch->SendStartStream(aStream, aStream.RemoteSEID());
       
   996 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateStarting);
       
   997 		}
       
   998 	return retVal;
       
   999 	}
       
  1000 
       
  1001 void TAVStreamStateReady::Started(CAVStream& aStream) const
       
  1002 	{
       
  1003 	LOG_FUNC
       
  1004 	ChangeState(aStream, CAVStreamStateFactory::EStreamStateStreaming);
       
  1005 	}
       
  1006 	
       
  1007 void TAVStreamStateReady::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
  1008 	{
       
  1009 	LOG_FUNC
       
  1010 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
  1011 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1012 	}
       
  1013 
       
  1014 void TAVStreamStateStarting::Enter(CAVStream& aStream) const
       
  1015 	{
       
  1016 	LOG_FUNC
       
  1017 	// Tell the physical link that encryption keys could be refreshed now, to prevent an auto refresh later
       
  1018 	aStream.TryToAndThenPreventHostEncryptionKeyRefresh();
       
  1019 	}
       
  1020 
       
  1021 
       
  1022 void TAVStreamStateStarting::StartConfirm(CAVStream& aStream, TInt aResult, TSEID /*aRemoteSEID*/) const
       
  1023 	{
       
  1024 	LOG_FUNC
       
  1025 	// just change state
       
  1026 	if (aResult==KErrNone)
       
  1027 		{
       
  1028 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateStreaming);
       
  1029 		aStream.iStreamNotify.StreamStarted(aStream.LocalSEID());
       
  1030 		}
       
  1031 	else
       
  1032 		{
       
  1033 		// whether suspended or idle, we return to ready 
       
  1034 		// but first release the prevent encryption key refresh token
       
  1035 		aStream.AllowHostEncryptionKeyRefresh();
       
  1036 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateReady);
       
  1037 		aStream.iStreamNotify.StreamInitiatedServiceFailed(aStream, aResult);		
       
  1038 		}
       
  1039 	}
       
  1040 	
       
  1041 TInt TAVStreamStateStarting::StartReceived(CAVStream& /*aStream*/) const
       
  1042 	{
       
  1043 	LOG_FUNC
       
  1044 
       
  1045 	// we need to tell the other end 'nope we're busy' because the starts 'crossed in the post'
       
  1046 	// returning KErrInUse will tell the other end to go away (politely of course)
       
  1047 	return KErrInUse;
       
  1048 	}
       
  1049 
       
  1050 
       
  1051 void TAVStreamStateReleasing::Release(CAVStream& /*aStream*/) const
       
  1052 	{
       
  1053 	LOG_FUNC
       
  1054 	// we are already releasing so do nothing.
       
  1055 	}
       
  1056 	
       
  1057 void TAVStreamStateReleasing::ReleaseConfirm(CAVStream& aStream, TInt /*aResult*/, TSEID /*aSEID*/) const
       
  1058 	{
       
  1059 	LOG_FUNC
       
  1060 	// ignore error - proceed anyway
       
  1061 	aStream.Released();
       
  1062 	}
       
  1063 	
       
  1064 void TAVStreamStateReleasing::DropSession(CAVStream& /*aStream*/, TAvdtpTransportSessionType /*aType*/, CUserPlaneTransportSession& /*aSession*/) const
       
  1065 	{
       
  1066 	LOG_FUNC
       
  1067 	// to guard against sending multiple Releases per dropped session
       
  1068 	// since we're releasing, we don't need to send a Release, but we just consume
       
  1069 	}
       
  1070 	
       
  1071 void TAVStreamStateReleasing::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
  1072 	{
       
  1073 	LOG_FUNC
       
  1074 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
  1075 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1076 	}
       
  1077 	
       
  1078 
       
  1079 void TAVStreamStateAborting::AbortConfirm(CAVStream& aStream, TSEID /*aSEID*/) const
       
  1080 	{
       
  1081 	LOG_FUNC
       
  1082 	aStream.Released();
       
  1083 	}
       
  1084 
       
  1085 void TAVStreamStateAborting::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
  1086 	{
       
  1087 	LOG_FUNC
       
  1088 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
  1089 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1090 	}
       
  1091 	
       
  1092 
       
  1093 void TAVStreamStateAborting::Release(CAVStream& /*aStream*/) const
       
  1094 	{
       
  1095 	LOG_FUNC
       
  1096 	// we are already releasing so do nothing.
       
  1097 	}
       
  1098 		
       
  1099 
       
  1100 void TAVStreamStateCreatingLogicalChannels::LogicalChannelsAvailable(CAVStream& aStream, TLogicalChannelFactoryTicket aTicket, TInt aError) const
       
  1101 	{
       
  1102 	LOG_FUNC
       
  1103 	aStream.iFactoryJob = aTicket;
       
  1104 	aStream.BindLogicalAndTransportChannels(aTicket, aError);
       
  1105 			
       
  1106 	if (aError==KErrNone)
       
  1107 		{
       
  1108 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateReady);
       
  1109 		// tell sessions...
       
  1110 		aStream.TransportChannelsReady();		
       
  1111 		}
       
  1112 	else
       
  1113 		{
       
  1114 		aStream.iStreamNotify.StreamInitiatedServiceFailed(aStream, aError);
       
  1115 		}
       
  1116 	}
       
  1117 	
       
  1118 
       
  1119 void TAVStreamStateCreatingLogicalChannels::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
  1120 	{
       
  1121 	LOG_FUNC
       
  1122 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
  1123 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1124 	}
       
  1125 
       
  1126 void TAVStreamStateWaitingForLogicalChannels::Enter(CAVStream& aStream) const
       
  1127 	{
       
  1128 	LOG_FUNC
       
  1129 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1130 	
       
  1131 	// start guard timer in case logical channels never arrive for TCs
       
  1132 	aStream.StartWatchdog();
       
  1133 	}
       
  1134 
       
  1135 void TAVStreamStateWaitingForLogicalChannels::LogicalChannelsAvailable(CAVStream& aStream, TLogicalChannelFactoryTicket aResponse, TInt aError) const
       
  1136 	{
       
  1137 	LOG_FUNC
       
  1138 	// we created the transport channels in :Await, so now we can bind
       
  1139 	// then the sessions can call :AddSession and scoop up the TCs
       
  1140 	aStream.iFactoryJob = aResponse;
       
  1141 	aStream.BindLogicalAndTransportChannels(aResponse, aError);
       
  1142 
       
  1143 	if (aError==KErrNone)
       
  1144 		{	
       
  1145 		const TBool reportingPresent = aStream.iReportingBinding.iChannel ? ETrue : EFalse;
       
  1146 		const TBool recoveryPresent = aStream.iRecoveryBinding.iChannel ? ETrue : EFalse;
       
  1147 
       
  1148 		aStream.iNumSessionsRequired = AvdtpInternalUtils::NumberOfTransportObjects(reportingPresent, recoveryPresent);
       
  1149 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateWaitForSessions);
       
  1150 		// tell signalling session		
       
  1151 		aStream.iStreamNotify.StreamAccepted(aStream.LocalSEID(),
       
  1152 												aStream.RemoteSEID(), reportingPresent, recoveryPresent);
       
  1153 		}
       
  1154 	else
       
  1155 		{
       
  1156 		aStream.iStreamNotify.StreamInitiatedServiceFailed(aStream, aError);
       
  1157 		}
       
  1158 	}
       
  1159 
       
  1160 void TAVStreamStateWaitingForLogicalChannels::DropSession(CAVStream& aStream, TAvdtpTransportSessionType /*aType*/,
       
  1161 		 CUserPlaneTransportSession& /*aSession*/) const
       
  1162 	{
       
  1163 		LOG_FUNC
       
  1164 		aStream.iProtocol.LogicalChannelFactory().Cancel(aStream.iFactoryJob);
       
  1165 	}
       
  1166 
       
  1167 void TAVStreamStateWaitingForLogicalChannels::Exit(CAVStream& aStream) const
       
  1168 	{
       
  1169 	LOG_FUNC
       
  1170 	// start guard timer in case logical channels never arrive for TCs
       
  1171 	aStream.StopWatchdog();
       
  1172 	}
       
  1173 
       
  1174 void TAVStreamStateWaitingForLogicalChannels::WatchdogFired(CAVStream& aStream) const
       
  1175 	{
       
  1176 	LOG_FUNC
       
  1177 	// need to tidy TCs, and Abort stream and cancel job
       
  1178 	TLogicalChannelFactoryTicket nullTicket;
       
  1179 	
       
  1180 	aStream.BindLogicalAndTransportChannels(nullTicket, KErrTimedOut);
       
  1181 	
       
  1182 	aStream.iStreamNotify.StreamInitiatedServiceFailed(aStream, KErrTimedOut);
       
  1183 	}
       
  1184 
       
  1185 
       
  1186 /**
       
  1187 An ACP primitive: the TCs & LCs are ready, now we are awaiting the sessions
       
  1188 to come in and connect to the TCs.  The sessions do so at the behest of GAVDP
       
  1189 */
       
  1190 TInt TAVStreamStateWaitForSessions::AddSession(CAVStream& aStream,
       
  1191 									TAvdtpTransportSessionType aType,
       
  1192 						   			CUserPlaneTransportSession& aSession,
       
  1193 						   			CTransportChannel*& aChannel) const
       
  1194 	{
       
  1195 	LOG_FUNC
       
  1196 	TInt ret = KErrNone;
       
  1197 
       
  1198 	// bind session to channel - the channel is there, we'd have been told if it had gone
       
  1199 	TTransportBinding* b = NULL;
       
  1200 	
       
  1201 	switch (aType)
       
  1202 		{
       
  1203 		case EMedia:
       
  1204 			b = &aStream.iMediaBinding;
       
  1205 			break;
       
  1206 		case EReporting:
       
  1207 			// check GAVDP isn't being naughty and asking for an unconfigured session
       
  1208 			if (aStream.CheckConfigured(EServiceCategoryReporting))
       
  1209 				{
       
  1210 				b = &aStream.iReportingBinding;
       
  1211 				}
       
  1212 			else
       
  1213 				{
       
  1214 				// GAVDP asking for a bearer that is not configured
       
  1215 				ret = KErrNotSupported;
       
  1216 				}
       
  1217 			break;
       
  1218 		case ERecovery:
       
  1219 			// check GAVDP isn't being naughty and asking for an unconfigured session
       
  1220 			if (aStream.CheckConfigured(EServiceCategoryRecovery))
       
  1221 				{
       
  1222 				b = &aStream.iRecoveryBinding;
       
  1223 				}
       
  1224 			else
       
  1225 				{
       
  1226 				// GAVDP asking for a bearer that is not configured
       
  1227 				ret = KErrNotSupported;
       
  1228 				}
       
  1229 			break;
       
  1230 		default:
       
  1231 			PanicInState(EAvdtpBadSessionAttachingToStream);
       
  1232 		}
       
  1233 	
       
  1234 	if (ret == KErrNone)
       
  1235 		{
       
  1236 		ret = b->iChannel->AttachTransportSession(aSession, aType);
       
  1237 		if (ret==KErrNone)
       
  1238 			{
       
  1239 			// stream needs to remember binding
       
  1240 			b->iSession = &aSession;
       
  1241 			// and session need to know channel
       
  1242 			aChannel = b->iChannel;
       
  1243 			// check if all sessions have bound
       
  1244 			if (!--aStream.iNumSessionsRequired)
       
  1245 				{
       
  1246 				ChangeState(aStream, CAVStreamStateFactory::EStreamStateReady);
       
  1247 				aStream.TransportChannelsReady();
       
  1248 				}
       
  1249 			}
       
  1250 		}
       
  1251 	return ret;
       
  1252 	}	
       
  1253 
       
  1254 TInt TAVStreamStateWaitForSessions::StartReceived(CAVStream& aStream) const
       
  1255 	{
       
  1256 	LOG_FUNC
       
  1257 	ChangeState(aStream, CAVStreamStateFactory::EStreamStateWaitForSessionsStartReceived);
       
  1258 	return KErrNone;	
       
  1259 	}	
       
  1260 
       
  1261 void TAVStreamStateWaitForSessions::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
  1262 	{
       
  1263 	LOG_FUNC
       
  1264 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
  1265 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1266 	}
       
  1267 
       
  1268 /**
       
  1269 Overrides the method in TAVStreamStateWaitForSessions. The start has already been received by
       
  1270 CSignallingSession::StartIndication, so after changing the state to EStreamStateReady data
       
  1271 stored in the CAVStream object will be used to pass a start indication to GAVDP.
       
  1272 */
       
  1273 TInt TAVStreamStateWaitForSessionsStartReceived::AddSession(CAVStream& aStream,
       
  1274 												TAvdtpTransportSessionType aType,
       
  1275 						   						CUserPlaneTransportSession& aSession,
       
  1276 						   						CTransportChannel*& aChannel) const
       
  1277 	{
       
  1278 	LOG_FUNC
       
  1279 	// Call the function from the parent class to bind the session
       
  1280 	TInt ret = TAVStreamStateWaitForSessions::AddSession(aStream,aType,aSession,aChannel);
       
  1281 	
       
  1282 	// if that worked, and all the channels are bound, we can now issue the delayed start
       
  1283 	if((ret == KErrNone) && (!aStream.iNumSessionsRequired))
       
  1284 		{
       
  1285 		aStream.ReadyForStartIndication();
       
  1286 		}
       
  1287 
       
  1288 	return ret;
       
  1289 	}
       
  1290 	
       
  1291 TInt TAVStreamStateWaitForSessionsStartReceived::StartReceived(CAVStream& /*aStream*/) const
       
  1292 	{
       
  1293 	LOG_FUNC
       
  1294 	return KErrNotReady;
       
  1295 	}	
       
  1296 
       
  1297 void TAVStreamStateWaitForSessionsStartReceived::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
  1298 	{
       
  1299 	LOG_FUNC
       
  1300 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
  1301 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1302 	}
       
  1303 
       
  1304 void TAVStreamStateSuspending::SuspendConfirm(CAVStream& aStream, TInt aResult, TSEID /*aRemoteSEID*/) const
       
  1305 	{
       
  1306 	LOG_FUNC
       
  1307 	// just change state
       
  1308 	if (aResult==KErrNone)
       
  1309 		{
       
  1310 		// no difference between a "suspended" state, and ready
       
  1311 		// making them the same helps support reconfig in more states
       
  1312 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateReady);
       
  1313 		aStream.iStreamNotify.StreamSuspended(aStream.LocalSEID());
       
  1314 		}
       
  1315 	else
       
  1316 		{
       
  1317 		// stay in streaming state and notify the user of the error
       
  1318 		ChangeState(aStream, CAVStreamStateFactory::EStreamStateStreaming);
       
  1319 		aStream.iStreamNotify.StreamInitiatedServiceFailed(aStream, aResult);
       
  1320 		}
       
  1321 	}
       
  1322 
       
  1323 void TAVStreamStateSuspending::Suspended(CAVStream& /*aStream*/) const
       
  1324 	{
       
  1325 	LOG_FUNC
       
  1326 	// throw away
       
  1327 	}
       
  1328 	
       
  1329 
       
  1330 void TAVStreamStateSuspending::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
  1331 	{
       
  1332 	LOG_FUNC
       
  1333 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
  1334 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1335 	}
       
  1336 
       
  1337 void TAVStreamStateReconfiguring::ReconfigConfirm(CAVStream& aStream, TInt aResult, 
       
  1338 												TSEID /*aRemoteSEID*/, TAvdtpServiceCategory aFailedCategory) const
       
  1339 	{
       
  1340 	LOG_FUNC
       
  1341 	// ok to return to ready on success or failure
       
  1342 	ChangeState(aStream, CAVStreamStateFactory::EStreamStateReady);
       
  1343 	TRAPD(err, aStream.iLocalSEP->CommitPendingConfigurationL(aResult==KErrNone, ETrue));
       
  1344 	if (err!=KErrNone)
       
  1345 		{
       
  1346 		aStream.iStreamNotify.StreamInitiatedServiceFailed(aStream, aResult);
       
  1347 		}
       
  1348 	aStream.iStreamNotify.StreamConfigured(aStream.LocalSEID(), aResult, aFailedCategory);
       
  1349 	}
       
  1350 
       
  1351 void TAVStreamStateReconfiguring::Enter(CAVStream& __DEBUG_ONLY(aStream)) const
       
  1352 	{
       
  1353 	LOG_FUNC
       
  1354 	//We should not be preventing the encryption key refresh in this state. Asserting this condition. 
       
  1355 	__ASSERT_DEBUG(!aStream.IsHostEncryptionKeyRefreshPrevented(),Panic(EUnexpectedEncryptionKeyRefreshPrevent));
       
  1356 	}
       
  1357 	
       
  1358 
       
  1359 void TAVStreamStateStreaming::Enter(CAVStream& aStream) const
       
  1360 	{                              
       
  1361 	LOG_FUNC
       
  1362  // experiments with window dragging show not much change if thread priority bumped
       
  1363  // maybe due to trying to get into esock in the first place
       
  1364  // Changing the role of the Esock_BT thread in the cmi file, from player to 
       
  1365  // DealerPlayer allows messages to be passed directly to the Esock_BT thread
       
  1366  
       
  1367  	aStream.iOriginalESockBTPriority = RThread().Priority(); //save the original priority of the Esock_BT thread.
       
  1368  	RThread().SetPriority(EPriorityRealTime);
       
  1369 	
       
  1370 	}
       
  1371 
       
  1372 void TAVStreamStateStreaming::Exit(CAVStream& aStream) const
       
  1373 	{
       
  1374 	LOG_FUNC
       
  1375 	RThread().SetPriority(aStream.iOriginalESockBTPriority);//set the priority of the thread back to the original value.
       
  1376 	
       
  1377 	// Tell the physical link that encryption keys could be refreshed now, to prevent an auto refresh later
       
  1378 	aStream.AllowHostEncryptionKeyRefresh();
       
  1379 	}
       
  1380 	
       
  1381 TInt TAVStreamStateStreaming::Suspend(CAVStream& aStream) const
       
  1382 	{
       
  1383 	LOG_FUNC
       
  1384 	TInt retVal = KErrNone;
       
  1385 	CSignallingChannel* sigch = aStream.iProtocol.FindSignallingChannel(aStream.iRemoteAddress.BTAddr());
       
  1386 		
       
  1387 	__ASSERT_DEBUG(sigch, PanicInState(EAvdtpSignallingChannelShouldExist));
       
  1388 	if (sigch)
       
  1389 		{
       
  1390 		retVal = sigch->SendSuspendStream(aStream, aStream.RemoteSEID());
       
  1391 		if (retVal==KErrNone)
       
  1392 			{
       
  1393 			ChangeState(aStream, CAVStreamStateFactory::EStreamStateSuspending);
       
  1394 			}
       
  1395 		}
       
  1396 	return retVal;
       
  1397 	}
       
  1398 	
       
  1399 void TAVStreamStateStreaming::Suspended(CAVStream& aStream) const
       
  1400 	{
       
  1401 	LOG_FUNC
       
  1402 	ChangeState(aStream, CAVStreamStateFactory::EStreamStateReady);
       
  1403 	}
       
  1404 
       
  1405 TBool TAVStreamStateStreaming::IsStreaming(const CAVStream& /*aStream*/) const
       
  1406 	{
       
  1407 	LOG_FUNC
       
  1408 	return ETrue;
       
  1409 	}
       
  1410 	
       
  1411 TInt TAVStreamStateStreaming::Start(CAVStream& /*aStream*/) const
       
  1412 	{
       
  1413 	// don't want to tell remote to Start when already Streaming, cos it's BadState
       
  1414 	return KErrNotReady;
       
  1415 	}
       
  1416  
       
  1417 TInt TAVStreamStateStreaming::StartReceived(CAVStream& /*aStream*/) const
       
  1418 	{
       
  1419 	LOG_FUNC
       
  1420 	return KErrNotReady;
       
  1421 	}
       
  1422