diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btstack/linkmgr/ACLSAP.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetooth/btstack/linkmgr/ACLSAP.h Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,360 @@ +// Copyright (c) 2003-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 the ACL SAP class, and ACL State Classes (using State and Flyweight pattern) +// +// + +#ifndef _ACLSAP_H +#define _ACLSAP_H + +#include "debug.h" +#include <es_prot.h> +#include <es_mbuf.h> +#include <bluetooth/aclsockaddr.h> +#include "basebandsap.h" +#include "notification.h" +#include "linkutil.h" + +class CLinkMgrProtocol; +class CPhysicalLink; +class CPhysicalLinksManager; + +class TACLLinkState; +class CACLLink; +class CACLDataItem; +class CACLDataQController; + +/** + Factory for the ACL Link states + + The states are flyweight classes +**/ +NONSHARABLE_CLASS(CACLLinkStateFactory) : public CBase + { +public: + static CACLLinkStateFactory* NewL(); + ~CACLLinkStateFactory(); + enum TACLLinkStates + { + EClosed, + EListening, + EAccepting, + EWaitForLink, + EWaitForStart, + EWaitForStartError, + EWaitForStartParked, + EOpen, + EOpenParked, + EClosing, + // *** keep next one last *** + EACLLinkMaxState, + }; + + TACLLinkState& GetState(TACLLinkStates aState); + TInt StateIndex(const TACLLinkState* aState) const; +private: + void ConstructL(); + TFixedArray<TACLLinkState*, EACLLinkMaxState> iStates; + }; + + +NONSHARABLE_CLASS(TACLLinkState) + { +public: + TACLLinkState(CACLLinkStateFactory& aFactory); + + virtual void Enter(CACLLink& aContext) const; + + virtual void ActiveOpen(CACLLink& aContext) const; + virtual TInt PassiveOpen(CACLLink& aContext, TUint aQueSize) const; + virtual void Shutdown(CACLLink& aContext, CServProviderBase::TCloseType aCloseType) const; + virtual void DataReceived(CACLLink& aContext, TUint8 aFlag, const TDesC8& aData) const; + virtual TUint Write(CACLLink& aContext, const TDesC8& aData, TUint aOptions, TSockAddr* aAddr) const; + virtual void Start(CACLLink& aContext) const; + virtual TBool ConnectRequest(CACLLink& aContext, const TBTConnect& aConnectDetails, const CPhysicalLink& aPhysicalLink) const; + virtual void ConnectComplete(CACLLink& aContext, const TBTConnect& aConnectDetails) const; + virtual void Disconnection(CACLLink& aContext) const; + virtual void Error(CACLLink& aContext, TInt aError) const; + + virtual void Timeout(CACLLink& aContext, TBasebandTimeout aTimeout) const; + virtual void Exit(CACLLink& aContext) const; + virtual void Deletion(CACLLink& aContext) const; + + virtual TBool IsIdle() const; + virtual void Park(CACLLink& aContext) const; + virtual void Unpark(CACLLink& aContext) const; +protected: + // Exits old state, sets the new state, and enters it. + void ChangeState(CACLLink& aContext, CACLLinkStateFactory::TACLLinkStates aState) const; + void PanicInState(TLinkPanic aPanic) const; + +protected: + CACLLinkStateFactory& iFactory; +#ifdef __FLOG_ACTIVE + TBuf<48> iName; +#endif + }; + +NONSHARABLE_CLASS(TACLLinkStateListening) : public TACLLinkState + { +public: + TACLLinkStateListening(CACLLinkStateFactory& aFactory); + + void Enter(CACLLink& aContext) const; + + void Shutdown(CACLLink& aContext, CServProviderBase::TCloseType aCloseType) const; + TBool ConnectRequest(CACLLink& aContext, const TBTConnect& aConnect, const CPhysicalLink& aPhysicalLink) const; + + void Deletion(CACLLink& aContext) const; + + void Exit(CACLLink& aContext) const; + + void Error(CACLLink& aContext, TInt aError) const; +private: + void SpawnL(CACLLink& aContext, CPhysicalLink& aPhysicalLink) const; + }; + +NONSHARABLE_CLASS(TACLLinkStateAccepting) : public TACLLinkState + { +public: + TACLLinkStateAccepting(CACLLinkStateFactory& aFactory); + void Enter(CACLLink& aContext) const; + void Exit(CACLLink& aContext) const; + void ConnectComplete(CACLLink& aContext, const TBTConnect& aConnect) const; + void Error(CACLLink& aContext, TInt aError) const; + void Disconnection(CACLLink& aContext) const; + void Deletion(CACLLink& aContext) const; + void Timeout(CACLLink& aContext, TBasebandTimeout aTimeout) const; + void Shutdown(CACLLink& aContext, CServProviderBase::TCloseType aCloseType) const; + }; + +NONSHARABLE_CLASS(TACLLinkStateWaitForLink) : public TACLLinkState + { +public: + TACLLinkStateWaitForLink(CACLLinkStateFactory& aFactory); + + void Shutdown(CACLLink& aContext, CServProviderBase::TCloseType aCloseType) const; + void ConnectComplete(CACLLink& aContext, const TBTConnect& aConnectDetails) const; + void Error(CACLLink& aContext, TInt aError) const; + void Disconnection(CACLLink& aContext) const; + void Exit(CACLLink& aContext) const; + }; + +NONSHARABLE_CLASS(TACLLinkStateWaitForStart) : public TACLLinkState + { +public: + TACLLinkStateWaitForStart(CACLLinkStateFactory& aFactory); + void Enter(CACLLink& aContext) const; + void Start(CACLLink& aContext) const; + void Error(CACLLink& aContext, TInt aError) const; + void Deletion(CACLLink& aContext) const; + void Disconnection(CACLLink& aContext) const; + void Park(CACLLink& aContext) const; + void Shutdown(CACLLink& aContext, CServProviderBase::TCloseType aCloseType) const; + }; + +NONSHARABLE_CLASS(TACLLinkStateWaitForStartError) : public TACLLinkState + { +public: + TACLLinkStateWaitForStartError(CACLLinkStateFactory& aFactory); + void Start(CACLLink& aContext) const; + void Disconnection(CACLLink& aContext) const; + void Error(CACLLink& aContext, TInt aError) const; + void Deletion(CACLLink& aContext) const; + }; + +NONSHARABLE_CLASS(TACLLinkStateWaitForStartParked) : public TACLLinkStateWaitForStart + { +public: + TACLLinkStateWaitForStartParked(CACLLinkStateFactory& aFactory); + void Unpark(CACLLink& aContext) const; + void Start(CACLLink& aContext) const; + }; + + +NONSHARABLE_CLASS(TACLLinkStateOpen) : public TACLLinkState + { +public: + TACLLinkStateOpen(CACLLinkStateFactory& aFactory); + void Enter(CACLLink& aContext) const; + + TUint Write(CACLLink& aContext, const TDesC8& aData, TUint aOptions, TSockAddr* aAddr) const; + void DataReceived(CACLLink& aContext, TUint8 aFlag, const TDesC8& aData) const; + void Disconnection(CACLLink& aContext) const; + void Shutdown(CACLLink& aContext, CServProviderBase::TCloseType aCloseType) const; + void Park(CACLLink& aContext) const; + void Error(CACLLink& aContext, TInt aError) const; + void Exit(CACLLink& aContext) const; + }; + +NONSHARABLE_CLASS(TACLLinkStateOpenParked) : public TACLLinkStateOpen + { +public: + TACLLinkStateOpenParked(CACLLinkStateFactory& aFactory); + void Enter(CACLLink& aContext) const; + + TUint Write(CACLLink& aContext, const TDesC8& aData, TUint aOptions, TSockAddr* aAddr) const; + void DataReceived(CACLLink& aContext, TUint8 aFlag, const TDesC8& aData) const; + void Unpark(CACLLink& aContext) const; + + void Exit(CACLLink& aContext) const; + }; + +NONSHARABLE_CLASS(TACLLinkStateClosing) : public TACLLinkState + { +public: + TACLLinkStateClosing(CACLLinkStateFactory& aFactory); + + void ActiveOpen(CACLLink& aContext) const; + void Shutdown(CACLLink& aContext, CServProviderBase::TCloseType aCloseType) const; + void Disconnection(CACLLink& aContext) const; + void DataReceived(CACLLink& aContext, TUint8 aFlag, const TDesC8& aData) const; + TUint Write(CACLLink& aContext, const TDesC8& aData, TUint aOptions, TSockAddr* aAddr) const; + void Enter(CACLLink& aContext) const; + void Deletion(CACLLink& aContext) const; + + TBool IsIdle() const; + + void Error(CACLLink& aContext, TInt aError) const; + }; + +NONSHARABLE_CLASS(TACLLinkStateClosed) : public TACLLinkState + { +public: + TACLLinkStateClosed(CACLLinkStateFactory& aFactory); + + void Start(CACLLink& aContext) const; // CSockets Start + void Enter(CACLLink& aContext) const; + void ActiveOpen(CACLLink& aContext) const; + TInt PassiveOpen(CACLLink& aContext, TUint aQueSize) const; + void Shutdown(CACLLink& aContext, CServProviderBase::TCloseType aCloseType) const; + + void Deletion(CACLLink& aContext) const; + TBool IsIdle() const; + }; + + +NONSHARABLE_CLASS(CACLLink) : public CBTBasebandSAP, public MLogicalLink + { +friend class TACLLinkState; +friend class TACLLinkStateOpen; +friend class TACLLinkStateOpenParked; +friend class TACLLinkStateListening; +friend class TACLLinkStateAccepting; +friend class TACLLinkStateWaitForStart; +friend class TACLLinkStateWaitForStartParked; +friend class TACLLinkStateWaitForLink; +friend class TACLLinkStateClosing; +friend class TACLLinkStateClosed; +public: + static CACLLink* NewL(CPhysicalLinksManager& aLinksMan, + CPhysicalLink* aConnection, + CLinkMgrProtocol& aProtocol); + static CACLLink* NewLC(CPhysicalLinksManager& aLinksMan, + CPhysicalLink* aConnection, + CLinkMgrProtocol& aProtocol); + ~CACLLink(); + // from SAP + virtual void Start(); + virtual void AutoBind(); + virtual void LocalName(TSockAddr& anAddr) const ; + virtual TInt SetLocalName(TSockAddr& anAddr); + virtual void RemName(TSockAddr& anAddr) const ; + virtual TInt SetRemName(TSockAddr& anAddr); + virtual TInt GetOption(TUint level,TUint name,TDes8& anOption)const ; + virtual void Ioctl(TUint level,TUint name,TDes8* anOption); + virtual void CancelIoctl(TUint aLevel,TUint aName); + virtual TInt SAPSetOption(TUint level,TUint name,const TDesC8 &anOption); + + virtual void ActiveOpen(); + virtual TInt PassiveOpen(TUint aQueSize); + virtual void Shutdown(TCloseType option); + virtual void Shutdown(TCloseType option,const TDesC8& aDisconnectionData); + + + TUint Write(const TDesC8& aDesc,TUint aOptions, TSockAddr* aAddr); + + void GetData(TDes8& aDesc,TUint aOptions,TSockAddr* anAddr=NULL); + TInt GetData(RMBufChain& aData, TUint aLength, TUint aOptions, TSockAddr* aAddr=NULL); + + void Timeout(TBasebandTimeout aTimeout); + + TBool IsIdle() const; + TBool IsLocallyInitiated() const; + + void ACLDataReceived(THCIConnHandle aConnH, TUint8 aFlag, const TDesC8& aData); + +// from MLogicalLink + virtual TBool ConnectRequest(const TBTConnect& aConnect, const CPhysicalLink& aPhysicalLink); + virtual void ConnectComplete(const TBTConnect& aConnect); + virtual void Disconnection(); + virtual void Error(TInt aError); + virtual void DataReceived(THCIConnHandle aConnH, TUint8 aFlag, const TDesC8& aData); + + void PacketsSent(THCIConnHandle aConnH, TUint16 aNumPackets); + void PhysicalLinkChange(const TBTBasebandEventNotification& aEvent, CPhysicalLink& aPhysicalLink); + void TryToSend(); + +private: + CACLLink(CPhysicalLinksManager& aManager, + CPhysicalLink* aConnection, + CLinkMgrProtocol& aProtocol); + void ConstructL(); + void NotifyDataToSocket(TUint8 aFlag, const TDesC8& aData); + void CloseLogicalLink(); + TInt OpenLogicalLink(); + void ParkLogicalLink(); + void UnparkLogicalLink(); + void BindAndConnectPhysicalLinkL(); + void ClearPhysicalLink(); + TInt DoACLGetOption(TUint aName,TDes8& aOption) const; + TInt DoACLSetOption(TUint aName, const TDesC8& aOption); + TUint DoWrite(CACLDataItem& aFrame, CACLDataQController& aQctrl, + const TDesC8& aData, TUint8 aOptions); + TBool CanHandleFlags(TUint8 aFlag) const; + + TInt ProcessFlush(); + +private: // from MAccessRequestResponseHandler + void AccessRequestComplete(TInt aResult); + +private: + enum TInitiationState + { + EInvalidInitiationState = 0x00, + ELocallyInitiated = 0x01, + ERemotelyInitiated = 0x02, + }; + void SetInitiationState(TInitiationState aState); + void ClearInitiationState(); + +private: + CLinkMgrProtocol& iProtocol; + TACLLinkState* iState; + + RMBufPktQ iInboundBuffer; + + TACLPort iLocalPort; // based on PB flags + TBool iSocketBlocked; + + TInitiationState iInitiationState; // simpler than modelling in state machine. + }; + +#ifdef __FLOG_ACTIVE +#define STATENAME(x) iName=_L(x) +#else +#define STATENAME(x) +#endif + +#endif // _ACLSAP_H