|
1 // Copyright (c) 2006-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 // Name : UserAgentServer.cpp |
|
15 // Part of : TransactionUser |
|
16 // Version : SIP/5.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include "SipAssert.h" |
|
22 #include "siperr.h" |
|
23 #include "siprequest.h" |
|
24 #include "sipresponse.h" |
|
25 #include "siptoheader.h" |
|
26 #include "sipmaxforwardsheader.h" |
|
27 #include "uricontainer.h" |
|
28 #include "sipstrings.h" |
|
29 #include "sipstrconsts.h" |
|
30 #include "MSipRegistrations.h" |
|
31 #include "MSipDialogs.h" |
|
32 #include "MSIPRequestRouter.h" |
|
33 #include "Transmitter.h" |
|
34 |
|
35 #include "UserAgentServer.h" |
|
36 #include "UserAgentState.h" |
|
37 #include "UserAgentTimer.h" |
|
38 #include "TimerValues.h" |
|
39 #include "CTransactionStore.h" |
|
40 #include "SIPMessageUtility.h" |
|
41 |
|
42 |
|
43 // ----------------------------------------------------------------------------- |
|
44 // CUserAgentServer::CUserAgentServer |
|
45 // ----------------------------------------------------------------------------- |
|
46 // |
|
47 CUserAgentServer::CUserAgentServer(CUserAgentCreateParams& aParams, |
|
48 MSipDialogs& aDialogs, |
|
49 MSIPRequestRouter& aRouter) : |
|
50 CUserAgent(aParams), |
|
51 iDialogs(aDialogs), |
|
52 iRouter(aRouter) |
|
53 { |
|
54 } |
|
55 |
|
56 // ----------------------------------------------------------------------------- |
|
57 // CUserAgentServer::~CUserAgentServer |
|
58 // If transaction exists or InviteUAS sent a 2xx, inform ConnectionMgr to stop |
|
59 // using the responses. |
|
60 // ----------------------------------------------------------------------------- |
|
61 // |
|
62 CUserAgentServer::~CUserAgentServer() |
|
63 { |
|
64 CancelGetOwnerRequest(); |
|
65 iToTag.Close(); |
|
66 |
|
67 if (iTransmitter) |
|
68 { |
|
69 iTransmitter->CancelSendResponses(CUserAgent::TransactionId(), ETrue); |
|
70 } |
|
71 } |
|
72 |
|
73 // ----------------------------------------------------------------------------- |
|
74 // CUserAgentServer::IsUAS |
|
75 // ----------------------------------------------------------------------------- |
|
76 // |
|
77 TBool CUserAgentServer::IsUAS() const |
|
78 { |
|
79 __TEST_INVARIANT; |
|
80 return ETrue; |
|
81 } |
|
82 |
|
83 // ----------------------------------------------------------------------------- |
|
84 // CUserAgentServer::RegistrationId |
|
85 // UAS doesn't have a registration ID. |
|
86 // ----------------------------------------------------------------------------- |
|
87 // |
|
88 TRegistrationId CUserAgentServer::RegistrationId() const |
|
89 { |
|
90 __TEST_INVARIANT; |
|
91 |
|
92 return KEmptyRegistrationId; |
|
93 } |
|
94 |
|
95 // ----------------------------------------------------------------------------- |
|
96 // CUserAgentServer::OwnerFoundL |
|
97 // ----------------------------------------------------------------------------- |
|
98 // |
|
99 void |
|
100 CUserAgentServer::OwnerFoundL(TUint32 aRequestId, MTransactionOwner* aOwner) |
|
101 { |
|
102 __TEST_INVARIANT; |
|
103 __SIP_ASSERT_LEAVE(aOwner && aRequestId == iRouterRequestId, KErrArgument); |
|
104 |
|
105 if (!HasStopped()) |
|
106 { |
|
107 State().OwnerFoundL(*this, aOwner); |
|
108 } |
|
109 |
|
110 __TEST_INVARIANT; |
|
111 } |
|
112 |
|
113 // ----------------------------------------------------------------------------- |
|
114 // CUserAgentServer::OwnerNotFoundL |
|
115 // ----------------------------------------------------------------------------- |
|
116 // |
|
117 void CUserAgentServer::OwnerNotFoundL(TUint32 aRequestId, CSIPResponse* aResp) |
|
118 { |
|
119 __TEST_INVARIANT; |
|
120 __SIP_ASSERT_LEAVE(aResp && aRequestId == iRouterRequestId, KErrArgument); |
|
121 |
|
122 if (HasStopped()) |
|
123 { |
|
124 delete aResp; |
|
125 } |
|
126 else |
|
127 { |
|
128 State().OwnerNotFoundL(*this, aResp); |
|
129 } |
|
130 |
|
131 __TEST_INVARIANT; |
|
132 } |
|
133 |
|
134 // ----------------------------------------------------------------------------- |
|
135 // CUserAgentServer::ErrorOccurred |
|
136 // ----------------------------------------------------------------------------- |
|
137 // |
|
138 void CUserAgentServer::ErrorOccurred(TUint32 aRequestId, TInt aError) |
|
139 { |
|
140 __TEST_INVARIANT; |
|
141 __SIP_ASSERT_LEAVE(aRequestId == iRouterRequestId, KErrArgument); |
|
142 |
|
143 StopTimerOwnerResolver(); |
|
144 if (aError == KErrNoMemory) |
|
145 { |
|
146 Stop(aError); |
|
147 } |
|
148 else |
|
149 { |
|
150 TRAPD(err, RequestRouterErrorL()); |
|
151 if (err != KErrNone) |
|
152 { |
|
153 Stop(aError); |
|
154 } |
|
155 } |
|
156 |
|
157 __TEST_INVARIANT; |
|
158 } |
|
159 |
|
160 // ----------------------------------------------------------------------------- |
|
161 // CUserAgentServer::RequestRouterErrorL |
|
162 // ----------------------------------------------------------------------------- |
|
163 // |
|
164 void CUserAgentServer::RequestRouterErrorL() |
|
165 { |
|
166 __TEST_INVARIANT; |
|
167 |
|
168 if (!HasStopped()) |
|
169 { |
|
170 State().RequestRouterErrorL(*this); |
|
171 } |
|
172 |
|
173 __TEST_INVARIANT; |
|
174 } |
|
175 |
|
176 // ----------------------------------------------------------------------------- |
|
177 // CUserAgentServer::InitialRequestReceivedL |
|
178 // ----------------------------------------------------------------------------- |
|
179 // |
|
180 void CUserAgentServer::InitialRequestReceivedL(CSIPRequest* aReq, |
|
181 const CUserAgentState& aGetTxOwner, |
|
182 const CUserAgentState& aWaitRespFromApp, |
|
183 const CUserAgentState& aErrorRespSent) |
|
184 { |
|
185 __TEST_INVARIANT; |
|
186 __SIP_ASSERT_LEAVE(aReq, KErrArgument); |
|
187 |
|
188 if (!UpdateTransportProtocol(*aReq)) |
|
189 { |
|
190 delete aReq; |
|
191 Stop(KErrNone); |
|
192 return; |
|
193 } |
|
194 |
|
195 StoreToTag(*aReq); |
|
196 |
|
197 TInt responseCode = 0; |
|
198 RStringF reasonPhrase; |
|
199 if (CheckReceivedRequest(*aReq, responseCode, reasonPhrase)) |
|
200 { |
|
201 iTransactionStore.StoreContactHeadersL(TransactionId(), *aReq); |
|
202 |
|
203 if (DoesDialogExistForRequestL(*aReq)) |
|
204 { |
|
205 //Enter next state before passing request. If upper layer sends |
|
206 //response synchronously in PassMsgToTransactionOwnerL, UAS is in a |
|
207 //correct state to handle it. |
|
208 ChangeState(aWaitRespFromApp); |
|
209 PassMsgToTransactionOwnerL(aReq); |
|
210 } |
|
211 else |
|
212 { |
|
213 RequestOutsideDialogL(aReq, aGetTxOwner, aErrorRespSent); |
|
214 } |
|
215 } |
|
216 else |
|
217 { |
|
218 SendErrorResponseL(responseCode, reasonPhrase, aErrorRespSent); |
|
219 delete aReq; |
|
220 } |
|
221 |
|
222 __TEST_INVARIANT; |
|
223 } |
|
224 |
|
225 // ----------------------------------------------------------------------------- |
|
226 // CUserAgentServer::CheckReceivedRequest |
|
227 // If no To-tag, compare request to ongoing transactions to see if it is a |
|
228 // merged request. |
|
229 // ----------------------------------------------------------------------------- |
|
230 // |
|
231 TBool CUserAgentServer::CheckReceivedRequest(CSIPRequest& aReq, |
|
232 TInt& aResponseCode, |
|
233 RStringF& aReasonPhrase) const |
|
234 { |
|
235 __TEST_INVARIANT; |
|
236 __ASSERT_ALWAYS(aReq.To() != NULL, |
|
237 User::Panic(_L("UAS:ChkRcvReq to"), KErrArgument)); |
|
238 |
|
239 if (aReq.HasHeader(SIPStrings::StringF(SipStrConsts::EMaxForwardsHeader))) |
|
240 { |
|
241 TSglQueIter<CSIPHeaderBase> iter = |
|
242 aReq.Headers(SIPStrings::StringF(SipStrConsts::EMaxForwardsHeader)); |
|
243 CSIPMaxForwardsHeader& maxForw = |
|
244 static_cast<CSIPMaxForwardsHeader&>(*iter); |
|
245 |
|
246 if (maxForw.Value() == 0) |
|
247 { |
|
248 aReasonPhrase = |
|
249 SIPStrings::StringF(SipStrConsts::EPhraseTooManyHops); |
|
250 aResponseCode = 483; |
|
251 return EFalse; |
|
252 } |
|
253 } |
|
254 |
|
255 if (!aReq.To()->HasParam(SIPStrings::StringF(SipStrConsts::ETag)) && |
|
256 iTransactionStore.IsMergedRequest(*this, aReq)) |
|
257 { |
|
258 aReasonPhrase = |
|
259 SIPStrings::StringF(SipStrConsts::EPhraseLoopDetected); |
|
260 aResponseCode = 482; |
|
261 return EFalse; |
|
262 } |
|
263 |
|
264 return ETrue; |
|
265 } |
|
266 |
|
267 // ----------------------------------------------------------------------------- |
|
268 // CUserAgentServer::DoesDialogExistForRequestL |
|
269 // ----------------------------------------------------------------------------- |
|
270 // |
|
271 TBool CUserAgentServer::DoesDialogExistForRequestL(CSIPRequest& aReq) |
|
272 { |
|
273 __TEST_INVARIANT; |
|
274 __SIP_ASSERT_LEAVE(!iObserver && !iOutgoingMsg, KErrAlreadyExists); |
|
275 |
|
276 CSIPResponse* resp = NULL; |
|
277 iObserver = iDialogs.TransactionOwnerL(aReq, &resp); |
|
278 |
|
279 if (!iObserver && resp) |
|
280 { |
|
281 iOutgoingMsg = resp; |
|
282 } |
|
283 |
|
284 __TEST_INVARIANT; |
|
285 return iObserver != NULL; |
|
286 } |
|
287 |
|
288 // ----------------------------------------------------------------------------- |
|
289 // CUserAgentServer::RequestOutsideDialogL |
|
290 // If registration subsystem does not recognize the Request-URI, a 404 is sent. |
|
291 // Record-Routes are only stored from requests outside dialog |
|
292 // ----------------------------------------------------------------------------- |
|
293 // |
|
294 void |
|
295 CUserAgentServer::RequestOutsideDialogL(CSIPRequest* aReq, |
|
296 const CUserAgentState& aGetTxOwner, |
|
297 const CUserAgentState& aErrorRespSent) |
|
298 { |
|
299 __TEST_INVARIANT; |
|
300 __SIP_ASSERT_LEAVE(aReq, KErrArgument); |
|
301 |
|
302 if (iOutgoingMsg) |
|
303 { |
|
304 HandleResponseFromDialogsL(aErrorRespSent); |
|
305 } |
|
306 else |
|
307 { |
|
308 CURIContainer* uri = aReq->RequestURI(); |
|
309 if (uri && iRegistrations.CheckRequestURI(*uri)) |
|
310 { |
|
311 TRAPD(err, iRouterRequestId = |
|
312 iRouter.TransactionOwnerL(*aReq, |
|
313 TransportParams().IapId(), |
|
314 *this)); |
|
315 if (err == KErrNone) |
|
316 { |
|
317 StartTimerOwnerResolverL(); |
|
318 iTransactionStore.StoreRecordRouteHeadersL(TransactionId(), |
|
319 *aReq); |
|
320 __SIP_ASSERT_LEAVE(!iIncomingMsg, KErrAlreadyExists); |
|
321 iIncomingMsg = aReq; |
|
322 |
|
323 ChangeState(aGetTxOwner); |
|
324 return; //aReq is not deleted |
|
325 } |
|
326 |
|
327 SendErrorResponseL(603, |
|
328 SIPStrings::StringF(SipStrConsts::EPhraseDecline), |
|
329 aErrorRespSent); |
|
330 } |
|
331 else |
|
332 { |
|
333 SendErrorResponseL(404, |
|
334 SIPStrings::StringF(SipStrConsts::EPhraseNotFound), |
|
335 aErrorRespSent); |
|
336 } |
|
337 } |
|
338 |
|
339 delete aReq; |
|
340 |
|
341 __TEST_INVARIANT; |
|
342 } |
|
343 |
|
344 // ----------------------------------------------------------------------------- |
|
345 // CUserAgentServer::SendErrorResponseL |
|
346 // ----------------------------------------------------------------------------- |
|
347 // |
|
348 void CUserAgentServer::SendErrorResponseL(TInt aResponseCode, |
|
349 RStringF aReasonPhrase, |
|
350 const CUserAgentState& aErrorRespSent) |
|
351 { |
|
352 __TEST_INVARIANT; |
|
353 __SIP_ASSERT_LEAVE(aResponseCode >= 300, KErrArgument); |
|
354 |
|
355 CSIPResponse* resp = CSIPResponse::NewLC(aResponseCode, aReasonPhrase); |
|
356 FillResponseL(*resp); |
|
357 |
|
358 ChangeState(aErrorRespSent); |
|
359 SendResponseToTransactionL(resp); |
|
360 CleanupStack::Pop(resp); |
|
361 |
|
362 __TEST_INVARIANT; |
|
363 } |
|
364 |
|
365 // ----------------------------------------------------------------------------- |
|
366 // CUserAgentServer::CheckResponseL |
|
367 // Via headers should not be present yet. UAS copies them from the request. |
|
368 // ----------------------------------------------------------------------------- |
|
369 // |
|
370 void CUserAgentServer::CheckResponseL(const CSIPResponse& aResp) const |
|
371 { |
|
372 __TEST_INVARIANT; |
|
373 |
|
374 if (aResp.HasHeader(SIPStrings::StringF(SipStrConsts::EViaHeader))) |
|
375 { |
|
376 User::Leave(KErrSIPMalformedMessage); |
|
377 } |
|
378 } |
|
379 |
|
380 // ----------------------------------------------------------------------------- |
|
381 // CUserAgentServer::FillResponseL |
|
382 // If the To-header doesn't yet have a tag, it's added unless the response is |
|
383 // 100. If a tag has already been generated, it is used for all responses. |
|
384 // ----------------------------------------------------------------------------- |
|
385 // |
|
386 void CUserAgentServer::FillResponseL(CSIPResponse& aResp) |
|
387 { |
|
388 __TEST_INVARIANT; |
|
389 |
|
390 iTransactionStore.CopyHeadersToResponseL(TransactionId(), aResp); |
|
391 CheckContactHeadersL(aResp, aResp.To()); |
|
392 |
|
393 RStringF tag = SIPStrings::StringF(SipStrConsts::ETag); |
|
394 |
|
395 if (aResp.ResponseCode() > 100) |
|
396 { |
|
397 CSIPToHeader* to = aResp.To(); |
|
398 __SIP_ASSERT_LEAVE(to != NULL, KErrArgument); |
|
399 |
|
400 if (iToTag.DesC().Length() > 0) |
|
401 { |
|
402 if (!to->HasParam(tag)) |
|
403 { |
|
404 to->SetParamL(tag, iToTag); |
|
405 } |
|
406 } |
|
407 else |
|
408 { |
|
409 if (!to->HasParam(tag)) |
|
410 { |
|
411 //Generate the tag after CopyHeadersToResponseL so SIP headers |
|
412 //can be used as random input for tag. |
|
413 AddTagL(*to); |
|
414 } |
|
415 |
|
416 StoreToTag(aResp); |
|
417 |
|
418 //Put the tag to store. Routing of an ACK needs it. |
|
419 iTransactionStore.UpdateToTagL(TransactionId(), iToTag); |
|
420 } |
|
421 } |
|
422 |
|
423 __TEST_INVARIANT; |
|
424 } |
|
425 |
|
426 // ----------------------------------------------------------------------------- |
|
427 // CUserAgentServer::StoreToTag |
|
428 // ----------------------------------------------------------------------------- |
|
429 // |
|
430 void CUserAgentServer::StoreToTag(CSIPMessage& aMsg) |
|
431 { |
|
432 __TEST_INVARIANT; |
|
433 __ASSERT_ALWAYS(iToTag.DesC().Length() == 0, |
|
434 User::Panic(_L("StoreToTag exist"), KErrAlreadyExists)); |
|
435 |
|
436 CSIPToHeader* to = aMsg.To(); |
|
437 __ASSERT_ALWAYS(to != NULL, |
|
438 User::Panic(_L("StoreToTag !to"), KErrArgument)); |
|
439 |
|
440 if (to->HasParam(SIPStrings::StringF(SipStrConsts::ETag))) |
|
441 { |
|
442 iToTag.Close(); |
|
443 iToTag = to->ParamValue(SIPStrings::StringF(SipStrConsts::ETag)).Copy(); |
|
444 } |
|
445 |
|
446 __TEST_INVARIANT; |
|
447 } |
|
448 |
|
449 // ----------------------------------------------------------------------------- |
|
450 // CUserAgentServer::SendResponseToTransactionL |
|
451 // ----------------------------------------------------------------------------- |
|
452 // |
|
453 void CUserAgentServer::SendResponseToTransactionL(CSIPResponse* aResp) const |
|
454 { |
|
455 __TEST_INVARIANT; |
|
456 __SIP_ASSERT_LEAVE(iTransaction, KErrNotFound); |
|
457 __SIP_ASSERT_LEAVE(aResp, KErrArgument); |
|
458 |
|
459 iTransaction->SendResponseL(aResp, iTransportProtocol, TransportParams()); |
|
460 } |
|
461 |
|
462 // ----------------------------------------------------------------------------- |
|
463 // CUserAgentServer::HandleResponseFromDialogsL |
|
464 // ----------------------------------------------------------------------------- |
|
465 // |
|
466 void |
|
467 CUserAgentServer::HandleResponseFromDialogsL(const CUserAgentState& aNextState) |
|
468 { |
|
469 __TEST_INVARIANT; |
|
470 __SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound); |
|
471 |
|
472 CSIPResponse* resp = static_cast<CSIPResponse*>(iOutgoingMsg); |
|
473 __SIP_ASSERT_LEAVE(resp->IsErrorResponse(), KErrSIPMalformedMessage); |
|
474 |
|
475 FillResponseL(*resp); |
|
476 |
|
477 ChangeState(aNextState); |
|
478 SendResponseToTransactionL(resp); |
|
479 iOutgoingMsg = NULL; |
|
480 |
|
481 __TEST_INVARIANT; |
|
482 } |
|
483 |
|
484 // ----------------------------------------------------------------------------- |
|
485 // CUserAgentServer::HandleOwnerFoundL |
|
486 // Enter next state before passing request to MTransactionOwner. If upper layer |
|
487 // sends response synchronously in MTransactionOwner::ReceiveL, UAS must be in a |
|
488 // correct state to handle it. |
|
489 // ----------------------------------------------------------------------------- |
|
490 // |
|
491 void |
|
492 CUserAgentServer::HandleOwnerFoundL(MTransactionOwner* aOwner, |
|
493 const CUserAgentState& aWaitRespFromApp) |
|
494 { |
|
495 __TEST_INVARIANT; |
|
496 //Observer can be set only once by MSIPRequestRouter. But when application |
|
497 //sends a response, it can change MTransactionOwner with every SendL call. |
|
498 __SIP_ASSERT_LEAVE(!iObserver, KErrAlreadyExists); |
|
499 __SIP_ASSERT_LEAVE(aOwner, KErrArgument); |
|
500 |
|
501 iObserver = aOwner; |
|
502 |
|
503 StopTimerOwnerResolver(); |
|
504 |
|
505 ChangeState(aWaitRespFromApp); |
|
506 PassStoredRequestToTransactionOwnerL(); |
|
507 |
|
508 __TEST_INVARIANT; |
|
509 } |
|
510 |
|
511 // ----------------------------------------------------------------------------- |
|
512 // CUserAgentServer::HandleOwnerNotFoundL |
|
513 // Response can not be 2xx for INVITE since it has different state in the |
|
514 // InviteUAS than the error responses. |
|
515 // ----------------------------------------------------------------------------- |
|
516 // |
|
517 void |
|
518 CUserAgentServer::HandleOwnerNotFoundL(CSIPResponse* aResp, |
|
519 const CUserAgentState& aFinalRespSent) |
|
520 { |
|
521 __TEST_INVARIANT; |
|
522 __SIP_ASSERT_LEAVE(iIncomingMsg, KErrNotFound); |
|
523 __SIP_ASSERT_LEAVE(aResp && aResp->ResponseCode() >= 200, KErrArgument); |
|
524 |
|
525 if (static_cast<CSIPRequest*>(iIncomingMsg)->Method() == |
|
526 SIPStrings::StringF(SipStrConsts::EInvite)) |
|
527 { |
|
528 __SIP_ASSERT_LEAVE(aResp->ResponseCode() >= 300, KErrArgument); |
|
529 } |
|
530 |
|
531 StopTimerOwnerResolver(); |
|
532 CheckResponseL(*aResp); |
|
533 FillResponseL(*aResp); |
|
534 ChangeState(aFinalRespSent); |
|
535 SendResponseToTransactionL(aResp); |
|
536 |
|
537 __TEST_INVARIANT; |
|
538 } |
|
539 |
|
540 // ----------------------------------------------------------------------------- |
|
541 // CUserAgentServer::HandleRequestRouterErrorL |
|
542 // ----------------------------------------------------------------------------- |
|
543 // |
|
544 void CUserAgentServer::HandleRequestRouterErrorL( |
|
545 const CUserAgentState& aErrorRespSent) |
|
546 { |
|
547 __TEST_INVARIANT; |
|
548 |
|
549 CancelGetOwnerRequest(); |
|
550 SendErrorResponseL(603, |
|
551 SIPStrings::StringF(SipStrConsts::EPhraseDecline), |
|
552 aErrorRespSent); |
|
553 __TEST_INVARIANT; |
|
554 } |
|
555 |
|
556 // ----------------------------------------------------------------------------- |
|
557 // CUserAgentServer::HandleSendResponseL |
|
558 // Free stored Record-Route and Contact headers when a final response is sent. |
|
559 // Always keep the TransportId from original TSIPTransportParams. |
|
560 // ----------------------------------------------------------------------------- |
|
561 // |
|
562 void CUserAgentServer::HandleSendResponseL(CSIPResponse* aResp, |
|
563 const TSIPTransportParams& aParams) |
|
564 { |
|
565 __TEST_INVARIANT; |
|
566 __SIP_ASSERT_LEAVE(aResp, KErrArgument); |
|
567 |
|
568 CheckResponseL(*aResp); |
|
569 FillResponseL(*aResp); |
|
570 |
|
571 if (CSIPMessageUtility::IsFinalResponse(*aResp)) |
|
572 { |
|
573 iTransactionStore.FreeRecordRouteHeaders(TransactionId()); |
|
574 iTransactionStore.FreeContactHeaders(TransactionId()); |
|
575 } |
|
576 |
|
577 TSIPTransportParams newParams(aParams); |
|
578 newParams.SetTransportId(iTransportParams.TransportId()); |
|
579 iTransportParams = newParams; |
|
580 |
|
581 __TEST_INVARIANT; |
|
582 } |
|
583 |
|
584 // ----------------------------------------------------------------------------- |
|
585 // CUserAgentServer::StartTimerOwnerResolverL |
|
586 // Timer duration is selected to be shorter than timer F2, so if this timer |
|
587 // expires, the server transaction still exists and a response can be sent. |
|
588 // ----------------------------------------------------------------------------- |
|
589 // |
|
590 void CUserAgentServer::StartTimerOwnerResolverL() |
|
591 { |
|
592 __TEST_INVARIANT; |
|
593 __SIP_ASSERT_LEAVE(!iTimerOwnerResolver, KErrAlreadyExists); |
|
594 |
|
595 iTimerOwnerResolver = |
|
596 CTimerOwnerResolver::NewL(iTimers, |
|
597 this, |
|
598 (iTimerValues.Duration64xT1() / 10) * 9); |
|
599 __TEST_INVARIANT; |
|
600 } |
|
601 |
|
602 // ----------------------------------------------------------------------------- |
|
603 // CUserAgentServer::StopTimerOwnerResolver |
|
604 // ----------------------------------------------------------------------------- |
|
605 // |
|
606 void CUserAgentServer::StopTimerOwnerResolver() |
|
607 { |
|
608 __TEST_INVARIANT; |
|
609 |
|
610 delete iTimerOwnerResolver; |
|
611 iTimerOwnerResolver = NULL; |
|
612 |
|
613 __TEST_INVARIANT; |
|
614 } |
|
615 |
|
616 // ----------------------------------------------------------------------------- |
|
617 // CUserAgentServer::CancelGetOwnerRequest |
|
618 // ----------------------------------------------------------------------------- |
|
619 // |
|
620 void CUserAgentServer::CancelGetOwnerRequest() const |
|
621 { |
|
622 __TEST_INVARIANT; |
|
623 |
|
624 iRouter.Cancel(iRouterRequestId); |
|
625 } |
|
626 |
|
627 // ----------------------------------------------------------------------------- |
|
628 // CUserAgentServer::PassStoredRequestToTransactionOwnerL |
|
629 // iIncomingMsg is not passed as parameter to PassMsgToTransactionOwnerL(), |
|
630 // since iIncomingMsg would be set to NULL only after PassMsgToTransactionOwnerL |
|
631 // returns. If upper layer deletes the request, accessing iIncomingMsg causes |
|
632 // crash in TU's invariants. |
|
633 // ----------------------------------------------------------------------------- |
|
634 // |
|
635 void CUserAgentServer::PassStoredRequestToTransactionOwnerL() |
|
636 { |
|
637 __TEST_INVARIANT; |
|
638 __SIP_ASSERT_LEAVE(iIncomingMsg, KErrNotFound); |
|
639 |
|
640 CSIPMessage* msg = iIncomingMsg; |
|
641 iIncomingMsg = NULL; |
|
642 CleanupStack::PushL(msg); |
|
643 PassMsgToTransactionOwnerL(msg); |
|
644 CleanupStack::Pop(msg); |
|
645 |
|
646 __TEST_INVARIANT; |
|
647 } |
|
648 |
|
649 // ----------------------------------------------------------------------------- |
|
650 // CUserAgentServer::ToTag |
|
651 // ----------------------------------------------------------------------------- |
|
652 // |
|
653 RStringF CUserAgentServer::ToTag() const |
|
654 { |
|
655 __TEST_INVARIANT; |
|
656 return iToTag; |
|
657 } |
|
658 |
|
659 // ----------------------------------------------------------------------------- |
|
660 // CUserAgentServer::__DbgTestInvariant |
|
661 // ----------------------------------------------------------------------------- |
|
662 // |
|
663 |
|
664 void CUserAgentServer::__DbgTestInvariant() const |
|
665 { |
|
666 //For CCancelUAS, iOwnerResolver is always NULL |
|
667 if ((iIncomingMsg && !iIncomingMsg->IsRequest()) || |
|
668 (iOutgoingMsg && iOutgoingMsg->IsRequest()) || |
|
669 !iOwnsOutgoingMsg) |
|
670 { |
|
671 User::Invariant(); |
|
672 } |
|
673 } |
|
674 |