/[resiprocate]/branches/b-client-outbound-20110213/resip/dum/test/basicClientUserAgent.cxx
ViewVC logotype

Contents of /branches/b-client-outbound-20110213/resip/dum/test/basicClientUserAgent.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9021 - (show annotations) (download)
Sat Feb 19 17:54:39 2011 UTC (8 years, 11 months ago) by sgodin
File MIME type: text/plain
File size: 34454 byte(s)
-modified basicClient
 - track all calls created and end properly when shutdown
 - added new command line parameter to be able to place a call after registration
 - Once call is placed, five test MESSAGEs will be sent every 30 seconds, then a BYE will be sent
 - 30 seconds later the entire process is repeated
 - if we receive a call then it will be auto-answered, and for any received call, if we receive a
   sip MESSAGE, then a answer MESSAGE will be sent to the far end - this allows mid-dialog routing
   testing in both directions
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(!mCallTarget.host().empty())
429 {
430 // re-start a new call
431 BasicClientCall* newCall = new BasicClientCall(*this);
432 newCall->initiateCall(mCallTarget, mProfile);
433 }
434 }
435 }
436
437 void
438 BasicClientUserAgent::registerCall(BasicClientCall* call)
439 {
440 mCallList.insert(call);
441 }
442
443 void
444 BasicClientUserAgent::unregisterCall(BasicClientCall* call)
445 {
446 std::set<BasicClientCall*>::iterator it = mCallList.find(call);
447 if(it != mCallList.end())
448 {
449 mCallList.erase(it);
450 }
451 }
452
453 bool
454 BasicClientUserAgent::isValidCall(BasicClientCall* call)
455 {
456 std::set<BasicClientCall*>::iterator it = mCallList.find(call);
457 if(it != mCallList.end())
458 {
459 return true;
460 }
461 return false;
462 }
463
464 void
465 BasicClientUserAgent::onDumCanBeDeleted()
466 {
467 mDumShutdown = true;
468 }
469
470 ////////////////////////////////////////////////////////////////////////////////
471 // Registration Handler ////////////////////////////////////////////////////////
472 ////////////////////////////////////////////////////////////////////////////////
473 void
474 BasicClientUserAgent::onSuccess(ClientRegistrationHandle h, const SipMessage& msg)
475 {
476 InfoLog(<< "onSuccess(ClientRegistrationHandle): msg=" << msg.brief());
477 if(mRegHandle.getId() == 0) // Note: reg handle id will only be 0 on first successful registration
478 {
479 // Check if we should try to form a test subscription
480 if(!mSubscribeTarget.host().empty())
481 {
482 SharedPtr<SipMessage> sub = mDum->makeSubscription(NameAddr(mSubscribeTarget), mProfile, "basicClientTest");
483 mDum->send(sub);
484 }
485
486 // Check if we should try to form a test call
487 if(!mCallTarget.host().empty())
488 {
489 BasicClientCall* newCall = new BasicClientCall(*this);
490 newCall->initiateCall(mCallTarget, mProfile);
491 }
492 }
493 mRegHandle = h;
494 mRegistrationRetryDelayTime = 0; // reset
495 }
496
497 void
498 BasicClientUserAgent::onFailure(ClientRegistrationHandle h, const SipMessage& msg)
499 {
500 InfoLog(<< "onFailure(ClientRegistrationHandle): msg=" << msg.brief());
501 mRegHandle = h;
502 }
503
504 void
505 BasicClientUserAgent::onRemoved(ClientRegistrationHandle h, const SipMessage&msg)
506 {
507 InfoLog(<< "onRemoved(ClientRegistrationHandle): msg=" << msg.brief());
508 mRegHandle = h;
509 }
510
511 int
512 BasicClientUserAgent::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg)
513 {
514 mRegHandle = h;
515
516 if(mRegistrationRetryDelayTime == 0)
517 {
518 mRegistrationRetryDelayTime = BaseRegistrationRetryTimeAllFlowsFailed; // We only have one flow in this test app
519 }
520
521 // Use back off procedures of RFC 5626 section 4.5
522 mRegistrationRetryDelayTime = resipMin(MaxRegistrationRetryTime, mRegistrationRetryDelayTime * 2);
523
524 // return an evenly distributed random number between 50% and 100% of mRegistrationRetryDelayTime
525 int retryTime = Helper::jitterValue(mRegistrationRetryDelayTime, 50, 100);
526 InfoLog(<< "onRequestRetry(ClientRegistrationHandle): msg=" << msg.brief() << ", retryTime=" << retryTime);
527
528 return retryTime;
529 }
530
531
532 ////////////////////////////////////////////////////////////////////////////////
533 // InviteSessionHandler ////////////////////////////////////////////////////////
534 ////////////////////////////////////////////////////////////////////////////////
535 void
536 BasicClientUserAgent::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
537 {
538 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onNewSession(h, oat, msg);
539 }
540
541 void
542 BasicClientUserAgent::onNewSession(ServerInviteSessionHandle 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::onFailure(ClientInviteSessionHandle h, const SipMessage& msg)
549 {
550 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onFailure(h, msg);
551 }
552
553 void
554 BasicClientUserAgent::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
555 {
556 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onEarlyMedia(h, msg, sdp);
557 }
558
559 void
560 BasicClientUserAgent::onProvisional(ClientInviteSessionHandle h, const SipMessage& msg)
561 {
562 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onProvisional(h, msg);
563 }
564
565 void
566 BasicClientUserAgent::onConnected(ClientInviteSessionHandle h, const SipMessage& msg)
567 {
568 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onConnected(h, msg);
569 }
570
571 void
572 BasicClientUserAgent::onConnected(InviteSessionHandle h, const SipMessage& msg)
573 {
574 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onConnected(h, msg);
575 }
576
577 void
578 BasicClientUserAgent::onStaleCallTimeout(ClientInviteSessionHandle h)
579 {
580 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onStaleCallTimeout(h);
581 }
582
583 void
584 BasicClientUserAgent::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
585 {
586 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onTerminated(h, reason, msg);
587 }
588
589 void
590 BasicClientUserAgent::onRedirected(ClientInviteSessionHandle h, const SipMessage& msg)
591 {
592 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRedirected(h, msg);
593 }
594
595 void
596 BasicClientUserAgent::onAnswer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
597 {
598 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onAnswer(h, msg, sdp);
599 }
600
601 void
602 BasicClientUserAgent::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
603 {
604 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOffer(h, msg, sdp);
605 }
606
607 void
608 BasicClientUserAgent::onOfferRequired(InviteSessionHandle h, const SipMessage& msg)
609 {
610 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRequired(h, msg);
611 }
612
613 void
614 BasicClientUserAgent::onOfferRejected(InviteSessionHandle h, const SipMessage* msg)
615 {
616 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRejected(h, msg);
617 }
618
619 void
620 BasicClientUserAgent::onOfferRequestRejected(InviteSessionHandle h, const SipMessage& msg)
621 {
622 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onOfferRequestRejected(h, msg);
623 }
624
625 void
626 BasicClientUserAgent::onRemoteSdpChanged(InviteSessionHandle h, const SipMessage& msg, const SdpContents& sdp)
627 {
628 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRemoteSdpChanged(h, msg, sdp);
629 }
630
631 void
632 BasicClientUserAgent::onInfo(InviteSessionHandle h, const SipMessage& msg)
633 {
634 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfo(h, msg);
635 }
636
637 void
638 BasicClientUserAgent::onInfoSuccess(InviteSessionHandle h, const SipMessage& msg)
639 {
640 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfoSuccess(h, msg);
641 }
642
643 void
644 BasicClientUserAgent::onInfoFailure(InviteSessionHandle h, const SipMessage& msg)
645 {
646 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onInfoFailure(h, msg);
647 }
648
649 void
650 BasicClientUserAgent::onRefer(InviteSessionHandle h, ServerSubscriptionHandle ssh, const SipMessage& msg)
651 {
652 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onRefer(h, ssh, msg);
653 }
654
655 void
656 BasicClientUserAgent::onReferAccepted(InviteSessionHandle h, ClientSubscriptionHandle csh, const SipMessage& msg)
657 {
658 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferAccepted(h, csh, msg);
659 }
660
661 void
662 BasicClientUserAgent::onReferRejected(InviteSessionHandle h, const SipMessage& msg)
663 {
664 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferRejected(h, msg);
665 }
666
667 void
668 BasicClientUserAgent::onReferNoSub(InviteSessionHandle h, const SipMessage& msg)
669 {
670 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReferNoSub(h, msg);
671 }
672
673 void
674 BasicClientUserAgent::onMessage(InviteSessionHandle h, const SipMessage& msg)
675 {
676 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessage(h, msg);
677 }
678
679 void
680 BasicClientUserAgent::onMessageSuccess(InviteSessionHandle h, const SipMessage& msg)
681 {
682 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessageSuccess(h, msg);
683 }
684
685 void
686 BasicClientUserAgent::onMessageFailure(InviteSessionHandle h, const SipMessage& msg)
687 {
688 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onMessageFailure(h, msg);
689 }
690
691 void
692 BasicClientUserAgent::onForkDestroyed(ClientInviteSessionHandle h)
693 {
694 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onForkDestroyed(h);
695 }
696
697 void
698 BasicClientUserAgent::onReadyToSend(InviteSessionHandle h, SipMessage& msg)
699 {
700 dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get())->onReadyToSend(h, msg);
701 }
702
703
704 ////////////////////////////////////////////////////////////////////////////////
705 // DialogSetHandler ///////////////////////////////////////////////////
706 ////////////////////////////////////////////////////////////////////////////////
707 void
708 BasicClientUserAgent::onTrying(AppDialogSetHandle h, const SipMessage& msg)
709 {
710 BasicClientCall *call = dynamic_cast<BasicClientCall *>(h.get());
711 if(call)
712 {
713 call->onTrying(h, msg);
714 }
715 else
716 {
717 InfoLog(<< "onTrying(AppDialogSetHandle): " << msg.brief());
718 }
719 }
720
721 void
722 BasicClientUserAgent::onNonDialogCreatingProvisional(AppDialogSetHandle h, const SipMessage& msg)
723 {
724 BasicClientCall *call = dynamic_cast<BasicClientCall *>(h.get());
725 if(call)
726 {
727 call->onNonDialogCreatingProvisional(h, msg);
728 }
729 else
730 {
731 InfoLog(<< "onNonDialogCreatingProvisional(AppDialogSetHandle): " << msg.brief());
732 }
733 }
734
735 ////////////////////////////////////////////////////////////////////////////////
736 // ClientSubscriptionHandler ///////////////////////////////////////////////////
737 ////////////////////////////////////////////////////////////////////////////////
738 void
739 BasicClientUserAgent::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
740 {
741 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
742 if(call)
743 {
744 call->onUpdatePending(h, msg, outOfOrder);
745 return;
746 }
747 InfoLog(<< "onUpdatePending(ClientSubscriptionHandle): " << msg.brief());
748 h->acceptUpdate();
749 }
750
751 void
752 BasicClientUserAgent::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
753 {
754 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
755 if(call)
756 {
757 call->onUpdateActive(h, msg, outOfOrder);
758 return;
759 }
760 InfoLog(<< "onUpdateActive(ClientSubscriptionHandle): " << msg.brief());
761 h->acceptUpdate();
762 }
763
764 void
765 BasicClientUserAgent::onUpdateExtension(ClientSubscriptionHandle h, const SipMessage& msg, bool outOfOrder)
766 {
767 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
768 if(call)
769 {
770 call->onUpdateExtension(h, msg, outOfOrder);
771 return;
772 }
773 InfoLog(<< "onUpdateExtension(ClientSubscriptionHandle): " << msg.brief());
774 h->acceptUpdate();
775 }
776
777 void
778 BasicClientUserAgent::onNotifyNotReceived(ClientSubscriptionHandle h)
779 {
780 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
781 if(call)
782 {
783 call->onNotifyNotReceived(h);
784 return;
785 }
786 WarningLog(<< "onNotifyNotReceived(ClientSubscriptionHandle)");
787 h->end();
788 }
789
790 void
791 BasicClientUserAgent::onTerminated(ClientSubscriptionHandle h, const SipMessage* msg)
792 {
793 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
794 if(call)
795 {
796 call->onTerminated(h, msg);
797 return;
798 }
799 if(msg)
800 {
801 InfoLog(<< "onTerminated(ClientSubscriptionHandle): msg=" << msg->brief());
802 }
803 else
804 {
805 InfoLog(<< "onTerminated(ClientSubscriptionHandle)");
806 }
807 }
808
809 void
810 BasicClientUserAgent::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& msg)
811 {
812 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
813 if(call)
814 {
815 call->onNewSubscription(h, msg);
816 return;
817 }
818 mClientSubscriptionHandle = h;
819 InfoLog(<< "onNewSubscription(ClientSubscriptionHandle): msg=" << msg.brief());
820 }
821
822 int
823 BasicClientUserAgent::onRequestRetry(ClientSubscriptionHandle h, int retrySeconds, const SipMessage& msg)
824 {
825 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h->getAppDialogSet().get());
826 if(call)
827 {
828 return call->onRequestRetry(h, retrySeconds, msg);
829 }
830 InfoLog(<< "onRequestRetry(ClientSubscriptionHandle): msg=" << msg.brief());
831 return FailedSubscriptionRetryTime;
832 }
833
834 ////////////////////////////////////////////////////////////////////////////////
835 // ServerSubscriptionHandler ///////////////////////////////////////////////////
836 ////////////////////////////////////////////////////////////////////////////////
837 void
838 BasicClientUserAgent::onNewSubscription(ServerSubscriptionHandle h, const SipMessage& msg)
839 {
840 InfoLog(<< "onNewSubscription(ServerSubscriptionHandle): " << msg.brief());
841
842 mServerSubscriptionHandle = h;
843 mServerSubscriptionHandle->setSubscriptionState(Active);
844 mServerSubscriptionHandle->send(mServerSubscriptionHandle->accept());
845
846 sendNotify();
847 }
848
849 void
850 BasicClientUserAgent::onNewSubscriptionFromRefer(ServerSubscriptionHandle ss, const SipMessage& msg)
851 {
852 InfoLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): " << msg.brief());
853 // Received an out-of-dialog refer request with implicit subscription
854 try
855 {
856 if(msg.exists(h_ReferTo))
857 {
858 // Check if TargetDialog header is present
859 if(msg.exists(h_TargetDialog))
860 {
861 pair<InviteSessionHandle, int> presult;
862 presult = mDum->findInviteSession(msg.header(h_TargetDialog));
863 if(!(presult.first == InviteSessionHandle::NotValid()))
864 {
865 BasicClientCall* callToRefer = (BasicClientCall*)presult.first->getAppDialogSet().get();
866
867 callToRefer->onRefer(presult.first, ss, msg);
868 return;
869 }
870 }
871
872 // We don't support ood refers that don't target a dialog - reject request
873 WarningLog (<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): Received ood refer (noSub) w/out a Target-Dialog: " << msg.brief());
874 ss->send(ss->reject(400));
875 }
876 else
877 {
878 WarningLog (<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): Received refer w/out a Refer-To: " << msg.brief());
879 ss->send(ss->reject(400));
880 }
881 }
882 catch(BaseException &e)
883 {
884 WarningLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): exception " << e);
885 }
886 catch(...)
887 {
888 WarningLog(<< "onNewSubscriptionFromRefer(ServerSubscriptionHandle): unknown exception");
889 }
890 }
891
892 void
893 BasicClientUserAgent::onRefresh(ServerSubscriptionHandle, const SipMessage& msg)
894 {
895 InfoLog(<< "onRefresh(ServerSubscriptionHandle): " << msg.brief());
896 }
897
898 void
899 BasicClientUserAgent::onTerminated(ServerSubscriptionHandle)
900 {
901 InfoLog(<< "onTerminated(ServerSubscriptionHandle)");
902 }
903
904 void
905 BasicClientUserAgent::onReadyToSend(ServerSubscriptionHandle, SipMessage&)
906 {
907 }
908
909 void
910 BasicClientUserAgent::onNotifyRejected(ServerSubscriptionHandle, const SipMessage& msg)
911 {
912 WarningLog(<< "onNotifyRejected(ServerSubscriptionHandle): " << msg.brief());
913 }
914
915 void
916 BasicClientUserAgent::onError(ServerSubscriptionHandle, const SipMessage& msg)
917 {
918 WarningLog(<< "onError(ServerSubscriptionHandle): " << msg.brief());
919 }
920
921 void
922 BasicClientUserAgent::onExpiredByClient(ServerSubscriptionHandle, const SipMessage& sub, SipMessage& notify)
923 {
924 InfoLog(<< "onExpiredByClient(ServerSubscriptionHandle): " << notify.brief());
925 }
926
927 void
928 BasicClientUserAgent::onExpired(ServerSubscriptionHandle, SipMessage& msg)
929 {
930 InfoLog(<< "onExpired(ServerSubscriptionHandle): " << msg.brief());
931 }
932
933 bool
934 BasicClientUserAgent::hasDefaultExpires() const
935 {
936 return true;
937 }
938
939 UInt32
940 BasicClientUserAgent::getDefaultExpires() const
941 {
942 return 60;
943 }
944
945 ////////////////////////////////////////////////////////////////////////////////
946 // OutOfDialogHandler //////////////////////////////////////////////////////////
947 ////////////////////////////////////////////////////////////////////////////////
948 void
949 BasicClientUserAgent::onSuccess(ClientOutOfDialogReqHandle, const SipMessage& msg)
950 {
951 InfoLog(<< "onSuccess(ClientOutOfDialogReqHandle): " << msg.brief());
952 }
953
954 void
955 BasicClientUserAgent::onFailure(ClientOutOfDialogReqHandle h, const SipMessage& msg)
956 {
957 WarningLog(<< "onFailure(ClientOutOfDialogReqHandle): " << msg.brief());
958 }
959
960 void
961 BasicClientUserAgent::onReceivedRequest(ServerOutOfDialogReqHandle ood, const SipMessage& msg)
962 {
963 InfoLog(<< "onReceivedRequest(ServerOutOfDialogReqHandle): " << msg.brief());
964
965 switch(msg.method())
966 {
967 case OPTIONS:
968 {
969 SharedPtr<SipMessage> optionsAnswer = ood->answerOptions();
970 ood->send(optionsAnswer);
971 break;
972 }
973 default:
974 ood->send(ood->reject(501 /* Not Implemented*/));
975 break;
976 }
977 }
978
979 ////////////////////////////////////////////////////////////////////////////////
980 // RedirectHandler /////////////////////////////////////////////////////////////
981 ////////////////////////////////////////////////////////////////////////////////
982 void
983 BasicClientUserAgent::onRedirectReceived(AppDialogSetHandle h, const SipMessage& msg)
984 {
985 BasicClientCall* call = dynamic_cast<BasicClientCall *>(h.get());
986 if(call)
987 {
988 call->onRedirectReceived(h, msg);
989 }
990 else
991 {
992 InfoLog(<< "onRedirectReceived(AppDialogSetHandle): " << msg.brief());
993 }
994 }
995
996 bool
997 BasicClientUserAgent::onTryingNextTarget(AppDialogSetHandle, const SipMessage& msg)
998 {
999 InfoLog(<< "onTryingNextTarget(AppDialogSetHandle): " << msg.brief());
1000
1001 // Always allow redirection for now
1002 return true;
1003 }
1004
1005
1006
1007
1008 /* ====================================================================
1009
1010 Copyright (c) 2011, SIP Spectrum, Inc.
1011 All rights reserved.
1012
1013 Redistribution and use in source and binary forms, with or without
1014 modification, are permitted provided that the following conditions are
1015 met:
1016
1017 1. Redistributions of source code must retain the above copyright
1018 notice, this list of conditions and the following disclaimer.
1019
1020 2. Redistributions in binary form must reproduce the above copyright
1021 notice, this list of conditions and the following disclaimer in the
1022 documentation and/or other materials provided with the distribution.
1023
1024 3. Neither the name of SIP Spectrum nor the names of its contributors
1025 may be used to endorse or promote products derived from this
1026 software without specific prior written permission.
1027
1028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1029 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1030 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1031 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1032 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1033 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1034 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1035 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1036 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1038 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1039
1040 ==================================================================== */
1041

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