/[resiprocate]/main/resip/dum/test/basicClientCall.cxx
ViewVC logotype

Contents of /main/resip/dum/test/basicClientCall.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10975 - (show annotations) (download)
Sun Feb 16 20:04:10 2014 UTC (5 years, 3 months ago) by sgodin
File MIME type: text/plain
File size: 22851 byte(s)
-removed use of raw transport pointers in Tuple and SipMessage (finally!!)
 -required repro record route logic to be modified - no longer store transport specific
  record routes in the Transport class - the Proxy class now tracks these
 -removed SipMessage::getReceivedTransport and added isFromWire method that can be used in
  it's place in various locations

1 #include "basicClientCall.hxx"
2
3 #include <resip/stack/SdpContents.hxx>
4 #include <resip/stack/PlainContents.hxx>
5 #include <resip/stack/SipMessage.hxx>
6 #include <resip/stack/ShutdownMessage.hxx>
7 #include <resip/stack/SipStack.hxx>
8 #include <resip/dum/ClientAuthManager.hxx>
9 #include <resip/dum/ClientInviteSession.hxx>
10 #include <resip/dum/ClientSubscription.hxx>
11 #include <resip/dum/DialogUsageManager.hxx>
12 #include <resip/dum/InviteSessionHandler.hxx>
13 #include <resip/dum/MasterProfile.hxx>
14 #include <resip/dum/ServerInviteSession.hxx>
15 #include <resip/dum/AppDialog.hxx>
16 #include <resip/dum/AppDialogSet.hxx>
17 #include <resip/dum/AppDialogSetFactory.hxx>
18 #include <rutil/Log.hxx>
19 #include <rutil/Logger.hxx>
20 #include <rutil/Random.hxx>
21 #include <rutil/WinLeakCheck.hxx>
22
23 #include <sstream>
24 #include <time.h>
25
26 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST
27
28 using namespace resip;
29 using namespace std;
30
31 static unsigned int CallTimerTime = 30; // Time between call timer
32 static unsigned int CallTimeCounterToByeOn = 6; // BYE the call after the call timer has expired 6 times
33
34 namespace resip
35 {
36 class CallTimer : public resip::DumCommand
37 {
38 public:
39 CallTimer(BasicClientUserAgent& userAgent, BasicClientCall* call) : mUserAgent(userAgent), mCall(call) {}
40 CallTimer(const CallTimer& rhs) : mUserAgent(rhs.mUserAgent), mCall(rhs.mCall) {}
41 ~CallTimer() {}
42
43 void executeCommand() { mUserAgent.onCallTimeout(mCall); }
44
45 resip::Message* clone() const { return new CallTimer(*this); }
46 EncodeStream& encode(EncodeStream& strm) const { strm << "CallTimer:"; return strm; }
47 EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
48
49 private:
50 BasicClientUserAgent& mUserAgent;
51 BasicClientCall* mCall;
52 };
53 }
54
55 BasicClientCall::BasicClientCall(BasicClientUserAgent& userAgent)
56 : AppDialogSet(userAgent.getDialogUsageManager()),
57 mUserAgent(userAgent),
58 mTimerExpiredCounter(0),
59 mPlacedCall(false),
60 mUACConnectedDialogId(Data::Empty, Data::Empty, Data::Empty)
61 {
62 mUserAgent.registerCall(this);
63 }
64
65 BasicClientCall::~BasicClientCall()
66 {
67 mUserAgent.unregisterCall(this);
68 }
69
70 void
71 BasicClientCall::initiateCall(const Uri& target, SharedPtr<UserProfile> profile)
72 {
73 SdpContents offer;
74 makeOffer(offer);
75 SharedPtr<SipMessage> invite = mUserAgent.getDialogUsageManager().makeInviteSession(NameAddr(target), profile, &offer, this);
76 mUserAgent.getDialogUsageManager().send(invite);
77 mPlacedCall = true;
78 }
79
80 void
81 BasicClientCall::terminateCall()
82 {
83 AppDialogSet::end();
84 }
85
86 void
87 BasicClientCall::timerExpired()
88 {
89 mTimerExpiredCounter++;
90 if(mTimerExpiredCounter < CallTimeCounterToByeOn)
91 {
92 // First few times, send a message to the other party
93 if(mInviteSessionHandle.isValid())
94 {
95 PlainContents plain("test message");
96 mInviteSessionHandle->message(plain);
97 }
98 }
99 else
100 {
101 // Then hangup
102 terminateCall();
103 }
104
105 // start timer for next one
106 auto_ptr<ApplicationMessage> timer(new CallTimer(mUserAgent, this));
107 mUserAgent.mStack->post(timer, CallTimerTime, &mUserAgent.getDialogUsageManager());
108 }
109
110 SharedPtr<UserProfile>
111 BasicClientCall::selectUASUserProfile(const SipMessage& msg)
112 {
113 return mUserAgent.getIncomingUserProfile(msg);
114 }
115
116 bool
117 BasicClientCall::isUACConnected()
118 {
119 return !mUACConnectedDialogId.getCallId().empty();
120 }
121
122 bool
123 BasicClientCall::isStaleFork(const DialogId& dialogId)
124 {
125 return (!mUACConnectedDialogId.getCallId().empty() && dialogId != mUACConnectedDialogId);
126 }
127
128 void
129 BasicClientCall::makeOffer(SdpContents& offer)
130 {
131 static Data txt("v=0\r\n"
132 "o=- 0 0 IN IP4 0.0.0.0\r\n"
133 "s=basicClient\r\n"
134 "c=IN IP4 0.0.0.0\r\n"
135 "t=0 0\r\n"
136 "m=audio 8000 RTP/AVP 0 101\r\n"
137 "a=rtpmap:0 pcmu/8000\r\n"
138 "a=rtpmap:101 telephone-event/8000\r\n"
139 "a=fmtp:101 0-15\r\n");
140
141 static HeaderFieldValue hfv(txt.data(), txt.size());
142 static Mime type("application", "sdp");
143 static SdpContents offerSdp(hfv, type);
144
145 offer = offerSdp;
146
147 // Set sessionid and version for this offer
148 UInt64 currentTime = Timer::getTimeMicroSec();
149 offer.session().origin().getSessionId() = currentTime;
150 offer.session().origin().getVersion() = currentTime;
151 }
152
153 ////////////////////////////////////////////////////////////////////////////////
154 // InviteSessionHandler ///////////////////////////////////////////////////
155 ////////////////////////////////////////////////////////////////////////////////
156
157 void
158 BasicClientCall::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
159 {
160 InfoLog(<< "onNewSession(ClientInviteSessionHandle): msg=" << msg.brief());
161 mInviteSessionHandle = h->getSessionHandle(); // Note: each forked leg will update mInviteSession - need to set mInviteSessionHandle for final answering leg on 200
162 if(mInviteSessionHandleReplaced.isValid())
163 {
164 // See comment in flowTerminated for an explanation of this logic
165 ((BasicClientCall*)mInviteSessionHandleReplaced->getAppDialogSet().get())->terminateCall();
166 }
167 }
168
169 void
170 BasicClientCall::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
171 {
172 InfoLog(<< "onNewSession(ServerInviteSessionHandle): msg=" << msg.brief());
173 mInviteSessionHandle = h->getSessionHandle();
174
175 // First check if this INVITE is to replace an existing session
176 if(msg.exists(h_Replaces))
177 {
178 pair<InviteSessionHandle, int> presult;
179 presult = mDum.findInviteSession(msg.header(h_Replaces));
180 if(!(presult.first == InviteSessionHandle::NotValid()))
181 {
182 BasicClientCall* callToReplace = dynamic_cast<BasicClientCall *>(presult.first->getAppDialogSet().get());
183 InfoLog(<< "onNewSession(ServerInviteSessionHandle): replacing existing call");
184
185 // Copy over flag that indicates if we placed the call or not
186 mPlacedCall = callToReplace->mPlacedCall;
187
188 if(mPlacedCall)
189 {
190 // Restart Call Timer
191 auto_ptr<ApplicationMessage> timer(new CallTimer(mUserAgent, this));
192 mUserAgent.mStack->post(timer, CallTimerTime, &mUserAgent.getDialogUsageManager());
193 }
194
195 // Session to replace was found - end old session
196 callToReplace->end();
197 }
198 else
199 {
200 // Session to replace not found - reject it
201 h->reject(481 /* Call/Transaction Does Not Exist */);
202 }
203 }
204 }
205
206 void
207 BasicClientCall::onFailure(ClientInviteSessionHandle h, const SipMessage& msg)
208 {
209 WarningLog(<< "onFailure: msg=" << msg.brief());
210
211 if (msg.isResponse())
212 {
213 switch(msg.header(h_StatusLine).statusCode())
214 {
215 case 408:
216 case 503:
217 if(!msg.isFromWire())
218 {
219 // Try another flow?
220 }
221 default:
222 break;
223 }
224 }
225 }
226
227 void
228 BasicClientCall::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
229 {
230 InfoLog(<< "onEarlyMedia: msg=" << msg.brief() << ", sdp=" << sdp);
231 }
232
233 void
234 BasicClientCall::onProvisional(ClientInviteSessionHandle h, const SipMessage& msg)
235 {
236 InfoLog(<< "onProvisional: msg=" << msg.brief());
237
238 if(isStaleFork(h->getDialogId()))
239 {
240 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it
241 InfoLog(<< "onProvisional: from stale fork, msg=" << msg.brief());
242 return;
243 }
244 InfoLog(<< "onProvisional: msg=" << msg.brief());
245 }
246
247 void
248 BasicClientCall::onConnected(ClientInviteSessionHandle h, const SipMessage& msg)
249 {
250 InfoLog(<< "onConnected: msg=" << msg.brief());
251 if(!isUACConnected())
252 {
253 // It is possible in forking scenarios to get multiple 200 responses, if this is
254 // our first 200 response, then this is the leg we accept, store the connected DialogId
255 mUACConnectedDialogId = h->getDialogId();
256 // Note: each forked leg will update mInviteSessionHandle (in onNewSession call) - need to set mInviteSessionHandle for final answering leg on 200
257 mInviteSessionHandle = h->getSessionHandle();
258
259 // start call timer
260 auto_ptr<ApplicationMessage> timer(new CallTimer(mUserAgent, this));
261 mUserAgent.mStack->post(timer, CallTimerTime, &mUserAgent.getDialogUsageManager());
262 }
263 else
264 {
265 // We already have a connected leg - end this one with a BYE
266 h->end();
267 }
268 }
269
270 void
271 BasicClientCall::onConnected(InviteSessionHandle h, const SipMessage& msg)
272 {
273 InfoLog(<< "onConnected: msg=" << msg.brief());
274 }
275
276 void
277 BasicClientCall::onStaleCallTimeout(ClientInviteSessionHandle h)
278 {
279 WarningLog(<< "onStaleCallTimeout");
280 }
281
282 void
283 BasicClientCall::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
284 {
285 Data reasonData;
286
287 switch(reason)
288 {
289 case InviteSessionHandler::RemoteBye:
290 reasonData = "received a BYE from peer";
291 break;
292 case InviteSessionHandler::RemoteCancel:
293 reasonData = "received a CANCEL from peer";
294 break;
295 case InviteSessionHandler::Rejected:
296 reasonData = "received a rejection from peer";
297 break;
298 case InviteSessionHandler::LocalBye:
299 reasonData = "ended locally via BYE";
300 break;
301 case InviteSessionHandler::LocalCancel:
302 reasonData = "ended locally via CANCEL";
303 break;
304 case InviteSessionHandler::Replaced:
305 reasonData = "ended due to being replaced";
306 break;
307 case InviteSessionHandler::Referred:
308 reasonData = "ended due to being referred";
309 break;
310 case InviteSessionHandler::Error:
311 reasonData = "ended due to an error";
312 break;
313 case InviteSessionHandler::Timeout:
314 reasonData = "ended due to a timeout";
315 break;
316 default:
317 assert(false);
318 break;
319 }
320
321 if(isStaleFork(h->getDialogId()))
322 {
323 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it
324 if(msg)
325 {
326 InfoLog(<< "onTerminated: from stale fork, reason=" << reasonData << ", msg=" << msg->brief());
327 }
328 else
329 {
330 InfoLog(<< "onTerminated: from stale fork, reason=" << reasonData);
331 }
332 return;
333 }
334
335 if(msg)
336 {
337 InfoLog(<< "onTerminated: reason=" << reasonData << ", msg=" << msg->brief());
338 }
339 else
340 {
341 InfoLog(<< "onTerminated: reason=" << reasonData);
342 }
343 }
344
345 void
346 BasicClientCall::onRedirected(ClientInviteSessionHandle h, const SipMessage& msg)
347 {
348 // DUM will recurse on redirect requests, so nothing to do here
349 InfoLog(<< "onRedirected: msg=" << msg.brief());
350 }
351
352 void
353 BasicClientCall::onAnswer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
354 {
355 if(isStaleFork(h->getDialogId()))
356 {
357 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it
358 InfoLog(<< "onAnswer: from stale fork, msg=" << msg.brief() << ", sdp=" << sdp);
359 return;
360 }
361 InfoLog(<< "onAnswer: msg=" << msg.brief() << ", sdp=" << sdp);
362
363 // Process Answer here
364 }
365
366 void
367 BasicClientCall::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
368 {
369 if(isStaleFork(h->getDialogId()))
370 {
371 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it
372 InfoLog(<< "onOffer: from stale fork, msg=" << msg.brief() << ", sdp=" << sdp);
373 return;
374 }
375 InfoLog(<< "onOffer: msg=" << msg.brief() << ", sdp=" << sdp);
376
377 // Provide Answer here - for test client just echo back same SDP as received for now
378 h->provideAnswer(sdp);
379 ServerInviteSession* uas = dynamic_cast<ServerInviteSession*>(h.get());
380 if(uas && !uas->isAccepted())
381 {
382 uas->accept();
383 }
384 }
385
386 void
387 BasicClientCall::onOfferRequired(InviteSessionHandle h, const SipMessage& msg)
388 {
389 if(isStaleFork(h->getDialogId()))
390 {
391 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it
392 InfoLog(<< "onOfferRequired: from stale fork, msg=" << msg.brief());
393 return;
394 }
395 InfoLog(<< "onOfferRequired: msg=" << msg.brief());
396
397 // Provide Offer Here
398 SdpContents offer;
399 makeOffer(offer);
400
401 h->provideOffer(offer);
402 }
403
404 void
405 BasicClientCall::onOfferRejected(InviteSessionHandle h, const SipMessage* msg)
406 {
407 if(isStaleFork(h->getDialogId()))
408 {
409 // If we receive a response from a stale fork (ie. after someone sends a 200), then we want to ignore it
410 if(msg)
411 {
412 WarningLog(<< "onOfferRejected: from stale fork, msg=" << msg->brief());
413 }
414 else
415 {
416 WarningLog(<< "onOfferRejected: from stale fork");
417 }
418 return;
419 }
420 if(msg)
421 {
422 WarningLog(<< "onOfferRejected: msg=" << msg->brief());
423 }
424 else
425 {
426 WarningLog(<< "onOfferRejected");
427 }
428 }
429
430 void
431 BasicClientCall::onOfferRequestRejected(InviteSessionHandle h, const SipMessage& msg)
432 {
433 InfoLog(<< "onOfferRequestRejected: msg=" << msg.brief());
434 // This is called when we are waiting to resend a INVITE with no sdp after a glare condition, and we
435 // instead receive an inbound INVITE or UPDATE
436 }
437
438 void
439 BasicClientCall::onRemoteSdpChanged(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
440 {
441 /// called when a modified SDP is received in a 2xx response to a
442 /// session-timer reINVITE. Under normal circumstances where the response
443 /// SDP is unchanged from current remote SDP no handler is called
444 /// There is not much we can do about this. If session timers are used then they are managed seperately per leg
445 /// and we have no real mechanism to notify the other peer of new SDP without starting a new offer/answer negotiation
446 InfoLog(<< "onRemoteSdpChanged: msg=" << msg << ", sdp=" << sdp);
447
448 // Process SDP Answer here
449 }
450
451 void
452 BasicClientCall::onInfo(InviteSessionHandle h, const SipMessage& msg)
453 {
454 InfoLog(<< "onInfo: msg=" << msg.brief());
455
456 // Handle message here
457 h->acceptNIT();
458 }
459
460 void
461 BasicClientCall::onInfoSuccess(InviteSessionHandle h, const SipMessage& msg)
462 {
463 InfoLog(<< "onInfoSuccess: msg=" << msg.brief());
464 }
465
466 void
467 BasicClientCall::onInfoFailure(InviteSessionHandle h, const SipMessage& msg)
468 {
469 WarningLog(<< "onInfoFailure: msg=" << msg.brief());
470 }
471
472 void
473 BasicClientCall::onRefer(InviteSessionHandle h, ServerSubscriptionHandle ss, const SipMessage& msg)
474 {
475 InfoLog(<< "onRefer: msg=" << msg.brief());
476
477 // Handle Refer request here
478 }
479
480 void
481 BasicClientCall::onReferAccepted(InviteSessionHandle h, ClientSubscriptionHandle csh, const SipMessage& msg)
482 {
483 InfoLog(<< "onReferAccepted: msg=" << msg.brief());
484 }
485
486 void
487 BasicClientCall::onReferRejected(InviteSessionHandle h, const SipMessage& msg)
488 {
489 WarningLog(<< "onReferRejected: msg=" << msg.brief());
490 }
491
492 void
493 BasicClientCall::onReferNoSub(InviteSessionHandle h, const SipMessage& msg)
494 {
495 InfoLog(<< "onReferNoSub: msg=" << msg.brief());
496
497 // Handle Refer request with (no-subscription indication) here
498 }
499
500 void
501 BasicClientCall::onMessage(InviteSessionHandle h, const SipMessage& msg)
502 {
503 InfoLog(<< "onMessage: msg=" << msg.brief());
504
505 // Handle message here
506 h->acceptNIT();
507
508 if(!mPlacedCall)
509 {
510 // If we didn't place the call - answer the message with another message
511 PlainContents plain("test message answer");
512 h->message(plain);
513 }
514 }
515
516 void
517 BasicClientCall::onMessageSuccess(InviteSessionHandle h, const SipMessage& msg)
518 {
519 InfoLog(<< "onMessageSuccess: msg=" << msg.brief());
520 }
521
522 void
523 BasicClientCall::onMessageFailure(InviteSessionHandle h, const SipMessage& msg)
524 {
525 WarningLog(<< "onMessageFailure: msg=" << msg.brief());
526 }
527
528 void
529 BasicClientCall::onForkDestroyed(ClientInviteSessionHandle h)
530 {
531 InfoLog(<< "onForkDestroyed:");
532 }
533
534 void
535 BasicClientCall::onReadyToSend(InviteSessionHandle h, SipMessage& msg)
536 {
537 }
538
539 void
540 BasicClientCall::onFlowTerminated(InviteSessionHandle h)
541 {
542 if(h->isConnected())
543 {
544 NameAddr inviteWithReplacesTarget;
545 if(h->remoteTarget().uri().exists(p_gr))
546 {
547 // If remote contact is a GRUU then use it
548 inviteWithReplacesTarget.uri() = h->remoteTarget().uri();
549 }
550 else
551 {
552 //.Use remote AOR
553 inviteWithReplacesTarget.uri() = h->peerAddr().uri();
554 }
555 InfoLog(<< "BasicClientCall::onFlowTerminated: trying INVITE w/replaces to " << inviteWithReplacesTarget);
556 // The flow terminated - try an Invite (with Replaces) to recover the call
557 BasicClientCall *replacesCall = new BasicClientCall(mUserAgent);
558
559 // Copy over flag that indicates wether original call was placed or received
560 replacesCall->mPlacedCall = mPlacedCall;
561
562 // Note: We want to end this call since it is to be replaced. Normally the endpoint
563 // receiving the INVITE with replaces would send us a BYE for the session being replaced.
564 // However, since the old flow is dead, we will never see this BYE. We need this call to
565 // go away somehow, however we cannot just end it directly here via terminateCall.
566 // Since the flow to other party is likely fine - if we terminate this call now the BYE
567 // is very likely to make it to the far end, before the above INVITE - if this happens then
568 // the replaces logic of the INVITE will have no effect. We want to delay the release of
569 // this call, by passing our handle to the new INVITE call and have it terminate this call,
570 // once we know the far end has processed our new INVITE.
571 replacesCall->mInviteSessionHandleReplaced = mInviteSessionHandle;
572
573 SdpContents offer;
574 replacesCall->makeOffer(offer);
575 SharedPtr<SipMessage> invite = mUserAgent.getDialogUsageManager().makeInviteSession(inviteWithReplacesTarget, h, getUserProfile(), &offer, replacesCall);
576 mUserAgent.getDialogUsageManager().send(invite);
577 }
578 }
579
580 ////////////////////////////////////////////////////////////////////////////////
581 // DialogSetHandler ///////////////////////////////////////////////////
582 ////////////////////////////////////////////////////////////////////////////////
583 void
584 BasicClientCall::onTrying(AppDialogSetHandle h, const SipMessage& msg)
585 {
586 InfoLog(<< "onTrying: msg=" << msg.brief());
587 if(isUACConnected()) return; // Ignore 100's if already connected
588
589 // Handle message here
590 }
591
592 void
593 BasicClientCall::onNonDialogCreatingProvisional(AppDialogSetHandle h, const SipMessage& msg)
594 {
595 InfoLog(<< "onNonDialogCreatingProvisional: msg=" << msg.brief());
596 if(isUACConnected()) return; // Ignore provionals if already connected
597
598 // Handle message here
599 }
600
601 ////////////////////////////////////////////////////////////////////////////////
602 // ClientSubscriptionHandler ///////////////////////////////////////////////////
603 ////////////////////////////////////////////////////////////////////////////////
604 void
605 BasicClientCall::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
606 {
607 InfoLog(<< "onUpdatePending(ClientSubscriptionHandle): " << msg.brief());
608 if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer")
609 {
610 //process Refer Notify Here
611 }
612 h->acceptUpdate();
613 }
614
615 void
616 BasicClientCall::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
617 {
618 InfoLog(<< "onUpdateActive(ClientSubscriptionHandle): " << msg.brief());
619 if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer")
620 {
621 //process Refer Notify Here
622 }
623 h->acceptUpdate();
624 }
625
626 void
627 BasicClientCall::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
628 {
629 InfoLog(<< "onUpdateExtension(ClientSubscriptionHandle): " << msg.brief());
630 if (msg.exists(h_Event) && msg.header(h_Event).value() == "refer")
631 {
632 //process Refer Notify Here
633 }
634 h->acceptUpdate();
635 }
636
637 void
638 BasicClientCall::onNotifyNotReceived(resip::ClientSubscriptionHandle h)
639 {
640 InfoLog(<< "onNotifyNotReceived(ClientSubscriptionHandle)");
641 h->end();
642 }
643
644 void
645 BasicClientCall::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg)
646 {
647 if(msg)
648 {
649 InfoLog(<< "onTerminated(ClientSubscriptionHandle): " << msg->brief());
650 //Note: Final notify is sometimes only passed in the onTerminated callback
651 if (msg->isRequest() && msg->exists(h_Event) && msg->header(h_Event).value() == "refer")
652 {
653 //process Refer Notify Here
654 }
655 }
656 else
657 {
658 InfoLog(<< "onTerminated(ClientSubscriptionHandle)");
659 }
660 }
661
662 void
663 BasicClientCall::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg)
664 {
665 InfoLog(<< "onNewSubscription(ClientSubscriptionHandle): " << msg.brief());
666 }
667
668 int
669 BasicClientCall::onRequestRetry(ClientSubscriptionHandle h, int retrySeconds, const SipMessage& msg)
670 {
671 InfoLog(<< "onRequestRetry(ClientSubscriptionHandle): " << msg.brief());
672 return -1;
673 }
674
675 void
676 BasicClientCall::onRedirectReceived(AppDialogSetHandle h, const SipMessage& msg)
677 {
678 InfoLog(<< "onRedirectReceived: msg=" << msg.brief());
679 }
680
681
682 /* ====================================================================
683
684 Copyright (c) 2011, SIP Spectrum, Inc.
685 All rights reserved.
686
687 Redistribution and use in source and binary forms, with or without
688 modification, are permitted provided that the following conditions are
689 met:
690
691 1. Redistributions of source code must retain the above copyright
692 notice, this list of conditions and the following disclaimer.
693
694 2. Redistributions in binary form must reproduce the above copyright
695 notice, this list of conditions and the following disclaimer in the
696 documentation and/or other materials provided with the distribution.
697
698 3. Neither the name of SIP Spectrum nor the names of its contributors
699 may be used to endorse or promote products derived from this
700 software without specific prior written permission.
701
702 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
703 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
704 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
705 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
706 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
707 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
708 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
709 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
710 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
711 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
712 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
713
714 ==================================================================== */

Properties

Name Value
svn:eol-style native
svn:mime-type text/plain

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.26