|
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 : CSIPRegEventSubscriber.cpp |
|
15 // Part of : SIP Profile Agent |
|
16 // implementation |
|
17 // Version : 1.0 |
|
18 // |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 // INCLUDE FILES |
|
24 #include "CSIPRegEventSubscriber.h" |
|
25 #include "CSIPNotifyXmlBodyParser.h" |
|
26 #include "sipreginfoelement.h" |
|
27 #include "TSIPRegEventStateNotSubscribed.h" |
|
28 #include "TSIPRegEventStateSubscribing.h" |
|
29 #include "TSIPRegEventStateSubscribed.h" |
|
30 #include "TSIPRegEventStateReSubscribing.h" |
|
31 #include "sipfromheader.h" |
|
32 #include "siptoheader.h" |
|
33 #include "sipeventheader.h" |
|
34 #include "siprefresh.h" |
|
35 #include "sipmessageelements.h" |
|
36 #include "sipexpiresheader.h" |
|
37 #include "sipacceptheader.h" |
|
38 #include "sipcontenttypeheader.h" |
|
39 #include "sipsubscriptionstateheader.h" |
|
40 #include "sipretryafterheader.h" |
|
41 #include "sipresponseelements.h" |
|
42 #include "siperr.h" |
|
43 #include "sipstrings.h" |
|
44 #include "sipstrconsts.h" |
|
45 #include <sipprofileagentextensionparams.h> |
|
46 |
|
47 |
|
48 _LIT8(KRegEventName, "reg"); |
|
49 _LIT8(KAcceptType, "application"); |
|
50 _LIT8(KAcceptSubtype, "reginfo+xml"); |
|
51 _LIT8(KStateActive, "active"); |
|
52 _LIT8(KStatePending, "pending"); |
|
53 _LIT8(KStateTerminated, "terminated"); |
|
54 _LIT8(KReasonProbation, "probation"); |
|
55 _LIT8(KReasonRejected, "rejected"); |
|
56 _LIT8(KReasonGiveup, "giveup"); |
|
57 _LIT8(KReasonNoresource, "noresource"); |
|
58 |
|
59 |
|
60 // ----------------------------------------------------------------------------- |
|
61 // CSIPRegEventSubscriber::NewL |
|
62 // ----------------------------------------------------------------------------- |
|
63 // |
|
64 CSIPRegEventSubscriber* CSIPRegEventSubscriber::NewL( |
|
65 CSIPNotifyXmlBodyParser& aXmlParser, |
|
66 CSIPConnection& aConnection, |
|
67 MSIPRegistrationContext& aContext, |
|
68 CUri8& aUserIdentity, |
|
69 MSIPRegEventSubscriberObserver& aObserver, |
|
70 CSipProfileAgentConfigExtension& aConfigExtension) |
|
71 { |
|
72 CSIPRegEventSubscriber* self = |
|
73 NewLC(aXmlParser,aConnection,aContext,aUserIdentity,aObserver,aConfigExtension); |
|
74 CleanupStack::Pop(); |
|
75 return self; |
|
76 } |
|
77 |
|
78 // ----------------------------------------------------------------------------- |
|
79 // CSIPRegEventSubscriber::NewLC |
|
80 // ----------------------------------------------------------------------------- |
|
81 // |
|
82 CSIPRegEventSubscriber* CSIPRegEventSubscriber::NewLC( |
|
83 CSIPNotifyXmlBodyParser& aXmlParser, |
|
84 CSIPConnection& aConnection, |
|
85 MSIPRegistrationContext& aContext, |
|
86 CUri8& aUserIdentity, |
|
87 MSIPRegEventSubscriberObserver& aObserver, |
|
88 CSipProfileAgentConfigExtension& aConfigExtension) |
|
89 { |
|
90 CSIPRegEventSubscriber* self = |
|
91 new(ELeave)CSIPRegEventSubscriber( |
|
92 aXmlParser,aConnection,aContext,aUserIdentity,aObserver,aConfigExtension); |
|
93 CleanupStack::PushL(self); |
|
94 self->ConstructL(); |
|
95 return self; |
|
96 } |
|
97 |
|
98 // ----------------------------------------------------------------------------- |
|
99 // CSIPRegEventSubscriber::CSIPRegEventSubscriber |
|
100 // ----------------------------------------------------------------------------- |
|
101 // |
|
102 CSIPRegEventSubscriber::CSIPRegEventSubscriber( |
|
103 CSIPNotifyXmlBodyParser& aXmlParser, |
|
104 CSIPConnection& aConnection, |
|
105 MSIPRegistrationContext& aContext, |
|
106 CUri8& aUserIdentity, |
|
107 MSIPRegEventSubscriberObserver& aObserver, |
|
108 CSipProfileAgentConfigExtension& aConfigExtension) |
|
109 : iStates(MSIPRegEventContext::EMaxStates), |
|
110 iCurrentState(MSIPRegEventContext::ENotSubscribed), |
|
111 iXmlParser(aXmlParser), |
|
112 iConnection(aConnection), |
|
113 iRegistrationContext(aContext), |
|
114 iUserIdentity(aUserIdentity), |
|
115 iObserver(aObserver), |
|
116 iConfigExtension(aConfigExtension) |
|
117 { |
|
118 } |
|
119 |
|
120 // ----------------------------------------------------------------------------- |
|
121 // CSIPRegEventSubscriber::ConstructL |
|
122 // ----------------------------------------------------------------------------- |
|
123 // |
|
124 void CSIPRegEventSubscriber::ConstructL() |
|
125 { |
|
126 InitializeStatesL(); |
|
127 iReasonProbation = SIPStrings::Pool().OpenFStringL(KReasonProbation); |
|
128 iReasonRejected = SIPStrings::Pool().OpenFStringL(KReasonRejected); |
|
129 iReasonGiveup = SIPStrings::Pool().OpenFStringL(KReasonGiveup); |
|
130 iReasonNoresource = SIPStrings::Pool().OpenFStringL(KReasonNoresource); |
|
131 iSubscribeAssoc = CreateSubscribeAssocL(); |
|
132 } |
|
133 |
|
134 // ----------------------------------------------------------------------------- |
|
135 // CSIPRegEventSubscriber::InitializeStatesL |
|
136 // ----------------------------------------------------------------------------- |
|
137 // |
|
138 void CSIPRegEventSubscriber::InitializeStatesL() |
|
139 { |
|
140 iStates.AppendL(TSIPRegEventStateNotSubscribed(*this), |
|
141 sizeof(TSIPRegEventStateNotSubscribed)); |
|
142 |
|
143 iStates.AppendL(TSIPRegEventStateSubscribing(*this), |
|
144 sizeof(TSIPRegEventStateSubscribing)); |
|
145 |
|
146 iStates.AppendL(TSIPRegEventStateSubscribed(*this), |
|
147 sizeof(TSIPRegEventStateSubscribed)); |
|
148 |
|
149 iStates.AppendL(TSIPRegEventStateReSubscribing(*this), |
|
150 sizeof(TSIPRegEventStateReSubscribing)); |
|
151 } |
|
152 |
|
153 // ----------------------------------------------------------------------------- |
|
154 // CSIPRegEventSubscriber::~CSIPRegEventSubscriber |
|
155 // ----------------------------------------------------------------------------- |
|
156 // |
|
157 CSIPRegEventSubscriber::~CSIPRegEventSubscriber() |
|
158 { |
|
159 delete iSubscribeAssoc; |
|
160 delete iClientTransaction; |
|
161 iReasonProbation.Close(); |
|
162 iReasonRejected.Close(); |
|
163 iReasonGiveup.Close(); |
|
164 iReasonNoresource.Close(); |
|
165 delete iCurrentRegInfoElement; |
|
166 } |
|
167 |
|
168 // ----------------------------------------------------------------------------- |
|
169 // CSIPRegEventSubscriber::SubscribeL |
|
170 // ----------------------------------------------------------------------------- |
|
171 // |
|
172 void CSIPRegEventSubscriber::SubscribeL() |
|
173 { |
|
174 CurrentState().SubscribeL(); |
|
175 } |
|
176 |
|
177 // ----------------------------------------------------------------------------- |
|
178 // CSIPRegEventSubscriber::DoSubscribeL |
|
179 // ----------------------------------------------------------------------------- |
|
180 // |
|
181 void CSIPRegEventSubscriber::DoSubscribeL() |
|
182 { |
|
183 CSIPRefresh* refresh = CSIPRefresh::NewLC(); |
|
184 CSIPMessageElements* message = CreateMessageElementsLC( |
|
185 iConfigExtension.ExpiryValueL(TSIPProfileTypeInfo::EIms, |
|
186 CSipProfileAgentConfigExtension::EProfileSubscriptionValue)); |
|
187 |
|
188 CSIPClientTransaction* transaction = |
|
189 iSubscribeAssoc->SendSubscribeL(message,refresh); |
|
190 |
|
191 CleanupStack::Pop(message); |
|
192 CleanupStack::Pop(refresh); |
|
193 delete iClientTransaction; |
|
194 iClientTransaction = transaction; |
|
195 } |
|
196 |
|
197 // ----------------------------------------------------------------------------- |
|
198 // CSIPRegEventSubscriber::ReSubscribeL |
|
199 // ----------------------------------------------------------------------------- |
|
200 // |
|
201 void CSIPRegEventSubscriber::ReSubscribeL() |
|
202 { |
|
203 CSIPSubscribeDialogAssoc* subscribeAssoc = CreateSubscribeAssocL(); |
|
204 CleanupStack::PushL(subscribeAssoc); |
|
205 |
|
206 CSIPRefresh* refresh = CSIPRefresh::NewLC(); |
|
207 CSIPMessageElements* message = CreateMessageElementsLC( |
|
208 iConfigExtension.ExpiryValueL(TSIPProfileTypeInfo::EIms, |
|
209 CSipProfileAgentConfigExtension::EProfileSubscriptionValue)); |
|
210 |
|
211 CSIPClientTransaction* transaction = |
|
212 subscribeAssoc->SendSubscribeL(message,refresh); |
|
213 |
|
214 CleanupStack::Pop(message); |
|
215 CleanupStack::Pop(refresh); |
|
216 delete iClientTransaction; |
|
217 iClientTransaction = transaction; |
|
218 |
|
219 CleanupStack::Pop(subscribeAssoc); |
|
220 delete iSubscribeAssoc; |
|
221 iSubscribeAssoc = subscribeAssoc; |
|
222 } |
|
223 |
|
224 // ----------------------------------------------------------------------------- |
|
225 // CSIPRegEventSubscriber::RefreshL |
|
226 // ----------------------------------------------------------------------------- |
|
227 // |
|
228 void CSIPRegEventSubscriber::RefreshL() |
|
229 { |
|
230 CurrentState().RefreshL(); |
|
231 } |
|
232 |
|
233 // ----------------------------------------------------------------------------- |
|
234 // CSIPRegEventSubscriber::DoRefreshL |
|
235 // ----------------------------------------------------------------------------- |
|
236 // |
|
237 void CSIPRegEventSubscriber::DoRefreshL() |
|
238 { |
|
239 CSIPMessageElements* message = CreateMessageElementsLC( |
|
240 iConfigExtension.ExpiryValueL(TSIPProfileTypeInfo::EIms, |
|
241 CSipProfileAgentConfigExtension::EProfileSubscriptionValue)); |
|
242 |
|
243 CSIPClientTransaction* transaction = iSubscribeAssoc->UpdateL(message); |
|
244 |
|
245 CleanupStack::Pop(message); |
|
246 delete iClientTransaction; |
|
247 iClientTransaction = transaction; |
|
248 } |
|
249 |
|
250 // ----------------------------------------------------------------------------- |
|
251 // CSIPRegEventSubscriber::ReSubscribeAfterL |
|
252 // ----------------------------------------------------------------------------- |
|
253 // |
|
254 void CSIPRegEventSubscriber::ReSubscribeAfterL(TUint aRetryAfter) |
|
255 { |
|
256 iObserver.SubscriptionFailedL(aRetryAfter); |
|
257 } |
|
258 |
|
259 // ----------------------------------------------------------------------------- |
|
260 // CSIPRegEventSubscriber::SubscriptionFailedL |
|
261 // ----------------------------------------------------------------------------- |
|
262 // |
|
263 void CSIPRegEventSubscriber::SubscriptionFailedL() |
|
264 { |
|
265 iObserver.SubscriptionFailedL(); |
|
266 } |
|
267 |
|
268 // ----------------------------------------------------------------------------- |
|
269 // CSIPRegEventSubscriber::RegEventNotSupportedByNetworkL |
|
270 // ----------------------------------------------------------------------------- |
|
271 // |
|
272 void CSIPRegEventSubscriber::RegEventNotSupportedByNetworkL() |
|
273 { |
|
274 iObserver.RegEventNotSupportedByNetworkL(); |
|
275 } |
|
276 |
|
277 // ----------------------------------------------------------------------------- |
|
278 // CSIPRegEventSubscriber::ReRegister |
|
279 // ----------------------------------------------------------------------------- |
|
280 // |
|
281 void CSIPRegEventSubscriber::ReRegister() |
|
282 { |
|
283 iObserver.ReRegister(); |
|
284 } |
|
285 |
|
286 // ----------------------------------------------------------------------------- |
|
287 // CSIPRegEventSubscriber::ChangeState |
|
288 // ----------------------------------------------------------------------------- |
|
289 // |
|
290 void CSIPRegEventSubscriber::ChangeState(TState aNewState) |
|
291 { |
|
292 iCurrentState = aNewState; |
|
293 } |
|
294 |
|
295 // ----------------------------------------------------------------------------- |
|
296 // CSIPRegEventSubscriber::HasTransaction |
|
297 // ----------------------------------------------------------------------------- |
|
298 // |
|
299 TBool CSIPRegEventSubscriber::HasTransaction( |
|
300 const CSIPTransactionBase& aTransaction) const |
|
301 { |
|
302 return (iClientTransaction && aTransaction == *iClientTransaction); |
|
303 } |
|
304 |
|
305 // ----------------------------------------------------------------------------- |
|
306 // CSIPRegEventSubscriber::HasRefresh |
|
307 // ----------------------------------------------------------------------------- |
|
308 // |
|
309 TBool CSIPRegEventSubscriber::HasRefresh( |
|
310 const CSIPRefresh& aRefresh) const |
|
311 { |
|
312 return (*iSubscribeAssoc->SIPRefresh() == aRefresh); |
|
313 } |
|
314 |
|
315 // ----------------------------------------------------------------------------- |
|
316 // CSIPRegEventSubscriber::HasDialog |
|
317 // ----------------------------------------------------------------------------- |
|
318 // |
|
319 TBool CSIPRegEventSubscriber::HasDialog(const CSIPDialog& aDialog) const |
|
320 { |
|
321 return (aDialog == iSubscribeAssoc->Dialog()); |
|
322 } |
|
323 |
|
324 // ----------------------------------------------------------------------------- |
|
325 // CSIPRegEventSubscriber::RequestReceivedL |
|
326 // ----------------------------------------------------------------------------- |
|
327 // |
|
328 void CSIPRegEventSubscriber::RequestReceivedL( |
|
329 CSIPServerTransaction* aTransaction, |
|
330 CSIPDialog& aDialog) |
|
331 { |
|
332 if (HasDialog(aDialog)) |
|
333 { |
|
334 __ASSERT_ALWAYS(aTransaction, User::Leave(KErrCorrupt)); |
|
335 __ASSERT_ALWAYS(aTransaction->RequestElements() != NULL, |
|
336 User::Leave(KErrCorrupt)); |
|
337 const CSIPRequestElements& request = *(aTransaction->RequestElements()); |
|
338 CSIPResponseElements* response = HandleReceivedRequestLC(request); |
|
339 if (response->StatusCode() == 200) |
|
340 { |
|
341 TRAPD(err, ParseXmlL(request)); |
|
342 if (err == KErrNone) |
|
343 { |
|
344 TBool terminated = EFalse; |
|
345 TInt retryAfter = 0; |
|
346 HandleSubscriptionStateL(request,terminated,retryAfter); |
|
347 aTransaction->SendResponseL(response); |
|
348 CleanupStack::Pop(response); |
|
349 if (terminated) |
|
350 { |
|
351 iObserver.TerminatedL(*iCurrentRegInfoElement,retryAfter); |
|
352 } |
|
353 else |
|
354 { |
|
355 iObserver.NotifyReceivedL(*iCurrentRegInfoElement); |
|
356 } |
|
357 } |
|
358 else if (err == KErrNoMemory) |
|
359 { |
|
360 User::Leave(err); |
|
361 } |
|
362 else |
|
363 { |
|
364 response->SetStatusCodeL(400); |
|
365 response->SetReasonPhraseL( |
|
366 SIPStrings::StringF(SipStrConsts::EPhraseBadRequest)); |
|
367 aTransaction->SendResponseL(response); |
|
368 CleanupStack::Pop(response); |
|
369 } |
|
370 } |
|
371 else |
|
372 { |
|
373 aTransaction->SendResponseL(response); |
|
374 CleanupStack::Pop(response); |
|
375 } |
|
376 delete aTransaction; |
|
377 } |
|
378 } |
|
379 |
|
380 // ----------------------------------------------------------------------------- |
|
381 // CSIPRegEventSubscriber::ResponseReceivedL |
|
382 // ----------------------------------------------------------------------------- |
|
383 // |
|
384 void CSIPRegEventSubscriber::ResponseReceivedL( |
|
385 CSIPClientTransaction& aTransaction) |
|
386 { |
|
387 if (HasTransaction(aTransaction)) |
|
388 { |
|
389 const CSIPResponseElements* response = aTransaction.ResponseElements(); |
|
390 __ASSERT_ALWAYS(response != NULL, User::Leave(KErrCorrupt)); |
|
391 HandleReceivedResponseL(*response); |
|
392 } |
|
393 } |
|
394 |
|
395 // ----------------------------------------------------------------------------- |
|
396 // CSIPRegEventSubscriber::ErrorOccured |
|
397 // ----------------------------------------------------------------------------- |
|
398 // |
|
399 void CSIPRegEventSubscriber::ErrorOccured( |
|
400 TInt /*aError*/, |
|
401 CSIPTransactionBase& aTransaction) |
|
402 { |
|
403 if (HasTransaction(aTransaction)) |
|
404 { |
|
405 TRAP_IGNORE(CurrentState().ErrorOccuredL()) |
|
406 } |
|
407 } |
|
408 |
|
409 // ----------------------------------------------------------------------------- |
|
410 // CSIPRegEventSubscriber::ErrorOccured |
|
411 // ----------------------------------------------------------------------------- |
|
412 // |
|
413 void CSIPRegEventSubscriber::ErrorOccured(TInt aError, |
|
414 CSIPDialog& aDialog) |
|
415 { |
|
416 if (HasDialog(aDialog)) |
|
417 { |
|
418 const CSIPClientTransaction* transaction = |
|
419 iSubscribeAssoc->SIPRefresh()->SIPTransaction(); |
|
420 if (transaction && aError == KErrSIPTerminatedWithResponse) |
|
421 { |
|
422 TUint statusCode = transaction->ResponseElements()->StatusCode(); |
|
423 TUint after = RetryAfterValue(*transaction->ResponseElements()); |
|
424 TRAP_IGNORE(CurrentState().ResponseReceivedL(statusCode,after)) |
|
425 } |
|
426 else |
|
427 { |
|
428 TRAP_IGNORE(CurrentState().ErrorOccuredL()) |
|
429 } |
|
430 } |
|
431 } |
|
432 |
|
433 // ----------------------------------------------------------------------------- |
|
434 // CSIPRegEventSubscriber::HandleReceivedRequestLC |
|
435 // ----------------------------------------------------------------------------- |
|
436 // |
|
437 CSIPResponseElements* CSIPRegEventSubscriber::HandleReceivedRequestLC( |
|
438 const CSIPRequestElements& aRequest) |
|
439 { |
|
440 if (!MethodOK(aRequest) || |
|
441 !ContentTypeOK(aRequest) || |
|
442 !SubscriptionStateOK(aRequest)) |
|
443 { |
|
444 return CSIPResponseElements::NewLC(400, |
|
445 SIPStrings::StringF(SipStrConsts::EPhraseBadRequest)); |
|
446 } |
|
447 |
|
448 if (!EventOK(aRequest)) |
|
449 { |
|
450 return CSIPResponseElements::NewLC(489, |
|
451 SIPStrings::StringF(SipStrConsts::EPhraseBadEvent)); |
|
452 } |
|
453 |
|
454 return CSIPResponseElements::NewLC(200, |
|
455 SIPStrings::StringF(SipStrConsts::EPhraseOk)); |
|
456 } |
|
457 |
|
458 // ----------------------------------------------------------------------------- |
|
459 // CSIPRegEventSubscriber::HandleReceivedResponseL |
|
460 // ----------------------------------------------------------------------------- |
|
461 // |
|
462 void CSIPRegEventSubscriber::HandleReceivedResponseL( |
|
463 const CSIPResponseElements& aResponse) |
|
464 { |
|
465 TUint statusCode = aResponse.StatusCode(); |
|
466 if (statusCode >= 200) |
|
467 { |
|
468 TUint retryAfter = RetryAfterValue(aResponse); |
|
469 delete iClientTransaction; |
|
470 iClientTransaction = NULL; |
|
471 CurrentState().ResponseReceivedL(statusCode,retryAfter); |
|
472 } |
|
473 } |
|
474 |
|
475 // ----------------------------------------------------------------------------- |
|
476 // CSIPRegEventSubscriber::RetryAfterValue |
|
477 // ----------------------------------------------------------------------------- |
|
478 // |
|
479 TUint CSIPRegEventSubscriber::RetryAfterValue( |
|
480 const CSIPResponseElements& aResponse) const |
|
481 { |
|
482 TUint retryAfter = 0; |
|
483 CSIPRetryAfterHeader* retryAfterHeader = |
|
484 static_cast<CSIPRetryAfterHeader*>( |
|
485 FindHeader(aResponse.MessageElements(), |
|
486 SIPStrings::StringF(SipStrConsts::ERetryAfterHeader))); |
|
487 if (retryAfterHeader) |
|
488 { |
|
489 retryAfter = retryAfterHeader->RetryAfter(); |
|
490 } |
|
491 return retryAfter; |
|
492 } |
|
493 |
|
494 // ----------------------------------------------------------------------------- |
|
495 // CSIPRegEventSubscriber::ParseXmlL |
|
496 // ----------------------------------------------------------------------------- |
|
497 // |
|
498 void CSIPRegEventSubscriber::ParseXmlL(const CSIPRequestElements& aRequest) |
|
499 { |
|
500 CSIPRegInfoElement* regInfoElement = CSIPRegInfoElement::NewLC(); |
|
501 iXmlParser.ParseL(regInfoElement,aRequest.MessageElements().Content()); |
|
502 CleanupStack::Pop(regInfoElement); |
|
503 delete iCurrentRegInfoElement; |
|
504 iCurrentRegInfoElement = regInfoElement; |
|
505 } |
|
506 |
|
507 // ----------------------------------------------------------------------------- |
|
508 // CSIPRegEventSubscriber::HandleSubscriptionStateL |
|
509 // ----------------------------------------------------------------------------- |
|
510 // |
|
511 void CSIPRegEventSubscriber::HandleSubscriptionStateL( |
|
512 const CSIPRequestElements& aRequest, |
|
513 TBool& aTerminated, |
|
514 TInt& aRetryAfter) |
|
515 { |
|
516 TBool terminated = EFalse; |
|
517 |
|
518 CSIPHeaderBase* header = |
|
519 FindHeader(aRequest.MessageElements(), |
|
520 SIPStrings::StringF(SipStrConsts::ESubscriptionStateHeader)); |
|
521 |
|
522 __ASSERT_ALWAYS(header != NULL, User::Leave(KErrCorrupt)); |
|
523 |
|
524 CSIPSubscriptionStateHeader* ssHeader = |
|
525 static_cast<CSIPSubscriptionStateHeader*>(header); |
|
526 |
|
527 CSIPRefresh* refresh = |
|
528 const_cast<CSIPRefresh*>(iSubscribeAssoc->SIPRefresh()); |
|
529 |
|
530 TPtrC8 state(ssHeader->SubStateValue()); |
|
531 |
|
532 if (state.CompareF(KStateActive) == 0 || |
|
533 state.CompareF(KStatePending) == 0) |
|
534 { |
|
535 TInt expires = ssHeader->ExpiresParameter(); |
|
536 if (expires > 0) |
|
537 { |
|
538 refresh->SetIntervalL(static_cast<TUint>(expires)); |
|
539 } |
|
540 } |
|
541 else if (state.CompareF(KStateTerminated) == 0) |
|
542 { |
|
543 HandleTerminatedState(*ssHeader, aRetryAfter); |
|
544 terminated = ETrue; |
|
545 } |
|
546 else // Unknown state |
|
547 { |
|
548 // Just refresh after one minute |
|
549 refresh->SetIntervalL(60); |
|
550 } |
|
551 |
|
552 aTerminated = terminated; |
|
553 } |
|
554 |
|
555 // ----------------------------------------------------------------------------- |
|
556 // CSIPRegEventSubscriber::HandleTerminatedState |
|
557 // ----------------------------------------------------------------------------- |
|
558 // |
|
559 void CSIPRegEventSubscriber::HandleTerminatedState( |
|
560 CSIPSubscriptionStateHeader& aState, |
|
561 TInt& aRetryAfter) |
|
562 { |
|
563 TInt retryAfter = aState.RetryAfterParameter(); |
|
564 |
|
565 RStringF reason = |
|
566 aState.ParamValue(SIPStrings::StringF(SipStrConsts::EReason)); |
|
567 |
|
568 if (reason == iReasonProbation || |
|
569 reason == iReasonGiveup) |
|
570 { |
|
571 if (retryAfter < 0) |
|
572 { |
|
573 // re-SUBSCRIBE after one hour |
|
574 retryAfter = 3600; |
|
575 } |
|
576 } |
|
577 else if (reason == iReasonRejected || |
|
578 reason == iReasonNoresource) |
|
579 { |
|
580 // do NOT re-SUBSRIBE |
|
581 retryAfter = -1; |
|
582 } |
|
583 else |
|
584 { |
|
585 // deactivated, timeout or anything else: re-SUBSCRIBE immediately |
|
586 retryAfter = 0; |
|
587 } |
|
588 |
|
589 aRetryAfter = retryAfter; |
|
590 } |
|
591 |
|
592 // ----------------------------------------------------------------------------- |
|
593 // CSIPRegEventSubscriber::CreateSubscribeAssocL |
|
594 // ----------------------------------------------------------------------------- |
|
595 // |
|
596 CSIPSubscribeDialogAssoc* CSIPRegEventSubscriber::CreateSubscribeAssocL() |
|
597 { |
|
598 TPtrC8 uriDes(iUserIdentity.Uri().UriDes()); |
|
599 CUri8* remoteUri = CUri8::NewLC(iUserIdentity.Uri()); |
|
600 CSIPFromHeader* from = CSIPFromHeader::DecodeL(uriDes); |
|
601 CleanupStack::PushL(from); |
|
602 CSIPEventHeader* event = CSIPEventHeader::NewLC(KRegEventName); |
|
603 |
|
604 CSIPSubscribeDialogAssoc* subscribeAssoc = |
|
605 CSIPSubscribeDialogAssoc::NewL(iConnection,remoteUri, |
|
606 iRegistrationContext,event,from); |
|
607 |
|
608 CleanupStack::Pop(event); |
|
609 CleanupStack::Pop(from); |
|
610 CleanupStack::Pop(remoteUri); |
|
611 |
|
612 return subscribeAssoc; |
|
613 } |
|
614 |
|
615 // ----------------------------------------------------------------------------- |
|
616 // CSIPRegEventSubscriber::CreateMessageElementsLC |
|
617 // ----------------------------------------------------------------------------- |
|
618 // |
|
619 CSIPMessageElements* |
|
620 CSIPRegEventSubscriber::CreateMessageElementsLC(TUint aExpiresValue) |
|
621 { |
|
622 CSIPMessageElements* message = CSIPMessageElements::NewLC(); |
|
623 RPointerArray<CSIPHeaderBase> headers; |
|
624 CSIPHeaderBase::PushLC(&headers); |
|
625 // Expires |
|
626 CSIPExpiresHeader* expires = new(ELeave)CSIPExpiresHeader(aExpiresValue); |
|
627 CleanupStack::PushL(expires); |
|
628 headers.AppendL(expires); |
|
629 CleanupStack::Pop(expires); |
|
630 // Accept |
|
631 CSIPAcceptHeader* accept = |
|
632 CSIPAcceptHeader::NewLC(KAcceptType,KAcceptSubtype); |
|
633 headers.AppendL(accept); |
|
634 CleanupStack::Pop(accept); |
|
635 message->SetUserHeadersL(headers); |
|
636 CleanupStack::Pop(1); // headers |
|
637 headers.Close(); |
|
638 return message; |
|
639 } |
|
640 |
|
641 // ----------------------------------------------------------------------------- |
|
642 // CSIPRegEventSubscriber::MethodOK |
|
643 // ----------------------------------------------------------------------------- |
|
644 // |
|
645 TBool CSIPRegEventSubscriber::MethodOK(const CSIPRequestElements& aRequest) |
|
646 { |
|
647 return (aRequest.Method() == SIPStrings::StringF(SipStrConsts::ENotify)); |
|
648 } |
|
649 |
|
650 // ----------------------------------------------------------------------------- |
|
651 // CSIPRegEventSubscriber::ContentTypeOK |
|
652 // ----------------------------------------------------------------------------- |
|
653 // |
|
654 TBool CSIPRegEventSubscriber::ContentTypeOK(const CSIPRequestElements& aRequest) |
|
655 { |
|
656 const CSIPContentTypeHeader* contentType = |
|
657 aRequest.MessageElements().ContentType(); |
|
658 if (!contentType) |
|
659 { |
|
660 return EFalse; |
|
661 } |
|
662 if (contentType->MediaType().CompareF(KAcceptType) != 0) |
|
663 { |
|
664 return EFalse; |
|
665 } |
|
666 return (contentType->MediaSubtype().CompareF(KAcceptSubtype) == 0); |
|
667 } |
|
668 |
|
669 // ----------------------------------------------------------------------------- |
|
670 // CSIPRegEventSubscriber::SubscriptionStateOK |
|
671 // ----------------------------------------------------------------------------- |
|
672 // |
|
673 TBool CSIPRegEventSubscriber::SubscriptionStateOK( |
|
674 const CSIPRequestElements& aRequest) |
|
675 { |
|
676 CSIPHeaderBase* header = |
|
677 FindHeader(aRequest.MessageElements(), |
|
678 SIPStrings::StringF(SipStrConsts::ESubscriptionStateHeader)); |
|
679 return (header != NULL); |
|
680 } |
|
681 |
|
682 // ----------------------------------------------------------------------------- |
|
683 // CSIPRegEventSubscriber::EventOK |
|
684 // ----------------------------------------------------------------------------- |
|
685 // |
|
686 TBool CSIPRegEventSubscriber::EventOK(const CSIPRequestElements& aRequest) |
|
687 { |
|
688 CSIPHeaderBase* header = |
|
689 FindHeader(aRequest.MessageElements(), |
|
690 SIPStrings::StringF(SipStrConsts::EEventHeader)); |
|
691 if (!header) |
|
692 { |
|
693 return EFalse; |
|
694 } |
|
695 CSIPEventHeader* event = static_cast<CSIPEventHeader*>(header); |
|
696 return (event->EventPackage().CompareF(KRegEventName) == 0); |
|
697 } |
|
698 |
|
699 // ----------------------------------------------------------------------------- |
|
700 // CSIPRegEventSubscriber::FindHeader |
|
701 // ----------------------------------------------------------------------------- |
|
702 // |
|
703 CSIPHeaderBase* CSIPRegEventSubscriber::FindHeader( |
|
704 const CSIPMessageElements& aMessage, |
|
705 RStringF aHeaderName) const |
|
706 { |
|
707 TBool found = EFalse; |
|
708 CSIPHeaderBase* header = NULL; |
|
709 const RPointerArray<CSIPHeaderBase>& headers = aMessage.UserHeaders(); |
|
710 for (TInt i=0; i < headers.Count() && !found; i++) |
|
711 { |
|
712 header = headers[i]; |
|
713 if (header->Name() == aHeaderName) |
|
714 { |
|
715 found = ETrue; |
|
716 } |
|
717 else |
|
718 { |
|
719 header = NULL; |
|
720 } |
|
721 } |
|
722 return header; |
|
723 } |
|
724 |
|
725 // ---------------------------------------------------------------------------- |
|
726 // CSIPRegEventSubscriber::CurrentState |
|
727 // ---------------------------------------------------------------------------- |
|
728 // |
|
729 TSIPRegEventSubscriptionStateBase& CSIPRegEventSubscriber::CurrentState() |
|
730 { |
|
731 return iStates.At(iCurrentState); |
|
732 } |