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

Contents of /main/resip/dum/test/UserAgent.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8478 - (show annotations) (download)
Wed May 6 20:50:59 2009 UTC (10 years, 7 months ago) by bcampen
File MIME type: text/plain
File size: 14802 byte(s)
Fixing ClientSubscription's reaction (or rather lack thereof) when the server never sends a NOTIFY.

1 #include "rutil/Log.hxx"
2 #include "rutil/Logger.hxx"
3 #include "resip/stack/Pidf.hxx"
4 #include "resip/dum/ClientAuthManager.hxx"
5 #include "resip/dum/ClientInviteSession.hxx"
6 #include "resip/dum/ServerInviteSession.hxx"
7 #include "resip/dum/ClientSubscription.hxx"
8 #include "resip/dum/ServerSubscription.hxx"
9 #include "resip/dum/ClientRegistration.hxx"
10 #include "resip/dum/ServerRegistration.hxx"
11 #include "resip/dum/ClientPublication.hxx"
12 #include "resip/dum/ServerPublication.hxx"
13 #include "resip/dum/ServerOutOfDialogReq.hxx"
14
15 #if defined (USE_SSL)
16 #if defined(WIN32)
17 #include "resip/stack/ssl/WinSecurity.hxx"
18 #else
19 #include "resip/stack/ssl/Security.hxx"
20 #endif
21 #endif
22
23 #include "UserAgent.hxx"
24
25 using namespace resip;
26 using namespace std;
27
28 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST
29
30 UserAgent::UserAgent(int argc, char** argv) :
31 CommandLineParser(argc, argv),
32 mProfile(new MasterProfile),
33 #if defined(USE_SSL)
34 mSecurity(new Security(mCertPath)),
35 mStack(mSecurity),
36 #else
37 mSecurity(0),
38 mStack(mSecurity),
39 #endif
40 mDum(mStack),
41 mStackThread(mStack)
42 {
43 Log::initialize(mLogType, mLogLevel, argv[0]);
44
45 #if defined(USE_SSL)
46 if (mGenUserCert)
47 {
48 mSecurity->generateUserCert(mAor.getAor());
49 }
50 #endif
51
52 addTransport(UDP, mUdpPort);
53 addTransport(TCP, mTcpPort);
54 #if defined(USE_SSL)
55 addTransport(TLS, mTlsPort);
56 #endif
57 #if defined(USED_DTLS)
58 addTransport(DTLS, mDtlsPort);
59 #endif
60
61 mProfile->setDefaultRegistrationTime(mRegisterDuration);
62 mProfile->addSupportedMethod(NOTIFY);
63 mProfile->validateAcceptEnabled() = false;
64 mProfile->validateContentEnabled() = false;
65 mProfile->addSupportedMimeType(NOTIFY, Pidf::getStaticType());
66 mProfile->setDefaultFrom(NameAddr(mAor));
67 mProfile->setDigestCredential(mAor.host(), mAor.user(), mPassword);
68
69 if (!mContact.host().empty())
70 {
71 mProfile->setOverrideHostAndPort(mContact);
72 }
73 if (!mOutboundProxy.host().empty())
74 {
75 mProfile->setOutboundProxy(Uri(mOutboundProxy));
76 }
77 mProfile->setUserAgent("limpc/1.0");
78
79 mDum.setMasterProfile(mProfile);
80 mDum.setClientRegistrationHandler(this);
81 mDum.addClientSubscriptionHandler(Symbols::Presence, this);
82 mDum.addClientPublicationHandler(Symbols::Presence, this);
83 mDum.addOutOfDialogHandler(OPTIONS, this);
84 mDum.setClientAuthManager(std::auto_ptr<ClientAuthManager>(new ClientAuthManager));
85 mDum.setInviteSessionHandler(this);
86
87 mStackThread.run();
88 }
89
90 UserAgent::~UserAgent()
91 {
92 mStackThread.shutdown();
93 mStackThread.join();
94 }
95
96 void
97 UserAgent::startup()
98 {
99 if (mRegisterDuration)
100 {
101 InfoLog (<< "register for " << mAor);
102 mDum.send(mDum.makeRegistration(NameAddr(mAor)));
103 }
104
105 //for (std::vector<Uri> i = mBuddies.begin(); i != mBuddies.end(); ++i)
106 {
107 }
108
109 #if 0
110 mDum.send(mDum.makePublish);
111
112 auto_ptr<SipMessage> msg( sa.dialog->makeInitialPublish(NameAddr(sa.uri),NameAddr(mAor)) );
113 Pidf* pidf = new Pidf( *mPidf );
114 msg->header(h_Event).value() = "presence";
115 msg->setContents( pidf );
116 setOutbound( *msg );
117 mStack->send( *msg );
118 #endif
119 }
120
121 void
122 UserAgent::shutdown()
123 {
124 }
125
126 void
127 UserAgent::process()
128 {
129 while (mDum.process());
130 }
131
132 void
133 UserAgent::addTransport(TransportType type, int port)
134 {
135 for (; port < port+10; ++port)
136 {
137 try
138 {
139 if (port)
140 {
141 if (!mNoV4)
142 {
143 mDum.addTransport(type, port, V4, Data::Empty, mTlsDomain);
144 return;
145 }
146
147 if (!mNoV6)
148 {
149 mDum.addTransport(type, port, V6, Data::Empty, mTlsDomain);
150 return;
151 }
152 }
153 }
154 catch (BaseException& e)
155 {
156 InfoLog (<< "Caught: " << e);
157 WarningLog (<< "Failed to add " << Tuple::toData(type) << " transport on " << port);
158 }
159 }
160 throw Transport::Exception("Port already in use", __FILE__, __LINE__);
161 }
162
163
164 void
165 UserAgent::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
166 {
167 InfoLog(<< h->myAddr().uri().user() << " 180 from " << h->peerAddr().uri().user());
168
169 // Schedule an end() call; checks handle validity, and whether the Session
170 // is already tearing down (isTerminated() check)
171 mStack.post(std::auto_ptr<ApplicationMessage>(new EndInviteSessionCommand(h->getSessionHandle())), 60, &mDum);
172 }
173
174 void
175 UserAgent::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
176 {
177 InfoLog(<< h->myAddr().uri().user() << " INVITE from " << h->peerAddr().uri().user());
178
179 h->provisional(180);
180 // .bwc. Er, this doesn't look right. We should provide an answer when we get
181 // the onOffer() callback, not the onNewSession() callback.
182 // SdpContents* sdp = dynamic_cast<SdpContents*>(msg.getContents());
183 // h->provideAnswer(*sdp);
184 // h->accept();
185
186 // Schedule an end() call; checks handle validity, and whether the Session
187 // is already tearing down (isTerminated() check)
188 mStack.post(std::auto_ptr<ApplicationMessage>(new EndInviteSessionCommand(h->getSessionHandle())), 60, &mDum);
189
190 // might update presence here
191 }
192
193 void
194 UserAgent::onFailure(ClientInviteSessionHandle h, const SipMessage& msg)
195 {
196 InfoLog(<< h->myAddr().uri().user()
197 << " outgoing call failed "
198 << h->peerAddr().uri().user()
199 << " status=" << msg.header(h_StatusLine).statusCode());
200 }
201
202 void
203 UserAgent::onEarlyMedia(ClientInviteSessionHandle, const SipMessage&, const SdpContents&)
204 {
205 }
206
207 void
208 UserAgent::onProvisional(ClientInviteSessionHandle, const SipMessage& msg)
209 {
210 }
211
212 void
213 UserAgent::onConnected(ClientInviteSessionHandle h, const SipMessage& msg)
214 {
215 InfoLog(<< h->myAddr().uri().user() << " in INVITE session with " << h->peerAddr().uri().user());
216 }
217
218 void
219 UserAgent::onConnected(InviteSessionHandle, const SipMessage& msg)
220 {
221 }
222
223 void
224 UserAgent::onStaleCallTimeout(ClientInviteSessionHandle)
225 {
226 WarningLog(<< "onStaleCallTimeout");
227 }
228
229 void
230 UserAgent::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
231 {
232 WarningLog(<< h->myAddr().uri().user() << " call terminated with " << h->peerAddr().uri().user() << " reason=" << reason);
233 }
234
235 void
236 UserAgent::onRedirected(ClientInviteSessionHandle, const SipMessage& msg)
237 {
238 assert(false);
239 }
240
241 void
242 UserAgent::onAnswer(InviteSessionHandle, const SipMessage& msg, const SdpContents&)
243 {
244 }
245
246 void
247 UserAgent::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& offer)
248 {
249 InfoLog(<< h->myAddr().uri().user() << " offer from " << h->peerAddr().uri().user());
250
251 SdpContents* sdp = dynamic_cast<SdpContents*>(msg.getContents());
252 h->provideAnswer(*sdp);
253 if(msg.isRequest() && msg.method()==INVITE && !h->isConnected())
254 {
255 ServerInviteSession* uas = dynamic_cast<ServerInviteSession*>(h.get());
256 if(uas)
257 {
258 uas->accept();
259 }
260 }
261 }
262
263 void
264 UserAgent::onOfferRequired(InviteSessionHandle h, const SipMessage& msg)
265 {
266 InfoLog(<< h->myAddr().uri().user() << " offer requested by "
267 << h->peerAddr().uri().user());
268
269 static Data txt("v=0\r\n"
270 "o=1900 369696545 369696545 IN IP4 192.168.2.15\r\n"
271 "s=X-Lite\r\n"
272 "c=IN IP4 192.168.2.15\r\n"
273 "t=0 0\r\n"
274 "m=audio 8000 RTP/AVP 8 3 98 97 101\r\n"
275 "a=rtpmap:8 pcma/8000\r\n"
276 "a=rtpmap:3 gsm/8000\r\n"
277 "a=rtpmap:98 iLBC\r\n"
278 "a=rtpmap:97 speex/8000\r\n"
279 "a=rtpmap:101 telephone-event/8000\r\n"
280 "a=fmtp:101 0-15\r\n");
281
282 static HeaderFieldValue hfv(txt.data(), txt.size());
283 static Mime type("application", "sdp");
284 static SdpContents sdp(&hfv, type);
285 h->provideOffer(sdp);
286 }
287
288 void
289 UserAgent::onOfferRejected(InviteSessionHandle h, const SipMessage* msg)
290 {
291 InfoLog(<< h->myAddr().uri().user() << " offer rejected by "
292 << h->peerAddr().uri().user());
293 }
294
295 void
296 UserAgent::onDialogModified(InviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
297 {
298 InfoLog(<< h->myAddr().uri().user() << " dialog modified "
299 << h->peerAddr().uri().user());
300 }
301
302 void
303 UserAgent::onInfo(InviteSessionHandle h, const SipMessage& msg)
304 {
305 InfoLog(<< h->myAddr().uri().user() << " INFO "
306 << h->peerAddr().uri().user());
307 h->acceptNIT();
308 }
309
310 void
311 UserAgent::onInfoSuccess(InviteSessionHandle, const SipMessage& msg)
312 {
313 }
314
315 void
316 UserAgent::onInfoFailure(InviteSessionHandle, const SipMessage& msg)
317 {
318 }
319
320 void
321 UserAgent::onRefer(InviteSessionHandle, ServerSubscriptionHandle, const SipMessage& msg)
322 {
323 assert(0);
324 }
325
326 void
327 UserAgent::onReferAccepted(InviteSessionHandle, ClientSubscriptionHandle, const SipMessage& msg)
328 {
329 assert(false);
330 }
331
332 void
333 UserAgent::onReferRejected(InviteSessionHandle, const SipMessage& msg)
334 {
335 assert(0);
336 }
337
338 void
339 UserAgent::onReferNoSub(InviteSessionHandle, const SipMessage& msg)
340 {
341 assert(0);
342 }
343
344 void
345 UserAgent::onMessage(InviteSessionHandle h, const SipMessage& msg)
346 {
347 InfoLog(<< h->myAddr().uri().user() << " MESSAGE "
348 << h->peerAddr().uri().user());
349 h->acceptNIT();
350 }
351
352 void
353 UserAgent::onMessageSuccess(InviteSessionHandle, const SipMessage& msg)
354 {
355 }
356
357 void
358 UserAgent::onMessageFailure(InviteSessionHandle, const SipMessage& msg)
359 {
360 }
361
362
363 ////////////////////////////////////////////////////////////////////////////////
364 // Registration Handler ////////////////////////////////////////////////////////
365 ////////////////////////////////////////////////////////////////////////////////
366 void
367 UserAgent::onSuccess(ClientRegistrationHandle h, const SipMessage& response)
368 {
369 }
370
371 void
372 UserAgent::onFailure(ClientRegistrationHandle h, const SipMessage& response)
373 {
374 }
375
376 void
377 UserAgent::onRemoved(ClientRegistrationHandle h, const SipMessage&)
378 {
379 }
380
381 int
382 UserAgent::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg)
383 {
384 //assert(false);
385 return -1;
386 }
387
388 ////////////////////////////////////////////////////////////////////////////////
389 // ClientSubscriptionHandler ///////////////////////////////////////////////////
390 ////////////////////////////////////////////////////////////////////////////////
391 void
392 UserAgent::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& notify, bool outOfOrder)
393 {
394 }
395
396 void
397 UserAgent::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& notify, bool outOfOrder)
398 {
399 }
400
401 void
402 UserAgent::onUpdateExtension(ClientSubscriptionHandle, const SipMessage& notify, bool outOfOrder)
403 {
404 }
405
406 void
407 UserAgent::onTerminated(ClientSubscriptionHandle h, const SipMessage* notify)
408 {
409 }
410
411 void
412 UserAgent::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& notify)
413 {
414 }
415
416 int
417 UserAgent::onRequestRetry(ClientSubscriptionHandle h, int retryMinimum, const SipMessage& notify)
418 {
419 return -1;
420 }
421
422 ////////////////////////////////////////////////////////////////////////////////
423 // ClientPublicationHandler ////////////////////////////////////////////////////
424 ////////////////////////////////////////////////////////////////////////////////
425 void
426 UserAgent::onSuccess(ClientPublicationHandle h, const SipMessage& status)
427 {
428 }
429
430 void
431 UserAgent::onRemove(ClientPublicationHandle h, const SipMessage& status)
432 {
433 }
434
435 void
436 UserAgent::onFailure(ClientPublicationHandle h, const SipMessage& response)
437 {
438 }
439
440 int
441 UserAgent::onRequestRetry(ClientPublicationHandle h, int retryMinimum, const SipMessage& response)
442 {
443 return -1;
444 }
445
446 ////////////////////////////////////////////////////////////////////////////////
447 // OutOfDialogHandler //////////////////////////////////////////////////////////
448 ////////////////////////////////////////////////////////////////////////////////
449 void
450 UserAgent::onSuccess(ClientOutOfDialogReqHandle, const SipMessage& response)
451 {
452 InfoLog(<< response.header(h_CSeq).method() << "::OK: " << response );
453 }
454
455 void
456 UserAgent::onFailure(ClientOutOfDialogReqHandle, const SipMessage& response)
457 {
458 ErrLog(<< response.header(h_CSeq).method() << "::failure: " << response );
459 if (response.exists(h_Warnings)) ErrLog (<< response.header(h_Warnings).front());
460 }
461
462 void
463 UserAgent::onReceivedRequest(ServerOutOfDialogReqHandle h, const SipMessage& request)
464 {
465 InfoLog(<< request.method() << ": Just respond.");
466 h->send(h->accept());
467 }
468
469 void
470 UserAgent::onForkDestroyed(ClientInviteSessionHandle)
471 {
472 }
473
474 /* ====================================================================
475 * The Vovida Software License, Version 1.0
476 *
477 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
478 *
479 * Redistribution and use in source and binary forms, with or without
480 * modification, are permitted provided that the following conditions
481 * are met:
482 *
483 * 1. Redistributions of source code must retain the above copyright
484 * notice, this list of conditions and the following disclaimer.
485 *
486 * 2. Redistributions in binary form must reproduce the above copyright
487 * notice, this list of conditions and the following disclaimer in
488 * the documentation and/or other materials provided with the
489 * distribution.
490 *
491 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
492 * and "Vovida Open Communication Application Library (VOCAL)" must
493 * not be used to endorse or promote products derived from this
494 * software without prior written permission. For written
495 * permission, please contact vocal@vovida.org.
496 *
497 * 4. Products derived from this software may not be called "VOCAL", nor
498 * may "VOCAL" appear in their name, without prior written
499 * permission of Vovida Networks, Inc.
500 *
501 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
502 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
503 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
504 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
505 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
506 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
507 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
508 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
509 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
510 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
511 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
512 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
513 * DAMAGE.
514 *
515 * ====================================================================
516 *
517 * This software consists of voluntary contributions made by Vovida
518 * Networks, Inc. and many individuals on behalf of Vovida Networks,
519 * Inc. For more information on Vovida Networks, Inc., please see
520 * <http://www.vovida.org/>.
521 *
522 */

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