linklayerprotocols/pppnif/SPPP/PPPHDLC.H
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 1997-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 /**
       
    17  @file
       
    18  @internalComponent 
       
    19 */
       
    20 
       
    21 #if !defined(PPPHDLC_H)
       
    22 #define PPPHDLC_H
       
    23 
       
    24 #include <networking/bca.h>
       
    25 #include <networking/bcafactory.h>
       
    26 #include "PPPBASE.H"
       
    27 #include "PPPConfig.h"
       
    28 
       
    29 //=========================================
       
    30 // JGG PPP CHANGE
       
    31 #include <etelpckt.h>
       
    32 //#include <ETelGprs.h> // don't link to ETelGPRS, just include for the data count structure
       
    33 //=========================================
       
    34 
       
    35 #ifndef MAX
       
    36  #define MAX(a, b) ((a > b) ? a : b)
       
    37 #endif
       
    38 // Length of longest typical encoded HDLC frame 
       
    39 const TInt KPppHdlcSize    = 1503;
       
    40 const TInt KPppHdlcFcsSize = 4;
       
    41 
       
    42 // Create buffer at least size of mbuf + overhead, to ensure execution of escape sequence expansion code (refer CPppHdlcLink::DoSend)
       
    43 const TInt KPppHdlcBufSize = 2 * (MAX(KPppHdlcSize, KMBufSmallSize) + KPppHdlcFcsSize + 1);
       
    44 typedef TBuf8<KPppHdlcBufSize> TPppHdlcBuf;
       
    45 
       
    46 // Framing chars
       
    47 const TUint8 KPppHdlcFlagChar = 0x7e;
       
    48 const TUint8 KPppHdlcEscChar = 0x7d; 
       
    49 const TUint8 KPppHdlcEscBit = 0x20;
       
    50 
       
    51 // HDLC address and control vales
       
    52 const TUint8 KPppHdlcAddrByte = 0xff;
       
    53 const TUint8 KPppHdlcCtrlUIByte = 0x03;
       
    54 const TUint8 KPppHdlcPadChar = 0x01;
       
    55 
       
    56 const TInt KPppHdlcSendChannel = 0;
       
    57 const TInt KPppHdlcRecvChannel = 1;
       
    58 
       
    59 const TInt KPppHdlcCommReadPriority = 150;
       
    60 const TInt KPppHdlcCommWritePriority = 100;
       
    61 
       
    62 // Flags use in FCS negotiation
       
    63 const TUint KPppHdlcFcs0Flag = 0x1;
       
    64 const TUint KPppHdlcFcs16Flag = 0x2;
       
    65 const TUint KPppHdlcFcs32Flag = 0x4;
       
    66 
       
    67 using namespace BasebandChannelAdaptation;
       
    68 
       
    69 // BCA factory is hosted in BCA dll: this routine creates BCA factory instance.
       
    70 typedef MBcaFactory* (*TNewBcaFactoryL)();
       
    71 
       
    72 class CBcaWriter;
       
    73 class CBcaReader;
       
    74 class CBcaControl;
       
    75 
       
    76 
       
    77 NONSHARABLE_CLASS(CPppHdlcLink) : public CPppLinkBase, public MPppOptionHandler
       
    78 /**
       
    79 PPP over serial line protocol (RFC 1662)
       
    80 */
       
    81 	{
       
    82 	enum TPppHdlcState
       
    83 		{ EPppHdlcClosed, EPppHdlcConnecting, EPppHdlcOpen, EPppHdlcDisconnecting, EPppHdlcReconnecting };
       
    84 
       
    85 public:
       
    86 	CPppHdlcLink(CPppLcp* aLcp);
       
    87 	~CPppHdlcLink();
       
    88 	virtual void CreateL();
       
    89 	// CPppLinkBase
       
    90 	virtual TInt Send(RMBufChain& aPacket, TUint aPppId=KPppIdAsIs);
       
    91 	virtual void OpenL();
       
    92 	virtual void Close();
       
    93 	virtual void StartL();
       
    94 	virtual void Stop(TInt aReason, TBool aLinkDown=ETrue);	
       
    95 	virtual void GetSendRecvSize(TInt& aMaxRecvSize, TInt& aMaxSendSize);
       
    96 	virtual TInt SpeedMetric();
       
    97 	
       
    98 	//BCA related methods
       
    99 	void LoadBcaL();
       
   100 	
       
   101 	TBool DoShutdownBcaGracefully() const;	
       
   102 	void LinkDown(TInt aStatus);
       
   103 	void LinkTerminationComplete();
       
   104 	
       
   105 	void SetOriginalSerialPortConfig(TCommConfig& aHdlcConfig);
       
   106 	void GetSerialPortConfigForHdlc(TCommConfig& aHdlcConfig) const;
       
   107 	TCommConfig OriginalSerialPortConfig() const;
       
   108 
       
   109 
       
   110 	void CancelOperation();
       
   111 	void StartPPP();
       
   112 	TBool ShutDownPPP();
       
   113 	void FreeBuf();
       
   114 	void BcaReadComplete(TInt aStatus);
       
   115 	void BcaWriteComplete(TInt aStatus); 
       
   116 	#if defined (_DEBUG)
       
   117 	inline CPppLog& Logger() const;
       
   118 	#endif
       
   119 	//======================================
       
   120 	// JGG PPP CHANGE
       
   121 	virtual void GetDataTransfer(RPacketContext::TDataVolume&);
       
   122 	//virtual void GetDataTransfer(RGprsContext::TDataVolume&);
       
   123 	//========================================
       
   124 	
       
   125     inline TPtrC GetBCAStack() const;
       
   126     inline TPtrC GetBCAName() const;
       
   127     inline TPtrC GetPortName() const;
       
   128     inline TUint32 GetIAPid() const;
       
   129     inline TCommRole GetCommRole() const;
       
   130     inline TUint32 GetHandShaking() const;
       
   131     inline TPtrC8 GetExcessData() const;
       
   132     	
       
   133 protected:
       
   134 	 
       
   135 	// MOptionExtender
       
   136 	virtual void OptNegotiationStarted();
       
   137 	virtual void OptNegotiationAborted();
       
   138 	virtual void OptNegotiationComplete();
       
   139 	virtual void OptFillinConfigRequestL(RPppOptionList& aRequestList);
       
   140 	virtual TPppOptResponse OptCheckConfigRequest(RPppOption& aOption);
       
   141 	virtual void OptApplyConfigRequest(RPppOption& aOption);
       
   142 	virtual void OptRecvConfigAck(RPppOption& aOption);
       
   143 	virtual void OptRecvConfigNak(RPppOption& aOption, RPppOptionList& aReqList);
       
   144 	virtual void OptRecvConfigReject(RPppOption& aOption, RPppOptionList& aReqList);
       
   145 private:
       
   146 	void DoSend(TBool aRestart);
       
   147 	void DoRecv();
       
   148 	void DoBadRecv();
       
   149 	TBool AppendRecvMbuf(TUint8*& mptr, TUint8*& mend);
       
   150 	void PacketModeOnL();
       
   151 	void PacketModeOff();
       
   152 	void InitEscMap();
       
   153 	void SetEscMapBit(TUint8 aChar);
       
   154 	inline TBool IsEscapedChar(TUint8 aChar);
       
   155 	inline TBool IsInRecvEscMap(TUint8 aChar);
       
   156 	void EncodeChar(TUint8*& aPtr, TUint8 aChar);
       
   157 	TBool DecodeChar(TUint8*& aPtr, TUint8*& aPtrEnd, TUint8 aChar);
       
   158 	TBool UnescapeChar(TUint8*& ptr, TUint8*& end, TUint8*& mptr, TUint8*& mend);
       
   159 	void DeferredApplyOptions();
       
   160 	void ReadIniFileL();
       
   161 	inline void CallBackOptRequestGranted(); // CSW
       
   162 	void LogUserData(RMBufChain& aPacket, TInt aChannel);	
       
   163 	void CreateHdlcHeader(TUint8*& aPtr, TBool aRestart, TUint16 aProt);
       
   164 	TUint16 DecodeProtocolID(TUint8*& ptr) const;
       
   165 
       
   166 
       
   167     /** The original comm port configuration */
       
   168 	TCommConfig iOrigConfig;
       
   169 	
       
   170 	/** HDLC connection state */
       
   171 	TPppHdlcState iState;
       
   172 	
       
   173 	/** Internal configuration flags */
       
   174 	TUint iFlags;
       
   175 	
       
   176 	/** Flags to apply once LCP has finished negotiation */
       
   177 	TUint iPendingMask;
       
   178 
       
   179 	/** Mask of flags to apply once LCP has finished negotiation */
       
   180 	TUint iPendingFlags;
       
   181 	
       
   182 	/** Currently negotiated control character escape map for sending */
       
   183 	TUint iPendingEscMap;
       
   184 	
       
   185 	RMBuf* iApplyConfigMarker;
       
   186 
       
   187 	/** Send buffer low water mark below which flow is turned on */
       
   188 	TInt iSendLoWat;
       
   189 
       
   190 	/** Send buffer high water mark above which flow is turned off */
       
   191 	TInt iSendHiWat;
       
   192 	
       
   193 	/** Number of buffers currently sending */
       
   194 	TInt iSendNumBufs;
       
   195 	
       
   196 	/** Whether packet flow has been turned off due to exceeding the high water mark */
       
   197 	TBool iSendFlowOn;
       
   198 	
       
   199 	/** Queue of packets to send */
       
   200 	RMBufPktQ iSendQ;
       
   201 	
       
   202 	/** Current packet being sent */
       
   203 	RMBufChain iSendPkt;
       
   204 	
       
   205 	/** Buffer holding bytes to send to comm port */
       
   206 	TPppHdlcBuf iSendBuf;
       
   207 	
       
   208 	/** CRC-16 for current sending frame */
       
   209 	TPppFcs16 iSendFcs16;
       
   210 
       
   211 	/** CRC-16 for current receiving frame */
       
   212 	TPppFcs16 iRecvFcs16;
       
   213 
       
   214 #ifdef __LCP_EXTENSION_FCS_32
       
   215 	/** CRC-32 for current sending frame */
       
   216 	TPppFcs32 iSendFcs32;
       
   217 
       
   218 	/** CRC-32 for current receiving frame */
       
   219 	TPppFcs32 iRecvFcs32;
       
   220 #endif	
       
   221 
       
   222     /** Control character escape map to use while sending */
       
   223 	TUint32 iSendEscMap[8];
       
   224 	
       
   225 	/** Used for telling peer which characters < 0x20 to escape	ACCM negotiation */
       
   226 	TUint32 iRecvEscMap;
       
   227 
       
   228 	/** The escape map we would like to use */
       
   229 	TUint32 iDesiredRecvEscMap;
       
   230 	
       
   231 	/** Queue of incoming PPP packets ready to be processed by LCP */
       
   232 	RMBufPktQ iRecvQ;
       
   233 	
       
   234 	/** Current packet being received */
       
   235 	RMBufQ iRecvPkt;
       
   236 	
       
   237 	/** Current MBuf of packet being received */
       
   238 	RMBuf* iRecvMBuf;
       
   239 	
       
   240 	/** Buffer containing a raw PPP packet from a comm port */
       
   241 	TPppHdlcBuf iRecvBuf;
       
   242 
       
   243     /** Number of IP data bytes sent */
       
   244 	TUint32 iSentData;
       
   245 
       
   246     /** Number of IP data bytes received */
       
   247 	TUint32 iRecvdData;
       
   248 	//TBool iUpdate;
       
   249 	
       
   250 	/** BCA lives here*/
       
   251 	TAutoClose<RLibrary> iBcaDll;
       
   252 
       
   253 	/** The Baseband Channel Adaptor - the actual link provider */
       
   254    	MBca* iBca; 
       
   255    	   	
       
   256    	/** used to send data*/
       
   257 	CBcaWriter* iBcaWriter;
       
   258 	
       
   259 	/** used to receive data*/
       
   260 	CBcaReader* iBcaReader;
       
   261 	
       
   262 	/** used to control the BCA asynchronously*/
       
   263 	CBcaControl* iBcaControl;
       
   264 	
       
   265 	/** IAP ID used to open CommDB*/
       
   266 	TUint32 iIapId;
       
   267 		
       
   268 	/** PPP NIF down error code*/
       
   269 	TInt iError;
       
   270 	
       
   271 	/** if PPP is down*/
       
   272 	TBool iLinkDown;
       
   273 	
       
   274 #if defined (_DEBUG)
       
   275 	/** Verbosity of log */
       
   276 	TInt iLogLevel;
       
   277 	
       
   278 	/** File format of stored data dump */
       
   279 	TInt iLogFormat;
       
   280 	
       
   281 	/** Type of data stored in log dump file */
       
   282 	TInt iLogLinkFormat;
       
   283 #endif
       
   284 	};
       
   285 
       
   286 inline TBool CPppHdlcLink::IsEscapedChar(TUint8 aChar)
       
   287 /**
       
   288 Determine if character should be escaped on transmit based on ACCM negotiation.
       
   289 
       
   290 @param aChar Character
       
   291 
       
   292 @return Whether character should be escaped
       
   293 */
       
   294 	{
       
   295 	return (iSendEscMap[aChar>>5] & (1<<(aChar&0x1f))) !=0;
       
   296 	}
       
   297 
       
   298 inline TBool CPppHdlcLink::IsInRecvEscMap(TUint8 aChar)
       
   299 /**
       
   300 Determine if character should have been escaped on receive based on ACCM negotiation.
       
   301 
       
   302 @param aChar Character
       
   303 
       
   304 @return Whether character should have been escaped
       
   305 */
       
   306 	{
       
   307 	return (iRecvEscMap < 0x20) && (iRecvEscMap & (1<<(aChar&0x1f)));
       
   308 	}
       
   309 	
       
   310 inline TUint32 CPppHdlcLink::GetIAPid() const
       
   311     {
       
   312     return iPppLcp->GetBCAProvision()->GetIAPid();
       
   313     }
       
   314     
       
   315 inline TPtrC CPppHdlcLink::GetBCAStack() const
       
   316     {
       
   317     return iPppLcp->GetBCAProvision()->GetBCAStack();        
       
   318     }
       
   319 
       
   320 inline TPtrC CPppHdlcLink::GetBCAName() const
       
   321     {
       
   322     return iPppLcp->GetBCAProvision()->GetBCAName();
       
   323     }
       
   324 
       
   325 inline TPtrC CPppHdlcLink::GetPortName() const
       
   326     {
       
   327     return iPppLcp->GetBCAProvision()->GetPortName();        
       
   328     }
       
   329 
       
   330 inline TCommRole CPppHdlcLink::GetCommRole() const
       
   331     {
       
   332     return iPppLcp->GetBCAProvision()->GetCommRole();
       
   333     }
       
   334 
       
   335 inline TUint32 CPppHdlcLink::GetHandShaking() const
       
   336     {        
       
   337     return iPppLcp->GetBCAProvision()->GetHandShaking();
       
   338     }
       
   339 
       
   340 inline TPtrC8 CPppHdlcLink::GetExcessData() const
       
   341     {        
       
   342     return iPppLcp->GetExcessData();
       
   343     }
       
   344 
       
   345 /** Gets the PPP logger
       
   346 
       
   347 @return the reference to the logger object.
       
   348 */
       
   349 #if defined (_DEBUG)
       
   350 inline CPppLog& CPppHdlcLink::Logger() const
       
   351 	{
       
   352 	ASSERT(iPppLcp);
       
   353 	ASSERT(iPppLcp->iLogger);
       
   354 	return *(iPppLcp->iLogger);	
       
   355 	}
       
   356 #endif
       
   357 /**
       
   358 Control of the BCA: translates the instructions from the higher level (i.e. HDLC) 
       
   359 into sequences of Control actions on the BCA, and dispatches them. 
       
   360 
       
   361 */
       
   362 NONSHARABLE_CLASS(CBcaControl) : public CActive
       
   363 	{
       
   364 public:
       
   365 	CBcaControl(CPppHdlcLink& aUser, MBca& aBca);
       
   366 	~CBcaControl();
       
   367 
       
   368 	void StartStartupSequence();
       
   369 	void StartShutdownSequence();
       
   370 	inline TBool BcaIsOpen() const;
       
   371 	
       
   372 	// CActive.
       
   373 	void RunL();
       
   374 	void DoCancel();
       
   375 	
       
   376 private: 
       
   377 	
       
   378 	TBool IsShuttingDown() const;
       
   379 	
       
   380 	// N.B.
       
   381 	// The order of these enums reflects the BCA lifecycle, and thus is absolutely critical!
       
   382 	// Later, we'll be doing checks like if iControlStep < EShuttingDown
       
   383 	// New steps must be inserted in an appropriate position. There is no danger of BC
       
   384 	// break, because this enum is local to this class, obviously.
       
   385 	 
       
   386 	/** Current control step on BCA.*/
       
   387 	enum TBcaControlStep
       
   388 		{
       
   389 		/** Not doing anything */
       
   390 		ENone,
       
   391 		
       
   392 		//
       
   393 		// Startup sequence
       
   394 		// 
       
   395 		
       
   396 		/** Pseudo step - starting BCA sequence started */
       
   397 		EStartingStartup,
       
   398 		/** Setting IAP */
       
   399 		ESettingIap,
       
   400 		/** Provisioning the BCA stack */
       
   401 		ESettingBcaStack,		
       
   402 		/** Opening the BCA for use */
       
   403 		EOpeningChannel,
       
   404 		/** Enabling monitoring of serial control lines */
       
   405 		EnablingLinkMonitoring,
       
   406 		/** Getting current serial config */
       
   407 		EGettingSerialConfig,
       
   408 		/** Applying serial config settings appropriate for HDLC */
       
   409 		ESettingSerialConfigForHdlc,
       
   410 		/** Setting BCA internal buffers size */
       
   411 		ESettingBufferSize,
       
   412 		/** Purging the buffers */
       
   413 		EResettingBuffers,
       
   414 		
       
   415 		//
       
   416 		// Shutdown sequence
       
   417 		//		
       
   418 		
       
   419 		/** Pseudo step - starting BCA shutdown sequence */
       
   420 		EStartingShutdown,
       
   421 		/** Returning the Comm port to its original state */
       
   422 		ERestoringOrigSerialConfig,
       
   423 		/** Shutting down the open channel, possibly in a graceful way */
       
   424 		EShuttingDownChannel
       
   425 		};
       
   426 		
       
   427 	/** Our user, the HDLC link */
       
   428 	CPppHdlcLink& iUser;
       
   429 
       
   430 	
       
   431 	/** BCA */ 
       
   432 	MBca& iBca;
       
   433 
       
   434 	/** Control step we are currently executing */
       
   435 	TBcaControlStep iControlStep;
       
   436 	
       
   437 	/** Is the BCA open? I.e. do we have to close it or not? */
       
   438 	TBool iBcaIsOpen;
       
   439 	
       
   440 	/** Storage for retrieved serial port configuration */
       
   441 	TCommConfig iSerialConfig;
       
   442 	};
       
   443 
       
   444 
       
   445 /**
       
   446 Asynchronous BCA reader.
       
   447 
       
   448 */
       
   449 NONSHARABLE_CLASS(CBcaReader) : public CActive
       
   450 	{
       
   451 public:
       
   452 	CBcaReader(CPppHdlcLink& aUser, MBca& aBca, TInt aPriority);
       
   453 	~CBcaReader();
       
   454 
       
   455 	void Read(TDes8& aDes);
       
   456 	void ReadReady();
       
   457 
       
   458 	void RunL();
       
   459 	void DoCancel();	
       
   460 
       
   461 private:
       
   462 	/** Our user - the HDLC link */ 
       
   463 	CPppHdlcLink& iUser;
       
   464 	
       
   465 	/** The BCA  */
       
   466 	MBca& iBca;
       
   467 	};
       
   468 	
       
   469 /**
       
   470 Asynchronus BCA writer.
       
   471 
       
   472 */
       
   473 NONSHARABLE_CLASS(CBcaWriter) : public CActive
       
   474 	{
       
   475 public:
       
   476 	CBcaWriter(CPppHdlcLink& aUser, MBca& aBca, TInt aPriority);
       
   477 	~CBcaWriter();
       
   478 
       
   479 	void Write(const TDesC8& aDes);
       
   480 
       
   481 	void RunL();
       
   482 	void DoCancel();	
       
   483 
       
   484 private: 
       
   485 	
       
   486 	/** Our user - the HDLC link */
       
   487 	CPppHdlcLink& iUser;
       
   488 	/* The BCA */
       
   489 	MBca& iBca;
       
   490 	};
       
   491 	
       
   492 
       
   493 /**
       
   494 Returns True if the BCA has been opened, i.e. if it has to be closed
       
   495 
       
   496 @return ETrue if the BCA has been opened
       
   497 */	
       
   498 inline TBool CBcaControl::BcaIsOpen() const
       
   499 	{
       
   500 	return iBcaIsOpen;
       
   501 	}	
       
   502 
       
   503 #endif