diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btstack/l2cap/l2capSigStates.h --- /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 +#include +#include + +#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 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