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