bluetooth/btstack/avctp/avctpmuxerstates.h
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/avctp/avctpmuxerstates.h	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,330 @@
+// Copyright (c) 2005-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 classes to implement each state a Avctp Muxer can
+// be in.
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef AVCTPTRANSPORTSTATES_H
+#define AVCTPTRANSPORTSTATES_H
+
+#include <e32base.h>
+#include <bluetoothav.h>
+
+// when rationalising logging, will not need this to get FLOG_ACTIVE MACRO in this header
+#include <comms-infras/commsdebugutility.h>
+
+
+#include "avctputils.h"
+
+// Forward definitions
+class TAvctpMuxerState;
+class RMBufChain;
+
+/**
+The state factory for AVCTP muxer states
+
+  @internalComponent
+*/
+NONSHARABLE_CLASS(CAvctpMuxerStateFactory) : public CBase
+	{
+friend class CAvctpProtocol; // So only the protocol can new up a state factory
+
+public:
+	/** Index of the Muxer states */
+	enum TAvctpMuxerStates
+		{
+		/** No link, prior to establishing the link*/
+		EClosed = 0,
+		/** Waiting for the lower protocol link */
+		ELinkPending = 1,
+		/** The lower protocol link has been established */
+		EOpen = 2,
+		/** The second lower protocol link is opening */
+		ESecondLinkPending = 3,
+		/** Both lower protocol links have been established */
+		EFullyOpen = 4,
+		/** Provides convenient way of numbering the states */
+		EMaxStates = 5,
+		};
+	
+	TAvctpMuxerState& GetState(const TAvctpMuxerStates aState) const;
+	TInt StateIndex(const TAvctpMuxerState* aState) const;
+
+	~CAvctpMuxerStateFactory();
+
+private:
+	static CAvctpMuxerStateFactory* NewL();
+	CAvctpMuxerStateFactory();
+
+private:
+	/** The lightweight Muxer states */
+	TFixedArray<TAvctpMuxerState*, EMaxStates> iStates;
+	};
+
+// Forward Declarations
+class CAvctpTransport;
+class TBTDevAddr;
+class MSubConnectionControlClient;
+
+/**
+The base class for all the state classes in the AVCTP muxer state
+pattern.  These classes act as the state classes in the pattern,
+with the Muxer being the context. This class provides the default 
+implementation for the states.
+
+All states are flyweight classes managed by a State factory, so
+this class also has a pointer to the global factory singleton.
+
+There are four categories of events represented as pure virtual
+functions.  These are:
+
+1.	"Artificial" state events
+2.	Events coming in from the muxer's control clients.
+3.	Events coming in from the CAvctpSaps.
+4.	Events coming from below, via the L2CAP SAP.
+
+We don't panic on any events coming from below since these could be the
+result of defective remote behaviour and we don't want to give them a 
+means of bringing down our device. 
+
+Events coming from above we do panic if they are incorrect since any
+errors that reach this point are the result of programming errors.
+This is because CAvctpSap, CAvctpSapLinksMgr shield the muxer from
+direct interaction with other components / clients.
+
+For debugging purposes, a state name is implemented in derived classes 
+to allow state changes to be logged.
+
+This class defines basic default behaviour for all the events that
+a state responds to.
+
+Derived classes implement the events that they care about.
+
+@internalComponent
+*/
+NONSHARABLE_CLASS(TAvctpMuxerState)
+	{
+protected:
+	TAvctpMuxerState(CAvctpMuxerStateFactory& aFactory);
+public:
+	
+	// "Artificial" state events
+	virtual void Enter(CAvctpTransport& aTransport) const;
+	virtual void Exit(CAvctpTransport& aTransport) const;
+
+	virtual TBool IsIdle(CAvctpTransport& aTransport) const;
+
+	virtual void IdleTimerExpired(CAvctpTransport& aTransport) const;
+
+	virtual TInt Start(CAvctpTransport& aTransport, const TBTDevAddr& aAddr, TUint16 aClientId) const;
+	virtual TInt StartIncoming(CAvctpTransport& aTransport, const TBTDevAddr& aAddr, CServProviderBase* aL2CAPConSAP) const;
+	virtual TInt AddSecondChannel(CAvctpTransport& aTransport, CServProviderBase& aSAP) const;
+	virtual void RemoveSecondChannel(CAvctpTransport& aTransport) const;
+	virtual TInt SecondChannelRemoved(CAvctpTransport& aTransport) const;
+	virtual TInt CancelConnectRequest(CAvctpTransport& aTransport, TUint16 aClientId) const;
+	
+	// Events coming in on the user plane.
+	virtual void Shutdown(CAvctpTransport& aTransport, TInt aError) const;
+	
+	// Events coming from below, via the L2CAP SAP.  These are
+	// essentially state transitions caused by the remote end.
+	virtual void Disconnect(CAvctpTransport& aTransport) const;
+	virtual void ConnectComplete(CAvctpTransport& aTransport) const;
+	virtual void Error(CAvctpTransport& aTransport, TInt aError,TUint aOperationMask, TInt aChannel) const;
+	virtual TInt NewData(CAvctpTransport& aTransport, TUint aMtu, TInt aChannel) const;
+	virtual void CanSend(CAvctpTransport& aTransport, TInt aChannel) const;
+	
+#ifdef __FLOG_ACTIVE
+	TBuf<48> iName;
+#endif //__FLOG_ACTIVE
+
+protected:
+	// State change utility function
+	void ChangeState(CAvctpTransport& aTransport, CAvctpMuxerStateFactory::TAvctpMuxerStates aNewState) const;
+	void PanicInState(SymbianAvctp::TPanic aPanic) const;
+	void ShutDownSecondarySap(CAvctpTransport& aTransport, TBool aNotifyClient) const;
+private:
+    // Forbid copying
+	TAvctpMuxerState(const TAvctpMuxerState&);
+	const TAvctpMuxerState& operator=(const TAvctpMuxerState&) const;
+
+private:
+	/** The state factory, used to change states */
+	CAvctpMuxerStateFactory& iFactory;
+	};
+
+/**
+The closed state.
+
+This is the state that newly created saps start in, and the state
+they end in after a communication has closed down or a connection
+failed.
+
+Basically this is a quiescent state from which the Muxer can go to
+different futures though currently it commits suicide :] Note that
+though the delete attempts to be asynchronous, it's not guaranteed
+so it's best not to do anything with the muxer after changing state
+to closed.
+
+  @internalComponent
+*/
+NONSHARABLE_CLASS(TAvctpStateClosed) : public TAvctpMuxerState
+	{
+public:
+	TAvctpStateClosed(CAvctpMuxerStateFactory& aFactory);
+	
+	// "Artificial" state events
+	virtual void Enter(CAvctpTransport& aTransport) const;
+	virtual void Exit(CAvctpTransport& aTransport) const;
+	virtual void IdleTimerExpired(CAvctpTransport& aTransport) const;
+	
+	virtual TInt Start(CAvctpTransport& aTransport, const TBTDevAddr& aAddr, TUint16 aClientId) const;
+	// Events coming in on the control plane.
+	virtual TInt StartIncoming(CAvctpTransport& aTransport, const TBTDevAddr& aAddr, CServProviderBase* aL2CAPConSAP) const;
+	
+	};
+
+  
+/**
+The link pending state.
+
+Waiting for the L2CAP link to be created.
+
+  @internalComponent
+*/
+NONSHARABLE_CLASS(TAvctpStateLinkPending) : public TAvctpMuxerState
+ 	{
+public:
+	TAvctpStateLinkPending(CAvctpMuxerStateFactory& aFactory);	
+
+	// "Artificial" state events
+	virtual void Enter(CAvctpTransport& aTransport) const;
+
+	virtual TBool IsIdle(CAvctpTransport& aTransport) const;
+	
+	// Events coming in on the control plane.
+	virtual TInt CancelConnectRequest(CAvctpTransport& aTransport, TUint16 aClientId) const;
+	
+	// Events coming from below, via the L2CAP SAP.  These are
+	// essentially state transitions caused by the remote end.
+	virtual void ConnectComplete(CAvctpTransport& aTransport) const;
+	virtual void Error(CAvctpTransport& aTransport, TInt aError,TUint aOperationMask, TInt aChannel) const;
+	};
+
+
+/**
+The open state.
+
+We have an open L2CAP link with the remote device
+
+  @internalComponent
+*/
+NONSHARABLE_CLASS(TAvctpStateOpen) : public TAvctpMuxerState
+	{
+public:
+	TAvctpStateOpen(CAvctpMuxerStateFactory& aFactory);
+
+	// "Artificial" state events
+	virtual void Enter(CAvctpTransport& aTransport) const;
+	virtual void Exit(CAvctpTransport& aTransport) const;
+
+	virtual TInt Start(CAvctpTransport& aTransport, const TBTDevAddr& aAddr, TUint16 aClientId) const;
+	virtual TInt AddSecondChannel(CAvctpTransport& aTransport, CServProviderBase& aSAP) const;
+	
+	// Events coming in on the user plane.
+	virtual void Shutdown(CAvctpTransport& aTransport, TInt aError) const;
+
+	// Events coming from below, via the L2CAP SAP.  These are
+	// essentially state transitions caused by the remote end.
+	virtual void Disconnect(CAvctpTransport& aTransport) const;
+	virtual void Error(CAvctpTransport& aTransport, TInt aError,TUint aOperationMask, TInt aChannel) const;
+	virtual TInt NewData(CAvctpTransport& aTransport, TUint aMtu, TInt aChannel) const;
+	virtual void CanSend(CAvctpTransport& aTransport, TInt aChannel) const;
+	};
+
+
+/**
+The Second channel pending state.
+
+  @internalComponent
+*/
+NONSHARABLE_CLASS(TAvctpStateSecondChannelPending) : public TAvctpStateOpen
+	{
+public:
+	TAvctpStateSecondChannelPending(CAvctpMuxerStateFactory& aFactory);
+	
+	virtual void Enter(CAvctpTransport& aTransport) const;
+	virtual void Exit(CAvctpTransport& aTransport) const;
+	virtual TInt Start(CAvctpTransport& aTransport, const TBTDevAddr& aAddr, TUint16 aClientId) const;
+
+	// Events coming in on the user plane.
+	virtual void Shutdown(CAvctpTransport& aTransport, TInt aError) const;
+	
+	// Events coming from below, via the L2CAP SAP.  These are
+	// essentially state transitions caused by the remote end.
+	virtual void Disconnect(CAvctpTransport& aTransport) const;
+	virtual void Error(CAvctpTransport& aTransport, TInt aError,TUint aOperationMask, TInt aChannel) const;
+	virtual TInt NewData(CAvctpTransport& aTransport, TUint aMtu, TInt aChannel) const;
+	virtual void CanSend(CAvctpTransport& aTransport, TInt aChannel) const;
+	virtual void ConnectComplete(CAvctpTransport& aTransport) const;
+	virtual void RemoveSecondChannel(CAvctpTransport& aTransport) const;
+	};
+
+	
+/**
+The fully open state.
+
+We have an open L2CAP link with the remote device
+
+  @internalComponent
+*/
+NONSHARABLE_CLASS(TAvctpStateFullyOpen) : public TAvctpStateOpen
+	{
+public:
+	TAvctpStateFullyOpen(CAvctpMuxerStateFactory& aFactory);
+
+	// "Artificial" state events
+	virtual void Enter(CAvctpTransport& aTransport) const;
+	virtual void Exit(CAvctpTransport& aTransport) const;
+	
+	virtual TInt Start(CAvctpTransport& aTransport, const TBTDevAddr& aAddr, TUint16 aClientId) const;
+	virtual void RemoveSecondChannel(CAvctpTransport& aTransport) const;
+	virtual TInt SecondChannelRemoved(CAvctpTransport& aTransport) const;
+	
+	// Events coming in on the user plane.
+	virtual void Shutdown(CAvctpTransport& aTransport, TInt aError) const;
+
+	// Events coming from below, via the L2CAP SAP.  These are
+	// essentially state transitions caused by the remote end.
+	virtual void Disconnect(CAvctpTransport& aTransport) const;
+	virtual void Error(CAvctpTransport& aTransport, TInt aError,TUint aOperationMask, TInt aChannel) const;
+	virtual TInt NewData(CAvctpTransport& aTransport, TUint aMtu, TInt aChannel) const;
+	virtual void CanSend(CAvctpTransport& aTransport, TInt aChannel) const;
+	};
+	
+	
+#ifdef __FLOG_ACTIVE
+#define STATENAME(x)  iName=_L(x)
+#else
+#define STATENAME(x)
+#endif
+
+#endif // AVCTPTRANSPORTSTATES_H 
+