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

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