/[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 9066 - (show annotations) (download)
Wed Mar 16 15:20:36 2011 UTC (8 years, 8 months ago) by bcampen
File MIME type: text/plain
File size: 35007 byte(s)
Fixing a few compiler warnings.

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

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