bluetooth/btstack/l2cap/l2sapstates.h
changeset 0 29b1cd4cb562
child 48 22de2e391156
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/l2cap/l2sapstates.h	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,484 @@
+// Copyright (c) 1999-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 L2CAP sap can
+// be in.
+// Note we assume for all states that the socket will only send us
+// reasonable state change requests - i.e. it won't call PassiveOpen
+// on a connected socket.  We make no such assumption about events
+// coming from the Mux
+// 
+//
+
+
+#ifndef L2CAPSAPSTATES_H
+#define L2CAPSAPSTATES_H
+
+#include <e32base.h>
+#include <es_prot.h>
+#include <bt_sock.h>
+
+
+#include "L2CapChannelConfig.h"
+#include "L2types.h"
+
+class CL2CAPConnectionSAP;
+class CL2CAPSAPStateFactory;
+
+class CL2CAPMux;
+
+NONSHARABLE_CLASS(TL2CAPSAPState)
+	{
+public:
+	friend class CL2CAPConnectionSAP;
+
+	TL2CAPSAPState(CL2CAPSAPStateFactory& aFactory);
+
+	
+	// Events called from the SAP.  As we assume that the socket
+	// will never send us requests which are invalid for our state,
+	// the default is to do nothing.  Derived state classes can then
+	// simply implement the appropriate bits.
+	virtual void Start(CL2CAPConnectionSAP& aSAP) const;
+
+	virtual TInt Ioctl(CL2CAPConnectionSAP& aSAP, TUint aLevel, TUint aName, TDes8* aOption) const;
+	virtual void CancelIoctl(CL2CAPConnectionSAP& aSAP, TUint aLevel, TUint aName) const;
+	virtual void IoctlComplete(CL2CAPConnectionSAP& aSAP, TInt aErr, TUint aLevel, TUint aName, TDesC8* aBuf) const;
+
+	virtual void ActiveOpen(CL2CAPConnectionSAP& aSAP) const;
+	virtual TInt PassiveOpen(CL2CAPConnectionSAP& aSAP, TUint aQueSize) const;
+	virtual void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+	virtual void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	
+	virtual TInt Send(CL2CAPConnectionSAP& aSAP, RMBufChain& aData, TUint aFlag) const;
+	virtual TInt Read(CL2CAPConnectionSAP& aSAP, RMBufChain& aData) const;
+
+	virtual void Bound(CL2CAPConnectionSAP& aSAP) const;
+	
+	// Events called from the SAP Signal Handler.
+	virtual void ChannelConfigured(CL2CAPConnectionSAP& aSAP,
+	                               CL2CapChannelConfig& aConfig,
+                                   CL2CAPMux& aMuxer,
+                                   TL2CAPPort aLocalPort,
+                                   TL2CAPPort aRemotePort);
+                                       
+	virtual void ReconfiguringChannel(CL2CAPConnectionSAP& aSAP) const;
+
+	virtual void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+	virtual void CloseOutgoingSDUQueue(CL2CAPConnectionSAP& aSAP) const;
+	virtual void SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+	virtual void LinkUp(CL2CAPConnectionSAP& aSAP) const;
+	virtual void ChannelOpened(CL2CAPConnectionSAP& aSAP) const;
+
+	// Events called from the Data Controller.
+	virtual void NewData(CL2CAPConnectionSAP& aSAP) const;
+	virtual TInt NewDataAsyncCallBack(CL2CAPConnectionSAP& aSAP) const;
+	virtual void CanSend(CL2CAPConnectionSAP& aSAP) const;
+	virtual void SDUQueueClosed(CL2CAPConnectionSAP& aSAP) const;
+	virtual void DataPlaneError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+
+	// Events from the security manager.
+	virtual void AccessRequestComplete(CL2CAPConnectionSAP& aSignalHandler, TInt aResult) const;
+	
+	// State Transition Actions.
+	virtual void Enter(CL2CAPConnectionSAP& aSAP) const;
+	virtual void Exit(CL2CAPConnectionSAP& aSAP) const;
+	
+	// Helper function.
+	void NotifySocketClosed(CL2CAPConnectionSAP& aSAP) const;
+
+protected:
+	void StartCalledWhileDisconnected(CL2CAPConnectionSAP& aSAP) const;
+	void PanicInState(TL2CAPPanic aPanic) const;
+	void DebugPanicInState(TL2CAPPanic aPanic) const;
+	
+protected:
+	CL2CAPSAPStateFactory& iFactory;  // Used to get next state.
+
+private:
+    // Forbid copying
+	TL2CAPSAPState(const TL2CAPSAPState&);
+	const TL2CAPSAPState& operator=(const TL2CAPSAPState&) const;
+	};
+
+
+
+
+/**
+   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 sap can go to
+   different futures.
+**/
+
+NONSHARABLE_CLASS(TL2CAPSAPStateClosed) : public TL2CAPSAPState
+	{
+public:
+	TL2CAPSAPStateClosed(CL2CAPSAPStateFactory& aFactory);
+
+	// Events called from the SAP.
+	void Start(CL2CAPConnectionSAP& aSAP) const;
+	void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+	
+	void ActiveOpen(CL2CAPConnectionSAP& aSAP) const;
+	void SDUQueueClosed(CL2CAPConnectionSAP& aSAP) const;
+
+	void Bound(CL2CAPConnectionSAP& aSAP) const;
+	
+	// Events called from the SAP Signal Handler.
+	void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+ 	void SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+	
+	// Events called from the Data Controller.
+	TInt NewDataAsyncCallBack(CL2CAPConnectionSAP& aSAP) const;
+		
+	// State Transition Actions.
+	void Enter(CL2CAPConnectionSAP& aSAP) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSAPStateChannelPendingBase) : public TL2CAPSAPState
+ 	{
+public:
+	TL2CAPSAPStateChannelPendingBase(CL2CAPSAPStateFactory& aFactory);	
+
+	// Events called from the SAP.
+	virtual void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	virtual void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+
+	// Events called from the SAP Signal Handler.
+	virtual void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+ 	virtual void SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+ 	};
+ 	
+NONSHARABLE_CLASS(TL2CAPSAPStatePassiveLinkPending) : public TL2CAPSAPStateChannelPendingBase
+ 	{
+public:
+	TL2CAPSAPStatePassiveLinkPending(CL2CAPSAPStateFactory& aFactory);	
+
+	// Events called from the SAP Signal Handler.
+	void LinkUp(CL2CAPConnectionSAP& aSAP) const;
+ 	};
+
+NONSHARABLE_CLASS(TL2CAPSAPStateActiveLinkPending) : public TL2CAPSAPStateChannelPendingBase
+ 	{
+public:
+	TL2CAPSAPStateActiveLinkPending(CL2CAPSAPStateFactory& aFactory);	
+
+	// Events called from the SAP Signal Handler.
+	void LinkUp(CL2CAPConnectionSAP& aSAP) const;
+ 	};
+
+NONSHARABLE_CLASS(TL2CAPSAPStateActiveSecMode4AccessRequestPending) : public TL2CAPSAPStateChannelPendingBase
+	{
+public:
+	TL2CAPSAPStateActiveSecMode4AccessRequestPending(CL2CAPSAPStateFactory& aFactory);
+	
+	// Events called from the SAP.
+	void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+
+	// Events called from the SAP Signal Handler.
+	void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+ 	void SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+	
+	void AccessRequestComplete(CL2CAPConnectionSAP& aSignalHandler, TInt aResult) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSAPStateActiveChannelRequestPending) : public TL2CAPSAPStateChannelPendingBase
+	{
+public:
+	TL2CAPSAPStateActiveChannelRequestPending(CL2CAPSAPStateFactory& aFactory);
+	
+	// Events called from the SAP Signal Handler.
+	void ChannelOpened(CL2CAPConnectionSAP& aSAP) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSAPStatePassiveAccessRequestPending) : public TL2CAPSAPStateChannelPendingBase
+ 	{
+public:
+	TL2CAPSAPStatePassiveAccessRequestPending(CL2CAPSAPStateFactory& aFactory);	
+
+	// Events called from the SAP.
+	void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+
+	// Events called from the SAP Signal Handler.
+	void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+ 	void SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+
+	// Events from the security manager.
+	void AccessRequestComplete(CL2CAPConnectionSAP& aSignalHandler, TInt aResult) const;
+ 	};
+
+NONSHARABLE_CLASS(TL2CAPSAPStateActiveSecMode2AccessRequestPending) : public TL2CAPSAPStateChannelPendingBase
+ 	{
+public:
+	TL2CAPSAPStateActiveSecMode2AccessRequestPending(CL2CAPSAPStateFactory& aFactory);	
+
+	// Events called from the SAP.
+	void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+
+	// Events called from the SAP Signal Handler.
+	void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+ 	void SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+
+	// Events from the security manager.
+	void AccessRequestComplete(CL2CAPConnectionSAP& aSignalHandler, TInt aResult) const;
+ 	};
+
+
+NONSHARABLE_CLASS(TL2CAPSAPStatePendingOpen) : public TL2CAPSAPStateChannelPendingBase
+	{
+public:
+	TL2CAPSAPStatePendingOpen(CL2CAPSAPStateFactory& aFactory);
+
+	// Events called from the SAP Signal Handler.
+	void ChannelConfigured(CL2CAPConnectionSAP& aSAP,
+	                       CL2CapChannelConfig& aConfig,
+                           CL2CAPMux& aMuxer,
+                           TL2CAPPort aLocalPort,
+                           TL2CAPPort aRemotePort);
+
+	// Events called from the Data Controller.
+	void DataPlaneError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;	
+
+	// State Transition Actions.
+	};
+
+
+NONSHARABLE_CLASS(TL2CAPSAPStateListening) : public TL2CAPSAPState
+	{
+public:
+	TL2CAPSAPStateListening(CL2CAPSAPStateFactory& aFactory);
+
+	// Events called from the SAP.
+	void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+	void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	
+	// Events called from the SAP Signal Handler.
+	void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+
+	// Events called from the Data Controller.
+	
+	// State Transition Actions.
+	void Enter(CL2CAPConnectionSAP& aSAP) const;
+	void Exit(CL2CAPConnectionSAP& aSAP) const;	
+	};
+
+
+NONSHARABLE_CLASS(TL2CAPSAPStateOpen) : public TL2CAPSAPState
+	{
+public:
+	TL2CAPSAPStateOpen(CL2CAPSAPStateFactory& aFactory);
+
+	// Events called from the SAP.
+	virtual TInt Send(CL2CAPConnectionSAP& aSAP, RMBufChain& aData, TUint aFlag) const;
+	virtual TInt Read(CL2CAPConnectionSAP& aSAP, RMBufChain& aData) const;
+
+	virtual void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+	virtual void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	
+	// Events called from the SAP Signal Handler.
+	virtual void ReconfiguringChannel(CL2CAPConnectionSAP& aSAP) const;
+	virtual void ChannelConfigured(CL2CAPConnectionSAP& aSAP,
+	                       		   CL2CapChannelConfig& aConfig,
+                                   CL2CAPMux& aMuxer,
+                                   TL2CAPPort aLocalPort,
+                                   TL2CAPPort aRemotePort);
+	virtual void SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+	virtual void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+	virtual void CloseOutgoingSDUQueue(CL2CAPConnectionSAP& aSAP) const;
+
+	// Events called from the Data Controller.
+	virtual void NewData(CL2CAPConnectionSAP& aSAP) const;
+	virtual TInt NewDataAsyncCallBack(CL2CAPConnectionSAP& aSAP) const;
+	virtual void CanSend(CL2CAPConnectionSAP& aSAP) const;
+	virtual void DataPlaneError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;	
+	
+	// State Transition Actions.
+	};
+
+NONSHARABLE_CLASS(TL2CAPSAPStateAccepting) : public TL2CAPSAPStateOpen
+	{
+public:
+	TL2CAPSAPStateAccepting(CL2CAPSAPStateFactory& aFactory);
+
+	// Events called from the SAP.
+	void Start(CL2CAPConnectionSAP& aSAP) const;
+	void NewData(CL2CAPConnectionSAP& aSAP) const;
+	
+	// Events called from the SAP Signal Handler.
+	void ReconfiguringChannel(CL2CAPConnectionSAP& aSAP) const;
+	
+	// Events called from the Data Controller.
+	TInt NewDataAsyncCallBack(CL2CAPConnectionSAP& aSAP) const;
+	void CanSend(CL2CAPConnectionSAP& aSAP) const;
+	
+	// State Transition Actions.
+	void Exit(CL2CAPConnectionSAP& aSAP) const;	
+	};
+
+/**
+This state exists to determine if the other side believes the link is opened.
+It won't send us data until it has finished configuring the channel.  On
+reception of data the Signal Handler will be informed before moving the state
+machine on to fully open.
+*/
+NONSHARABLE_CLASS(TL2CAPSAPStateAwaitingInitialData) : public TL2CAPSAPStateOpen
+	{
+public:
+	TL2CAPSAPStateAwaitingInitialData(CL2CAPSAPStateFactory& aFactory);
+	
+	// Events called from the SAP Signal Handler.
+	void ReconfiguringChannel(CL2CAPConnectionSAP& aSAP) const;
+
+	// Events called from the Data Controller.
+	void NewData(CL2CAPConnectionSAP& aSAP) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSAPStateDisconnecting) : public TL2CAPSAPState
+	{
+public:
+	TL2CAPSAPStateDisconnecting(CL2CAPSAPStateFactory& aFactory);
+
+	// Events called from the SAP.
+	void Start(CL2CAPConnectionSAP& aSAP) const;
+	TInt Send(CL2CAPConnectionSAP& aSAP, RMBufChain& aData, TUint aFlag) const;
+	TInt Read(CL2CAPConnectionSAP& aSAP, RMBufChain& aData) const;
+
+	void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+	void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+
+	
+	// Events called from the SAP Signal Handler.
+	void ChannelConfigured(CL2CAPConnectionSAP& aSAP,
+						   CL2CapChannelConfig& aConfig,
+						   CL2CAPMux& aMuxer,
+						   TL2CAPPort aLocalPort,
+						   TL2CAPPort aRemotePort);
+
+	void ReconfiguringChannel(CL2CAPConnectionSAP& aSAP) const;
+
+	void SignalHandlerError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;
+	void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+	void CloseOutgoingSDUQueue(CL2CAPConnectionSAP& aSAP) const;
+	
+	// Events called from the Data Controller.
+	void SDUQueueClosed(CL2CAPConnectionSAP& aSAP) const;
+	void NewData(CL2CAPConnectionSAP& aSAP) const;
+	TInt NewDataAsyncCallBack(CL2CAPConnectionSAP& aSAP) const;
+	void CanSend(CL2CAPConnectionSAP& aSAP) const;
+	void DataPlaneError(CL2CAPConnectionSAP& aSAP, TInt aErrorCode, MSocketNotify::TOperationBitmasks aErrorAction) const;	
+	
+	// State Transition Actions.
+	};
+
+
+NONSHARABLE_CLASS(TL2CAPSAPStateError) : public TL2CAPSAPState
+	{
+public:
+	TL2CAPSAPStateError(CL2CAPSAPStateFactory& aFactory);
+
+	// Events called from the SAP.
+	void Start(CL2CAPConnectionSAP& aSAP) const;
+
+	TInt Ioctl(CL2CAPConnectionSAP& aSAP, TUint aLevel, TUint aName, TDes8* aOption) const;
+	void CancelIoctl(CL2CAPConnectionSAP& aSAP, TUint aLevel, TUint aName) const;
+	void IoctlComplete(CL2CAPConnectionSAP& aSAP, TInt aErr, TUint aLevel, TUint aName, TDesC8* aBuf) const;
+
+	void ActiveOpen(CL2CAPConnectionSAP& aSAP) const;
+	TInt PassiveOpen(CL2CAPConnectionSAP& aSAP, TUint aQueSize) const;
+	void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+	void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+	
+	TInt Send(CL2CAPConnectionSAP& aSAP, RMBufChain& aData, TUint aFlag) const;
+	TInt Read(CL2CAPConnectionSAP& aSAP, RMBufChain& aData) const;
+
+	// Events called from the SAP Signal Handler.
+	void ChannelClosed(CL2CAPConnectionSAP& aSAP) const;
+
+	// State Transition Actions.
+	void Enter(CL2CAPConnectionSAP& aSAP) const;	
+	};
+
+/**
+   The BOUND state.
+
+   This is the state that freshly bound saps are in. This state should 
+   only be reached once for each sap since ESOCK doesn't allow rebinding 
+   or unbinding of saps. 
+
+   A sap can be bound from an ESOCK point of view but not be in this state.
+   Then the sap will either be on the listening path or Closed.
+**/
+
+NONSHARABLE_CLASS(TL2CAPSAPStateBound) : public TL2CAPSAPState
+	{
+public:
+	TL2CAPSAPStateBound(CL2CAPSAPStateFactory& aFactory);
+
+	// Events called from the SAP.
+	TInt PassiveOpen(CL2CAPConnectionSAP& aSAP, TUint aQueSize) const;	
+	void Shutdown(CL2CAPConnectionSAP& aSAP) const;
+	void FastShutdown(CL2CAPConnectionSAP& aSAP) const;
+
+	// State Transition Actions.
+	void Enter(CL2CAPConnectionSAP& aSAP) const;
+	void Exit(CL2CAPConnectionSAP& aSAP) const;	
+	};
+	
+
+NONSHARABLE_CLASS(CL2CAPSAPStateFactory) : public CBase
+	{
+friend class CL2CAPProtocol;	
+public:
+	enum TStates
+		{
+		EClosed = 0,
+		EPassiveLinkPending,
+		EActiveLinkPending,
+		EPassiveAccessRequestPending,
+		EActiveSecMode2AccessRequestPending,
+		EPendingOpen,
+		EListening,
+		EAccepting,
+		EAwaitingInitialData,
+		EOpen,
+		EDisconnecting,
+		EError,
+		EBound,
+		EActiveSecMode4AccessRequestPending,
+		EActiveChannelRequestPending,
+		EMaxState,
+		};
+	
+	TL2CAPSAPState& GetState(const TStates aState) const;
+	TInt StateIndex(const TL2CAPSAPState* aState) const;
+
+	~CL2CAPSAPStateFactory();
+
+private:
+	static CL2CAPSAPStateFactory* NewL();
+	CL2CAPSAPStateFactory();
+
+	TFixedArray<TL2CAPSAPState*, EMaxState> iStates;
+	};
+
+	
+#endif