bluetooth/btstack/rfcomm/rfcommmuxchannel.h
changeset 0 29b1cd4cb562
child 23 32ba20339036
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #ifndef RFCOMMMUXCHANNEL_H
       
    17 #define RFCOMMMUXCHANNEL_H
       
    18 
       
    19 #include <e32base.h>
       
    20 #include "debug.h"
       
    21 #include "rfcommframe.h"
       
    22 #include "rfcommmuxer.h"
       
    23 #include "rfcommutil.h"
       
    24 
       
    25 class CMuxChannelState;
       
    26 class TMuxChannelState;
       
    27 
       
    28 /**
       
    29    Factory for the Mux channel states
       
    30 
       
    31    The states are flyweight classes
       
    32 **/
       
    33 NONSHARABLE_CLASS(CMuxChannelStateFactory) : public CBase
       
    34 	{
       
    35 public:
       
    36 	static CMuxChannelStateFactory* NewL();
       
    37 	~CMuxChannelStateFactory();
       
    38 	enum TChannelState
       
    39 		{
       
    40 		EClosed,
       
    41 		EWaitForLink,
       
    42 		EError,
       
    43 		ELinkUp,
       
    44 		EWaitForSABMResp,
       
    45 		EOpen,
       
    46 		EClosing,
       
    47 	// *** keep next one last ***
       
    48 		ERfcommChannelMaxState,
       
    49 		};
       
    50 	
       
    51 	TMuxChannelState* GetState(TChannelState aState);
       
    52 	TInt StateIndex(const TMuxChannelState* aState) const;
       
    53 private:
       
    54 	void ConstructL();
       
    55 	TFixedArray<TMuxChannelState*, ERfcommChannelMaxState> iStates;
       
    56 	};
       
    57 
       
    58 /**
       
    59    Manages the mux channel (DLCI 0) and the L2CAP link
       
    60 
       
    61    Before an RFCOMM session can be used, a L2CAP link to the remote
       
    62    host must be established and the multiplexer control channel must
       
    63    be brought up.  When the RFCOMM session is no longer required, or
       
    64    when the remote end wishes to close things down, the control
       
    65    channel and the L2CAP link must be terminated.
       
    66 
       
    67    As both these operations have multiple steps and interesting
       
    68    failure modes, a state machine is implemented to control this.
       
    69 **/
       
    70 NONSHARABLE_CLASS(CRfcommMuxChannel) : public CBase
       
    71 	{
       
    72 friend class TMuxChannelState;
       
    73 friend class TMuxChannelStateClosed;
       
    74 friend class TMuxChannelStateWaitForLink;
       
    75 friend class TMuxChannelStateError;
       
    76 friend class TMuxChannelStateConnected;
       
    77 friend class TMuxChannelStateLinkUp;
       
    78 friend class TMuxChannelStateWaitForSABMResp;
       
    79 friend class TMuxChannelStateOpen;
       
    80 friend class TMuxChannelStateClosing;
       
    81 
       
    82 public:
       
    83 	CRfcommMuxChannel(CMuxChannelStateFactory& aFactory, CRfcommMuxer& aMux,
       
    84 		CServProviderBase& aSAP, CMuxChannelStateFactory::TChannelState aInitialState);
       
    85 	~CRfcommMuxChannel();
       
    86 
       
    87 	// Requests from the muxer
       
    88 	void SetAddress(TBTDevAddr& aAddr);
       
    89 	void Open();
       
    90 	void Close();
       
    91 	TBool IsOpen();
       
    92 	TInt MaxDataSize();
       
    93 
       
    94 	// Rfcomm events
       
    95 	void UA();
       
    96 	void DISC();
       
    97 	void DM();
       
    98 	void PN(TBool aCommand, TRfcommPortParams& aParams);
       
    99 	void SABM();
       
   100 	void FrameTimeout(CRfcommFrame* aFrm);
       
   101 
       
   102 	// L2CAP events (passed on from the mux)
       
   103 	void Disconnect();
       
   104 	void CanClose();
       
   105 	void ConnectComplete();
       
   106 	void Error(TInt aError,TUint aOperationMask);
       
   107 	TBool CanAttachSAP();
       
   108 
       
   109 private:
       
   110 	TInt TransmitSABM();
       
   111 	TInt TransmitUA();
       
   112 	TInt TransmitDISC();
       
   113 	TInt TransmitDM();
       
   114 	TInt TransmitPN(TBool aCommand, const TRfcommPortParams& aParams);
       
   115 	void QueIdleTimer(TInt aDelay);
       
   116 	void DequeIdleTimer();
       
   117 	static TInt IdleTimerCallback(TAny*);
       
   118 	
       
   119 	CServProviderBase& iSAP;
       
   120 	CRfcommMuxer& iMux;
       
   121 	TMuxChannelState* iState;
       
   122 	TBool iClosePending;
       
   123 	TBool iOpenPending;
       
   124 	TDeltaTimerEntry iIdleTimer;
       
   125 	TBool iIdleTimerQueued;
       
   126 	TInt iMaxDataSize;
       
   127 	};
       
   128 
       
   129 
       
   130 /**
       
   131    Base class for mux channel states.
       
   132 
       
   133    This implements a basic set of behaviours for all states that can
       
   134    then be overridden.  All the states are flyweight classes.
       
   135 **/
       
   136 NONSHARABLE_CLASS(TMuxChannelState)
       
   137 	{
       
   138 public:
       
   139 	TMuxChannelState(CMuxChannelStateFactory& aFactory);
       
   140 
       
   141 	virtual void Enter(CRfcommMuxChannel& aContext, TBool aDisconnectingIdleTimer = ETrue);
       
   142 	virtual void Open(CRfcommMuxChannel& aContext);
       
   143 	virtual void Close(CRfcommMuxChannel& aContext);
       
   144 	virtual TBool IsOpen(CRfcommMuxChannel& aContext);
       
   145 	virtual void UA(CRfcommMuxChannel& aContext);
       
   146 	virtual void DISC(CRfcommMuxChannel& aContext);
       
   147 	virtual void DM(CRfcommMuxChannel& aContext);
       
   148 	virtual void PN(CRfcommMuxChannel& aContext,
       
   149 					TBool aCommand, TRfcommPortParams&
       
   150 					aParams);
       
   151 	virtual void SABM(CRfcommMuxChannel& aContext);
       
   152 	virtual void FrameTimeout(CRfcommMuxChannel& aContext,
       
   153 							  CRfcommFrame* aFrm);
       
   154 	virtual void Disconnect(CRfcommMuxChannel& aContext);
       
   155 	virtual void CanClose(CRfcommMuxChannel& aContext);
       
   156 	virtual void ConnectComplete(CRfcommMuxChannel& aContext);
       
   157 	virtual void Error(CRfcommMuxChannel& aContext, TInt aError,
       
   158 					   TUint aOperationMask);
       
   159 	virtual void IdleTimeout(CRfcommMuxChannel& aContext);
       
   160 	virtual TBool CanAttachSAP();
       
   161 
       
   162 protected:
       
   163 	// Sets the state, but doesn't enter it.
       
   164 	void SetState(CRfcommMuxChannel& aContext, CMuxChannelStateFactory::TChannelState aState);
       
   165 	void PanicInState(TRFCOMMPanic aPanic) const;
       
   166 	void DebugPanicInState(TRFCOMMPanic aPanic) const;
       
   167 	
       
   168 protected:
       
   169 	CMuxChannelStateFactory& iFactory;
       
   170 #ifdef __FLOG_ACTIVE
       
   171 	TBuf<48> iName;
       
   172 #endif
       
   173 	};
       
   174 
       
   175 /**
       
   176    Closed state.
       
   177 
       
   178    This is the state we start in when this end is to initiate the L2CAP link.
       
   179 
       
   180    On an Open() we do the active connect.
       
   181 
       
   182 **/
       
   183 NONSHARABLE_CLASS(TMuxChannelStateClosed) : public TMuxChannelState
       
   184 	{
       
   185 public:
       
   186 	TMuxChannelStateClosed(CMuxChannelStateFactory& aFactory);
       
   187 	
       
   188 	void Enter(CRfcommMuxChannel& aContext, TBool aDisconnectingIdleTimer = ETrue);
       
   189 	void Open(CRfcommMuxChannel& aContext);
       
   190 	void Close(CRfcommMuxChannel& aContext);
       
   191 	};
       
   192 
       
   193 /**
       
   194    Waiting for the L2CAP link to come up.
       
   195 **/
       
   196 NONSHARABLE_CLASS(TMuxChannelStateWaitForLink) : public TMuxChannelState
       
   197 	{
       
   198 public:
       
   199 	TMuxChannelStateWaitForLink(CMuxChannelStateFactory& aFactory);
       
   200 	
       
   201 	void ConnectComplete(CRfcommMuxChannel& aContext);
       
   202 	void Close(CRfcommMuxChannel& aContext);
       
   203 	void Error(CRfcommMuxChannel& aContext, TInt aError,
       
   204 			   TUint aOperationMask);
       
   205 	};
       
   206 
       
   207 /**
       
   208    The Error state
       
   209 
       
   210    This represents a fatal error on the L2CAP link (SAP) such that it
       
   211    would be pointless to attempt to reconnect the channel with the
       
   212    same SAP.
       
   213 
       
   214    Entry to this state should be terminal to our associated muxer.
       
   215 **/
       
   216 NONSHARABLE_CLASS(TMuxChannelStateError) : public TMuxChannelState
       
   217 	{
       
   218 public:
       
   219 	TMuxChannelStateError(CMuxChannelStateFactory& aFactory);
       
   220 	
       
   221 	void Open(CRfcommMuxChannel& aContext);
       
   222 	void Close(CRfcommMuxChannel& aContext);
       
   223 	TBool CanAttachSAP();
       
   224 	};
       
   225 
       
   226 /**
       
   227    Base class for all the connected states.
       
   228 
       
   229    This implements the connected superstate, with the superstate
       
   230    behaviours.  It also includes some default behaviours for its
       
   231    substates.
       
   232 
       
   233    The connected state is when the L2CAP link is up.
       
   234 **/
       
   235 NONSHARABLE_CLASS(TMuxChannelStateConnected) : public TMuxChannelState
       
   236 	{
       
   237 public:
       
   238 	TMuxChannelStateConnected(CMuxChannelStateFactory& aFactory);
       
   239 
       
   240 	void FrameTimeoutHelper(CRfcommMuxChannel& aContext);
       
   241 
       
   242 	// These functions are over-ridden from TMuxChannelState 
       
   243 	void Disconnect(CRfcommMuxChannel& aContext);
       
   244 
       
   245 	// ...and these will also be over-ridden in child states
       
   246 	virtual void SABM(CRfcommMuxChannel& aContext);
       
   247 	virtual void FrameTimeout(CRfcommMuxChannel& aContext,
       
   248 							  CRfcommFrame* aFrm);
       
   249 	virtual void Error(CRfcommMuxChannel& aContext, TInt aError,
       
   250 					   TUint aOperationMask);
       
   251 	};
       
   252 
       
   253 /**
       
   254    The L2CAP link is up
       
   255    
       
   256    This class is entered when the link comes up, or when the mux
       
   257    channel is disconnected without closing the l2cap link.  From here,
       
   258    a timeout will close the link.
       
   259 
       
   260    This is the initial state for the mux channel if the muxer was
       
   261    created due to an incoming connection.
       
   262 
       
   263    From here, the SABM/UA exchange occurs to bring up the mux channel,
       
   264    and the DISC/UA to return to here.  Eventually a timeout, link
       
   265    disconnection or Close() will cause the link to be dropped.
       
   266 **/
       
   267 NONSHARABLE_CLASS(TMuxChannelStateLinkUp) : public TMuxChannelStateConnected
       
   268 	{
       
   269 public:
       
   270 	TMuxChannelStateLinkUp(CMuxChannelStateFactory& aFactory);
       
   271 	
       
   272 	// Over-ridden from parent class:
       
   273 	void Enter(CRfcommMuxChannel& aContext, TBool aDisconnectingIdleTimer = ETrue);
       
   274 	void Open(CRfcommMuxChannel& aContext);
       
   275 	void Close(CRfcommMuxChannel& aContext);
       
   276 	void SABM(CRfcommMuxChannel& aContext);
       
   277 	void DISC(CRfcommMuxChannel& aContext);
       
   278 	void IdleTimeout(CRfcommMuxChannel& aContext);
       
   279 	void FrameTimeout(CRfcommMuxChannel& aContext, CRfcommFrame* aFrm);
       
   280 	};
       
   281 
       
   282 /**
       
   283    Waiting for the mux channel to be connected
       
   284 **/
       
   285 NONSHARABLE_CLASS(TMuxChannelStateWaitForSABMResp) : public TMuxChannelStateConnected
       
   286 	{
       
   287 public:
       
   288 	TMuxChannelStateWaitForSABMResp(CMuxChannelStateFactory& aFactory);
       
   289 	
       
   290 	void UA(CRfcommMuxChannel& aContext);
       
   291 	void DM(CRfcommMuxChannel& aContext);
       
   292 	void SABM(CRfcommMuxChannel& aContext);
       
   293 	void DISC(CRfcommMuxChannel& aContext);
       
   294 	void Close(CRfcommMuxChannel& aContext);
       
   295 	};
       
   296 
       
   297 /**
       
   298    The mux channel is now fully open
       
   299 
       
   300    At this point the muxer is signalled that it can start to use the
       
   301    channel.
       
   302    
       
   303 **/
       
   304 NONSHARABLE_CLASS(TMuxChannelStateOpen) : public TMuxChannelStateConnected
       
   305 	{
       
   306 public:
       
   307 	TMuxChannelStateOpen(CMuxChannelStateFactory& aFactory);
       
   308 	
       
   309 	void Enter(CRfcommMuxChannel& aContext, TBool aDisconnectingIdleTimer = ETrue);
       
   310 	TBool IsOpen(CRfcommMuxChannel& aContext);
       
   311 	void Close(CRfcommMuxChannel& aContext);
       
   312 	void SABM(CRfcommMuxChannel& aContext);
       
   313 	void DISC(CRfcommMuxChannel& aContext);
       
   314 	};
       
   315 
       
   316 /**
       
   317    Closing down the L2CAP Link
       
   318 
       
   319    The whole mux channel is no longer required, so the link is being
       
   320    closed.
       
   321 **/
       
   322 NONSHARABLE_CLASS(TMuxChannelStateClosing) : public TMuxChannelStateConnected
       
   323 	{
       
   324 public:
       
   325 	TMuxChannelStateClosing(CMuxChannelStateFactory& aFactory);
       
   326 	// Over-ridden from parent:
       
   327 	void FrameTimeout(CRfcommMuxChannel& aContext,
       
   328 							  CRfcommFrame* aFrm);
       
   329 	void CanClose(CRfcommMuxChannel& aContext);
       
   330 	TBool CanAttachSAP();
       
   331 	};
       
   332 
       
   333 #ifdef __FLOGGING__
       
   334 #define STATENAME(x)  iName=_L(x)
       
   335 #else
       
   336 #define STATENAME(x)
       
   337 #endif
       
   338 
       
   339 #include "rfcommmuxchannel.inl"
       
   340 #endif