bluetooth/btstack/linkmgr/ACLSAP.h
changeset 0 29b1cd4cb562
child 8 2b6718f05bdb
--- /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