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

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