bluetooth/btstack/l2cap/L2CapPDU.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 L2CAPPDU_H_
       
    17 #define L2CAPPDU_H_
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <es_sock.h>
       
    21 #include <es_prot.h>
       
    22 
       
    23 #include <es_mbuf.h>
       
    24 #include <bttypes.h>
       
    25 
       
    26 #include "L2types.h"
       
    27 #include "l2util.h"
       
    28 
       
    29 class HL2CapCommand;
       
    30 class CServProviderBase;
       
    31 class CL2CAPMux;
       
    32 class CL2CapDataFlowController;
       
    33 
       
    34 class HIFramePDU;
       
    35 class HBFramePDU;
       
    36 class HGFramePDU;
       
    37 class HCFramePDU;
       
    38 class HSFramePDU;
       
    39 class HL2CapPDU;
       
    40 
       
    41 class MOutgoingPDUHandler
       
    42 	{
       
    43 public:
       
    44 	virtual TInt HandleOutgoingIFrame(HIFramePDU* aIFrame) = 0;
       
    45 	virtual TInt HandleOutgoingBFrame(HBFramePDU* aBFrame) = 0;
       
    46 	virtual TInt HandleOutgoingGFrame(HGFramePDU* aGFrame) = 0;
       
    47 	virtual TInt HandleOutgoingCFrame(HCFramePDU* aCFrame) = 0;
       
    48 	virtual TInt HandleOutgoingSFrame(HSFramePDU* aSFrame) = 0;
       
    49 	};
       
    50 
       
    51 // A PDU owner gets notified though this interface when a PDU send operation is complete.
       
    52 // It's then up to the owner to delete the PDU or resend it, and to move it between
       
    53 // various PDU lists - a PDU should not call iLink.Deque() nor destruct itself unless
       
    54 // it has been orphaned.
       
    55 // In practice CL2CAPMux owns C-, S- and B-Frames, while (E)RTM Data Controllers own
       
    56 // I-Frames.
       
    57 class MPduOwner
       
    58 	{
       
    59 public:
       
    60 	virtual void HandlePduSendComplete(HL2CapPDU& aPdu) = 0;
       
    61 	virtual void HandlePduSendError(HL2CapPDU& aPdu) = 0;
       
    62 	};
       
    63 
       
    64 enum TL2CapSAR
       
    65 	{
       
    66 	EUnsegmentedL2CapSDU	= 0,
       
    67 	EStartOfL2CapSDU		= 1,
       
    68 	EEndOfL2CapSDU			= 2,
       
    69 	EContinuationOfL2CapSDU	= 3,
       
    70 	};
       
    71 	
       
    72 enum TSupervisoryFunction
       
    73 	{
       
    74 	EReceiverReady		= 0,
       
    75 	EReject				= 1,
       
    76 	EReceiverNotReady	= 2,
       
    77 	ESelectiveReject	= 3,
       
    78 	};
       
    79 
       
    80 class MDataPlaneElement
       
    81 	{
       
    82 public:
       
    83 	virtual void DataElementSent(TUint16 aElementID = 0) = 0;
       
    84 	virtual void DataElementFlushed(TUint16 aElementID = 0) = 0;
       
    85 
       
    86 	virtual TBool IsPDUFlushed() const = 0;
       
    87 	};
       
    88 	
       
    89 NONSHARABLE_CLASS(TDataPlaneElementHandle) : public TSockAddr
       
    90 	{
       
    91 public:
       
    92 	struct SDataPlaneElementHandle
       
    93 		{
       
    94 		MDataPlaneElement* iDataElement;
       
    95 		TUint16 iElementID;
       
    96 		};
       
    97 			
       
    98 	TDataPlaneElementHandle(MDataPlaneElement* aDataElement, TUint16 aElementID = 0);
       
    99 
       
   100 	MDataPlaneElement& DataPlaneElement() const;
       
   101 	TUint16 ElementID() const;
       
   102 	};
       
   103 
       
   104 
       
   105 //
       
   106 // Base class for all PDU types.
       
   107 //
       
   108 NONSHARABLE_CLASS(HL2CapPDU) : public MDataPlaneElement
       
   109 	{
       
   110 public:
       
   111 	// Base or shared length definitions.	
       
   112 	const static TUint8 KPDUHeaderLength 			= 4;
       
   113 	const static TUint8 KControlFieldLength			= 2;		
       
   114 	const static TUint8 KSDULengthFieldLength		= 2;
       
   115 	const static TUint8 KMaxPDUHeaderLength			= KPDUHeaderLength + KControlFieldLength + KSDULengthFieldLength;		
       
   116 	const static TUint8 KFCSFieldLength				= 2;
       
   117 	const static TUint8 KSFrameLength				= 8;
       
   118 
       
   119 	const static TUint8 KNumberOfFragmentsUnknown 	= 0;
       
   120 		
       
   121 	virtual ~HL2CapPDU();
       
   122 	
       
   123 	// Deliver Interface.
       
   124 	virtual void DeliverOutgoingPDU(MOutgoingPDUHandler& aPDUHandler);
       
   125 
       
   126 	// Method for reconstructing SDU data.
       
   127 	virtual void AppendPayloadToBuffer(RMBufChain& aSDUData);
       
   128 	 
       
   129 	// Message Accessors.
       
   130 	// Static
       
   131 	static TUint16 PDUPayloadLength(const RMBufChain& aPDU);
       
   132 	static TUint16 PDUCID(const RMBufChain& aPDU);
       
   133     static TInt CheckDecode(const RMBufChain& aPDU);
       
   134 
       
   135 	// This method appends a fragment to the aPDU parameter and then
       
   136 	// checks if the PDU is complete.
       
   137 	static TBool AddFragment(RMBufChain& aPDU, RMBufChain& aPDUFragment);
       
   138 
       
   139 	// Member
       
   140 	inline TUint16 PDUPayloadLength() const;
       
   141 
       
   142 	inline TUint16 PDUCID() const;
       
   143 	void SetPDUCID(TUint16 aCID);
       
   144 
       
   145 	// Calculate the PDU length, and place it in the PDU header.
       
   146 	void WritePDUPayloadLength();  
       
   147 
       
   148 	// For basic mode return the fragment overhead otherwise return the
       
   149 	// L2CAP PDU overhead in bytes.
       
   150 	static TInt GetPDUOrFragmentOverhead(TBool aBasicMode);
       
   151 	
       
   152 	// Return the optimal PDU size based on the MTU and controller buffer size.
       
   153 	static TInt GetPDUOrFragmentSize(TInt aMTU, TInt aMaxMps, TInt aBufSize, TBool aBasicMode);
       
   154 	
       
   155 	inline TInt OptimalFragmentSize() const;
       
   156 	
       
   157 	// Inline accessor methods.
       
   158 	inline RMBufChain& PDUBuffer();
       
   159 	inline void SetPDUFlushed();
       
   160 	inline TBool IsPDUFlushed() const;
       
   161 	inline TDataPlaneElementHandle& ElementHandle();
       
   162 
       
   163 	void PDUSendPending(TUint16 aTotalNumberOfFragments);
       
   164 	void PDUSendComplete();
       
   165 	
       
   166 	inline void SetPduOwner(MPduOwner* aPduOwner);
       
   167 	inline TBool HasOwner() const;
       
   168 	inline TBool IsOwner(const MPduOwner* aPduOwner) const;
       
   169 	inline void DeregisterPduOwner();
       
   170 
       
   171 	inline TBool IsAwaitingHciCompletion() const;
       
   172 
       
   173 	inline TBool IsQueuedForSend() const;
       
   174 	inline void SetQueuedForSend(TBool aQueuedForSend);
       
   175 
       
   176 	// MDataPlaneElement Interface
       
   177 	void DataElementSent(TUint16 aElementID);
       
   178 	void DataElementFlushed(TUint16 aElementID);
       
   179 		
       
   180 protected:
       
   181 	// An optimal fragment size of 0 indicates that we do not expect fragmentation to take place
       
   182 	HL2CapPDU(RMBufChain& aPDUData, TInt aOptimalFragmentSize);
       
   183 	HL2CapPDU(TInt aOptimalFragmentSize = 0);
       
   184 
       
   185 	void SetPDUPayloadLength(TUint16 aLength);
       
   186 
       
   187 	virtual void DeliverOutgoingPDUDoubleDispatch(MOutgoingPDUHandler& aPDUHandler) = 0;
       
   188 	virtual void SendComplete(); // for frame type-specific actions on send complete
       
   189 
       
   190 	inline TUint16 CalcCRC();	
       
   191 	static TUint16 CalcCRC(const RMBufChain& aPDU);	
       
   192 
       
   193 public:
       
   194 	// General link though which the PDU is "owned" by different entities during its lifetime.
       
   195 	// An I-Frame PDU starts as a member of the PDU list in its SDU, then is pulled by a data
       
   196 	// controller and depending on the data controller, proceeds through its unacknowledged I-Frame
       
   197 	// lists (RTM and ERTM). B-Frames start linked to their SDUs but then are put on link muxer's
       
   198 	// PDU list, because Basic mode doesn't do retransmissions, so the data controller doesn't care.
       
   199 	// S-Frames are created inside data controllers and are put on the link muxer's list as well -
       
   200 	// they are fire'n'forget too.
       
   201 	// Note that the owning relationship is formalized with the MPduOwner interface.
       
   202 	TDblQueLink iLink;
       
   203 	// This is an additional link that can be used by a data controller to manage internal PDU
       
   204 	// queues. (currently used in ERTM for Outgoing Q)
       
   205 	TSglQueLink iDataControllerInternalQLink;
       
   206 protected:
       
   207 	// Base or shared field positions. 
       
   208 	const static TUint8 KLengthByteOffset 			= 0;
       
   209 	const static TUint8 KCIDByteOffset 				= 2;
       
   210 	const static TUint8 KControlFieldByteOffset 	= 4;
       
   211 	const static TUint8 KSDULengthFieldByteOffset 	= 6;
       
   212 
       
   213 	// Control field bit masks.	
       
   214 	const static TUint16 KCtrlFrameTypeMask 	= 0x0001;
       
   215 	const static TUint16 KCtrlTxSeqMask			= 0x007e;
       
   216 	const static TUint16 KCtrlReTxDisableMask	= 0x0080;
       
   217 	const static TUint16 KCtrlFinalBitMask		= 0x0080;
       
   218 	const static TUint16 KCtrlPollBitMask		= 0x0010;
       
   219 	const static TUint16 KCtrlReqSeqMask		= 0x3f00;
       
   220 	const static TUint16 KCtrlSARMask			= 0xc000;
       
   221 	const static TUint16 KCtrlSupervisoryMask	= 0x000c;
       
   222 
       
   223 	// Control field bit shifters.
       
   224 	const static TUint16 KCtrlTxSeqShift		= 1;
       
   225 	const static TUint16 KCtrlReTxDisableShift	= 7;
       
   226 	const static TUint16 KCtrlReqSeqShift		= 8;
       
   227 	const static TUint16 KCtrlSARShift			= 14;
       
   228 				
       
   229 	// All message information is held in this buffer.	
       
   230 	RMBufChain iPDUData;
       
   231 
       
   232 	TBool iIsFlushed;
       
   233 	TBool iSendingError;
       
   234 
       
   235 	// True when it's on the OutgoingQ in ERTM waiting for GetPdu to pull it.
       
   236 	// Used for protecting the consistency of the OutgoingQ list - we mustn't try to
       
   237 	// queue the same frame twice. Also useful for detecting misbehaving remotes, if
       
   238 	// they try to request a retransmission of the same I-Frame more than once (per
       
   239 	// one loss).
       
   240 	TBool iQueuedForSend;
       
   241 
       
   242 	// This indicates whether an initiated transmission has been completed by HCI or not,
       
   243 	// so that a retransmission of the PDU can proceed or be stalled until this becomes false.
       
   244 	// A PDU is supposed to start its life with this condition = False so that the initial
       
   245 	// transmission can proceed, and then it should become True once the PDU is scheduled
       
   246 	// for transmission. This is important for PDUs that can are acknowledgable or can be
       
   247 	// rejected by the peer (read I-Frames). In case the acknowledgement/reject comes through
       
   248 	// before the HCI completion event (which happens with the USB HCTL on Windows) we want
       
   249 	// to wait until an I-Frame is transmitted until we can delete it/start re-transmitting it.
       
   250 	// Note: an I-Frame may be queued for a retransmission before being completed by HCI
       
   251 	// (because it may happen that we receive the (S)REJ before the HCI packet completion
       
   252 	// event). That's why there are separate boolean flags instead of a single PDU state
       
   253 	// enum.
       
   254 	TBool iAwaitingHciCompletion;
       
   255 
       
   256 	TDataPlaneElementHandle iElementHandle;
       
   257 	MPduOwner* iPduOwner;	// Non-owned pointer.
       
   258 	
       
   259 	// Optimal Fragment size.
       
   260 	// Only set for basic mode as we expect segmentation only in all other cases.
       
   261 	TInt iOptimalFragmentSize;
       
   262 	
       
   263 public:	
       
   264 	TUint16 iTotalNumberOfFragments;
       
   265 	TUint16 iFragmentAcksReceived;
       
   266 	};
       
   267 
       
   268 //
       
   269 // Class used to fragment and send any type of PDU.
       
   270 // An instance of this class is currently owned by the Mux
       
   271 //
       
   272 NONSHARABLE_CLASS(HFragmentedPDUSender)
       
   273 	{
       
   274 public:
       
   275 	enum TFragmentSenderStatus
       
   276 		{
       
   277 		EFragmentOK				= 0,
       
   278 		EFragmentationComplete 	= 1,
       
   279 		EFlowControlledOff 		= 2,
       
   280 		};
       
   281 		
       
   282 	HFragmentedPDUSender(CL2CAPMux& aMuxer);
       
   283 	~HFragmentedPDUSender();
       
   284 		
       
   285 	TInt FragmentPDU(HL2CapPDU& aPDU);
       
   286 	TFragmentSenderStatus WriteNextFragment(CServProviderBase& aSender, TInt aACLMTU);
       
   287 	inline TBool IsPDUBeingSent() const; 
       
   288 
       
   289 	void Reset();
       
   290 	void CheckForFlushed();
       
   291 	void PDUSenderFailed();
       
   292 
       
   293 private:
       
   294 	HL2CapPDU* iPDU;			// Non-owned
       
   295 	HBufC8* iPDUBuffer;			// Buffer for the outgoing PDU.
       
   296 	CL2CAPMux& iMuxer;			// Reference to the sending object.
       
   297 	TInt iCurrentWriteIndex;	// Current position in the PDU buffer.
       
   298 	TUint16 iCurrentFragmentID;	// Current [next] fragment ID to be sent (first fragment has ID = 0)
       
   299 	TInt iPDULength;			// Length of the PDU being sent.
       
   300 	TInt iPDUFragmentSize;		// Optimal fragment size.
       
   301 	};
       
   302 
       
   303 //
       
   304 // Basic frame PDU class.
       
   305 //
       
   306 NONSHARABLE_CLASS(HBFramePDU) : public HL2CapPDU
       
   307 	{
       
   308 public:
       
   309 	~HBFramePDU();
       
   310 
       
   311 	static HBFramePDU* New(RMBufChain& aPayloadData, TInt aOptimalFragmentSize);
       
   312 
       
   313 	// Deliver Interface.
       
   314 	void DeliverOutgoingPDUDoubleDispatch(MOutgoingPDUHandler& aPDUHandler);
       
   315 
       
   316 	static void RemoveHeaderBytes(RMBufChain& aPDU);
       
   317 	void AppendPayloadToBuffer(RMBufChain& aSDUData);
       
   318 
       
   319 	void PDUFragmentSent(TUint16 aFragmentIx);
       
   320 	
       
   321 	static TInt CheckPayloadDecode(const RMBufChain& aPDU);
       
   322 		
       
   323 private:
       
   324 	HBFramePDU(RMBufChain& aPDUData, TInt aOptimalFragmentSize);
       
   325 
       
   326 	virtual void SendComplete();
       
   327 	};
       
   328 
       
   329 	
       
   330 //
       
   331 // Information frame PDU class.
       
   332 //
       
   333 NONSHARABLE_CLASS(HIFramePDU) : public HL2CapPDU
       
   334 	{
       
   335 public:
       
   336 	~HIFramePDU();
       
   337 	
       
   338 	static HIFramePDU* New(RMBufChain& aPayloadData, TL2CapSAR aPduSAR);
       
   339 
       
   340 	// Deliver Interface.
       
   341 	void DeliverOutgoingPDUDoubleDispatch(MOutgoingPDUHandler& aPDUHandler);
       
   342 
       
   343 	// Message Accessors.
       
   344 	// Static
       
   345 	static TBool IFrameIdentifier(const RMBufChain& aPDU);
       
   346 	static TBool CheckFCS(const RMBufChain& aPDU);
       
   347 	static TInt CheckPayloadDecode(const RMBufChain& aPDU);
       
   348 	static TInt CheckLengthWithinLimits(const RMBufChain& aPDU, TUint16 aMps);
       
   349 	static TInt CheckStartSduLength(const RMBufChain& aPDU, TUint16 aMtu);
       
   350 	static TL2CapSAR SAR(const RMBufChain& aPDU);
       
   351 	static void RemoveHeaderAndFCSBytes(RMBufChain& aPDU);
       
   352 	static TBool IsStartOfSDU(const RMBufChain& aPDU);
       
   353 	static TUint16 SDUSize(const RMBufChain& aPDU);
       
   354 	static TUint8 ReqSeqNumber(const RMBufChain& aPDU);
       
   355 	static TUint8 TxSeqNumber(const RMBufChain& aPDU);
       
   356 	static TBool FinalBit(const RMBufChain& aPDU);
       
   357 	static TBool RetransmitDisable(const RMBufChain& aPDU);
       
   358 	
       
   359 	// Member
       
   360 	void SetFinalBit(TBool aFinalBit);
       
   361 	inline TBool FinalBit() const;
       
   362 	
       
   363 	inline TUint8 TxSeqNumber() const;
       
   364 	void SetTxSeqNumber(TUint8 aTxSeqNum);
       
   365 	
       
   366 	void SetRetransmitDisable(TBool aReTxDisable);
       
   367 
       
   368 	inline TUint8 ReqSeqNumber() const;
       
   369 	void SetReqSeqNumber(TUint8 aReqSeqNum);
       
   370 	
       
   371 	inline TL2CapSAR SAR() const;
       
   372 	void SetSAR(TL2CapSAR aSARValue);
       
   373 	
       
   374 	inline TUint16 SDUSize() const;
       
   375 	void SetSDUSize(TUint16 aSDUSize);
       
   376 	
       
   377 	void CalculateAndSetFCS();
       
   378 	TBool CheckFCS();
       
   379 	
       
   380 	void AppendPayloadToBuffer(RMBufChain& aSDUData);	
       
   381 
       
   382 	inline TBool IsStartOfSDU() const;
       
   383 	
       
   384 	// Re-transmission Methods
       
   385 	inline TBool CanTransmit(TUint8 aMaxNumberOfTransmissions) const;
       
   386 	inline TUint8 TransmissionCount() const;
       
   387 	
       
   388 	inline TBool Acked() const { return iAcked; }
       
   389 	inline void SetAcked(TBool aAcked) { iAcked = aAcked; }
       
   390 
       
   391 private:
       
   392 	const static TUint16 KIFrameControlDefault	= 0x0000;			
       
   393 
       
   394 	HIFramePDU(RMBufChain& aPDUData);
       
   395 
       
   396 	void SetIFrameControlDefault();
       
   397 	virtual void SendComplete();
       
   398 
       
   399 	TUint8 iTransmissionCount;
       
   400 	TBool iAcked;					// has been acknowledged by the remote
       
   401 	};
       
   402 
       
   403 //
       
   404 // Group frame PDU class.
       
   405 //
       
   406 NONSHARABLE_CLASS(HGFramePDU) : public HL2CapPDU
       
   407 	{
       
   408 public:
       
   409 	HGFramePDU(RMBufChain& aPDUData);
       
   410 	~HGFramePDU();
       
   411 	
       
   412 	static HGFramePDU* New(RMBufChain& aPayloadData);
       
   413 
       
   414 	// Deliver Interface.
       
   415 	void DeliverOutgoingPDUDoubleDispatch(MOutgoingPDUHandler& aPDUHandler);
       
   416 
       
   417 	TUint16 PSM() const;
       
   418 	void SetPSM(TUint16 aPSM);
       
   419 	
       
   420 	void AppendPayloadToBuffer(RMBufChain& aSDUData);
       
   421 	
       
   422 private:
       
   423 	const static TUint8 KGFramePSMLength 			= 2;
       
   424 	};
       
   425 
       
   426 
       
   427 //
       
   428 // Control frame PDU class.
       
   429 //
       
   430 NONSHARABLE_CLASS(HCFramePDU) : public HL2CapPDU
       
   431 	{
       
   432 public:
       
   433 	const static TUint8 KCFrameHeaderLength			= 4;
       
   434 	const static TUint8 KCFrameCodeSize				= 1;
       
   435 	const static TUint8 KCFrameIdentifierSize		= 1;
       
   436 	const static TUint8 KCFrameLengthSize     		= 2;
       
   437 		
       
   438 	static HCFramePDU* New(TInt aOptimalFragmentSize);
       
   439 
       
   440 	HCFramePDU(RMBufChain& aPDUData, TInt aOptimalFragmentSize);
       
   441 	
       
   442 	~HCFramePDU();
       
   443 
       
   444 	// Deliver Interface.
       
   445 	void DeliverOutgoingPDUDoubleDispatch(MOutgoingPDUHandler& aPDUHandler);
       
   446 
       
   447 	HL2CapCommand* FirstCommand();
       
   448 	HL2CapCommand* NextCommand();
       
   449 
       
   450 	inline TBool HasCommands() const;
       
   451 	
       
   452 	TInt AddCommand(HL2CapCommand& aCommand, CL2CAPMux& aMuxer);
       
   453 	TInt CheckDecode();
       
   454 	
       
   455 private:
       
   456 	TInt CheckPayloadDecode();
       
   457 	TInt CreateCommands();
       
   458 	
       
   459 	//Dbl link list of commands included within this pdu
       
   460 	TDblQue<HL2CapCommand> iCommands;
       
   461 	TDblQueIter<HL2CapCommand> iCommandIter;
       
   462 	};
       
   463 
       
   464 
       
   465 //
       
   466 // Supervisory frame PDU class.
       
   467 //
       
   468 NONSHARABLE_CLASS(HSFramePDU) : public HL2CapPDU
       
   469 	{
       
   470 public:
       
   471 	HSFramePDU(RMBufChain& aPDUData);
       
   472 	~HSFramePDU();
       
   473 	
       
   474 	static HSFramePDU* New(TSupervisoryFunction aFunction);
       
   475 	static HSFramePDU* NewL(TSupervisoryFunction aFunction);
       
   476 
       
   477 	// Deliver Interface.
       
   478 	void DeliverOutgoingPDUDoubleDispatch(MOutgoingPDUHandler& aPDUHandler);
       
   479 
       
   480 	// Message Accessors.
       
   481 	// Static
       
   482 	static TInt CheckLengthField(const RMBufChain& aPDU);
       
   483 	static TBool CheckFCS(RMBufChain& aPDU);
       
   484 	static TInt CheckPayloadDecode(RMBufChain& aPDU);
       
   485 	static TSupervisoryFunction SupervisoryFunction(const RMBufChain& aPDU);
       
   486 	static TUint8 ReqSeqNumber(const RMBufChain& aPDU);
       
   487 	static TBool RetransmitDisable(const RMBufChain& aPDU);
       
   488 	static TBool FinalBit(const RMBufChain& aPDU);
       
   489 	static TBool PollBit(const RMBufChain& aPDU);
       
   490 	
       
   491 	// Members
       
   492 	void SetFinalBit(TBool aFinalBit);
       
   493 	inline TBool FinalBit() const;
       
   494 
       
   495 	void SetPollBit(TBool aPollBit);
       
   496 	inline TBool PollBit() const;
       
   497 
       
   498 	void SetSupervisoryFunction(TSupervisoryFunction aSupervisoryFunction);
       
   499 	inline TSupervisoryFunction SupervisoryFunction() const;
       
   500 
       
   501 	void SetRetransmitDisable(TBool aReTxDisable);
       
   502 	void SetReqSeqNumber(TUint8 aReqSeqNum);
       
   503 	inline TUint8 ReqSeqNumber() const;
       
   504 	
       
   505 	void CalculateAndSetFCS();
       
   506 	TInt CheckFCS();
       
   507 
       
   508 	void SetSFrameControlDefault();
       
   509 	
       
   510 	void PDUFragmentSent(TUint16 aFragmentIx);
       
   511 	
       
   512 private:
       
   513 	const static TUint16 KSFrameControlDefault	= 0x0001;			
       
   514 	};
       
   515 
       
   516 
       
   517 //
       
   518 // PDU Fragment sender inline methods.
       
   519 //
       
   520 inline TBool HFragmentedPDUSender::IsPDUBeingSent() const
       
   521 	{
       
   522 	return (iPDU != NULL);
       
   523 	}
       
   524 
       
   525 
       
   526 //
       
   527 // Base class inline methods.
       
   528 //
       
   529 inline RMBufChain& HL2CapPDU::PDUBuffer()
       
   530 	{
       
   531 	return iPDUData;
       
   532 	}
       
   533 
       
   534 inline void HL2CapPDU::SetPDUFlushed()
       
   535 	{
       
   536 	iIsFlushed = ETrue;
       
   537 	}
       
   538 	
       
   539 inline TBool HL2CapPDU::IsPDUFlushed() const
       
   540 	{
       
   541 	return iIsFlushed;
       
   542 	}
       
   543 
       
   544 inline TDataPlaneElementHandle& HL2CapPDU::ElementHandle()
       
   545 	{
       
   546 	return iElementHandle;
       
   547 	}
       
   548 
       
   549 inline TUint16 HL2CapPDU::PDUCID() const
       
   550 	{
       
   551 	return PDUCID(iPDUData);
       
   552 	}
       
   553 
       
   554 inline TUint16 HL2CapPDU::PDUPayloadLength() const
       
   555 	{
       
   556 	return PDUPayloadLength(iPDUData);
       
   557 	}
       
   558 
       
   559 inline TUint16 HL2CapPDU::CalcCRC()	
       
   560 	{
       
   561 	return CalcCRC(iPDUData);
       
   562 	}
       
   563 	
       
   564 inline TInt HL2CapPDU::OptimalFragmentSize() const
       
   565 	{
       
   566 	return iOptimalFragmentSize;
       
   567 	}
       
   568 
       
   569 inline void HL2CapPDU::SetPduOwner(MPduOwner* aPduOwner)
       
   570 	{
       
   571 	__ASSERT_ALWAYS(aPduOwner != NULL, Panic(EL2CAPNullOwnerSupplied));
       
   572 	__ASSERT_ALWAYS(iPduOwner == NULL || iPduOwner == aPduOwner, Panic(EL2CAPTryingToStealOwnedPdu));
       
   573 	iPduOwner = aPduOwner;
       
   574 	}
       
   575 
       
   576 inline TBool HL2CapPDU::HasOwner() const
       
   577 	{
       
   578 	return iPduOwner != NULL;
       
   579 	}
       
   580 
       
   581 inline TBool HL2CapPDU::IsOwner(const MPduOwner* aPduOwner) const
       
   582 	{
       
   583 	__ASSERT_ALWAYS(aPduOwner != NULL, Panic(EL2CAPNullOwnerSupplied));
       
   584 	return iPduOwner == aPduOwner;
       
   585 	}
       
   586 
       
   587 inline void HL2CapPDU::DeregisterPduOwner()
       
   588 	{
       
   589 	iPduOwner = NULL;
       
   590 	}
       
   591 
       
   592 inline TBool HL2CapPDU::IsAwaitingHciCompletion() const
       
   593 	{
       
   594 	return iAwaitingHciCompletion;
       
   595 	}
       
   596 
       
   597 inline TBool HL2CapPDU::IsQueuedForSend() const
       
   598 	{
       
   599 	return iQueuedForSend;
       
   600 	}
       
   601 
       
   602 inline void HL2CapPDU::SetQueuedForSend(TBool aQueuedForSend)
       
   603 	{
       
   604 	iQueuedForSend = aQueuedForSend;
       
   605 	}
       
   606 
       
   607 //
       
   608 // Information frame inline methods.
       
   609 //
       
   610 inline TBool HIFramePDU::CanTransmit(TUint8 aMaxNumberOfTransmissions) const
       
   611 	{
       
   612 	return (iTransmissionCount < aMaxNumberOfTransmissions);
       
   613 	}
       
   614 
       
   615 inline TUint8 HIFramePDU::TransmissionCount() const
       
   616 	{
       
   617 	return iTransmissionCount;
       
   618 	}
       
   619 
       
   620 
       
   621 inline TL2CapSAR HIFramePDU::SAR() const
       
   622 	{
       
   623 	return SAR(iPDUData);
       
   624 	}
       
   625 	
       
   626 inline TBool HIFramePDU::IsStartOfSDU() const
       
   627 	{
       
   628 	return IsStartOfSDU(iPDUData);
       
   629 	}
       
   630 
       
   631 inline TUint16 HIFramePDU::SDUSize() const
       
   632 	{
       
   633 	return SDUSize(iPDUData);
       
   634 	}
       
   635 
       
   636 inline TUint8 HIFramePDU::ReqSeqNumber() const
       
   637 	{
       
   638 	return ReqSeqNumber(iPDUData);
       
   639 	}
       
   640 
       
   641 inline TUint8 HIFramePDU::TxSeqNumber() const
       
   642 	{
       
   643 	return TxSeqNumber(iPDUData);
       
   644 	}
       
   645 
       
   646 inline TBool HIFramePDU::FinalBit() const
       
   647 	{
       
   648 	return FinalBit(iPDUData);
       
   649 	}
       
   650 
       
   651 //
       
   652 // Control frame inline methods.
       
   653 //
       
   654 inline TBool HCFramePDU::HasCommands() const
       
   655 	{
       
   656 	return !iCommands.IsEmpty();
       
   657 	}
       
   658 
       
   659 //
       
   660 // Supervisory frame inline methods.
       
   661 //
       
   662 inline TBool HSFramePDU::FinalBit() const
       
   663 	{
       
   664 	return FinalBit(iPDUData); 
       
   665 	}
       
   666 
       
   667 inline TBool HSFramePDU::PollBit() const
       
   668 	{
       
   669 	return PollBit(iPDUData);
       
   670 	}
       
   671 
       
   672 inline TSupervisoryFunction HSFramePDU::SupervisoryFunction() const
       
   673 	{
       
   674 	return SupervisoryFunction(iPDUData);
       
   675 	}
       
   676 
       
   677 inline TUint8 HSFramePDU::ReqSeqNumber() const
       
   678 	{
       
   679 	return ReqSeqNumber(iPDUData);
       
   680 	}
       
   681 
       
   682 #endif