|
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 : InviteUAC.cpp |
|
15 // Part of : TransactionUser |
|
16 // Version : SIP/6.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include "siperr.h" |
|
22 #include "sipfromheader.h" |
|
23 #include "sipviaheader.h" |
|
24 #include "siprequest.h" |
|
25 #include "sipresponse.h" |
|
26 #include "sipstrings.h" |
|
27 #include "sipstrconsts.h" |
|
28 #include "MSipRegistrations.h" |
|
29 #include "TransactionMgr.h" |
|
30 #include "ClientTransaction.h" |
|
31 #include "Transmitter.h" |
|
32 #include "DeleteMgr.h" |
|
33 #include "SipAssert.h" |
|
34 |
|
35 #include "InviteUAC.h" |
|
36 #include "InviteUACStates.h" |
|
37 #include "CTransactionStore.h" |
|
38 #include "SIPMessageUtility.h" |
|
39 #include "SIPRequestUtility.h" |
|
40 #include "TimerValues.h" |
|
41 #include "UserAgentTimer.h" |
|
42 #include "UserAgentCreateParams.h" |
|
43 #include "RouteSet.h" |
|
44 #include "ResolvingResults.h" |
|
45 |
|
46 |
|
47 // ----------------------------------------------------------------------------- |
|
48 // CInviteUAC::NewL |
|
49 // ----------------------------------------------------------------------------- |
|
50 // |
|
51 CInviteUAC* CInviteUAC::NewL(CUserAgentCreateParams& aParams, |
|
52 MSipConnectionMgr& aConnectionMgr, |
|
53 MSipUriResolver& aResolver, |
|
54 CSIPSec& aSIPSec, |
|
55 TUint32 aCSeqNumber, |
|
56 TBool aIsPrivateAddress, |
|
57 CUserAgentState* aAckSenderState) |
|
58 { |
|
59 CInviteUAC* self = new (ELeave) CInviteUAC(aParams, |
|
60 aConnectionMgr, |
|
61 aResolver, |
|
62 aSIPSec, |
|
63 aCSeqNumber, |
|
64 aIsPrivateAddress, |
|
65 aAckSenderState); |
|
66 CleanupStack::PushL(self); |
|
67 self->CUserAgent::ConstructL(aConnectionMgr); |
|
68 self->CUserAgentClient::ConstructL(); |
|
69 CleanupStack::Pop(self); |
|
70 return self; |
|
71 } |
|
72 |
|
73 // ----------------------------------------------------------------------------- |
|
74 // CInviteUAC::CInviteUAC |
|
75 // ----------------------------------------------------------------------------- |
|
76 // |
|
77 CInviteUAC::CInviteUAC(CUserAgentCreateParams& aParams, |
|
78 MSipConnectionMgr& aConnectionMgr, |
|
79 MSipUriResolver& aResolver, |
|
80 CSIPSec& aSIPSec, |
|
81 TUint32 aCSeqNumber, |
|
82 TBool aIsPrivateAddress, |
|
83 CUserAgentState* aAckSenderState) : |
|
84 CUserAgentClient(aParams, aResolver, aSIPSec, aCSeqNumber), |
|
85 iConnectionMgr(aConnectionMgr), |
|
86 iIsPrivateAddress(aIsPrivateAddress), |
|
87 iAckSenderState(aAckSenderState) |
|
88 #ifdef CPPUNIT_TEST |
|
89 , iAckSenders(1) |
|
90 #endif |
|
91 { |
|
92 } |
|
93 |
|
94 // ----------------------------------------------------------------------------- |
|
95 // CInviteUAC::~CInviteUAC |
|
96 // ----------------------------------------------------------------------------- |
|
97 // |
|
98 CInviteUAC::~CInviteUAC() |
|
99 { |
|
100 CancelAllTimers(); |
|
101 iAckSenders.ResetAndDestroy(); |
|
102 delete iDeleteThisTransaction; |
|
103 } |
|
104 |
|
105 // ----------------------------------------------------------------------------- |
|
106 // CInviteUAC::ReceiveResponseL |
|
107 // Application sends ACK (uses ITC) to 2xx, so stop transaction and enter next |
|
108 // state after PassRespToTransactionOwnerL, as ACK isn't sent inside it. |
|
109 // ----------------------------------------------------------------------------- |
|
110 // |
|
111 void CInviteUAC::ReceiveResponseL(CSIPResponse* aResp, |
|
112 const CUserAgentState& aResolve, |
|
113 const CUserAgentState& aWaitResponse, |
|
114 const CUserAgentState& aWaitAckFromApp, |
|
115 const CUserAgentState& aWaitTransactionToEnd) |
|
116 { |
|
117 __TEST_INVARIANT; |
|
118 __SIP_ASSERT_LEAVE(aResp, KErrArgument); |
|
119 __SIP_ASSERT_LEAVE(!iTimerWait2xxRetransmissions, KErrAlreadyExists); |
|
120 |
|
121 if (!ShouldUaTryAgainL(aResp, aResolve, aWaitResponse)) |
|
122 { |
|
123 CSIPResponse::TType type = aResp->Type(); |
|
124 if (type == CSIPResponse::E2XX) |
|
125 { |
|
126 // UAC treats INVITE transaction completed 64*T1 after the first |
|
127 // 2xx. Expire with KErrNone as UAC ends successfully. |
|
128 iTimerWait2xxRetransmissions = CTimerStopUA::NewL(iTimers, |
|
129 this, |
|
130 iTimerValues.Duration64xT1(), |
|
131 KErrNone); |
|
132 } |
|
133 PassRespToTransactionOwnerL(aResp, |
|
134 // If timer, set UA and timer pointers |
|
135 iTimerWait2xxRetransmissions ? this : NULL, |
|
136 iTimerWait2xxRetransmissions); |
|
137 if (type == CSIPResponse::E2XX) |
|
138 { |
|
139 StopTransaction(); |
|
140 ChangeState(aWaitAckFromApp); |
|
141 } |
|
142 else if (type == CSIPResponse::E1XX) |
|
143 { |
|
144 // Pass 1xx to upper layer |
|
145 } |
|
146 else |
|
147 { |
|
148 // Transaction sends ACK, UAC waits it to end |
|
149 ChangeState(aWaitTransactionToEnd); |
|
150 } |
|
151 } |
|
152 |
|
153 __TEST_INVARIANT; |
|
154 } |
|
155 |
|
156 // ----------------------------------------------------------------------------- |
|
157 // CInviteUAC::PrepareTxForNewRequestL |
|
158 // ----------------------------------------------------------------------------- |
|
159 // |
|
160 void CInviteUAC::PrepareTxForNewRequestL(TTransactionId& aNewTransactionId) |
|
161 |
|
162 { |
|
163 __TEST_INVARIANT; |
|
164 |
|
165 CTransmitter* transmitter = CTransmitter::NewL(iConnectionMgr); |
|
166 static_cast<CClientTransaction*>(iTransaction)-> |
|
167 RunIndependently(aNewTransactionId, &iDeleteMgr, EFalse); |
|
168 iTransmitter = transmitter; |
|
169 |
|
170 __TEST_INVARIANT; |
|
171 } |
|
172 |
|
173 // ----------------------------------------------------------------------------- |
|
174 // CInviteUAC::CreateTransactionL |
|
175 // ----------------------------------------------------------------------------- |
|
176 // |
|
177 void CInviteUAC::CreateTransactionL() |
|
178 { |
|
179 __TEST_INVARIANT; |
|
180 __SIP_ASSERT_LEAVE(!iTransaction, KErrAlreadyExists); |
|
181 |
|
182 iTransaction = iTransactionMgr.CreateTransactionL( |
|
183 CTransactionBase::KClientInviteTransaction, |
|
184 *this, |
|
185 *iTransmitter, |
|
186 iTimerValues, |
|
187 iIsPrivateAddress && !iRegistrations.IsOutboundProxy(NextHopL())); |
|
188 __TEST_INVARIANT; |
|
189 } |
|
190 |
|
191 // ----------------------------------------------------------------------------- |
|
192 // CInviteUAC::ClearTransactionOwner |
|
193 // ----------------------------------------------------------------------------- |
|
194 // |
|
195 void CInviteUAC::ClearTransactionOwner() |
|
196 { |
|
197 __TEST_INVARIANT; |
|
198 |
|
199 for (TInt i = 0; i < iAckSenders.Count(); i++) |
|
200 { |
|
201 iAckSenders[i]->ClearTransactionOwner(); |
|
202 } |
|
203 CUserAgent::ClearTransactionOwner(); |
|
204 |
|
205 __TEST_INVARIANT; |
|
206 } |
|
207 |
|
208 // ----------------------------------------------------------------------------- |
|
209 // CInviteUAC::DeleteTimer |
|
210 // ----------------------------------------------------------------------------- |
|
211 // |
|
212 void CInviteUAC::DeleteTimer(const CUserAgentTimer& aTimer) |
|
213 { |
|
214 __TEST_INVARIANT; |
|
215 |
|
216 if (&aTimer == iTimerWait2xxRetransmissions) |
|
217 { |
|
218 StopTimerUaTimeout(); |
|
219 } |
|
220 if (&aTimer == iSIPSecTimer) |
|
221 { |
|
222 StopTimerSIPSec(); |
|
223 } |
|
224 |
|
225 __TEST_INVARIANT; |
|
226 } |
|
227 |
|
228 // ----------------------------------------------------------------------------- |
|
229 // CInviteUAC::IsInviteUAC |
|
230 // ----------------------------------------------------------------------------- |
|
231 // |
|
232 TBool CInviteUAC::IsInviteUAC() const |
|
233 { |
|
234 __TEST_INVARIANT; |
|
235 return ETrue; |
|
236 } |
|
237 |
|
238 // ----------------------------------------------------------------------------- |
|
239 // CInviteUAC::IsSubInviteUAC |
|
240 // ----------------------------------------------------------------------------- |
|
241 // |
|
242 TBool CInviteUAC::IsSubInviteUAC() const |
|
243 { |
|
244 __TEST_INVARIANT; |
|
245 return iAckSenderState == NULL; |
|
246 } |
|
247 |
|
248 // ----------------------------------------------------------------------------- |
|
249 // CInviteUAC::IsCanceled |
|
250 // ----------------------------------------------------------------------------- |
|
251 // |
|
252 TBool CInviteUAC::IsCanceled() const |
|
253 { |
|
254 __TEST_INVARIANT; |
|
255 return iCanceled; |
|
256 } |
|
257 |
|
258 // ----------------------------------------------------------------------------- |
|
259 // CInviteUAC::StartSIPSecTimerL |
|
260 // ----------------------------------------------------------------------------- |
|
261 // |
|
262 void CInviteUAC::StartSIPSecTimerL() |
|
263 { |
|
264 __TEST_INVARIANT; |
|
265 __SIP_ASSERT_LEAVE(!iSIPSecTimer, KErrAlreadyExists); |
|
266 |
|
267 iSIPSecTimer = CTimerAsyncSIPSec::NewL(iTimers, this); |
|
268 |
|
269 __TEST_INVARIANT; |
|
270 } |
|
271 |
|
272 // ----------------------------------------------------------------------------- |
|
273 // CInviteUAC::SendAckL |
|
274 // ----------------------------------------------------------------------------- |
|
275 // |
|
276 void CInviteUAC::SendAckL(CSIPRequest* aAck, |
|
277 MTransactionOwner& aObserver, |
|
278 const TSIPTransportParams& aParams, |
|
279 TRegistrationId aRegisterId, |
|
280 const CURIContainer& aRemoteTarget, |
|
281 TBool aDeleteRequest, |
|
282 RStringF aBranch) |
|
283 { |
|
284 __TEST_INVARIANT; |
|
285 __SIP_ASSERT_LEAVE(aAck, KErrArgument); |
|
286 |
|
287 State().SendAckL(*this, |
|
288 aAck, |
|
289 aObserver, |
|
290 aParams, |
|
291 aRegisterId, |
|
292 aRemoteTarget, |
|
293 aDeleteRequest, |
|
294 aBranch); |
|
295 __TEST_INVARIANT; |
|
296 } |
|
297 |
|
298 // ----------------------------------------------------------------------------- |
|
299 // CInviteUAC::CancelInvite |
|
300 // ----------------------------------------------------------------------------- |
|
301 // |
|
302 void CInviteUAC::CancelInvite() |
|
303 { |
|
304 __TEST_INVARIANT; |
|
305 |
|
306 iCanceled = ETrue; |
|
307 |
|
308 __TEST_INVARIANT; |
|
309 } |
|
310 |
|
311 // ----------------------------------------------------------------------------- |
|
312 // CInviteUAC::CopyRouteHeadersToCancelL |
|
313 // ----------------------------------------------------------------------------- |
|
314 // |
|
315 void CInviteUAC::CopyRouteHeadersToCancelL(CSIPRequest& aCancel) |
|
316 { |
|
317 __TEST_INVARIANT; |
|
318 __SIP_ASSERT_LEAVE(iOutgoingMsg, KErrNotFound); |
|
319 |
|
320 CSIPMessageUtility::CopyHeadersL(*iOutgoingMsg, |
|
321 aCancel, |
|
322 SIPStrings::StringF(SipStrConsts::ERouteHeader)); |
|
323 __TEST_INVARIANT; |
|
324 } |
|
325 |
|
326 // ----------------------------------------------------------------------------- |
|
327 // CInviteUAC::HandleIcmpErrorL |
|
328 // Cancel send. If 2 UAs use same address, one gets ICMP error KErrSIPICMPFailure and its send ends |
|
329 // but the other can be active. Unless UA stops, pass ICMP error to "sub UACs". |
|
330 // ----------------------------------------------------------------------------- |
|
331 // |
|
332 void CInviteUAC::HandleIcmpErrorL(const TInetAddr& aAddress, |
|
333 const CUserAgentState& aResolveAckAddress, |
|
334 const CUserAgentState& aWaitResponse) |
|
335 { |
|
336 __TEST_INVARIANT; |
|
337 |
|
338 if (CSIPMessageUtility::CompareTInetAddr(iRemoteAddr, |
|
339 iTransportProtocol, |
|
340 aAddress)) |
|
341 { |
|
342 iTransmitter->Cancel(); |
|
343 TInt error = KErrSIPICMPFailure; |
|
344 if (!TryNextAddressL(error, aResolveAckAddress, aWaitResponse)) |
|
345 { |
|
346 Stop(error); |
|
347 return; |
|
348 } |
|
349 } |
|
350 |
|
351 for (TInt i = 0; i < iAckSenders.Count(); ++i) |
|
352 { |
|
353 // Use any error code. "sub UAC" stops with CSIP::ETransportFailure. |
|
354 iAckSenders[i]->IcmpErrorL(aAddress, |
|
355 CSipConnectionMgr::EHostUnreachable); |
|
356 } |
|
357 |
|
358 __TEST_INVARIANT; |
|
359 } |
|
360 |
|
361 // ----------------------------------------------------------------------------- |
|
362 // CInviteUAC::CheckAckL |
|
363 // Application must fill To-header, as many 2xx (each with a unique To-tag) can |
|
364 // arrive and UAC won't know which tag to put in To-header. |
|
365 // ----------------------------------------------------------------------------- |
|
366 // |
|
367 void CInviteUAC::CheckAckL(CSIPRequest& aAck) const |
|
368 { |
|
369 __TEST_INVARIANT; |
|
370 |
|
371 if (!aAck.HasHeader(SIPStrings::StringF(SipStrConsts::EToHeader)) || |
|
372 aAck.HasHeader(SIPStrings::StringF(SipStrConsts::EViaHeader))) |
|
373 { |
|
374 User::Leave(KErrSIPMalformedMessage); |
|
375 } |
|
376 } |
|
377 |
|
378 // ----------------------------------------------------------------------------- |
|
379 // CInviteUAC::FillAckL |
|
380 // ----------------------------------------------------------------------------- |
|
381 // |
|
382 void CInviteUAC::FillAckL(CSIPRequest& aAck, RStringF aBranch) |
|
383 { |
|
384 __TEST_INVARIANT; |
|
385 __SIP_ASSERT_LEAVE(iRemoteTarget, KErrNotFound); |
|
386 |
|
387 SIPRequestUtility::FillRouteAndRequestUriL(aAck, |
|
388 *iRouteSet, |
|
389 *iRemoteTarget); |
|
390 // Copy From-header before Contact-headers are handled |
|
391 iTransactionStore.CopyHeadersToRequestL(TransactionId(), |
|
392 aAck, |
|
393 EFalse, // Request-URI already set |
|
394 EFalse);// Don't copy Via |
|
395 CheckContactHeadersL(aAck, aAck.From()); |
|
396 |
|
397 if (!aAck.HasHeader(SIPStrings::StringF(SipStrConsts::EMaxForwardsHeader))) |
|
398 { |
|
399 SIPRequestUtility::FillNewMaxForwardsL(aAck); |
|
400 } |
|
401 |
|
402 FillNewViaL(aAck, aBranch); |
|
403 // "sub UAC" has no iOutgoingMsg, but the authorization headers have already |
|
404 // been copied from the first ACK. |
|
405 CSIPMessageUtility::CopyAuthorizationHeadersL(iOutgoingMsg, aAck); |
|
406 SIPRequestUtility::FillSupportedSecAgreeL(aAck); |
|
407 |
|
408 __TEST_INVARIANT; |
|
409 } |
|
410 |
|
411 // ----------------------------------------------------------------------------- |
|
412 // CInviteUAC::AckAddressResolvedL |
|
413 // Remote address must exist. |
|
414 // ----------------------------------------------------------------------------- |
|
415 // |
|
416 void CInviteUAC::AckAddressResolvedL() |
|
417 { |
|
418 __TEST_INVARIANT; |
|
419 __SIP_ASSERT_LEAVE(SelectNextRemoteAddressL(), KErrNotFound); |
|
420 |
|
421 if (FillSecurityParamsL()) |
|
422 { |
|
423 SendRequestToNetworkL(); |
|
424 } |
|
425 |
|
426 __TEST_INVARIANT; |
|
427 } |
|
428 |
|
429 // ----------------------------------------------------------------------------- |
|
430 // CInviteUAC::SendFirstAckL |
|
431 // Clear INVITE's route set and resolving results before resolving ACK address. |
|
432 // ----------------------------------------------------------------------------- |
|
433 // |
|
434 void CInviteUAC::SendFirstAckL(CSIPRequest* aAck, |
|
435 MTransactionOwner& aObserver, |
|
436 const TSIPTransportParams& aParams, |
|
437 TRegistrationId aRegisterId, |
|
438 const CURIContainer& aRemoteTarget, |
|
439 TBool aDeleteRequest, |
|
440 RStringF aBranch) |
|
441 { |
|
442 __TEST_INVARIANT; |
|
443 __SIP_ASSERT_LEAVE(aAck, KErrArgument); |
|
444 __SIP_ASSERT_LEAVE(!iObserverForFirstAck, KErrAlreadyExists); |
|
445 // Main-UAC must always use a new branch |
|
446 if (iAckSenderState && aBranch != SIPStrings::StringF(SipStrConsts::EEmpty)) |
|
447 { |
|
448 User::Leave(KErrArgument); |
|
449 } |
|
450 |
|
451 iObserver = &aObserver; |
|
452 iObserverForFirstAck = &aObserver; |
|
453 iRegisterId = aRegisterId; |
|
454 iTransportParams = aParams; |
|
455 |
|
456 CheckAckL(*aAck); |
|
457 StoreRemoteTargetL(aRemoteTarget); |
|
458 |
|
459 delete iRouteSet; |
|
460 iRouteSet = NULL; |
|
461 iRouteSet = CRouteSet::NewL(*aAck, iRegistrations, iRegisterId); |
|
462 |
|
463 FillAckL(*aAck, aBranch); |
|
464 StoreRequestUriL(*aAck); |
|
465 |
|
466 iResolvingResults->ClearAll(); |
|
467 ResolveNextHopL(ETrue); |
|
468 |
|
469 StoreOutgoingMsg(aAck); |
|
470 SetRequestOwnership(aDeleteRequest); |
|
471 |
|
472 __TEST_INVARIANT; |
|
473 } |
|
474 |
|
475 // ----------------------------------------------------------------------------- |
|
476 // CInviteUAC::SendAdditionalAckL |
|
477 // Get branch value before updating observer. Don't update iObserverForFirstAck. |
|
478 // ----------------------------------------------------------------------------- |
|
479 // |
|
480 void CInviteUAC::SendAdditionalAckL(CSIPRequest* aAck, |
|
481 MTransactionOwner& aObserver, |
|
482 const TSIPTransportParams& aParams, |
|
483 TRegistrationId aRegisterId, |
|
484 const CURIContainer& aRemoteTarget, |
|
485 TBool aDeleteRequest) |
|
486 { |
|
487 __TEST_INVARIANT; |
|
488 __SIP_ASSERT_LEAVE(aAck, KErrArgument); |
|
489 |
|
490 iObserver = &aObserver; |
|
491 iRegisterId = aRegisterId; |
|
492 |
|
493 CUserAgentCreateParams* params = |
|
494 CUserAgentCreateParams::NewLC(iTransactionMgr, |
|
495 iTimers, |
|
496 iSIPMsgUtility, |
|
497 iTimerValues, |
|
498 iRegistrations, |
|
499 iRegistrationContact, |
|
500 iSigComp, |
|
501 iTransactionStore, |
|
502 iDeleteMgr, |
|
503 aDeleteRequest, |
|
504 aParams); |
|
505 params->iTransactionId = TransactionId(); |
|
506 params->iObserver = iObserver; |
|
507 params->iInitialUaState = iAckSenderState; |
|
508 |
|
509 CInviteUAC* subUac = |
|
510 CInviteUAC::NewL(*params, |
|
511 iConnectionMgr, |
|
512 iResolver, |
|
513 iSIPSec, |
|
514 0, // CSeq value not used for ACK |
|
515 iIsPrivateAddress, // Not used for ACK |
|
516 NULL); // State is NULL for "sub UAC" |
|
517 CleanupStack::PopAndDestroy(params); |
|
518 CleanupStack::PushL(subUac); |
|
519 iAckSenders.AppendL(subUac); |
|
520 CleanupStack::Pop(subUac); |
|
521 |
|
522 CSIPMessageUtility::CopyAuthorizationHeadersL(iOutgoingMsg, *aAck); |
|
523 subUac->SendAckL(aAck, |
|
524 *iObserver, |
|
525 aParams, |
|
526 iRegisterId, |
|
527 aRemoteTarget, |
|
528 aDeleteRequest, |
|
529 SelectBranchToUse(aObserver)); |
|
530 __TEST_INVARIANT; |
|
531 } |
|
532 |
|
533 // ----------------------------------------------------------------------------- |
|
534 // CInviteUAC::HandleAdditional2xxL |
|
535 // SIPSec must handle 2xx synchronously. PassRespToTransactionOwnerL allows only |
|
536 // one final response, so use PassMsgToTransactionOwnerL. Drop other responses. |
|
537 // ----------------------------------------------------------------------------- |
|
538 // |
|
539 void CInviteUAC::HandleAdditional2xxL(CSIPResponse* aResp) |
|
540 { |
|
541 __TEST_INVARIANT; |
|
542 __SIP_ASSERT_LEAVE(aResp, KErrArgument); |
|
543 |
|
544 if (aResp->Type() == CSIPResponse::E2XX) |
|
545 { |
|
546 __SIP_ASSERT_LEAVE(!PassResponseToSIPSecL(*aResp), KErrGeneral); |
|
547 PassMsgToTransactionOwnerL(aResp); |
|
548 } |
|
549 else |
|
550 { |
|
551 delete aResp; |
|
552 } |
|
553 } |
|
554 |
|
555 // ----------------------------------------------------------------------------- |
|
556 // CInviteUAC::Ptr |
|
557 // ----------------------------------------------------------------------------- |
|
558 // |
|
559 CInviteUAC& CInviteUAC::Ptr(CUserAgent& aUserAgent) |
|
560 { |
|
561 return static_cast<CInviteUAC&>(aUserAgent); |
|
562 } |
|
563 |
|
564 // ----------------------------------------------------------------------------- |
|
565 // CInviteUAC::StopTransaction |
|
566 // Even if AddDeleteRequest fails, transaction is detached and won't receive |
|
567 // messages. Transaction doesn't know its id, so write log here. |
|
568 // ----------------------------------------------------------------------------- |
|
569 // |
|
570 void CInviteUAC::StopTransaction() |
|
571 { |
|
572 __TEST_INVARIANT; |
|
573 __SIP_ASSERT_RETURN(iTransaction, KErrNotFound); |
|
574 __SIP_ASSERT_RETURN(!iDeleteThisTransaction, KErrAlreadyExists); |
|
575 |
|
576 // Prevent transaction from calling TransactionEndsL |
|
577 iTransaction->DetachFromUserAgent(); |
|
578 iTransaction->Terminated(); |
|
579 __SIP_INT_LOG1("TU transaction state=Terminated, taID", TransactionId() ) |
|
580 |
|
581 if (iDeleteMgr.AddDeleteRequest(iTransaction) != KErrNone) |
|
582 { |
|
583 iDeleteThisTransaction = iTransaction; |
|
584 } |
|
585 iTransaction = NULL; |
|
586 iTransactionStore.ClearTransaction(TransactionId()); |
|
587 |
|
588 __TEST_INVARIANT; |
|
589 } |
|
590 |
|
591 // ----------------------------------------------------------------------------- |
|
592 // CInviteUAC::StopTimerUaTimeout |
|
593 // ----------------------------------------------------------------------------- |
|
594 // |
|
595 void CInviteUAC::StopTimerUaTimeout() |
|
596 { |
|
597 __TEST_INVARIANT; |
|
598 |
|
599 delete iTimerWait2xxRetransmissions; |
|
600 iTimerWait2xxRetransmissions = NULL; |
|
601 |
|
602 __TEST_INVARIANT; |
|
603 } |
|
604 |
|
605 // ----------------------------------------------------------------------------- |
|
606 // CInviteUAC::StopTimerSIPSec |
|
607 // ----------------------------------------------------------------------------- |
|
608 // |
|
609 void CInviteUAC::StopTimerSIPSec() |
|
610 { |
|
611 __TEST_INVARIANT; |
|
612 |
|
613 delete iSIPSecTimer; |
|
614 iSIPSecTimer = NULL; |
|
615 |
|
616 __TEST_INVARIANT; |
|
617 } |
|
618 |
|
619 // ----------------------------------------------------------------------------- |
|
620 // CInviteUAC::CancelAllTimers |
|
621 // ----------------------------------------------------------------------------- |
|
622 // |
|
623 void CInviteUAC::CancelAllTimers() |
|
624 { |
|
625 __TEST_INVARIANT; |
|
626 |
|
627 StopTimerUaTimeout(); |
|
628 StopTimerSIPSec(); |
|
629 |
|
630 __TEST_INVARIANT; |
|
631 } |
|
632 |
|
633 // ----------------------------------------------------------------------------- |
|
634 // CInviteUAC::SelectBranchToUse |
|
635 // ----------------------------------------------------------------------------- |
|
636 // |
|
637 RStringF CInviteUAC::SelectBranchToUse(MTransactionOwner& aObserver) const |
|
638 { |
|
639 __TEST_INVARIANT; |
|
640 |
|
641 const RStringF KEmpty = SIPStrings::StringF(SipStrConsts::EEmpty); |
|
642 RStringF branch = UsedBranch(aObserver); |
|
643 |
|
644 for (TInt i = 0; branch == KEmpty && i < iAckSenders.Count(); ++i) |
|
645 { |
|
646 branch = iAckSenders[i]->UsedBranch(aObserver); |
|
647 } |
|
648 return branch; |
|
649 } |
|
650 |
|
651 // ----------------------------------------------------------------------------- |
|
652 // CInviteUAC::UsedBranch |
|
653 // ----------------------------------------------------------------------------- |
|
654 // |
|
655 RStringF CInviteUAC::UsedBranch(MTransactionOwner& aObserver) const |
|
656 { |
|
657 __TEST_INVARIANT; |
|
658 |
|
659 if ((&aObserver == iObserverForFirstAck) && iOutgoingMsg) |
|
660 { |
|
661 const RStringF KBranch = SIPStrings::StringF(SipStrConsts::EBranch); |
|
662 CSIPViaHeader* via = CSIPMessageUtility::TopVia(*iOutgoingMsg); |
|
663 if (via && via->HasParam(KBranch)) |
|
664 { |
|
665 return via->ParamValue(KBranch); |
|
666 } |
|
667 } |
|
668 return SIPStrings::StringF(SipStrConsts::EEmpty); |
|
669 } |
|
670 |
|
671 // ----------------------------------------------------------------------------- |
|
672 // CInviteUAC::SetSipSecError |
|
673 // ----------------------------------------------------------------------------- |
|
674 // |
|
675 void CInviteUAC::SetSipSecError(TInt aErr) |
|
676 { |
|
677 iSipSecError = aErr; |
|
678 } |
|
679 |
|
680 // ----------------------------------------------------------------------------- |
|
681 // CInviteUAC::__DbgTestInvariant |
|
682 // ----------------------------------------------------------------------------- |
|
683 // |
|
684 |
|
685 void CInviteUAC::__DbgTestInvariant() const |
|
686 { |
|
687 // A "sub UAC" can't have "sub UACs" or timer |
|
688 if (!iAckSenderState && |
|
689 (iAckSenders.Count() > 0 || |
|
690 iTimerWait2xxRetransmissions || |
|
691 iSIPSecTimer)) |
|
692 { |
|
693 User::Invariant(); |
|
694 } |
|
695 } |