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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9022 - (show annotations) (download)
Sat Feb 19 18:27:49 2011 UTC (8 years, 9 months ago) by sgodin
Original Path: branches/b-client-outbound-20110213/resip/dum/test/basicClientUserAgent.cxx
File MIME type: text/plain
File size: 34612 byte(s)
-added another makeInviteSession interface for forming INVITE with Replaces
-basicClient now tries to perform an Invite with Replaces if a flow is terminated

1 #include <rutil/Log.hxx>
2 #include <rutil/Logger.hxx>
3 #include <rutil/DnsUtil.hxx>
4 #include <resip/stack/SdpContents.hxx>
5 #include <resip/stack/PlainContents.hxx>
6 #include <resip/stack/ConnectionTerminated.hxx>
7 #include <resip/stack/Helper.hxx>
8 #include <resip/dum/AppDialogSetFactory.hxx>
9 #include <resip/dum/ClientAuthManager.hxx>
10 #include <resip/dum/KeepAliveManager.hxx>
11 #include <resip/dum/ClientInviteSession.hxx>
12 #include <resip/dum/ServerInviteSession.hxx>
13 #include <resip/dum/ClientSubscription.hxx>
14 #include <resip/dum/ServerSubscription.hxx>
15 #include <resip/dum/ClientRegistration.hxx>
16 #include <resip/dum/ServerRegistration.hxx>
17 #include <resip/dum/ServerOutOfDialogReq.hxx>
18
19 #if defined (USE_SSL)
20 #if defined(WIN32)
21 #include "resip/stack/ssl/WinSecurity.hxx"
22 #else
23 #include "resip/stack/ssl/Security.hxx"
24 #endif
25 #endif
26
27 #include "basicClientUserAgent.hxx"
28 #include "basicClientCall.hxx"
29
30 using namespace resip;
31 using namespace std;
32
33 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST
34
35 static unsigned int MaxRegistrationRetryTime = 1800; // RFC5626 section 4.5 default
36 static unsigned int BaseRegistrationRetryTimeAllFlowsFailed = 30; // RFC5626 section 4.5 default
37 static unsigned int BaseRegistrationRetryTime = 90; // RFC5626 section 4.5 default
38 static unsigned int NotifySendTime = 30; // If someone subscribes to our test event package, then send notifies every 30 seconds
39 static unsigned int FailedSubscriptionRetryTime = 60;
40
41 namespace resip
42 {
43 class ClientAppDialogSetFactory : public AppDialogSetFactory
44 {
45 public:
46 ClientAppDialogSetFactory(BasicClientUserAgent& ua) : mUserAgent(ua) {}
47 resip::AppDialogSet* createAppDialogSet(DialogUsageManager& dum, const SipMessage& msg)
48 {
49 switch(msg.method())
50 {
51 case INVITE:
52 return new BasicClientCall(mUserAgent);
53 break;
54 default:
55 return AppDialogSetFactory::createAppDialogSet(dum, msg);
56 break;
57 }
58 }
59 private:
60 BasicClientUserAgent& mUserAgent;
61 };
62
63 // Used to set the IP Address in outbound SDP to match the IP address choosen by the stack to send the message on
64 class SdpMessageDecorator : public MessageDecorator
65 {
66 public:
67 virtual ~SdpMessageDecorator() {}
68 virtual void decorateMessage(SipMessage &msg,
69 const Tuple &source,
70 const Tuple &destination,
71 const Data& sigcompId)
72 {
73 SdpContents* sdp = dynamic_cast<SdpContents*>(msg.getContents());
74 if(sdp)
75 {
76 // Fill in IP and Port from source
77 sdp->session().connection().setAddress(Tuple::inet_ntop(source), source.ipVersion() == V6 ? SdpContents::IP6 : SdpContents::IP4);
78 sdp->session().origin().setAddress(Tuple::inet_ntop(source), source.ipVersion() == V6 ? SdpContents::IP6 : SdpContents::IP4);
79 InfoLog( << "SdpMessageDecorator: src=" << source << ", dest=" << destination << ", msg=" << endl << msg.brief());
80 }
81 }
82 virtual void rollbackMessage(SipMessage& msg) {} // Nothing to do
83 virtual MessageDecorator* clone() const { return new SdpMessageDecorator; }
84 };
85
86 class NotifyTimer : public resip::DumCommand
87 {
88 public:
89 NotifyTimer(BasicClientUserAgent& userAgent, unsigned int timerId) : mUserAgent(userAgent), mTimerId(timerId) {}
90 NotifyTimer(const NotifyTimer& rhs) : mUserAgent(rhs.mUserAgent), mTimerId(rhs.mTimerId) {}
91 ~NotifyTimer() {}
92
93 void executeCommand() { mUserAgent.onNotifyTimeout(mTimerId); }
94
95 resip::Message* clone() const { return new NotifyTimer(*this); }
96 EncodeStream& encode(EncodeStream& strm) const { strm << "NotifyTimer: id=" << mTimerId; return strm; }
97 EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
98
99 private:
100 BasicClientUserAgent& mUserAgent;
101 unsigned int mTimerId;
102 };
103 } // end namespace
104
105 BasicClientUserAgent::BasicClientUserAgent(int argc, char** argv) :
106 BasicClientCmdLineParser(argc, argv),
107 mProfile(new MasterProfile),
108 #if defined(USE_SSL)
109 mSecurity(new Security(mCertPath)),
110 #else
111 mSecurity(0),
112 #endif
113 mStack(mSecurity, DnsStub::EmptyNameserverList, &mSelectInterruptor),
114 mDum(new DialogUsageManager(mStack)),
115 mStackThread(mStack, mSelectInterruptor),
116 mDumShutdownRequested(false),
117 mDumShutdown(false),
118 mRegistrationRetryDelayTime(0),
119 mCurrentNotifyTimerId(0)
120 {
121 Log::initialize(mLogType, mLogLevel, argv[0]);
122
123 addTransport(UDP, mUdpPort);
124 addTransport(TCP, mTcpPort);
125 #if defined(USE_SSL)
126 addTransport(TLS, mTlsPort);
127 #endif
128 #if defined(USED_DTLS)
129 addTransport(DTLS, mDtlsPort);
130 #endif
131
132 // Disable Statistics Manager
133 mStack.statisticsManagerEnabled() = false;
134
135 // Supported Methods
136 mProfile->clearSupportedMethods();
137 mProfile->addSupportedMethod(INVITE);
138 mProfile->addSupportedMethod(ACK);
139 mProfile->addSupportedMethod(CANCEL);
140 mProfile->addSupportedMethod(OPTIONS);
141 mProfile->addSupportedMethod(BYE);
142 //mProfile->addSupportedMethod(REFER);
143 mProfile->addSupportedMethod(NOTIFY);
144 mProfile->addSupportedMethod(SUBSCRIBE);
145 //mProfile->addSupportedMethod(UPDATE);
146 mProfile->addSupportedMethod(INFO);
147 mProfile->addSupportedMethod(MESSAGE);
148 //mProfile->addSupportedMethod(PRACK);
149 //mProfile->addSupportedOptionTag(Token(Symbols::C100rel)); // Automatically added when using setUacReliableProvisionalMode
150 mProfile->setUacReliableProvisionalMode(MasterProfile::Supported);
151 //mProfile->setUasReliableProvisionalMode(MasterProfile::Supported); // TODO - needs support in DUM, currently unimplemented
152
153 // Support Languages
154 mProfile->clearSupportedLanguages();
155 mProfile->addSupportedLanguage(Token("en"));
156
157 // Support Mime Types
158 mProfile->clearSupportedMimeTypes();
159 mProfile->addSupportedMimeType(INVITE, Mime("application", "sdp"));
160 mProfile->addSupportedMimeType(INVITE, Mime("multipart", "mixed"));
161 mProfile->addSupportedMimeType(INVITE, Mime("multipart", "signed"));
162 mProfile->addSupportedMimeType(INVITE, Mime("multipart", "alternative"));
163 mProfile->addSupportedMimeType(OPTIONS,Mime("application", "sdp"));
164 mProfile->addSupportedMimeType(OPTIONS,Mime("multipart", "mixed"));
165 mProfile->addSupportedMimeType(OPTIONS, Mime("multipart", "signed"));
166 mProfile->addSupportedMimeType(OPTIONS, Mime("multipart", "alternative"));
167 mProfile->addSupportedMimeType(PRACK, Mime("application", "sdp"));
168 mProfile->addSupportedMimeType(PRACK, Mime("multipart", "mixed"));
169 mProfile->addSupportedMimeType(PRACK, Mime("multipart", "signed"));
170 mProfile->addSupportedMimeType(PRACK, Mime("multipart", "alternative"));
171 mProfile->addSupportedMimeType(UPDATE, Mime("application", "sdp"));
172 mProfile->addSupportedMimeType(UPDATE, Mime("multipart", "mixed"));
173 mProfile->addSupportedMimeType(UPDATE, Mime("multipart", "signed"));
174 mProfile->addSupportedMimeType(UPDATE, Mime("multipart", "alternative"));
175 mProfile->addSupportedMimeType(MESSAGE, Mime("text","plain")); // Invite session in-dialog routing testing
176 mProfile->addSupportedMimeType(NOTIFY, Mime("text","plain")); // subscription testing
177 //mProfile->addSupportedMimeType(NOTIFY, Mime("message", "sipfrag"));
178
179 // Supported Options Tags
180 mProfile->clearSupportedOptionTags();
181 //mMasterProfile->addSupportedOptionTag(Token(Symbols::Replaces));
182 mProfile->addSupportedOptionTag(Token(Symbols::Timer)); // Enable Session Timers
183 if(mOutboundEnabled)
184 {
185 mProfile->addSupportedOptionTag(Token(Symbols::Outbound)); // RFC 5626 - outbound
186 mProfile->addSupportedOptionTag(Token(Symbols::Path)); // RFC 3327 - path
187 }
188 //mMasterProfile->addSupportedOptionTag(Token(Symbols::NoReferSub));
189 //mMasterProfile->addSupportedOptionTag(Token(Symbols::TargetDialog));
190
191 // Supported Schemes
192 mProfile->clearSupportedSchemes();
193 mProfile->addSupportedScheme("sip");
194 #if defined(USE_SSL)
195 mProfile->addSupportedScheme("sips");
196 #endif
197
198 // Validation Settings
199 mProfile->validateContentEnabled() = false;
200 mProfile->validateContentLanguageEnabled() = false;
201 mProfile->validateAcceptEnabled() = false;
202
203 // Have stack add Allow/Supported/Accept headers to INVITE dialog establishment messages
204 mProfile->clearAdvertisedCapabilities(); // Remove Profile Defaults, then add our preferences
205 mProfile->addAdvertisedCapability(Headers::Allow);
206 //mProfile->addAdvertisedCapability(Headers::AcceptEncoding); // This can be misleading - it might specify what is expected in response
207 mProfile->addAdvertisedCapability(Headers::AcceptLanguage);
208 mProfile->addAdvertisedCapability(Headers::Supported);
209 mProfile->setMethodsParamEnabled(true);
210
211 // Install Sdp Message Decorator
212 SharedPtr<MessageDecorator> outboundDecorator(new SdpMessageDecorator);
213 mProfile->setOutboundDecorator(outboundDecorator);
214
215 // Other Profile Settings
216 mProfile->setUserAgent("basicClient/1.0");
217 mProfile->setDefaultRegistrationTime(mRegisterDuration);
218 mProfile->setDefaultRegistrationRetryTime(120);
219 if(!mContact.host().empty())
220 {
221 mProfile->setOverrideHostAndPort(mContact);
222 }
223 if(!mOutboundProxy.host().empty())
224 {
225 mProfile->setOutboundProxy(Uri(mOutboundProxy));
226 //mProfile->setForceOutboundProxyOnAllRequestsEnabled(true);
227 mProfile->setExpressOutboundAsRouteSetEnabled(true);
228 }
229
230 // UserProfile Settings
231 mProfile->setDefaultFrom(NameAddr(mAor));
232 mProfile->setDigestCredential(mAor.host(), mAor.user(), mPassword);
233 // Generate InstanceId appropriate for testing only. Should be UUID that persists
234 // across machine re-starts and is unique to this applicaiton instance. The one used
235 // here is only as unique as the hostname of this machine. If someone runs two
236 // instances of this application on the same host for the same Aor, then things will
237 // break. See RFC5626 section 4.1
238 Data hostname = DnsUtil::getLocalHostName();
239 Data instanceHash = hostname.md5().uppercase();
240 assert(instanceHash.size() == 32);
241 Data instanceId(48, Data::Preallocate);
242 instanceId += "<urn:uuid:";
243 instanceId += instanceHash.substr(0, 8);
244 instanceId += "-";
245 instanceId += instanceHash.substr(8, 4);
246 instanceId += "-";
247 instanceId += instanceHash.substr(12, 4);
248 instanceId += "-";
249 instanceId += instanceHash.substr(16, 4);
250 instanceId += "-";
251 instanceId += instanceHash.substr(20, 12);
252 instanceId += ">";
253 mProfile->setInstanceId(instanceId);
254 if(mOutboundEnabled)
255 {
256 mProfile->setRegId(1);
257 mProfile->clientOutboundEnabled() = true;
258 }
259
260 // Install Managers
261 mDum->setClientAuthManager(std::auto_ptr<ClientAuthManager>(new ClientAuthManager));
262 mDum->setKeepAliveManager(std::auto_ptr<KeepAliveManager>(new KeepAliveManager));
263 mProfile->setKeepAliveTimeForDatagram(30);
264 //mProfile->setKeepAliveTimeForStream(120);
265 mProfile->setKeepAliveTimeForStream(30); // !slg! TODO - testing only
266
267 // Install Handlers
268 mDum->setInviteSessionHandler(this);
269 mDum->setDialogSetHandler(this);
270 mDum->addOutOfDialogHandler(OPTIONS, this);
271 //mDum->addOutOfDialogHandler(REFER, this);
272 mDum->setRedirectHandler(this);
273 mDum->setClientRegistrationHandler(this);
274 mDum->addClientSubscriptionHandler("basicClientTest", this); // fabricated test event package
275 mDum->addServerSubscriptionHandler("basicClientTest", this);
276
277 // Set AppDialogSetFactory
278 auto_ptr<AppDialogSetFactory> dsf(new ClientAppDialogSetFactory(*this));
279 mDum->setAppDialogSetFactory(dsf);
280
281 mDum->setMasterProfile(mProfile);
282
283 mDum->registerForConnectionTermination(this);
284 }
285
286 BasicClientUserAgent::~BasicClientUserAgent()
287 {
288 mStackThread.shutdown();
289 mStackThread.join();
290
291 delete mDum;
292 }
293
294 void
295 BasicClientUserAgent::startup()
296 {
297 mStackThread.run();
298
299 if (mRegisterDuration)
300 {
301 InfoLog (<< "register for " << mAor);
302 mDum->send(mDum->makeRegistration(NameAddr(mAor)));
303 }
304 }
305
306 void
307 BasicClientUserAgent::shutdown()
308 {
309 assert(mDum);
310 mDumShutdownRequested = true; // Set flag so that shutdown operations can be run in dum process thread
311 }
312
313 bool
314 BasicClientUserAgent::process(int timeoutMs)
315 {
316 if(!mDumShutdown)
317 {
318 if(mDumShutdownRequested)
319 {
320 // unregister
321 if(mRegHandle.isValid())
322 {
323 mRegHandle->end();
324 }
325
326 // end any subscriptions
327 if(mServerSubscriptionHandle.isValid())
328 {
329 mServerSubscriptionHandle->end();
330 }
331 if(mClientSubscriptionHandle.isValid())
332 {
333 mClientSubscriptionHandle->end();
334 }
335
336 // End all calls - copy list in case delete/unregister of call is immediate
337 std::set<BasicClientCall*> tempCallList = mCallList;
338 std::set<BasicClientCall*>::iterator it = tempCallList.begin();
339 for(; it != tempCallList.end(); it++)
340 {
341 (*it)->terminateCall();
342 }
343
344 mDum->shutdown(this);
345 mDumShutdownRequested = false;
346 }
347 mDum->process(timeoutMs);
348 return true;
349 }
350 return false;
351 }
352
353 void
354 BasicClientUserAgent::addTransport(TransportType type, int port)
355 {
356 if(port == 0) return; // Transport disabled
357
358 for (; port < port+10; ++port)
359 {
360 try
361 {
362 if (!mNoV4)
363 {
364 mStack.addTransport(type, port, V4, StunEnabled, Data::Empty, mTlsDomain);
365 return;
366 }
367
368 if (mEnableV6)
369 {
370 mStack.addTransport(type, port, V6, StunEnabled, Data::Empty, mTlsDomain);
371 return;
372 }
373 }
374 catch (BaseException& e)
375 {
376 InfoLog (<< "Caught: " << e);
377 WarningLog (<< "Failed to add " << Tuple::toData(type) << " transport on " << port);
378 }
379 }
380 throw Transport::Exception("Port already in use", __FILE__, __LINE__);
381 }
382
383 void
384 BasicClientUserAgent::post(Message* msg)
385 {
386 ConnectionTerminated* terminated = dynamic_cast<ConnectionTerminated*>(msg);
387 if (terminated)
388 {
389 InfoLog(<< "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% BasicClientUserAgent received connection terminated message for: " << terminated->getFlow()); // !slg! TODO - remove strange log markers
390 delete msg;
391 return;
392 }
393 assert(false);
394 }
395
396 void
397 BasicClientUserAgent::onNotifyTimeout(unsigned int timerId)
398 {
399 if(timerId == mCurrentNotifyTimerId)
400 {
401 sendNotify();
402 }
403 }
404
405 void
406 BasicClientUserAgent::sendNotify()
407 {
408 if(mServerSubscriptionHandle.isValid())
409 {
410 PlainContents plain("test notify");
411 mServerSubscriptionHandle->send(mServerSubscriptionHandle->update(&plain));
412
413 // start timer for next one
414 auto_ptr<ApplicationMessage> timer(new NotifyTimer(*this, ++mCurrentNotifyTimerId));
415 mStack.post(timer, NotifySendTime, mDum);
416 }
417 }
418
419 void
420 BasicClientUserAgent::onCallTimeout(BasicClientCall* call)
421 {
422 if(isValidCall(call))
423 {
424 call->timerExpired();
425 }
426 else // call no longer exists
427 {
428 if(!mCallTarget.host().empty())
429 {
430 // re-start a new call
431 BasicClientCall* newCall = new BasicClientCall(*this);
432 newCall->initiateCall(mCallTarget, mProfile);
433 }
434 }
435 }
436
437 void
438 BasicClientUserAgent::registerCall(BasicClientCall* call)
439 {
440 mCallList.insert(call);
441 }
442
443 void
444 BasicClientUserAgent::unregisterCall(BasicClientCall* call)
445 {
446 std::set<BasicClientCall*>::iterator it = mCallList.find(call);
447 if(it != mCallList.end())
448 {
449 mCallList.erase(it);
450 }
451 }
452
453 bool
454 BasicClientUserAgent::isValidCall(BasicClientCall* call)
455 {
456 std::set<BasicClientCall*>::iterator it = mCallList.find(call);
457 if(it != mCallList.end())
458 {
459 return true;
460 }
461 return false;
462 }
463
464 void
465 BasicClientUserAgent::onDumCanBeDeleted()
466 {
467 mDumShutdown = true;
468 }
469
470 ////////////////////////////////////////////////////////////////////////////////
471 // Registration Handler ////////////////////////////////////////////////////////
472 ////////////////////////////////////////////////////////////////////////////////
473 void
474 BasicClientUserAgent::onSuccess(ClientRegistrationHandle h, const SipMessage& msg)
475 {
476 InfoLog(<< "onSuccess(ClientRegistrationHandle): msg=" << msg.brief());
477 if(mRegHandle.getId() == 0) // Note: reg handle id will only be 0 on first successful registration
478 {
479 // Check if we should try to form a test subscription
480 if(!mSubscribeTarget.host().empty())
481 {
482 SharedPtr<SipMessage> sub = mDum->makeSubscription(NameAddr(mSubscribeTarget), mProfile, "basicClientTest");
483 mDum->send(sub);
484 }
485
486 // Check if we should try to form a test call
487 if(!mCallTarget.host().empty())
488 {
489 BasicClientCall* newCall = new BasicClientCall(*this);
490 newCall->initiateCall(mCallTarget, mProfile);
491 }
492 }
493 mRegHandle = h;
494 mRegistrationRetryDelayTime = 0; // reset
495 }
496
497 void
498 BasicClientUserAgent::onFailure(ClientRegistrationHandle h, const SipMessage& msg)
499 {
500 InfoLog(<< "onFailure(ClientRegistrationHandle): msg=" << msg.brief());
501 mRegHandle = h;
502 }
503
504 void
505 BasicClientUserAgent::onRemoved(ClientRegistrationHandle h, const SipMessage&msg)
506 {
507 InfoLog(<< "onRemoved(ClientRegistrationHandle): msg=" << msg.brief());
508 mRegHandle = h;
509 }
510
511 int
512 BasicClientUserAgent::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg)
513 {
514 mRegHandle = h;
515
516 if(mRegistrationRetryDelayTime == 0)
517 {
518 mRegistrationRetryDelayTime = BaseRegistrationRetryTimeAllFlowsFailed; // We only have one flow in this test app
519 }
520
521 // Use back off procedures of RFC 5626 section 4.5
522 mRegistrationRetryDelayTime = resipMin(MaxRegistrationRetryTime, mRegistrationRetryDelayTime * 2);
523
524 // return an evenly distributed random number between 50% and 100% of mRegistrationRetryDelayTime
525 int retryTime = Helper::jitterValue(mRegistrationRetryDelayTime, 50, 100);
526 InfoLog(<< "onRequestRetry(ClientRegistrationHandle): msg=" << msg.brief() << ", retryTime=" << retryTime);
527
528 return retryTime;
529 }
530
531
532 ////////////////////////////////////////////////////////////////////////////////
533 // InviteSessionHandler ////////////////////////////////////////////////////////
534 ////////////////////////////////////////////////////////////////////////////////
535 void
536 BasicClientUserAgent::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
537 {
538 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onNewSession(h, oat, msg);
539 }
540
541 void
542 BasicClientUserAgent::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
543 {
544 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onNewSession(h, oat, msg);
545 }
546
547 void
548 BasicClientUserAgent::onFailure(ClientInviteSessionHandle h, const SipMessage& msg)
549 {
550 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onFailure(h, msg);
551 }
552
553 void
554 BasicClientUserAgent::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
555 {
556 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onEarlyMedia(h, msg, sdp);
557 }
558
559 void
560 BasicClientUserAgent::onProvisional(ClientInviteSessionHandle h, const SipMessage& msg)
561 {
562 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onProvisional(h, msg);
563 }
564
565 void
566 BasicClientUserAgent::onConnected(ClientInviteSessionHandle h, const SipMessage& msg)
567 {
568 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onConnected(h, msg);
569 }
570
571 void
572 BasicClientUserAgent::onConnected(InviteSessionHandle h, const SipMessage& msg)
573 {
574 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onConnected(h, msg);
575 }
576
577 void
578 BasicClientUserAgent::onStaleCallTimeout(ClientInviteSessionHandle h)
579 {
580 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onStaleCallTimeout(h);
581 }
582
583 void
584 BasicClientUserAgent::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
585 {
586 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onTerminated(h, reason, msg);
587 }
588
589 void
590 BasicClientUserAgent::onRedirected(ClientInviteSessionHandle h, const SipMessage& msg)
591 {
592 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRedirected(h, msg);
593 }
594
595 void
596 BasicClientUserAgent::onAnswer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
597 {
598 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onAnswer(h, msg, sdp);
599 }
600
601 void
602 BasicClientUserAgent::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
603 {
604 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOffer(h, msg, sdp);
605 }
606
607 void
608 BasicClientUserAgent::onOfferRequired(InviteSessionHandle h, const SipMessage& msg)
609 {
610 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRequired(h, msg);
611 }
612
613 void
614 BasicClientUserAgent::onOfferRejected(InviteSessionHandle h, const SipMessage* msg)
615 {
616 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRejected(h, msg);
617 }
618
619 void
620 BasicClientUserAgent::onOfferRequestRejected(InviteSessionHandle h, const SipMessage& msg)
621 {
622 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRequestRejected(h, msg);
623 }
624
625 void
626 BasicClientUserAgent::onRemoteSdpChanged(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
627 {
628 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRemoteSdpChanged(h, msg, sdp);
629 }
630
631 void
632 BasicClientUserAgent::onInfo(InviteSessionHandle h, const SipMessage& msg)
633 {
634 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfo(h, msg);
635 }
636
637 void
638 BasicClientUserAgent::onInfoSuccess(InviteSessionHandle h, const SipMessage& msg)
639 {
640 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfoSuccess(h, msg);
641 }
642
643 void
644 BasicClientUserAgent::onInfoFailure(InviteSessionHandle h, const SipMessage& msg)
645 {
646 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfoFailure(h, msg);
647 }
648
649 void
650 BasicClientUserAgent::onRefer(InviteSessionHandle h, ServerSubscriptionHandle ssh, const SipMessage& msg)
651 {
652 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRefer(h, ssh, msg);
653 }
654
655 void
656 BasicClientUserAgent::onReferAccepted(InviteSessionHandle h, ClientSubscriptionHandle csh, const SipMessage& msg)
657 {
658 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferAccepted(h, csh, msg);
659 }
660
661 void
662 BasicClientUserAgent::onReferRejected(InviteSessionHandle h, const SipMessage& msg)
663 {
664 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferRejected(h, msg);
665 }
666
667 void
668 BasicClientUserAgent::onReferNoSub(InviteSessionHandle h, const SipMessage& msg)
669 {
670 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferNoSub(h, msg);
671 }
672
673 void
674 BasicClientUserAgent::onMessage(InviteSessionHandle h, const SipMessage& msg)
675 {
676 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessage(h, msg);
677 }
678
679 void
680 BasicClientUserAgent::onMessageSuccess(InviteSessionHandle h, const SipMessage& msg)
681 {
682 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessageSuccess(h, msg);
683 }
684
685 void
686 BasicClientUserAgent::onMessageFailure(InviteSessionHandle h, const SipMessage& msg)
687 {
688 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessageFailure(h, msg);
689 }
690
691 void
692 BasicClientUserAgent::onForkDestroyed(ClientInviteSessionHandle h)
693 {
694 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onForkDestroyed(h);
695 }
696
697 void
698 BasicClientUserAgent::onReadyToSend(InviteSessionHandle h, SipMessage& msg)
699 {
700 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReadyToSend(h, msg);
701 }
702
703 void
704 BasicClientUserAgent::onFlowTerminated(InviteSessionHandle h)
705 {
706 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onFlowTerminated(h);
707 }
708
709
710 ////////////////////////////////////////////////////////////////////////////////
711 // DialogSetHandler ///////////////////////////////////////////////////
712 ////////////////////////////////////////////////////////////////////////////////
713 void
714 BasicClientUserAgent::onTrying(AppDialogSetHandle h, const SipMessage& msg)
715 {
716 BasicClientCall *call = dynamic_cast<BasicClientCall *>(h.get());
717 if(call)
718 {
719 call->onTrying(h, msg);
720 }
721 else
722 {
723 InfoLog(<< "onTrying(AppDialogSetHandle): " << msg.brief());
724 }
725 }
726
727 void
728 BasicClientUserAgent::onNonDialogCreatingProvisional(AppDialogSetHandle h, const SipMessage& msg)
729 {
730 BasicClientCall *call = dynamic_cast<BasicClientCall *>(h.get());
731 if(call)
732 {
733 call->onNonDialogCreatingProvisional(h, msg);
734 }
735 else
736 {
737 InfoLog(<< "onNonDialogCreatingProvisional(AppDialogSetHandle): " << msg.brief());
738 }
739 }
740
741 ////////////////////////////////////////////////////////////////////////////////
742 // ClientSubscriptionHandler ///////////////////////////////////////////////////
743 ////////////////////////////////////////////////////////////////////////////////
744 void
745 BasicClientUserAgent::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
746 {
747 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
748 if(call)
749 {
750 call->onUpdatePending(h, msg, outOfOrder);
751 return;
752 }
753 InfoLog(<< "onUpdatePending(ClientSubscriptionHandle): " << msg.brief());
754 h->acceptUpdate();
755 }
756
757 void
758 BasicClientUserAgent::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
759 {
760 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
761 if(call)
762 {
763 call->onUpdateActive(h, msg, outOfOrder);
764 return;
765 }
766 InfoLog(<< "onUpdateActive(ClientSubscriptionHandle): " << msg.brief());
767 h->acceptUpdate();
768 }
769
770 void
771 BasicClientUserAgent::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
772 {
773 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
774 if(call)
775 {
776 call->onUpdateExtension(h, msg, outOfOrder);
777 return;
778 }
779 InfoLog(<< "onUpdateExtension(ClientSubscriptionHandle): " << msg.brief());
780 h->acceptUpdate();
781 }
782
783 void
784 BasicClientUserAgent::onNotifyNotReceived(ClientSubscriptionHandle h)
785 {
786 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
787 if(call)
788 {
789 call->onNotifyNotReceived(h);
790 return;
791 }
792 WarningLog(<< "onNotifyNotReceived(ClientSubscriptionHandle)");
793 h->end();
794 }
795
796 void
797 BasicClientUserAgent::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg)
798 {
799 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
800 if(call)
801 {
802 call->onTerminated(h, msg);
803 return;
804 }
805 if(msg)
806 {
807 InfoLog(<< "onTerminated(ClientSubscriptionHandle): msg=" << msg->brief());
808 }
809 else
810 {
811 InfoLog(<< "onTerminated(ClientSubscriptionHandle)");
812 }
813 }
814
815 void
816 BasicClientUserAgent::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg)
817 {
818 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
819 if(call)
820 {
821 call->onNewSubscription(h, msg);
822 return;
823 }
824 mClientSubscriptionHandle = h;
825 InfoLog(<< "onNewSubscription(ClientSubscriptionHandle): msg=" << msg.brief());
826 }
827
828 int
829 BasicClientUserAgent::onRequestRetry(ClientSubscriptionHandle h, int retrySeconds, const SipMessage& msg)
830 {
831 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
832 if(call)
833 {
834 return call->onRequestRetry(h, retrySeconds, msg);
835 }
836 InfoLog(<< "onRequestRetry(ClientSubscriptionHandle): msg=" << msg.brief());
837 return FailedSubscriptionRetryTime;
838 }
839
840 ////////////////////////////////////////////////////////////////////////////////
841 // ServerSubscriptionHandler ///////////////////////////////////////////////////
842 ////////////////////////////////////////////////////////////////////////////////
843 void
844 BasicClientUserAgent::onNewSubscription(ServerSubscriptionHandle h, const SipMessage& msg)
845 {
846 InfoLog(<< "onNewSubscription(ServerSubscriptionHandle): " << msg.brief());
847
848 mServerSubscriptionHandle = h;
849 mServerSubscriptionHandle->setSubscriptionState(Active);
850 mServerSubscriptionHandle->send(mServerSubscriptionHandle->accept());
851
852 sendNotify();
853 }
854
855 void
856 BasicClientUserAgent::onNewSubscriptionFromRefer(ServerSubscriptionHandle ss, const SipMessage& msg)
857 {
858 InfoLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): " << msg.brief());
859 // Received an out-of-dialog refer request with implicit subscription
860 try
861 {
862 if(msg.exists(h_ReferTo))
863 {
864 // Check if TargetDialog header is present
865 if(msg.exists(h_TargetDialog))
866 {
867 pair<InviteSessionHandle, int> presult;
868 presult = mDum->findInviteSession(msg.header(h_TargetDialog));
869 if(!(presult.first == InviteSessionHandle::NotValid()))
870 {
871 BasicClientCall* callToRefer = (BasicClientCall*)presult.first->getAppDialogSet().get();
872
873 callToRefer->onRefer(presult.first, ss, msg);
874 return;
875 }
876 }
877
878 // We don't support ood refers that don't target a dialog - reject request
879 WarningLog (<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): Received ood refer (noSub) w/out a Target-Dialog: " << msg.brief());
880 ss->send(ss->reject(400));
881 }
882 else
883 {
884 WarningLog (<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): Received refer w/out a Refer-To: " << msg.brief());
885 ss->send(ss->reject(400));
886 }
887 }
888 catch(BaseException &e)
889 {
890 WarningLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): exception " << e);
891 }
892 catch(...)
893 {
894 WarningLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): unknown exception");
895 }
896 }
897
898 void
899 BasicClientUserAgent::onRefresh(ServerSubscriptionHandle, const SipMessage& msg)
900 {
901 InfoLog(<< "onRefresh(ServerSubscriptionHandle): " << msg.brief());
902 }
903
904 void
905 BasicClientUserAgent::onTerminated(ServerSubscriptionHandle)
906 {
907 InfoLog(<< "onTerminated(ServerSubscriptionHandle)");
908 }
909
910 void
911 BasicClientUserAgent::onReadyToSend(ServerSubscriptionHandle, SipMessage&)
912 {
913 }
914
915 void
916 BasicClientUserAgent::onNotifyRejected(ServerSubscriptionHandle, const SipMessage& msg)
917 {
918 WarningLog(<< "onNotifyRejected(ServerSubscriptionHandle): " << msg.brief());
919 }
920
921 void
922 BasicClientUserAgent::onError(ServerSubscriptionHandle, const SipMessage& msg)
923 {
924 WarningLog(<< "onError(ServerSubscriptionHandle): " << msg.brief());
925 }
926
927 void
928 BasicClientUserAgent::onExpiredByClient(ServerSubscriptionHandle, const SipMessage& sub, SipMessage& notify)
929 {
930 InfoLog(<< "onExpiredByClient(ServerSubscriptionHandle): " << notify.brief());
931 }
932
933 void
934 BasicClientUserAgent::onExpired(ServerSubscriptionHandle, SipMessage& msg)
935 {
936 InfoLog(<< "onExpired(ServerSubscriptionHandle): " << msg.brief());
937 }
938
939 bool
940 BasicClientUserAgent::hasDefaultExpires() const
941 {
942 return true;
943 }
944
945 UInt32
946 BasicClientUserAgent::getDefaultExpires() const
947 {
948 return 60;
949 }
950
951 ////////////////////////////////////////////////////////////////////////////////
952 // OutOfDialogHandler //////////////////////////////////////////////////////////
953 ////////////////////////////////////////////////////////////////////////////////
954 void
955 BasicClientUserAgent::onSuccess(ClientOutOfDialogReqHandle, const SipMessage& msg)
956 {
957 InfoLog(<< "onSuccess(ClientOutOfDialogReqHandle): " << msg.brief());
958 }
959
960 void
961 BasicClientUserAgent::onFailure(ClientOutOfDialogReqHandle h, const SipMessage& msg)
962 {
963 WarningLog(<< "onFailure(ClientOutOfDialogReqHandle): " << msg.brief());
964 }
965
966 void
967 BasicClientUserAgent::onReceivedRequest(ServerOutOfDialogReqHandle ood, const SipMessage& msg)
968 {
969 InfoLog(<< "onReceivedRequest(ServerOutOfDialogReqHandle): " << msg.brief());
970
971 switch(msg.method())
972 {
973 case OPTIONS:
974 {
975 SharedPtr<SipMessage> optionsAnswer = ood->answerOptions();
976 ood->send(optionsAnswer);
977 break;
978 }
979 default:
980 ood->send(ood->reject(501 /* Not Implemented*/));
981 break;
982 }
983 }
984
985 ////////////////////////////////////////////////////////////////////////////////
986 // RedirectHandler /////////////////////////////////////////////////////////////
987 ////////////////////////////////////////////////////////////////////////////////
988 void
989 BasicClientUserAgent::onRedirectReceived(AppDialogSetHandle h, const SipMessage& msg)
990 {
991 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h.get());
992 if(call)
993 {
994 call->onRedirectReceived(h, msg);
995 }
996 else
997 {
998 InfoLog(<< "onRedirectReceived(AppDialogSetHandle): " << msg.brief());
999 }
1000 }
1001
1002 bool
1003 BasicClientUserAgent::onTryingNextTarget(AppDialogSetHandle, const SipMessage& msg)
1004 {
1005 InfoLog(<< "onTryingNextTarget(AppDialogSetHandle): " << msg.brief());
1006
1007 // Always allow redirection for now
1008 return true;
1009 }
1010
1011
1012
1013
1014 /* ====================================================================
1015
1016 Copyright (c) 2011, SIP Spectrum, Inc.
1017 All rights reserved.
1018
1019 Redistribution and use in source and binary forms, with or without
1020 modification, are permitted provided that the following conditions are
1021 met:
1022
1023 1. Redistributions of source code must retain the above copyright
1024 notice, this list of conditions and the following disclaimer.
1025
1026 2. Redistributions in binary form must reproduce the above copyright
1027 notice, this list of conditions and the following disclaimer in the
1028 documentation and/or other materials provided with the distribution.
1029
1030 3. Neither the name of SIP Spectrum nor the names of its contributors
1031 may be used to endorse or promote products derived from this
1032 software without specific prior written permission.
1033
1034 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1035 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1036 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1037 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1038 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1039 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1040 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1041 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1042 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1043 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1044 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1045
1046 ==================================================================== */
1047

Properties

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

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27