/[resiprocate]/main/resip/dum/test/basicClientUserAgent.cxx
ViewVC logotype

Annotation of /main/resip/dum/test/basicClientUserAgent.cxx

Parent Directory Parent Directory | Revision Log Revision Log


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

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