|
1 // Copyright (c) 2005-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 : TSIPRegistrationUtility.cpp |
|
15 // Part of : Registration |
|
16 // Version : SIP/4.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include "TSIPRegistrationUtility.h" |
|
22 #include "MTransactionUser.h" |
|
23 #include "MSigComp.h" |
|
24 #include "siprequest.h" |
|
25 #include "siptoheader.h" |
|
26 #include "sipfromheader.h" |
|
27 #include "sipcontactheader.h" |
|
28 #include "sipaddress.h" |
|
29 #include "uricontainer.h" |
|
30 #include "sipuri.h" |
|
31 #include "siphostport.h" |
|
32 #include "sipexpiresheader.h" |
|
33 #include "siprouteheader.h" |
|
34 #include "CSIPRegistrationBindingBase.h" |
|
35 #include "SipAssert.h" |
|
36 #include "sipstrings.h" |
|
37 #include "sipstrconsts.h" |
|
38 #include "siperr.h" |
|
39 |
|
40 const TInt KOneHourInSeconds = 3600; |
|
41 |
|
42 #define HEADER_IN_REQUEST(H, N) static_cast<H*>(aRequest.Header(N,0)) |
|
43 |
|
44 // ----------------------------------------------------------------------------- |
|
45 // TSIPRegistrationUtility::LocalAddressLC |
|
46 // ----------------------------------------------------------------------------- |
|
47 // |
|
48 HBufC8* TSIPRegistrationUtility::LocalAddressLC (const TUint aIapId, |
|
49 MTransactionUser& aTU) |
|
50 { |
|
51 // get local IP address by giving IAP id |
|
52 TInetAddr localAddress; |
|
53 aTU.GetLocalAddress(aIapId, localAddress); |
|
54 |
|
55 // create Local IP address |
|
56 const TInt KMaxIPAddrLength = 256; |
|
57 HBufC* ipAddressOutputBuf = HBufC::NewLC(KMaxIPAddrLength); |
|
58 TPtr ipAddressOutputPtr(ipAddressOutputBuf->Des()); |
|
59 localAddress.Output(ipAddressOutputPtr); |
|
60 |
|
61 HBufC8* outPutBuf = HBufC8::NewL(ipAddressOutputPtr.Length()); |
|
62 TPtr8 outPutPtr(outPutBuf->Des()); |
|
63 outPutPtr.Copy(ipAddressOutputPtr); |
|
64 CleanupStack::PopAndDestroy(ipAddressOutputBuf); |
|
65 CleanupStack::PushL(outPutBuf); |
|
66 |
|
67 return outPutBuf; |
|
68 } |
|
69 |
|
70 // ----------------------------------------------------------------------------- |
|
71 // TSIPRegistrationUtility::CheckRegisterRequestL |
|
72 // ----------------------------------------------------------------------------- |
|
73 // |
|
74 void TSIPRegistrationUtility::CheckRegisterRequestL ( |
|
75 CSIPRequest& aRequest, |
|
76 const CSIPRouteHeader* aOutboundProxy, |
|
77 const TUint32 aIapId, |
|
78 MTransactionUser& aTU) |
|
79 { |
|
80 // panic if there is no To header in request in debug mode. |
|
81 // leaves with error code KErrArgument in release mode. |
|
82 __SIP_ASSERT_LEAVE(aRequest.To() != 0, KErrArgument); |
|
83 |
|
84 // panic if RegisterRequestNoFromHeader in debug mode. |
|
85 // leaves with error code KErrArgument in release mode. |
|
86 __SIP_ASSERT_LEAVE(aRequest.From() != 0, KErrArgument); |
|
87 |
|
88 CheckToHeaderL(*(aRequest.To())); |
|
89 CheckRegisterContactL(aRequest, aIapId, aTU); |
|
90 CheckRegisterExpiresValueL(aRequest); |
|
91 if (aOutboundProxy) |
|
92 { |
|
93 CheckSipsSchemeInAorAndOtherAddressL( |
|
94 *aRequest.To(),aOutboundProxy->SIPAddress()); |
|
95 } |
|
96 } |
|
97 |
|
98 // ----------------------------------------------------------------------------- |
|
99 // TSIPRegistrationUtility::CheckUpdateRegisterRequestL |
|
100 // ----------------------------------------------------------------------------- |
|
101 // |
|
102 void TSIPRegistrationUtility::CheckUpdateRegisterRequestL ( |
|
103 CSIPRequest& aRequest, |
|
104 CSIPRegistrationBindingBase& aBinding) |
|
105 { |
|
106 // panic if there is to header in update register request in debug |
|
107 // mode. leaves with error code KErrArgument in release build |
|
108 __SIP_ASSERT_LEAVE(!aRequest.To(), KErrArgument); |
|
109 |
|
110 // panic if there is from header in update register request in debug |
|
111 // mode. leaves with error code KErrArgument in release build |
|
112 __SIP_ASSERT_LEAVE(!aRequest.From(), KErrArgument); |
|
113 |
|
114 CheckUpdateRegisterContactL(aRequest, aBinding); |
|
115 CheckUpdateRegisterExpiresValueL(aRequest, aBinding); |
|
116 } |
|
117 |
|
118 // ----------------------------------------------------------------------------- |
|
119 // TSIPRegistrationUtility::CheckUnregisterRequestL |
|
120 // ----------------------------------------------------------------------------- |
|
121 // |
|
122 void TSIPRegistrationUtility::CheckUnregisterRequestL ( |
|
123 CSIPRequest& aRequest, |
|
124 CSIPRegistrationBindingBase& aBinding) |
|
125 { |
|
126 const RStringF KContactHeaderName = |
|
127 SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
128 |
|
129 // panic if there is to header in unregister request in debug mode, |
|
130 // Leaves with error code KErrArgument in release mode |
|
131 __SIP_ASSERT_LEAVE(!aRequest.To(), KErrArgument); |
|
132 |
|
133 // panic if there is from header in unregister request in debug mode, |
|
134 // Leaves with error code KErrArgument in release mode |
|
135 __SIP_ASSERT_LEAVE(!aRequest.From(), KErrArgument); |
|
136 |
|
137 // panic if there is contact header in unregister request in debug mode, |
|
138 // Leaves with error code KErrArgument in release mode |
|
139 __SIP_ASSERT_LEAVE(!aRequest.HasHeader(KContactHeaderName), |
|
140 KErrArgument); |
|
141 |
|
142 // fill in contact header |
|
143 CSIPContactHeader* contact = |
|
144 static_cast<CSIPContactHeader*>(aBinding.Contact().CloneL()); |
|
145 CleanupStack::PushL(contact); |
|
146 contact->SetExpiresParameterL(0); //set expires parameter to 0 |
|
147 aRequest.AddHeaderL(contact); |
|
148 CleanupStack::Pop(contact); |
|
149 } |
|
150 |
|
151 // ----------------------------------------------------------------------------- |
|
152 // TSIPRegistrationUtility::CheckFetchingRequestL |
|
153 // ----------------------------------------------------------------------------- |
|
154 // |
|
155 void TSIPRegistrationUtility::CheckFetchingRequestL (CSIPRequest& aRequest) |
|
156 { |
|
157 const RStringF KContactHeaderName = |
|
158 SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
159 |
|
160 // panic if there is contact header in binding in debug mode. |
|
161 // leaves with error code KErrArgument in release mode. |
|
162 __SIP_ASSERT_LEAVE(!(aRequest.HasHeader(KContactHeaderName)), |
|
163 KErrArgument); |
|
164 |
|
165 CheckToHeaderL (*(aRequest.To())); |
|
166 } |
|
167 |
|
168 // ----------------------------------------------------------------------------- |
|
169 // TSIPRegistrationUtility::CheckOutboundProxyCompParameterL |
|
170 // ----------------------------------------------------------------------------- |
|
171 // |
|
172 void TSIPRegistrationUtility::CheckOutboundProxyCompParameterL( |
|
173 CSIPRouteHeader& aOutboundProxy, |
|
174 MSigComp& aSigComp) |
|
175 { |
|
176 if (aOutboundProxy.SIPAddress().URI().IsSIPURI()) |
|
177 { |
|
178 CSIPURI& uri = *(aOutboundProxy.SIPAddress().URI().SIPURI()); |
|
179 |
|
180 // when the uri of outboundProxy contains "comp" parameter and |
|
181 // comp == "sigcomp", leave if sigComp asked from MSigComp |
|
182 // is not supported. |
|
183 RStringF comp = SIPStrings::StringF(SipStrConsts::EComp); |
|
184 RStringF sigcomp = SIPStrings::StringF(SipStrConsts::ESigComp); |
|
185 if (uri.ParamValue(comp) == sigcomp && !aSigComp.IsSupported()) |
|
186 { |
|
187 User::Leave(KErrNotSupported); |
|
188 } |
|
189 } |
|
190 } |
|
191 |
|
192 // ----------------------------------------------------------------------------- |
|
193 // TSIPRegistrationUtility::CheckToHeaderL |
|
194 // ----------------------------------------------------------------------------- |
|
195 // |
|
196 void TSIPRegistrationUtility::CheckToHeaderL(CSIPToHeader& aTo) |
|
197 { |
|
198 CURIContainer& uri = aTo.SIPAddress().URI(); |
|
199 if (uri.IsSIPURI()) |
|
200 { |
|
201 __ASSERT_ALWAYS(uri.SIPURI()->User().Length() > 0, |
|
202 User::Leave(KErrArgument)); |
|
203 } |
|
204 } |
|
205 |
|
206 // ----------------------------------------------------------------------------- |
|
207 // TSIPRegistrationUtility::CheckRegisterContactL |
|
208 // ----------------------------------------------------------------------------- |
|
209 // |
|
210 void TSIPRegistrationUtility::CheckRegisterContactL( |
|
211 CSIPRequest& aRequest, |
|
212 const TUint32 aIapId, |
|
213 MTransactionUser& aTU) |
|
214 { |
|
215 const RStringF KContactHeaderName = |
|
216 SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
217 |
|
218 __SIP_ASSERT_LEAVE(aRequest.HeaderCount(KContactHeaderName) == 1, |
|
219 KErrArgument); |
|
220 |
|
221 CSIPContactHeader* contact = |
|
222 HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName); |
|
223 |
|
224 __SIP_ASSERT_LEAVE(!contact->Star(), KErrArgument); |
|
225 __SIP_ASSERT_LEAVE(contact->SIPAddress() != 0, KErrArgument); |
|
226 |
|
227 CheckSipsSchemeInAorAndOtherAddressL(*aRequest.To(),*contact->SIPAddress()); |
|
228 |
|
229 CheckSIPAddressInContactHeaderL(*contact, aIapId, aTU); |
|
230 } |
|
231 |
|
232 // ----------------------------------------------------------------------------- |
|
233 // TSIPRegistrationUtility::CheckUpdateRegisterContactL |
|
234 // ----------------------------------------------------------------------------- |
|
235 // |
|
236 void TSIPRegistrationUtility::CheckUpdateRegisterContactL( |
|
237 CSIPRequest& aRequest, |
|
238 CSIPRegistrationBindingBase& aBinding) |
|
239 { |
|
240 const RStringF KContactHeaderName = |
|
241 SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
242 |
|
243 // contact header is not empty in request |
|
244 if (aRequest.HasHeader(KContactHeaderName)) |
|
245 { |
|
246 __SIP_ASSERT_LEAVE(aRequest.HeaderCount(KContactHeaderName) == 1, |
|
247 KErrArgument); |
|
248 |
|
249 CSIPContactHeader* contactInRequest = |
|
250 HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName); |
|
251 |
|
252 __SIP_ASSERT_LEAVE(!contactInRequest->Star(), KErrArgument); |
|
253 |
|
254 CheckSipsSchemeInAorAndOtherAddressL( |
|
255 aBinding.AOR(),*contactInRequest->SIPAddress()); |
|
256 |
|
257 if (contactInRequest->SIPAddress()->URI().IsSIPURI()) |
|
258 { |
|
259 __ASSERT_ALWAYS(aBinding.Contact().SIPAddress()->URI().IsSIPURI(), |
|
260 User::Leave(KErrArgument)); |
|
261 |
|
262 CSIPURI& uriInRequestContact = |
|
263 *(contactInRequest->SIPAddress()->URI().SIPURI()); |
|
264 |
|
265 CSIPURI& uriInBindingContact = |
|
266 *(aBinding.Contact().SIPAddress()->URI().SIPURI()); |
|
267 |
|
268 CSIPHostPort& hostPortInRequestContact = |
|
269 uriInRequestContact.HostPort(); |
|
270 |
|
271 CSIPHostPort& hostPortInBindingContact = |
|
272 uriInBindingContact.HostPort(); |
|
273 |
|
274 // if there is no host in contact of request |
|
275 if (hostPortInRequestContact.Host().CompareF( |
|
276 SIPStrings::StringF(SipStrConsts::ELocalHost).DesC()) == 0) |
|
277 { |
|
278 hostPortInRequestContact.SetHostL(hostPortInBindingContact.Host()); |
|
279 } |
|
280 // if there is no port in contact of request |
|
281 if (!hostPortInRequestContact.HasPort() && |
|
282 hostPortInBindingContact.HasPort()) |
|
283 { |
|
284 hostPortInRequestContact.SetPort(hostPortInBindingContact.Port()); |
|
285 } |
|
286 } |
|
287 |
|
288 // leave if the contact in binding is different as the one in request |
|
289 __ASSERT_ALWAYS (contactInRequest->SIPAddress()->URI() == |
|
290 aBinding.Contact().SIPAddress()->URI(), |
|
291 User::Leave (KErrArgument)); |
|
292 } |
|
293 else |
|
294 { |
|
295 // create contact header, fill in the sip address from contact |
|
296 // in binding. add the contact header to request |
|
297 CSIPAddress* address = |
|
298 CSIPAddress::NewLC(*(aBinding.Contact().SIPAddress())); |
|
299 CSIPContactHeader* contactHeader = CSIPContactHeader::NewL(address); |
|
300 CleanupStack::Pop(address); |
|
301 CleanupStack::PushL(contactHeader); |
|
302 aRequest.AddHeaderL(contactHeader); |
|
303 CleanupStack::Pop(contactHeader); |
|
304 } |
|
305 } |
|
306 |
|
307 // ----------------------------------------------------------------------------- |
|
308 // TSIPRegistrationUtility::CheckRegisterExpiresValueL |
|
309 // ----------------------------------------------------------------------------- |
|
310 // |
|
311 void TSIPRegistrationUtility::CheckRegisterExpiresValueL(CSIPRequest& aRequest) |
|
312 { |
|
313 const RStringF KContactHeaderName = |
|
314 SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
315 |
|
316 const RStringF KExpiresHeaderName = |
|
317 SIPStrings::StringF(SipStrConsts::EExpiresHeader); |
|
318 |
|
319 CSIPContactHeader* contactHeader = |
|
320 HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName); |
|
321 |
|
322 // panic if there is no contact header == 0 in debug mode. |
|
323 // leaves with error code KErrArgument in release mode. |
|
324 __SIP_ASSERT_LEAVE(contactHeader, KErrArgument); |
|
325 |
|
326 if (contactHeader->ExpiresParameter() >= 0) |
|
327 { |
|
328 // panic RegisterRequestExpiresParameterIsZero in release mode. |
|
329 // leaves with error code KErrArgument in release mode. |
|
330 __SIP_ASSERT_LEAVE((contactHeader->ExpiresParameter() != 0), |
|
331 KErrArgument); |
|
332 } |
|
333 else if (!aRequest.HasHeader(KExpiresHeaderName)) |
|
334 { |
|
335 // set default expires value one hour |
|
336 contactHeader->SetExpiresParameterL(KOneHourInSeconds); |
|
337 } |
|
338 else |
|
339 { |
|
340 CSIPExpiresHeader* expiresHeader = |
|
341 HEADER_IN_REQUEST(CSIPExpiresHeader, KExpiresHeaderName); |
|
342 |
|
343 // panic expires header value is 0 in release mode. |
|
344 // leaves with error code KErrArgument in release mode. |
|
345 __SIP_ASSERT_LEAVE(expiresHeader->Value() != 0, KErrArgument); |
|
346 |
|
347 // copies expires value from expire header to expires parameter |
|
348 // in Contact, remove the expires header. |
|
349 contactHeader->SetExpiresParameterL(expiresHeader->Value()); |
|
350 if (aRequest.RemoveHeader(expiresHeader) == KErrNone) |
|
351 { |
|
352 delete expiresHeader; expiresHeader = 0; |
|
353 } |
|
354 } |
|
355 } |
|
356 |
|
357 // ----------------------------------------------------------------------------- |
|
358 // TSIPRegistrationUtility::RemoveRegisterExpiresParam |
|
359 // ----------------------------------------------------------------------------- |
|
360 // |
|
361 void TSIPRegistrationUtility::RemoveRegisterExpiresParam(CSIPRequest& aRequest) |
|
362 { |
|
363 const RStringF KContactHeaderName = |
|
364 SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
365 |
|
366 //remove the expires param |
|
367 if (aRequest.HasHeader(KContactHeaderName)) |
|
368 { |
|
369 CSIPContactHeader* contactHeader = |
|
370 HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName); |
|
371 if(contactHeader->ExpiresParameter() != KErrNotFound) |
|
372 { |
|
373 contactHeader->RemoveExpiresParam(); |
|
374 } |
|
375 } |
|
376 } |
|
377 |
|
378 // ----------------------------------------------------------------------------- |
|
379 // TSIPRegistrationUtility::CheckUpdateRegisterExpiresValueL |
|
380 // ----------------------------------------------------------------------------- |
|
381 // |
|
382 void TSIPRegistrationUtility::CheckUpdateRegisterExpiresValueL( |
|
383 CSIPRequest& aRequest, |
|
384 CSIPRegistrationBindingBase& aBinding) |
|
385 { |
|
386 const RStringF KContactHeaderName = |
|
387 SIPStrings::StringF(SipStrConsts::EContactHeader); |
|
388 |
|
389 const RStringF KExpiresHeaderName = |
|
390 SIPStrings::StringF(SipStrConsts::EExpiresHeader); |
|
391 |
|
392 CSIPContactHeader* contactHeader = |
|
393 HEADER_IN_REQUEST(CSIPContactHeader, KContactHeaderName); |
|
394 |
|
395 // panic is contactHeader == 0 in debug mode. |
|
396 // leaves with error code KErrArgument in release mode. |
|
397 __SIP_ASSERT_LEAVE(contactHeader, KErrArgument); |
|
398 |
|
399 if (contactHeader->ExpiresParameter() < 0) |
|
400 { |
|
401 if (!aRequest.HasHeader(KExpiresHeaderName)) |
|
402 { |
|
403 // set default expires value from binding |
|
404 contactHeader->SetExpiresParameterL( |
|
405 aBinding.Contact().ExpiresParameter()); |
|
406 } |
|
407 else |
|
408 { |
|
409 // copies expires value from expire header to expires parameter |
|
410 // in Contact, remove the expires header. |
|
411 CSIPExpiresHeader* expiresHeader = |
|
412 HEADER_IN_REQUEST(CSIPExpiresHeader, KExpiresHeaderName); |
|
413 |
|
414 contactHeader->SetExpiresParameterL(expiresHeader->Value()); |
|
415 if (aRequest.RemoveHeader(expiresHeader) == KErrNone) |
|
416 { |
|
417 delete expiresHeader; expiresHeader = 0; |
|
418 } |
|
419 } |
|
420 } |
|
421 } |
|
422 |
|
423 // ----------------------------------------------------------------------------- |
|
424 // TSIPRegistrationUtility::CheckSIPAddressInContactHeaderL |
|
425 // ----------------------------------------------------------------------------- |
|
426 // |
|
427 void TSIPRegistrationUtility::CheckSIPAddressInContactHeaderL( |
|
428 CSIPContactHeader& aContact, |
|
429 const TUint32 aIapId, |
|
430 MTransactionUser& aTransationUser) |
|
431 { |
|
432 if (aContact.SIPAddress()->URI().IsSIPURI()) |
|
433 { |
|
434 CSIPURI& contactUri = *(aContact.SIPAddress()->URI().SIPURI()); |
|
435 if (contactUri.HostPort().Host().CompareF( |
|
436 SIPStrings::StringF(SipStrConsts::ELocalHost).DesC()) == 0) |
|
437 { |
|
438 // fills in the host part by coping the Local IP address |
|
439 HBufC8* localAddr = |
|
440 TSIPRegistrationUtility::LocalAddressLC( |
|
441 aIapId, aTransationUser); |
|
442 contactUri.HostPort().SetHostL(*localAddr); |
|
443 CleanupStack::PopAndDestroy(); //localAddr |
|
444 } |
|
445 } |
|
446 } |
|
447 |
|
448 // ----------------------------------------------------------------------------- |
|
449 // TSIPRegistrationUtility::CheckSipsSchemeInAorAndOtherAddressL |
|
450 // ----------------------------------------------------------------------------- |
|
451 // |
|
452 void TSIPRegistrationUtility::CheckSipsSchemeInAorAndOtherAddressL( |
|
453 const CSIPToHeader& aAor, |
|
454 const CSIPAddress& aAddress) |
|
455 { |
|
456 if (aAor.SIPAddress().URI().IsSIPURI() && |
|
457 aAor.SIPAddress().URI().SIPURI()->IsSIPSURI()) |
|
458 { |
|
459 __ASSERT_ALWAYS(aAddress.URI().IsSIPURI(), |
|
460 User::Leave(KErrSIPInvalidURIType)); |
|
461 __ASSERT_ALWAYS(aAddress.URI().SIPURI()->IsSIPSURI(), |
|
462 User::Leave(KErrSIPInvalidURIType)); |
|
463 } |
|
464 } |