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

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