linklayerprotocols/pppnif/SPPP/MSCBCP.CPP
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 #include <in_iface.h>
       
    17 #include "MSCBCPC.H"
       
    18 
       
    19 
       
    20 //
       
    21 
       
    22 
       
    23 /*
       
    24    Exactly one Callback Control Protocol packet is encapsulated
       
    25    in the Information field of a PPP Data Link Layer frame.
       
    26    A summary of the CBCP packet format is shown below.  The
       
    27    fields are transmitted from left to right.
       
    28     0                   1                   2                   3
       
    29     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
    30    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
    31    |     Code      |  Identifier   |            Length             |
       
    32    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
    33    |    Data ...   +-+-+-+-+   Code
       
    34       The Code field is one octet and identifies the type of CBCP
       
    35       packet.  CBCP Codes are assigned as follows:
       
    36 	     1       Callback Request       ( Answerer -> Caller )
       
    37          2       Callback Response      ( Caller   -> Answerer )
       
    38          3       Callback Ack           ( Answerer -> Caller )
       
    39 	Identifier
       
    40       The Identifier field is one octet and aids in matching requests
       
    41       and replies.   Length
       
    42       The Length field is two octets and indicates the length of the
       
    43       CBCP packet including the Code, Identifier, Length and Data
       
    44       fields.  Octets outside the range of the Length field should be
       
    45       treated as Data Link Layer padding and should be ignored on
       
    46       reception.
       
    47 
       
    48 
       
    49   3.2 Callback Configuration Options
       
    50 
       
    51     0                   1                   2
       
    52     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
       
    53    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
    54    | Callback Type |    Length     |Callback delay |
       
    55    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
    56    | Callback Address(es) ...
       
    57    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
       
    58 
       
    59     Callback Type
       
    60 
       
    61     1 - No callback
       
    62     2 - Callback to a user-specifiable number.
       
    63     3 - Callback to a pre-specified or administrator specified number.
       
    64     4 - Callback to any of a list of numbers.
       
    65 
       
    66 
       
    67     Length
       
    68       The Length field is one octet and indicates the length of the
       
    69       Callback Option including the Type, Length and Data fields.
       
    70       >=3
       
    71 
       
    72     Callback delay
       
    73         The amount of time is seconds the Answerer MUST wait before
       
    74         calling the Caller back.  Answerer sets to 0, Caller MAY change if
       
    75         the required value if is different from 0.
       
    76         <= 255
       
    77 
       
    78 
       
    79     Callback Addresses
       
    80 
       
    81     0                   1                   2
       
    82     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
       
    83    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
    84    | Address Type  |    ASCIIZ address
       
    85    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
    86 
       
    87         Address Type
       
    88 
       
    89             1 - for PSTN/ISDN
       
    90 
       
    91             Other? (TBD)
       
    92 
       
    93         Address Format
       
    94 
       
    95             For PSTN/ISDN this is an NULL terminated ASCII string.
       
    96 
       
    97             Valid characters are 0-9, *, #, T, P, W, @, comma, space,
       
    98             dash, and parentheses."
       
    99 
       
   100 
       
   101 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+//-+-----+
       
   102 |  Code | Id  |    Length     |CBckType| Len | delay | 1   | phone number  |  0  |
       
   103 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+//-+-----+
       
   104     0      1     2       3        4       5      6      7     8    ..
       
   105 */
       
   106 
       
   107 
       
   108 const TUint KPppIdNcpMsCbcp = 0xC029;
       
   109 
       
   110 const TUint8 KPppMsCbcpOptRequest  = 1;	// Callback Request  ( Answerer -> Caller )
       
   111 const TUint8 KPppMsCbcpOptResponse = 2;	// Callback Response ( Caller   -> Answerer )
       
   112 const TUint8 KPppMsCbcpOptAck     = 3;	// Callback Ack      ( Answerer -> Caller )
       
   113 
       
   114 enum TMsCbcpCallbackOptType
       
   115 		{
       
   116 		EMsCbcpCallbackOptTypeNoCallback = 1,
       
   117 		EMsCbcpCallbackOptTypeUserSpecified = 2,
       
   118 		EMsCbcpCallbackOptTypeServerSpecified = 3,
       
   119 		EMsCbcpCallbackOptTypeList = 4
       
   120 		};
       
   121 
       
   122 #define PKT_BUF_SIZE			256
       
   123 #define RESPONSE_BUF_SIZE		PKT_BUF_SIZE
       
   124 #define KCbcpMaxRequestLength	256	// maximum length allowed for an incoming MsCbcpOptRequest pkt
       
   125 
       
   126 /**
       
   127 'MS CBCP-client' class (a client is the machine that dials out to request callback)
       
   128 @internalComponent
       
   129 */
       
   130 NONSHARABLE_CLASS(CPppMsCbcpClient) : public CBase, public MPppRecvr
       
   131 	{
       
   132 	friend class PppNcpMsCbcpFactory;
       
   133 public:
       
   134 	CPppMsCbcpClient(	CPppLcp * aLcp,
       
   135 						TMSCBCPAction aAction,
       
   136 						const TUint8 * aCallbackInfo,
       
   137 						const TInt aCallbackInfoLen );
       
   138 	~CPppMsCbcpClient();
       
   139 	void ConstructL();
       
   140 private:
       
   141 	// from MPppRecvr: upcalls
       
   142 	virtual TBool RecvFrame(RMBufChain& aPacket);		// from MPppRecvr
       
   143 	virtual void LowerLayerUp();						// from MPppRecvr
       
   144 	virtual void LowerLayerDown(TInt aStatus);			// from MPppRecvr
       
   145 	virtual void KillProtocol();
       
   146 	virtual void FrameError();
       
   147 
       
   148 private:
       
   149 	INLINE void ValidateArgumentsL() const;
       
   150 	INLINE void HandleRXOfferFromServer(const TUint8 * aPacket, TInt aLen );
       
   151 	INLINE TBool GenerateResponseToServersOffer(	TBool&		aServerOfferAcceptable,
       
   152 									TUint8 *		aResponse,
       
   153 									TInt&			aResponseLen,
       
   154 									const TUint8 *	aOfferPktFromServer,	// recvd packet
       
   155 									TInt			aOfferPktFromServerLen);
       
   156 	INLINE void ProcessRecvdFrame(const TUint8 * aPacket, TInt aLen );
       
   157 	INLINE void SendResponse(const TUint8 * aResponse, TInt aResponseLen );
       
   158 	INLINE TBool IsCallbackOfferAcceptable( TMsCbcpCallbackOptType aRecvdCallbackType ) const;
       
   159 	INLINE TBool AcceptServerSpecifiedNumber() const;
       
   160 	INLINE TInt GetCallbackResponsePhoneNumber(
       
   161 											TUint8 *				aResultPhoneNumber,	// output
       
   162 											TMsCbcpCallbackOptType	aRecvdCallbackType ) const;
       
   163 	INLINE void RecvdAck();
       
   164 	INLINE TInt GetClientPhoneNumber( TUint8 * aResultPhoneNumber ) const;
       
   165 private:
       
   166 	CPppLcp * const			iLcp;
       
   167 	TBool					iServerOfferAcceptable;	// True if the server has made an acceptable offer of callback to use
       
   168 	const TMSCBCPAction		iAction;
       
   169 	const TUint8 * const	iCallbackInfo;
       
   170 	const TInt				iCallbackInfoLen;
       
   171 	TInt					iResponseLen;
       
   172 	TUint8					iResponseBuf[ RESPONSE_BUF_SIZE ];
       
   173 	TBool					iDead;
       
   174 	};
       
   175 
       
   176 #define LOG1( p1 )				LOG( Log::Printf(_L(p1) ) )
       
   177 #define LOG2( p1, p2 )			LOG( Log::Printf(_L(p1), (p2) ) )
       
   178 #define LOG3( p1, p2, p3 )		LOG( Log::Printf(_L(p1), (p2), (p3) ) )
       
   179 #define LOG4( p1, p2, p3, p4 )	LOG( Log::Printf(_L(p1), (p2), (p3), (p4) ) )
       
   180 
       
   181 
       
   182 
       
   183 CPppMsCbcpClient * PppNcpMsCbcpFactory::NewL(	CPppLcp * aLcp,
       
   184 												TMSCBCPAction aAction,
       
   185 												const TUint8 * aCallbackInfo,
       
   186 												const TInt aCallbackInfoLen )
       
   187 	{
       
   188 	CPppMsCbcpClient * p;
       
   189 
       
   190 	p = new (ELeave) CPppMsCbcpClient(aLcp, aAction, aCallbackInfo, aCallbackInfoLen );
       
   191 	CleanupStack::PushL( p );
       
   192 	p->ConstructL();
       
   193 	CleanupStack::Pop();
       
   194 	return p;
       
   195 	}
       
   196 
       
   197 void PppNcpMsCbcpFactory::Delete( CPppMsCbcpClient * instance)
       
   198 	{
       
   199 	delete instance;
       
   200 	}
       
   201 
       
   202 CPppMsCbcpClient::CPppMsCbcpClient(	CPppLcp *		aLcp,
       
   203 									TMSCBCPAction	aAction,
       
   204 									const TUint8 *	aCallbackInfo,
       
   205 									const TInt		aCallbackInfoLen )
       
   206 	:	MPppRecvr(aLcp, EPppPhaseLateCallback, KPppIdNcpMsCbcp ),
       
   207 		iLcp( aLcp ),
       
   208 		iServerOfferAcceptable( EFalse ),
       
   209 		iAction( aAction ),
       
   210 		iCallbackInfo( aCallbackInfo ),
       
   211 		iCallbackInfoLen( aCallbackInfo ? aCallbackInfoLen : 0 ),
       
   212 		iDead( EFalse )
       
   213 	{
       
   214 	__ASSERT_DEBUG( iCallbackInfoLen >=0, PppPanic(EPppPanic_PPPNoCallbackInfo) );
       
   215 	__ASSERT_DEBUG( iLcp, PppPanic(EPppPanic_PPPLcpRequired) );
       
   216 	}
       
   217 
       
   218 CPppMsCbcpClient::~CPppMsCbcpClient()
       
   219 	{
       
   220 	}
       
   221 
       
   222 void CPppMsCbcpClient::ConstructL()
       
   223 	{
       
   224 	ValidateArgumentsL();
       
   225 	Register();
       
   226 	}
       
   227 
       
   228 //
       
   229 // CRC Error for a frame deliverred to this protocol
       
   230 // No use to this module
       
   231 //
       
   232 void CPppMsCbcpClient::FrameError()
       
   233 	{
       
   234 	}
       
   235 
       
   236 //
       
   237 // Someone rejected this we should not receive any more 
       
   238 // frames on it.
       
   239 //
       
   240 void CPppMsCbcpClient::KillProtocol()
       
   241 	{
       
   242 	iDead = ETrue;
       
   243 	}
       
   244 
       
   245 void CPppMsCbcpClient::ValidateArgumentsL() const
       
   246 	{
       
   247 	if (RESPONSE_BUF_SIZE < (8+1+iCallbackInfoLen))
       
   248 		{
       
   249 		User::Leave(KErrArgument);
       
   250 		}
       
   251 	}
       
   252 
       
   253 void CPppMsCbcpClient::LowerLayerUp()
       
   254 	{
       
   255 	// TBS
       
   256 	}
       
   257 
       
   258 void CPppMsCbcpClient::LowerLayerDown(TInt /*aStatus*/)
       
   259 	{
       
   260 	}
       
   261 
       
   262 
       
   263 TBool CPppMsCbcpClient::RecvFrame(RMBufChain& aPacket)
       
   264 	{
       
   265 	RMBufPacket pkt;
       
   266 	pkt.Assign(aPacket);
       
   267 	pkt.Unpack();
       
   268 
       
   269 	if (iDead)
       
   270 		{
       
   271 		// Link dead
       
   272 		pkt.Free();
       
   273 		return EFalse;
       
   274 		}
       
   275 
       
   276 	const TUint rmbuflen = pkt.Info()->iLength;
       
   277 
       
   278 	// Extract and drop LCP header
       
   279 	pkt.Align(4);
       
   280 	const TUint8 * ptr = pkt.First()->Ptr();
       
   281 
       
   282 	TUint len = BigEndian::Get16( ptr+2 );
       
   283 	
       
   284 	// Check packet length is OK
       
   285 	if (rmbuflen < len)
       
   286 		{
       
   287 		// Too short!
       
   288 		pkt.Free();
       
   289 		return EFalse;
       
   290 		}
       
   291 	ProcessRecvdFrame( ptr, len );
       
   292 	pkt.Free();
       
   293 	return EFalse;
       
   294 	}
       
   295 
       
   296 void CPppMsCbcpClient::HandleRXOfferFromServer(const TUint8 * aPacket, TInt aLen )
       
   297 	{
       
   298 	if (! GenerateResponseToServersOffer(	iServerOfferAcceptable,
       
   299 									iResponseBuf,
       
   300 									iResponseLen,
       
   301 									aPacket,
       
   302 									aLen))
       
   303 		{
       
   304 		// if invalid or unacceptable, take it all down
       
   305 		iPppLcp->TerminateLink(MNifIfNotify::EDisconnect, KErrIfCallbackNotAcceptable);	// all done, shut it all down
       
   306 		return;	
       
   307 		}
       
   308 
       
   309 	SendResponse( iResponseBuf, iResponseLen );
       
   310 	}
       
   311 
       
   312 
       
   313 void CPppMsCbcpClient::RecvdAck()
       
   314 	{
       
   315 
       
   316 	iLcp->CallbackGrantedAndAuthenticated();
       
   317 	iPppLcp->TerminateLink(MNifIfNotify::ECallBack);	// all done, shut it all down
       
   318 	}
       
   319 
       
   320 
       
   321 void CPppMsCbcpClient::SendResponse(const TUint8 * aResponsePkt, TInt aResponsePktLen )
       
   322 	{
       
   323 	RMBufPacket pkt;
       
   324 	RMBufPktInfo* info = NULL;
       
   325 	const TInt len = aResponsePktLen;
       
   326 
       
   327 	TRAPD(err, pkt.AllocL(len));
       
   328 	if (err!=KErrNone)
       
   329 		return;
       
   330 
       
   331 	TRAP(err, info = pkt.NewInfoL());
       
   332 	if (err!=KErrNone)
       
   333 		{
       
   334 		pkt.Free();
       
   335 		return;
       
   336 		}
       
   337 	TUint8 * const ptr = pkt.First()->Ptr();
       
   338 	Mem::Copy( ptr, aResponsePkt, aResponsePktLen );
       
   339 	info->iLength = len;	
       
   340 	TPppAddr::Cast((info->iDstAddr)).SetProtocol(iPppId);
       
   341 	pkt.Pack();
       
   342 	SendFrame(pkt);
       
   343 	}
       
   344 
       
   345 const TInt KMsCbcpCallbackDelay = 2;	// callback delay in seconds suggested to server
       
   346 
       
   347 TBool CPppMsCbcpClient::IsCallbackOfferAcceptable( TMsCbcpCallbackOptType aRecvdCallbackType ) const
       
   348 // Return TRUE if the servers offer of callback is acceptable
       
   349 	{
       
   350 	switch ( aRecvdCallbackType )
       
   351 		{
       
   352 	case EMsCbcpCallbackOptTypeNoCallback:	// 1
       
   353 		return EFalse;
       
   354 	case EMsCbcpCallbackOptTypeUserSpecified:	// 2
       
   355 		return ETrue;
       
   356 	case EMsCbcpCallbackOptTypeServerSpecified:	// 3
       
   357 		return AcceptServerSpecifiedNumber();
       
   358 	case EMsCbcpCallbackOptTypeList: // 4
       
   359 		return EFalse;
       
   360 	default:
       
   361 		return EFalse;	// recvd a bad garbage thing
       
   362 		}
       
   363 	}
       
   364 
       
   365 INLINE TBool CPppMsCbcpClient::AcceptServerSpecifiedNumber() const
       
   366 // Returns true if we are willing to accept a phone number specified by the server, rather than one we've specified ourselves.
       
   367 	{
       
   368 	return iAction != EMSCBCPActionRequireClientSpecifiedNumber;
       
   369 	}
       
   370 
       
   371 
       
   372 
       
   373 INLINE TInt ResponseLength( TMsCbcpCallbackOptType responseCallbackType, TInt responsePhoneNumberLen, TInt aRequestFromSrvLen )
       
   374 // Return the total length of a response packet of type 'responseCallbackType'
       
   375 // including a phone number of length responsePhoneNumberLen, if applicable
       
   376 // Note: responsePhoneNumberLen does NOT include any trailing zero on the phone number
       
   377 	{
       
   378 	switch ( responseCallbackType )
       
   379 		{
       
   380 	case EMsCbcpCallbackOptTypeUserSpecified:
       
   381 		return (8 + 1 + responsePhoneNumberLen);	// +1 for zt
       
   382 	case EMsCbcpCallbackOptTypeServerSpecified:
       
   383 		return aRequestFromSrvLen+3;
       
   384 	default:
       
   385 		return 0;				
       
   386 		}
       
   387 	}
       
   388 
       
   389 TBool CPppMsCbcpClient::GenerateResponseToServersOffer(	TBool&			aServerOfferAcceptable,	// out
       
   390 												TUint8 *		aResponse,				// out: resulting response packet
       
   391 												TInt&			aResponseLen,			// out: len of above
       
   392 												const TUint8 *	aOfferPktFromServer,			// recvd packet
       
   393 												TInt			aOfferPktFromServerLen)
       
   394 // Analyses the given received recvd MsCbcpOptRequest packet 'aOfferPktFromServer'
       
   395 // If it is valid,
       
   396 //		writes an appropriate response packet at aResponse, aResponseLen
       
   397 // Sets caller's aServerOfferAcceptable true/false according to whether the server's offer of callback is acceptable
       
   398 // Returns True if the recvd MsCbcpOptRequest packet is valid and acceptable
       
   399 // Returns False if its corrupt or unacceptable, in which case we must terminate the link
       
   400 	{
       
   401 
       
   402 	if ( aOfferPktFromServerLen > KCbcpMaxRequestLength )
       
   403 		return EFalse;
       
   404 	if ( aOfferPktFromServerLen <= 4 )
       
   405 		return EFalse;
       
   406 
       
   407 	//
       
   408 	// We can receive multiple options in that case we have to decide which 
       
   409 	// to use. Specifically in the case off a user specified number to be called
       
   410 	// back on the options are:
       
   411 	// 1. No Callback and
       
   412 	// 2. Caller specifies the number
       
   413 	// PRR 8/4/98
       
   414 	//
       
   415 	TInt	lengthProcessed=4; // Used to keep track when we're offerred multiple options
       
   416 	TBool	callbackok = EFalse;
       
   417 	TInt	responsePhoneNumberLen;
       
   418 	TMsCbcpCallbackOptType recvdCallbackType;
       
   419 
       
   420 	do
       
   421 		{
       
   422 		recvdCallbackType = TMsCbcpCallbackOptType( aOfferPktFromServer[lengthProcessed] );
       
   423 
       
   424 		//
       
   425 		// If someone offers us No Call back then we try to match any other option 
       
   426 		// they may send, but we have this as a default to go back to.
       
   427 		callbackok = IsCallbackOfferAcceptable( recvdCallbackType );
       
   428 
       
   429 		if (callbackok)
       
   430 			{
       
   431 			break;
       
   432 			}
       
   433 
       
   434 		lengthProcessed += aOfferPktFromServer[lengthProcessed+1];
       
   435 		} while ( lengthProcessed < aOfferPktFromServerLen );
       
   436 
       
   437 	if (!callbackok)
       
   438 		{
       
   439 		return EFalse;	// cannot agree
       
   440 		}
       
   441 
       
   442 	TMsCbcpCallbackOptType responseCallbackType = recvdCallbackType;
       
   443 
       
   444 	responsePhoneNumberLen = GetCallbackResponsePhoneNumber(	aResponse+8,	// result phone number
       
   445 																recvdCallbackType );
       
   446 
       
   447 
       
   448 	*(aResponse+8 + responsePhoneNumberLen) = 0;	// zero-terminate it
       
   449 
       
   450 	TInt responselen = ResponseLength( responseCallbackType, responsePhoneNumberLen, aOfferPktFromServerLen-lengthProcessed );
       
   451 
       
   452 	aResponse[0] = KPppMsCbcpOptResponse;
       
   453 	aResponse[1] = aOfferPktFromServer[1];		// id
       
   454 	BigEndian::Put16( aResponse+2, TUint16(responselen) );
       
   455 	aResponse[4] = TUint8(responseCallbackType);
       
   456 	aResponse[5] = TUint8( responselen - 4 ); 
       
   457 	if (recvdCallbackType == EMsCbcpCallbackOptTypeUserSpecified)
       
   458 		{
       
   459 		aResponse[6] = KMsCbcpCallbackDelay;
       
   460 		}
       
   461 	else
       
   462 		{
       
   463 		aResponse[6] = aOfferPktFromServer[6+lengthProcessed];
       
   464 		}
       
   465 	aResponse[7] = 1;	// PSTN Address type
       
   466 
       
   467 	aResponseLen = responselen;				// return result
       
   468 	aServerOfferAcceptable = callbackok;	// return result
       
   469 	return ETrue;
       
   470 	}
       
   471 
       
   472 TInt CPppMsCbcpClient::GetClientPhoneNumber( TUint8 * aResultPhoneNumber ) const
       
   473 	{
       
   474 	Mem::Copy( aResultPhoneNumber, iCallbackInfo, iCallbackInfoLen );
       
   475 	return iCallbackInfoLen;
       
   476 	}
       
   477 
       
   478 TInt CPppMsCbcpClient::GetCallbackResponsePhoneNumber(
       
   479 											TUint8 *				aResultPhoneNumber,	// output
       
   480 											TMsCbcpCallbackOptType	aRecvdCallbackType ) const
       
   481 // Works out what the phone number should be in our response packet - our response to the server's offer
       
   482 // Outputs:
       
   483 //	Writes the phone number at aResultPhoneNumber
       
   484 //	Returns the length of the result
       
   485 //
       
   486 // Given the received
       
   487 	{
       
   488 	switch ( aRecvdCallbackType )
       
   489 		{
       
   490 	case EMsCbcpCallbackOptTypeUserSpecified: //= 2,
       
   491 		return GetClientPhoneNumber( aResultPhoneNumber );
       
   492 	case EMsCbcpCallbackOptTypeServerSpecified: //= 3,
       
   493 		return 0; // We have no say over the phone number, we do as we're bid PRR
       
   494 	default:		
       
   495         __ASSERT_DEBUG( EFalse, PppPanic(EPppPanic_PPPInvalidCallback) );
       
   496 		}
       
   497 	return 0;
       
   498 	}
       
   499 
       
   500 
       
   501 void CPppMsCbcpClient::ProcessRecvdFrame(const TUint8 * aPacket, TInt aLen )
       
   502 	{
       
   503 	TUint op = aPacket[0];
       
   504 
       
   505 	TInt len = BigEndian::Get16( aPacket + 2);
       
   506 	if ( len <=4 || len > aLen )
       
   507 		return;
       
   508 
       
   509 	switch (op)
       
   510 		{
       
   511 	case KPppMsCbcpOptRequest:
       
   512 		HandleRXOfferFromServer( aPacket, len );
       
   513 		break;
       
   514 	case KPppMsCbcpOptAck:
       
   515 		RecvdAck();
       
   516 		break;
       
   517 	default:
       
   518 		break;
       
   519 		}
       
   520 	}
       
   521