bluetooth/btstack/linkmgr/SCOSAP.h
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/linkmgr/SCOSAP.h	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,416 @@
+// 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 SCO SAP class, and SCO State Classes (using State and Flyweight pattern)
+// 
+//
+
+#ifndef _SCOSAP_H_
+#define _SCOSAP_H_
+
+#include "debug.h"
+#include "basebandsap.h"
+#include "notification.h"
+#include "Basebandmodel.h"
+#include "internaltypes.h"
+#include "linkutil.h"
+
+class CPhysicalLink;
+class CHctlSynchronousDataFrame;
+
+static const TInt KInboundSCODataSize  = 255;
+static const TInt KMinESCOPacketSize = 1;
+static const TInt KMinESCOBandwidth = 1;
+static const TInt KMilliSecondsFactor = 1000;
+static const TInt KBasebandSlotsPerSecond = 1600;
+
+static const TInt KMaxEV3Size = 30;
+static const TInt KMaxEV4Size = 120;
+static const TInt KMaxEV5Size = 180;
+
+static const TInt KEV3Slots = 1;
+static const TInt KEV4Slots = 3;
+static const TInt KEV5Slots = 3;
+
+
+class TSyncLinkState;
+
+NONSHARABLE_CLASS(CBTSynchronousLink) : public CBTBasebandSAP, public MLogicalLink
+	{
+	friend class TSyncLinkState;
+	friend class TSCOLinkStateClosed;
+	friend class TSCOLinkStateWaitForSCO;
+	friend class TSCOLinkStateListening;
+	friend class TSCOLinkStateAccepting;
+	friend class TSCOLinkStateWaitForStart;
+	friend class TSCOLinkStateWaitForStartError;
+	friend class TSCOLinkStateOpen;
+	friend class TSCOLinkStateClosing;
+	
+	public:
+		~CBTSynchronousLink();
+
+		virtual void Start();
+		virtual void ActiveOpen();
+		virtual TInt PassiveOpen(TUint aQueSize);
+		virtual void Shutdown(TCloseType option);
+		virtual void Shutdown(TCloseType aClose, const TDesC8& /*aDisconnectionData*/);
+		virtual void AutoBind();
+		virtual TUint Write(const TDesC8& aDesc,TUint aOptions, TSockAddr* aAddr);
+		virtual void GetData(TDes8& aDesc,TUint options,TSockAddr* aAddr=NULL);
+		virtual TInt SetLocalName(TSockAddr& aAddr);
+		virtual TInt SetRemName(TSockAddr& aAddr);
+		
+		virtual TInt SAPSetOption(TUint level, TUint name, const TDesC8& aOption) =0;
+		virtual TInt GetOption(TUint level, TUint name, TDes8& aOption) const =0;
+		
+		// Pure virtuals from base classes
+		virtual void Timeout(TBasebandTimeout aTimeout);
+		virtual void PacketsSent(THCIConnHandle /*aHandle*/, TUint16 /*aNumPackets*/);
+
+		void PhysicalLinkChange(const TBTBasebandEventNotification& aEvent, CPhysicalLink& aPhysicalLink);
+
+
+		virtual TBool ConnectRequest(const TBTConnect& aConnect, const CPhysicalLink& aPhysicalLink);
+		virtual void ConnectComplete(const TBTConnect& aSCOLink);
+		virtual void SyncConnectComplete(const TBTConnect& aSCOLink, const TBTSyncConnectOpts& aSyncOpts);
+		virtual void Disconnection();
+		virtual void Error(TInt aErr);
+		virtual void DataReceived(THCIConnHandle aConnH, TUint8 aIgnored, const TDesC8& aData);
+		virtual TBool IsIdle() const;
+		virtual TBool IsOpen() const;
+	
+		TInt CommonShutdown();
+		void DoActiveOpenL();
+		void ReleaseAndUnbind();
+		
+		virtual TUint DoWrite(const TDesC8& aData, TUint aOptions, TSockAddr* aAddr) =0;
+		virtual TDes8& InboundFrame() =0;
+		virtual TBool IsLinkProbablyPossible() =0;
+		virtual TInt MakeConnection(CPhysicalLink* aPhysLink) =0;
+		virtual void SetExtOptions(TBTSyncConnectOpts aSyncOpts) =0;
+		
+		inline const TLinkType& LinkType() { return iLinkType; };
+		
+		void ParentClosing();
+		TBool ConnectPending() const;
+	
+	protected:
+		CBTSynchronousLink(CPhysicalLinksManager& aLinksMan, CPhysicalLink* aPhysicalLink, TLinkType aLinkType);
+		void ConstructL();
+
+
+	protected:
+		TSyncLinkState*	iState;
+		TBool			iClosePending;
+		TLinkType		iLinkType;
+	};
+
+
+NONSHARABLE_CLASS(CSCOLink) : public CBTSynchronousLink
+/**
+	Provides a representation of the SCO link(s)
+
+	This are created when the (linkmgr) protocol is asked
+	for a SAP with KBTSCOLink type.
+
+
+**/
+	{
+public:
+	static CSCOLink* NewLC(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aConnection);
+	static CSCOLink* NewL(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aConnection);
+	~CSCOLink();
+	// from CServProviderBase
+	virtual TInt SAPSetOption(TUint aLevel, TUint aName, const TDesC8& aOption);
+	virtual TInt GetOption(TUint level, TUint name, TDes8& aOption) const;
+	
+// events for the SCO Link (not PHY)
+	void PacketTypeChange(THCIErrorCode aErr, THCIConnHandle aConnH, TUint16 aNewPacket);
+
+	TDes8& InboundFrame();
+	TBool IsLinkProbablyPossible();
+	TInt MakeConnection(CPhysicalLink* aPhysLink);	
+	
+private:
+	CSCOLink(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aConnection);
+	void ConstructL();
+	TUint DoWrite(const TDesC8& aData, TUint aOptions, TSockAddr* aAddr);
+	void SetExtOptions(TBTSyncConnectOpts aSyncOpts);
+
+
+private:
+	CHctlSynchronousDataFrame*	iOutboundSCOFrame;
+	TBuf8<KInboundSCODataSize>	iInboundSCOFrame;
+	TBTSyncPacketTypes			iUserHVPacketTypes;
+	};
+
+
+NONSHARABLE_CLASS(CeSCOLink) : public CBTSynchronousLink
+/**
+	Provides a representation of the eSCO link(s)
+
+	This are created when the (linkmgr) protocol is asked
+	for a SAP with KBTeSCOLink type.
+**/
+	{
+public:
+	static CeSCOLink* NewLC(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aConnection);
+	static CeSCOLink* NewL(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aConnection);
+	~CeSCOLink();
+	// from CServProviderBase
+	virtual TInt SAPSetOption(TUint aLevel, TUint aName, const TDesC8& aOption);
+	virtual TInt GetOption(TUint level, TUint name, TDes8& aOption) const;
+	
+// events for the SCO Link (not PHY)
+	void PacketTypeChange(THCIErrorCode aErr, THCIConnHandle aConnH, TUint16 aNewPacket);
+
+	TDes8& InboundFrame();
+	TBool IsLinkProbablyPossible();
+	TInt MakeConnection(CPhysicalLink* aPhysLink);	
+	void SetExtOptions(TBTSyncConnectOpts aSyncOpts);
+	
+	TUint16 GetPacketMask() const;
+	void GetExtOptions(TBTeSCOLinkParams& aOptions) const;
+
+private:
+	CeSCOLink(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aConnection);
+	void ConstructL();
+	TUint DoWrite(const TDesC8& aData, TUint aOptions, TSockAddr* aAddr);
+
+	TUint MinBandwidth();
+	TUint MaxBandwidth();
+
+private:
+	CHctlSynchronousDataFrame*	iOutboundSCOFrame;
+	TBuf8<KInboundSCODataSize>	iInboundSCOFrame;
+	TBTSyncPacketTypes			iUserPacketTypes;
+	TUint						iTransmitBandwidth;
+	TUint						iReceiveBandwidth;
+	TUint16						iMaxLatency;
+	TUint16						iVoiceSettings;
+	TUint8						iRetransmissionEffort;
+	};
+
+
+
+//--------------------------------------------------
+// STATE FACTORY
+//--------------------------------------------------
+
+/**
+   Factory for the ACL Link states
+
+   The states are flyweight classes
+**/
+NONSHARABLE_CLASS(CSyncLinkStateFactory) : public CBase
+	{
+public:
+	static CSyncLinkStateFactory* NewL();
+	~CSyncLinkStateFactory();
+	enum TSyncLinkStates
+		{
+		EClosed,
+		EListening,
+		EAccepting,
+		EWaitForStart,
+		EWaitForStartError,
+		EWaitForSCO,
+		EOpen,	
+		EClosing,
+	// *** keep next one last ***
+		ESyncLinkMaxState,
+		};
+	
+	TSyncLinkState& GetState(TSyncLinkStates aState);
+	TInt StateIndex(const TSyncLinkState* aState) const;
+private:
+	void ConstructL();
+	TFixedArray<TSyncLinkState*, ESyncLinkMaxState> iStates;
+	};
+
+
+
+//--------------------------------------------------
+// STATES 
+//--------------------------------------------------
+
+NONSHARABLE_CLASS(TSyncLinkState)
+	{
+public:
+	TSyncLinkState(CSyncLinkStateFactory& aFactory);
+
+	virtual void Enter(CBTSynchronousLink& aContext) const;
+
+	virtual void ActiveOpen(CBTSynchronousLink& aContext) const;
+	virtual TInt PassiveOpen(CBTSynchronousLink& aContext, TUint aQueSize) const;
+	virtual void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+
+	virtual void DataReceived(CBTSynchronousLink& aContext, const TDesC8& aData) const;
+	virtual void ConnectComplete(CBTSynchronousLink& aContext, const TBTConnect& aSCOInfo, const TBTSyncConnectOpts& aSyncOpts) const;
+	virtual void Disconnection(CBTSynchronousLink& aContext) const;
+	virtual void Error(CBTSynchronousLink& aContext, TInt aErr) const;
+	virtual TBool ConnectRequest(CBTSynchronousLink& aContext, const TBTConnect& aSCOLink, const CPhysicalLink& aPhysicalLink) const;
+
+	virtual void PacketTypeChange(CBTSynchronousLink& aContext, THCIErrorCode aErr, THCIConnHandle aConnH, TUint16 aNewPacket) const;
+	virtual TUint Write(CBTSynchronousLink& aContext, const TDesC8& aData, TUint aOptions, TSockAddr* aAddr) const;
+	virtual void Start(CBTSynchronousLink& aContext) const;
+	virtual void Exit(CBTSynchronousLink& aContext) const;
+	virtual void Deletion(CBTSynchronousLink& aContext) const;
+	virtual TBool IsIdle() const;
+	virtual TBool IsOpen() const;
+	virtual void Timeout(CBTSynchronousLink& aContext, TBasebandTimeout aTimeout) const;
+	virtual void ParentClosing(CBTSynchronousLink& aContext) const;
+	virtual TBool IsConnectPending() const;
+
+protected:
+	// Exits old state, sets the new state, and enters it.
+	void ChangeState(CBTSynchronousLink& aContext, CSyncLinkStateFactory::TSyncLinkStates aState) const;
+	void PanicInState(TLinkPanic aPanic) const;
+
+protected:
+	CSyncLinkStateFactory& iFactory;
+#ifdef __FLOG_ACTIVE
+	TBuf<48> iName;
+#endif
+	};
+
+
+NONSHARABLE_CLASS(TSCOLinkStateClosed) : public TSyncLinkState
+	{
+public:
+	TSCOLinkStateClosed(CSyncLinkStateFactory& aFactory);
+
+	void Enter(CBTSynchronousLink& aContext) const;
+
+	void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+	void Deletion(CBTSynchronousLink& aContext) const;
+	void ActiveOpen(CBTSynchronousLink& aContext) const;
+	TInt PassiveOpen(CBTSynchronousLink& aContext, TUint aQueSize) const;
+	void Disconnection(CBTSynchronousLink& aContext) const;
+	void Start(CBTSynchronousLink& aContext) const;
+	TBool IsIdle() const;
+	};
+
+
+NONSHARABLE_CLASS(TSCOLinkStateWaitForSCO) : public TSyncLinkState
+	{
+public:
+	TSCOLinkStateWaitForSCO(CSyncLinkStateFactory& aFactory);
+
+	void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+	void ConnectComplete(CBTSynchronousLink& aContext, const TBTConnect& aSCOInfo, const TBTSyncConnectOpts& aSyncOpts) const;
+	void Disconnection(CBTSynchronousLink& aContext) const;
+	void Error(CBTSynchronousLink& aContext, TInt aErr) const;
+	TBool IsConnectPending() const;
+	};
+
+
+NONSHARABLE_CLASS(TSCOLinkStateAccepting) : public TSyncLinkState
+	{
+public:
+	TSCOLinkStateAccepting(CSyncLinkStateFactory& aFactory);
+
+	void Enter(CBTSynchronousLink& aContext) const;
+	void Exit(CBTSynchronousLink& aContext) const;	
+	void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+	void Disconnection(CBTSynchronousLink& aContext) const;
+
+// the logical link
+	void ConnectComplete(CBTSynchronousLink& aContext, const TBTConnect& aSCOInfo, const TBTSyncConnectOpts& aSyncOpts) const;
+	void Error(CBTSynchronousLink& aContext, TInt aError) const;
+	void Timeout(CBTSynchronousLink& aContext, TBasebandTimeout aTimeout) const;
+
+	void Deletion(CBTSynchronousLink& aContext) const;
+	void ParentClosing(CBTSynchronousLink& aContext) const;
+	};
+
+
+NONSHARABLE_CLASS(TSCOLinkStateListening) : public TSyncLinkState
+	{
+public:
+	TSCOLinkStateListening(CSyncLinkStateFactory& aFactory);
+
+	void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+	void Deletion(CBTSynchronousLink& aContext) const;
+	TBool ConnectRequest(CBTSynchronousLink& aContext, const TBTConnect& aSCOLink, const CPhysicalLink& aPhysicalLink) const;
+
+	void Exit(CBTSynchronousLink& aContext) const;
+
+private:
+	void SpawnL(CBTSynchronousLink& aContext, CPhysicalLink& aPhysicalLink) const;
+	};
+
+
+NONSHARABLE_CLASS(TSCOLinkStateWaitForStart) : public TSyncLinkState
+	{
+public:
+	TSCOLinkStateWaitForStart(CSyncLinkStateFactory& aFactory);
+
+	void Start(CBTSynchronousLink& aContext) const;
+	void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+	
+	void Deletion(CBTSynchronousLink& aContext) const;
+	void Disconnection(CBTSynchronousLink& aContext) const;
+
+	void Error(CBTSynchronousLink& aContext, TInt aError) const;
+	};
+
+NONSHARABLE_CLASS(TSCOLinkStateWaitForStartError) : public TSyncLinkState
+	{
+public:
+	TSCOLinkStateWaitForStartError(CSyncLinkStateFactory& aFactory);
+	void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+
+	void Start(CBTSynchronousLink& aContext) const;
+	void Deletion(CBTSynchronousLink& aContext) const;
+	};
+
+NONSHARABLE_CLASS(TSCOLinkStateOpen) : public TSyncLinkState
+	{
+public:
+	TSCOLinkStateOpen(CSyncLinkStateFactory& aFactory);
+
+	void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+	void DataReceived(CBTSynchronousLink& aContext, const TDesC8& aData) const;
+	void Disconnection(CBTSynchronousLink& aContext) const;
+	void Error(CBTSynchronousLink& aContext, TInt aErr) const;
+	void PacketTypeChange(CBTSynchronousLink& aContext, THCIErrorCode aErr, THCIConnHandle aConnH, TUint16 aNewPacket) const;
+	TUint Write(CBTSynchronousLink& aContext, const TDesC8& aData, TUint aOptions, TSockAddr* aAddr) const;
+	TBool IsOpen() const;
+
+	void Exit(CBTSynchronousLink& aContext) const;
+	};
+
+
+
+NONSHARABLE_CLASS(TSCOLinkStateClosing) : public TSyncLinkState
+	{
+public:
+	TSCOLinkStateClosing(CSyncLinkStateFactory& aFactory);
+	void Shutdown(CBTSynchronousLink& aContext, CServProviderBase::TCloseType aCloseType) const;
+	void ConnectComplete(CBTSynchronousLink& aContext, const TBTConnect& /*aSCOInfo*/, const TBTSyncConnectOpts& /*aSyncOpts*/) const;
+	void ActiveOpen(CBTSynchronousLink& aContext) const;
+	void Error(CBTSynchronousLink& /*aContext*/, TInt /*aError*/) const;
+	void Deletion(CBTSynchronousLink& /*aContext*/) const;
+	void Disconnection(CBTSynchronousLink& aContext) const;
+	TBool IsIdle() const;
+	};
+
+#ifdef __FLOG_ACTIVE
+#define STATENAME(x)  iName=_L(x)
+#else
+#define STATENAME(x)
+#endif
+
+#endif // _SCOSAP_H_