/[resiprocate]/main/resip/dum/ServerInviteSession.cxx
ViewVC logotype

Contents of /main/resip/dum/ServerInviteSession.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5645 - (show annotations) (download)
Tue Nov 15 05:20:40 2005 UTC (14 years, 2 months ago) by derek
File size: 29429 byte(s)
fixup endreason

1 #include "resip/stack/MultipartMixedContents.hxx"
2 #include "resip/stack/MultipartAlternativeContents.hxx"
3 #include "resip/dum/Dialog.hxx"
4 #include "resip/dum/DialogUsageManager.hxx"
5 #include "resip/dum/DumTimeout.hxx"
6 #include "resip/dum/InviteSessionHandler.hxx"
7 #include "resip/dum/ServerInviteSession.hxx"
8 #include "resip/dum/MasterProfile.hxx"
9 #include "resip/dum/UsageUseException.hxx"
10 #include "resip/dum/DumHelper.hxx"
11 #include "rutil/Logger.hxx"
12 #include "rutil/compat.hxx"
13 #include "rutil/WinLeakCheck.hxx"
14
15 using namespace resip;
16
17 #define RESIPROCATE_SUBSYSTEM Subsystem::DUM
18
19 ServerInviteSession::ServerInviteSession(DialogUsageManager& dum, Dialog& dialog, const SipMessage& request)
20 : InviteSession(dum, dialog),
21 mFirstRequest(request),
22 mCurrentRetransmit1xx(0)
23 {
24 assert(request.isRequest());
25 mState = UAS_Start;
26 }
27
28 ServerInviteSessionHandle
29 ServerInviteSession::getHandle()
30 {
31 return ServerInviteSessionHandle(mDum, getBaseHandle().getId());
32 }
33
34 void
35 ServerInviteSession::redirect(const NameAddrs& contacts, int code)
36 {
37 InfoLog (<< toData(mState) << ": redirect(" << code << ")"); // -> " << contacts);
38
39 switch (mState)
40 {
41 case UAS_EarlyNoOffer:
42 case UAS_EarlyOffer:
43 case UAS_EarlyProvidedAnswer:
44 case UAS_EarlyProvidedOffer:
45 case UAS_EarlyReliable:
46 case UAS_FirstEarlyReliable:
47 case UAS_FirstSentOfferReliable:
48 case UAS_NoOffer:
49 case UAS_NoOfferReliable:
50 case UAS_Offer:
51 case UAS_OfferProvidedAnswer:
52 case UAS_OfferReliable:
53 case UAS_ProvidedOffer:
54 case UAS_ReceivedUpdate:
55 case UAS_ReceivedUpdateWaitingAnswer:
56 case UAS_SentUpdate:
57 {
58 // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of
59 // an offer/answer exchange with PRACK.
60 // e.g. we sent 183 reliably and then 302 before PRACK was received. Ideally,
61 // we should send 200PRACK
62 SipMessage response;
63 mDialog.makeResponse(response, mFirstRequest, code);
64 response.header(h_Contacts) = contacts;
65 send(response);
66
67 transition(Terminated);
68 mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Ended);
69 mDum.destroy(this);
70 break;
71 }
72
73 case UAS_Accepted:
74 case UAS_WaitingToOffer:
75 case UAS_WaitingToHangup:
76 case UAS_WaitingToTerminate:
77 case UAS_SentUpdateAccepted:
78 case UAS_Start:
79 default:
80 assert(0);
81 throw UsageUseException("Can't redirect after accepted", __FILE__, __LINE__);
82 break;
83 }
84 }
85
86 void
87 ServerInviteSession::provisional(int code)
88 {
89 InfoLog (<< toData(mState) << ": provisional(" << code << ")");
90
91 switch (mState)
92 {
93 case UAS_Offer:
94 transition(UAS_EarlyOffer);
95 sendProvisional(code);
96 break;
97
98 case UAS_OfferProvidedAnswer:
99 case UAS_EarlyProvidedAnswer:
100 transition(UAS_EarlyProvidedAnswer);
101 sendProvisional(code);
102 break;
103
104 case UAS_ProvidedOffer:
105 case UAS_EarlyProvidedOffer:
106 transition(UAS_EarlyProvidedOffer);
107 sendProvisional(code);
108 break;
109
110 case UAS_EarlyOffer:
111 transition(UAS_EarlyOffer);
112 sendProvisional(code);
113 break;
114
115 case UAS_NoOffer:
116 case UAS_EarlyNoOffer:
117 transition(UAS_EarlyNoOffer);
118 sendProvisional(code);
119 break;
120
121
122 case UAS_NoOfferReliable:
123 case UAS_EarlyReliable:
124 // TBD
125 assert(0);
126 break;
127
128 case UAS_Accepted:
129 case UAS_WaitingToOffer:
130 case UAS_FirstEarlyReliable:
131 case UAS_FirstSentOfferReliable:
132 case UAS_OfferReliable:
133 case UAS_ReceivedUpdate:
134 case UAS_ReceivedUpdateWaitingAnswer:
135 case UAS_SentUpdate:
136 case UAS_SentUpdateAccepted:
137 case UAS_Start:
138 case UAS_WaitingToHangup:
139 case UAS_WaitingToTerminate:
140 default:
141 assert(0);
142 break;
143 }
144 }
145
146 void
147 ServerInviteSession::provideOffer(const SdpContents& offer,
148 DialogUsageManager::EncryptionLevel level,
149 const SdpContents* alternative)
150 {
151 InfoLog (<< toData(mState) << ": provideOffer");
152 switch (mState)
153 {
154 case UAS_NoOffer:
155 transition(UAS_ProvidedOffer);
156 mProposedLocalSdp = InviteSession::makeSdp(offer, alternative);
157 mProposedEncryptionLevel = level;
158 break;
159
160 case UAS_EarlyNoOffer:
161 transition(UAS_EarlyProvidedOffer);
162 mProposedLocalSdp = InviteSession::makeSdp(offer, alternative);
163 mProposedEncryptionLevel = level;
164 break;
165
166 case UAS_NoOfferReliable:
167 mProposedLocalSdp = InviteSession::makeSdp(offer, alternative);
168 mProposedEncryptionLevel = level;
169 // !jf! transition ?
170 break;
171
172 case UAS_EarlyReliable:
173 // queue offer
174 transition(UAS_SentUpdate);
175 mProposedLocalSdp = InviteSession::makeSdp(offer, alternative);
176 mProposedEncryptionLevel = level;
177 sendUpdate(offer);
178 break;
179
180 case UAS_Accepted:
181 // queue the offer to be sent after the ACK is received
182 transition(UAS_WaitingToOffer);
183 mProposedLocalSdp = InviteSession::makeSdp(offer);
184 mProposedEncryptionLevel = level;
185 break;
186
187 case UAS_WaitingToOffer:
188 InviteSession::provideOffer(offer, level, alternative);
189 break;
190
191 case UAS_EarlyProvidedAnswer:
192 case UAS_EarlyProvidedOffer:
193 case UAS_FirstEarlyReliable:
194 case UAS_FirstSentOfferReliable:
195 case UAS_Offer:
196 case UAS_EarlyOffer:
197 case UAS_OfferReliable:
198 case UAS_OfferProvidedAnswer:
199 case UAS_ProvidedOffer:
200 case UAS_ReceivedUpdate:
201 case UAS_ReceivedUpdateWaitingAnswer:
202 case UAS_SentUpdate:
203 case UAS_SentUpdateAccepted:
204 case UAS_Start:
205 case UAS_WaitingToHangup:
206 case UAS_WaitingToTerminate:
207 case UAS_AcceptedWaitingAnswer:
208 assert(0);
209 break;
210 default:
211 InviteSession::provideOffer(offer, level, alternative);
212 break;
213 }
214 }
215
216 void
217 ServerInviteSession::provideOffer(const SdpContents& offer)
218 {
219 this->provideOffer(offer, mCurrentEncryptionLevel, 0);
220 }
221
222 void
223 ServerInviteSession::provideAnswer(const SdpContents& answer)
224 {
225 InviteSessionHandler* handler = mDum.mInviteSessionHandler;
226 InfoLog (<< toData(mState) << ": provideAnswer");
227 switch (mState)
228 {
229 case UAS_Offer:
230 transition(UAS_OfferProvidedAnswer);
231 mCurrentRemoteSdp = mProposedRemoteSdp;
232 mCurrentLocalSdp = InviteSession::makeSdp(answer);
233 break;
234
235 case UAS_EarlyOffer:
236 transition(UAS_EarlyProvidedAnswer);
237 mCurrentRemoteSdp = mProposedRemoteSdp;
238 mCurrentLocalSdp = InviteSession::makeSdp(answer);
239 break;
240
241 case UAS_OfferReliable:
242 // send1XX-answer, timer::1xx
243 transition(UAS_FirstEarlyReliable);
244 break;
245
246 case UAS_ReceivedUpdate:
247 // send::200U-answer
248 transition(UAS_EarlyReliable);
249 break;
250
251 case UAS_ReceivedUpdateWaitingAnswer:
252 // send::2XXU-answer
253 // send::2XXI
254 handler->onConnected(getSessionHandle(), mInvite200);
255 transition(Connected);
256 break;
257
258 case UAS_Accepted:
259 case UAS_WaitingToOffer:
260 case UAS_EarlyNoOffer:
261 case UAS_EarlyProvidedAnswer:
262 case UAS_EarlyProvidedOffer:
263 case UAS_EarlyReliable:
264 case UAS_FirstEarlyReliable:
265 case UAS_FirstSentOfferReliable:
266 case UAS_NoOffer:
267 case UAS_NoOfferReliable:
268 case UAS_OfferProvidedAnswer:
269 case UAS_ProvidedOffer:
270 case UAS_SentUpdate:
271 case UAS_SentUpdateAccepted:
272 case UAS_Start:
273 case UAS_WaitingToHangup:
274 case UAS_WaitingToTerminate:
275 case UAS_AcceptedWaitingAnswer:
276 assert(0);
277 break;
278 default:
279 InviteSession::provideAnswer(answer);
280 break;
281 }
282 }
283
284 void
285 ServerInviteSession::end()
286 {
287 end(NotSpecified);
288 }
289
290 void
291 ServerInviteSession::end(EndReason reason)
292 {
293 InfoLog (<< toData(mState) << ": end");
294 if (mEndReason == NotSpecified)
295 {
296 mEndReason = reason;
297 }
298
299 switch (mState)
300 {
301 case UAS_EarlyNoOffer:
302 case UAS_EarlyOffer:
303 case UAS_EarlyProvidedAnswer:
304 case UAS_EarlyProvidedOffer:
305 case UAS_NoOffer:
306 case UAS_Offer:
307 case UAS_OfferProvidedAnswer:
308 case UAS_ProvidedOffer:
309 reject(480);
310 break;
311
312 case UAS_OfferReliable:
313 case UAS_EarlyReliable:
314 case UAS_FirstSentOfferReliable:
315 case UAS_FirstEarlyReliable:
316 case UAS_NoOfferReliable:
317 case UAS_ReceivedUpdate: // !slg! todo: send 488U
318 case UAS_ReceivedUpdateWaitingAnswer: // !slg! todo: send 488U
319 case UAS_SentUpdate:
320 case UAS_WaitingToTerminate:
321 reject(480);
322 break;
323
324 case UAS_Start:
325 assert(0);
326 break;
327
328 case UAS_Accepted:
329 case UAS_WaitingToOffer:
330 case UAS_SentUpdateAccepted:
331 case UAS_AcceptedWaitingAnswer:
332 if(mCurrentRetransmit200) // If retransmit200 timer is active then ACK is not received yet - wait for it
333 {
334 transition(UAS_WaitingToHangup);
335 }
336 else
337 {
338 // ACK has likely timedout - hangup immediately
339 sendBye();
340 transition(Terminated);
341 mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Ended);
342 }
343 break;
344
345 case UAS_WaitingToHangup: // This can happen if we are waiting for an ACK to hangup and the ACK timesout
346 break;
347
348 default:
349 InviteSession::end(reason);
350 break;
351 }
352 }
353
354 void
355 ServerInviteSession::reject(int code, WarningCategory *warning)
356 {
357 InfoLog (<< toData(mState) << ": reject(" << code << ")");
358
359 switch (mState)
360 {
361 case UAS_EarlyNoOffer:
362 case UAS_EarlyOffer:
363 case UAS_EarlyProvidedAnswer:
364 case UAS_EarlyProvidedOffer:
365 case UAS_NoOffer:
366 case UAS_Offer:
367 case UAS_OfferProvidedAnswer:
368 case UAS_ProvidedOffer:
369
370 case UAS_EarlyReliable:
371 case UAS_FirstEarlyReliable:
372 case UAS_FirstSentOfferReliable:
373 case UAS_NoOfferReliable:
374 case UAS_OfferReliable:
375 case UAS_ReceivedUpdate:
376 case UAS_SentUpdate:
377 {
378 // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of
379 // an offer/answer exchange with PRACK.
380 // e.g. we sent 183 reliably and then 302 before PRACK was received. Ideally,
381 // we should send 200PRACK
382 SipMessage response;
383 mDialog.makeResponse(response, mFirstRequest, code);
384 if(warning)
385 {
386 response.header(h_Warnings).push_back(*warning);
387 }
388 send(response);
389
390 transition(Terminated);
391 mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Ended);
392 mDum.destroy(this);
393 break;
394 }
395
396 case UAS_Accepted:
397 case UAS_WaitingToOffer:
398 case UAS_ReceivedUpdateWaitingAnswer:
399 case UAS_SentUpdateAccepted:
400 case UAS_Start:
401 case UAS_WaitingToHangup:
402 case UAS_WaitingToTerminate:
403 assert(0);
404 break;
405
406 default:
407 InviteSession::reject(code);
408 break;
409 }
410 }
411
412 void
413 ServerInviteSession::accept(int code)
414 {
415 InfoLog (<< toData(mState) << ": accept(" << code << ")");
416 InviteSessionHandler* handler = mDum.mInviteSessionHandler;
417 switch (mState)
418 {
419 case UAS_Offer:
420 case UAS_EarlyOffer:
421 assert(0);
422 break;
423
424 case UAS_OfferProvidedAnswer:
425 case UAS_EarlyProvidedAnswer:
426 transition(UAS_Accepted);
427 sendAccept(code, mCurrentLocalSdp.get());
428 handler->onConnected(getSessionHandle(), mInvite200);
429 break;
430
431 case UAS_NoOffer:
432 case UAS_EarlyNoOffer:
433 assert(0);
434
435 case UAS_ProvidedOffer:
436 case UAS_EarlyProvidedOffer:
437 transition(UAS_AcceptedWaitingAnswer);
438 sendAccept(code, mProposedLocalSdp.get());
439 break;
440
441 case UAS_Accepted:
442 case UAS_WaitingToOffer:
443 assert(0); // Already Accepted
444 break;
445
446 case UAS_FirstEarlyReliable:
447 // queue 2xx
448 // waiting for PRACK
449 transition(UAS_Accepted);
450 mDialog.makeResponse(mInvite200, mFirstRequest, code);
451 handleSessionTimerRequest(mInvite200, mFirstRequest);
452 break;
453
454 case UAS_EarlyReliable:
455 transition(Connected);
456 sendAccept(code, 0);
457 handler->onConnected(getSessionHandle(), mInvite200);
458 break;
459
460 case UAS_SentUpdate:
461 transition(UAS_SentUpdateAccepted);
462 sendAccept(code, 0);
463 break;
464
465 case UAS_ReceivedUpdate:
466 transition(UAS_ReceivedUpdateWaitingAnswer);
467 mDialog.makeResponse(mInvite200, mFirstRequest, code);// queue 2xx
468 handleSessionTimerRequest(mInvite200, mFirstRequest);
469 break;
470
471 case UAS_FirstSentOfferReliable:
472 case UAS_NoOfferReliable:
473 case UAS_OfferReliable:
474 case UAS_ReceivedUpdateWaitingAnswer:
475 case UAS_SentUpdateAccepted:
476 case UAS_Start:
477 case UAS_WaitingToHangup:
478 case UAS_WaitingToTerminate:
479 default:
480 assert(0);
481 break;
482 }
483 }
484
485 void
486 ServerInviteSession::dispatch(const SipMessage& msg)
487 {
488 switch (mState)
489 {
490 case UAS_Start:
491 dispatchStart(msg);
492 break;
493
494 case UAS_Offer:
495 case UAS_EarlyOffer:
496 case UAS_EarlyProvidedAnswer:
497 case UAS_NoOffer:
498 case UAS_ProvidedOffer:
499 case UAS_EarlyNoOffer:
500 case UAS_EarlyProvidedOffer:
501 case UAS_OfferProvidedAnswer:
502 dispatchOfferOrEarly(msg);
503 break;
504 case UAS_Accepted:
505 dispatchAccepted(msg);
506 break;
507 case UAS_WaitingToOffer:
508 dispatchWaitingToOffer(msg);
509 break;
510 case UAS_AcceptedWaitingAnswer:
511 dispatchAcceptedWaitingAnswer(msg);
512 break;
513 case UAS_EarlyReliable:
514 dispatchEarlyReliable(msg);
515 break;
516 case UAS_FirstEarlyReliable:
517 dispatchFirstEarlyReliable(msg);
518 break;
519 case UAS_FirstSentOfferReliable:
520 dispatchFirstSentOfferReliable(msg);
521 break;
522 case UAS_NoOfferReliable:
523 dispatchNoOfferReliable(msg);
524 break;
525 case UAS_OfferReliable:
526 dispatchOfferReliable(msg);
527 break;
528 case UAS_ReceivedUpdate:
529 dispatchReceivedUpdate(msg);
530 break;
531 case UAS_ReceivedUpdateWaitingAnswer:
532 dispatchReceivedUpdateWaitingAnswer(msg);
533 break;
534 case UAS_SentUpdate:
535 dispatchSentUpdate(msg);
536 break;
537 case UAS_WaitingToHangup:
538 dispatchWaitingToHangup(msg);
539 break;
540 case UAS_WaitingToTerminate:
541 dispatchWaitingToTerminate(msg);
542 break;
543 case UAS_SentUpdateAccepted:
544 dispatchSentUpdateAccepted(msg);
545 break;
546 default:
547 InviteSession::dispatch(msg);
548 break;
549 }
550 }
551
552 void
553 ServerInviteSession::dispatch(const DumTimeout& timeout)
554 {
555 if (timeout.type() == DumTimeout::Retransmit1xx)
556 {
557 if (mCurrentRetransmit1xx && m1xx.header(h_CSeq).sequence() == timeout.seq()) // If timer isn't stopped and this timer is for last 1xx sent, then resend
558 {
559 send(m1xx);
560 startRetransmit1xxTimer();
561 }
562 }
563 else
564 {
565 InviteSession::dispatch(timeout);
566 }
567 }
568
569 void
570 ServerInviteSession::dispatchStart(const SipMessage& msg)
571 {
572 assert(msg.isRequest());
573 assert(msg.header(h_CSeq).method() == INVITE);
574
575 InviteSessionHandler* handler = mDum.mInviteSessionHandler;
576 std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);
577 storePeerCapabilities(msg);
578
579 switch (toEvent(msg, sdp.get()))
580 {
581 case OnInviteOffer:
582 mLastSessionModification = msg;
583 transition(UAS_Offer);
584 mProposedRemoteSdp = InviteSession::makeSdp(*sdp);
585 mCurrentEncryptionLevel = getEncryptionLevel(msg);
586 handler->onNewSession(getHandle(), Offer, msg);
587 if(!isTerminated())
588 {
589 handler->onOffer(getSessionHandle(), msg, *sdp);
590 }
591 break;
592 case OnInvite:
593 mLastSessionModification = msg;
594 transition(UAS_NoOffer);
595 handler->onNewSession(getHandle(), None, msg);
596 if(!isTerminated())
597 {
598 handler->onOfferRequired(getSessionHandle(), msg);
599 }
600 break;
601 case OnInviteReliableOffer:
602 mLastSessionModification = msg;
603 transition(UAS_OfferReliable);
604 mProposedRemoteSdp = InviteSession::makeSdp(*sdp);
605 mCurrentEncryptionLevel = getEncryptionLevel(msg);
606 handler->onNewSession(getHandle(), Offer, msg);
607 if(!isTerminated())
608 {
609 handler->onOffer(getSessionHandle(), msg, *sdp);
610 }
611 break;
612 case OnInviteReliable:
613 mLastSessionModification = msg;
614 transition(UAS_NoOfferReliable);
615 handler->onNewSession(getHandle(), None, msg);
616 if(!isTerminated())
617 {
618 handler->onOfferRequired(getSessionHandle(), msg);
619 }
620 break;
621 default:
622 assert(0);
623 break;
624 }
625 }
626
627 // Offer, Early, EarlyNoOffer, NoOffer
628 void
629 ServerInviteSession::dispatchOfferOrEarly(const SipMessage& msg)
630 {
631 std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);
632 switch (toEvent(msg, sdp.get()))
633 {
634 case OnCancel:
635 dispatchCancel(msg);
636 break;
637 case OnBye:
638 dispatchBye(msg);
639 break;
640 default:
641 assert(msg.isRequest());
642 dispatchUnknown(msg);
643 break;
644 }
645 }
646
647 void
648 ServerInviteSession::dispatchAccepted(const SipMessage& msg)
649 {
650 InviteSessionHandler* handler = mDum.mInviteSessionHandler;
651 std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);
652 InfoLog (<< "dispatchAccepted: " << msg.brief());
653
654 switch (toEvent(msg, sdp.get()))
655 {
656 case OnAck:
657 {
658 mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
659 transition(Connected);
660 // handler->onConnected(getSessionHandle(), msg); // not needed since onConnected is called when 200 is sent
661 break;
662 }
663
664 case OnAckAnswer:
665 {
666 mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
667 sendBye();
668 transition(Terminated);
669 handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg);
670 break;
671 }
672
673 case OnCancel:
674 {
675 // Cancel and 200 crossed
676 SipMessage c200;
677 mDialog.makeResponse(c200, msg, 200);
678 send(c200);
679 break;
680 }
681
682 case OnBye:
683 {
684 SipMessage b200;
685 mDialog.makeResponse(b200, msg, 200);
686 send(b200);
687
688 transition(Terminated);
689 handler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, &msg);
690 mDum.destroy(this);
691 break;
692 }
693
694
695 default:
696 if(msg.isRequest())
697 {
698 dispatchUnknown(msg);
699 }
700 break;
701 }
702 }
703
704 void
705 ServerInviteSession::dispatchWaitingToOffer(const SipMessage& msg)
706 {
707 InviteSessionHandler* handler = mDum.mInviteSessionHandler;
708 std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);
709 InfoLog (<< "dispatchAccepted: " << msg.brief());
710
711 switch (toEvent(msg, sdp.get()))
712 {
713 case OnAck:
714 {
715 assert(mProposedLocalSdp.get());
716 mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
717 provideProposedOffer();
718 break;
719 }
720
721 case OnAckAnswer:
722 {
723 mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
724 sendBye();
725 transition(Terminated);
726 handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg);
727 break;
728 }
729
730 case OnCancel:
731 {
732 // Cancel and 200 crossed
733 SipMessage c200;
734 mDialog.makeResponse(c200, msg, 200);
735 send(c200);
736 break;
737 }
738
739 case OnBye:
740 {
741 SipMessage b200;
742 mDialog.makeResponse(b200, msg, 200);
743 send(b200);
744
745 transition(Terminated);
746 handler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, &msg);
747 mDum.destroy(this);
748 break;
749 }
750
751 default:
752 if(msg.isRequest())
753 {
754 dispatchUnknown(msg);
755 }
756 break;
757 }
758 }
759
760 void
761 ServerInviteSession::dispatchAcceptedWaitingAnswer(const SipMessage& msg)
762 {
763 InviteSessionHandler* handler = mDum.mInviteSessionHandler;
764 std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);
765
766 switch (toEvent(msg, sdp.get()))
767 {
768 case OnAckAnswer:
769 {
770 mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
771 transition(Connected);
772 setCurrentLocalSdp(msg);
773 mCurrentEncryptionLevel = getEncryptionLevel(msg);
774 mCurrentRemoteSdp = InviteSession::makeSdp(*sdp);
775 handler->onAnswer(getSessionHandle(), msg, *sdp);
776 if(!isTerminated()) // onAnswer callback may call end() or reject()
777 {
778 handler->onConnected(getSessionHandle(), msg);
779 }
780 break;
781 }
782
783 case OnAck:
784 {
785 mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
786 mEndReason = IllegalNegotiation;
787 sendBye();
788 transition(Terminated);
789 handler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg);
790 break;
791 }
792
793 case OnCancel:
794 {
795 // no transition
796
797 SipMessage c200;
798 mDialog.makeResponse(c200, msg, 200);
799 send(c200);
800 break;
801 }
802
803 case OnPrack: // broken
804 {
805 // no transition
806
807 SipMessage p200;
808 mDialog.makeResponse(p200, msg, 200);
809 send(p200);
810
811 sendAccept(200, 0);
812 break;
813 }
814
815 default:
816 if(msg.isRequest())
817 {
818 dispatchUnknown(msg);
819 }
820 break;
821 }
822 }
823
824 void
825 ServerInviteSession::dispatchOfferReliable(const SipMessage& msg)
826 {
827 }
828
829 void
830 ServerInviteSession::dispatchNoOfferReliable(const SipMessage& msg)
831 {
832 }
833
834 void
835 ServerInviteSession::dispatchFirstSentOfferReliable(const SipMessage& msg)
836 {
837 }
838
839 void
840 ServerInviteSession::dispatchFirstEarlyReliable(const SipMessage& msg)
841 {
842 }
843
844 void
845 ServerInviteSession::dispatchEarlyReliable(const SipMessage& msg)
846 {
847 }
848
849 void
850 ServerInviteSession::dispatchSentUpdate(const SipMessage& msg)
851 {
852 }
853
854 void
855 ServerInviteSession::dispatchSentUpdateAccepted(const SipMessage& msg)
856 {
857 }
858
859 void
860 ServerInviteSession::dispatchReceivedUpdate(const SipMessage& msg)
861 {
862 }
863
864 void
865 ServerInviteSession::dispatchReceivedUpdateWaitingAnswer(const SipMessage& msg)
866 {
867 }
868
869 void
870 ServerInviteSession::dispatchWaitingToTerminate(const SipMessage& msg)
871 {
872 }
873
874 void
875 ServerInviteSession::dispatchWaitingToHangup(const SipMessage& msg)
876 {
877 std::auto_ptr<SdpContents> sdp = InviteSession::getSdp(msg);
878
879 switch (toEvent(msg, sdp.get()))
880 {
881 case OnPrack:
882 case OnAck:
883 case OnAckAnswer:
884 {
885 mCurrentRetransmit200 = 0; // stop the 200 retransmit timer
886
887 sendBye();
888 transition(Terminated);
889 mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Ended);
890 break;
891 }
892
893 default:
894 break;
895 }
896 }
897
898 void
899 ServerInviteSession::dispatchCancel(const SipMessage& msg)
900 {
901 SipMessage c200;
902 mDialog.makeResponse(c200, msg, 200);
903 send(c200);
904
905 SipMessage i487;
906 mDialog.makeResponse(i487, mFirstRequest, 487);
907 send(i487);
908
909 transition(Terminated);
910 mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, &msg);
911 mDum.destroy(this);
912 }
913
914 void
915 ServerInviteSession::dispatchBye(const SipMessage& msg)
916 {
917 SipMessage b200;
918 mDialog.makeResponse(b200, msg, 200);
919 send(b200);
920
921 SipMessage i487;
922 mDialog.makeResponse(i487, mFirstRequest, 487);
923 send(i487);
924
925 transition(Terminated);
926 mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, &msg);
927 mDum.destroy(this);
928 }
929
930 void
931 ServerInviteSession::dispatchUnknown(const SipMessage& msg)
932 {
933 SipMessage r481; // !jf! what should we send here?
934 mDialog.makeResponse(r481, msg, 481);
935 send(r481);
936
937 SipMessage i400;
938 mDialog.makeResponse(i400, mFirstRequest, 400);
939 send(i400);
940
941 transition(Terminated);
942 mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::GeneralFailure, &msg);
943 mDum.destroy(this);
944 }
945
946 void
947 ServerInviteSession::startRetransmit1xxTimer()
948 {
949 // RFC3261 13.3.1 says the UAS must send a non-100 provisional response every minute, to handle the possiblity of lost provisional responses
950 mCurrentRetransmit1xx = mDialog.mDialogSet.getUserProfile()->get1xxRetransmissionTime();
951 if(mCurrentRetransmit1xx > 0)
952 {
953 int seq = m1xx.header(h_CSeq).sequence();
954 mDum.addTimer(DumTimeout::Retransmit1xx, mCurrentRetransmit1xx, getBaseHandle(), seq);
955 }
956 }
957
958 void
959 ServerInviteSession::sendProvisional(int code)
960 {
961 mDialog.makeResponse(m1xx, mFirstRequest, code);
962 switch (mState)
963 {
964 case UAS_OfferProvidedAnswer:
965 case UAS_EarlyProvidedAnswer:
966 if (mCurrentLocalSdp.get()) // early media
967 {
968 setSdp(m1xx, mCurrentLocalSdp.get());
969 }
970 break;
971
972 default:
973 break;
974 }
975 startRetransmit1xxTimer();
976 DumHelper::setOutgoingEncryptionLevel(m1xx, mProposedEncryptionLevel);
977 send(m1xx);
978 }
979
980 void
981 ServerInviteSession::sendAccept(int code, Contents* sdp)
982 {
983 mDialog.makeResponse(mInvite200, mFirstRequest, code);
984 handleSessionTimerRequest(mInvite200, mFirstRequest);
985 if (sdp)
986 {
987 setSdp(mInvite200, sdp);
988 }
989 mCurrentRetransmit1xx = 0; // Stop the 1xx timer
990 startRetransmit200Timer(); // 2xx timer
991 DumHelper::setOutgoingEncryptionLevel(mInvite200, mCurrentEncryptionLevel);
992 send(mInvite200);
993 }
994
995 void
996 ServerInviteSession::sendUpdate(const SdpContents& sdp)
997 {
998 if (updateMethodSupported())
999 {
1000 mDialog.makeRequest(mLastSessionModification, UPDATE);
1001 InviteSession::setSdp(mLastSessionModification, sdp);
1002 DumHelper::setOutgoingEncryptionLevel(mLastSessionModification, mProposedEncryptionLevel);
1003 send(mLastSessionModification);
1004 }
1005 else
1006 {
1007 throw UsageUseException("Can't send UPDATE to peer", __FILE__, __LINE__);
1008 }
1009 }
1010
1011 /* ====================================================================
1012 * The Vovida Software License, Version 1.0
1013 *
1014 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
1015 *
1016 * Redistribution and use in source and binary forms, with or without
1017 * modification, are permitted provided that the following conditions
1018 * are met:
1019 *
1020 * 1. Redistributions of source code must retain the above copyright
1021 * notice, this list of conditions and the following disclaimer.
1022 *
1023 * 2. Redistributions in binary form must reproduce the above copyright
1024 * notice, this list of conditions and the following disclaimer in
1025 * the documentation and/or other materials provided with the
1026
1027 * distribution.
1028 *
1029 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1030 * and "Vovida Open Communication Application Library (VOCAL)" must
1031 * not be used to endorse or promote products derived from this
1032 * software without prior written permission. For written
1033 * permission, please contact vocal@vovida.org.
1034 *
1035 * 4. Products derived from this software may not be called "VOCAL", nor
1036 * may "VOCAL" appear in their name, without prior written
1037 * permission of Vovida Networks, Inc.
1038 *
1039 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1040 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1041 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1042 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
1043 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1044 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1045 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1046 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1047 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1048 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1049 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1050 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1051 * DAMAGE.
1052 *
1053 * ====================================================================
1054 *
1055 * This software consists of voluntary contributions made by Vovida
1056 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1057 * Inc. For more information on Vovida Networks, Inc., please see
1058 * <http://www.vovida.org/>.
1059 *
1060 */

Properties

Name Value
svn:eol-style LF

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27