--- /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