/[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 9016 - (show annotations) (download)
Wed Feb 16 18:06:10 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: 30166 byte(s)
-treat internal 503 errors the same as 408 errors when dispatching onRequestRetry callback for
 ClientRegistration, ClientSubscription and ClientPublication
 - allows retry logic that is consistent when using both UDP or TCP/TLS transports
 - note:  TCP/TLS transports get a 503 error when they cannot connect, UDP transports typically
          get a 408 error when the far end is not present
-ClientRegistration changes to ensure calling requestRefresh will not assert in any state
 - allow calling requestRefresh while a retry timer is running to request an immediate retry 
-Created new ClientRegistrationHandler callback:  onFlowTerminated - default implementation is
 to immediately try a registration refresh to establish a new flow
-Dispatch flowTerminated to all ClientSubscription, ServerSubscription and InviteSession dialogs
-implemented registration retry backoff logic from RFC5626 section 4.5 in basicClient test program

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

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