bluetooth/btstack/avdtp/avdtpStream.h
changeset 0 29b1cd4cb562
child 22 786b94c6f0a4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/avdtp/avdtpStream.h	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,626 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Defines the avdtp stream.  The stream appears when the SEPs have been configured
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef AVDTPSTREAM_H
+#define AVDTPSTREAM_H
+
+#include <bluetoothav.h>
+
+#include "bt.h"
+#include "avdtpTransportSession.h"
+#include "avdtpTransportChannel.h"
+#include "avdtpLogicalChannelFactory.h"
+#include "avdtpServiceInterface.h"
+#include "avdtpSEPCache.h"
+#include "avdtpAllocators.h"
+#include "avdtputil.h"
+
+// when rationalising logging, will not need this to get FLOG_ACTIVE MACRO in this header
+#include <comms-infras/commsdebugutility.h>
+
+class CAVStream;
+class CSignallingSession;
+class CTransportSession;
+class CUserPlaneTransportSession;
+class CAvdtpSAP;
+class CAvdtpProtocol;
+class TAVStreamState;
+class CAVStreamStateFactory;
+class CLocalSEP;
+class CWatchdogTimer;
+
+#ifdef _OOM_TEST
+const TInt KAvdtpLogicalChannelsWatchdogTimeout = 50000; 
+#else
+const TInt KAvdtpLogicalChannelsWatchdogTimeout = 30000000; //30s	
+#endif
+
+/**
+Interface for upcalls from stream to signalling session
+*/
+class MAvdtpStreamNotify
+	{
+public:
+	virtual void StreamStarted(TSEID aLocalSEID) =0;
+	virtual void StreamSuspended(TSEID aLocalSEID) =0;
+	virtual void StreamAccepted(TSEID aLocalSEID, TSEID aRemoteSEID, TBool aWithReporting, TBool aWithRecovery) =0;
+	virtual void StreamConfigured(TSEID aLocalSEID, TInt aError, TAvdtpServiceCategory aFailedCategory) =0;
+	virtual void StreamInitiatedServiceFailed(const CAVStream& aStream, TInt aError) =0;
+	virtual void StreamReadyForStartIndication(const TAvdtpTransactionLabel aLabel, const TSEID aSeid) =0;
+	};
+
+#ifdef __FLOG_ACTIVE
+#define STATENAME(statename) iName = _L(statename);
+#else
+#define STATENAME(statename)
+#endif
+
+NONSHARABLE_CLASS(TPendingStreamDetails)
+	{
+public:
+	TPendingStreamDetails()
+		{
+		Reset();
+		};
+		
+	void Reset() 
+		{
+		iLocalSEP = NULL;
+		iStreamNotify = NULL;
+		iRemoteSEID.Reset();
+		};
+		
+	CLocalSEP* iLocalSEP; //non-owned
+	MAvdtpStreamNotify* iStreamNotify; // non-owned
+	TSEID iRemoteSEID;
+	TBool iRequireReporting;
+	TBool iRequireRecovery;
+	};
+
+/**
+	This class knows which SAPs constitute 1 stream
+	SAPs can therefore use this to propagate important matters
+	e.g. Coordinating sends to MUX? Flushing?
+	
+	Instances of this class appear during the signalling phase
+	When endpoints have been discovered, the GC will Select a SEP
+	which will cause a CAVStream to be instantiated.
+	
+	The stream then needs to be told of the capabilities that have been selected
+	If remote supports MUX then we always choose to use that
+	
+	Once the stream is told it knows how many sessions will be required.
+	
+*/
+
+NONSHARABLE_CLASS(CAVStream) : public CBase, public XLogicalChannelFactoryClient,
+								public XAvdtpSignalReceiver
+	{
+friend class CAvdtpProtocol;
+friend class CWatchdogTimer;
+friend class CSignallingSession;
+friend class TAVStreamState;
+friend class TAVStreamStateIdle;
+friend class TAVStreamStateOpening;
+friend class TAVStreamStateReleasing;
+friend class TAVStreamStateAborting;
+friend class TAVStreamStateCreatingLogicalChannels;
+friend class TAVStreamStateWaitingForLogicalChannels;
+friend class TAVStreamStateOpen;
+friend class TAVStreamStateReady;
+friend class TAVStreamStateWaitForSessions;
+friend class TAVStreamStateStreaming;
+friend class TAVStreamStateConfiguring;
+friend class TAVStreamStateConfigured;
+friend class TAVStreamStateINTConfigured;
+friend class TAVStreamStateACPConfigured;
+friend class TAVStreamStateReconfiguring;
+friend class TAVStreamStateStarting;
+friend class TAVStreamStateSuspending;
+friend class TAVStreamStateWaitForSessionsStartReceived;
+
+public:
+	static CAVStream* NewL(const TAvdtpSockAddr& aAddr,
+					 MAvdtpStreamNotify& aStreamNotify,
+					 CAvdtpProtocol& aProtocol,
+					 CLocalSEP& aLocalSEP);
+	~CAVStream();
+	void NotifyUserPlaneTransportSessionsError(CUserPlaneTransportSession* aErroredSession, TInt aError);
+	void LocalSEPDestroyed(const CLocalSEP& aTerminator);
+	
+	TInt AddSession(TAvdtpTransportSessionType aType,
+					CUserPlaneTransportSession& aSession,
+					CTransportChannel*& aTransportChannel);
+	void DropSession(TAvdtpTransportSessionType aType, CUserPlaneTransportSession& aSession);
+	void ClearSession(CUserPlaneTransportSession& aSession);
+
+	inline TSEID LocalSEID() const;
+	inline TSEID RemoteSEID() const;
+	inline TBTDevAddr DeviceAddress() const;
+	void CanMuxFrag(TBool& aCanMux, TBool& aCanFrag) const;	
+	TBool CheckConfigured(TAvdtpServiceCategory aCategory) const;
+	void GetTSID(RTSID& aTSID, TAvdtpTransportSessionType aSessionType);
+	TBool MultiplexingConfigured() const;
+	
+// INT stuff
+	void SetConfigurationL(RBuf8& aPacketBuffer,
+							CSignallingChannel& aSignallingChannel,
+							TBool aReportingConfigured,
+							TBool aRecoveryConfigured);
+	TInt Start();
+	TInt Suspend();
+	
+// ACP stuff
+	void Configured();
+	void AwaitLogicalChannelsL();
+	void Started();
+	void Suspended();
+	TBool IsStreaming() const;
+	TInt StartIndication(TAvdtpTransactionLabel aLabel, TSEID aSeid);
+	TBool IsHostEncryptionKeyRefreshPrevented();
+	
+private:
+	CAVStream(const TAvdtpSockAddr& aAddr,
+				MAvdtpStreamNotify& aStreamNotify,
+				CAvdtpProtocol& aProtocol,
+				CLocalSEP& aLocalSEP);
+	void ConstructL();
+
+private:
+	void LogicalChannelFactoryRequestComplete(TLogicalChannelFactoryTicket aTicket, TInt aResult);
+	void BindLogicalAndTransportChannels(TLogicalChannelFactoryTicket aTicket, TInt aError);
+	void TransportChannelsReady();
+	TAvdtpMultiplexingCapability* CreateMuxCapabilityL(TBool aRequireReporting, TBool aRequireRecovery, CSignallingChannel& aIDProvider);
+	void DeallocateUnclaimedTransportSessionIDs();
+// signalling channel callbacks
+	virtual void OpenConfirm(TInt aResult, TSEID aSEID);
+	virtual void ReleaseConfirm(TInt aResult, TSEID aSEID);
+	virtual void StartConfirm(TInt aResult, TSEID aRemoteSEID);
+	virtual void SuspendConfirm(TInt aResult, TSEID aRemoteSEID);
+	virtual void SetConfigConfirm(TInt aResult, TSEID aRemoteSEID, TAvdtpServiceCategory aFailedCategory);
+	virtual void ReconfigConfirm(TInt aResult, TSEID aRemoteSEID, TAvdtpServiceCategory aFailedCategory);
+	virtual void AbortConfirm(TSEID aRemoteSEID);
+	void ReadyForStartIndication();
+	void Release();		// initiate release proceedings, eg SEP has been destroyed
+	void Released();	// release proceedings completed
+	// the watchdog guards against failed creation/reception of transport channels
+	void StartWatchdog();
+	void StopWatchdog();
+	void WatchdogFired();
+	void TryToAndThenPreventHostEncryptionKeyRefresh();
+	void AllowHostEncryptionKeyRefresh();
+	
+private:
+	NONSHARABLE_STRUCT(TStartDetails)
+		{
+	public:
+		TAvdtpTransactionLabel 	iLabel;
+		TSEID iSeid;
+		};
+
+private:
+	CAvdtpProtocol&		iProtocol;
+
+	MAvdtpStreamNotify& iStreamNotify;
+
+	TTransportBinding	iMediaBinding;
+	TTransportBinding	iReportingBinding;
+	TTransportBinding	iRecoveryBinding;
+	
+	TFixedArray<RTSID, 3>	iMuxedTSIDs; // fixed to make easier to access by sessiontype
+
+	TAvdtpSockAddr		iRemoteAddress;	// devaddr and RemoteSEID
+	CLocalSEP*			iLocalSEP;		// NULL if the SEP is destroyed and we need to Release
+
+	TInt				iNumSessionsRequired; // the number that constitute this stream
+	// iNumSessions is used to determine when transportchannels should be activated/shutdown
+	const TAVStreamState*		iState;		// non-owned
+
+	TLogicalChannelFactoryTicket iFactoryJob;
+	
+	CWatchdogTimer*		iWatchdogTimer;
+	TStartDetails	iStartDetails;
+	TThreadPriority iOriginalESockBTPriority;
+	TBool			iNotifiedACLStreamActive;
+	TDblQueLink			iProtocolQLink;
+	//First try to refresh the encrption key and then prevent it from refreshing in future untill
+	//we allow it later. This is done so that we do not (or forced by controller) refresh the encryption key 
+	//in the middle of streaming audio data. 
+	MBluetoothControlPlaneToken*	iTryToAndThenPreventHostEncryptionKeyRefreshToken;
+	};
+	
+
+NONSHARABLE_CLASS(CWatchdogTimer) : public CTimer
+	{
+public:
+	static CWatchdogTimer* NewL(CAVStream& aObserver);
+private:
+	CWatchdogTimer(CAVStream& aObserver);
+	void RunL();
+	void ConstructL();
+private:
+	CAVStream& iObserver;
+	};
+
+NONSHARABLE_CLASS(CAVStreamStateFactory) : public CBase
+	{
+public:
+	static CAVStreamStateFactory* NewL();
+	enum TAVStreamStates
+		{
+		EStreamStateIdle,
+		EStreamStateConfiguring,
+		EStreamStateINTConfigured,
+		EStreamStateACPConfigured,
+		EStreamStateOpening,
+		EStreamStateWaitForSessions,
+		EStreamStateOpen, // AVDTP Open transaction performed
+		EStreamStateReady, // all logical channels in place
+		EStreamStateReleasing,
+		EStreamStateAborting,
+		EStreamStateStreaming,
+		EStreamStateWaitingForLogicalChannels,
+		EStreamStateCreatingLogicalChannels,
+		EStreamStateSuspending,
+		EStreamStateStarting,
+		EStreamStateReconfiguring,
+		EStreamStateWaitForSessionsStartReceived,
+	// *** keep next one last ***
+		EStreamMaxState,
+		};
+	const TAVStreamState& GetState(TAVStreamStates aState) const;
+	TInt StateIndex(const TAVStreamState* aState) const;
+	~CAVStreamStateFactory();
+private:
+	void ConstructL();
+	TFixedArray<TAVStreamState*, EStreamMaxState> iStates;
+	};
+	
+NONSHARABLE_CLASS(TAVStreamState)
+	{
+public:
+	virtual void Release(CAVStream& aStream) const;
+	virtual void LogicalChannelsAvailable(CAVStream& aStream, TLogicalChannelFactoryTicket aTicket, TInt aErr) const;
+	virtual TInt AddSession(CAVStream& aStream, 
+							TAvdtpTransportSessionType aType,
+							CUserPlaneTransportSession& aSession,
+							CTransportChannel*& aTransportChannel) const;
+	virtual void DropSession(CAVStream& aStream, TAvdtpTransportSessionType aType,
+							 CUserPlaneTransportSession& aSession) const;
+	
+// INT stuff
+	virtual void SetConfigurationL(CAVStream& aStream, 
+									RBuf8& aPacketBuffer,
+									CSignallingChannel& aSignallingChannel,
+									TBool aReportingConfigured,
+									TBool aRecoveryConfigured) const;
+
+	// forwarded from service_interface
+	virtual void SetConfigConfirm(CAVStream& aStream, TInt aResult, TSEID aRemoteSEID, TAvdtpServiceCategory aFailedCategory) const;
+	virtual void ReconfigConfirm(CAVStream& aStream, TInt aResult, 
+									TSEID aRemoteSEID, TAvdtpServiceCategory aFailedCategory) const;
+	virtual void StartConfirm(CAVStream& aStream, TInt aResult, TSEID aRemoteSEID) const;
+	virtual void SuspendConfirm(CAVStream& aStream, TInt aResult, TSEID aRemoteSEID) const;
+	virtual void OpenConfirm(CAVStream& aStream, TInt aResult, TSEID aSEID) const;
+	virtual void ReleaseConfirm(CAVStream& aStream, TInt aResult, TSEID aSEID) const;
+	virtual void AbortConfirm(CAVStream& aStream, TSEID aRemoteSEID) const;
+	virtual TInt Start(CAVStream& aStream) const;
+	virtual TInt Suspend(CAVStream& aStream) const;
+
+// ACP stuff
+	virtual void Configured(CAVStream& aStream) const;
+	virtual void AwaitLogicalChannelsL(CAVStream& aStream) const;
+	virtual TBool IsStreaming(const CAVStream& aStream) const;
+	virtual TInt StartReceived(CAVStream& aStream) const;
+	virtual void Started(CAVStream& aStream) const;
+	virtual void Suspended(CAVStream& aStream) const;
+
+	virtual void Enter(CAVStream& aStream) const;
+	virtual void Exit(CAVStream& aStream) const;
+	virtual void WatchdogFired(CAVStream& aStream) const;
+
+protected:
+	TAVStreamState(CAVStreamStateFactory& aFactory);
+	void ChangeState(CAVStream& aContext, CAVStreamStateFactory::TAVStreamStates aState) const;
+	void PanicInState(TAvdtpPanic aPanic) const;
+protected:
+	CAVStreamStateFactory&	iFactory;
+#ifdef __FLOG_ACTIVE
+	TBuf<32>				iName;
+#endif
+	};
+
+/**
+State when:
+Stream object initially created (either INT or ACP)
+Or after configured: reason is that the remote may have got a GetConfig
+and been happy with configuration, so no need for it to configure
+*/ 
+NONSHARABLE_CLASS(TAVStreamStateIdle) : public TAVStreamState
+	{
+public:
+	TAVStreamStateIdle(CAVStreamStateFactory& aFactory);
+	
+	virtual void SetConfigurationL(CAVStream& aStream, 
+							RBuf8& aPacketBuffer,
+							CSignallingChannel& aSignallingChannel,
+							TBool aReportingConfigured,
+							TBool aRecoveryConfigured) const;
+	virtual void Configured(CAVStream& aStream) const;
+	virtual void Enter(CAVStream& aStream) const;
+private:
+	};
+
+NONSHARABLE_CLASS(TAVStreamStateConfiguring) : public TAVStreamStateIdle
+	{
+public:
+	TAVStreamStateConfiguring(CAVStreamStateFactory& aFactory);
+	virtual void SetConfigConfirm(CAVStream& aStram, TInt aResult, TSEID aRemoteSEID, TAvdtpServiceCategory aFailedCategory) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+
+/*
+Abstract state to get common Release event for INT and ACPConfigured states
+Since abstract, this isn't added as a state in the state factory
+*/
+NONSHARABLE_CLASS(TAVStreamStateConfigured) : public TAVStreamStateIdle
+	{
+public:
+	virtual void Release(CAVStream& aStream) const;	
+	virtual void Enter(CAVStream& aStream) const;
+protected:
+	TAVStreamStateConfigured(CAVStreamStateFactory& aFactory);	
+	};
+	
+NONSHARABLE_CLASS(TAVStreamStateINTConfigured) : public TAVStreamStateConfigured
+	{
+public:
+	TAVStreamStateINTConfigured(CAVStreamStateFactory& aFactory);
+	virtual TInt AddSession(CAVStream& aStream,
+					TAvdtpTransportSessionType aType,
+					CUserPlaneTransportSession& aSession,
+					CTransportChannel*& aChannel) const;
+	virtual void DropSession(CAVStream& aStream, TAvdtpTransportSessionType aType,
+					 CUserPlaneTransportSession& aSession) const;
+	virtual void SetConfigurationL(CAVStream& aStream, 
+									RBuf8& aPacketBuffer,
+									CSignallingChannel& aSignallingChannel,
+									TBool aReportingConfigured,
+									TBool aRecoveryConfigured) const;
+	virtual void Enter(CAVStream& aStream) const;
+private:
+	void TryToOpen(CAVStream& aStream) const;
+	};
+
+NONSHARABLE_CLASS(TAVStreamStateACPConfigured) : public TAVStreamStateConfigured
+	{
+public:
+	TAVStreamStateACPConfigured(CAVStreamStateFactory& aFactory);
+	virtual void AwaitLogicalChannelsL(CAVStream& aStream) const;
+	TInt AddSession(CAVStream& aStream, 
+							TAvdtpTransportSessionType aType,
+							CUserPlaneTransportSession& aSession,
+							CTransportChannel*& aTransportChannel) const;
+	virtual void Enter(CAVStream& aStream) const;
+private:
+	void TryToOpen(CAVStream& aStream) const;
+	void DoAwaitDirectChannelsL(CAVStream& aStream,
+								TBool aRequireReporting,
+								TBool aRequireRecovery) const;
+	void DoAwaitMuxedChannelsL(CAVStream& aStream,
+							    TAvdtpMultiplexingCapabilityHelper& aHelper,
+								TBool aRequireReporting,
+								TBool aRequireRecovery) const;
+	};
+	
+NONSHARABLE_CLASS(TAVStreamStateWaitForSessions) : public TAVStreamStateIdle
+	{
+public:
+	TAVStreamStateWaitForSessions(CAVStreamStateFactory& aFactory);
+	
+	virtual TInt AddSession(CAVStream& aStream,
+					TAvdtpTransportSessionType aType,
+					CUserPlaneTransportSession& aSession,
+					CTransportChannel*& aChannel) const;
+				
+	virtual TInt StartReceived(CAVStream& aStream) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+
+NONSHARABLE_CLASS(TAVStreamStateWaitForSessionsStartReceived) : public TAVStreamStateWaitForSessions
+	{
+public:
+	TAVStreamStateWaitForSessionsStartReceived(CAVStreamStateFactory& aFactory);
+	
+	virtual TInt AddSession(CAVStream& aStream,
+					TAvdtpTransportSessionType aType,
+					CUserPlaneTransportSession& aSession,
+					CTransportChannel*& aChannel) const;
+	
+	virtual TInt StartReceived(CAVStream& aStream) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+	
+NONSHARABLE_CLASS(TAVStreamStateOpening) : public TAVStreamStateIdle
+	{
+public:
+	TAVStreamStateOpening(CAVStreamStateFactory& aFactory);
+	virtual void OpenConfirm(CAVStream& aStream, TInt aResult, TSEID aRemoteSEID) const;
+	virtual void DropSession(CAVStream& aStream, TAvdtpTransportSessionType aType, CUserPlaneTransportSession& aSession) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+	
+	
+NONSHARABLE_CLASS(TAVStreamStateOpen) : public TAVStreamStateIdle
+	{
+public:
+	TAVStreamStateOpen(CAVStreamStateFactory& aFactory);
+	virtual void Release(CAVStream& aStream) const;
+	virtual void DropSession(CAVStream& aStream, TAvdtpTransportSessionType aType, CUserPlaneTransportSession& aSession) const;
+	virtual void Enter(CAVStream& aStream) const;
+private:
+	void DoRelease(CAVStream& aStream) const;	
+	};
+
+/**
+Ready state is 'GAVDP Open' + Transport channels connected.
+This state is required to make up for the big difference between having got an error-free
+AVDTP Open response (thus "open") and the successful subsequent transport channel connection, and session attachment
+which once complete means we are open, ready for moving to streaming, or reconfiguring
+*/
+NONSHARABLE_CLASS(TAVStreamStateReady) : public TAVStreamStateOpen
+	{
+public:
+	TAVStreamStateReady(CAVStreamStateFactory& aFactory);
+	virtual TInt AddSession(CAVStream& aStream,
+			TAvdtpTransportSessionType aType,
+			CUserPlaneTransportSession& aSession,
+			CTransportChannel*& aChannel) const;
+	// next pertains to reconfiguration
+	void SetConfigurationL(CAVStream& aStream, 
+									RBuf8& aPacketBuffer,
+									CSignallingChannel& aSignallingChannel,
+									TBool aReportingConfigured,
+									TBool aRecoveryConfigured) const;
+	virtual TInt StartReceived(CAVStream& aStream) const;
+	virtual TInt Start(CAVStream& aStream) const;
+	virtual void Started(CAVStream& aStream) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+
+/**
+Waiting for Logical Channels happens after we have got a AVDTP Open and sent Response
+*/
+NONSHARABLE_CLASS(TAVStreamStateWaitingForLogicalChannels) : public TAVStreamStateOpen
+	{
+public:
+	TAVStreamStateWaitingForLogicalChannels(CAVStreamStateFactory& aFactory);
+	virtual void Enter(CAVStream& aStream) const;
+	virtual void LogicalChannelsAvailable(CAVStream& aStream, TLogicalChannelFactoryTicket aTicket, TInt aErr) const;
+	virtual void Exit(CAVStream& aStream) const;
+	virtual void WatchdogFired(CAVStream& aStream) const;
+	virtual void DropSession(CAVStream& aStream, TAvdtpTransportSessionType aType, CUserPlaneTransportSession& aSession) const;
+	};
+	
+/**
+Creating Logical Channels happens after we have got a AVDTP Open Response back
+*/
+NONSHARABLE_CLASS(TAVStreamStateCreatingLogicalChannels) : public TAVStreamStateOpen
+	{
+public:
+	TAVStreamStateCreatingLogicalChannels(CAVStreamStateFactory& aFactory);
+	virtual void LogicalChannelsAvailable(CAVStream& aStream, TLogicalChannelFactoryTicket aTicket, TInt aErr) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+
+NONSHARABLE_CLASS(TAVStreamStateReconfiguring) : public TAVStreamStateReady
+	{
+public:
+	TAVStreamStateReconfiguring(CAVStreamStateFactory& aFactory);
+	virtual void ReconfigConfirm(CAVStream& aStram, TInt aResult, TSEID aRemoteSEID, TAvdtpServiceCategory aFailedCategory) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+
+NONSHARABLE_CLASS(TAVStreamStateReleasing) : public TAVStreamStateReady
+	{
+public:
+	TAVStreamStateReleasing(CAVStreamStateFactory& aFactory);
+	virtual void Release(CAVStream& aStream) const;
+	virtual void ReleaseConfirm(CAVStream& aStream, TInt aResult, TSEID aSEID) const;
+	virtual void DropSession(CAVStream& aStream, TAvdtpTransportSessionType aType, CUserPlaneTransportSession& aSession) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+
+/*
+Rarely entered state - required to gracefully release a Configured, but UnOpened, stream
+**/
+NONSHARABLE_CLASS(TAVStreamStateAborting) : public TAVStreamStateReady
+	{
+public:
+	TAVStreamStateAborting(CAVStreamStateFactory& aFactory);
+	virtual void Release(CAVStream& aStream) const;
+	virtual void AbortConfirm(CAVStream& aStream, TSEID aRemoteSEID) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+
+	
+NONSHARABLE_CLASS(TAVStreamStateStarting) : public TAVStreamStateReady
+	{
+public:
+	TAVStreamStateStarting(CAVStreamStateFactory& aFactory);
+	virtual void StartConfirm(CAVStream& aStream, TInt aResult, TSEID aSEID) const;
+	virtual TInt StartReceived(CAVStream& aStream) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+	
+NONSHARABLE_CLASS(TAVStreamStateStreaming) : public TAVStreamStateReady
+	{
+public:
+	TAVStreamStateStreaming(CAVStreamStateFactory& aFactory);
+	virtual TInt Suspend(CAVStream& aStream) const;
+	virtual TBool IsStreaming(const CAVStream& aStream) const;
+	virtual void Suspended(CAVStream& aStream) const;
+	virtual TInt Start(CAVStream& aStream) const;
+	virtual void Enter(CAVStream& aStream) const;
+	virtual void Exit(CAVStream& aStream) const;
+	virtual TInt StartReceived(CAVStream& aStream) const;
+	};
+
+NONSHARABLE_CLASS(TAVStreamStateSuspending) : public TAVStreamStateReady
+	{
+public:
+	TAVStreamStateSuspending(CAVStreamStateFactory& aFactory);
+	virtual void SuspendConfirm(CAVStream& aStream, TInt aResult, TSEID aRemoteSEID) const;
+	virtual void Suspended(CAVStream& aStream) const;
+	virtual void Enter(CAVStream& aStream) const;
+	};
+
+inline TBTDevAddr CAVStream::DeviceAddress() const
+	{
+	return iRemoteAddress.BTAddr();
+	}
+	
+inline TSEID CAVStream::RemoteSEID() const
+	{
+#ifdef _DEBUG
+	TSEID seid = iRemoteAddress.SEID();
+	__ASSERT_DEBUG(!seid.IsLocal(), Panic(EAvdtpSEIDHasWrongDomain));
+	return seid;
+#else
+	return iRemoteAddress.SEID();
+#endif
+	}
+
+#include "avdtpLocalSEP.h"
+		
+inline TSEID CAVStream::LocalSEID() const
+	{
+#ifdef _DEBUG
+	TSEID seid = iLocalSEP->SEID();
+	__ASSERT_DEBUG(seid.IsLocal(), Panic(EAvdtpSEIDHasWrongDomain));
+	return seid;
+#else
+	return iLocalSEP->SEID();
+#endif
+	}
+
+#endif //AVDTPSTREAM_H