reSIProcate/DialogUsageManager  9694
UserAgent.cxx
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include "config.h"
00003 #endif
00004 
00005 #include "rutil/Log.hxx"
00006 #include "rutil/Logger.hxx"
00007 #include "resip/stack/Pidf.hxx"
00008 #include "resip/dum/ClientAuthManager.hxx"
00009 #include "resip/dum/ClientInviteSession.hxx"
00010 #include "resip/dum/ServerInviteSession.hxx"
00011 #include "resip/dum/ClientSubscription.hxx"
00012 #include "resip/dum/ServerSubscription.hxx"
00013 #include "resip/dum/ClientRegistration.hxx"
00014 #include "resip/dum/ServerRegistration.hxx"
00015 #include "resip/dum/ClientPublication.hxx"
00016 #include "resip/dum/ServerPublication.hxx"
00017 #include "resip/dum/ServerOutOfDialogReq.hxx"
00018 
00019 #if defined (USE_SSL)
00020 #if defined(WIN32) 
00021 #include "resip/stack/ssl/WinSecurity.hxx"
00022 #else
00023 #include "resip/stack/ssl/Security.hxx"
00024 #endif
00025 #endif
00026 
00027 #include "UserAgent.hxx"
00028 
00029 using namespace resip;
00030 using namespace std;
00031 
00032 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST
00033 
00034 UserAgent::UserAgent(int argc, char** argv) : 
00035    CommandLineParser(argc, argv),
00036    mProfile(new MasterProfile),
00037 #if defined(USE_SSL)
00038    mSecurity(new Security(mCertPath)),
00039    mStack(mSecurity),
00040 #else
00041    mSecurity(0),
00042    mStack(mSecurity),
00043 #endif
00044    mDum(mStack),
00045    mStackThread(mStack)
00046 {
00047    Log::initialize(mLogType, mLogLevel, argv[0]);
00048 
00049 #if defined(USE_SSL)
00050    if (mGenUserCert)
00051    {
00052       mSecurity->generateUserCert(mAor.getAor());
00053    }
00054 #endif
00055 
00056    addTransport(UDP, mUdpPort);
00057    addTransport(TCP, mTcpPort);
00058 #if defined(USE_SSL)
00059    addTransport(TLS, mTlsPort);
00060 #endif
00061 #if defined(USED_DTLS)
00062    addTransport(DTLS, mDtlsPort);
00063 #endif
00064 
00065    mProfile->setDefaultRegistrationTime(mRegisterDuration);
00066    mProfile->addSupportedMethod(NOTIFY);
00067    mProfile->validateAcceptEnabled() = false;
00068    mProfile->validateContentEnabled() = false;
00069    mProfile->addSupportedMimeType(NOTIFY, Pidf::getStaticType());
00070    mProfile->setDefaultFrom(NameAddr(mAor));
00071    mProfile->setDigestCredential(mAor.host(), mAor.user(), mPassword);
00072    
00073    if (!mContact.host().empty())
00074    {
00075       mProfile->setOverrideHostAndPort(mContact);
00076    }
00077    if (!mOutboundProxy.host().empty())
00078    {
00079       mProfile->setOutboundProxy(Uri(mOutboundProxy));
00080    }
00081    mProfile->setUserAgent("limpc/1.0");
00082    
00083    mDum.setMasterProfile(mProfile);
00084    mDum.setClientRegistrationHandler(this);
00085    mDum.addClientSubscriptionHandler(Symbols::Presence, this);
00086    mDum.addClientPublicationHandler(Symbols::Presence, this);
00087    mDum.addOutOfDialogHandler(OPTIONS, this);
00088    mDum.setClientAuthManager(std::auto_ptr<ClientAuthManager>(new ClientAuthManager));
00089    mDum.setInviteSessionHandler(this);
00090    
00091    mStackThread.run(); 
00092 }
00093 
00094 UserAgent::~UserAgent()
00095 {
00096    mStackThread.shutdown();
00097    mStackThread.join();
00098 }
00099 
00100 void
00101 UserAgent::startup()
00102 {
00103    if (mRegisterDuration)
00104    {
00105       InfoLog (<< "register for " << mAor);
00106       mDum.send(mDum.makeRegistration(NameAddr(mAor)));
00107    }
00108 
00109    //for (std::vector<Uri> i = mBuddies.begin(); i != mBuddies.end(); ++i)
00110    {
00111    }
00112 
00113 #if 0
00114    mDum.send(mDum.makePublish);
00115 
00116    auto_ptr<SipMessage> msg( sa.dialog->makeInitialPublish(NameAddr(sa.uri),NameAddr(mAor)) );
00117    Pidf* pidf = new Pidf( *mPidf );
00118    msg->header(h_Event).value() = "presence";
00119    msg->setContents( pidf );
00120    setOutbound( *msg );
00121    mStack->send( *msg );
00122 #endif
00123 }
00124 
00125 void
00126 UserAgent::shutdown()
00127 {
00128 }
00129 
00130 void
00131 UserAgent::process()
00132 {
00133    while (mDum.process());
00134 }
00135 
00136 void
00137 UserAgent::addTransport(TransportType type, int port)
00138 {
00139    for (int i=0; i < 10; ++i)
00140    {
00141       try
00142       {
00143          if (port)
00144          {
00145             if (!mNoV4)
00146             {
00147                mDum.addTransport(type, port+i, V4, Data::Empty, mTlsDomain);
00148                return;
00149             }
00150 
00151             if (!mNoV6)
00152             {
00153                mDum.addTransport(type, port+i, V6, Data::Empty, mTlsDomain);
00154                return;
00155             }
00156          }
00157       }
00158       catch (BaseException& e)
00159       {
00160          InfoLog (<< "Caught: " << e);
00161          WarningLog (<< "Failed to add " << Tuple::toData(type) << " transport on " << port);
00162       }
00163    }
00164    throw Transport::Exception("Port already in use", __FILE__, __LINE__);
00165 }
00166 
00167 
00168 void
00169 UserAgent::onNewSession(ClientInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
00170 {
00171    InfoLog(<< h->myAddr().uri().user() << " 180 from  " << h->peerAddr().uri().user());
00172 
00173    // Schedule an end() call; checks handle validity, and whether the Session
00174    // is already tearing down (isTerminated() check)
00175    mStack.post(std::auto_ptr<ApplicationMessage>(new EndInviteSessionCommand(h->getSessionHandle())), 60, &mDum);
00176 }
00177 
00178 void
00179 UserAgent::onNewSession(ServerInviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
00180 {
00181    InfoLog(<< h->myAddr().uri().user() << " INVITE from  " << h->peerAddr().uri().user());
00182          
00183    h->provisional(180);
00184    // .bwc. Er, this doesn't look right. We should provide an answer when we get
00185    // the onOffer() callback, not the onNewSession() callback.
00186    // SdpContents* sdp = dynamic_cast<SdpContents*>(msg.getContents());
00187    // h->provideAnswer(*sdp);
00188    // h->accept();
00189 
00190    // Schedule an end() call; checks handle validity, and whether the Session
00191    // is already tearing down (isTerminated() check)
00192    mStack.post(std::auto_ptr<ApplicationMessage>(new EndInviteSessionCommand(h->getSessionHandle())), 60, &mDum);
00193 
00194    // might update presence here
00195 }
00196 
00197 void
00198 UserAgent::onFailure(ClientInviteSessionHandle h, const SipMessage& msg)
00199 {
00200    InfoLog(<< h->myAddr().uri().user() 
00201            << " outgoing call failed " 
00202            << h->peerAddr().uri().user() 
00203            << " status=" << msg.header(h_StatusLine).statusCode());
00204 }
00205       
00206 void
00207 UserAgent::onEarlyMedia(ClientInviteSessionHandle, const SipMessage&, const SdpContents&)
00208 {
00209 }
00210 
00211 void
00212 UserAgent::onProvisional(ClientInviteSessionHandle, const SipMessage& msg)
00213 {
00214 }
00215 
00216 void
00217 UserAgent::onConnected(ClientInviteSessionHandle h, const SipMessage& msg)
00218 {
00219    InfoLog(<< h->myAddr().uri().user() << " in INVITE session with " << h->peerAddr().uri().user());
00220 }
00221 
00222 void
00223 UserAgent::onConnected(InviteSessionHandle, const SipMessage& msg)
00224 {
00225 }
00226 
00227 void
00228 UserAgent::onStaleCallTimeout(ClientInviteSessionHandle)
00229 {
00230    WarningLog(<< "onStaleCallTimeout");
00231 }
00232 
00233 void
00234 UserAgent::onTerminated(InviteSessionHandle h, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
00235 {
00236    WarningLog(<< h->myAddr().uri().user() << " call terminated with " << h->peerAddr().uri().user() << " reason=" << reason);
00237 }
00238 
00239 void
00240 UserAgent::onRedirected(ClientInviteSessionHandle, const SipMessage& msg)
00241 {
00242    assert(false);
00243 }
00244 
00245 void
00246 UserAgent::onAnswer(InviteSessionHandle, const SipMessage& msg, const SdpContents&)
00247 {
00248 }
00249 
00250 void
00251 UserAgent::onOffer(InviteSessionHandle h, const SipMessage& msg, const SdpContents& offer)
00252 {
00253    InfoLog(<< h->myAddr().uri().user() << " offer from  " << h->peerAddr().uri().user());
00254 
00255    SdpContents* sdp = dynamic_cast<SdpContents*>(msg.getContents());
00256    h->provideAnswer(*sdp);
00257    if(msg.isRequest() && msg.method()==INVITE && !h->isConnected())
00258    {
00259       ServerInviteSession* uas = dynamic_cast<ServerInviteSession*>(h.get());
00260       if(uas)
00261       {
00262          uas->accept();
00263       }
00264    }
00265 }
00266 
00267 void
00268 UserAgent::onOfferRequired(InviteSessionHandle h, const SipMessage& msg)
00269 {
00270    InfoLog(<< h->myAddr().uri().user() << " offer requested by  " 
00271             << h->peerAddr().uri().user());
00272 
00273    static Data txt("v=0\r\n"
00274                   "o=1900 369696545 369696545 IN IP4 192.168.2.15\r\n"
00275                   "s=X-Lite\r\n"
00276                   "c=IN IP4 192.168.2.15\r\n"
00277                   "t=0 0\r\n"
00278                   "m=audio 8000 RTP/AVP 8 3 98 97 101\r\n"
00279                   "a=rtpmap:8 pcma/8000\r\n"
00280                   "a=rtpmap:3 gsm/8000\r\n"
00281                   "a=rtpmap:98 iLBC\r\n"
00282                   "a=rtpmap:97 speex/8000\r\n"
00283                   "a=rtpmap:101 telephone-event/8000\r\n"
00284                   "a=fmtp:101 0-15\r\n");
00285 
00286    static HeaderFieldValue hfv(txt.data(), txt.size());
00287    static Mime type("application", "sdp");
00288    static SdpContents sdp(hfv, type);
00289    h->provideOffer(sdp);
00290 }
00291 
00292 void
00293 UserAgent::onOfferRejected(InviteSessionHandle h, const SipMessage* msg)
00294 {
00295    InfoLog(<< h->myAddr().uri().user() << " offer rejected by  " 
00296             << h->peerAddr().uri().user());
00297 }
00298 
00299 void
00300 UserAgent::onDialogModified(InviteSessionHandle h, InviteSession::OfferAnswerType oat, const SipMessage& msg)
00301 {
00302    InfoLog(<< h->myAddr().uri().user() << " dialog modified " 
00303             << h->peerAddr().uri().user());
00304 }
00305 
00306 void
00307 UserAgent::onInfo(InviteSessionHandle h, const SipMessage& msg)
00308 {
00309    InfoLog(<< h->myAddr().uri().user() << " INFO " 
00310             << h->peerAddr().uri().user());
00311    h->acceptNIT();
00312 }
00313 
00314 void
00315 UserAgent::onInfoSuccess(InviteSessionHandle, const SipMessage& msg)
00316 {
00317 }
00318 
00319 void
00320 UserAgent::onInfoFailure(InviteSessionHandle, const SipMessage& msg)
00321 {
00322 }
00323 
00324 void
00325 UserAgent::onRefer(InviteSessionHandle, ServerSubscriptionHandle, const SipMessage& msg)
00326 {
00327     assert(0);
00328 }
00329 
00330 void
00331 UserAgent::onReferAccepted(InviteSessionHandle, ClientSubscriptionHandle, const SipMessage& msg)
00332 {
00333    assert(false);
00334 }
00335 
00336 void
00337 UserAgent::onReferRejected(InviteSessionHandle, const SipMessage& msg)
00338 {
00339    assert(0);
00340 }
00341 
00342 void
00343 UserAgent::onReferNoSub(InviteSessionHandle, const SipMessage& msg)
00344 {
00345    assert(0);
00346 }
00347 
00348 void
00349 UserAgent::onMessage(InviteSessionHandle h, const SipMessage& msg)
00350 {
00351    InfoLog(<< h->myAddr().uri().user() << " MESSAGE " 
00352             << h->peerAddr().uri().user());
00353    h->acceptNIT();
00354 }
00355 
00356 void
00357 UserAgent::onMessageSuccess(InviteSessionHandle, const SipMessage& msg)
00358 {
00359 }
00360 
00361 void
00362 UserAgent::onMessageFailure(InviteSessionHandle, const SipMessage& msg)
00363 {
00364 }
00365 
00366 
00368 // Registration Handler ////////////////////////////////////////////////////////
00370 void 
00371 UserAgent::onSuccess(ClientRegistrationHandle h, const SipMessage& response)
00372 {
00373 }
00374 
00375 void
00376 UserAgent::onFailure(ClientRegistrationHandle h, const SipMessage& response)
00377 {
00378 }
00379 
00380 void
00381 UserAgent::onRemoved(ClientRegistrationHandle h, const SipMessage&)
00382 {
00383 }
00384 
00385 int 
00386 UserAgent::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg)
00387 {
00388    //assert(false);
00389    return -1;
00390 }
00391 
00393 // ClientSubscriptionHandler ///////////////////////////////////////////////////
00395 void
00396 UserAgent::onUpdatePending(ClientSubscriptionHandle h, const SipMessage& notify, bool outOfOrder)
00397 {
00398 }
00399 
00400 void
00401 UserAgent::onUpdateActive(ClientSubscriptionHandle h, const SipMessage& notify, bool outOfOrder)
00402 {
00403 }
00404 
00405 void
00406 UserAgent::onUpdateExtension(ClientSubscriptionHandle, const SipMessage& notify, bool outOfOrder)
00407 {
00408 }
00409 
00410 void
00411 UserAgent::onTerminated(ClientSubscriptionHandle h, const SipMessage* notify)
00412 {
00413 }
00414 
00415 void
00416 UserAgent::onNewSubscription(ClientSubscriptionHandle h, const SipMessage& notify)
00417 {
00418 }
00419 
00420 int 
00421 UserAgent::onRequestRetry(ClientSubscriptionHandle h, int retryMinimum, const SipMessage& notify)
00422 {
00423    return -1;
00424 }
00425 
00427 // ClientPublicationHandler ////////////////////////////////////////////////////
00429 void
00430 UserAgent::onSuccess(ClientPublicationHandle h, const SipMessage& status)
00431 {
00432 }
00433 
00434 void
00435 UserAgent::onRemove(ClientPublicationHandle h, const SipMessage& status)
00436 {
00437 }
00438 
00439 void
00440 UserAgent::onFailure(ClientPublicationHandle h, const SipMessage& response)
00441 {
00442 }
00443 
00444 int 
00445 UserAgent::onRequestRetry(ClientPublicationHandle h, int retryMinimum, const SipMessage& response)
00446 {
00447    return -1;
00448 }
00449       
00451 // OutOfDialogHandler //////////////////////////////////////////////////////////
00453 void 
00454 UserAgent::onSuccess(ClientOutOfDialogReqHandle, const SipMessage& response)
00455 {
00456    InfoLog(<< response.header(h_CSeq).method() << "::OK: " << response );
00457 }
00458 
00459 void 
00460 UserAgent::onFailure(ClientOutOfDialogReqHandle, const SipMessage& response)
00461 {
00462    ErrLog(<< response.header(h_CSeq).method() << "::failure: " << response );
00463    if (response.exists(h_Warnings)) ErrLog  (<< response.header(h_Warnings).front());
00464 }
00465 
00466 void 
00467 UserAgent::onReceivedRequest(ServerOutOfDialogReqHandle h, const SipMessage& request)
00468 {
00469    InfoLog(<< request.method() << ": Just respond.");
00470    h->send(h->accept());
00471 }
00472 
00473 void
00474 UserAgent::onForkDestroyed(ClientInviteSessionHandle)
00475 {
00476 }
00477 
00478 /* ====================================================================
00479  * The Vovida Software License, Version 1.0 
00480  * 
00481  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00482  * 
00483  * Redistribution and use in source and binary forms, with or without
00484  * modification, are permitted provided that the following conditions
00485  * are met:
00486  * 
00487  * 1. Redistributions of source code must retain the above copyright
00488  *    notice, this list of conditions and the following disclaimer.
00489  * 
00490  * 2. Redistributions in binary form must reproduce the above copyright
00491  *    notice, this list of conditions and the following disclaimer in
00492  *    the documentation and/or other materials provided with the
00493  *    distribution.
00494  * 
00495  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00496  *    and "Vovida Open Communication Application Library (VOCAL)" must
00497  *    not be used to endorse or promote products derived from this
00498  *    software without prior written permission. For written
00499  *    permission, please contact vocal@vovida.org.
00500  *
00501  * 4. Products derived from this software may not be called "VOCAL", nor
00502  *    may "VOCAL" appear in their name, without prior written
00503  *    permission of Vovida Networks, Inc.
00504  * 
00505  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00506  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00507  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00508  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00509  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00510  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00511  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00512  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00513  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00514  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00515  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00516  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00517  * DAMAGE.
00518  * 
00519  * ====================================================================
00520  * 
00521  * This software consists of voluntary contributions made by Vovida
00522  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00523  * Inc.  For more information on Vovida Networks, Inc., please see
00524  * <http://www.vovida.org/>.
00525  *
00526  */