/[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 9024 - (show annotations) (download)
Sat Feb 19 20:00:06 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: 34691 byte(s)
-basicClient changes in order to accept an inbound Invite with Replaces

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

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