|
1 // Copyright (c) 2008-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 : TransactionInfo.cpp |
|
15 // Part of : TransactionUser |
|
16 // Version : SIP/6.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include "SipAssert.h" |
|
22 #include "uricontainer.h" |
|
23 #include "siptoheader.h" |
|
24 #include "sipfromheader.h" |
|
25 #include "sipviaheader.h" |
|
26 #include "sipcallidheader.h" |
|
27 #include "sipcseqheader.h" |
|
28 #include "siprecordrouteheader.h" |
|
29 #include "sipcontactheader.h" |
|
30 #include "siprequest.h" |
|
31 #include "sipstrings.h" |
|
32 #include "sipstrconsts.h" |
|
33 |
|
34 #include "CUserAgent.h" |
|
35 #include "TransactionInfo.h" |
|
36 #include "CTransactionHeaders.h" |
|
37 #include "SIPMessageUtility.h" |
|
38 |
|
39 // ----------------------------------------------------------------------------- |
|
40 // CTransactionInfo::NewL |
|
41 // ----------------------------------------------------------------------------- |
|
42 // |
|
43 CTransactionInfo* |
|
44 CTransactionInfo::NewL(CTransactionBase::TTransactionType aType, TUint32 aIapId) |
|
45 { |
|
46 return new (ELeave) CTransactionInfo(aType, aIapId); |
|
47 } |
|
48 |
|
49 // ----------------------------------------------------------------------------- |
|
50 // CTransactionInfo::CTransactionInfo |
|
51 // ----------------------------------------------------------------------------- |
|
52 // |
|
53 CTransactionInfo::CTransactionInfo(CTransactionBase::TTransactionType aType, |
|
54 TUint32 aIapId) : |
|
55 iTransactionType(aType), |
|
56 iIapId(aIapId) |
|
57 #ifdef CPPUNIT_TEST |
|
58 , iViaHeaders(1), |
|
59 iRecordRoute(1), |
|
60 iContact(1) |
|
61 #endif |
|
62 { |
|
63 } |
|
64 |
|
65 // ----------------------------------------------------------------------------- |
|
66 // CTransactionInfo::~CTransactionInfo |
|
67 // ----------------------------------------------------------------------------- |
|
68 // |
|
69 CTransactionInfo::~CTransactionInfo() |
|
70 { |
|
71 ClearMessageHeaders(); |
|
72 } |
|
73 |
|
74 // ----------------------------------------------------------------------------- |
|
75 // CTransactionInfo::FreeContents |
|
76 // UA owns transaction. Delete it only if it is detached from UA, or it differs |
|
77 // from UA's transaction (=should be impossible). |
|
78 // ----------------------------------------------------------------------------- |
|
79 // |
|
80 void CTransactionInfo::FreeContents() |
|
81 { |
|
82 if (!iUserAgent || (iUserAgent->Transaction() != iTransaction)) |
|
83 { |
|
84 delete iTransaction; |
|
85 iTransaction = NULL; |
|
86 } |
|
87 |
|
88 delete iUserAgent; |
|
89 iUserAgent = NULL; |
|
90 } |
|
91 |
|
92 // ----------------------------------------------------------------------------- |
|
93 // CTransactionInfo::ClearMessageHeaders |
|
94 // ----------------------------------------------------------------------------- |
|
95 // |
|
96 void CTransactionInfo::ClearMessageHeaders() |
|
97 { |
|
98 delete iRequestURI; |
|
99 iRequestURI = NULL; |
|
100 |
|
101 delete iTo; |
|
102 iTo = NULL; |
|
103 |
|
104 delete iFrom; |
|
105 iFrom = NULL; |
|
106 |
|
107 delete iCallID; |
|
108 iCallID = NULL; |
|
109 |
|
110 iMethod.Close(); |
|
111 iCSeq = 0; |
|
112 iViaHeaders.ResetAndDestroy(); |
|
113 iRecordRoute.ResetAndDestroy(); |
|
114 iContact.ResetAndDestroy(); |
|
115 } |
|
116 |
|
117 // ----------------------------------------------------------------------------- |
|
118 // CTransactionInfo::Receiver |
|
119 // ----------------------------------------------------------------------------- |
|
120 // |
|
121 MTransactionReceiver* CTransactionInfo::Receiver() |
|
122 { |
|
123 if (iTransaction) |
|
124 { |
|
125 return iTransaction; |
|
126 } |
|
127 return iUserAgent; |
|
128 } |
|
129 |
|
130 // ----------------------------------------------------------------------------- |
|
131 // CTransactionInfo::UserAgent |
|
132 // ----------------------------------------------------------------------------- |
|
133 // |
|
134 CUserAgent* CTransactionInfo::UserAgent() |
|
135 { |
|
136 return iUserAgent; |
|
137 } |
|
138 |
|
139 // ----------------------------------------------------------------------------- |
|
140 // CTransactionInfo::SetUserAgent |
|
141 // ----------------------------------------------------------------------------- |
|
142 // |
|
143 void CTransactionInfo::SetUserAgent(CUserAgent* aUserAgent) |
|
144 { |
|
145 iUserAgent = aUserAgent; |
|
146 } |
|
147 |
|
148 // ----------------------------------------------------------------------------- |
|
149 // CTransactionInfo::SetTransaction |
|
150 // ----------------------------------------------------------------------------- |
|
151 // |
|
152 void CTransactionInfo::SetTransaction(CTransactionBase* aTransaction) |
|
153 { |
|
154 iTransaction = aTransaction; |
|
155 } |
|
156 |
|
157 // ----------------------------------------------------------------------------- |
|
158 // CTransactionInfo::TransactionId |
|
159 // ----------------------------------------------------------------------------- |
|
160 // |
|
161 TTransactionId CTransactionInfo::TransactionId() const |
|
162 { |
|
163 return iTransactionId; |
|
164 } |
|
165 |
|
166 // ----------------------------------------------------------------------------- |
|
167 // CTransactionInfo::SetTransactionId |
|
168 // ----------------------------------------------------------------------------- |
|
169 // |
|
170 void CTransactionInfo::SetTransactionId(TTransactionId aTransactionId) |
|
171 { |
|
172 iTransactionId = aTransactionId; |
|
173 } |
|
174 |
|
175 // ----------------------------------------------------------------------------- |
|
176 // CTransactionInfo::IapId |
|
177 // ----------------------------------------------------------------------------- |
|
178 // |
|
179 TUint32 CTransactionInfo::IapId() const |
|
180 { |
|
181 return iIapId; |
|
182 } |
|
183 |
|
184 // ----------------------------------------------------------------------------- |
|
185 // CTransactionInfo::TopVia |
|
186 // ----------------------------------------------------------------------------- |
|
187 // |
|
188 CSIPViaHeader& CTransactionInfo::TopVia() const |
|
189 { |
|
190 __ASSERT_ALWAYS(iViaHeaders.Count() > 0, |
|
191 User::Panic(_L("TaInfo:TopVia"), KErrNotFound)); |
|
192 return *iViaHeaders[0]; |
|
193 } |
|
194 |
|
195 // ----------------------------------------------------------------------------- |
|
196 // CTransactionInfo::UpdateMessageHeadersL |
|
197 // ----------------------------------------------------------------------------- |
|
198 // |
|
199 void CTransactionInfo::UpdateMessageHeadersL(CSIPMessage* aMsg) |
|
200 { |
|
201 if (aMsg) |
|
202 { |
|
203 ClearMessageHeaders(); |
|
204 |
|
205 if (aMsg->IsRequest()) |
|
206 { |
|
207 CURIContainer* uri = static_cast<CSIPRequest*>(aMsg)->RequestURI(); |
|
208 if (uri) |
|
209 { |
|
210 iRequestURI = CURIContainer::NewL(*uri); |
|
211 } |
|
212 } |
|
213 |
|
214 iMethod.Close(); |
|
215 iMethod = CSIPMessageUtility::MessageMethod(*aMsg).Copy(); |
|
216 |
|
217 iTo = static_cast<CSIPToHeader*> |
|
218 (CSIPMessageUtility::CopyHeaderFromMsgL(*aMsg, |
|
219 SIPStrings::StringF(SipStrConsts::EToHeader))); |
|
220 iFrom = static_cast<CSIPFromHeader*> |
|
221 (CSIPMessageUtility::CopyHeaderFromMsgL(*aMsg, |
|
222 SIPStrings::StringF(SipStrConsts::EFromHeader))); |
|
223 iCallID = static_cast<CSIPCallIDHeader*> |
|
224 (CSIPMessageUtility::CopyHeaderFromMsgL(*aMsg, |
|
225 SIPStrings::StringF(SipStrConsts::ECallIDHeader))); |
|
226 |
|
227 if (aMsg->HasHeader(SIPStrings::StringF(SipStrConsts::ECSeqHeader))) |
|
228 { |
|
229 iCSeq = aMsg->CSeq()->Seq(); |
|
230 } |
|
231 |
|
232 CopyViaHeadersFromMsgL(*aMsg); |
|
233 } |
|
234 } |
|
235 |
|
236 // ----------------------------------------------------------------------------- |
|
237 // CTransactionInfo::UpdateToTagL |
|
238 // Server transaction has checked there is no To-tag yet. |
|
239 // ----------------------------------------------------------------------------- |
|
240 // |
|
241 void CTransactionInfo::UpdateToTagL(RStringF aTag) |
|
242 { |
|
243 __SIP_ASSERT_LEAVE(iTo, KErrNotFound); |
|
244 |
|
245 RStringF tag = SIPStrings::StringF(SipStrConsts::ETag); |
|
246 __SIP_ASSERT_LEAVE(!iTo->HasParam(tag), KErrAlreadyExists); |
|
247 |
|
248 iTo->SetParamL(tag, aTag); |
|
249 } |
|
250 |
|
251 // ----------------------------------------------------------------------------- |
|
252 // CTransactionInfo::CopyViaHeadersFromMsgL |
|
253 // Sent requests have empty host part, but response matching won't use sent-by. |
|
254 // ----------------------------------------------------------------------------- |
|
255 // |
|
256 void CTransactionInfo::CopyViaHeadersFromMsgL(CSIPMessage& aMsg) |
|
257 { |
|
258 const RStringF KVia = SIPStrings::StringF(SipStrConsts::EViaHeader); |
|
259 if (aMsg.HasHeader(KVia)) |
|
260 { |
|
261 iViaHeaders.ResetAndDestroy(); |
|
262 |
|
263 TSglQueIter<CSIPHeaderBase> iter = aMsg.Headers(KVia); |
|
264 for (CSIPHeaderBase* header = iter++; header; header = iter++) |
|
265 { |
|
266 CSIPViaHeader* via = dynamic_cast<CSIPViaHeader*>(header->CloneL()); |
|
267 CleanupStack::PushL(via); |
|
268 iViaHeaders.AppendL(via); |
|
269 CleanupStack::Pop(via); |
|
270 } |
|
271 } |
|
272 } |
|
273 |
|
274 // ----------------------------------------------------------------------------- |
|
275 // CTransactionInfo::StoreRecordRouteHeadersL |
|
276 // ----------------------------------------------------------------------------- |
|
277 // |
|
278 void CTransactionInfo::StoreRecordRouteHeadersL(CSIPRequest& aReq) |
|
279 { |
|
280 __SIP_ASSERT_LEAVE(iRecordRoute.Count() == 0, KErrAlreadyExists); |
|
281 |
|
282 const RStringF KRecordRoute = |
|
283 SIPStrings::StringF(SipStrConsts::ERecordRouteHeader); |
|
284 if (aReq.HasHeader(KRecordRoute)) |
|
285 { |
|
286 TSglQueIter<CSIPHeaderBase> iter = aReq.Headers(KRecordRoute); |
|
287 for (CSIPHeaderBase* header = iter++; header; header = iter++) |
|
288 { |
|
289 CSIPRecordRouteHeader* rr = |
|
290 static_cast<CSIPRecordRouteHeader*>(header->CloneL()); |
|
291 CleanupStack::PushL(rr); |
|
292 iRecordRoute.AppendL(rr); |
|
293 CleanupStack::Pop(rr); |
|
294 } |
|
295 } |
|
296 } |
|
297 |
|
298 // ----------------------------------------------------------------------------- |
|
299 // CTransactionInfo::FreeRecordRouteHeaders |
|
300 // ----------------------------------------------------------------------------- |
|
301 // |
|
302 void CTransactionInfo::FreeRecordRouteHeaders() |
|
303 { |
|
304 iRecordRoute.ResetAndDestroy(); |
|
305 } |
|
306 |
|
307 // ----------------------------------------------------------------------------- |
|
308 // CTransactionInfo::StoreContactHeadersL |
|
309 // ----------------------------------------------------------------------------- |
|
310 // |
|
311 void CTransactionInfo::StoreContactHeadersL(CSIPRequest& aReq) |
|
312 { |
|
313 __SIP_ASSERT_LEAVE(iContact.Count() == 0, KErrAlreadyExists); |
|
314 |
|
315 const RStringF KContact = SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
316 if (aReq.HasHeader(KContact)) |
|
317 { |
|
318 TSglQueIter<CSIPHeaderBase> iter = aReq.Headers(KContact); |
|
319 for (CSIPHeaderBase* header = iter++; header; header = iter++) |
|
320 { |
|
321 CSIPContactHeader* contact = |
|
322 dynamic_cast<CSIPContactHeader*>(header->CloneL()); |
|
323 CleanupStack::PushL(contact); |
|
324 iContact.AppendL(contact); |
|
325 CleanupStack::Pop(contact); |
|
326 } |
|
327 } |
|
328 } |
|
329 |
|
330 // ----------------------------------------------------------------------------- |
|
331 // CTransactionInfo::FreeContactHeaders |
|
332 // ----------------------------------------------------------------------------- |
|
333 // |
|
334 void CTransactionInfo::FreeContactHeaders() |
|
335 { |
|
336 iContact.ResetAndDestroy(); |
|
337 } |
|
338 |
|
339 // ----------------------------------------------------------------------------- |
|
340 // CTransactionInfo::RequiredHeadersPresent |
|
341 // ----------------------------------------------------------------------------- |
|
342 // |
|
343 TBool CTransactionInfo::RequiredHeadersPresent() const |
|
344 { |
|
345 return iViaHeaders.Count() > 0 && iFrom && iTo && iCallID && MethodExists(); |
|
346 } |
|
347 |
|
348 // ----------------------------------------------------------------------------- |
|
349 // CTransactionInfo::MethodExists |
|
350 // ----------------------------------------------------------------------------- |
|
351 // |
|
352 TBool CTransactionInfo::MethodExists() const |
|
353 { |
|
354 return iMethod.DesC().Length() > 0; |
|
355 } |
|
356 |
|
357 // ----------------------------------------------------------------------------- |
|
358 // CTransactionInfo::CompareType |
|
359 // ----------------------------------------------------------------------------- |
|
360 // |
|
361 TBool |
|
362 CTransactionInfo::CompareType(CTransactionBase::TTransactionType aType) const |
|
363 { |
|
364 return aType == iTransactionType; |
|
365 } |
|
366 |
|
367 // ----------------------------------------------------------------------------- |
|
368 // CTransactionInfo::CompareMethod |
|
369 // If the received message is ACK, iMethod should be INVITE. |
|
370 // ----------------------------------------------------------------------------- |
|
371 // |
|
372 TBool CTransactionInfo::CompareMethod(RStringF aMsgMethod) const |
|
373 { |
|
374 if (aMsgMethod == SIPStrings::StringF(SipStrConsts::EAck)) |
|
375 { |
|
376 return iMethod == SIPStrings::StringF(SipStrConsts::EInvite); |
|
377 } |
|
378 |
|
379 return aMsgMethod == iMethod; |
|
380 } |
|
381 |
|
382 // ----------------------------------------------------------------------------- |
|
383 // CTransactionInfo::CompareRequestLine |
|
384 // Don't compare ACK's Request-URI, as it can be different than in INVITE. |
|
385 // ----------------------------------------------------------------------------- |
|
386 // |
|
387 TBool CTransactionInfo::CompareRequestLine(const CURIContainer& aReqUri, |
|
388 RStringF aMethod, |
|
389 TBool aSearchCanceledUas) const |
|
390 { |
|
391 if (iRequestURI) |
|
392 { |
|
393 if (aMethod == SIPStrings::StringF(SipStrConsts::EAck)) |
|
394 { |
|
395 return CompareMethod(aMethod); |
|
396 } |
|
397 |
|
398 if (aReqUri == *iRequestURI) |
|
399 { |
|
400 return (aSearchCanceledUas || CompareMethod(aMethod)); |
|
401 } |
|
402 } |
|
403 |
|
404 return EFalse; |
|
405 } |
|
406 |
|
407 // ----------------------------------------------------------------------------- |
|
408 // CTransactionInfo::CompareHeaders |
|
409 // If ACK, don't compare top Via. |
|
410 // ----------------------------------------------------------------------------- |
|
411 // |
|
412 TBool CTransactionInfo::CompareHeaders(CSIPRequest& aReq) const |
|
413 { |
|
414 __ASSERT_DEBUG(aReq.RequestURI() != NULL && |
|
415 aReq.HasHeader(SIPStrings::StringF(SipStrConsts::EViaHeader)) && |
|
416 aReq.HasHeader(SIPStrings::StringF(SipStrConsts::EFromHeader)) && |
|
417 aReq.HasHeader(SIPStrings::StringF(SipStrConsts::EToHeader)) && |
|
418 aReq.HasHeader(SIPStrings::StringF(SipStrConsts::ECSeqHeader)) && |
|
419 aReq.HasHeader(SIPStrings::StringF(SipStrConsts::ECallIDHeader)), |
|
420 User::Panic(_L("CTaInfo:Compare aReq"), KErrArgument)); |
|
421 __ASSERT_DEBUG(RequiredHeadersPresent(), |
|
422 User::Panic(_L("CTaInfo:Compare headers not stored"), KErrArgument)); |
|
423 |
|
424 |
|
425 |
|
426 if (CSIPMessageUtility::CompareTags(*iTo, *aReq.To()) && |
|
427 CSIPMessageUtility::CompareTags(*iFrom, *aReq.From()) && |
|
428 *iCallID == *aReq.CallID() && |
|
429 iCSeq == aReq.CSeq()->Seq()) |
|
430 { |
|
431 if(CSIPMessageUtility::IsAck(aReq)) |
|
432 return ETrue; |
|
433 else |
|
434 { |
|
435 CSIPViaHeader* topvia = CSIPMessageUtility::TopVia(aReq); |
|
436 if (topvia) |
|
437 return(*topvia == TopVia()); |
|
438 } |
|
439 } |
|
440 return EFalse; |
|
441 } |
|
442 |
|
443 |
|
444 // ----------------------------------------------------------------------------- |
|
445 // CTransactionInfo::IsMergedRequest |
|
446 // aCSeqMethod can't be ACK, as stray ACKs are dropped. |
|
447 // ----------------------------------------------------------------------------- |
|
448 // |
|
449 TBool CTransactionInfo::IsMergedRequest(const CUserAgent& aUserAgent, |
|
450 CSIPFromHeader& aFrom, |
|
451 CSIPCallIDHeader& aCallID, |
|
452 TUint aCSeqNbr, |
|
453 RStringF aCSeqMethod) const |
|
454 { |
|
455 __ASSERT_DEBUG(aCSeqMethod != SIPStrings::StringF(SipStrConsts::EAck), |
|
456 User::Panic(_L("CTaInfo:IsMergedRequest"), KErrArgument)); |
|
457 return (iUserAgent != &aUserAgent) && |
|
458 iFrom && |
|
459 iCallID && |
|
460 MethodExists() && |
|
461 CSIPMessageUtility::CompareTags(aFrom, *iFrom) && |
|
462 (aCallID == *iCallID) && |
|
463 (aCSeqNbr == iCSeq) && |
|
464 iUserAgent->IsUAS() && // Allow application to send request to itself |
|
465 // Allow receiving CANCEL |
|
466 (iMethod != SIPStrings::StringF(SipStrConsts::EInvite) || |
|
467 aCSeqMethod != SIPStrings::StringF(SipStrConsts::ECancel)); |
|
468 } |
|
469 |
|
470 // ----------------------------------------------------------------------------- |
|
471 // CTransactionInfo::TransactionHeadersL |
|
472 // ----------------------------------------------------------------------------- |
|
473 // |
|
474 MTransactionHeaders* CTransactionInfo::TransactionHeadersL() |
|
475 { |
|
476 return CTransactionHeaders::NewL(iRequestURI, |
|
477 iTo, |
|
478 iFrom, |
|
479 iCallID, |
|
480 iCSeq, |
|
481 iRecordRoute, |
|
482 iContact); |
|
483 } |
|
484 |
|
485 // ----------------------------------------------------------------------------- |
|
486 // CTransactionInfo::CopyToFromCallIDCSeqToMsgL |
|
487 // Copy headers only if they don't exist. |
|
488 // ----------------------------------------------------------------------------- |
|
489 // |
|
490 void CTransactionInfo::CopyToFromCallIDCSeqToMsgL(CSIPMessage& aMsg) const |
|
491 { |
|
492 if (iTo && !aMsg.HasHeader(SIPStrings::StringF(SipStrConsts::EToHeader))) |
|
493 { |
|
494 CSIPToHeader* to = CSIPToHeader::NewLC(*iTo); |
|
495 aMsg.AddHeaderL(to); |
|
496 CleanupStack::Pop(to); |
|
497 } |
|
498 |
|
499 if (iFrom && |
|
500 !aMsg.HasHeader(SIPStrings::StringF(SipStrConsts::EFromHeader))) |
|
501 { |
|
502 CSIPFromHeader* from = CSIPFromHeader::NewLC(*iFrom); |
|
503 aMsg.AddHeaderL(from); |
|
504 CleanupStack::Pop(from); |
|
505 } |
|
506 |
|
507 if (iCallID && |
|
508 !aMsg.HasHeader(SIPStrings::StringF(SipStrConsts::ECallIDHeader))) |
|
509 { |
|
510 CSIPCallIDHeader* callID = |
|
511 static_cast<CSIPCallIDHeader*>(iCallID->CloneL()); |
|
512 CleanupStack::PushL(callID); |
|
513 aMsg.AddHeaderL(callID); |
|
514 CleanupStack::Pop(callID); |
|
515 } |
|
516 |
|
517 CSIPMessageUtility::FillCSeqL(aMsg, |
|
518 iCSeq, |
|
519 aMsg.IsRequest() ? static_cast<CSIPRequest&>(aMsg).Method() : iMethod); |
|
520 } |
|
521 |
|
522 // ----------------------------------------------------------------------------- |
|
523 // CTransactionInfo::CopyViaHeadersToMsgL |
|
524 // ----------------------------------------------------------------------------- |
|
525 // |
|
526 void CTransactionInfo::CopyViaHeadersToMsgL(CSIPMessage& aMsg) const |
|
527 { |
|
528 for (TInt i = 0; i < iViaHeaders.Count(); ++i) |
|
529 { |
|
530 CSIPViaHeader* via = |
|
531 static_cast<CSIPViaHeader*>(iViaHeaders[i]->CloneL()); |
|
532 CleanupStack::PushL(via); |
|
533 aMsg.AddHeaderL(via); |
|
534 CleanupStack::Pop(via); |
|
535 } |
|
536 } |
|
537 |
|
538 // ----------------------------------------------------------------------------- |
|
539 // CTransactionInfo::CopyRequestUriToRequestL |
|
540 // ----------------------------------------------------------------------------- |
|
541 // |
|
542 void CTransactionInfo::CopyRequestUriToRequestL(CSIPRequest& aReq) const |
|
543 { |
|
544 __SIP_ASSERT_LEAVE(iRequestURI, KErrNotFound); |
|
545 |
|
546 CURIContainer* reqUri = CURIContainer::NewLC(*iRequestURI); |
|
547 aReq.SetRequestURIL(reqUri); |
|
548 CleanupStack::Pop(reqUri); |
|
549 } |
|
550 |
|
551 // ----------------------------------------------------------------------------- |
|
552 // CTransactionInfo::BuildRequestFromStoredInfoL |
|
553 // ----------------------------------------------------------------------------- |
|
554 // |
|
555 CSIPRequest* CTransactionInfo::BuildRequestFromStoredInfoL() const |
|
556 { |
|
557 CSIPRequest* req(NULL); |
|
558 if (iRequestURI && iTo && iFrom && MethodExists()) |
|
559 { |
|
560 req = CSIPRequest::NewLC(iMethod); |
|
561 CopyToFromCallIDCSeqToMsgL(*req); |
|
562 CopyRequestUriToRequestL(*req); |
|
563 CleanupStack::Pop(req); |
|
564 } |
|
565 return req; |
|
566 } |
|
567 |
|
568 // ----------------------------------------------------------------------------- |
|
569 // CTransactionInfo::RequestMethod |
|
570 // ----------------------------------------------------------------------------- |
|
571 // |
|
572 RStringF CTransactionInfo::RequestMethod() const |
|
573 { |
|
574 return iMethod; |
|
575 } |