bluetooth/btstack/rfcomm/rfcommmuxer.h
changeset 0 29b1cd4cb562
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 RFCOMMMUXER_H
       
    17 #define RFCOMMMUXER_H
       
    18 
       
    19 #include <es_prot.h>
       
    20 #include <bttypes.h>
       
    21 #include "rfcommsap.h"
       
    22 #include "rfcommframe.h"
       
    23 #include "rfcommflow.h"
       
    24 
       
    25 class CRfcommSignalFrame;
       
    26 class CRfcommMuxChannel;
       
    27 class CRfcommFlowStrategyFactory;
       
    28 class CMuxChannelStateFactory;
       
    29 class TRfcommFlowStrategy;
       
    30 /**
       
    31    Acts as the TS7.10 multiplexer.
       
    32    
       
    33    There is one of these per remote device, as only one RFCOMM
       
    34    multiplexer session can be run between two devices.  This class
       
    35    acts as an internal socket binding to a lower level SAP.  Thus we
       
    36    derive from MSocketNotify so that the SAP can directly notify us of events.
       
    37 
       
    38 **/
       
    39 NONSHARABLE_CLASS(CRfcommMuxer) : public CBase, public MSocketNotify
       
    40 	{
       
    41 friend class CRfcommProtocol;
       
    42 friend class CRfcommMuxChannel;
       
    43 
       
    44 public:
       
    45 	// Create/destroy
       
    46 
       
    47 	// Two flavours of factory - one takes an L2CAP connection which should 
       
    48 	// be used by the Mux channel associated with this muxer. The other 
       
    49 	// takes a CProtocolBase which it can use to create its own connection
       
    50 	static CRfcommMuxer* NewL(CRfcommProtocol& aProt, CProtocolBase& aL2CAP,
       
    51 							  CMuxChannelStateFactory& aFactory);
       
    52 
       
    53 	static CRfcommMuxer* NewL(CRfcommProtocol& aProt, CServProviderBase* aSAP,
       
    54 							  CMuxChannelStateFactory& aFactory);
       
    55 	
       
    56 	~CRfcommMuxer();
       
    57 	// Interface for the Protocol to request services
       
    58 	void Bind(TBTDevAddr& aAddr);
       
    59 	void AddSAP(CRfcommSAP& aSAP);
       
    60 	void DetachSAP(CRfcommSAP& aSAP);
       
    61 
       
    62 	void GetInboundServerChannelsInUse(TFixedArray<TBool, KMaxRfcommServerChannel>& aChannelInUse);
       
    63 	
       
    64 	// Interface for the SAPs to request actions
       
    65 	TUint8 MakeOutboundDLCI(TUint8 aServerChannel);
       
    66 	TUint8 MakeInboundDLCI(TUint8 aServerChannel);
       
    67 	TUint8 MakeServerChannel(TUint8 aDLCI);
       
    68 
       
    69 	TInt SendSABM(CRfcommSAP& aSAP);
       
    70 	TInt SendMSC(CRfcommSAP& aSAP, TUint8 aFlags);
       
    71 	TInt SendMSCRsp(CRfcommSAP& aSAP, TUint8 aFlags);
       
    72 	TInt SendRLS(CRfcommSAP& aSAP, TUint8 aStatus);
       
    73 	TInt SendRLSRsp(CRfcommSAP& aSAP, TUint8 aStatus);
       
    74 	TInt SendRPN(CRfcommSAP& aSAP, TBool aCommand, TUint8 aLength, 
       
    75 				 const TRfcommRPNTransaction& aRPNTransaction);
       
    76 	TInt SendUA(CRfcommSAP& aSAP);
       
    77 	TInt SendUA(TUint8 aDLCI);
       
    78 	TInt SendPN(CRfcommSAP& aSAP, const TRfcommPortParams& params);
       
    79 	TInt SendPNResponse(CRfcommSAP& aSAP, const TRfcommPortParams& params);
       
    80 	void SendDISC(CRfcommSAP& aSAP);
       
    81 	void SendDISC(TUint8 aDLCI);
       
    82 	void SendDM(TUint8 aDLCI);
       
    83 	TInt SendFCon();
       
    84 	TInt SendFCoff();
       
    85 	void Donate(CRfcommSAP& aSAP, TUint8 aCredit); //TRY_CBFC
       
    86 	TInt Write(CRfcommSAP& aSAP, TUint8 aCredit, const TDesC8& aData);
       
    87 	void SetCanHandleData(CRfcommSAP& aSAP, TBool aCanReceive);
       
    88 	TInt GetMaxDataSize() const;
       
    89 	TInt Ioctl(TUint aLevel, TUint aName, TDes8* aOption);
       
    90 	void CancelIoctl(TUint aLevel, TUint aName);
       
    91 	TInt SetOption(TUint aLevel, TUint aName, const TDesC8 &aOption);
       
    92 	TInt GetOption(TUint aLevel, TUint aName, TDes8 &aOption);
       
    93 	
       
    94 	// From MSocketNotify
       
    95 	void NewData(TUint aCount);
       
    96 	void CanSend();
       
    97 	void ConnectComplete();
       
    98 	void ConnectComplete(const TDesC8& aConnectData);
       
    99 	void ConnectComplete(CServProviderBase& aSSP);
       
   100 	void ConnectComplete(CServProviderBase& aSSP,const TDesC8& aConnectData);
       
   101 	void CanClose(TDelete aDelete=EDelete);
       
   102 	void CanClose(const TDesC8& aDisconnectData,TDelete aDelete=EDelete);
       
   103 	void Error(TInt anError,TUint anOperationMask=EErrorAllOperations);
       
   104 	void Disconnect(void);
       
   105 	void Disconnect(TDesC8& aDisconnectData);
       
   106 	void IoctlComplete(TDesC8 *aBuf);
       
   107 
       
   108 	void NoBearer(const TDesC8& /*aConnectionInf*/) {};
       
   109 	void Bearer(const TDesC8& /*aConnectionInf*/) {};
       
   110 
       
   111 	// Other functions
       
   112 	void PropagateIoctlCompletion(TInt aError, TUint aIoctlLevel, TUint aIoctlName, TDesC8* aBuf);
       
   113 	void FrameResponseTimeout(CRfcommFrame* aFrame);
       
   114 	
       
   115 	void ClearResponseQueue(CRfcommSAP& aSAP);
       
   116 	void ClearOutboundQueue(CRfcommSAP& aSAP);
       
   117 	
       
   118 	void MuxChannelUp();
       
   119 	void MuxChannelDown();	// the MuxChannel has gone down - so notify SAPs
       
   120 	void MuxChannelError(TBool aFatal, TInt anError);
       
   121 	void MuxChannelClosed();	// the MuxChannel has gone down - no need for the muxer
       
   122 	void CloseSAPs();
       
   123 	const TBTDevAddr& RemoteBTAddr() const;
       
   124 	CRfcommSAP* FindSAP(const TUint8 aDLCI);
       
   125 //TRY_CBFC
       
   126 	void DisallowCBFC();
       
   127 	void AllowCBFC();
       
   128 	TRfcommFlowStrategy* FlowStrategy();
       
   129 	CRfcommFlowStrategyFactory::TFlowStrategies FlowType();
       
   130 	TBool SetFlowType(CRfcommFlowStrategyFactory::TFlowStrategies aFlowType);
       
   131 
       
   132 
       
   133 
       
   134 private:
       
   135 
       
   136 	enum TInitiationDirection
       
   137 		{
       
   138 		KInitiationDirectionIncoming,	//	0
       
   139 		KInitiationDirectionOutgoing	//	1
       
   140 		};
       
   141 		
       
   142 	CRfcommMuxer(CRfcommProtocol& aProtocol, TInitiationDirection); 
       
   143 	void ConstructL(CMuxChannelStateFactory& aFactory, CProtocolBase& aL2CAP);
       
   144 	void ConstructL(CMuxChannelStateFactory& aFactory, CServProviderBase* aSAP);
       
   145 	void CommonConstructL();
       
   146 
       
   147 	// Processing incoming frames
       
   148 	void ProcessFrame();
       
   149 	void ParseCtrlMessageL();
       
   150 	void ParsePNL(TInt aOffset, TInt aLen, TUint8& aDLCI, TRfcommPortParams& aParams);
       
   151 	void ParseRPN(TInt aOffset, TInt aLen, TUint8& aDLCI, 
       
   152 				  TRfcommRPNTransaction* aRPNTransactionPtr=NULL);
       
   153 	void ProcessDataFrame(TUint8 aDLCI, TBool aPoll);
       
   154 	TInt GetTypeFieldL(TInt& aType, TInt aPos);
       
   155 	TInt GetLengthFieldL(TInt& aLen, TInt aPos);
       
   156 	void HandleDISC(TUint8 aDLCI);
       
   157 	void HandleSABM(TUint8 aDLCI);
       
   158 	void HandleUA(TUint8 aDLCI);
       
   159 	void HandleDM(TUint8 aDLCI);
       
   160 	void HandlePN(TBool aCommand, TUint8 aDLCI, TRfcommPortParams& aParams);
       
   161 	void HandleRPN(const TBool& aCommand, const TUint8& aDLCI, 
       
   162 				   const TRfcommRPNTransaction* aRPNTransactionPtr=NULL);
       
   163 	void HandleTest(TBool aCommand, TInt aOffset, TInt aLen);
       
   164 	void HandleFCon(TBool aCommand);
       
   165 	void HandleFCoff(TBool aCommand);
       
   166 	void HandleMSC(TBool aCommand, TUint8 aDLCI, TUint8 aSignals);
       
   167 	void HandleRLS(TBool aCommand, TUint8 aDLCI, TUint8 aStatus);
       
   168 	
       
   169 	// Packet utility functions
       
   170 	TBool CheckFCS(TUint8 aFCS, TUint8 aCtrl);
       
   171 	TUint8 DecodeDLCI(TUint8 aAddr);
       
   172 	void DecodeLengthAndCredit(TBool aCBFC);
       
   173 	TUint8 BuildAddr(TUint8 aDLCI, TBool aCommand);
       
   174 	void EnqueFrame(CRfcommFrame* aFrm);
       
   175 	void TryToSend();
       
   176 	TInt CtrlFrameResponse(TUint8 aDLCI);
       
   177 	void MuxCtrlResponse(TUint8 aType);
       
   178 	void MuxCtrlResponseDM(TUint8 aDLCI);
       
   179 	
       
   180 	// Flow control
       
   181 	void SetSendBlocked(CRfcommSAP& aSAP, TBool aState);
       
   182 	void SignalSAPsCanSend();
       
   183 	TBool ClearToSend() const
       
   184 			{return iCanSend;}
       
   185 	void SetCanSend(TBool aState)   //< True if OK to send
       
   186 			{iCanSend=aState;}
       
   187 	TBool L2CAPBlocked() const
       
   188 			{return iL2CAPSendBlocked;}
       
   189 	void L2CAPBlocked(TBool aState)
       
   190 			{iL2CAPSendBlocked=aState;}
       
   191 
       
   192 	// Constructing packets
       
   193 	CRfcommMuxCtrlFrame* NewSignalFrame(TInt aCommandLength, TBool aCommand, CRfcommSAP* aSAP =NULL);
       
   194 	CRfcommCtrlFrame* NewFrame(CRfcommSAP* aSAP =NULL);
       
   195 	CRfcommDataFrame* NewDataFrame(TUint8 aDLCI, TInt aLen, TUint8 aCredit, CRfcommSAP* aSAP=NULL);
       
   196 
       
   197 	// Sending packets
       
   198 	TInt TransmitSABM(TUint8 aDLCI, CRfcommSAP* aSAP =NULL);
       
   199 	TInt TransmitUA(TUint8 aDLCI, CRfcommSAP* aSAP =NULL);
       
   200 	TInt TransmitDISC(TUint8 aDLCI, CRfcommSAP* aSAP =NULL);
       
   201 	TInt TransmitDM(TUint8 aDLCI, TBool aPFBit, CRfcommSAP* aSAP =NULL);	
       
   202 	TInt TransmitPN(TUint8 aDLCI, TBool aCommand, const TRfcommPortParams& aParams,
       
   203 					CRfcommSAP* aSAP =NULL);
       
   204 	TInt TransmitRPN(TUint8 aDLCI, TBool aCommand, TUint8 aLen,
       
   205 					 const TRfcommRPNTransaction& aRPNTransaction, CRfcommSAP* aSAP = NULL);
       
   206 	TInt TransmitNSC(TBool aCommand, TUint8 aType);
       
   207 	TInt TransmitFCon(TBool aCommand, CRfcommSAP* aSAP =NULL);
       
   208 	TInt TransmitFCoff(TBool aCommand, CRfcommSAP* aSAP =NULL);
       
   209 	TInt TransmitMSC(TUint8 aDLCI, TBool aCommand, TUint8 aSignals,
       
   210 					  CRfcommSAP* aSAP =NULL);
       
   211 	TInt TransmitTest(TBool aCommand, const TDesC8& aData, CRfcommSAP* aSAP =NULL);
       
   212 	TInt TransmitRLS(TBool aCommand, TUint8 aDLCI, TUint8 aStatus,
       
   213 					 CRfcommSAP* aSAP =NULL);
       
   214 
       
   215 	
       
   216 	// Callbacks & timers
       
   217 	static TInt IdleTimerExpired(TAny* aMux);
       
   218 	static TInt TryToSendCallbackStatic(TAny* aMux);
       
   219 	void TryToSendCallback();
       
   220 	void CheckForIdle(TBool aClosing = EFalse);
       
   221 	void QueIdleTimer();
       
   222 	void DequeIdleTimer();
       
   223 
       
   224 	// Utility
       
   225 	void DeleteQueuedFrames();
       
   226 	CRfcommSAP* FindConnectedOrListeningSAP(const TUint8 aDLCI);
       
   227 	TUint8 MakeDLCI(TUint8 aServerChannel, TUint8 aDirectionBit);
       
   228 
       
   229 	// Reception of data from L2CAP
       
   230 	TBool CanProcessNewData() const;
       
   231 	void SetNoFreeSpace(TInt aDLCI, TBool aNoSpace);
       
   232 
       
   233 	// Debug
       
   234 #ifdef __FLOG_ACTIVE
       
   235 	void ExplainOutgoingFrame(CRfcommFrame* aFrm, CRfcommMuxer* aMux );
       
   236 	void LogMuxCommand(CRfcommSAP* aSAP, CRfcommMuxer* aMux, TUint8 aCommand);
       
   237 #endif
       
   238 	
       
   239 	// Data items
       
   240 	TDblQue<CRfcommSAP> iSAPs;  //< SAPs using this Mux
       
   241 	TDblQue<CRfcommFrame> iOutboundQ; //< Frames to send
       
   242 	TDblQue<CRfcommFrame> iResponseQ; //< Frames waiting for a response
       
   243 	TInt iOutboundQLength;
       
   244 	CRfcommProtocol& iProtocol;
       
   245 	CServProviderBase* iBoundSAP;
       
   246 	TInt iL2CAPMTU;
       
   247 	TBTDevAddr  iRemoteAddr;
       
   248 	const TInt iDirection; //< 1 if we are initiating, else 0
       
   249 
       
   250 	TBool iClosing;  //< True if we are closing down our channel
       
   251 	TDeltaTimerEntry  iIdleTimerEntry; //< Disconnection idle timer
       
   252 	TBool  iIdleTimerQueued;
       
   253 	TInt iMuxIdleTimeout;
       
   254 
       
   255 	CAsyncCallBack* iSendCallback;
       
   256 	HBufC8*  iNextPacket;   // Next packet coming up from L2CAP
       
   257 
       
   258 	TInt iCurrentHeaderLength; //< Length of the current frame's header
       
   259 	TInt iCurrentDataLength;  //< Length of the current frame's data
       
   260 
       
   261 	// Ioctls
       
   262 	TUint  iIoctlLevel;
       
   263 	TUint  iIoctlName;
       
   264 	
       
   265 	// Flow control
       
   266 	TBool  iCanSend;  //< False if remote has asked us not to send (FCoff)
       
   267 	TDblQue<CRfcommSAP> iBlockedSAPs;  //< SAPs that are blocked
       
   268 	// Control over reading from L2CAP
       
   269 	TInt     iPacketsWaiting;   //< Number of packets L2CAP has for us
       
   270 	TUint32  iSAPNoFreeSpaceMask[2];  //< Mask showing which SAP have no space left
       
   271 	TInt	 iDataFramesSent;
       
   272 	// Mux channel
       
   273 	CRfcommMuxChannel* iMuxChannel;
       
   274 	TBool  iL2CAPSendBlocked;  // Is L2CAP ok to send data?
       
   275 	//TRY_CBFC
       
   276 	TBool iCBFCDisallowed; // ensure flow strategy set to Mux type when object is instantiated
       
   277 	TBool iTriedCBFC;	// have we tried to set CBFC ?
       
   278 	TInt iCurrentCredit; // a temporary store for the received frame credit
       
   279 	TInt iInitialTxCredit;	// used as default credit for new SAPs
       
   280 	TRfcommFlowStrategy* iFlowStrategy;
       
   281 	
       
   282 	// Go on a Q
       
   283 	TDblQueLink iLink;
       
   284 	};
       
   285 
       
   286 
       
   287 #endif