< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index  

Re: [reSIProcate] windows updated vs.net files


Dear All, dear Klaus,

you can find in attachment basicCall.cxx and basicRegister.cxx. I build them with vs.net 2003 with SSL support. Into project file, I changed the option library runtime and I’m using DLL Multithread (/MD) (or debug version, /MDd) to avoid a linking problem due to openssl.

Into files, I’ve changed (you can find my changes looking for “ANDREA”):
- basicCall.cxx: using namespace std; and I defined a TestInviteSessionHandler:: onForkDestroyed;
-       basicRegister.cxx: using namespace std;

Now, I’m spending my time trying to understand DUM and SUBSCRIBE/NOTIFY mechanism. If anyone has suggestions or simple programs, you’re welcome!

andrea

Klaus Darilion wrote:


andy wrote:

...
in the next days I'll also check test program in winxp platform.


cool - I'm waiting eagerly.

reagards,
klaus




#include "resiprocate/SdpContents.hxx"
#include "resiprocate/SipMessage.hxx"
#include "resiprocate/ShutdownMessage.hxx"
#include "resiprocate/SipStack.hxx"
#include "resiprocate/dum/ClientAuthManager.hxx"
#include "resiprocate/dum/ClientInviteSession.hxx"
#include "resiprocate/dum/ClientRegistration.hxx"
#include "resiprocate/dum/DialogUsageManager.hxx"
#include "resiprocate/dum/DumShutdownHandler.hxx"
#include "resiprocate/dum/InviteSessionHandler.hxx"
#include "resiprocate/dum/Profile.hxx"
#include "resiprocate/dum/RegistrationHandler.hxx"
#include "resiprocate/dum/ServerInviteSession.hxx"
#include "resiprocate/dum/ServerOutOfDialogReq.hxx"
#include "resiprocate/dum/OutOfDialogHandler.hxx"
#include "resiprocate/dum/AppDialog.hxx"
#include "resiprocate/dum/AppDialogSet.hxx"
#include "resiprocate/dum/AppDialogSetFactory.hxx"
#include "resiprocate/os/Log.hxx"
#include "resiprocate/os/Logger.hxx"
#include "resiprocate/os/Random.hxx"

#include <sstream>
#include <time.h>

#define RESIPROCATE_SUBSYSTEM Subsystem::TEST

using namespace resip;

//andrea
using namespace std;

void sleepSeconds(unsigned int seconds)
{
#ifdef WIN32
   Sleep(seconds*1000);
#else
   sleep(seconds);
#endif
}

/////////////////////////////////////////////////////////////////////////////////
//
// Classes that provide the mapping between Application Data and DUM 
// dialogs/dialogsets
//                                                                              
// The DUM layer creates an AppDialog/AppDialogSet object for inbound/outbound
// SIP Request that results in Dialog creation.
//                                                                              
/////////////////////////////////////////////////////////////////////////////////
class testAppDialog : public AppDialog
{
public:
   testAppDialog(HandleManager& ham, Data &SampleAppData) : AppDialog(ham), 
mSampleAppData(SampleAppData)
   {  cout << mSampleAppData << ": testAppDialog: created." << endl;  }
   virtual ~testAppDialog() 
   { cout << mSampleAppData << ": testAppDialog: destroyed." << endl; }
   Data mSampleAppData;
};

class testAppDialogSet : public AppDialogSet
{
public:
   testAppDialogSet(DialogUsageManager& dum, Data SampleAppData) : 
AppDialogSet(dum), mSampleAppData(SampleAppData)
   {  cout << mSampleAppData << ": testAppDialogSet: created." << endl;  }
   virtual ~testAppDialogSet() 
   {  cout << mSampleAppData << ": testAppDialogSet: destroyed." << endl;  }
   virtual AppDialog* createAppDialog(const SipMessage& msg) 
   {  return new testAppDialog(mDum, mSampleAppData);  }
   Data mSampleAppData;
};

class testAppDialogSetFactory : public AppDialogSetFactory
{
public:
   virtual AppDialogSet* createAppDialogSet(DialogUsageManager& dum, const 
SipMessage& msg) 
   {  return new testAppDialogSet(dum, Data("UAS") + Data("(") + 
getMethodName(msg.header(h_RequestLine).getMethod()) + Data(")"));  }
   // For a UAS the testAppDialogSet will be created by DUM using this 
function.  If you want to set 
   // Application Data, then one approach is to wait for 
onNewSession(ServerInviteSessionHandle ...) 
   // to be called, then use the ServerInviteSessionHandle to get at the 
AppDialogSet or AppDialog,
   // then cast to your derived class and set the desired application data.
};


// Generic InviteSessionHandler
class TestInviteSessionHandler : public InviteSessionHandler, public 
ClientRegistrationHandler, public OutOfDialogHandler
{
   public:
      Data name;
      bool registered;
      ClientRegistrationHandle registerHandle;
      
      TestInviteSessionHandler(const Data& n) : name(n), registered(false) 
      {
      }

      virtual ~TestInviteSessionHandler()
      {
      }
      
      virtual void onSuccess(ClientRegistrationHandle h, const SipMessage& 
response)
      {         
         registerHandle = h;   
         assert(registerHandle.isValid());         
         cout << name << ": ClientRegistration-onSuccess - " << 
response.brief() << endl;
         registered = true;
      }

      virtual void onFailure(ClientRegistrationHandle, const SipMessage& msg)
      {
         cout << name << ": ClientRegistration-onFailure - " << msg.brief() << 
endl;
         throw;  // Ungracefully end
      }

      virtual void onRemoved(ClientRegistrationHandle)
      {
          cout << name << ": ClientRegistration-onRemoved" << endl;
      }

      virtual void onNewSession(ClientInviteSessionHandle, 
InviteSession::OfferAnswerType oat, const SipMessage& msg)
      {
         cout << name << ": ClientInviteSession-onNewSession - " << msg.brief() 
<< endl;
      }
      
      virtual void onNewSession(ServerInviteSessionHandle, 
InviteSession::OfferAnswerType oat, const SipMessage& msg)
      {
         cout << name << ": ServerInviteSession-onNewSession - " << msg.brief() 
<< endl;
      }

      virtual void onFailure(ClientInviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": ClientInviteSession-onFailure - " << msg.brief() << 
endl;
      }
      
      virtual void onProvisional(ClientInviteSessionHandle, const SipMessage& 
msg)
      {
         cout << name << ": ClientInviteSession-onProvisional - " << 
msg.brief() << endl;
      }

      virtual void onConnected(ClientInviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": ClientInviteSession-onConnected - " << msg.brief() 
<< endl;
      }

      virtual void onStaleCallTimeout(ClientInviteSessionHandle)
      {
         cout << name << ": ClientInviteSession-onStaleCallTimeout" << endl;
      }

      virtual void onConnected(InviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onConnected - " << msg.brief() << 
endl;
      }

      virtual void onRedirected(ClientInviteSessionHandle, const SipMessage& 
msg)
      {
         cout << name << ": ClientInviteSession-onRedirected - " << msg.brief() 
<< endl;
      }

      virtual void onTerminated(InviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onTerminated - " << msg.brief() << 
endl;
         assert(0); // This is overrideen in UAS and UAC specific handlers
      }

      virtual void onAnswer(InviteSessionHandle, const SipMessage& msg, const 
SdpContents*sdp)
      {
         cout << name << ": InviteSession-onAnswer(SDP)" << endl;
         //sdp->encode(cout);
      }

      virtual void onOffer(InviteSessionHandle is, const SipMessage& msg, const 
SdpContents*sdp)      
      {
         cout << name << ": InviteSession-onOffer(SDP)" << endl;
         //sdp->encode(cout);
      }

      virtual void onEarlyMedia(ClientInviteSessionHandle, const SipMessage& 
msg, const SdpContents*sdp)
      {
         cout << name << ": InviteSession-onEarlyMedia(SDP)" << endl;
         //sdp->encode(cout);
      }

      virtual void onOfferRequired(InviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onOfferRequired - " << msg.brief() << 
endl;
      }

      virtual void onOfferRejected(InviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onOfferRejected - " << msg.brief() << 
endl;
      }

      virtual void onDialogModified(InviteSessionHandle, 
InviteSession::OfferAnswerType oat, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onDialogModified - " << msg.brief() 
<< endl;
      }

      virtual void onInfo(InviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onInfo - " << msg.brief() << endl;
      }

      virtual void onRefer(InviteSessionHandle, ServerSubscriptionHandle, const 
SipMessage& msg)
      {
         cout << name << ": InviteSession-onRefer - " << msg.brief() << endl;
      }

      virtual void onReferRejected(InviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onReferRejected - " << msg.brief() << 
endl;
      }

      virtual void onInfoSuccess(InviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onInfoSuccess - " << msg.brief() << 
endl;
      }

      virtual void onInfoFailure(InviteSessionHandle, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onInfoFailure - " << msg.brief() << 
endl;
      }

      // Out-of-Dialog Callbacks
      virtual void onSuccess(ClientOutOfDialogReqHandle, const SipMessage& 
successResponse)
      {
          cout << name << ": ClientOutOfDialogReq-onSuccess - " << 
successResponse.brief() << endl;
      }
      virtual void onFailure(ClientOutOfDialogReqHandle, const SipMessage& 
errorResponse)
      {
          cout << name << ": ClientOutOfDialogReq-onFailure - " << 
errorResponse.brief() << endl;
      }
      virtual void onReceivedRequest(ServerOutOfDialogReqHandle ood, const 
SipMessage& request)
      {
          cout << name << ": ServerOutOfDialogReq-onReceivedRequest - " << 
request.brief() << endl;
          // Add SDP to response here if required
          cout << name << ": Sending 200 response to OPTIONS." << endl;
          ood->send(ood->answerOptions());
      }

      // ANDREA
      virtual void onForkDestroyed(ClientInviteSessionHandle) {
                        cout << name << ": onForkDestroyed\n";
                }

};

class TestUac : public TestInviteSessionHandler
{
   public:
      bool done;
      SdpContents* sdp;     
      HeaderFieldValue* hfv;      
      Data* txt;      

      TestUac() 
         : TestInviteSessionHandler("UAC"), 
           done(false),
           sdp(0),
           hfv(0),
           txt(0)
      {
         txt = new Data("v=0\r\n"
                        "o=1900 369696545 369696545 IN IP4 192.168.2.15\r\n"
                        "s=X-Lite\r\n"
                        "c=IN IP4 192.168.2.15\r\n"
                        "t=0 0\r\n"
                        "m=audio 8000 RTP/AVP 8 3 98 97 101\r\n"
                        "a=rtpmap:8 pcma/8000\r\n"
                        "a=rtpmap:3 gsm/8000\r\n"
                        "a=rtpmap:98 iLBC\r\n"
                        "a=rtpmap:97 speex/8000\r\n"
                        "a=rtpmap:101 telephone-event/8000\r\n"
                        "a=fmtp:101 0-15\r\n");
         
         hfv = new HeaderFieldValue(txt->data(), txt->size());
         Mime type("application", "sdp");
         sdp = new SdpContents(hfv, type);
      }

      virtual ~TestUac()
      {
         delete sdp;
      }

      virtual void onTerminated(InviteSessionHandle is, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onTerminated - " << msg.brief() << 
endl;
         done = true;
      }
};

class TestUas : public TestInviteSessionHandler
{

   public:
      bool done;
      time_t* pHangupAt;

      SdpContents* sdp;
      HeaderFieldValue* hfv;
      Data* txt;      

      TestUas(time_t* pH) 
         : TestInviteSessionHandler("UAS"), 
           done(false),
           pHangupAt(pH),
           hfv(0)
      { 
         pHangupAt = pHangupAt;

         txt = new Data("v=0\r\n"
                        "o=1900 369696545 369696545 IN IP4 192.168.2.15\r\n"
                        "s=X-Lite\r\n"
                        "c=IN IP4 192.168.2.15\r\n"
                        "t=0 0\r\n"
                        "m=audio 8001 RTP/AVP 8 3 98 97 101\r\n"
                        "a=rtpmap:8 pcma/8000\r\n"
                        "a=rtpmap:3 gsm/8000\r\n"
                        "a=rtpmap:98 iLBC\r\n"
                        "a=rtpmap:97 speex/8000\r\n"
                        "a=rtpmap:101 telephone-event/8000\r\n"
                        "a=fmtp:101 0-15\r\n");
         
         hfv = new HeaderFieldValue(txt->data(), txt->size());
         Mime type("application", "sdp");
         sdp = new SdpContents(hfv, type);
      }

      ~TestUas()
      {
         delete sdp;
      }

      virtual void 
      onNewSession(ServerInviteSessionHandle sis, 
InviteSession::OfferAnswerType oat, const SipMessage& msg)
      {
         cout << name << ": ServerInviteSession-onNewSession - " << msg.brief() 
<< endl;
         cout << name << ": Sending 180 response." << endl;
         mSis = sis;         
         sis->send(sis->provisional(180));
      }

      virtual void onTerminated(InviteSessionHandle is, const SipMessage& msg)
      {
         cout << name << ": InviteSession-onTerminated - " << msg.brief() << 
endl;
         done = true;
      }

      virtual void onOffer(InviteSessionHandle is, const SipMessage& msg, const 
SdpContents* sdp)      
      {
         cout << name << ": InviteSession-onOffer(SDP)" << endl;
         //sdp->encode(cout);
         cout << name << ": Sending 200 response with SDP answer." << endl;
         is->setAnswer(sdp);
         mSis->send(mSis->accept());
         *pHangupAt = time(NULL) + 5;
      }

      // Normal people wouldn't put this functionality in the handler
      // it's a kludge for this test for right now
      void hangup()
      {
         if (mSis.isValid())
         {
            cout << name << ": Sending BYE." << endl;
            mSis->end();
         }
      }
   private:
      ServerInviteSessionHandle mSis;      
};

class TestShutdownHandler : public DumShutdownHandler
{
   public:
      TestShutdownHandler(const Data& n) : name(n), dumShutDown(false) { }
      bool dumShutDown;
      Data name;
      virtual void onDumCanBeDeleted() 
      {
         cout << name << ": onDumCanBeDeleted." << endl;
         dumShutDown = true;
      }
};


#define NO_REGISTRATION 1
int 
main (int argc, char** argv)
{
   Log::initialize(Log::Cout, resip::Log::Warning, argv[0]);
   //Log::initialize(Log::Cout, resip::Log::Info, argv[0]);

   //set up UAC
   DialogUsageManager* dumUac = new DialogUsageManager();
   dumUac->addTransport(UDP, 12005);

   Profile uacProfile;      
   auto_ptr<ClientAuthManager> uacAuth(new ClientAuthManager(uacProfile));
   dumUac->setProfile(&uacProfile);
   dumUac->setClientAuthManager(uacAuth);

   TestUac uac;
   dumUac->setInviteSessionHandler(&uac);
   dumUac->setClientRegistrationHandler(&uac);
   dumUac->addOutOfDialogHandler(OPTIONS, &uac);

   auto_ptr<testAppDialogSetFactory> uac_dsf(new testAppDialogSetFactory);
   dumUac->setAppDialogSetFactory(uac_dsf);

#if !defined(NO_REGISTRATION)
   //your aor, credentials, etc here
   NameAddr uacAor("sip:101@xxxxxxx");
   dumUac->getProfile()->addDigestCredential( "foo.net", "derek@xxxxxxx", 
"pass6" );
   dumUac->getProfile()->setOutboundProxy(Uri("sip:209.134.58.33:9090"));    
#else
   NameAddr uacAor("sip:UAC@xxxxxxxxx:12005");
#endif

   dumUac->getProfile()->setDefaultFrom(uacAor);
   dumUac->getProfile()->setDefaultRegistrationTime(70);

   //set up UAS
   DialogUsageManager* dumUas = new DialogUsageManager();
   dumUas->addTransport(UDP, 12010);
   
   Profile uasProfile;   
   std::auto_ptr<ClientAuthManager> uasAuth(new ClientAuthManager(uasProfile));
   dumUas->setProfile(&uasProfile);
   dumUas->setClientAuthManager(uasAuth);

#if !defined(NO_REGISTRATION)
   //your aor, credentials, etc here
   NameAddr uasAor("sip:105@xxxxxxx");
   dumUas->getProfile()->addDigestCredential( "foo.net", "derek@xxxxxxx", 
"pass6" );
   dumUas->getProfile()->setOutboundProxy(Uri("sip:209.134.58.33:9090"));    
#else
   NameAddr uasAor("sip:UAS@xxxxxxxxx:12010");
#endif

   dumUas->getProfile()->setDefaultRegistrationTime(70);
   dumUas->getProfile()->setDefaultFrom(uasAor);

   time_t bHangupAt = 0;
   TestUas uas(&bHangupAt);
   dumUas->setClientRegistrationHandler(&uas);
   dumUas->setInviteSessionHandler(&uas);
   dumUas->addOutOfDialogHandler(OPTIONS, &uas);

   auto_ptr<testAppDialogSetFactory> uas_dsf(new testAppDialogSetFactory);
   dumUas->setAppDialogSetFactory(uas_dsf);

#if !defined(NO_REGISTRATION)
   {
      SipMessage& regMessage = dumUas->makeRegistration(uasAor, new 
testAppDialogSet(*dumUac, "UAS(Registration)"));
      cout << "Sending register for Uas: " << endl << regMessage << endl;
      dumUas->send(regMessage);
   }
   {
      SipMessage& regMessage = dumUac->makeRegistration(uacAor, new 
testAppDialogSet(*dumUac, "UAS(Registration)"));
      cout << "Sending register for Uac: " << endl << regMessage << endl;
      dumUac->send(regMessage);
   }
#else
   uac.registered = true;
   uas.registered = true;
#endif

   bool finishedTest = false;
   bool stoppedRegistering = false;
   bool startedCallFlow = false;
   bool hungup = false;   
   TestShutdownHandler uasShutdownHandler("UAS");   
   TestShutdownHandler uacShutdownHandler("UAC");   

   while (!(uasShutdownHandler.dumShutDown && uacShutdownHandler.dumShutDown))
   {
     if (!uacShutdownHandler.dumShutDown)
     {
        FdSet fdset;
        dumUac->buildFdSet(fdset);
        int err = fdset.selectMilliSeconds(dumUac->getTimeTillNextProcessMS());
        assert ( err != -1 );
        dumUac->process(fdset);
     }
     if (!uasShutdownHandler.dumShutDown)
     {
        FdSet fdset;
        dumUas->buildFdSet(fdset);
        int err = fdset.selectMilliSeconds(dumUas->getTimeTillNextProcessMS());
        assert ( err != -1 );
        dumUas->process(fdset);
     }

     if (!(uas.done && uac.done))
     {
        if (uas.registered && uac.registered && !startedCallFlow)
        {
           if (!startedCallFlow)
           {
              startedCallFlow = true;
#if !defined(NO_REGISTRATION)
              cout << "!!!!!!!!!!!!!!!! Registered !!!!!!!!!!!!!!!! " << endl;
#endif

              // Kick off call flow by sending an OPTIONS request then an 
INVITE request from the UAC to the UAS
              cout << "UAC: Sending Options Request to UAS." << endl;
                          dumUac->send(dumUac->makeOutOfDialogRequest(uasAor, 
uacAor, 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

              cout << "UAC: Sending Invite Request to UAS." << endl;
              dumUac->send(dumUac->makeInviteSession(uasAor, uacAor, uac.sdp, 
new testAppDialogSet(*dumUac, "UAC(INVITE)")));
           }
        }

        // Check if we should hangup yet
        if (bHangupAt!=0)
        {
           if (time(NULL)>bHangupAt && !hungup)
           {
              hungup = true;
              uas.hangup();
           }
        }
     }
     else
     {
        if (!stoppedRegistering)
        {
           finishedTest = true;
           stoppedRegistering = true;
           dumUas->shutdown(&uasShutdownHandler);
           dumUac->shutdown(&uacShutdownHandler);
#if !defined(NO_REGISTRATION)
           uas.registerHandle->stopRegistering();
           uac.registerHandle->stopRegistering();
#endif
        }
     }
   }

   // OK to delete DUM objects now
   delete dumUac; 
   delete dumUas;

   cout << "!!!!!!!!!!!!!!!!!! Successful !!!!!!!!!! " << endl;
}
#include "resiprocate/SipStack.hxx"
#include "resiprocate/dum/ClientAuthManager.hxx"
#include "resiprocate/dum/ClientRegistration.hxx"
#include "resiprocate/dum/DialogUsageManager.hxx"
#include "resiprocate/dum/InviteSessionHandler.hxx"
#include "resiprocate/dum/Profile.hxx"
#include "resiprocate/dum/RegistrationHandler.hxx"
#include "resiprocate/os/Log.hxx"
#include "resiprocate/os/Logger.hxx"
#include "resiprocate/os/Subsystem.hxx"
#include "resiprocate/dum/AppDialogSet.hxx"
#include "resiprocate/dum/AppDialog.hxx"


#define RESIPROCATE_SUBSYSTEM Subsystem::TEST

using namespace resip;
// ANDREA
using namespace std;

class RegisterAppDialogSet : public AppDialogSet
{
   public:
      RegisterAppDialogSet(DialogUsageManager& dum) : AppDialogSet(dum) 
      {}      
};

   

class Client : public ClientRegistrationHandler
{
   public:
      Client() : done(false), removing(true) {}

      virtual void onSuccess(ClientRegistrationHandle h, const SipMessage& 
response)
      {
          InfoLog( << "Client::Success: " << endl << response );
          if (removing)
          {
             removing = false;             
#ifdef WIN32
         Sleep(2000);
#else
         sleep(5);
#endif
         ClientRegistration* foo = h.get();          
          h->removeAll();
          }
          else
          {             
             done = true;
          }          
      }

      virtual void onRemoved(ClientRegistrationHandle)
      {
          InfoLog ( << "Client::onRemoved ");
      }

      virtual void onFailure(ClientRegistrationHandle, const SipMessage& 
response)
      {
          InfoLog ( << "Client::onFailure: " << response );
          done = true;
      }

      bool done;
      bool removing;      
};

/*
class RegistrationServer : public ServerRegistrationHandler
{
   public:
      RegistrationServer() : done(false) {}
      virtual void onRefresh(ServerRegistrationHandle, const SipMessage& reg)=0;
      
      /// called when one of the contacts is removed
      virtual void onRemoveOne(ServerRegistrationHandle, const SipMessage& 
reg)=0;
      
      /// Called when all the contacts are removed 
      virtual void onRemoveAll(ServerRegistrationHandle, const SipMessage& 
reg)=0;
      
      /// Called when a new contact is added. This is after authentication has
      /// all sucseeded
      virtual void onAdd(ServerRegistrationHandle, const SipMessage& reg)=0;

      /// Called when an registration expires 
      virtual void onExpired(ServerRegistrationHandle, const NameAddr& 
contact)=0;
   private:
      bool done;
};
*/

int 
main (int argc, char** argv)
{
   int level=(int)Log::Info;
   if (argc >1 ) level = atoi(argv[1]);

   Log::initialize(Log::Cout, (resip::Log::Level)level, argv[0]);

   Client client;
   Profile profile;   
   auto_ptr<ClientAuthManager> clientAuth(new ClientAuthManager(profile));   

   DialogUsageManager clientDum;
   clientDum.addTransport(UDP, 15060);
   clientDum.setProfile(&profile);

   clientDum.setClientRegistrationHandler(&client);
   clientDum.setClientAuthManager(clientAuth);
   clientDum.getProfile()->setDefaultRegistrationTime(70);

   NameAddr from("sip:101@xxxxxxxxxxxxxxxxxxxxxxx");
   clientDum.getProfile()->setDefaultFrom(from);


//   profile.addDigestCredential( "xten.gloo.net", "derek@xxxxxxxxxxxxx", 
"123456" );
//   profile.addDigestCredential( "sphone.vopr.vonage.net", "13015604286", "" );

   SipMessage & regMessage = clientDum.makeRegistration(from, new 
RegisterAppDialogSet(clientDum));
   NameAddr contact;
//   contact.uri().user() = "13015604286";   
//   regMessage.header(h_Contacts).push_back(contact);   

   InfoLog( << regMessage << "Generated register: " << endl << regMessage );
   clientDum.send( regMessage );

   int n = 0;
   while ( !client.done )

   {
     FdSet fdset;

     // Should these be buildFdSet on the DUM?
     clientDum.buildFdSet(fdset);
     int err = fdset.selectMilliSeconds(100);
     assert ( err != -1 );

     clientDum.process(fdset);
     if (!(n++ % 10)) cerr << "|/-\\"[(n/10)%4] << '\b';

   }   
   return 0;
}