bluetooth/btstack/l2cap/L2CapDataController.h
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2004-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 L2CAPDATACONTROLLER_H_
       
    17 #define L2CAPDATACONTROLLER_H_
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <bt_sock.h>
       
    21 
       
    22 #include "L2CapPDU.h"
       
    23 #include "L2CapSDUQueue.h"
       
    24 
       
    25 namespace L2CapDataUtils
       
    26 	{
       
    27 	// Helper function used for transmit and receive sequence numbers which are 6 bits long.
       
    28 	inline TUint8 Mod64(TInt aValue);
       
    29 	// Helper function for checking whether a sequence number is within a given window.
       
    30 	// Handles both Start <= End and Start > End.
       
    31 	inline TBool InWindow(TInt aTxSeq, TInt aStart, TInt aEnd);
       
    32 	}
       
    33 
       
    34 class CL2CapSDUQueue;
       
    35 class CL2CAPMux;
       
    36 class CL2CapSDU;
       
    37 
       
    38 NONSHARABLE_CLASS(CL2CapBasicDataController) : public CBase, public MOutgoingPDUHandler
       
    39 	{
       
    40 public:
       
    41 	static CL2CapBasicDataController* NewL(TL2CAPPort aLocalCID, TL2CAPPort aRemoteCID, CL2CAPMux& aMuxer, CL2CapSDUQueue& aSDUQueue, TL2CapDataControllerConfig* aConfig);
       
    42 
       
    43 	CL2CapBasicDataController(TL2CAPPort aLocalCID, TL2CAPPort aRemoteCID, CL2CAPMux& aMuxer, CL2CapSDUQueue& aSDUQueue, TL2CapDataControllerConfig* aConfig, TBool aIsBasicDataVersion);
       
    44 	virtual ~CL2CapBasicDataController();
       
    45 	
       
    46 	virtual void ProcessFlushTimerExpiry();
       
    47 
       
    48 	void UpdateConfig(TL2CapDataControllerConfig* aConfig);
       
    49 	void UpdateChannelPriority(TUint8 aNewPriority);
       
    50 	
       
    51 	void DeregisterFromMuxer();
       
    52 
       
    53 	// These two are the main input/output interface to the data controller, lots of interesting
       
    54 	// stuff happens in their context.
       
    55 	// Input - called by the muxer when a data frame is received.
       
    56 	TBool HandleIncomingDataFrame(RMBufChain& aDataFrame);
       
    57 	// Output - called by the muxer when it wants some data to send out.
       
    58 	HL2CapPDU* GetPdu();
       
    59 
       
    60 	// Outgoing PDU handler.
       
    61 	virtual TInt HandleOutgoingIFrame(HIFramePDU* aIFrame);
       
    62 	virtual TInt HandleOutgoingBFrame(HBFramePDU* aBFrame);
       
    63 	virtual TInt HandleOutgoingGFrame(HGFramePDU* aGFrame);
       
    64 	virtual TInt HandleOutgoingCFrame(HCFramePDU* aCFrame);
       
    65 	virtual TInt HandleOutgoingSFrame(HSFramePDU* aSFrame);
       
    66 
       
    67 	virtual void OutgoingPduAvailableOnSduQ();
       
    68 
       
    69 	virtual void ErrorD(TInt aError);
       
    70 
       
    71 	virtual void SetIncomingSduQFull(TBool aIncomingSduQFull);
       
    72 
       
    73 	// Signal from the SDU Q that we need to send remaining data and call the SDU Q back
       
    74 	// when it's been sent & acknowledged by the peer. Returning True means it's already
       
    75 	// been done and we can be synchronously deleted.
       
    76 	virtual TBool DeliverOutgoingDataAndSignalToSduQWhenDone();
       
    77 
       
    78 	inline CL2CapSDUQueue& SDUQueue() const;
       
    79 	inline CL2CAPMux& Muxer() const;
       
    80 	inline TL2CAPPort LocalCID() const;
       
    81 	inline TL2CAPPort RemoteCID() const;
       
    82 	inline TL2CapDataControllerConfig& Config() const;
       
    83 
       
    84 	inline TBool IsBasicDataVersion() const;
       
    85 
       
    86 protected:
       
    87 	// Note: leaving functions need to be trapped within this class, all public
       
    88 	// functions are non-leaving.
       
    89 
       
    90 	// Dispatches incoming data frames to appropriate frame-type handlers below.
       
    91 	// Leaves are trapped by HandleIncomingDataFrame, which will close the connection.
       
    92 	TBool HandleIncomingDataFrameL(RMBufChain& aDataFrame);
       
    93 	// These need to be overridden by deriving controllers.
       
    94 	virtual void HandleIncomingIFrameL(RMBufChain& aDataFrame);
       
    95 	virtual void HandleIncomingBFrameL(RMBufChain& aDataFrame);
       
    96 	virtual void HandleIncomingSFrameL(RMBufChain& aDataFrame);
       
    97 
       
    98 	// Needs to be overridden by deriving controllers.
       
    99 	// Leaves are trapped by GetPdu, which will close the connection. 
       
   100 	virtual HL2CapPDU* GetPduL();
       
   101 
       
   102 #ifdef _DEBUG
       
   103 public:
       
   104 	TInt GetDataPlaneConfig(TL2DataPlaneConfig& conf) const;
       
   105 #endif	
       
   106 
       
   107 public:
       
   108 	TDblQueLink iLink;	
       
   109 				
       
   110 protected:
       
   111 	CL2CapSDUQueue& iSDUQueue;
       
   112 	CL2CAPMux& iMuxer;
       
   113 	TL2CAPPort iLocalCID; 
       
   114 	TL2CAPPort iRemoteCID;
       
   115 	TL2CapDataControllerConfig* iConfig;
       
   116 
       
   117 	TBool iDataPlaneErrored;
       
   118 	TBool iIsBasicDataVersion;
       
   119 	};
       
   120 
       
   121 
       
   122 NONSHARABLE_CLASS(MRetransmissionModeTimerClient)
       
   123 	{
       
   124 public:
       
   125 	virtual void MonitorTimerExpired() = 0;
       
   126 	virtual void AckTimerExpired() = 0;
       
   127 	virtual void SendPeerAckTimerExpired() = 0;
       
   128 	virtual TUint16 MonitorTimeout() = 0;
       
   129 	virtual TUint16 RetransmissionTimeout() = 0;
       
   130 	virtual TUint16 PeerRetransmissionTimeout() = 0;
       
   131 	};
       
   132 
       
   133 NONSHARABLE_CLASS(RL2CapRetransmissionModeTimerManager)
       
   134 	{
       
   135 public:
       
   136 	RL2CapRetransmissionModeTimerManager(MRetransmissionModeTimerClient& aClient);
       
   137 	void Close();
       
   138 
       
   139 	void StartMonitorTimer();
       
   140 	void StartAckTimer();
       
   141 	void StopMonitorTimer();
       
   142 	void StopAckTimer();
       
   143 
       
   144 	TBool StartSendPeerAckTimer();
       
   145 	void StopSendPeerAckTimer();
       
   146 
       
   147 	void HandleFECTimerExpired();
       
   148 	void HandleSendPeerAckTimerExpired();
       
   149 	static TInt FECTimerExpired(TAny* aTimerMan);
       
   150 	static TInt SendPeerAckTimerExpired(TAny* aTimerMan);
       
   151 
       
   152 	inline TBool IsAckTimerRunning() const;
       
   153 	inline TBool IsMonitorTimerRunning() const;
       
   154 	inline TBool IsSendPeerAckTimerRunning() const;
       
   155 
       
   156 protected:
       
   157 	MRetransmissionModeTimerClient& iClient;
       
   158 
       
   159 private:
       
   160 	void CancelFECTimer();
       
   161 
       
   162 	// Both of these values are in milliseconds.
       
   163 	const static TUint16 KAveTimeToTransmitAckToPeer 		= 800;
       
   164 	const static TUint16 KMinimumPeerAckTimeout				= 800;
       
   165 
       
   166 	enum TFECTimerState
       
   167 		{
       
   168 		EFECTimerIdle,
       
   169 		EMonitorTimerRunning,
       
   170 		EAckTimerRunning,
       
   171 		};
       
   172 
       
   173 	// Timer for outgoing data.  Used for both Monitor and RTx timers.
       
   174 	// Note that only one of them can be outstanding at any time (as per the spec).
       
   175 	TFECTimerState		iFECTimerState;
       
   176 	TDeltaTimerEntry	iFECTimerEntry;
       
   177 
       
   178 	// Timer for incoming data.  Send ack. to peer timer.
       
   179 	TBool				iSendPeerAckTimerRunning;
       
   180 	TDeltaTimerEntry	iSendPeerAckTimerEntry;
       
   181 	};
       
   182 
       
   183 
       
   184 NONSHARABLE_CLASS(CL2CapDataFlowController)
       
   185 	: public CL2CapBasicDataController, public MPduOwner, public MRetransmissionModeTimerClient
       
   186 	{
       
   187 public:
       
   188 	CL2CapDataFlowController(TL2CAPPort aLocalCID, TL2CAPPort aRemoteCID, CL2CAPMux& aMuxer, CL2CapSDUQueue& aSDUQueue, TL2CapDataControllerConfig* aConfig);
       
   189 	virtual ~CL2CapDataFlowController();
       
   190 	
       
   191 	virtual void ProcessFlushTimerExpiry();
       
   192 
       
   193 	// MPduOwner
       
   194 	virtual void HandlePduSendComplete(HL2CapPDU& aPdu);
       
   195 	virtual void HandlePduSendError(HL2CapPDU& aPdu);
       
   196 
       
   197 	virtual HL2CapPDU* GetPduL();
       
   198 
       
   199 	virtual TInt HandleOutgoingIFrame(HIFramePDU* aIFrame);
       
   200 	virtual TInt HandleOutgoingSFrame(HSFramePDU* aSFrame);
       
   201 
       
   202 	virtual void SetIncomingSduQFull(TBool aIncomingSduQFull);
       
   203 
       
   204 protected:
       
   205 	virtual void HandleIncomingIFrameL(RMBufChain& aDataFrame);
       
   206 	virtual void HandleIncomingSFrameL(RMBufChain& aDataFrame);
       
   207 
       
   208 	virtual void PDUAvailable();
       
   209 	TBool CanSendPDU();
       
   210 	virtual void RemoveAckedPDUsFromSentQueue();
       
   211 	void ProcessIFrameL(RMBufChain& aDataFrame);
       
   212 
       
   213 	// MRetransmissionModeTimerClient
       
   214 	virtual void MonitorTimerExpired();
       
   215 	virtual void AckTimerExpired();
       
   216 	virtual void SendPeerAckTimerExpired();
       
   217 	virtual TUint16 MonitorTimeout();
       
   218 	virtual TUint16 RetransmissionTimeout();
       
   219 	virtual TUint16 PeerRetransmissionTimeout();
       
   220 
       
   221 protected:
       
   222 	// This value represents the number of frames the peer can still send prior 
       
   223 	// to the local device sending an ack.  ie, if the peer TxWindow is 20 then
       
   224 	// (20 - KTxWinAckThresholdOffset) frames can be received before an ack is 
       
   225 	// sent.  NB.  This does not affect the operation of the SendPeerAckTimer.
       
   226 	const static TUint8 KTxWinAckThresholdOffset 			= 3;
       
   227 
       
   228 	// Window related information, as defined in the spec (chapter "Variables and sequence numbers").
       
   229 	TUint8 iNextTxSeq;
       
   230 	TUint8 iExpectedAckSeq;
       
   231 	
       
   232 	TUint8 iExpectedTxSeq;
       
   233 	// Stores the acknowledgment number most recently sent to the peer.
       
   234 	// Used to detect that we're reaching the end of peer's send window and hence should
       
   235 	// send an ack.
       
   236 	TUint8 iLastAckSentRxSeqNum;
       
   237 
       
   238 	// PDUs being sent, not yet completed by HCI.
       
   239 	TDblQue<HIFramePDU> iPendingSentPDUs;
       
   240 	// Completed by HCI and awaiting acknowledgement.
       
   241 	TDblQue<HIFramePDU> iSentPDUs;
       
   242 	
       
   243 	RL2CapRetransmissionModeTimerManager iTimerMan;
       
   244 
       
   245 	TBool iIncomingSduQFull;
       
   246 	
       
   247 	TBool iSendAckToPeer;
       
   248 	TBool iSenderTxWindowClosed;
       
   249 	};
       
   250 
       
   251 NONSHARABLE_CLASS(CL2CapDataReTxController) : public CL2CapDataFlowController
       
   252 	{
       
   253 public:
       
   254 	CL2CapDataReTxController(TL2CAPPort aLocalCID, TL2CAPPort aRemoteCID, CL2CAPMux& aMuxer, CL2CapSDUQueue& aSDUQueue, TL2CapDataControllerConfig* aConfig);
       
   255 
       
   256 	// MPduOwner
       
   257 	virtual void HandlePduSendComplete(HL2CapPDU& aPdu);
       
   258 
       
   259 	virtual TInt HandleOutgoingIFrame(HIFramePDU* aIFrame);
       
   260 
       
   261 	virtual TBool DeliverOutgoingDataAndSignalToSduQWhenDone();
       
   262 
       
   263 protected:
       
   264 	virtual void HandleIncomingIFrameL(RMBufChain& aDataFrame);
       
   265 	virtual void HandleIncomingSFrameL(RMBufChain& aDataFrame);
       
   266 
       
   267 	virtual void PDUAvailable();
       
   268 
       
   269 	virtual HL2CapPDU* GetPduL();
       
   270 
       
   271 	virtual void RemoveAckedPDUsFromSentQueue();
       
   272 
       
   273 	virtual void AckTimerExpired();
       
   274 private:
       
   275 	HL2CapPDU* RetransmitSentPDU();
       
   276 
       
   277 private:
       
   278 	HSFramePDU* iRejectPDU;
       
   279 	TBool iRetransmitSentPDUs;
       
   280 	TBool iRejectSent;
       
   281 	TBool iRetransmissionDisabled;
       
   282 	TBool iRestartAckTimer;
       
   283 	TInt iRetransTxVal;		// This variable is used to store the Tx Seq number of the next PDU to be retransmitted.  This keeps this value separate from the one used for new I-Frames.
       
   284 	TBool iDeliverOutgoingDataAndSignalToSduQWhenDone;
       
   285 	};
       
   286 
       
   287 
       
   288 inline TUint8 L2CapDataUtils::Mod64(TInt aValue)
       
   289 	{
       
   290 	return static_cast<TUint8>(aValue & 0x3f);
       
   291 	}
       
   292 
       
   293 inline TBool L2CapDataUtils::InWindow(TInt aTxSeq, TInt aStart, TInt aEnd)
       
   294 	{
       
   295 	if (aStart <= aEnd)
       
   296 		{
       
   297 		return aStart <= aTxSeq && aTxSeq <= aEnd;
       
   298 		}
       
   299 	else
       
   300 		{
       
   301 		return aStart <= aTxSeq || aTxSeq <= aEnd;
       
   302 		}
       
   303 	}
       
   304 
       
   305 
       
   306 inline CL2CapSDUQueue& CL2CapBasicDataController::SDUQueue() const
       
   307 	{
       
   308 	return iSDUQueue;
       
   309 	}
       
   310 	
       
   311 inline CL2CAPMux& CL2CapBasicDataController::Muxer() const
       
   312 	{
       
   313 	return iMuxer;
       
   314 	}
       
   315 	
       
   316 inline TL2CAPPort CL2CapBasicDataController::LocalCID() const
       
   317 	{
       
   318 	return iLocalCID;
       
   319 	}
       
   320 	
       
   321 inline TL2CAPPort CL2CapBasicDataController::RemoteCID() const
       
   322 	{
       
   323 	return iRemoteCID;
       
   324 	}
       
   325 
       
   326 inline TL2CapDataControllerConfig& CL2CapBasicDataController::Config() const
       
   327 	{
       
   328 	return *iConfig;
       
   329 	}
       
   330 
       
   331 inline TBool CL2CapBasicDataController::IsBasicDataVersion() const
       
   332 	{
       
   333 	return iIsBasicDataVersion;
       
   334 	}
       
   335 
       
   336 
       
   337 inline TBool RL2CapRetransmissionModeTimerManager::IsAckTimerRunning() const
       
   338 	{
       
   339 	return iFECTimerState == EAckTimerRunning;
       
   340 	}
       
   341 
       
   342 inline TBool RL2CapRetransmissionModeTimerManager::IsMonitorTimerRunning() const
       
   343 	{
       
   344 	return iFECTimerState == EMonitorTimerRunning;
       
   345 	}
       
   346 
       
   347 inline TBool RL2CapRetransmissionModeTimerManager::IsSendPeerAckTimerRunning() const
       
   348 	{
       
   349 	return iSendPeerAckTimerRunning;
       
   350 	}
       
   351 
       
   352 #endif