telephonyprotocols/gprsumtsqosprt/src/async_request.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2007-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 "iface.h"
       
    17 #include "context.h"
       
    18 #include "tc.h"
       
    19 #include <networking/qoserr.h>
       
    20 #include "guqos_err.h"
       
    21 #include "async_request.h"
       
    22 #include "guqos_log.h"
       
    23 
       
    24 
       
    25 
       
    26 // Open Channel Machine
       
    27 const SActionStep<COpenChannel> COpenChannel::iActionList[] =
       
    28 	{
       
    29 		&COpenChannel::ActionRemovePacketFilter,	// iState=0
       
    30 		&COpenChannel::ActionCommit,				// iState=1
       
    31 		&COpenChannel::ActionNewContext,			// iState=2
       
    32 		&COpenChannel::DoRememberCreatedContext,	// iState=3
       
    33 		&COpenChannel::ActionAddPacketFilter,		// iState=4
       
    34 		&COpenChannel::ActionAddSblpParameter,		// iState=5 == KStateReuseOldContext!
       
    35 		&COpenChannel::ActionSetQoS,
       
    36 		&COpenChannel::ActionCommit,
       
    37 		&COpenChannel::DoAddFlowToContext,
       
    38 		&COpenChannel::ActionNegotiationComplete
       
    39 	};
       
    40 const TInt KStateReuseOldContext = 5;	// *KEEP THIS IN SYNCH WITH ABOVE!*
       
    41 
       
    42 
       
    43 
       
    44 // Negotiate Channel Machine
       
    45 const SActionStep<CNegotiateChannel> CNegotiateChannel::iActionList[] =
       
    46 	{
       
    47 		&CNegotiateChannel::ActionAddSblpParameter,
       
    48 		&CNegotiateChannel::ActionSetQoS,
       
    49 		&CNegotiateChannel::ActionCommit,
       
    50 		&CNegotiateChannel::ActionNegotiationComplete,
       
    51 	};
       
    52 
       
    53 // Join Channel Machine
       
    54 const SActionStep<CJoinRequest> CJoinRequest::iActionList[] =
       
    55 	{
       
    56 		&CJoinRequest::ActionRemovePacketFilter,
       
    57 		&CJoinRequest::ActionCommit,
       
    58 		&CJoinRequest::DoStartWithTargetContext,
       
    59 		&CJoinRequest::ActionAddPacketFilter,
       
    60 		&CJoinRequest::DoAddFlowToContext,
       
    61 		&CJoinRequest::ActionRemovePacketFilter,	// Cleanup extra filters away, if present
       
    62 		&CJoinRequest::ActionCommit,
       
    63 		&CJoinRequest::ActionRequestComplete
       
    64 	};
       
    65 
       
    66 // Leave Channel Machine
       
    67 const SActionStep<CLeaveRequest> CLeaveRequest::iActionList[] =
       
    68 	{
       
    69 		&CLeaveRequest::ActionRemovePacketFilter,
       
    70 		&CLeaveRequest::ActionCommit,
       
    71 		&CLeaveRequest::ActionRequestComplete
       
    72 	};
       
    73 
       
    74 // Update Channel Machine (misnamed as "Close")
       
    75 const SActionStep<CClose> CClose::iActionList[] =
       
    76 	{
       
    77 		&CClose::ActionRemovePacketFilter,
       
    78 		&CClose::ActionCommit,
       
    79 		&CClose::ActionRequestComplete
       
    80 	};
       
    81 
       
    82 
       
    83 #ifdef _LOG
       
    84 //
       
    85 // Logging help classes
       
    86 //
       
    87 
       
    88 class TLogContextInfo : public TBuf<100>
       
    89 	{
       
    90 public:
       
    91 	TLogContextInfo(const CPdpContext* aContext);	
       
    92 	};
       
    93 
       
    94 TLogContextInfo::TLogContextInfo(const CPdpContext* aContext)
       
    95 	{
       
    96 	if (aContext)
       
    97 		{
       
    98 		Format(_L("context[%u] id=%d"), (TInt)aContext, aContext->ContextId()); // + 32
       
    99 		switch (aContext->ContextType())
       
   100 			{
       
   101 			case EPrimaryContext:	Append(_L(" primary")); break;
       
   102 			case ESecondaryContext:	Append(_L(" secondary")); break;			// + 10
       
   103 			case ENetworkInitiatedContext: Append(_L(" network")); break;
       
   104 			default: Append(_L(" unknown")); break;
       
   105 			}
       
   106 		switch (aContext->ContextStatus())
       
   107 			{
       
   108 			case RPacketContext::EStatusInactive: Append(_L(" inactive")); break;
       
   109 			case RPacketContext::EStatusActivating: Append(_L(" activating")); break;
       
   110 			case RPacketContext::EStatusActive: Append(_L(" active")); break;
       
   111 			case RPacketContext::EStatusDeactivating: Append(_L(" deactivating")); break;		// + 12
       
   112 			case RPacketContext::EStatusSuspended: Append(_L(" suspended")); break;
       
   113 			case RPacketContext::EStatusDeleted: Append(_L(" deleted")); break;
       
   114 			default: Append(_L(" unknown")); break;			
       
   115 			}
       
   116 		AppendFormat(_L("(%d)"), (TInt)aContext->ContextStatus());				// + 4
       
   117 
       
   118 		if (aContext->ChannelId())
       
   119 			{
       
   120 			AppendFormat(_L(" channel=%d"), aContext->ChannelId());				// + 18
       
   121 			}
       
   122 		AppendFormat(_L(", %d flows"), aContext->RefCount());					// + 11;
       
   123 		}
       
   124 	else
       
   125 		{
       
   126 		Append(_L("context NONE"));
       
   127 		}
       
   128 	}
       
   129 
       
   130 #endif
       
   131 
       
   132 
       
   133 CRequestBase::CRequestBase(CNif& aNif) : iNif(aNif)
       
   134 	{
       
   135 #ifdef _LOG
       
   136 	// This is only fallback, and should be overriden by the
       
   137 	//  derived classes!
       
   138 	_LIT(KLogName, "Base");
       
   139 	iName = &KLogName();
       
   140 #endif
       
   141 	}
       
   142 
       
   143 CRequestBase::~CRequestBase()
       
   144 	{
       
   145 	LOG(Log::Printf(_L("~\trequest %S[%u] destructed"), iName, (TInt)this));
       
   146 	}
       
   147 
       
   148 void CRequestBase::SetContext(CPdpContext *aContext)
       
   149 	/**
       
   150 	* Set/clear the current context for the state machine.
       
   151 	*/
       
   152 	{
       
   153 	LOG(TLogContextInfo info(aContext));
       
   154 	LOG(Log::Printf(_L("\trequest %S[%u] -- %S set"), iName, (TInt)this, &info));
       
   155 	if (iContext != aContext)
       
   156 		{
       
   157 		iContext = aContext;
       
   158 		// Context has been changed, need to clear modified flag.
       
   159 		iContextModified = EFalse;	
       
   160 		}
       
   161 	iParams = NULL;	// Paremeters can only come from NIF event.
       
   162 	}
       
   163 
       
   164 void CRequestBase::SetExpected(const TRequest aRequest)
       
   165 	{
       
   166 	/**
       
   167 	* Define the expected result of the next asynchronous operation.
       
   168 	*/
       
   169 	iExpected = aRequest;
       
   170 	// Assume that SetExpected is only used when a request to NIF
       
   171 	// has been passed. Thus, any call to SetExpected implies that
       
   172 	// the context will be modified by NIF.
       
   173 	iContextModified = ETrue;
       
   174 	}
       
   175 	
       
   176 	
       
   177 static TBool CheckSblpErrorInPcoBuffer(const TContextParameters& aParams, TUint8& parsedSblpErrorValue)
       
   178 	{
       
   179 	TBool retValue = EFalse;
       
   180 	TInt ret = KErrNone;
       
   181 	
       
   182 	// create the PCO id for rejection code
       
   183 	RPacketContext::TPcoId sblpRejectionCodePcoId(
       
   184 				RPacketContext::EEtelPcktPolicyControlRejectionCode); 
       
   185 	/*
       
   186 	 *  get the value of the RPacketContext::TContextConfigGPRS 
       
   187 	 *  object from the TContextParameters object passed by the nif
       
   188 	 */
       
   189 	RPacketContext::TContextConfigGPRS configGPRS;
       
   190 	aParams.iContextConfig.GetContextConfig(configGPRS);
       
   191 
       
   192 	// adjust the PCO buffer 
       
   193 	TPtr8 pcoBufferPtr(const_cast<TUint8*>
       
   194 				(configGPRS.iProtocolConfigOption.iMiscBuffer.Ptr()),
       
   195 				configGPRS.iProtocolConfigOption.iMiscBuffer.Length(),
       
   196 				configGPRS.iProtocolConfigOption.iMiscBuffer.Length()); 
       
   197 
       
   198 	// attach TTlv  to the buffer 
       
   199 	TTlvStruct<RPacketContext::TPcoId,RPacketContext::TPcoItemDataLength> 
       
   200 												pcoTLV(pcoBufferPtr,pcoBufferPtr.Length());		 
       
   201 	
       
   202 	// Retreive the sblp rejection code value from the buffer
       
   203 	TBuf8<253> sblpRejectionCodeBuf; 
       
   204 	sblpRejectionCodeBuf.SetLength(pcoBufferPtr.Length());		 
       
   205 	TPtr8 sblpRejectionCodePtr(const_cast<TUint8*>(sblpRejectionCodeBuf.Ptr()),
       
   206 						sblpRejectionCodeBuf.Length(),sblpRejectionCodeBuf.MaxLength()); 
       
   207 	
       
   208 	pcoTLV.ResetCursorPos(); 
       
   209 	TRAPD(err1, ret=pcoTLV.NextItemL(sblpRejectionCodePcoId,sblpRejectionCodePtr) ); 
       
   210 	if (err1 !=KErrNone || ret!=KErrNone)
       
   211 		{
       
   212 		return EFalse;
       
   213 		}
       
   214 
       
   215 	// sblpRejectionCodeBuf[0] shall contain SBLP Rejection code ( values 1-7)) 
       
   216 	parsedSblpErrorValue = sblpRejectionCodePtr[0];
       
   217 	if(parsedSblpErrorValue >= ESblpSubErrorValueMinimum && 
       
   218 		parsedSblpErrorValue <= ESblpSubErrorValueMaximum)
       
   219 		{
       
   220 		retValue = ETrue;
       
   221 		}
       
   222 	return retValue;
       
   223 	}
       
   224 
       
   225 
       
   226 void CRequestBase::Run(const TRequest aRequest, CPdpContext* aContext, const TContextParameters& aParams)
       
   227 	{
       
   228 	LOG(const TDesC* const name(iName)); // because request can get destroyed from under us, save the name here!
       
   229 	LOG(TLogContextInfo info(aContext));
       
   230 	LOG(Log::Printf(_L("Run\trequest %S[%u] Actions on event=%d reason=%d expected event=%d on %S"),
       
   231 		name, (TInt)this, (TInt)aRequest, aParams.iReasonCode, (TInt)iExpected, &info));
       
   232 
       
   233 	iContext = aContext;
       
   234 	iParams = &aParams;
       
   235 
       
   236 	if (iExpected != aRequest && iExpected != EPendingAny)
       
   237 		{
       
   238 		CompleteAndDestruct(KErrCancel, NULL);
       
   239 		}
       
   240 	else if (aParams.iReasonCode == KErrNone)
       
   241 		{
       
   242 		// Reset to accepting any, actions must use SetExpected,
       
   243 		// when they activate asynchronous operation with
       
   244 		// a specific responce.
       
   245 		iExpected = EPendingAny;
       
   246 		do
       
   247 			{
       
   248 			++iState;	// Last state done OK, try next one.
       
   249 			}
       
   250 		while (!Action(iContext, iParams));
       
   251 		// Note: there is no special terminating test, it is excepted that
       
   252 		// the builder of action list guarantees that it always ends with
       
   253 		// action which unconditionally returns ETrue.
       
   254 		}
       
   255 	else
       
   256 		{
       
   257 		// The expected request has failed.
       
   258 		TInt reason = aParams.iReasonCode;
       
   259 
       
   260 		iExtension.SetUmtsType();
       
   261 
       
   262 		/*
       
   263 		 *  if there is KErrGprsUserAuthenticationFailure error code returned by 
       
   264 		 *  the etel via nif, then we must check for the possible specific sblp 
       
   265 		 *  errors in the Protocol Configuration Option PCO buffer.
       
   266 		 *  
       
   267 		 *  If the buffer has a value for the 
       
   268 		 *  TPcoIDNetworkToMS::EEtelPcktPolicyControlRejectionCode id, then we can
       
   269 		 *  decide that sblp specific error has been occured if one of the the 
       
   270 		 *  possible sub error codes (totally six!) matches.
       
   271 		 */
       
   272 		
       
   273 		if (reason == KErrGprsUserAuthenticationFailure)
       
   274 			{
       
   275 			TUint8 parsedSblpErrorValue = KErrNone;
       
   276 			/*
       
   277 			 *  check if PCO buffer has sblp rejection code error value
       
   278 			 *  calling CheckSblpErrorInPcoBuffer() returns true only
       
   279 			 *  if there is error in the buffer and if the error range 
       
   280 			 *  is between (1-7)
       
   281 			 */
       
   282 			if (CheckSblpErrorInPcoBuffer(aParams,parsedSblpErrorValue))
       
   283 				{
       
   284 				/*
       
   285 				 *  it is definitely a sblp error
       
   286 				 *  Set the sblp error flag
       
   287 				 */
       
   288 		 		iExtension.SetSblpType();
       
   289 
       
   290 				// figure out the sub error type
       
   291 				switch (parsedSblpErrorValue)
       
   292 					{
       
   293 				case 1:
       
   294 					// Use the sblp error code to create Failure()
       
   295 					reason = EGuqosSblpAuthorizationFailureOfRequest;
       
   296 					break;
       
   297 				case 2:
       
   298 					reason = EGuqosSblpMissingBindingInfo;
       
   299 					break;
       
   300 				case 3:
       
   301 					reason = EGuqosSblpInvalidBindingInfo;
       
   302 					break;
       
   303 				case 4:
       
   304 					reason = EGuqosSblpBindingInfoNotAllowed;
       
   305 					break;
       
   306 				case 5:
       
   307 					reason = EGuqosSblpAuthorizingEntityTemporarilyUnavailable;
       
   308 					break;
       
   309 				case 6:
       
   310 					reason = EGuqosSblpNoCorrespondingSession;
       
   311 					break;
       
   312 				case 7:
       
   313 					reason = EGuqosSblpInvalidBundling;
       
   314 					break;
       
   315 				default:
       
   316 					/*
       
   317 					 *  it will never reach here!
       
   318 					 *  because the range checking is already done in
       
   319 					 *  CheckSblpErrorInPcoBuffer(aParams,parsedSblpErrorValue) 
       
   320 					 */
       
   321 					LOG(Log::Printf(_L("\trequest%S[%u] SBLP error value range fault!"), name, (TInt)this));
       
   322 					break;
       
   323 					}
       
   324 				}
       
   325 			}
       
   326 		// Deliver failure to the actual request implementation.
       
   327 		Failure(aContext, reason);
       
   328 		}
       
   329 	LOG(Log::Printf(_L("\trequest %S[%u] Run Actions Exit"), name, (TInt)this));
       
   330 	}
       
   331 
       
   332 
       
   333 void CRequestBase::Start()
       
   334 	{
       
   335 	LOG(const TDesC* const name(iName)); // because request can get destroyed from under us, save the name here!
       
   336 	LOG(TLogContextInfo info(iContext));
       
   337 	LOG(Log::Printf(_L("\trequest %S[%u] Start Actions with %S"), name, (TInt)this, &info));
       
   338 	// Rely on C-class 0-fill. Initially all state variables
       
   339 	// are zero, e.g.
       
   340 	//   iContext = NULL;
       
   341 	//   iParams = NULL;
       
   342 	//   iExpected = EPendingAny;
       
   343 	//   iState = 0
       
   344 	// This start does not touch those values and allows derived
       
   345 	// class to override this function with something that may initialize
       
   346 	// state, before calling the base implementation of the Start.
       
   347 
       
   348 	// Excecute actions until something catches or request terminates.
       
   349 	while (!Action(iContext, iParams))
       
   350 		{
       
   351 		++iState;
       
   352 		}
       
   353 	// Note: there is no special terminating test, it is excepted that
       
   354 	// the builder of action list guarantees that it always ends with
       
   355 	// action which unconditionally returns ETrue.
       
   356 	LOG(Log::Printf(_L("\trequest %S[%u] Start Actions Exit"), name, (TInt)this));
       
   357 	}
       
   358 
       
   359 void CRequestBase::CompleteAndDestruct(TInt aErrorCode, const TQoSParameters* aParams, const TExtensionData& aExtension)
       
   360 	{
       
   361 	LOG(Log::Printf(_L("\trequest %S[%u] CompleteAndDestruct ErrorCode=%d"), iName, (TInt)this, aErrorCode));
       
   362 	// Remove all references to this request...
       
   363 	iNif.CloseRequest(this);
       
   364 	// ...before delivering the completion. The delivery may call
       
   365 	// back, and this request must be totally removed by then, or
       
   366 	// bad things can happen (like, duplicate delete).
       
   367 	if (iNotify)
       
   368 		iNotify->RequestComplete(aErrorCode, aParams, aExtension);
       
   369 	delete this;
       
   370 	}
       
   371 
       
   372 
       
   373 TBool CRequestBase::IsOk(TInt aResult, CPdpContext *aContext)
       
   374 	{
       
   375 	if (aResult >= 0)
       
   376 		return ETrue;
       
   377 	LOG(TLogContextInfo info(aContext));
       
   378 	LOG(Log::Printf(_L("\trequest %S[%u] IsOk(%d) is not OK %S"), iName, (TInt)this, aResult, &info));
       
   379 	Failure(aContext, aResult);
       
   380 	return EFalse;
       
   381 	}
       
   382 
       
   383 TBool CRequestBase::ActionRemovePacketFilter(CPdpContext* aContext, const TContextParameters*)
       
   384 	/**
       
   385 	* Activate leaving flow from a context.
       
   386 	*/
       
   387 	{
       
   388 	LOG(TLogContextInfo info(aContext));
       
   389 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionRemovePacketFilter from %S"), iName, (TInt)this, iState, &info));
       
   390 	if (aContext)
       
   391 		{
       
   392 		// This branch is needed for the primary too, but only in rare case
       
   393 		// where a secondary is being changed into a primary.
       
   394 		if (iFlow)
       
   395 			{
       
   396 			// Move the flow to default context. If remove
       
   397 			// fails, it is higly likely that this flow was
       
   398 			// not included in TFT.
       
   399 			iFlow->SetContext(iNif.DefaultPdpContext());
       
   400 			}
       
   401 		if (aContext->RefCount() > 0 || aContext->IsPrimary())
       
   402 			{
       
   403 			// Context has remaining flows or is a Primary, collect unused filters.
       
   404 			// (in case of primary, all filters will be unused, if any present).
       
   405 			TTFTInfo tft;
       
   406 			TInt ret = aContext->RemovePacketFilter(tft, iFlow);
       
   407 			if (ret > 0)
       
   408 				{
       
   409 				LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionRemovePacketFilter -- removing %d filter(s)"), iName, (TInt)this, iState, ret));
       
   410 				SetExpected(EPendingPacketFilterRemove);
       
   411 				(void)IsOk(aContext->ModifyTft(KRemoveFilters, tft), aContext);
       
   412 				return ETrue;
       
   413 				}
       
   414 			else if (ret < 0)
       
   415 				{
       
   416 				LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionRemovePacketFilter -- TFT construct failed with %d"), iName, (TInt)this, iState, ret));
       
   417 				CompleteAndDestruct(ret, NULL);
       
   418 				return ETrue;
       
   419 				}
       
   420 			}
       
   421 		else
       
   422 			{
       
   423 			// All flows have been removed from the context. In the current implementation
       
   424 			// the context has been scheduled for destruction, and there is no need for
       
   425 			// removing any existing TFT...
       
   426 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionRemovePacketFilter -- No flows left"), iName, (TInt)this, iState));
       
   427 			}
       
   428 		}
       
   429 	// No TFT changes need to be done,
       
   430 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionRemovePacketFilter -- no filters to remove"), iName, (TInt)this, iState));
       
   431 	return EFalse;
       
   432 	}
       
   433 	
       
   434 
       
   435 TBool CRequestBase::ActionAddPacketFilter(CPdpContext* aContext, const TContextParameters* /*aParams*/)
       
   436 	{
       
   437 	LOG(TLogContextInfo info(aContext));
       
   438 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionAddPacketFilter on %S"), iName, (TInt)this, iState, &info));
       
   439 	if (aContext && iFlow)
       
   440 		{
       
   441 		TTFTInfo tft;
       
   442 		TInt err = aContext->AddPacketFilter(*iFlow, tft);
       
   443 		if (err < 0)
       
   444 			{
       
   445 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionAddPacketFilter -- TFT construct failed with %d"), iName, (TInt)this, iState, err));
       
   446 			Failure(aContext, err);
       
   447 			return ETrue;
       
   448 			}
       
   449 		else if (err > 0)
       
   450 			{
       
   451 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionAddPacketFilter -- adding %d filter(s)"), iName, (TInt)this, iState, err));
       
   452 			SetExpected(EPendingPacketFilterAdd);
       
   453 			(void)IsOk(aContext->ModifyTft(KAddFilters, tft), aContext);
       
   454 			return ETrue;
       
   455 			}
       
   456 		// Filter does not need modification, start some other operation...
       
   457 		}
       
   458 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionAddPacketFilter -- no filters added"), iName, (TInt)this, iState));
       
   459 	return EFalse;
       
   460 	}
       
   461 	
       
   462 TBool CRequestBase::ActionCommit(CPdpContext* aContext, const TContextParameters* /*aParams*/)
       
   463 	/**
       
   464 	* Activate changes made to a context.
       
   465 	*
       
   466 	* This action can be run after a sequence of context modifying
       
   467 	* actions (filter, QoS, etc.). Depending on the state of the
       
   468 	* context, this calls either ModifyActive or Activate.
       
   469 	*/
       
   470 	{
       
   471 	if (aContext)
       
   472 		{
       
   473 		LOG(TLogContextInfo info(aContext));
       
   474 
       
   475 		if (!aContext->ContextActive())
       
   476 			{
       
   477 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionCommit -- start Activate %S"), iName, (TInt)this, iState, &info));
       
   478 			SetExpected(EPendingActivate);
       
   479 			(void)IsOk(aContext->Activate(), aContext);
       
   480 			}
       
   481 		else if (iContextModified)
       
   482 			{
       
   483 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionCommit -- start ModifyActive %S"), iName, (TInt)this, iState, &info));
       
   484 			SetExpected(EPendingModifyActive);
       
   485 			(void)IsOk(aContext->ModifyActive(), aContext);
       
   486 			}
       
   487 		else
       
   488 			{
       
   489 			// For example all flows go into same tunnel and filter is same for everyone.
       
   490 			// A flow leaving context does not affect the filter.
       
   491 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionCommit -- skip ModifyActive, not modified %S"), iName, (TInt)this, iState, &info));
       
   492 			return EFalse;
       
   493 			}
       
   494 		return ETrue;
       
   495 		}
       
   496 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionCommit -- nothing to do, no context"), iName, (TInt)this, iState));
       
   497 	return EFalse;
       
   498 	}
       
   499 
       
   500 
       
   501 TBool CRequestBase::ActionRequestComplete(CPdpContext* /*aContext*/, const TContextParameters* /*aParams*/)
       
   502 	{
       
   503 	/**
       
   504 	* Default termination of the request.
       
   505 	*
       
   506 	* This action can be used as a default terminator of the request,
       
   507 	*/
       
   508 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionRequestComplete"), iName, (TInt)this, iState));
       
   509 	CompleteAndDestruct(KErrNone, NULL);
       
   510 	return ETrue;
       
   511 	}
       
   512 
       
   513 TBool CRequestBase::DoAddFlowToContext(CPdpContext* aContext, const TContextParameters*)
       
   514 	/**
       
   515 	* Set add current flow to current context.
       
   516 	*
       
   517 	* Add current flow to current context internally (e.g. add CFlowData object to
       
   518 	* CPdpContext object).
       
   519 	*/
       
   520 	{
       
   521 	LOG(TLogContextInfo info(aContext));
       
   522 	if (iFlow && aContext)
       
   523 		{
       
   524 		LOG(Log::Printf(_L("\trequest %S[%u] %2d.DoAddFlowToContext to %S"), iName, (TInt)this, iState, &info));
       
   525 		iFlow->SetContext(aContext);
       
   526 		}
       
   527 	else
       
   528 		{
       
   529 		LOG(Log::Printf(_L("\trequest %S[%u] %2d.DoAddFlowToContext to %S [not done]"), iName, (TInt)this, iState, &info));
       
   530 		}
       
   531 	// This allows the use ActionRemovePacketFilter to be used after this
       
   532 	// to clean out unnecessary filters. This is required in Join, because
       
   533 	// when the last flow leaves, the filters are not updated (cannot be
       
   534 	// removed because PDP Context cannot exist without filters, and just
       
   535 	// deleting the context would be too drastic). Thus, when the same flow
       
   536 	// or new flow joins back to existing context, we need to check and
       
   537 	// clean out stale filters.
       
   538 	iFlow = NULL;
       
   539 	return EFalse;
       
   540 	}
       
   541 
       
   542 void CRequestBase::Cancel(CFlowData* aFlowData)
       
   543 	/**
       
   544 	* Default cancel based on flow.
       
   545 	*
       
   546 	* If the only CFlowData pointer in request is stored in iFlow,
       
   547 	* then this default Cancel should be enough for most cases.
       
   548 	*/
       
   549 	{
       
   550 	if (iFlow == aFlowData)
       
   551 		{
       
   552 		LOG(Log::Printf(_L("\trequest %S[%u] Cancel due flow[%u] -- only detach the flow"), iName, (TInt)this, (TInt)iFlow));
       
   553 		// A running request is hard to cancel, because there is no way
       
   554 		// to tell NIF about it. Thus, when flow is cancelled, just detach
       
   555 		// it from the request and let the state machine run to completion
       
   556 		// without the flow (the machine should adapt!)
       
   557 		iFlow = NULL;
       
   558 		}
       
   559 	}
       
   560 
       
   561 void CRequestBase::Failure(CPdpContext* aContext, TInt aErrorCode)
       
   562 	/**
       
   563 	* The default Failure handler.
       
   564 	*
       
   565 	* Load the error code into iExtension and destruct.
       
   566 	*/
       
   567 	{
       
   568 	LOG(TLogContextInfo info(aContext));
       
   569 	(void)aContext; // silence warning in MARM release compile.
       
   570 	TInt ret = iExtension.SetErrorCode(aErrorCode);
       
   571 	LOG(Log::Printf(_L("\trequest %S[%u] Failure %S errorcode=%d ret=%d"), iName, (TInt)this, &info, aErrorCode, ret));
       
   572 	CompleteAndDestruct(ret == KErrNone ? aErrorCode : ret, NULL);
       
   573 	}
       
   574 
       
   575 // CNegotiationBase
       
   576 CNegotiationBase::CNegotiationBase(CNif& aNif) : CRequestBase(aNif)
       
   577 	{
       
   578 #ifdef _LOG
       
   579 	// This is only fallback, and should be ovvrriden by the
       
   580 	//  derived classes!
       
   581 	_LIT(KLogName, "Negotiation");
       
   582 	iName = &KLogName();
       
   583 #endif
       
   584 	}
       
   585 
       
   586 void CNegotiationBase::SetParameters(const TQoSParameters& aParams, CExtensionPolicy& aPolicy)
       
   587 	{
       
   588 	LOG(Log::Printf(_L("\trequest %S[%u] SetParamaters"), iName, (TInt)this));
       
   589 	iGeneric = aParams;
       
   590 	iUmts.ParsePolicyData(&aPolicy);
       
   591 	}
       
   592 
       
   593 void CNegotiationBase::SetParametersFlowExtn(CExtensionPolicy &aPolicy)
       
   594 	{
       
   595 	// ParsePolicyData will return true if SBLP presents
       
   596 	if (iFlowExtnParams.ParsePolicyDataForSblp(&aPolicy))
       
   597 		{
       
   598 		// SBLP presents
       
   599 		// so, set the Sblp flag for the channel
       
   600 	 	iSblp = ETrue;	
       
   601 		LOG(Log::Printf(_L("\trequest %S[%u] SetParametersFlowExtn -- SBLP"), iName, (TInt)this));
       
   602 		}
       
   603 	}
       
   604 	
       
   605 // CNegotiationBase
       
   606 TBool CNegotiationBase::ActionAddSblpParameter(CPdpContext *aContext, const TContextParameters* /*aParams*/)
       
   607 	{
       
   608 	/*
       
   609 	 *  if SBLP is supported, sblp parameter is added after setting the 
       
   610 	 *  Qos parameters
       
   611 	 *  
       
   612 	 *  once sblp parameter is added, the operations continue in the same
       
   613 	 *  way as it was 
       
   614 	 */
       
   615 	if(aContext && iSblp) // the negotiations requests sblp context
       
   616 		{
       
   617 		// call modifytft to add sblp
       
   618 		LOG(TLogContextInfo info(aContext));
       
   619 		TTFTInfo tft;
       
   620 		if (IsOk(tft.AddSblpToken(iFlowExtnParams.iAuthorizationToken, iFlowExtnParams.iFlowIds), aContext))
       
   621 			{
       
   622 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionAddSblpParameter -- Adding SBLP for %S"), iName, (TInt)this, iState, &info));
       
   623 			SetExpected(EPendingSblpParameterAdd);
       
   624 			(void)IsOk(aContext->ModifyTft(KAddSblpParameter, tft), aContext);
       
   625 			}
       
   626 		else
       
   627 			{
       
   628 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionAddSblpParameter -- Failed constructing TFT for SBLP for %S"),
       
   629 				iName, (TInt)this, iState, &info));
       
   630 			}
       
   631 		return ETrue;
       
   632 		}
       
   633 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionAddSblpParameter -- no SBLP"), iName, (TInt)this, iState));
       
   634 	return EFalse;
       
   635 	}
       
   636 	
       
   637 TBool CNegotiationBase::ActionSetQoS(CPdpContext *aContext, const TContextParameters* /*aParams*/)
       
   638 	{
       
   639 	if (aContext)
       
   640 		{
       
   641 		LOG(TLogContextInfo info(aContext));
       
   642 		LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionSetQoS -- request %S"), iName, (TInt)this, iState, &info));
       
   643 		SetExpected(EPendingSetQoS);
       
   644 		(void)IsOk(aContext->SetQoS(iGeneric, iUmts), aContext);
       
   645 		return ETrue;		
       
   646 		}
       
   647 		LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionSetQoS -- skipping"), iName, (TInt)this, iState));
       
   648 	return EFalse;
       
   649 	}
       
   650 
       
   651 
       
   652 TBool CNegotiationBase::ActionNegotiationComplete(CPdpContext *aContext, const TContextParameters* aParams)
       
   653 	{
       
   654 	LOG(TLogContextInfo info(aContext));
       
   655 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionNegotiationComplete %S"), iName, (TInt)this, iState, &info));
       
   656 	if (aParams)
       
   657 		{
       
   658 		// Return results of the negotiation to upper layers.
       
   659 		TInt ret = iExtension.CreateExtension(aParams->iContextConfig, aParams->iReasonCode);
       
   660 		if (ret != KErrNone)
       
   661 			{
       
   662 			LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionNegotiationComplete -- CreateExtension fail=%d"), iName, (TInt)this, iState, ret));
       
   663 			// Ugh.. can't construct the return value (probably out of memory)
       
   664 			// Try plain error instead (if that does not work, then nothing can
       
   665 			// be done about it...)
       
   666 			(void)iExtension.SetErrorCode(ret);
       
   667 			}
       
   668 		}
       
   669 
       
   670 	if (iFlow && aContext)
       
   671 		{
       
   672 		// If there is assocated flow, assume it will need to be moved
       
   673 		// to the current context (nothing happens, if this is already
       
   674 		// true.
       
   675 		iFlow->SetContext(aContext);
       
   676 		}
       
   677 
       
   678 	CompleteAndDestruct(KErrNone, &iGeneric, iExtension);
       
   679 	return ETrue;
       
   680 	}
       
   681 	
       
   682 void CNegotiationBase::Failure(CPdpContext* /*aPdpContext*/, TInt aErrorCode)
       
   683 	{
       
   684 	// If allocation space for extn fails, there not much
       
   685 	// that can be done, the request must be completed anyway
       
   686 	// with empty extn.
       
   687 	LOG(Log::Printf(_L("\trequest %S[%u] Failure code=%d"), iName, (TInt)this, aErrorCode));
       
   688 	(void)iExtension.SetErrorCode(aErrorCode);
       
   689 	CompleteAndDestruct(aErrorCode, &iGeneric, iExtension);
       
   690 	}
       
   691 
       
   692 	
       
   693 // CClose
       
   694 
       
   695 CClose* CClose::New(CPdpContext& aContext)
       
   696 	{
       
   697 	return new CClose(aContext);
       
   698 	}
       
   699 
       
   700 CClose::CClose(CPdpContext& aContext) : CRequestBase(aContext.Nif()), iClosing(aContext)
       
   701 	{
       
   702 #ifdef _LOG
       
   703 	_LIT(KLogName, "Close");
       
   704 	iName = &KLogName();
       
   705 #endif
       
   706 	LOG(Log::Printf(_L("new\trequest %S[%u] size=%d"), iName, (TInt)this, sizeof(*this)));
       
   707 	iNotify = NULL;
       
   708 	}
       
   709 	
       
   710 void CClose::Start()
       
   711 	{
       
   712 	LOG(TLogContextInfo info(&iClosing));
       
   713 	LOG(Log::Printf(_L("Start\trequest %S[%u] %S"), iName, (TInt)this, &info));
       
   714 	// Give the context to the state machine.
       
   715 	SetContext(&iClosing);
       
   716 	// Note: iFlow is NULL. This means that the packet
       
   717 	// filter is just recomputed based on currenly
       
   718 	// joined flows.
       
   719 	CRequestBase::Start();
       
   720 	}
       
   721 
       
   722 CClose::~CClose()
       
   723 	{
       
   724 	}
       
   725 
       
   726 void CClose::Cancel(CPdpContext* aContext)
       
   727 	{
       
   728 	if (&iClosing == aContext)
       
   729 		{
       
   730 		LOG(TLogContextInfo info(aContext));
       
   731 		LOG(Log::Printf(_L("Cancel\trequest %S[%u] for %S"), iName, (TInt)this, &info));
       
   732 		Failure(aContext, KErrDied);
       
   733 		}
       
   734 	}
       
   735 
       
   736 
       
   737 CDeleteRequest* CDeleteRequest::NewL(CPdpContext *aContext)
       
   738 	{
       
   739 	return new (ELeave) CDeleteRequest(aContext);
       
   740 	}
       
   741 
       
   742 CDeleteRequest::CDeleteRequest(CPdpContext* aContext) : CRequestBase(aContext->Nif()), iDelete(aContext)
       
   743 	{
       
   744 #ifdef _LOG
       
   745 	_LIT(KLogName, "Delete");
       
   746 	iName = &KLogName();
       
   747 #endif
       
   748 	LOG(Log::Printf(_L("new\trequest %S[%u] size=%d"), iName, (TInt)this, sizeof(*this)));
       
   749 	iNotify = NULL;
       
   750 	}
       
   751 	
       
   752 void CDeleteRequest::Start()
       
   753 	{
       
   754 	LOG(TLogContextInfo info(iDelete));
       
   755 	LOG(Log::Printf(_L("Start\trequest %S[%u] %S"), iName, (TInt)this, &info));
       
   756 	// Issue a context delete for this context to NIF
       
   757 	if (iDelete)
       
   758 		{
       
   759 		CPdpContext* context = iDelete;
       
   760 		iDelete = NULL;		// Prevent Cancel() from triggering...
       
   761 		context->Delete();	// Send delete request to NIF
       
   762 		context->Nif().DeletePdpContext(context);	// Destroys the object (.. this calls my Cancel!)
       
   763 		}
       
   764 	CompleteAndDestruct(KErrNone, NULL);
       
   765 	}
       
   766 
       
   767 void CDeleteRequest::Cancel(CPdpContext* aContext)
       
   768 	{
       
   769 	if (aContext == iDelete)
       
   770 		{
       
   771 		LOG(TLogContextInfo info(aContext));
       
   772 		LOG(Log::Printf(_L("Cancel\trequest %S[%u] for %S"), iName, (TInt)this, &info));
       
   773 		Failure(aContext, KErrDied);
       
   774 		}
       
   775 	}
       
   776 
       
   777 
       
   778 // COpenChannel
       
   779 
       
   780 COpenChannel* COpenChannel::New(TUint aChannelId, CFlowData &aFlow, MQoSNegotiateEvent* aNotify)
       
   781 	{
       
   782 	return new COpenChannel(aChannelId, aFlow, aNotify);
       
   783 	}
       
   784 
       
   785 COpenChannel::COpenChannel(TInt aChannelId, CFlowData& aFlow, MQoSNegotiateEvent* aNotify) :
       
   786 	CNegotiationBase(aFlow.Nif()),
       
   787 	iChannelId(aChannelId)
       
   788 	{
       
   789 #ifdef _LOG
       
   790 	_LIT(KLogName, "Open");
       
   791 	iName = &KLogName();
       
   792 #endif
       
   793 	LOG(Log::Printf(_L("new\trequest %S[%u] size=%d"), iName, (TInt)this, sizeof(*this)));
       
   794 	iNotify = aNotify;
       
   795 	iFlow = &aFlow;
       
   796 	}
       
   797 
       
   798 COpenChannel::~COpenChannel()
       
   799 	{
       
   800 	}
       
   801 
       
   802 TBool COpenChannel::ActionNewContext(CPdpContext */*aContext*/, const TContextParameters* /*aParams*/)
       
   803 	{
       
   804 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.ActionNewContext"), iName, (TInt)this, iState));
       
   805 	SetExpected(EPendingCreate);
       
   806 	(void)IsOk(iNif.NewPdpContext(), NULL);
       
   807 	return ETrue;
       
   808 	}
       
   809 	
       
   810 TBool COpenChannel::DoRememberCreatedContext(CPdpContext* aContext, const TContextParameters*)
       
   811 	{
       
   812 	iNewContext = aContext;
       
   813 	if (aContext)
       
   814 		{
       
   815 		// ..and bind it to the channel id.
       
   816 		aContext->SetChannelId(iChannelId);
       
   817 		LOG(TLogContextInfo info(aContext));
       
   818 		LOG(Log::Printf(_L("\trequest %S[%u] %2d.DoRememberCreatedContext -- %S"), iName, (TInt)this, iState, &info));
       
   819 		}
       
   820 	else
       
   821 		{
       
   822 		LOG(Log::Printf(_L("\trequest %S[%u] %2d.DoRememberCreatedContext -- No context created for channel=%d"),
       
   823 			iName, (TInt)this, iState, iChannelId));
       
   824 		}
       
   825 	return EFalse;
       
   826 	}
       
   827 
       
   828 void COpenChannel::Start()
       
   829 	{
       
   830 	LOG(Log::Printf(_L("Start\trequest %S[%u] -- COpenChannel Begin"), iName, (TInt)this));
       
   831 	if (!iFlow)
       
   832 		{
       
   833 		LOG(Log::Printf(_L("\trequest %S[%u] Flow has been cancelled"), iName, (TInt)this));
       
   834 		CompleteAndDestruct(KErrNone, NULL);
       
   835 		return;
       
   836 		}
       
   837 
       
   838 	// First check if currently used Pdp context can be modified!!
       
   839 	CPdpContext* context = iFlow->PdpContext();
       
   840 	SetContext(context);
       
   841 	if (context && context != iNif.DefaultPdpContext())
       
   842 		{
       
   843 		if (context->RefCount() == 1)
       
   844 			{
       
   845 			LOG(TLogContextInfo info(context));
       
   846 			LOG(Log::Printf(_L("\trequest %S[%u] -- reuse existsing %S"), iName, (TInt)this, &info));
       
   847 			// Start state machine at different point.
       
   848 			iState = KStateReuseOldContext;
       
   849 			}
       
   850 		}
       
   851 	// If not reusing old, the machine starts by trying
       
   852 	// to remove the TFT from old context, if any...
       
   853 	CRequestBase::Start();
       
   854 	}
       
   855 
       
   856 
       
   857 void COpenChannel::Failure(CPdpContext* aPdpContext, TInt aErrorCode)
       
   858 	{
       
   859 	LOG(Log::Printf(_L("\trequest %S[%u] Failure code=%d"), iName, (TInt)this, aErrorCode));
       
   860 
       
   861 	if (aPdpContext && aPdpContext == iNewContext)
       
   862 		{
       
   863 		iNewContext = NULL;
       
   864 		aPdpContext->Delete();
       
   865 		CNif& nif = aPdpContext->Nif();
       
   866 		nif.DeletePdpContext(aPdpContext);
       
   867 		}
       
   868 	CNegotiationBase::Failure(aPdpContext, aErrorCode);	
       
   869 	}
       
   870 
       
   871 void COpenChannel::Cancel(CPdpContext* aContext)
       
   872 	{
       
   873 	if (aContext == iNewContext)
       
   874 		{
       
   875 		// Prevent Failure from deleting the context (the caller of Cancel is
       
   876 		// just doing that).
       
   877 		iNewContext = NULL;
       
   878 		LOG(TLogContextInfo info(aContext));
       
   879 		LOG(Log::Printf(_L("Cancel\trequest %S[%u] Cancelled for "), iName, (TInt)this, &info));
       
   880 		Failure(aContext, KErrDied);
       
   881 		}
       
   882 	}
       
   883 
       
   884 
       
   885 // CNegotiateChannel
       
   886 
       
   887 CNegotiateChannel* CNegotiateChannel::New(CPdpContext* aContext, MQoSNegotiateEvent* aNotify)
       
   888 	{
       
   889 	return new CNegotiateChannel(aContext, aNotify);
       
   890 	}
       
   891 
       
   892 CNegotiateChannel::CNegotiateChannel(CPdpContext *aContext, MQoSNegotiateEvent* aNotify) :
       
   893 	CNegotiationBase(aContext->Nif())
       
   894 	{
       
   895 #ifdef _LOG
       
   896 	_LIT(KLogName, "Negotiate");
       
   897 	iName = &KLogName();
       
   898 #endif
       
   899 	LOG(Log::Printf(_L("new\trequest %S[%u] size=%d"), iName, (TInt)this, sizeof(*this)));
       
   900 	iNotify = aNotify;
       
   901 	iChannel = aContext;
       
   902 	}
       
   903 
       
   904 CNegotiateChannel::~CNegotiateChannel()
       
   905 	{
       
   906 	}
       
   907 
       
   908 
       
   909 void CNegotiateChannel::Start()
       
   910 	{
       
   911 	LOG(Log::Printf(_L("Start\trequest %S[%u] -- CNegotiateChannel Begin"), iName, (TInt)this));
       
   912 	SetContext(iChannel);
       
   913 	CRequestBase::Start();
       
   914 	}
       
   915 
       
   916 
       
   917 void CNegotiateChannel::Cancel(CPdpContext* aContext)
       
   918 	{
       
   919 	if (iChannel == aContext)
       
   920 		{
       
   921 		LOG(TLogContextInfo info(aContext));
       
   922 		LOG(Log::Printf(_L("Cancel\trequest %S[%u] Cancelled for %S"), iName, (TInt)this, &info));
       
   923 		iChannel = NULL;
       
   924 		
       
   925 		//??Where does this go?
       
   926 		Failure(aContext, KErrDied);
       
   927 		}
       
   928 	}
       
   929 
       
   930 
       
   931 
       
   932 // CJoinRequest
       
   933 CJoinRequest* CJoinRequest::New(CPdpContext* aContext, CFlowData* aFlowData, MQoSNegotiateEvent* aNotify)
       
   934 	{
       
   935 	return new CJoinRequest(aContext, aFlowData, aNotify);
       
   936 	}
       
   937 
       
   938 CJoinRequest::CJoinRequest(CPdpContext* aContext,  CFlowData* aFlowData, MQoSNegotiateEvent* aNotify) :
       
   939 	CRequestBase(aFlowData->Nif())
       
   940 	{
       
   941 #ifdef _LOG
       
   942 	_LIT(KLogName, "Join");
       
   943 	iName = &KLogName();
       
   944 #endif
       
   945 	LOG(Log::Printf(_L("new\trequest %S[%u] size=%d"), iName, (TInt)this, sizeof(*this)));
       
   946 	iNotify = aNotify;
       
   947 	iChannel = aContext;
       
   948 	iFlow = aFlowData;
       
   949 	}
       
   950 
       
   951 CJoinRequest::~CJoinRequest()
       
   952 	{
       
   953 	}
       
   954 
       
   955 void CJoinRequest::Start()
       
   956 	{
       
   957 	LOG(Log::Printf(_L("Start\trequest %S[%u] -- CJoinRequest Begin"), iName, (TInt)this));
       
   958 	if (!iFlow)
       
   959 		{
       
   960 		LOG(Log::Printf(_L("\trequest %S[%u] Flow has been cancelled"), iName, (TInt)this));
       
   961 		CompleteAndDestruct(KErrNone, NULL);
       
   962 		return;
       
   963 		}
       
   964 	CPdpContext* context = iFlow->PdpContext();
       
   965 	LOG(TLogContextInfo info(context));
       
   966 	if (context == iChannel)
       
   967 		{
       
   968 		// Already joined to the target context
       
   969 		LOG(Log::Printf(_L("\trequest %S[%u] already joined to %S"), iName, (TInt)this, &info));
       
   970 		CompleteAndDestruct(KErrNone, NULL, iExtension);
       
   971 		return;
       
   972 		}
       
   973 	// Start with removal of the TFT from old context.
       
   974 	SetContext(context);
       
   975 	CRequestBase::Start();
       
   976 	}
       
   977 
       
   978 
       
   979 TBool CJoinRequest::DoStartWithTargetContext(CPdpContext */*aContext*/, const TContextParameters* /*aParams*/)
       
   980 	{
       
   981 	LOG(TLogContextInfo info(iChannel));
       
   982 	LOG(Log::Printf(_L("\trequest %S[%u] %2d.DoStartWithTargetContext -- target %S"), iName, (TInt)this, iState, &info));
       
   983 	SetContext(iChannel);
       
   984 	return EFalse;
       
   985 	}
       
   986 
       
   987 
       
   988 void CJoinRequest::Failure(CPdpContext* /*aPdpContext*/, TInt aErrorCode)
       
   989 	{
       
   990 	LOG(Log::Printf(_L("\trequest %S[%u] Failure code=%d"), iName, (TInt)this, aErrorCode));
       
   991 	iExtension.SetErrorCode(aErrorCode);
       
   992 	CompleteAndDestruct(EQoSJoinFailure, NULL, iExtension);
       
   993 	}
       
   994 
       
   995 void CJoinRequest::Cancel(CPdpContext* aContext)
       
   996 	{
       
   997 	if (iChannel == aContext)
       
   998 		{
       
   999 		LOG(TLogContextInfo info(aContext));
       
  1000 		LOG(Log::Printf(_L("Cancel\trequest %S[%u] Cancelled for %S"), iName, (TInt)this, &info));
       
  1001 		Failure(aContext, KErrDied);
       
  1002 		}
       
  1003 	}
       
  1004 
       
  1005 // CLeaveRequest
       
  1006 CLeaveRequest* CLeaveRequest::New(CPdpContext* aContext, CFlowData* aFlowData, MQoSNegotiateEvent* aNotify)
       
  1007 	{
       
  1008 	return new CLeaveRequest(aContext, aFlowData, aNotify);
       
  1009 	}
       
  1010 
       
  1011 CLeaveRequest::CLeaveRequest(CPdpContext* aContext, CFlowData* aFlowData, MQoSNegotiateEvent* aNotify) :
       
  1012 	CRequestBase(aContext->Nif())
       
  1013 	{
       
  1014 #ifdef _LOG
       
  1015 	_LIT(KLogName, "Leave");
       
  1016 	iName = &KLogName();
       
  1017 #endif
       
  1018 	LOG(Log::Printf(_L("new\trequest %S[%u] size=%d"), iName, (TInt)this, sizeof(*this)));
       
  1019 	iNotify = aNotify;
       
  1020 	iChannel = aContext;
       
  1021 	iFlow = aFlowData;
       
  1022 	//?? Why channel? it should be same as flow currently joined?
       
  1023 	//?? Or just use channel and recompute, leave == close?
       
  1024 	}
       
  1025 
       
  1026 void CLeaveRequest::Start()
       
  1027 	{
       
  1028 	LOG(Log::Printf(_L("Start\trequest %S[%u] -- CLeaveRequest Begin"), iName, (TInt)this));
       
  1029 	// Start with removal of the TFT from old context.
       
  1030 	// The flow has nothing to do with this anymore?
       
  1031 	SetContext(iChannel);
       
  1032 	CRequestBase::Start();
       
  1033 	}
       
  1034 
       
  1035 CLeaveRequest::~CLeaveRequest()
       
  1036 	{
       
  1037 	LOG(Log::Printf(_L("CLeaveRequest::~CLeaveRequest()")));
       
  1038 	}
       
  1039 
       
  1040 
       
  1041 void CLeaveRequest::Failure(CPdpContext* /*aPdpContext*/, TInt aErrorCode)
       
  1042 	{
       
  1043 	LOG(Log::Printf(_L("\trequest %S[%u] Failure code=%d"), iName, (TInt)this, aErrorCode));
       
  1044 	iExtension.SetErrorCode(aErrorCode);
       
  1045 	CompleteAndDestruct(EQoSLeaveFailure, NULL, iExtension);
       
  1046 	}
       
  1047 
       
  1048 void CLeaveRequest::Cancel(CPdpContext* aContext)
       
  1049 	{
       
  1050 	if (iChannel == aContext)
       
  1051 		{
       
  1052 		LOG(TLogContextInfo info(aContext));
       
  1053 		LOG(Log::Printf(_L("Cancel\trequest %S[%u] Cancelled for %S"), iName, (TInt)this, &info));
       
  1054 		Failure(aContext, KErrDied);
       
  1055 		}
       
  1056 	}