|
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 // Name : SipDialogImplementation.cpp |
|
15 // Part of : SIPAPI |
|
16 // Version : SIP/6.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include <uri8.h> |
|
22 #include "siperr.h" |
|
23 #include "SipAssert.h" |
|
24 #include "SipDialogImplementation.h" |
|
25 #include "SipDialogAssocImplementation.h" |
|
26 #include "sipinvitedialogassoc.h" |
|
27 #include "sipsubscribedialogassoc.h" |
|
28 #include "sipdialogstate.h" |
|
29 #include "sipmessageelements.h" |
|
30 #include "siprequestelements.h" |
|
31 #include "sipresponseelements.h" |
|
32 #include "SipConnectionImplementation.h" |
|
33 #include "sipclientconnection.h" |
|
34 #include "sipinviteclienttransaction.h" |
|
35 #include "sipservertransaction.h" |
|
36 #include "sipregistrationcontext.h" |
|
37 #include "siprefresh.h" |
|
38 #include "sipaddress.h" |
|
39 #include "sipfromheader.h" |
|
40 #include "siptoheader.h" |
|
41 #include "sipcontactheader.h" |
|
42 #include "sipcallidheader.h" |
|
43 #include "sip.h" |
|
44 #include "SipImplementation.h" |
|
45 #include "sipstrings.h" |
|
46 #include "sipstrconsts.h" |
|
47 |
|
48 #ifdef CPPUNIT_TEST |
|
49 #include "TestCleanupStack.h" |
|
50 #endif |
|
51 |
|
52 |
|
53 // ----------------------------------------------------------------------------- |
|
54 // CSIPDialogImplementation::NewLC |
|
55 // ----------------------------------------------------------------------------- |
|
56 // |
|
57 CSIPDialogImplementation* CSIPDialogImplementation::NewLC( |
|
58 CSIPConnectionImplementation& aConnImplementation, |
|
59 const MSIPRegistrationContext* aContext) |
|
60 { |
|
61 CSIPDialog* dialog = aContext ? |
|
62 CSIPDialog::NewL(aConnImplementation, *aContext) : |
|
63 CSIPDialog::NewL(aConnImplementation); |
|
64 |
|
65 CSIPDialogImplementation* self = &dialog->Implementation(); |
|
66 CleanupStack::PushL(self); |
|
67 return self; |
|
68 } |
|
69 |
|
70 // ----------------------------------------------------------------------------- |
|
71 // CSIPDialogImplementation::NewL |
|
72 // ----------------------------------------------------------------------------- |
|
73 // |
|
74 CSIPDialogImplementation* CSIPDialogImplementation::NewL( |
|
75 CSIPDialog* aDialog, |
|
76 CSIPConnectionImplementation& aConnImplementation) |
|
77 { |
|
78 CSIPDialogImplementation* self = |
|
79 new (ELeave) CSIPDialogImplementation(aConnImplementation); |
|
80 CleanupStack::PushL(self); |
|
81 self->ConstructL(aDialog); |
|
82 CleanupStack::Pop(self); |
|
83 return self; |
|
84 } |
|
85 |
|
86 // ----------------------------------------------------------------------------- |
|
87 // CSIPDialogImplementation::NewL |
|
88 // ----------------------------------------------------------------------------- |
|
89 // |
|
90 CSIPDialogImplementation* CSIPDialogImplementation::NewL( |
|
91 CSIPDialog* aDialog, |
|
92 CSIPConnectionImplementation& aConnImplementation, |
|
93 const MSIPRegistrationContext& aContext) |
|
94 { |
|
95 CSIPDialogImplementation* self = |
|
96 new (ELeave) CSIPDialogImplementation(aConnImplementation, aContext); |
|
97 CleanupStack::PushL(self); |
|
98 self->ConstructL(aDialog); |
|
99 CleanupStack::Pop(self); |
|
100 return self; |
|
101 } |
|
102 |
|
103 // ----------------------------------------------------------------------------- |
|
104 // CSIPDialogImplementation::CSIPDialogImplementation |
|
105 // ----------------------------------------------------------------------------- |
|
106 // |
|
107 CSIPDialogImplementation::CSIPDialogImplementation( |
|
108 CSIPConnectionImplementation& aConnImplementation) : |
|
109 iConnection(&aConnImplementation) |
|
110 #ifdef CPPUNIT_TEST |
|
111 , iDialogAssocs(1) |
|
112 #endif |
|
113 { |
|
114 } |
|
115 |
|
116 // ----------------------------------------------------------------------------- |
|
117 // CSIPDialogImplementation::CSIPDialogImplementation |
|
118 // ----------------------------------------------------------------------------- |
|
119 // |
|
120 CSIPDialogImplementation::CSIPDialogImplementation( |
|
121 CSIPConnectionImplementation& aConnImplementation, |
|
122 const MSIPRegistrationContext& aContext) : |
|
123 iConnection(&aConnImplementation), |
|
124 iRegistration(&aContext) |
|
125 #ifdef CPPUNIT_TEST |
|
126 , iDialogAssocs(1) |
|
127 #endif |
|
128 , iStringPoolOpened(EFalse) |
|
129 { |
|
130 } |
|
131 |
|
132 // ----------------------------------------------------------------------------- |
|
133 // CSIPDialogImplementation::ConstructL |
|
134 // ----------------------------------------------------------------------------- |
|
135 // |
|
136 void CSIPDialogImplementation::ConstructL(CSIPDialog* aDialog) |
|
137 { |
|
138 CheckConnectionL(); |
|
139 iConnection->AddDialogL(*this); |
|
140 iState = iConnection->InitialDialogStateL(); |
|
141 iDialog = aDialog; |
|
142 |
|
143 SIPStrings::OpenL(); |
|
144 iStringPoolOpened = ETrue; |
|
145 } |
|
146 |
|
147 // ----------------------------------------------------------------------------- |
|
148 // CSIPDialogImplementation::~CSIPDialogImplementation |
|
149 // ----------------------------------------------------------------------------- |
|
150 // |
|
151 CSIPDialogImplementation::~CSIPDialogImplementation() |
|
152 { |
|
153 if (iConnection) |
|
154 { |
|
155 iConnection->RemoveDialog(*this); |
|
156 } |
|
157 |
|
158 iDialogAssocs.Reset(); |
|
159 |
|
160 delete iDialog; |
|
161 delete iFrom; |
|
162 delete iTo; |
|
163 delete iRemoteUri; |
|
164 delete iContact; |
|
165 delete iCallID; |
|
166 |
|
167 if (iStringPoolOpened) |
|
168 { |
|
169 SIPStrings::Close(); |
|
170 } |
|
171 } |
|
172 |
|
173 // ----------------------------------------------------------------------------- |
|
174 // CSIPDialogImplementation::State |
|
175 // ----------------------------------------------------------------------------- |
|
176 // |
|
177 CSIPDialog::TState CSIPDialogImplementation::State() const |
|
178 { |
|
179 __TEST_INVARIANT; |
|
180 return iState ? iState->State() : CSIPDialog::ETerminated; |
|
181 } |
|
182 |
|
183 // ----------------------------------------------------------------------------- |
|
184 // CSIPDialogImplementation::ChangeState |
|
185 // ----------------------------------------------------------------------------- |
|
186 // |
|
187 void CSIPDialogImplementation::ChangeState(const CDialogState* aNewState) |
|
188 { |
|
189 __TEST_INVARIANT; |
|
190 |
|
191 iState = aNewState; |
|
192 |
|
193 __TEST_INVARIANT; |
|
194 } |
|
195 |
|
196 // ----------------------------------------------------------------------------- |
|
197 // CSIPDialogImplementation::ConnectionLost |
|
198 // ----------------------------------------------------------------------------- |
|
199 // |
|
200 void CSIPDialogImplementation::ConnectionLost() |
|
201 { |
|
202 __TEST_INVARIANT; |
|
203 |
|
204 if (iState) |
|
205 { |
|
206 iState->ConnectionLost(*this); |
|
207 } |
|
208 |
|
209 for (TInt i = 0; i < iDialogAssocs.Count(); ++i) |
|
210 { |
|
211 iDialogAssocs[i]->Implementation().ConnectionLost(); |
|
212 } |
|
213 |
|
214 __TEST_INVARIANT; |
|
215 } |
|
216 |
|
217 // ----------------------------------------------------------------------------- |
|
218 // CSIPDialogImplementation::SIPDialogAssociations |
|
219 // ----------------------------------------------------------------------------- |
|
220 // |
|
221 const RPointerArray<CSIPDialogAssocBase>& |
|
222 CSIPDialogImplementation::SIPDialogAssociations() const |
|
223 { |
|
224 __TEST_INVARIANT; |
|
225 return iDialogAssocs; |
|
226 } |
|
227 |
|
228 // ----------------------------------------------------------------------------- |
|
229 // CSIPDialogImplementation::RegistrationContext |
|
230 // ----------------------------------------------------------------------------- |
|
231 // |
|
232 const MSIPRegistrationContext* |
|
233 CSIPDialogImplementation::RegistrationContext() const |
|
234 { |
|
235 __TEST_INVARIANT; |
|
236 return iRegistration; |
|
237 } |
|
238 |
|
239 // ----------------------------------------------------------------------------- |
|
240 // CSIPDialogImplementation::IsAssociated |
|
241 // ----------------------------------------------------------------------------- |
|
242 // |
|
243 TBool |
|
244 CSIPDialogImplementation::IsAssociated(const CSIPDialogAssocBase& aAssoc) const |
|
245 { |
|
246 __TEST_INVARIANT; |
|
247 |
|
248 for (TInt i = 0; i < iDialogAssocs.Count(); ++i) |
|
249 { |
|
250 if (iDialogAssocs[i] == &aAssoc) |
|
251 { |
|
252 return ETrue; |
|
253 } |
|
254 } |
|
255 |
|
256 return EFalse; |
|
257 } |
|
258 |
|
259 // ----------------------------------------------------------------------------- |
|
260 // CSIPDialogImplementation::Connection |
|
261 // ----------------------------------------------------------------------------- |
|
262 // |
|
263 CSIPConnection* CSIPDialogImplementation::Connection() |
|
264 { |
|
265 return GetConnection(); |
|
266 } |
|
267 |
|
268 // ----------------------------------------------------------------------------- |
|
269 // CSIPDialogImplementation::Connection |
|
270 // ----------------------------------------------------------------------------- |
|
271 // |
|
272 const CSIPConnection* CSIPDialogImplementation::Connection() const |
|
273 { |
|
274 return GetConnection(); |
|
275 } |
|
276 |
|
277 // ----------------------------------------------------------------------------- |
|
278 // CSIPDialogImplementation::GetConnection |
|
279 // ----------------------------------------------------------------------------- |
|
280 // |
|
281 CSIPConnection* CSIPDialogImplementation::GetConnection() const |
|
282 { |
|
283 __TEST_INVARIANT; |
|
284 |
|
285 CSIPConnection* conn = NULL; |
|
286 if (iConnection) |
|
287 { |
|
288 TRAP_IGNORE((conn = &iConnection->SIPConnectionL())) |
|
289 } |
|
290 return conn; |
|
291 } |
|
292 |
|
293 // ----------------------------------------------------------------------------- |
|
294 // CSIPDialogImplementation::FromHeader |
|
295 // ----------------------------------------------------------------------------- |
|
296 // |
|
297 const CSIPFromHeader& CSIPDialogImplementation::FromHeader() const |
|
298 { |
|
299 __TEST_INVARIANT; |
|
300 return *iFrom; |
|
301 } |
|
302 |
|
303 // ----------------------------------------------------------------------------- |
|
304 // CSIPDialogImplementation::ToHeader |
|
305 // ----------------------------------------------------------------------------- |
|
306 // |
|
307 const CSIPToHeader& CSIPDialogImplementation::ToHeader() const |
|
308 { |
|
309 __TEST_INVARIANT; |
|
310 return *iTo; |
|
311 } |
|
312 |
|
313 // ----------------------------------------------------------------------------- |
|
314 // CSIPDialogImplementation::RemoteURI |
|
315 // ----------------------------------------------------------------------------- |
|
316 // |
|
317 const CUri8& CSIPDialogImplementation::RemoteURI() const |
|
318 { |
|
319 __ASSERT_DEBUG(iRemoteUri, |
|
320 User::Panic(_L("CSIPDlgImp:RemoteURI"), KErrNotFound)); |
|
321 return *iRemoteUri; |
|
322 } |
|
323 |
|
324 // ----------------------------------------------------------------------------- |
|
325 // CSIPDialogImplementation::CallIdL |
|
326 // If Call-ID doesn't exist yet, application has asked it too early. |
|
327 // ----------------------------------------------------------------------------- |
|
328 // |
|
329 const CSIPCallIDHeader& CSIPDialogImplementation::CallIdL() const |
|
330 { |
|
331 __ASSERT_ALWAYS(iCallID, User::Leave(KErrSIPInvalidDialogState)); |
|
332 return *iCallID; |
|
333 } |
|
334 |
|
335 // ----------------------------------------------------------------------------- |
|
336 // CSIPDialogImplementation::StoreCallIdL |
|
337 // ----------------------------------------------------------------------------- |
|
338 // |
|
339 void CSIPDialogImplementation::StoreCallIdL() |
|
340 { |
|
341 __TEST_INVARIANT; |
|
342 __SIP_ASSERT_LEAVE(iDialogId != 0, KErrNotFound); |
|
343 CheckConnectionL(); |
|
344 |
|
345 CSIPCallIDHeader* tmp = iConnection->ClientConnectionL().CallIDL(iDialogId); |
|
346 delete iCallID; |
|
347 iCallID = tmp; |
|
348 } |
|
349 |
|
350 // ----------------------------------------------------------------------------- |
|
351 // CSIPDialogImplementation::CopyCallIdL |
|
352 // ----------------------------------------------------------------------------- |
|
353 // |
|
354 void CSIPDialogImplementation::CopyCallIdL( |
|
355 const CSIPDialogImplementation& aDialog) |
|
356 { |
|
357 __TEST_INVARIANT; |
|
358 |
|
359 CSIPCallIDHeader* tmp = |
|
360 static_cast<CSIPCallIDHeader*>(aDialog.CallIdL().CloneL()); |
|
361 delete iCallID; |
|
362 iCallID = tmp; |
|
363 } |
|
364 |
|
365 // ----------------------------------------------------------------------------- |
|
366 // CSIPDialogImplementation::operator== |
|
367 // ----------------------------------------------------------------------------- |
|
368 // |
|
369 TBool CSIPDialogImplementation::operator==( |
|
370 const CSIPDialogImplementation& aDialog) const |
|
371 { |
|
372 __TEST_INVARIANT; |
|
373 return this == &aDialog || |
|
374 (iDialogId && aDialog.iDialogId && (iDialogId == aDialog.iDialogId)); |
|
375 } |
|
376 |
|
377 // ----------------------------------------------------------------------------- |
|
378 // CSIPDialogImplementation::ReuseInitialRequestData |
|
379 // ----------------------------------------------------------------------------- |
|
380 // |
|
381 TInt CSIPDialogImplementation::ReuseInitialRequestData() |
|
382 { |
|
383 TInt err = KErrSIPInvalidDialogState; |
|
384 |
|
385 if (iState && iState->State() == CSIPDialog::ETerminated && |
|
386 iConnection && iConnection->SIP() && iConnection->ClientConnection()) |
|
387 { |
|
388 TUint32 originalRequestId = iInitialRequestId; |
|
389 iInitialRequestId = 0; |
|
390 const CDialogState* originalState = iState; |
|
391 iState = iConnection->SIP()->Implementation().InitialDialogState(); |
|
392 err = iConnection->ClientConnection()->ResetDialogState(iDialogId); |
|
393 if (err != KErrNone) |
|
394 { |
|
395 // Rollback to the original state |
|
396 iInitialRequestId = originalRequestId; |
|
397 iState = originalState; |
|
398 } |
|
399 else |
|
400 { |
|
401 iTo->DeleteParam(SIPStrings::StringF(SipStrConsts::ETag)); |
|
402 } |
|
403 } |
|
404 |
|
405 return err; |
|
406 } |
|
407 |
|
408 // ----------------------------------------------------------------------------- |
|
409 // CSIPDialogImplementation::Dialog |
|
410 // Don't use invariant here. |
|
411 // ----------------------------------------------------------------------------- |
|
412 // |
|
413 CSIPDialog& CSIPDialogImplementation::Dialog() |
|
414 { |
|
415 __ASSERT_DEBUG(iDialog, User::Panic(_L("CSIPDlgImp:Dialog"), KErrNotFound)); |
|
416 return *iDialog; |
|
417 } |
|
418 |
|
419 // ----------------------------------------------------------------------------- |
|
420 // CSIPDialogImplementation::IncomingResponseL |
|
421 // ----------------------------------------------------------------------------- |
|
422 // |
|
423 TBool |
|
424 CSIPDialogImplementation::IncomingResponseL(CSIPResponseElements* aElements, |
|
425 TUint32 aRequestId, |
|
426 TUint32 aDialogId, |
|
427 CConnectionCallback& aCallback) |
|
428 { |
|
429 __TEST_INVARIANT; |
|
430 __SIP_ASSERT_LEAVE(aElements != NULL, KErrArgument); |
|
431 |
|
432 if (iState) |
|
433 { |
|
434 return iState->IncomingResponseL(*this, |
|
435 aElements, |
|
436 aRequestId, |
|
437 aDialogId, |
|
438 aCallback); |
|
439 } |
|
440 delete aElements; |
|
441 return EFalse; |
|
442 } |
|
443 |
|
444 // ----------------------------------------------------------------------------- |
|
445 // CSIPDialogImplementation::IncomingResponseL |
|
446 // ----------------------------------------------------------------------------- |
|
447 // |
|
448 TBool |
|
449 CSIPDialogImplementation::IncomingResponseL(CSIPResponseElements* aElements, |
|
450 TUint32 aRequestId, |
|
451 TUint32 aRefreshId, |
|
452 TUint32 aDialogId, |
|
453 CConnectionCallback& aCallback) |
|
454 { |
|
455 __TEST_INVARIANT; |
|
456 __SIP_ASSERT_LEAVE(aElements != NULL, KErrArgument); |
|
457 |
|
458 if (iState) |
|
459 { |
|
460 return iState->IncomingResponseL(*this, |
|
461 aElements, |
|
462 aRequestId, |
|
463 aRefreshId, |
|
464 aDialogId, |
|
465 aCallback); |
|
466 } |
|
467 delete aElements; |
|
468 return EFalse; |
|
469 } |
|
470 |
|
471 // ----------------------------------------------------------------------------- |
|
472 // CSIPDialogImplementation::IncomingRequest |
|
473 // ----------------------------------------------------------------------------- |
|
474 // |
|
475 TBool CSIPDialogImplementation::IncomingRequestL( |
|
476 CSIPServerTransaction* aTransaction, |
|
477 CConnectionCallback& aCallback) |
|
478 { |
|
479 __TEST_INVARIANT; |
|
480 __SIP_ASSERT_LEAVE(aTransaction != NULL, KErrArgument); |
|
481 |
|
482 if (iState) |
|
483 { |
|
484 return iState->IncomingRequestL(*this, aTransaction, aCallback); |
|
485 } |
|
486 delete aTransaction; |
|
487 return EFalse; |
|
488 } |
|
489 |
|
490 // ----------------------------------------------------------------------------- |
|
491 // CSIPDialogImplementation::ErrorOccured |
|
492 // ----------------------------------------------------------------------------- |
|
493 // |
|
494 TBool CSIPDialogImplementation::ErrorOccured(TInt aError, |
|
495 TUint32 aRequestId, |
|
496 CConnectionCallback& aCallback) |
|
497 { |
|
498 __TEST_INVARIANT; |
|
499 return iState && |
|
500 iState->ErrorOccured(*this, aError, aRequestId, aCallback); |
|
501 } |
|
502 |
|
503 // ----------------------------------------------------------------------------- |
|
504 // CSIPDialogImplementation::ErrorOccured |
|
505 // ----------------------------------------------------------------------------- |
|
506 // |
|
507 TBool CSIPDialogImplementation::ErrorOccured(TInt aError, |
|
508 TUint32 aRefreshId, |
|
509 TUint32 aRequestId, |
|
510 CConnectionCallback& aCallback) |
|
511 { |
|
512 __TEST_INVARIANT; |
|
513 return iState && |
|
514 iState->ErrorOccured(*this, aError, aRefreshId, aRequestId, aCallback); |
|
515 } |
|
516 |
|
517 // ----------------------------------------------------------------------------- |
|
518 // CSIPDialogImplementation::DialogId |
|
519 // Don't use invariant here. |
|
520 // ----------------------------------------------------------------------------- |
|
521 // |
|
522 TUint32 CSIPDialogImplementation::DialogId() const |
|
523 { |
|
524 return iDialogId; |
|
525 } |
|
526 |
|
527 // ----------------------------------------------------------------------------- |
|
528 // CSIPDialogImplementation::SetDialogId |
|
529 // ----------------------------------------------------------------------------- |
|
530 // |
|
531 void CSIPDialogImplementation::SetDialogId(TUint32 aDialogId) |
|
532 { |
|
533 __TEST_INVARIANT; |
|
534 |
|
535 iDialogId = aDialogId; |
|
536 |
|
537 __TEST_INVARIANT; |
|
538 } |
|
539 |
|
540 // ----------------------------------------------------------------------------- |
|
541 // CSIPDialogImplementation::FindTransaction |
|
542 // ----------------------------------------------------------------------------- |
|
543 // |
|
544 CSIPTransactionBase* |
|
545 CSIPDialogImplementation::FindTransaction(TUint32 aRequestId) const |
|
546 { |
|
547 __TEST_INVARIANT; |
|
548 |
|
549 CSIPTransactionBase* ta = NULL; |
|
550 for (TInt i = 0; i < iDialogAssocs.Count() && !ta; ++i) |
|
551 { |
|
552 ta = iDialogAssocs[i]->Implementation().FindTransaction(aRequestId); |
|
553 } |
|
554 |
|
555 return ta; |
|
556 } |
|
557 |
|
558 // ----------------------------------------------------------------------------- |
|
559 // CSIPDialogImplementation::FindTransactionAndAssoc |
|
560 // ----------------------------------------------------------------------------- |
|
561 // |
|
562 TBool CSIPDialogImplementation::FindTransactionAndAssoc(TUint32 aRequestId, |
|
563 CSIPTransactionBase** aTransaction, |
|
564 CSIPDialogAssocBase** aAssoc) const |
|
565 { |
|
566 __TEST_INVARIANT; |
|
567 __SIP_ASSERT_RETURN_VALUE(aTransaction && aAssoc, EFalse); |
|
568 |
|
569 CSIPTransactionBase* ta = NULL; |
|
570 for (TInt i = 0; i < iDialogAssocs.Count(); ++i) |
|
571 { |
|
572 ta = iDialogAssocs[i]->Implementation().FindTransaction(aRequestId); |
|
573 if (ta) |
|
574 { |
|
575 *aTransaction = ta; |
|
576 *aAssoc = iDialogAssocs[i]; |
|
577 return ETrue; |
|
578 } |
|
579 } |
|
580 |
|
581 return EFalse; |
|
582 } |
|
583 |
|
584 // ----------------------------------------------------------------------------- |
|
585 // CSIPDialogImplementation::FindAssocAndRefreshL |
|
586 // Search with aRequestId. If not found, search with aRefreshId. |
|
587 // ----------------------------------------------------------------------------- |
|
588 // |
|
589 TBool CSIPDialogImplementation::FindAssocAndRefreshL(TUint32 aRequestId, |
|
590 TUint32 aRefreshId, |
|
591 CSIPDialogAssocBase** aAssoc, |
|
592 CSIPRefresh** aRefresh, |
|
593 CSIPTransactionBase** aTransaction) const |
|
594 { |
|
595 __TEST_INVARIANT; |
|
596 __SIP_ASSERT_RETURN_VALUE(aAssoc && aRefresh && aTransaction, EFalse); |
|
597 |
|
598 if (FindTransactionAndAssoc(aRequestId, aTransaction, aAssoc)) |
|
599 { |
|
600 *aRefresh = |
|
601 static_cast<CSIPClientTransaction*>(*aTransaction)->Refresh(); |
|
602 |
|
603 //Refresh must exist now |
|
604 __ASSERT_DEBUG(*aRefresh, |
|
605 User::Panic(_L("CSIPDlgImp:FindAssocAndRfr"), KErrNotFound)); |
|
606 if (*aRefresh) |
|
607 { |
|
608 return ETrue; |
|
609 } |
|
610 } |
|
611 |
|
612 if (FindAssocAndRefresh(aRefreshId, aAssoc, aRefresh)) |
|
613 { |
|
614 CSIPTransactionBase* ta = (*aRefresh)->Transaction(); |
|
615 if (ta) |
|
616 { |
|
617 CSIPTransactionBase::TState state = ta->StateL(); |
|
618 //If transaction has received a final response, it is the initial |
|
619 //transaction creating the refresh. Ignore EConfirmed state, as only |
|
620 //INVITE _server_ transaction has it. |
|
621 if (state != CSIPTransactionBase::ECompleted && |
|
622 state != CSIPTransactionBase::ETerminated) |
|
623 { |
|
624 *aTransaction = ta; |
|
625 } |
|
626 } |
|
627 return ETrue; |
|
628 } |
|
629 return EFalse; |
|
630 } |
|
631 |
|
632 // ----------------------------------------------------------------------------- |
|
633 // CSIPDialogImplementation::FindAssocAndRefresh |
|
634 // ----------------------------------------------------------------------------- |
|
635 // |
|
636 TBool CSIPDialogImplementation::FindAssocAndRefresh(TUint32 aRefreshId, |
|
637 CSIPDialogAssocBase** aAssoc, |
|
638 CSIPRefresh** aRefresh) const |
|
639 { |
|
640 __TEST_INVARIANT; |
|
641 __SIP_ASSERT_RETURN_VALUE(aAssoc && aRefresh, EFalse); |
|
642 |
|
643 CSIPRefresh* refresh = NULL; |
|
644 for (TInt i = 0; i < iDialogAssocs.Count(); ++i) |
|
645 { |
|
646 refresh = iDialogAssocs[i]->FindRefresh(aRefreshId); |
|
647 if (refresh) |
|
648 { |
|
649 *aAssoc = iDialogAssocs[i]; |
|
650 *aRefresh = refresh; |
|
651 return ETrue; |
|
652 } |
|
653 } |
|
654 |
|
655 return EFalse; |
|
656 } |
|
657 |
|
658 // ----------------------------------------------------------------------------- |
|
659 // CSIPDialogImplementation::FindRefresh |
|
660 // ----------------------------------------------------------------------------- |
|
661 // |
|
662 CSIPRefresh* CSIPDialogImplementation::FindRefresh( |
|
663 TUint32 aRequestId, |
|
664 TUint32 aRefreshId) const |
|
665 { |
|
666 CSIPDialogAssocBase* dummyAssoc = NULL; |
|
667 CSIPRefresh* refresh = NULL; |
|
668 CSIPTransactionBase* dummyTransaction; |
|
669 if (FindTransactionAndAssoc(aRequestId, &dummyTransaction, &dummyAssoc)) |
|
670 { |
|
671 return static_cast<CSIPClientTransaction*>(dummyTransaction)->Refresh(); |
|
672 } |
|
673 FindAssocAndRefresh(aRefreshId,&dummyAssoc,&refresh); |
|
674 return refresh; |
|
675 } |
|
676 |
|
677 // ----------------------------------------------------------------------------- |
|
678 // CSIPDialogImplementation::SendNonTargetRefreshRequestL |
|
679 // ----------------------------------------------------------------------------- |
|
680 // |
|
681 CSIPClientTransaction* CSIPDialogImplementation::SendNonTargetRefreshRequestL( |
|
682 CSIPDialogAssocImplementation& aAssoc, |
|
683 RStringF aMethod, |
|
684 CSIPMessageElements* aElements) const |
|
685 { |
|
686 __TEST_INVARIANT; |
|
687 return StateL().SendNonTargetRefreshRequestL(*this, |
|
688 aAssoc, |
|
689 aMethod, |
|
690 aElements); |
|
691 } |
|
692 |
|
693 // ----------------------------------------------------------------------------- |
|
694 // CSIPDialogImplementation::SendInviteL |
|
695 // ----------------------------------------------------------------------------- |
|
696 // |
|
697 CSIPClientTransaction* |
|
698 CSIPDialogImplementation::SendInviteL(CSIPInviteDialogAssoc& aAssoc, |
|
699 CSIPMessageElements* aElements) const |
|
700 { |
|
701 __TEST_INVARIANT; |
|
702 return StateL().SendInviteL(*this, aAssoc, aElements); |
|
703 } |
|
704 |
|
705 // ----------------------------------------------------------------------------- |
|
706 // CSIPDialogImplementation::SendPrackL |
|
707 // ----------------------------------------------------------------------------- |
|
708 // |
|
709 CSIPClientTransaction* |
|
710 CSIPDialogImplementation::SendPrackL(CSIPInviteDialogAssoc& aAssoc, |
|
711 CSIPMessageElements* aElements) const |
|
712 { |
|
713 __TEST_INVARIANT; |
|
714 return StateL().SendPrackL(aAssoc, aElements); |
|
715 } |
|
716 |
|
717 // ----------------------------------------------------------------------------- |
|
718 // CSIPDialogImplementation::SendUpdateL |
|
719 // ----------------------------------------------------------------------------- |
|
720 // |
|
721 CSIPClientTransaction* |
|
722 CSIPDialogImplementation::SendUpdateL(CSIPInviteDialogAssoc& aAssoc, |
|
723 CSIPMessageElements* aElements) const |
|
724 { |
|
725 __TEST_INVARIANT; |
|
726 return StateL().SendUpdateL(aAssoc, aElements); |
|
727 } |
|
728 |
|
729 // ----------------------------------------------------------------------------- |
|
730 // CSIPDialogImplementation::SendAckL |
|
731 // ----------------------------------------------------------------------------- |
|
732 // |
|
733 void CSIPDialogImplementation::SendAckL(CSIPInviteDialogAssoc& aAssoc, |
|
734 const CSIPClientTransaction& aTransaction, |
|
735 CSIPMessageElements* aElements) const |
|
736 { |
|
737 __TEST_INVARIANT; |
|
738 |
|
739 StateL().SendAckL(aAssoc, aTransaction, aElements); |
|
740 } |
|
741 |
|
742 // ----------------------------------------------------------------------------- |
|
743 // CSIPDialogImplementation::SendSubscribeL |
|
744 // ----------------------------------------------------------------------------- |
|
745 // |
|
746 CSIPClientTransaction* |
|
747 CSIPDialogImplementation::SendSubscribeL(CSIPSubscribeDialogAssoc& aAssoc, |
|
748 CSIPMessageElements* aElements, |
|
749 CSIPRefresh* aRefresh) const |
|
750 { |
|
751 __TEST_INVARIANT; |
|
752 return StateL().SendSubscribeL(*this, aAssoc, aElements, aRefresh); |
|
753 } |
|
754 |
|
755 // ----------------------------------------------------------------------------- |
|
756 // CSIPDialogImplementation::UpdateL |
|
757 // ----------------------------------------------------------------------------- |
|
758 // |
|
759 CSIPClientTransaction* |
|
760 CSIPDialogImplementation::UpdateL(CSIPSubscribeDialogAssoc& aAssoc, |
|
761 CSIPMessageElements* aElements) const |
|
762 { |
|
763 __TEST_INVARIANT; |
|
764 return StateL().UpdateL(*this, aAssoc, aElements); |
|
765 } |
|
766 |
|
767 // ----------------------------------------------------------------------------- |
|
768 // CSIPDialogImplementation::SendUnsubscribeL |
|
769 // ----------------------------------------------------------------------------- |
|
770 // |
|
771 CSIPClientTransaction* |
|
772 CSIPDialogImplementation::SendUnsubscribeL(CSIPSubscribeDialogAssoc& aAssoc, |
|
773 CSIPMessageElements* aElements) const |
|
774 { |
|
775 __TEST_INVARIANT; |
|
776 return StateL().SendUnsubscribeL(aAssoc, aElements); |
|
777 } |
|
778 |
|
779 // ----------------------------------------------------------------------------- |
|
780 // CSIPDialogImplementation::SendByeL |
|
781 // ----------------------------------------------------------------------------- |
|
782 // |
|
783 CSIPClientTransaction* |
|
784 CSIPDialogImplementation::SendByeL(CSIPInviteDialogAssoc& aAssoc, |
|
785 CSIPMessageElements* aElements) const |
|
786 { |
|
787 __TEST_INVARIANT; |
|
788 return StateL().SendByeL(aAssoc, aElements); |
|
789 } |
|
790 |
|
791 // ----------------------------------------------------------------------------- |
|
792 // CSIPDialogImplementation::SendCancelL |
|
793 // ----------------------------------------------------------------------------- |
|
794 // |
|
795 CSIPClientTransaction* |
|
796 CSIPDialogImplementation::SendCancelL(TUint32 aRequestId) const |
|
797 { |
|
798 __TEST_INVARIANT; |
|
799 |
|
800 CSIPTransactionBase* dummyTa = NULL; |
|
801 CSIPDialogAssocBase* assoc = NULL; |
|
802 __ASSERT_ALWAYS(FindTransactionAndAssoc(aRequestId, &dummyTa, &assoc), |
|
803 User::Leave(KErrSIPInvalidTransactionState)); |
|
804 __ASSERT_ALWAYS(assoc->Type() == SIPStrings::StringF(SipStrConsts::EInvite), |
|
805 User::Leave(KErrSIPInvalidTransactionState)); |
|
806 return static_cast<CSIPInviteDialogAssoc*> |
|
807 (assoc)->DoSendCancelL(aRequestId); |
|
808 } |
|
809 |
|
810 // ----------------------------------------------------------------------------- |
|
811 // CSIPDialogImplementation::SendNotifyL |
|
812 // ----------------------------------------------------------------------------- |
|
813 // |
|
814 CSIPClientTransaction* |
|
815 CSIPDialogImplementation::SendNotifyL(CSIPNotifyDialogAssoc& aAssoc, |
|
816 CSIPMessageElements* aElements) const |
|
817 { |
|
818 __TEST_INVARIANT; |
|
819 return StateL().SendNotifyL(aAssoc, aElements); |
|
820 } |
|
821 |
|
822 // ----------------------------------------------------------------------------- |
|
823 // CSIPDialogImplementation::SendReferL |
|
824 // ----------------------------------------------------------------------------- |
|
825 // |
|
826 CSIPClientTransaction* |
|
827 CSIPDialogImplementation::SendReferL(CSIPReferDialogAssoc& aAssoc, |
|
828 CSIPMessageElements* aElements) const |
|
829 { |
|
830 __TEST_INVARIANT; |
|
831 return StateL().SendReferL(*this, aAssoc, aElements); |
|
832 } |
|
833 |
|
834 // ----------------------------------------------------------------------------- |
|
835 // CSIPDialogImplementation::SendResponseL |
|
836 // ----------------------------------------------------------------------------- |
|
837 // |
|
838 void |
|
839 CSIPDialogImplementation::SendResponseL(const CSIPResponseElements& aElements, |
|
840 TUint32 aRequestId, |
|
841 TBool aAffectsDialogState, |
|
842 TBool aTargetRefresh) |
|
843 { |
|
844 __TEST_INVARIANT; |
|
845 |
|
846 StateL().SendResponseL(*this, |
|
847 aElements, |
|
848 aRequestId, |
|
849 aAffectsDialogState, |
|
850 aTargetRefresh); |
|
851 __TEST_INVARIANT; |
|
852 } |
|
853 |
|
854 // ----------------------------------------------------------------------------- |
|
855 // CSIPDialogImplementation::SendRequestInDialogL |
|
856 // CSIPClientConnection checks that connection is active. |
|
857 // ----------------------------------------------------------------------------- |
|
858 // |
|
859 CSIPClientTransaction* CSIPDialogImplementation::SendRequestInDialogL( |
|
860 CSIPDialogAssocImplementation& aAssoc, |
|
861 RStringF aMethod, |
|
862 CSIPMessageElements* aElements) const |
|
863 { |
|
864 __TEST_INVARIANT; |
|
865 CheckConnectionL(); |
|
866 |
|
867 CSIPClientTransaction* ta = CreateClientTransactionL(aMethod, aAssoc, NULL); |
|
868 CleanupStack::PushL(ta); |
|
869 |
|
870 TUint32 requestId(0); |
|
871 TUint32 dummyRefreshId(0); // Not used for non-refreshed requests |
|
872 iConnection->ClientConnectionL().SendRequestWithinDialogL(iDialogId, |
|
873 requestId, |
|
874 dummyRefreshId, |
|
875 aMethod, |
|
876 aElements, |
|
877 CSIPTransactionBase::IsTargetRefresh(aMethod)); |
|
878 CleanupStack::Pop(ta); |
|
879 ta->SetRequestId(requestId); |
|
880 |
|
881 delete aElements; |
|
882 return ta; |
|
883 } |
|
884 |
|
885 // ----------------------------------------------------------------------------- |
|
886 // CSIPDialogImplementation::CreateClientTransactionL |
|
887 // ----------------------------------------------------------------------------- |
|
888 // |
|
889 CSIPClientTransaction* |
|
890 CSIPDialogImplementation::CreateClientTransactionL(RStringF aType, |
|
891 CSIPDialogAssocImplementation& aAssoc, |
|
892 CSIPRefresh* aRefresh) const |
|
893 { |
|
894 __TEST_INVARIANT; |
|
895 |
|
896 if (aType == SIPStrings::StringF(SipStrConsts::EInvite)) |
|
897 { |
|
898 __SIP_ASSERT_LEAVE(!aRefresh, KErrArgument); |
|
899 return CSIPInviteClientTransaction::NewL(aAssoc); |
|
900 } |
|
901 |
|
902 return CSIPClientTransaction::NewL(aType, aAssoc, aRefresh); |
|
903 } |
|
904 |
|
905 // ----------------------------------------------------------------------------- |
|
906 // CSIPDialogImplementation::AddAssocL |
|
907 // Needs aType as aAssoc.Type can't be used as aAssoc::iImplementation is NULL |
|
908 // (CSIPDialogAssocImplementation::NewL hasn't returned yet). No invariant here. |
|
909 // ----------------------------------------------------------------------------- |
|
910 // |
|
911 void CSIPDialogImplementation::AddAssocL(CSIPDialogAssocBase& aAssoc, |
|
912 RStringF aType) |
|
913 { |
|
914 __ASSERT_ALWAYS(iDialogAssocs.Find(&aAssoc) == KErrNotFound && |
|
915 (aType != SIPStrings::StringF(SipStrConsts::EInvite) || |
|
916 !HasInviteAssoc()), User::Leave(KErrAlreadyExists)); |
|
917 iDialogAssocs.AppendL(&aAssoc); |
|
918 } |
|
919 |
|
920 // ----------------------------------------------------------------------------- |
|
921 // CSIPDialogImplementation::RemoveAssoc |
|
922 // CDeleteMgr isn't used, as it'd be in CSIP, which is not always accessible as |
|
923 // CSIPConnection and/or CSIP may've been deleted. Don't use invariant here. |
|
924 // ----------------------------------------------------------------------------- |
|
925 // |
|
926 void CSIPDialogImplementation::RemoveAssoc(const CSIPDialogAssocBase& aAssoc) |
|
927 { |
|
928 //Returns KErrNotFound e.g. if CSIPDialogAssocImplementation::ConstructL |
|
929 //runs out of memory. |
|
930 TInt pos = iDialogAssocs.Find(&aAssoc); |
|
931 if (pos != KErrNotFound) |
|
932 { |
|
933 iDialogAssocs.Remove(pos); |
|
934 |
|
935 if (iDialogAssocs.Count() == 0) |
|
936 { |
|
937 delete this; |
|
938 } |
|
939 } |
|
940 } |
|
941 |
|
942 // ----------------------------------------------------------------------------- |
|
943 // CSIPDialogImplementation::HasInviteAssoc |
|
944 // Don't use invariant here. |
|
945 // ----------------------------------------------------------------------------- |
|
946 // |
|
947 TBool CSIPDialogImplementation::HasInviteAssoc() const |
|
948 { |
|
949 for (TInt i = 0; i < iDialogAssocs.Count(); ++i) |
|
950 { |
|
951 if (iDialogAssocs[i]->Type() == |
|
952 SIPStrings::StringF(SipStrConsts::EInvite)) |
|
953 { |
|
954 return ETrue; |
|
955 } |
|
956 } |
|
957 |
|
958 return EFalse; |
|
959 } |
|
960 |
|
961 // ----------------------------------------------------------------------------- |
|
962 // CSIPDialogImplementation::ConnectionDeleted |
|
963 // As CSIPClientConnection is deleted, SIP client terminates all dialogs. So |
|
964 // TerminateDialog is not called here. Clear iState, as CSIPDialogImplementation |
|
965 // won't get noticed, when the CSIP owning the dialog states, is deleted. |
|
966 // ----------------------------------------------------------------------------- |
|
967 // |
|
968 void CSIPDialogImplementation::ConnectionDeleted() |
|
969 { |
|
970 __TEST_INVARIANT; |
|
971 |
|
972 iState = NULL; |
|
973 iConnection = NULL; |
|
974 |
|
975 __TEST_INVARIANT; |
|
976 } |
|
977 |
|
978 // ----------------------------------------------------------------------------- |
|
979 // CSIPDialogImplementation::CheckConnectionL |
|
980 // Don't use invariant here. |
|
981 // ----------------------------------------------------------------------------- |
|
982 // |
|
983 void CSIPDialogImplementation::CheckConnectionL() const |
|
984 { |
|
985 __ASSERT_ALWAYS(iConnection, User::Leave(KErrSIPResourceNotAvailable)); |
|
986 } |
|
987 |
|
988 // ----------------------------------------------------------------------------- |
|
989 // CSIPDialogImplementation::StateL |
|
990 // ----------------------------------------------------------------------------- |
|
991 // |
|
992 const CDialogState& CSIPDialogImplementation::StateL() const |
|
993 { |
|
994 __TEST_INVARIANT; |
|
995 __ASSERT_ALWAYS(iState != NULL, User::Leave(KErrSIPResourceNotAvailable)); |
|
996 return *iState; |
|
997 } |
|
998 |
|
999 // ----------------------------------------------------------------------------- |
|
1000 // CSIPDialogImplementation::UpdateState |
|
1001 // ----------------------------------------------------------------------------- |
|
1002 // |
|
1003 void |
|
1004 CSIPDialogImplementation::UpdateState(const CSIPClientTransaction& aTransaction, |
|
1005 const CDialogState& aEarly, |
|
1006 const CDialogState& aConfirmed, |
|
1007 const CDialogState& aTerminated) |
|
1008 { |
|
1009 __TEST_INVARIANT; |
|
1010 |
|
1011 const CSIPResponseElements* elem = aTransaction.ResponseElements(); |
|
1012 __SIP_ASSERT_RETURN(elem != NULL, KErrArgument); |
|
1013 |
|
1014 TUint status = elem->StatusCode(); |
|
1015 if (aTransaction.AffectsDialogState()) |
|
1016 { |
|
1017 if (status >= 300) |
|
1018 { |
|
1019 ChangeState(&aTerminated); |
|
1020 } |
|
1021 else if (status >= 200) |
|
1022 { |
|
1023 ChangeState(&aConfirmed); |
|
1024 } |
|
1025 else |
|
1026 { |
|
1027 if (status > 100 && State() == CSIPDialog::EInit) |
|
1028 { |
|
1029 ChangeState(&aEarly); |
|
1030 } |
|
1031 } |
|
1032 } |
|
1033 |
|
1034 __TEST_INVARIANT; |
|
1035 } |
|
1036 |
|
1037 // ----------------------------------------------------------------------------- |
|
1038 // CSIPDialogImplementation::CheckNoTransactionExistsL |
|
1039 // ----------------------------------------------------------------------------- |
|
1040 // |
|
1041 void CSIPDialogImplementation::CheckNoTransactionExistsL() const |
|
1042 { |
|
1043 __TEST_INVARIANT; |
|
1044 __ASSERT_ALWAYS(!iInitialRequestId, User::Leave(KErrSIPInvalidDialogState)); |
|
1045 } |
|
1046 |
|
1047 // ----------------------------------------------------------------------------- |
|
1048 // CSIPDialogImplementation::InitialTransactionStarted |
|
1049 // ----------------------------------------------------------------------------- |
|
1050 // |
|
1051 void CSIPDialogImplementation::InitialTransactionStarted(TUint32 aRequestId) |
|
1052 { |
|
1053 __TEST_INVARIANT; |
|
1054 __SIP_ASSERT_RETURN(aRequestId, KErrArgument); |
|
1055 __SIP_ASSERT_RETURN(!iInitialRequestId, KErrAlreadyExists); |
|
1056 |
|
1057 iInitialRequestId = aRequestId; |
|
1058 |
|
1059 __TEST_INVARIANT; |
|
1060 } |
|
1061 |
|
1062 // ----------------------------------------------------------------------------- |
|
1063 // CSIPDialogImplementation::InitialTransactionStarted |
|
1064 // ----------------------------------------------------------------------------- |
|
1065 // |
|
1066 void CSIPDialogImplementation::InitialTransactionStarted( |
|
1067 CSIPTransactionBase& aTransaction) |
|
1068 { |
|
1069 __TEST_INVARIANT; |
|
1070 |
|
1071 InitialTransactionStarted(aTransaction.RequestId()); |
|
1072 aTransaction.SetAffectsDialogState(); |
|
1073 |
|
1074 __TEST_INVARIANT; |
|
1075 } |
|
1076 |
|
1077 // ----------------------------------------------------------------------------- |
|
1078 // CSIPDialogImplementation::DoesNotifyConfirmDialog |
|
1079 // ----------------------------------------------------------------------------- |
|
1080 // |
|
1081 TBool CSIPDialogImplementation::DoesNotifyConfirmDialog() const |
|
1082 { |
|
1083 __TEST_INVARIANT; |
|
1084 |
|
1085 if (iInitialRequestId) |
|
1086 { |
|
1087 CSIPTransactionBase* ta = FindTransaction(iInitialRequestId); |
|
1088 return (ta && |
|
1089 (ta->Type() == SIPStrings::StringF(SipStrConsts::ESubscribe) || |
|
1090 ta->Type() == SIPStrings::StringF(SipStrConsts::ERefer)) && |
|
1091 ta->IsSIPClientTransaction()); |
|
1092 } |
|
1093 return EFalse; |
|
1094 } |
|
1095 |
|
1096 // ----------------------------------------------------------------------------- |
|
1097 // CSIPDialogImplementation::ChangeRefreshesToActive |
|
1098 // Adding a virtual function CSIPDialogAssocBase::ChangeRefreshToActive breaks |
|
1099 // BC, so an ugly way like this is used. |
|
1100 // ----------------------------------------------------------------------------- |
|
1101 // |
|
1102 void CSIPDialogImplementation::ChangeRefreshesToActive() const |
|
1103 { |
|
1104 __TEST_INVARIANT; |
|
1105 |
|
1106 for (TInt i = 0; i < iDialogAssocs.Count(); ++i) |
|
1107 { |
|
1108 if (iDialogAssocs[i]->Type() == |
|
1109 SIPStrings::StringF(SipStrConsts::ESubscribe)) |
|
1110 { |
|
1111 const CSIPRefresh* rfr = static_cast<CSIPSubscribeDialogAssoc*> |
|
1112 (iDialogAssocs[i])->SIPRefresh(); |
|
1113 if (rfr && rfr->State() == CSIPRefresh::EInactive) |
|
1114 { |
|
1115 //Get a modifiable pointer to the refresh |
|
1116 CSIPRefresh* refresh = |
|
1117 iDialogAssocs[i]->FindRefresh(rfr->RefreshId()); |
|
1118 __SIP_ASSERT_RETURN(refresh != NULL, KErrNotFound); |
|
1119 refresh->ChangeState(CSIPRefresh::EActive); |
|
1120 } |
|
1121 } |
|
1122 } |
|
1123 } |
|
1124 |
|
1125 // ----------------------------------------------------------------------------- |
|
1126 // CSIPDialogImplementation::UpdateRemoteTargetL |
|
1127 // ----------------------------------------------------------------------------- |
|
1128 // |
|
1129 void CSIPDialogImplementation::UpdateRemoteTargetL(RStringF aMethod, |
|
1130 const CSIPMessageElements& aElements) |
|
1131 { |
|
1132 __TEST_INVARIANT; |
|
1133 |
|
1134 if (CSIPTransactionBase::IsTargetRefresh(aMethod)) |
|
1135 { |
|
1136 CUri8* uri = GetUriFromContactL(aElements); |
|
1137 if (uri) |
|
1138 { |
|
1139 delete iRemoteUri; |
|
1140 iRemoteUri = uri; |
|
1141 } |
|
1142 } |
|
1143 __TEST_INVARIANT; |
|
1144 } |
|
1145 |
|
1146 // ----------------------------------------------------------------------------- |
|
1147 // CSIPDialogImplementation::SetHeadersL |
|
1148 // ----------------------------------------------------------------------------- |
|
1149 // |
|
1150 void CSIPDialogImplementation::SetHeadersL(CSIPFromHeader* aFrom, |
|
1151 CSIPToHeader* aTo, |
|
1152 CUri8* aRemoteUri, |
|
1153 CSIPContactHeader* aContact) |
|
1154 { |
|
1155 __SIP_ASSERT_LEAVE(aRemoteUri, KErrArgument); |
|
1156 __SIP_ASSERT_LEAVE(!iFrom && !iTo && !iRemoteUri && !iContact, |
|
1157 KErrAlreadyExists); |
|
1158 if (!aFrom) |
|
1159 { |
|
1160 __SIP_ASSERT_LEAVE(iRegistration != NULL, KErrNotFound); |
|
1161 iFrom = |
|
1162 iConnection->ClientConnectionL().AorL(iRegistration->ContextId()); |
|
1163 iFrom->DeleteParam(SIPStrings::StringF(SipStrConsts::ETag)); |
|
1164 } |
|
1165 |
|
1166 if (aTo) |
|
1167 { |
|
1168 iTo = aTo; |
|
1169 } |
|
1170 else |
|
1171 { |
|
1172 iTo = CSIPToHeader::DecodeL(aRemoteUri->Uri().UriDes()); |
|
1173 } |
|
1174 |
|
1175 if (aFrom) |
|
1176 { |
|
1177 iFrom = aFrom; |
|
1178 } |
|
1179 |
|
1180 iRemoteUri = aRemoteUri; |
|
1181 iContact = aContact; |
|
1182 |
|
1183 __TEST_INVARIANT; |
|
1184 } |
|
1185 |
|
1186 // ----------------------------------------------------------------------------- |
|
1187 // CSIPDialogImplementation::InitialTransactionReceivedL |
|
1188 // Request must have exactly one Contact header. Dialog subsystem hasn't checked |
|
1189 // that as request came outside dialog. iRemoteUri is set with the Contact URI. |
|
1190 // ----------------------------------------------------------------------------- |
|
1191 // |
|
1192 void CSIPDialogImplementation::InitialTransactionReceivedL( |
|
1193 CSIPServerTransaction& aTransaction) |
|
1194 { |
|
1195 __SIP_ASSERT_LEAVE(!iFrom && !iTo && !iRemoteUri, KErrAlreadyExists); |
|
1196 |
|
1197 const CSIPRequestElements* elem = aTransaction.RequestElements(); |
|
1198 __SIP_ASSERT_LEAVE(elem != NULL, KErrArgument); |
|
1199 |
|
1200 //From includes the remote tag, if remote filled it |
|
1201 iFrom = CSIPFromHeader::NewL(*elem->FromHeader()); |
|
1202 iTo = CSIPToHeader::NewL(*elem->ToHeader()); |
|
1203 iRemoteUri = GetUriFromContactL(elem->MessageElements()); |
|
1204 InitialTransactionStarted(aTransaction); |
|
1205 |
|
1206 if (!iRemoteUri) |
|
1207 { |
|
1208 CSIPResponseElements* resp = CSIPResponseElements::NewLC(400, |
|
1209 SIPStrings::StringF(SipStrConsts::EPhraseBadRequest)); |
|
1210 aTransaction.SendResponseL(resp); |
|
1211 CleanupStack::Pop(resp); |
|
1212 User::Leave(KErrSIPMalformedMessage); |
|
1213 } |
|
1214 |
|
1215 __TEST_INVARIANT; |
|
1216 } |
|
1217 |
|
1218 // ----------------------------------------------------------------------------- |
|
1219 // CSIPDialogImplementation::SendDialogCreatingRequestL |
|
1220 // ----------------------------------------------------------------------------- |
|
1221 // |
|
1222 CSIPClientTransaction* |
|
1223 CSIPDialogImplementation::SendDialogCreatingRequestL( |
|
1224 CSIPDialogAssocImplementation& aAssoc, |
|
1225 CSIPMessageElements* aElements, |
|
1226 CSIPRefresh* aRefresh) |
|
1227 { |
|
1228 __TEST_INVARIANT; |
|
1229 CheckConnectionL(); |
|
1230 |
|
1231 CSIPClientTransaction* ta = |
|
1232 CreateClientTransactionL(aAssoc.Type(), aAssoc, aRefresh); |
|
1233 CleanupStack::PushL(ta); |
|
1234 |
|
1235 TUint32 requestId(0); |
|
1236 TUint32 refreshId(0); |
|
1237 iConnection->ClientConnectionL().SendRequestAndCreateDialogL(requestId, |
|
1238 refreshId, |
|
1239 iDialogId, |
|
1240 aAssoc.Type(), |
|
1241 *iRemoteUri, |
|
1242 iFrom, |
|
1243 aElements, |
|
1244 iTo, |
|
1245 RegistrationId(), |
|
1246 (aRefresh != NULL)); |
|
1247 ta->SetRequestId(requestId); |
|
1248 InitialTransactionStarted(*ta); |
|
1249 StoreCallIdL(); |
|
1250 FillLocalTagL(ETrue); |
|
1251 CleanupStack::Pop(ta); |
|
1252 |
|
1253 if (aRefresh) |
|
1254 { |
|
1255 aRefresh->SetRefreshIdIfEmpty(refreshId); |
|
1256 } |
|
1257 delete aElements; |
|
1258 |
|
1259 //Contact can now be freed |
|
1260 delete iContact; |
|
1261 iContact = NULL; |
|
1262 |
|
1263 return ta; |
|
1264 } |
|
1265 |
|
1266 // ----------------------------------------------------------------------------- |
|
1267 // CSIPDialogImplementation::ContactHeader |
|
1268 // ----------------------------------------------------------------------------- |
|
1269 // |
|
1270 const CSIPContactHeader* CSIPDialogImplementation::ContactHeader() const |
|
1271 { |
|
1272 __TEST_INVARIANT; |
|
1273 return iContact; |
|
1274 } |
|
1275 |
|
1276 // ----------------------------------------------------------------------------- |
|
1277 // CSIPDialogImplementation::GetUriFromContactL |
|
1278 // Don't use invariant here. |
|
1279 // ----------------------------------------------------------------------------- |
|
1280 // |
|
1281 CUri8* CSIPDialogImplementation::GetUriFromContactL( |
|
1282 const CSIPMessageElements& aElements) const |
|
1283 { |
|
1284 CUri8* uri = NULL; |
|
1285 |
|
1286 RStringF contact = SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
1287 if (aElements.UserHeaderCount(contact) == 1) |
|
1288 { |
|
1289 RPointerArray<CSIPHeaderBase> headers = aElements.UserHeadersL(contact); |
|
1290 CleanupClosePushL(headers); |
|
1291 |
|
1292 CSIPContactHeader* contactHeader = |
|
1293 static_cast<CSIPContactHeader*>(headers[0]); |
|
1294 |
|
1295 const CSIPAddress* addr = contactHeader->SIPAddress(); |
|
1296 if (addr) |
|
1297 { |
|
1298 uri = CUri8::NewL(addr->Uri8().Uri()); |
|
1299 } |
|
1300 CleanupStack::PopAndDestroy(); //headers |
|
1301 } |
|
1302 return uri; |
|
1303 } |
|
1304 |
|
1305 // ----------------------------------------------------------------------------- |
|
1306 // CSIPDialogImplementation::FillLocalTagL |
|
1307 // ----------------------------------------------------------------------------- |
|
1308 // |
|
1309 void CSIPDialogImplementation::FillLocalTagL(TBool aClientInitiatedDialog) const |
|
1310 { |
|
1311 __TEST_INVARIANT; |
|
1312 __SIP_ASSERT_LEAVE(iDialogId != 0, KErrNotFound); |
|
1313 |
|
1314 RStringF tag = SIPStrings::StringF(SipStrConsts::ETag); |
|
1315 CSIPFromToHeaderBase* header = iFrom; |
|
1316 if (!aClientInitiatedDialog) |
|
1317 { |
|
1318 header = iTo; |
|
1319 } |
|
1320 |
|
1321 if (!header->HasParam(tag)) |
|
1322 { |
|
1323 CheckConnectionL(); |
|
1324 RStringF localTag = |
|
1325 iConnection->ClientConnectionL().LocalTagL(iDialogId); |
|
1326 CleanupClosePushL(localTag); |
|
1327 header->SetParamL(tag, localTag); |
|
1328 CleanupStack::PopAndDestroy(); //localTag |
|
1329 } |
|
1330 } |
|
1331 |
|
1332 // ----------------------------------------------------------------------------- |
|
1333 // CSIPDialogImplementation::FillRemoteTagL |
|
1334 // ----------------------------------------------------------------------------- |
|
1335 // |
|
1336 void |
|
1337 CSIPDialogImplementation::FillRemoteTagL(const CSIPToHeader& aToHeader) const |
|
1338 { |
|
1339 __TEST_INVARIANT; |
|
1340 |
|
1341 RStringF tag = SIPStrings::StringF(SipStrConsts::ETag); |
|
1342 if (aToHeader.HasParam(tag)) |
|
1343 { |
|
1344 iTo->SetParamL(tag, aToHeader.ParamValue(tag)); |
|
1345 } |
|
1346 } |
|
1347 |
|
1348 // ----------------------------------------------------------------------------- |
|
1349 // CSIPDialogImplementation::RegistrationId |
|
1350 // ----------------------------------------------------------------------------- |
|
1351 // |
|
1352 TUint32 CSIPDialogImplementation::RegistrationId() const |
|
1353 { |
|
1354 return (iRegistration ? iRegistration->ContextId() : 0); |
|
1355 } |
|
1356 |
|
1357 // ----------------------------------------------------------------------------- |
|
1358 // CSIPDialogImplementation::__DbgTestInvariant |
|
1359 // iState is NULL if CSIP has been deleted. |
|
1360 // Don't check iRemoteUri, as 400 response is sent when missing iRemoteUri from |
|
1361 // an incoming request that creates a dialog. |
|
1362 // ----------------------------------------------------------------------------- |
|
1363 // |
|
1364 |
|
1365 void CSIPDialogImplementation::__DbgTestInvariant() const |
|
1366 { |
|
1367 if (!iDialog || !iFrom || !iTo) |
|
1368 { |
|
1369 User::Invariant(); |
|
1370 } |
|
1371 } |