|
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 } |