bluetooth/btstack/l2cap/l2capSigStates.h
changeset 0 29b1cd4cb562
child 23 32ba20339036
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/l2cap/l2capSigStates.h	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,366 @@
+// Copyright (c) 2004-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:
+// Implements the signalling state machine for an L2Cap Channel
+// 
+//
+
+#ifndef L2CAPSIGSTATES_H
+#define L2CAPSIGSTATES_H
+
+
+#include <e32base.h>
+#include <bt_sock.h>
+#include <es_prot.h>
+
+#include "L2CapChannelConfig.h"
+
+class CL2CapSAPSignalHandler;
+class CL2CAPSignalStateFactory;
+class CL2CAPConnectionSAP;
+class TL2CAPSigState;
+
+class HConnectionResponse;
+class HConfigureRequest;
+class HConfigureResponse;
+
+
+// Factory class for the L2CAP state machine.
+NONSHARABLE_CLASS(CL2CAPSignalStateFactory) : public CBase
+	{
+public:
+	enum TSigStates
+		{
+		EClosed,
+		EWaitConnectRsp,
+		EWaitConnect,
+		EWaitConfig,
+		EWaitSendConfig,
+		EWaitConfigReqRsp,
+		EWaitConfigRsp,
+		EWaitConfigReq,
+		EOpen,
+		EWaitDisconnect,
+		EMaxState,
+		};
+
+	TL2CAPSigState& GetState(const TSigStates aState) const;
+	TInt StateIndex(const TL2CAPSigState* aState) const;
+	
+	static CL2CAPSignalStateFactory* NewL();
+	~CL2CAPSignalStateFactory();
+
+private:
+	CL2CAPSignalStateFactory();
+	void ConstructL();
+
+private:	
+	TFixedArray<TL2CAPSigState*, EMaxState> iSigStates;
+	};
+
+
+// Base class for the L2CAP state machine.
+NONSHARABLE_CLASS(TL2CAPSigState)
+	{
+public:
+	friend class CL2CapSAPSignalHandler;
+
+	TL2CAPSigState(const CL2CAPSignalStateFactory& aFactory);
+	
+	// Events from the SAP
+	virtual void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	virtual void OpenChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	virtual void ConnectRequestReceived(CL2CapSAPSignalHandler& aSignalHandler) const;
+	virtual void ConfigureChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	virtual TInt UpdateChannelConfig(CL2CapSAPSignalHandler& aSignalHandler, const TL2CapConfig& aAPIConfig) const;
+
+	virtual TInt GetNegotiatedChannelMode(const CL2CapSAPSignalHandler& aSignalHandler, TL2CapChannelMode& aMode) const;
+
+	// L2CAP commands received from the peer.
+	virtual void ConnectResponse(CL2CapSAPSignalHandler& aSignalHandler,
+								 HConnectionResponse* aConnectionResponse) const;
+	
+	virtual void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
+							   HConfigureRequest* aConfigRequest) const;
+	virtual void ConfigResponse(CL2CapSAPSignalHandler& aSignalHandler,
+ 		                        HConfigureResponse* aConfigResponse) const;
+	virtual void DisconnectRequest(CL2CapSAPSignalHandler& aSignalHandler, TUint8 aId) const;
+	virtual void DisconnectResponse(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// Events from the Mux
+	virtual void Error(CL2CapSAPSignalHandler& aSignalHandler,
+	                   TInt aErrorCode, 
+	                   MSocketNotify::TOperationBitmasks aErrorAction) const;
+
+	// Change of state events
+	virtual void Enter(CL2CapSAPSignalHandler& aSignalHandler) const;
+	virtual void Exit(CL2CapSAPSignalHandler& aSignalHandler) const;
+	
+	// Signal command queue event
+	virtual void PendingCommandsDrained(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// Timers
+	virtual void ConfigurationTimerExpiry(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// Helpers
+	virtual TBool IsChannelClosed() const;
+	virtual TBool IsChannelOpen() const;
+	void HandleDisconnectRequest(CL2CapSAPSignalHandler& aSignalHandler, TUint8 aId) const;
+	void HandleSAPDisconnect(CL2CapSAPSignalHandler& aSignalHandler) const;
+	TInt SendConfigRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	TInt SendConfigResponse(CL2CapSAPSignalHandler& aSignalHandler, TConfigResponseResult aResult) const;
+	void DisconnectWithError(CL2CapSAPSignalHandler& aSignalHandler, TInt aError) const;
+
+protected:
+	void PanicInState(TL2CAPPanic aPanic) const;
+
+protected:
+	const CL2CAPSignalStateFactory& iFactory;  // Get states
+	};
+
+
+/**
+   The closed state.
+
+   This is the state that newly created signal handlers start in, and the state
+   they end in after a communication has closed down or a connection
+   failed.
+*/
+NONSHARABLE_CLASS(TL2CAPSigStateClosed) : public TL2CAPSigState
+	{
+public:
+	TL2CAPSigStateClosed(const CL2CAPSignalStateFactory& aFactory);
+
+	// Events from the SAP
+	void OpenChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void ConnectRequestReceived(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
+					   HConfigureRequest* aConfigRequest) const;
+
+	// Change of state state events
+	void Enter(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// Helpers
+	TBool IsChannelClosed() const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSigStateWaitConnectRsp) : public TL2CAPSigState
+/*
+   Waiting for a response to our ConnectRequest.
+*/
+	{
+public:
+	TL2CAPSigStateWaitConnectRsp(const CL2CAPSignalStateFactory& aFactory);
+
+	// Events from the SAP
+	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// L2CAP commands received from the peer.
+	void ConnectResponse(CL2CapSAPSignalHandler& aSignalHandler,
+						 HConnectionResponse* aConnectionResponse) const;
+	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
+						 HConfigureRequest* aConfigRequest) const;				 
+	
+	// Change of state state events
+	void Enter(CL2CapSAPSignalHandler& aSignalHandler) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSigStateWaitConnect) : public TL2CAPSigState
+ 	{
+public:
+	TL2CAPSigStateWaitConnect(const CL2CAPSignalStateFactory& aFactory);	
+
+	// Events from the SAP
+	void OpenChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	
+	// L2CAP commands received from the peer.
+	void DisconnectRequest(CL2CapSAPSignalHandler& aSignalHandler, TUint8 aId) const;
+
+	// Change of state state events
+	void PendingCommandsDrained(CL2CapSAPSignalHandler& aSignalHandler) const;
+	
+	};
+	
+NONSHARABLE_CLASS(TL2CAPSigStateConfigBase) : public TL2CAPSigState
+/*
+	This is the base class for the config states. It will NEVER be instantiated itself.
+*/
+	{
+public:
+	using TL2CAPSigState::ConfigRequest;
+	using TL2CAPSigState::ConfigResponse;
+	TL2CAPSigStateConfigBase(const CL2CAPSignalStateFactory& aFactory);	
+
+	// L2CAP commands received from the peer.
+	void DisconnectRequest(CL2CapSAPSignalHandler& aSignalHandler, TUint8 aId) const;
+
+	void Error(CL2CapSAPSignalHandler& aSignalHandler,
+	           TInt aErrorCode, 
+	           MSocketNotify::TOperationBitmasks aErrorAction) const;
+
+	// Events from the SAP
+	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	TInt UpdateChannelConfig(CL2CapSAPSignalHandler& aSignalHandler, const TL2CapConfig& aAPIConfig) const;
+
+	// Timer Events
+	void ConfigurationTimerExpiry(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// Common handling of Config Request and Response commands.
+	virtual void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
+					   HConfigureRequest* aConfigRequest,
+					   CL2CAPSignalStateFactory::TSigStates aConfigSuccessState) const;
+	virtual void ConfigResponse(CL2CapSAPSignalHandler& aSignalHandler,
+ 		                HConfigureResponse* aConfigResponse,
+ 		                CL2CAPSignalStateFactory::TSigStates aConfigSuccessState) const;
+	};
+
+	
+NONSHARABLE_CLASS(TL2CAPSigStateWaitConfig) : public TL2CAPSigStateConfigBase
+/*
+	No config requests/responses sent or received.
+	Waiting to receive peer L2Cap supported features.
+*/
+	{
+public:
+	TL2CAPSigStateWaitConfig(const CL2CAPSignalStateFactory& aFactory);	
+
+	// Events from the SAP
+	void ConfigureChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// L2CAP commands received from the peer.
+	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
+					   HConfigureRequest* aConfigRequest) const;
+
+	// Change of state state events
+	void Enter(CL2CapSAPSignalHandler& aSignalHandler) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSigStateWaitSendConfig) : public TL2CAPSigStateConfigBase
+/*
+	Remote's config request received and responded to with 'success'.
+	Waiting to send outgoing config request...
+	...waiting to receive peer L2Cap supported features.
+*/
+	{
+public:
+	TL2CAPSigStateWaitSendConfig(const CL2CAPSignalStateFactory& aFactory);	
+
+	// Events from the SAP
+	void ConfigureChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSigStateWaitConfigReqRsp) : public TL2CAPSigStateConfigBase
+/*
+	Outgoing config request sent.
+	Waiting for remote's config request, and remote's config response.
+*/
+	{
+public:
+	TL2CAPSigStateWaitConfigReqRsp(const CL2CAPSignalStateFactory& aFactory);	
+
+	// L2CAP commands received from the peer.
+	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
+					   HConfigureRequest* aConfigRequest) const;
+	void ConfigResponse(CL2CapSAPSignalHandler& aSignalHandler,
+ 	                    HConfigureResponse* aConfigResponse) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSigStateWaitConfigRsp) : public TL2CAPSigStateConfigBase
+/*
+	Remote's config request received and responded to with 'success'.
+	Outgoing config request sent.
+	Waiting for remote's config response.
+*/
+	{
+public:
+	TL2CAPSigStateWaitConfigRsp(const CL2CAPSignalStateFactory& aFactory);	
+
+	// L2CAP commands received from the peer.
+	void ConfigResponse(CL2CapSAPSignalHandler& aSignalHandler,
+ 	                    HConfigureResponse* aConfigResponse) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSigStateWaitConfigReq) : public TL2CAPSigStateConfigBase
+/*
+	Outgoing config request sent, and responded to with 'success'.
+	Waiting for remote's config request.
+*/
+	{
+public:
+	TL2CAPSigStateWaitConfigReq(const CL2CAPSignalStateFactory& aFactory);	
+
+	// L2CAP commands received from the peer.
+	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
+					   HConfigureRequest* aConfigRequest) const;
+	};
+	
+
+NONSHARABLE_CLASS(TL2CAPSigStateOpen) : public TL2CAPSigState
+/*
+	L2Cap logical link open. Data can be sent and received.
+*/
+	{
+public:
+	TL2CAPSigStateOpen(const CL2CAPSignalStateFactory& aFactory);	
+
+	// Events from the SAP
+	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// L2CAP commands received from the peer.
+	void DisconnectRequest(CL2CapSAPSignalHandler& aSignalHandler, TUint8 aId) const;
+	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,HConfigureRequest* aConfigRequest) const; 
+
+	// Config state events
+	TInt UpdateChannelConfig(CL2CapSAPSignalHandler& aSignalHandler, const TL2CapConfig& aAPIConfig) const;
+
+	// Change of state state events
+	void Enter(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	TBool IsChannelOpen() const;
+	TInt GetNegotiatedChannelMode(const CL2CapSAPSignalHandler& aSignalHandler, TL2CapChannelMode& aMode) const;
+	};
+
+NONSHARABLE_CLASS(TL2CAPSigStateWaitDisconnect) : public TL2CAPSigState
+/*
+	Logical link still exists but is waiting to be disconnected. 
+	NB Signalling can still be received, and should be handled.
+*/
+	{
+public:
+	TL2CAPSigStateWaitDisconnect(const CL2CAPSignalStateFactory& aFactory);	
+
+	// Events from the SAP
+	void CloseChannelRequest(CL2CapSAPSignalHandler& aSignalHandler) const;
+	TInt UpdateChannelConfig(CL2CapSAPSignalHandler& aSignalHandler, const TL2CapConfig& aAPIConfig) const;
+
+	// State changes from the Mux
+	void DisconnectRequest(CL2CapSAPSignalHandler& aSignalHandler, TUint8 aId) const;
+	void DisconnectResponse(CL2CapSAPSignalHandler& aSignalHandler) const;
+
+	// Change of state state events
+	void Enter(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void PendingCommandsDrained(CL2CapSAPSignalHandler& aSignalHandler) const;
+	void ConnectResponse(CL2CapSAPSignalHandler& aSignalHandler,
+					   HConnectionResponse* aConnectionResponse) const;
+	void ConfigRequest(CL2CapSAPSignalHandler& aSignalHandler,
+					   HConfigureRequest* aConfigRequest) const;
+
+	void ConfigResponse(CL2CapSAPSignalHandler& /*aSignalHandler*/,
+ 	                	HConfigureResponse* /*aConfigResponse*/) const;
+	void ConfigureChannelRequest(CL2CapSAPSignalHandler& /*aSignalHandler*/) const;
+	};
+
+#endif