|
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 : SIPMessageUtility.cpp |
|
15 // Part of : TransactionUser |
|
16 // Version : SIP/5.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include <in_sock.h> |
|
22 #include <e32math.h> |
|
23 #include <utf.h> |
|
24 |
|
25 #include "SipAssert.h" |
|
26 #include "siprequest.h" |
|
27 #include "sipresponse.h" |
|
28 #include "sipuri.h" |
|
29 #include "uricontainer.h" |
|
30 #include "sipviaheader.h" |
|
31 #include "sipfromheader.h" |
|
32 #include "siptoheader.h" |
|
33 #include "sipaddress.h" |
|
34 #include "siphostport.h" |
|
35 #include "sipcseqheader.h" |
|
36 #include "sipstrings.h" |
|
37 #include "sipstrconsts.h" |
|
38 |
|
39 #include "SIPMessageUtility.h" |
|
40 #include "CUserAgent.h" |
|
41 |
|
42 |
|
43 const TInt KMaxBitsReturned = 6; |
|
44 const TInt KBitsInByte = 8; |
|
45 |
|
46 //Length of CSIPMessageUtility::iCounter as characters in hex representation |
|
47 const TInt KCounterLength = 8; |
|
48 |
|
49 |
|
50 // ----------------------------------------------------------------------------- |
|
51 // CSIPMessageUtility::CSIPMessageUtility |
|
52 // ----------------------------------------------------------------------------- |
|
53 // |
|
54 CSIPMessageUtility::CSIPMessageUtility() |
|
55 { |
|
56 TUint ticks = User::TickCount(); |
|
57 TTime now; |
|
58 now.UniversalTime(); |
|
59 TInt64 us = now.Int64(); |
|
60 |
|
61 iSeed = static_cast<TInt64>(ticks) + us; |
|
62 iCounter = I64LOW(us) - ticks; |
|
63 } |
|
64 |
|
65 // ----------------------------------------------------------------------------- |
|
66 // CSIPMessageUtility::~CSIPMessageUtility |
|
67 // ----------------------------------------------------------------------------- |
|
68 // |
|
69 CSIPMessageUtility::~CSIPMessageUtility() |
|
70 { |
|
71 } |
|
72 |
|
73 // ----------------------------------------------------------------------------- |
|
74 // CSIPMessageUtility::CompareTInetAddr |
|
75 // aAddr2 always has port filled. |
|
76 // ----------------------------------------------------------------------------- |
|
77 // |
|
78 TBool CSIPMessageUtility::CompareTInetAddr(const TInetAddr& aAddr, |
|
79 RStringF aTransportProtocol, |
|
80 const TInetAddr& aAddr2) |
|
81 { |
|
82 return aAddr.Match(aAddr2) && |
|
83 (SIPPort(aAddr, aTransportProtocol) == aAddr2.Port()); |
|
84 } |
|
85 |
|
86 // ----------------------------------------------------------------------------- |
|
87 // CSIPMessageUtility::SIPPort |
|
88 // ----------------------------------------------------------------------------- |
|
89 // |
|
90 TUint CSIPMessageUtility::SIPPort(const TInetAddr& aAddr, |
|
91 RStringF aTransportProtocol) |
|
92 { |
|
93 const TUint KDefaultSipPort = 5060; |
|
94 const TUint KDefaultSipPortForTLS = 5061; |
|
95 |
|
96 if (aAddr.Port() == 0) |
|
97 { |
|
98 if (aTransportProtocol == SIPStrings::StringF(SipStrConsts::ETLS)) |
|
99 { |
|
100 return KDefaultSipPortForTLS; |
|
101 } |
|
102 |
|
103 return KDefaultSipPort; |
|
104 } |
|
105 return aAddr.Port(); |
|
106 } |
|
107 |
|
108 // ----------------------------------------------------------------------------- |
|
109 // CSIPMessageUtility::ConvertUtf8LC |
|
110 // ----------------------------------------------------------------------------- |
|
111 // |
|
112 HBufC* CSIPMessageUtility::ConvertUtf8LC(const TDesC8& aUtf8) |
|
113 { |
|
114 HBufC* unicode = HBufC::NewLC(aUtf8.Size()); |
|
115 TPtr ptr = unicode->Des(); |
|
116 |
|
117 User::LeaveIfError(CnvUtfConverter::ConvertToUnicodeFromUtf8(ptr, aUtf8)); |
|
118 |
|
119 return unicode; |
|
120 } |
|
121 |
|
122 // ----------------------------------------------------------------------------- |
|
123 // CSIPMessageUtility::AddRandomStringL |
|
124 // ----------------------------------------------------------------------------- |
|
125 // |
|
126 void CSIPMessageUtility::AddRandomStringL(TDes8& aBuf, |
|
127 TInt aLength, |
|
128 TBool aCaseSensitive, |
|
129 CSIPMessage* aMsg, |
|
130 TTransactionId aTransactionId, |
|
131 const CUserAgent* aUserAgent) |
|
132 { |
|
133 __SIP_ASSERT_LEAVE(aLength <= aBuf.MaxLength() - aBuf.Length(), |
|
134 KErrOverflow); |
|
135 |
|
136 HBufC8* data = BuildInputDataL(aLength, aMsg, aTransactionId, aUserAgent); |
|
137 |
|
138 //2^KMaxBitsReturned (64) valid chars that can be put to descriptor |
|
139 _LIT8(KCharStore, |
|
140 "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"); |
|
141 TInt amountOfBits = KMaxBitsReturned; |
|
142 if (!aCaseSensitive) |
|
143 { |
|
144 //The capital letters are not used |
|
145 amountOfBits--; |
|
146 } |
|
147 |
|
148 TUint counter = 0; |
|
149 for (TInt i = 0; i < aLength; i++) |
|
150 { |
|
151 aBuf.Append(KCharStore()[CSIPMessageUtility::GetNextBits( |
|
152 *data, amountOfBits, counter) % KCharStore().Length()]); |
|
153 } |
|
154 |
|
155 delete data; |
|
156 } |
|
157 |
|
158 // ----------------------------------------------------------------------------- |
|
159 // CSIPMessageUtility::BuildInputDataL |
|
160 // Use the best source of randomness first, and add pseudorandom numbers until |
|
161 // there is enough data. |
|
162 // ----------------------------------------------------------------------------- |
|
163 // |
|
164 HBufC8* CSIPMessageUtility::BuildInputDataL(TUint aLength, |
|
165 CSIPMessage* aMsg, |
|
166 TTransactionId aTransactionId, |
|
167 const CUserAgent* aUserAgent) |
|
168 { |
|
169 //Extra bytes at end to have enough data for getting aLength amount of |
|
170 //KMaxBitsReturned bit sequences. |
|
171 const TInt KExtra = 4; |
|
172 HBufC8* buf = |
|
173 HBufC8::NewLC(((aLength * KMaxBitsReturned) / KBitsInByte) + KExtra); |
|
174 TPtr8 ptr = buf->Des(); |
|
175 |
|
176 //First two bytes are filled later. Terminate string with a zero. |
|
177 const TUint8 reserveString[] = {1, 1, 0}; |
|
178 ptr = reserveString; |
|
179 |
|
180 //Increment the counter every time the input data is created so even if To, |
|
181 //From etc. headers are same, output differs. |
|
182 iCounter++; |
|
183 |
|
184 AddCheckSumOfSipMessageL(aMsg, ptr); |
|
185 AddCheckSumOfTaIdL(aTransactionId, ptr); |
|
186 AddSystemInfo(ptr); |
|
187 |
|
188 if (aUserAgent && FitsInBuf(ptr, sizeof(TUint16))) |
|
189 { |
|
190 //UserAgent's current state |
|
191 ComputeChecksum(ptr, aUserAgent, sizeof(*aUserAgent)); |
|
192 } |
|
193 |
|
194 TInt random = 0; |
|
195 while (FitsInBuf(ptr, sizeof(random))) |
|
196 { |
|
197 random = Math::Rand(iSeed); |
|
198 ptr.Append(reinterpret_cast<const TUint8*>(&random), sizeof(random)); |
|
199 } |
|
200 |
|
201 //Write buf's checksum to the two reserved bytes. |
|
202 TUint16 cs = 0; |
|
203 Mem::Crc(cs, ptr.Ptr(), buf->Length()); |
|
204 ptr[0] = static_cast<TUint8>((cs & 0xff00) >> KBitsInByte); |
|
205 ptr[1] = static_cast<TUint8>(cs & 0xff); |
|
206 |
|
207 CleanupStack::Pop(buf); |
|
208 return buf; |
|
209 } |
|
210 |
|
211 // ----------------------------------------------------------------------------- |
|
212 // CSIPMessageUtility::GetNextBits |
|
213 // ----------------------------------------------------------------------------- |
|
214 // |
|
215 TUint8 |
|
216 CSIPMessageUtility::GetNextBits(const TDesC8& aBuf, TInt aBits, TUint& aCounter) |
|
217 { |
|
218 if (aBuf.Length() == 0) |
|
219 { |
|
220 return 0; |
|
221 } |
|
222 |
|
223 //Amount of aBits long bit sequences in aBuf |
|
224 TUint sixBitItems = aBuf.Length() * KBitsInByte / aBits; |
|
225 |
|
226 if (aCounter >= sixBitItems) |
|
227 { |
|
228 aCounter = 0; |
|
229 } |
|
230 |
|
231 //The position in aBuf, of the byte containing the first bit of the aBits |
|
232 //long bit sequence. Zero means the first byte. |
|
233 TInt startByte = aCounter * aBits / KBitsInByte; |
|
234 TUint16 result = static_cast<TUint16>(aBuf[startByte] << KBitsInByte); |
|
235 |
|
236 if (++startByte >= aBuf.Length()) |
|
237 { |
|
238 startByte = 0; |
|
239 } |
|
240 |
|
241 result = static_cast<TUint16>(result | aBuf[startByte]); |
|
242 |
|
243 |
|
244 //The position of the first bit of the aBits long bit sequence, within the |
|
245 //byte. Zero means the first bit. |
|
246 TUint offsetInsideByte = (aCounter * aBits) % KBitsInByte; |
|
247 |
|
248 //Remove excess bits from the result |
|
249 result = static_cast<TUint16>(result << offsetInsideByte); |
|
250 result >>= ((2 * KBitsInByte) - aBits); |
|
251 |
|
252 __ASSERT_DEBUG(result < (1 << aBits), |
|
253 User::Panic(_L("CSIPMsgUtil:GetNextBits"), KErrOverflow)); |
|
254 aCounter++; |
|
255 return static_cast<TUint8>(result); |
|
256 } |
|
257 |
|
258 // ----------------------------------------------------------------------------- |
|
259 // CSIPMessageUtility::FitsInBuf |
|
260 // ----------------------------------------------------------------------------- |
|
261 // |
|
262 TBool CSIPMessageUtility::FitsInBuf(const TDes8& aBuf, TInt aSize) |
|
263 { |
|
264 return (aBuf.Size() <= aBuf.MaxSize() - aSize); |
|
265 } |
|
266 |
|
267 // ----------------------------------------------------------------------------- |
|
268 // CSIPMessageUtility::AddCheckSumOfSipMessageL |
|
269 // ----------------------------------------------------------------------------- |
|
270 // |
|
271 void CSIPMessageUtility::AddCheckSumOfSipMessageL(CSIPMessage* aMsg, |
|
272 TDes8& aBuf) |
|
273 { |
|
274 if (aMsg) |
|
275 { |
|
276 if (aMsg->HasHeader(SIPStrings::StringF(SipStrConsts::EToHeader))) |
|
277 { |
|
278 AddCheckSumOfFromToHeaderL(*aMsg->To(), aBuf); |
|
279 } |
|
280 |
|
281 if (aMsg->HasHeader(SIPStrings::StringF(SipStrConsts::EFromHeader))) |
|
282 { |
|
283 AddCheckSumOfFromToHeaderL(*aMsg->From(), aBuf); |
|
284 } |
|
285 |
|
286 AddCheckSumOfCSeq(*aMsg, aBuf); |
|
287 AddCheckSumOfRequestLineL(*aMsg, aBuf); |
|
288 } |
|
289 } |
|
290 |
|
291 // ----------------------------------------------------------------------------- |
|
292 // CSIPMessageUtility::AddCheckSumOfFromToHeaderL |
|
293 // ----------------------------------------------------------------------------- |
|
294 // |
|
295 void |
|
296 CSIPMessageUtility::AddCheckSumOfFromToHeaderL(CSIPFromToHeaderBase& aHeader, |
|
297 TDes8& aBuf) |
|
298 { |
|
299 if (FitsInBuf(aBuf, sizeof(TUint16))) |
|
300 { |
|
301 HBufC8* toBuf = aHeader.SIPAddress().ToTextLC(); |
|
302 HBufC8* buf = HBufC8::NewLC(KCounterLength + toBuf->Length()); |
|
303 TPtr8 ptr = buf->Des(); |
|
304 |
|
305 //Add iCounter at the beginning, to get a greater effect on output |
|
306 ptr.AppendFormat(_L8("%x"), iCounter); |
|
307 ptr.Append(*toBuf); |
|
308 |
|
309 ComputeChecksum(aBuf, buf, buf->Length()); |
|
310 |
|
311 CleanupStack::PopAndDestroy(buf); |
|
312 CleanupStack::PopAndDestroy(toBuf); |
|
313 } |
|
314 } |
|
315 |
|
316 // ----------------------------------------------------------------------------- |
|
317 // CSIPMessageUtility::AddCheckSumOfCSeq |
|
318 // ----------------------------------------------------------------------------- |
|
319 // |
|
320 void CSIPMessageUtility::AddCheckSumOfCSeq(CSIPMessage& aMsg, TDes8& aBuf) |
|
321 { |
|
322 if (aMsg.HasHeader(SIPStrings::StringF(SipStrConsts::ECSeqHeader)) && |
|
323 FitsInBuf(aBuf, sizeof(TUint16))) |
|
324 { |
|
325 TUint cseq = aMsg.CSeq()->Seq(); |
|
326 ComputeChecksum(aBuf, &cseq, sizeof(cseq)); |
|
327 } |
|
328 } |
|
329 |
|
330 // ----------------------------------------------------------------------------- |
|
331 // CSIPMessageUtility::AddCheckSumOfClock |
|
332 // ----------------------------------------------------------------------------- |
|
333 // |
|
334 void CSIPMessageUtility::AddCheckSumOfClock(TDes8& aBuf) const |
|
335 { |
|
336 if (FitsInBuf(aBuf, sizeof(TUint16))) |
|
337 { |
|
338 TTime now; |
|
339 now.UniversalTime(); |
|
340 TInt64 timeAsInt = now.Int64(); |
|
341 TBuf8<20> timeBuf; |
|
342 |
|
343 //Add iCounter before timeAsInt. If this function is called very often, |
|
344 //timeAsInt can be same as in the previous call. |
|
345 timeBuf.Append(reinterpret_cast<const TUint8*>(&iCounter), |
|
346 sizeof(iCounter)); |
|
347 timeBuf.Append(reinterpret_cast<const TUint8*>(&timeAsInt), |
|
348 sizeof(timeAsInt)); |
|
349 ComputeChecksum(aBuf, &timeBuf, timeBuf.Length()); |
|
350 |
|
351 if (FitsInBuf(aBuf, sizeof(TUint16))) |
|
352 { |
|
353 timeBuf.Zero(); |
|
354 timeBuf.Append(reinterpret_cast<const TUint8*>(&iCounter), |
|
355 sizeof(iCounter)); |
|
356 TUint ticks = User::TickCount(); |
|
357 timeBuf.Append(reinterpret_cast<const TUint8*>(&ticks), |
|
358 sizeof(ticks)); |
|
359 ComputeChecksum(aBuf, &timeBuf, timeBuf.Length()); |
|
360 } |
|
361 } |
|
362 } |
|
363 |
|
364 // ----------------------------------------------------------------------------- |
|
365 // CSIPMessageUtility::AddCheckSumOfTaIdL |
|
366 // Add counter first, so it has greater effect on output. |
|
367 // ----------------------------------------------------------------------------- |
|
368 // |
|
369 void CSIPMessageUtility::AddCheckSumOfTaIdL(TTransactionId aTransactionId, |
|
370 TDes8& aBuf) |
|
371 { |
|
372 if (aTransactionId != KEmptyTransactionId && |
|
373 FitsInBuf(aBuf, sizeof(TUint16))) |
|
374 { |
|
375 const TInt KTransactionIdLengthInHex = 8; |
|
376 HBufC8* buf = HBufC8::NewLC(KCounterLength + KTransactionIdLengthInHex); |
|
377 TPtr8 ptr = buf->Des(); |
|
378 ptr.AppendFormat(_L8("%x%x"), iCounter, aTransactionId); |
|
379 |
|
380 ComputeChecksum(aBuf, buf, buf->Length()); |
|
381 CleanupStack::PopAndDestroy(buf); |
|
382 } |
|
383 } |
|
384 |
|
385 // ----------------------------------------------------------------------------- |
|
386 // CSIPMessageUtility::AddCheckSumOfRequestLineL |
|
387 // ----------------------------------------------------------------------------- |
|
388 // |
|
389 void CSIPMessageUtility::AddCheckSumOfRequestLineL(CSIPMessage& aMsg, |
|
390 TDes8& aBuf) |
|
391 { |
|
392 if (aMsg.IsRequest() && FitsInBuf(aBuf, sizeof(TUint16))) |
|
393 { |
|
394 CSIPRequest& req = static_cast<CSIPRequest&>(aMsg); |
|
395 if (req.RequestURI()) |
|
396 { |
|
397 HBufC8* uriBuf = req.RequestURI()->ToTextL(); |
|
398 CleanupStack::PushL(uriBuf); |
|
399 |
|
400 HBufC8* buf = |
|
401 HBufC8::NewLC(uriBuf->Length() + req.Method().DesC().Length()); |
|
402 TPtr8 ptr = buf->Des(); |
|
403 ptr.Append(*uriBuf); |
|
404 ptr.Append(req.Method().DesC()); |
|
405 |
|
406 ComputeChecksum(aBuf, buf, buf->Length()); |
|
407 |
|
408 CleanupStack::PopAndDestroy(buf); |
|
409 CleanupStack::PopAndDestroy(uriBuf); |
|
410 } |
|
411 } |
|
412 } |
|
413 |
|
414 // ----------------------------------------------------------------------------- |
|
415 // CSIPMessageUtility::AddSystemInfo |
|
416 // ----------------------------------------------------------------------------- |
|
417 // |
|
418 void CSIPMessageUtility::AddSystemInfo(TDes8& aBuf) const |
|
419 { |
|
420 AddCheckSumOfClock(aBuf); |
|
421 |
|
422 if (FitsInBuf(aBuf, sizeof(TUint16))) |
|
423 { |
|
424 TInt largest = 0; |
|
425 TInt total = User::Available(largest); |
|
426 TInt value = (largest + total - User::CountAllocCells()) + iCounter; |
|
427 ComputeChecksum(aBuf, &value, sizeof(value)); |
|
428 } |
|
429 |
|
430 if (FitsInBuf(aBuf, sizeof(TUint8))) |
|
431 { |
|
432 TTimeIntervalSeconds inactivity = User::InactivityTime(); |
|
433 if (inactivity.Int() > 0) |
|
434 { |
|
435 TUint8 byteVal = static_cast<TUint8>(inactivity.Int() & 0xff); |
|
436 aBuf.Append(&byteVal, sizeof(byteVal)); |
|
437 } |
|
438 } |
|
439 } |
|
440 |
|
441 // ----------------------------------------------------------------------------- |
|
442 // CSIPMessageUtility::ComputeChecksum |
|
443 // ----------------------------------------------------------------------------- |
|
444 // |
|
445 void |
|
446 CSIPMessageUtility::ComputeChecksum(TDes8& aBuf, const TAny* aPtr, TInt aLength) |
|
447 { |
|
448 __SIP_ASSERT_RETURN(aPtr != NULL, KErrArgument); |
|
449 |
|
450 TUint16 cs = 0; |
|
451 Mem::Crc(cs, aPtr, aLength); |
|
452 aBuf.Append(reinterpret_cast<const TUint8*>(&cs), sizeof(cs)); |
|
453 } |
|
454 |
|
455 // ----------------------------------------------------------------------------- |
|
456 // CSIPMessageUtility::MessageMethod |
|
457 // ----------------------------------------------------------------------------- |
|
458 // |
|
459 RStringF CSIPMessageUtility::MessageMethod(CSIPMessage& aMsg) |
|
460 { |
|
461 if (aMsg.IsRequest()) |
|
462 { |
|
463 return static_cast<const CSIPRequest&>(aMsg).Method(); |
|
464 } |
|
465 |
|
466 __ASSERT_DEBUG(aMsg.CSeq() != NULL, |
|
467 User::Panic(_L("CSIPMsgUtil:MsgMethod"), KErrArgument)); |
|
468 return aMsg.CSeq()->Method(); |
|
469 } |
|
470 |
|
471 // ----------------------------------------------------------------------------- |
|
472 // CSIPMessageUtility::TransactionType |
|
473 // ----------------------------------------------------------------------------- |
|
474 // |
|
475 CTransactionBase::TTransactionType |
|
476 CSIPMessageUtility::TransactionType(CSIPMessage& aMsg, TBool aIncomingMsg) |
|
477 { |
|
478 __ASSERT_ALWAYS( |
|
479 aMsg.HasHeader(SIPStrings::StringF(SipStrConsts::ECSeqHeader)), |
|
480 User::Panic(_L("MsgUt:TType CSeq"), KErrArgument)); |
|
481 |
|
482 RStringF cseqMethod = aMsg.CSeq()->Method(); |
|
483 if (cseqMethod == SIPStrings::StringF(SipStrConsts::EInvite) || |
|
484 cseqMethod == SIPStrings::StringF(SipStrConsts::EAck)) |
|
485 { |
|
486 if (aMsg.IsRequest() ^ aIncomingMsg) |
|
487 { |
|
488 //Outgoing request or incoming response |
|
489 return CTransactionBase::KClientInviteTransaction; |
|
490 } |
|
491 |
|
492 return CTransactionBase::KServerInviteTransaction; |
|
493 } |
|
494 |
|
495 if (aMsg.IsRequest() ^ aIncomingMsg) |
|
496 { |
|
497 return CTransactionBase::KClientTransaction; |
|
498 } |
|
499 |
|
500 return CTransactionBase::KServerTransaction; |
|
501 } |
|
502 |
|
503 // ----------------------------------------------------------------------------- |
|
504 // CSIPMessageUtility::HasViaMagicCookie |
|
505 // ----------------------------------------------------------------------------- |
|
506 // |
|
507 TBool CSIPMessageUtility::HasViaMagicCookie(CSIPMessage& aMsg) |
|
508 { |
|
509 CSIPViaHeader* topVia = TopVia(aMsg); |
|
510 RStringF branch = SIPStrings::StringF(SipStrConsts::EBranch); |
|
511 |
|
512 return topVia && |
|
513 topVia->HasParam(branch) && |
|
514 topVia->ParamValue(branch).DesC().Left( |
|
515 BranchMagicCookie().Length()).Compare(BranchMagicCookie()) == 0; |
|
516 } |
|
517 |
|
518 // ----------------------------------------------------------------------------- |
|
519 // CSIPMessageUtility::CheckTransport |
|
520 // ----------------------------------------------------------------------------- |
|
521 // |
|
522 TBool CSIPMessageUtility::CheckTransport(RStringF aTransport) |
|
523 { |
|
524 return aTransport == SIPStrings::StringF(SipStrConsts::EUDP) || |
|
525 aTransport == SIPStrings::StringF(SipStrConsts::ETCP) || |
|
526 aTransport == SIPStrings::StringF(SipStrConsts::ETLS); |
|
527 } |
|
528 |
|
529 // ----------------------------------------------------------------------------- |
|
530 // CSIPMessageUtility::TransportProtocol |
|
531 // ----------------------------------------------------------------------------- |
|
532 // |
|
533 TBool CSIPMessageUtility::TransportProtocol(CSIPMessage& aMsg, |
|
534 RStringF& aTransport) |
|
535 { |
|
536 CSIPViaHeader* topVia = TopVia(aMsg); |
|
537 if (topVia && CheckTransport(topVia->Transport())) |
|
538 { |
|
539 aTransport.Close(); |
|
540 aTransport = topVia->Transport().Copy(); |
|
541 return ETrue; |
|
542 } |
|
543 |
|
544 return EFalse; |
|
545 } |
|
546 |
|
547 // ----------------------------------------------------------------------------- |
|
548 // CSIPMessageUtility::UpdateViaTransportL |
|
549 // ----------------------------------------------------------------------------- |
|
550 // |
|
551 void CSIPMessageUtility::UpdateViaTransportL(CSIPMessage& aMsg, |
|
552 RStringF aTransport) |
|
553 { |
|
554 __SIP_ASSERT_LEAVE(CheckTransport(aTransport), KErrArgument); |
|
555 |
|
556 CSIPViaHeader* topVia = TopVia(aMsg); |
|
557 __SIP_ASSERT_LEAVE(topVia != NULL, KErrArgument); |
|
558 |
|
559 topVia->SetTransportL(aTransport); |
|
560 } |
|
561 |
|
562 // ----------------------------------------------------------------------------- |
|
563 // CSIPMessageUtility::CompareTags |
|
564 // If either tag is missing, tags are considered equal |
|
565 // ----------------------------------------------------------------------------- |
|
566 // |
|
567 TBool CSIPMessageUtility::CompareTags(const CSIPFromToHeaderBase& aHeader, |
|
568 const CSIPFromToHeaderBase& aHeader2) |
|
569 { |
|
570 RStringF tag = SIPStrings::StringF(SipStrConsts::ETag); |
|
571 if (aHeader.HasParam(tag) && aHeader2.HasParam(tag)) |
|
572 { |
|
573 return aHeader.ParamValue(tag) == aHeader2.ParamValue(tag); |
|
574 } |
|
575 |
|
576 return ETrue; |
|
577 } |
|
578 |
|
579 // ----------------------------------------------------------------------------- |
|
580 // CSIPMessageUtility::CopyHeadersL |
|
581 // If aDest already has headers, they are deleted. |
|
582 // ----------------------------------------------------------------------------- |
|
583 // |
|
584 void CSIPMessageUtility::CopyHeadersL(CSIPMessage& aSrc, |
|
585 CSIPMessage& aDest, |
|
586 RStringF aHeaderName) |
|
587 { |
|
588 if (aDest.HasHeader(aHeaderName)) |
|
589 { |
|
590 aDest.DeleteHeaders(aHeaderName); |
|
591 } |
|
592 |
|
593 if (aSrc.HasHeader(aHeaderName)) |
|
594 { |
|
595 TSglQueIter<CSIPHeaderBase> iter = aSrc.Headers(aHeaderName); |
|
596 |
|
597 for (CSIPHeaderBase* srcHeader = iter++; srcHeader; srcHeader= iter++) |
|
598 { |
|
599 CSIPHeaderBase* destHeader = srcHeader->CloneL(); |
|
600 CleanupStack::PushL(destHeader); |
|
601 aDest.AddHeaderL(destHeader); |
|
602 CleanupStack::Pop(destHeader); |
|
603 } |
|
604 } |
|
605 } |
|
606 |
|
607 // ----------------------------------------------------------------------------- |
|
608 // CSIPMessageUtility::CopyAuthorizationHeadersL |
|
609 // ----------------------------------------------------------------------------- |
|
610 // |
|
611 void CSIPMessageUtility::CopyAuthorizationHeadersL(CSIPMessage* aSrc, |
|
612 CSIPMessage& aDest) |
|
613 { |
|
614 if (aSrc) |
|
615 { |
|
616 CopyHeadersL(*aSrc, |
|
617 aDest, |
|
618 SIPStrings::StringF(SipStrConsts::EAuthorizationHeader)); |
|
619 CopyHeadersL(*aSrc, |
|
620 aDest, |
|
621 SIPStrings::StringF(SipStrConsts::EProxyAuthorizationHeader)); |
|
622 } |
|
623 } |
|
624 |
|
625 // ----------------------------------------------------------------------------- |
|
626 // CSIPMessageUtility::CopyHeaderFromMsgL |
|
627 // ----------------------------------------------------------------------------- |
|
628 // |
|
629 CSIPHeaderBase* |
|
630 CSIPMessageUtility::CopyHeaderFromMsgL(CSIPMessage& aMsg, RStringF aHeaderName) |
|
631 { |
|
632 if (aMsg.HasHeader(aHeaderName)) |
|
633 { |
|
634 TSglQueIter<CSIPHeaderBase> iter = aMsg.Headers(aHeaderName); |
|
635 CSIPHeaderBase* header = iter; |
|
636 return header->CloneL(); |
|
637 } |
|
638 |
|
639 return NULL; |
|
640 } |
|
641 |
|
642 // ----------------------------------------------------------------------------- |
|
643 // CSIPMessageUtility::FillCSeqL |
|
644 // ----------------------------------------------------------------------------- |
|
645 // |
|
646 void |
|
647 CSIPMessageUtility::FillCSeqL(CSIPMessage& aMsg, TUint aSeq, RStringF aMethod) |
|
648 { |
|
649 if (!aMsg.HasHeader(SIPStrings::StringF(SipStrConsts::ECSeqHeader))) |
|
650 { |
|
651 CSIPCSeqHeader* cseq = CSIPCSeqHeader::NewLC(aSeq, aMethod); |
|
652 aMsg.AddHeaderL(cseq); |
|
653 CleanupStack::Pop(cseq); |
|
654 } |
|
655 } |
|
656 |
|
657 // ----------------------------------------------------------------------------- |
|
658 // CSIPMessageUtility::HasSigCompParam |
|
659 // ----------------------------------------------------------------------------- |
|
660 // |
|
661 TBool CSIPMessageUtility::HasSigCompParam(const CURIContainer& aUri) |
|
662 { |
|
663 RStringF comp = SIPStrings::StringF(SipStrConsts::EComp); |
|
664 return aUri.IsSIPURI() && |
|
665 aUri.SIPURI()->HasParam(comp) && |
|
666 aUri.SIPURI()->ParamValue(comp) == |
|
667 SIPStrings::StringF(SipStrConsts::ESigComp); |
|
668 } |
|
669 |
|
670 // ----------------------------------------------------------------------------- |
|
671 // CSIPMessageUtility::IsAck |
|
672 // ----------------------------------------------------------------------------- |
|
673 // |
|
674 TBool CSIPMessageUtility::IsAck(const CSIPMessage& aMsg) |
|
675 { |
|
676 return aMsg.IsRequest() && |
|
677 (static_cast<const CSIPRequest&>(aMsg).Method() == |
|
678 SIPStrings::StringF(SipStrConsts::EAck)); |
|
679 } |
|
680 |
|
681 // ----------------------------------------------------------------------------- |
|
682 // CSIPMessageUtility::IsFinalResponse |
|
683 // ----------------------------------------------------------------------------- |
|
684 // |
|
685 TBool CSIPMessageUtility::IsFinalResponse(const CSIPResponse& aResp) |
|
686 { |
|
687 return aResp.Type() != CSIPResponse::E1XX; |
|
688 } |
|
689 |
|
690 // ----------------------------------------------------------------------------- |
|
691 // CSIPMessageUtility::Is2xxResponse |
|
692 // ----------------------------------------------------------------------------- |
|
693 // |
|
694 TBool CSIPMessageUtility::Is2xxResponse(const CSIPMessage& aMsg) |
|
695 { |
|
696 return !aMsg.IsRequest() && |
|
697 static_cast<const CSIPResponse&>(aMsg).Type() == CSIPResponse::E2XX; |
|
698 } |
|
699 |
|
700 // ----------------------------------------------------------------------------- |
|
701 // CSIPMessageUtility::TopVia() |
|
702 // ----------------------------------------------------------------------------- |
|
703 // |
|
704 CSIPViaHeader* CSIPMessageUtility::TopVia(CSIPMessage& aMsg) |
|
705 { |
|
706 if (aMsg.HasHeader(SIPStrings::StringF(SipStrConsts::EViaHeader))) |
|
707 { |
|
708 TSglQueIter<CSIPHeaderBase> headers = |
|
709 aMsg.Headers(SIPStrings::StringF(SipStrConsts::EViaHeader)); |
|
710 return &static_cast<CSIPViaHeader&>(*headers); |
|
711 } |
|
712 |
|
713 return NULL; |
|
714 } |
|
715 |
|
716 // ----------------------------------------------------------------------------- |
|
717 // CSIPMessageUtility::BranchMagicCookie() |
|
718 // If Via's Branch begins with this value, the SIP message <-> transaction |
|
719 // mapping is done using the Branch.value. |
|
720 // ----------------------------------------------------------------------------- |
|
721 // |
|
722 const TDesC8& CSIPMessageUtility::BranchMagicCookie() |
|
723 { |
|
724 _LIT8(KMagicCookie, "z9hG4bK"); |
|
725 return KMagicCookie; |
|
726 } |
|
727 |
|
728 // ----------------------------------------------------------------------------- |
|
729 // CSIPMessageUtility::UriDescriptor |
|
730 // ----------------------------------------------------------------------------- |
|
731 // |
|
732 const TDesC8& CSIPMessageUtility::UriDescriptor(const CURIContainer& aUri) |
|
733 { |
|
734 if (aUri.IsSIPURI()) |
|
735 { |
|
736 const CSIPURI& sipuri = *aUri.SIPURI(); |
|
737 RStringF maddr = SIPStrings::StringF(SipStrConsts::EMaddr); |
|
738 |
|
739 if (sipuri.HasParam(maddr)) |
|
740 { |
|
741 return sipuri.ParamValue(maddr).DesC(); |
|
742 } |
|
743 |
|
744 return sipuri.HostPort().Host(); |
|
745 } |
|
746 return aUri.Uri8()->Uri().UriDes(); |
|
747 } |
|
748 |
|
749 // ----------------------------------------------------------------------------- |
|
750 // CSIPMessageUtility::IsPrivateAddressL |
|
751 // ----------------------------------------------------------------------------- |
|
752 // |
|
753 TBool CSIPMessageUtility::IsPrivateAddressL(MSIPTransportMgr& aTransportMgr, |
|
754 TUint32 aIapId) |
|
755 { |
|
756 TInetAddr localAddr; |
|
757 User::LeaveIfError(aTransportMgr.GetLocalAddress(aIapId, localAddr)); |
|
758 |
|
759 // The following addresses are private (RFC 1918): |
|
760 // 10.0.0.0 - 10.255.255.255 |
|
761 const TUint32 KPrivateRange1Low = INET_ADDR(10, 0, 0, 0); |
|
762 const TUint32 KPrivateRange1High = INET_ADDR(10, 255, 255, 255); |
|
763 // 172.16.0.0 - 172.31.255.255 |
|
764 const TUint32 KPrivateRange2Low = INET_ADDR(172, 16, 0, 0); |
|
765 const TUint32 KPrivateRange2High = INET_ADDR(172, 31, 255, 255); |
|
766 // 192.168.0.0 - 192.168.255.255 |
|
767 const TUint32 KPrivateRange3Low = INET_ADDR(192, 168, 0, 0); |
|
768 const TUint32 KPrivateRange3High = INET_ADDR(192, 168, 255, 255); |
|
769 |
|
770 TUint32 addr = localAddr.Address(); |
|
771 //First check if a IPv4 address. IPv6 addresses are always public. |
|
772 return ( localAddr.Address() && |
|
773 ((addr >= KPrivateRange1Low && addr <= KPrivateRange1High) || |
|
774 (addr >= KPrivateRange2Low && addr <= KPrivateRange2High) || |
|
775 (addr >= KPrivateRange3Low && addr <= KPrivateRange3High))); |
|
776 } |