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