reSIProcate/DialogUsageManager  9680
BasicCall.cxx
Go to the documentation of this file.
00001 #include "resip/stack/SdpContents.hxx"
00002 #include "resip/stack/PlainContents.hxx"
00003 #include "resip/stack/SipMessage.hxx"
00004 #include "resip/stack/ShutdownMessage.hxx"
00005 #include "resip/stack/SipStack.hxx"
00006 #include "resip/dum/ClientAuthManager.hxx"
00007 #include "resip/dum/ClientInviteSession.hxx"
00008 #include "resip/dum/ClientRegistration.hxx"
00009 #include "resip/dum/DialogUsageManager.hxx"
00010 #include "resip/dum/DumShutdownHandler.hxx"
00011 #include "resip/dum/InviteSessionHandler.hxx"
00012 #include "resip/dum/MasterProfile.hxx"
00013 #include "resip/dum/RegistrationHandler.hxx"
00014 #include "resip/dum/ServerInviteSession.hxx"
00015 #include "resip/dum/ServerOutOfDialogReq.hxx"
00016 #include "resip/dum/OutOfDialogHandler.hxx"
00017 #include "resip/dum/AppDialog.hxx"
00018 #include "resip/dum/AppDialogSet.hxx"
00019 #include "resip/dum/AppDialogSetFactory.hxx"
00020 #include "rutil/Log.hxx"
00021 #include "rutil/Logger.hxx"
00022 #include "rutil/Random.hxx"
00023 #include "rutil/WinLeakCheck.hxx"
00024 
00025 #include <sstream>
00026 #include <time.h>
00027 
00028 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST
00029 /* #define NO_REGISTRATION 1 -- This is now run-time option */
00030 
00031 using namespace resip;
00032 using namespace std;
00033 
00035 //
00036 // Classes that provide the mapping between Application Data and DUM 
00037 // dialogs/dialogsets
00038 //                                                                              
00039 // The DUM layer creates an AppDialog/AppDialogSet object for inbound/outbound
00040 // SIP Request that results in Dialog creation.
00041 //                                                                              
00043 class testAppDialog : public AppDialog
00044 {
00045 public:
00046    testAppDialog(HandleManager& ham, Data &SampleAppData) : AppDialog(ham), mSampleAppData(SampleAppData)
00047    {  
00048       cout << mSampleAppData << ": testAppDialog: created." << endl;  
00049    }
00050    virtual ~testAppDialog() 
00051    { 
00052       cout << mSampleAppData << ": testAppDialog: destroyed." << endl; 
00053    }
00054    Data mSampleAppData;
00055 };
00056 
00057 class testAppDialogSet : public AppDialogSet
00058 {
00059 public:
00060    testAppDialogSet(DialogUsageManager& dum, Data SampleAppData) : AppDialogSet(dum), mSampleAppData(SampleAppData)
00061    {  
00062       cout << mSampleAppData << ": testAppDialogSet: created." << endl;  
00063    }
00064    virtual ~testAppDialogSet() 
00065    {  
00066       cout << mSampleAppData << ": testAppDialogSet: destroyed." << endl;  
00067    }
00068    virtual AppDialog* createAppDialog(const SipMessage& msg) 
00069    {  
00070       return new testAppDialog(mDum, mSampleAppData);  
00071    }
00072    virtual SharedPtr<UserProfile> selectUASUserProfile(const SipMessage& msg) 
00073    { 
00074       cout << mSampleAppData << ": testAppDialogSet: UAS UserProfile requested for msg: " << msg.brief() << endl;  
00075       return mDum.getMasterUserProfile(); 
00076    }
00077    Data mSampleAppData;
00078 };
00079 
00080 class testAppDialogSetFactory : public AppDialogSetFactory
00081 {
00082 public:
00083    virtual AppDialogSet* createAppDialogSet(DialogUsageManager& dum, const SipMessage& msg) 
00084    {  return new testAppDialogSet(dum, Data("UAS") + Data("(") + getMethodName(msg.header(h_RequestLine).getMethod()) + Data(")"));  }
00085    // For a UAS the testAppDialogSet will be created by DUM using this function.  If you want to set 
00086    // Application Data, then one approach is to wait for onNewSession(ServerInviteSessionHandle ...) 
00087    // to be called, then use the ServerInviteSessionHandle to get at the AppDialogSet or AppDialog,
00088    // then cast to your derived class and set the desired application data.
00089 };
00090 
00091 
00092 // Generic InviteSessionHandler
00093 class TestInviteSessionHandler : public InviteSessionHandler, public ClientRegistrationHandler, public OutOfDialogHandler
00094 {
00095    public:
00096       Data name;
00097       bool registered;
00098       ClientRegistrationHandle registerHandle;
00099       
00100       TestInviteSessionHandler(const Data& n) : name(n), registered(false) 
00101       {
00102       }
00103 
00104       virtual ~TestInviteSessionHandler()
00105       {
00106       }
00107       
00108       virtual void onSuccess(ClientRegistrationHandle h, const SipMessage& response)
00109       {         
00110          registerHandle = h;   
00111          assert(registerHandle.isValid());         
00112          cout << name << ": ClientRegistration-onSuccess - " << response.brief() << endl;
00113          registered = true;
00114       }
00115 
00116       virtual void onFailure(ClientRegistrationHandle, const SipMessage& msg)
00117       {
00118          cout << name << ": ClientRegistration-onFailure - " << msg.brief() << endl;
00119          throw;  // Ungracefully end
00120       }
00121 
00122       virtual void onRemoved(ClientRegistrationHandle, const SipMessage& response)
00123       {
00124           cout << name << ": ClientRegistration-onRemoved" << endl;
00125       }
00126 
00127       virtual int onRequestRetry(ClientRegistrationHandle, int retrySeconds, const SipMessage& response)
00128       {
00129           cout << name << ": ClientRegistration-onRequestRetry (" << retrySeconds << ") - " << response.brief() << endl;
00130           return -1;
00131       }
00132 
00133       virtual void onNewSession(ClientInviteSessionHandle, InviteSession::OfferAnswerType oat, const SipMessage& msg)
00134       {
00135          cout << name << ": ClientInviteSession-onNewSession - " << msg.brief() << endl;
00136       }
00137       
00138       virtual void onNewSession(ServerInviteSessionHandle, InviteSession::OfferAnswerType oat, const SipMessage& msg)
00139       {
00140          cout << name << ": ServerInviteSession-onNewSession - " << msg.brief() << endl;
00141       }
00142 
00143       virtual void onFailure(ClientInviteSessionHandle, const SipMessage& msg)
00144       {
00145          cout << name << ": ClientInviteSession-onFailure - " << msg.brief() << endl;
00146       }
00147       
00148       virtual void onProvisional(ClientInviteSessionHandle, const SipMessage& msg)
00149       {
00150          cout << name << ": ClientInviteSession-onProvisional - " << msg.brief() << endl;
00151       }
00152 
00153       virtual void onConnected(ClientInviteSessionHandle, const SipMessage& msg)
00154       {
00155          cout << name << ": ClientInviteSession-onConnected - " << msg.brief() << endl;
00156       }
00157 
00158       virtual void onStaleCallTimeout(ClientInviteSessionHandle handle)
00159       {
00160          cout << name << ": ClientInviteSession-onStaleCallTimeout" << endl;
00161       }
00162 
00163       virtual void onConnected(InviteSessionHandle, const SipMessage& msg)
00164       {
00165          cout << name << ": InviteSession-onConnected - " << msg.brief() << endl;
00166       }
00167 
00168       virtual void onRedirected(ClientInviteSessionHandle, const SipMessage& msg)
00169       {
00170          cout << name << ": ClientInviteSession-onRedirected - " << msg.brief() << endl;
00171       }
00172 
00173       virtual void onTerminated(InviteSessionHandle, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
00174       {
00175          cout << name << ": InviteSession-onTerminated - " << msg->brief() << endl;
00176          assert(0); // This is overrideen in UAS and UAC specific handlers
00177       }
00178 
00179       virtual void onAnswer(InviteSessionHandle, const SipMessage& msg, const SdpContents& sdp)
00180       {
00181          cout << name << ": InviteSession-onAnswer(SDP)" << endl;
00182          //sdp->encode(cout);
00183       }
00184 
00185       virtual void onOffer(InviteSessionHandle is, const SipMessage& msg, const SdpContents& sdp)      
00186       {
00187          cout << name << ": InviteSession-onOffer(SDP)" << endl;
00188          //sdp->encode(cout);
00189       }
00190 
00191       virtual void onEarlyMedia(ClientInviteSessionHandle, const SipMessage& msg, const SdpContents& sdp)
00192       {
00193          cout << name << ": InviteSession-onEarlyMedia(SDP)" << endl;
00194          //sdp->encode(cout);
00195       }
00196 
00197       virtual void onOfferRequired(InviteSessionHandle, const SipMessage& msg)
00198       {
00199          cout << name << ": InviteSession-onOfferRequired - " << msg.brief() << endl;
00200       }
00201 
00202       virtual void onOfferRejected(InviteSessionHandle, const SipMessage* msg)
00203       {
00204          cout << name << ": InviteSession-onOfferRejected" << endl;
00205       }
00206 
00207       virtual void onRefer(InviteSessionHandle, ServerSubscriptionHandle, const SipMessage& msg)
00208       {
00209          cout << name << ": InviteSession-onRefer - " << msg.brief() << endl;
00210       }
00211 
00212       virtual void onReferAccepted(InviteSessionHandle, ClientSubscriptionHandle, const SipMessage& msg)
00213       {
00214          cout << name << ": InviteSession-onReferAccepted - " << msg.brief() << endl;
00215       }
00216 
00217       virtual void onReferRejected(InviteSessionHandle, const SipMessage& msg)
00218       {
00219          cout << name << ": InviteSession-onReferRejected - " << msg.brief() << endl;
00220       }
00221 
00222       virtual void onReferNoSub(InviteSessionHandle, const SipMessage& msg)
00223       {
00224          cout << name << ": InviteSession-onReferNoSub - " << msg.brief() << endl;
00225       }
00226 
00227       virtual void onInfo(InviteSessionHandle, const SipMessage& msg)
00228       {
00229          cout << name << ": InviteSession-onInfo - " << msg.brief() << endl;
00230       }
00231 
00232       virtual void onInfoSuccess(InviteSessionHandle, const SipMessage& msg)
00233       {
00234          cout << name << ": InviteSession-onInfoSuccess - " << msg.brief() << endl;
00235       }
00236 
00237       virtual void onInfoFailure(InviteSessionHandle, const SipMessage& msg)
00238       {
00239          cout << name << ": InviteSession-onInfoFailure - " << msg.brief() << endl;
00240       }
00241 
00242       virtual void onMessage(InviteSessionHandle, const SipMessage& msg)
00243       {
00244          cout << name << ": InviteSession-onMessage - " << msg.brief() << endl;
00245       }
00246 
00247       virtual void onMessageSuccess(InviteSessionHandle, const SipMessage& msg)
00248       {
00249          cout << name << ": InviteSession-onMessageSuccess - " << msg.brief() << endl;
00250       }
00251 
00252       virtual void onMessageFailure(InviteSessionHandle, const SipMessage& msg)
00253       {
00254          cout << name << ": InviteSession-onMessageFailure - " << msg.brief() << endl;
00255       }
00256 
00257       virtual void onForkDestroyed(ClientInviteSessionHandle)
00258           {
00259          cout << name << ": ClientInviteSession-onForkDestroyed" << endl;
00260           }
00261 
00262       // Out-of-Dialog Callbacks
00263       virtual void onSuccess(ClientOutOfDialogReqHandle, const SipMessage& successResponse)
00264       {
00265           cout << name << ": ClientOutOfDialogReq-onSuccess - " << successResponse.brief() << endl;
00266       }
00267       virtual void onFailure(ClientOutOfDialogReqHandle, const SipMessage& errorResponse)
00268       {
00269           cout << name << ": ClientOutOfDialogReq-onFailure - " << errorResponse.brief() << endl;
00270       }
00271       virtual void onReceivedRequest(ServerOutOfDialogReqHandle ood, const SipMessage& request)
00272       {
00273           cout << name << ": ServerOutOfDialogReq-onReceivedRequest - " << request.brief() << endl;
00274           // Add SDP to response here if required
00275           cout << name << ": Sending 200 response to OPTIONS." << endl;
00276           ood->send(ood->answerOptions());
00277       }
00278 };
00279 
00280 class TestUac : public TestInviteSessionHandler
00281 {
00282    public:
00283       bool done;
00284       SdpContents* mSdp;     
00285       HeaderFieldValue* hfv;      
00286       Data* txt;
00287       int mNumExpectedMessages;
00288 
00289       TestUac() 
00290          : TestInviteSessionHandler("UAC"), 
00291            done(false),
00292            mSdp(0),
00293            hfv(0),
00294            txt(0),
00295            mNumExpectedMessages(2)
00296       {
00297          txt = new Data("v=0\r\n"
00298                         "o=1900 369696545 369696545 IN IP4 192.168.2.15\r\n"
00299                         "s=X-Lite\r\n"
00300                         "c=IN IP4 192.168.2.15\r\n"
00301                         "t=0 0\r\n"
00302                         "m=audio 8000 RTP/AVP 8 3 98 97 101\r\n"
00303                         "a=rtpmap:8 pcma/8000\r\n"
00304                         "a=rtpmap:3 gsm/8000\r\n"
00305                         "a=rtpmap:98 iLBC\r\n"
00306                         "a=rtpmap:97 speex/8000\r\n"
00307                         "a=rtpmap:101 telephone-event/8000\r\n"
00308                         "a=fmtp:101 0-15\r\n");
00309          
00310          hfv = new HeaderFieldValue(txt->data(), (unsigned int)txt->size());
00311          Mime type("application", "sdp");
00312          mSdp = new SdpContents(*hfv, type);
00313       }
00314 
00315       virtual ~TestUac()
00316       {
00317          assert(mNumExpectedMessages == 0);
00318          delete mSdp;
00319          delete txt;
00320          delete hfv;
00321       }
00322 
00323       virtual void onOffer(InviteSessionHandle is, const SipMessage& msg, const SdpContents& sdp)      
00324       {
00325          cout << name << ": InviteSession-onOffer(SDP)" << endl;
00326          //sdp->encode(cout);
00327          is->provideAnswer(sdp);
00328       }
00329 
00330       using TestInviteSessionHandler::onConnected;
00331       virtual void onConnected(ClientInviteSessionHandle is, const SipMessage& msg)
00332       {
00333          cout << name << ": ClientInviteSession-onConnected - " << msg.brief() << endl;
00334          cout << "Connected now - requestingOffer from UAS" << endl;
00335          is->requestOffer();
00336 
00337          // At this point no NIT should have been sent
00338          assert(!is->getLastSentNITRequest());
00339 
00340          // Send a first MESSAGE from UAC with some contents (we use a fake PlainContents contents here for
00341          // simplicity)
00342          PlainContents contents("Hi there!!!");
00343          is->message(contents);
00344 
00345          // Immediately send another one, which will end up queued on the
00346          // InviteSession's NIT queue
00347          PlainContents contentsOther("Hi again!!!");
00348          is->message(contentsOther);
00349       }
00350 
00351       virtual void onMessageSuccess(InviteSessionHandle is, const SipMessage& msg)
00352       {
00353          cout << name << ": InviteSession-onMessageSuccess - " << msg.brief() << endl;
00354 
00355          assert(is->getLastSentNITRequest());
00356          PlainContents* pContents = dynamic_cast<PlainContents*>(is->getLastSentNITRequest()->getContents());
00357          assert(pContents != NULL);
00358 
00359          if(mNumExpectedMessages == 2)
00360          {
00361             assert(pContents->text() == Data("Hi there!!!"));
00362             mNumExpectedMessages--;
00363          }
00364          else if(mNumExpectedMessages == 1)
00365          {
00366             assert(pContents->text() == Data("Hi again!!!"));
00367             mNumExpectedMessages--;
00368          }
00369       }
00370 
00371       virtual void onInfo(InviteSessionHandle is, const SipMessage& msg)
00372       {
00373          cout << name << ": InviteSession-onInfo - " << msg.brief() << endl;
00374          is->acceptNIT();
00375       }
00376 
00377       virtual void onTerminated(InviteSessionHandle, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
00378       {
00379          if(msg)
00380          {
00381             cout << name << ": InviteSession-onTerminated - " << msg->brief() << endl;
00382          }
00383          else
00384          {
00385             cout << name << ": InviteSession-onTerminated" << endl;
00386          }
00387          done = true;
00388       }
00389 };
00390 
00391 class TestUas : public TestInviteSessionHandler
00392 {
00393 
00394    public:
00395       bool done;
00396       bool requestedOffer;
00397       time_t* pHangupAt;
00398 
00399       SdpContents* mSdp;
00400       HeaderFieldValue* hfv;
00401       Data* txt;      
00402 
00403       int mNumExpectedInfos;
00404 
00405       TestUas(time_t* pH) 
00406          : TestInviteSessionHandler("UAS"), 
00407            done(false),
00408            requestedOffer(false),
00409            pHangupAt(pH),
00410            hfv(0),
00411            mNumExpectedInfos(2)
00412       { 
00413          txt = new Data("v=0\r\n"
00414                         "o=1900 369696545 369696545 IN IP4 192.168.2.15\r\n"
00415                         "s=X-Lite\r\n"
00416                         "c=IN IP4 192.168.2.15\r\n"
00417                         "t=0 0\r\n"
00418                         "m=audio 8001 RTP/AVP 8 3 98 97 101\r\n"
00419                         "a=rtpmap:8 pcma/8000\r\n"
00420                         "a=rtpmap:3 gsm/8000\r\n"
00421                         "a=rtpmap:98 iLBC\r\n"
00422                         "a=rtpmap:97 speex/8000\r\n"
00423                         "a=rtpmap:101 telephone-event/8000\r\n"
00424                         "a=fmtp:101 0-15\r\n");
00425          
00426          hfv = new HeaderFieldValue(txt->data(), (unsigned int)txt->size());
00427          Mime type("application", "sdp");
00428          mSdp = new SdpContents(*hfv, type);
00429       }
00430 
00431       ~TestUas()
00432       {
00433          assert(mNumExpectedInfos == 0);
00434          delete mSdp;
00435          delete txt;
00436          delete hfv;
00437       }
00438 
00439       using TestInviteSessionHandler::onNewSession;
00440       virtual void 
00441       onNewSession(ServerInviteSessionHandle sis, InviteSession::OfferAnswerType oat, const SipMessage& msg)
00442       {
00443          cout << name << ": ServerInviteSession-onNewSession - " << msg.brief() << endl;
00444          cout << name << ": Sending 180 response." << endl;
00445          mSis = sis;         
00446          sis->provisional(180);
00447       }
00448 
00449       virtual void onTerminated(InviteSessionHandle, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg)
00450       {
00451          cout << name << ": InviteSession-onTerminated - " << endl;
00452          done = true;
00453       }
00454 
00455       virtual void onOffer(InviteSessionHandle is, const SipMessage& msg, const SdpContents& sdp)      
00456       {
00457          cout << name << ": InviteSession-onOffer(SDP)" << endl;
00458          //sdp->encode(cout);
00459          cout << name << ": Sending 200 response with SDP answer." << endl;
00460          is->provideAnswer(sdp);
00461          mSis->accept();
00462       }
00463 
00464       virtual void onOfferRequired(InviteSessionHandle is, const SipMessage& msg)
00465       {
00466          cout << name << ": InviteSession-onOfferRequired - " << msg.brief() << endl;
00467          is->provideOffer(*mSdp);
00468       }
00469 
00470       virtual void onConnected(InviteSessionHandle is, const SipMessage& msg)
00471       {
00472          cout << name << ": InviteSession-onConnected - " << msg.brief() << endl;
00473          
00474          // At this point no NIT should have been sent
00475          assert(!is->getLastSentNITRequest());
00476 
00477          // Send a first INFO from UAS with some contents (we use a fake PlainContents contents here for
00478          // simplicity)
00479          PlainContents contents("Hello there!!!");
00480          is->info(contents);
00481 
00482          // Immediately send another one, which will end up queued on the
00483          // InviteSession's NIT queue
00484          PlainContents contentsOther("Hello again!!!");
00485          is->info(contentsOther);
00486       }
00487 
00488       virtual void onInfoSuccess(InviteSessionHandle is, const SipMessage& msg)
00489       {
00490          cout << name << ": InviteSession-onInfoSuccess - " << msg.brief() << endl;
00491 
00492          assert(is->getLastSentNITRequest());
00493          PlainContents* pContents = dynamic_cast<PlainContents*>(is->getLastSentNITRequest()->getContents());
00494          assert(pContents != NULL);
00495 
00496          if(mNumExpectedInfos == 2)
00497          {
00498             assert(pContents->text() == Data("Hello there!!!"));
00499             mNumExpectedInfos--;
00500          }
00501          else if(mNumExpectedInfos == 1)
00502          {
00503             assert(pContents->text() == Data("Hello again!!!"));
00504             mNumExpectedInfos--;
00505 
00506             // Schedule a BYE in 5 seconds
00507             if(*pHangupAt == 0)
00508             {
00509                *pHangupAt = time(NULL) + 5;
00510             }
00511          }
00512       }
00513 
00514       virtual void onMessage(InviteSessionHandle is, const SipMessage& msg)
00515       {
00516          cout << name << ": InviteSession-onMessage - " << msg.brief() << endl;
00517 
00518          is->acceptNIT();
00519       }
00520 
00521       // Normal people wouldn't put this functionality in the handler
00522       // it's a kludge for this test for right now
00523       void hangup()
00524       {
00525          if (mSis.isValid())
00526          {
00527             cout << name << ": Sending BYE." << endl;
00528             mSis->end();
00529             done = true;
00530          }
00531       }
00532    private:
00533       ServerInviteSessionHandle mSis;      
00534 };
00535 
00536 class TestShutdownHandler : public DumShutdownHandler
00537 {
00538    public:
00539       TestShutdownHandler(const Data& n) : name(n), dumShutDown(false) { }
00540       virtual ~TestShutdownHandler(){}
00541 
00542       Data name;
00543       bool dumShutDown;
00544       virtual void onDumCanBeDeleted() 
00545       {
00546          cout << name << ": onDumCanBeDeleted." << endl;
00547          dumShutDown = true;
00548       }
00549 };
00550 
00551 
00552 int 
00553 main (int argc, char** argv)
00554 {
00555    //Log::initialize(Log::Cout, resip::Log::Warning, argv[0]);
00556    //Log::initialize(Log::Cout, resip::Log::Debug, argv[0]);
00557    Log::initialize(Log::Cout, resip::Log::Info, argv[0]);
00558    //Log::initialize(Log::Cout, resip::Log::Debug, argv[0]);
00559 
00560 #if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) 
00561    FindMemoryLeaks fml;
00562    {
00563 #endif
00564    bool doReg = false;
00565    NameAddr uacAor;
00566    NameAddr uasAor;
00567    Data uacPasswd;
00568    Data uasPasswd;
00569    bool useOutbound = false;
00570    Uri outboundUri;
00571 
00572    if ( argc == 1 ) 
00573    {
00574       uacAor = NameAddr("sip:UAC@127.0.0.1:12005");
00575       uasAor = NameAddr("sip:UAS@127.0.0.1:12010");
00576       cout << "Skipping registration (no arguments)." << endl;
00577    } 
00578    else 
00579    {
00580       if ( argc < 5 ) 
00581       {
00582          cout << "usage: " << argv[0] <<
00583                  " sip:user1 passwd1 sip:user2 passwd2 [outbound]" << endl;
00584          return 1;
00585       }
00586       doReg = true;
00587       uacAor = NameAddr(argv[1]);
00588       uacPasswd = Data(argv[2]);
00589       uasAor = NameAddr(argv[3]);
00590       uasPasswd = Data(argv[4]);
00591       if ( argc >= 6 ) 
00592       {
00593          useOutbound = true;
00594          outboundUri = Uri(Data(argv[5]));
00595       }
00596    }
00597 
00598    //set up UAC
00599    SipStack stackUac;
00600    DialogUsageManager* dumUac = new DialogUsageManager(stackUac);
00601    dumUac->addTransport(UDP, 12005);
00602    dumUac->addTransport(TCP, 12005);
00603 
00604    SharedPtr<MasterProfile> uacMasterProfile(new MasterProfile);
00605    auto_ptr<ClientAuthManager> uacAuth(new ClientAuthManager);
00606    dumUac->setMasterProfile(uacMasterProfile);
00607    dumUac->setClientAuthManager(uacAuth);
00608 
00609    TestUac uac;
00610    dumUac->setInviteSessionHandler(&uac);
00611    dumUac->setClientRegistrationHandler(&uac);
00612    dumUac->addOutOfDialogHandler(OPTIONS, &uac);
00613 
00614    auto_ptr<AppDialogSetFactory> uac_dsf(new testAppDialogSetFactory);
00615    dumUac->setAppDialogSetFactory(uac_dsf);
00616 
00617    if ( doReg ) 
00618    {
00619       dumUac->getMasterProfile()->setDigestCredential(uacAor.uri().host(), uacAor.uri().user(), uacPasswd);
00620    }
00621    if (useOutbound) 
00622    {
00623        dumUac->getMasterProfile()->setOutboundProxy(outboundUri);
00624        dumUac->getMasterProfile()->addSupportedOptionTag(Token(Symbols::Outbound));
00625    }
00626 
00627    dumUac->getMasterProfile()->setDefaultFrom(uacAor);
00628    dumUac->getMasterProfile()->addSupportedMethod(INFO);
00629    dumUac->getMasterProfile()->addSupportedMethod(MESSAGE);
00630    dumUac->getMasterProfile()->addSupportedMimeType(INFO, PlainContents::getStaticType());
00631    dumUac->getMasterProfile()->addSupportedMimeType(MESSAGE, PlainContents::getStaticType());
00632    dumUac->getMasterProfile()->setDefaultRegistrationTime(70);
00633 
00634    //set up UAS
00635    SipStack stackUas;
00636    DialogUsageManager* dumUas = new DialogUsageManager(stackUas);
00637    dumUas->addTransport(UDP, 12010);
00638    dumUas->addTransport(TCP, 12010);
00639    
00640    SharedPtr<MasterProfile> uasMasterProfile(new MasterProfile);
00641    std::auto_ptr<ClientAuthManager> uasAuth(new ClientAuthManager);
00642    dumUas->setMasterProfile(uasMasterProfile);
00643    dumUas->setClientAuthManager(uasAuth);
00644 
00645    if(doReg) 
00646    {
00647       dumUas->getMasterProfile()->setDigestCredential(uasAor.uri().host(), uasAor.uri().user(), uasPasswd);
00648    }
00649    if(useOutbound) 
00650    {
00651       dumUas->getMasterProfile()->setOutboundProxy(outboundUri);
00652       dumUas->getMasterProfile()->addSupportedOptionTag(Token(Symbols::Outbound));
00653    }
00654 
00655    dumUas->getMasterProfile()->setDefaultFrom(uasAor);
00656    dumUas->getMasterProfile()->addSupportedMethod(INFO);
00657    dumUas->getMasterProfile()->addSupportedMethod(MESSAGE);
00658    dumUas->getMasterProfile()->addSupportedMimeType(INFO, PlainContents::getStaticType());
00659    dumUas->getMasterProfile()->addSupportedMimeType(MESSAGE, PlainContents::getStaticType());
00660    dumUas->getMasterProfile()->setDefaultRegistrationTime(70);
00661 
00662    time_t bHangupAt = 0;
00663    TestUas uas(&bHangupAt);
00664    dumUas->setClientRegistrationHandler(&uas);
00665    dumUas->setInviteSessionHandler(&uas);
00666    dumUas->addOutOfDialogHandler(OPTIONS, &uas);
00667 
00668    auto_ptr<AppDialogSetFactory> uas_dsf(new testAppDialogSetFactory);
00669    dumUas->setAppDialogSetFactory(uas_dsf);
00670 
00671    if (doReg) 
00672    {
00673       SharedPtr<SipMessage> regMessage = dumUas->makeRegistration(uasAor, new testAppDialogSet(*dumUac, "UAS(Registration)"));
00674       cout << "Sending register for Uas: " << endl << regMessage << endl;
00675       dumUas->send(regMessage);
00676    } 
00677    else 
00678    {
00679       uas.registered = true;
00680    }
00681    if (doReg) 
00682    {
00683       SharedPtr<SipMessage> regMessage = dumUac->makeRegistration(uacAor, new testAppDialogSet(*dumUac, "UAC(Registration)"));
00684       cout << "Sending register for Uac: " << endl << regMessage << endl;
00685       dumUac->send(regMessage);
00686    } 
00687    else 
00688    {
00689       uac.registered = true;
00690    }
00691 
00692    bool finishedTest = false;
00693    bool stoppedRegistering = false;
00694    bool startedCallFlow = false;
00695    bool hungup = false;   
00696    TestShutdownHandler uasShutdownHandler("UAS");   
00697    TestShutdownHandler uacShutdownHandler("UAC");   
00698 
00699    while (!(uasShutdownHandler.dumShutDown && uacShutdownHandler.dumShutDown))
00700    {
00701      if (!uacShutdownHandler.dumShutDown)
00702      {
00703         stackUac.process(50);
00704         while(dumUac->process());
00705      }
00706      if (!uasShutdownHandler.dumShutDown)
00707      {
00708         stackUas.process(50);
00709         while(dumUas->process());
00710      }
00711 
00712      if (!(uas.done && uac.done))
00713      {
00714         if (uas.registered && uac.registered && !startedCallFlow)
00715         {
00716            if (!startedCallFlow)
00717            {
00718               startedCallFlow = true;
00719               if ( doReg ) {
00720                  cout << "!!!!!!!!!!!!!!!! Registered !!!!!!!!!!!!!!!! " << endl;
00721               }
00722 
00723               // Kick off call flow by sending an OPTIONS request then an INVITE request from the UAC to the UAS
00724               cout << "UAC: Sending Options Request to UAS." << endl;
00725               dumUac->send(dumUac->makeOutOfDialogRequest(uasAor, OPTIONS, new testAppDialogSet(*dumUac, "UAC(OPTIONS)")));  // Should probably add Allow, Accept, Accept-Encoding, Accept-Language and Supported headers - but this is fine for testing/demonstration
00726 
00727               cout << "UAC: Sending Invite Request to UAS." << endl;
00728               dumUac->send(dumUac->makeInviteSession(uasAor, uac.mSdp, new testAppDialogSet(*dumUac, "UAC(INVITE)")));
00729            }
00730         }
00731 
00732         // Check if we should hangup yet
00733         if (bHangupAt!=0)
00734         {
00735            if (time(NULL)>bHangupAt && !hungup)
00736            {
00737               hungup = true;
00738               uas.hangup();
00739            }
00740         }
00741      }
00742      else
00743      {
00744         if (!stoppedRegistering)
00745         {
00746            finishedTest = true;
00747            stoppedRegistering = true;
00748            dumUas->shutdown(&uasShutdownHandler);
00749            dumUac->shutdown(&uacShutdownHandler);
00750             if ( doReg ) 
00751             {
00752               uas.registerHandle->stopRegistering();
00753               uac.registerHandle->stopRegistering();
00754             }
00755         }
00756      }
00757    }
00758 
00759    // OK to delete DUM objects now
00760    delete dumUac; 
00761    delete dumUas;
00762 
00763    cout << "!!!!!!!!!!!!!!!!!! Successful !!!!!!!!!! " << endl;
00764 #if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) 
00765    }
00766 #endif
00767 
00768 }
00769 
00770 /* ====================================================================
00771  * The Vovida Software License, Version 1.0 
00772  * 
00773  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00774  * 
00775  * Redistribution and use in source and binary forms, with or without
00776  * modification, are permitted provided that the following conditions
00777  * are met:
00778  * 
00779  * 1. Redistributions of source code must retain the above copyright
00780  *    notice, this list of conditions and the following disclaimer.
00781  * 
00782  * 2. Redistributions in binary form must reproduce the above copyright
00783  *    notice, this list of conditions and the following disclaimer in
00784  *    the documentation and/or other materials provided with the
00785  *    distribution.
00786  * 
00787  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00788  *    and "Vovida Open Communication Application Library (VOCAL)" must
00789  *    not be used to endorse or promote products derived from this
00790  *    software without prior written permission. For written
00791  *    permission, please contact vocal@vovida.org.
00792  *
00793  * 4. Products derived from this software may not be called "VOCAL", nor
00794  *    may "VOCAL" appear in their name, without prior written
00795  *    permission of Vovida Networks, Inc.
00796  * 
00797  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00798  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00799  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00800  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00801  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00802  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00803  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00804  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00805  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00806  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00807  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00808  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00809  * DAMAGE.
00810  * 
00811  * ====================================================================
00812  * 
00813  * This software consists of voluntary contributions made by Vovida
00814  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00815  * Inc.  For more snformation on Vovida Networks, Inc., please see
00816  * <http://www.vovida.org/>.
00817  *
00818  */