void testConstructor()
      {
         /*
          * This test exists to initialize the singleton plugin.
          * Doing it as a static ran into ordering problems.
          */
         CPPUNIT_ASSERT((xferctl=dynamic_cast<MSFT_ExchangeTransferHack*>(getAuthPlugin("msft"))));

         OsConfigDb xferConfigDb;
         xferConfigDb.set(MSFT_ExchangeTransferHack::RecognizerConfigKey, "^RTCC/");
         xferctl->readConfig(xferConfigDb);

         testUserAgent.setIsUserAgent(FALSE);

         testUserAgent.setUserAgentHeaderProperty("sipXecs/testproxy");

         testUserAgent.setForking(FALSE);  // Disable forking

         OsConfigDb configDb;
         configDb.set("SIPX_PROXY_AUTHENTICATE_ALGORITHM", "MD5");
         configDb.set("SIPX_PROXY_HOSTPORT", "sipx.example.edu");

         testSipRouter = new SipRouter(testUserAgent, mForwardingRules, configDb);
         xferctl->announceAssociatedSipRouter( testSipRouter );
      }
   void setUp()
      {
         hostIp = "127.0.0.1";

         eventName = SIP_EVENT_MESSAGE_SUMMARY;
         mwiMimeType = CONTENT_TYPE_SIMPLE_MESSAGE_SUMMARY;;

         // Construct a user agent that will function both as the subscriber
         // and the notfier.
         // Construct the URI of the notifier, which is also the URI of
         // the subscriber.
         // Also construct the name-addr version of the URI, which may be
         // different if it has a "transport" parameter.
         // And the resource-id to use, which is the AOR with any
         // parameters stripped off.

         createTestSipUserAgent(hostIp,
                                "111",
                                userAgentp,
                                aor,
                                aor_name_addr,
                                aor_contact_name_addr,
                                resource_id);

         subServerp =
            SipSubscribeServer::buildBasicServer(*userAgentp,
                                                 eventName);
         subServerp->start();

         // Get pointers to the Subscription Manager and Dialog Manager.
         subMgrp = subServerp->getSubscriptionMgr(eventName);
         CPPUNIT_ASSERT(subMgrp);
         dialogMgrp = subMgrp->getDialogMgr();
         CPPUNIT_ASSERT(dialogMgrp);

         // Create a simple Subscription client
         // Register an interest in SUBSCRIBE responses and NOTIFY requests
         // for this event type
         userAgentp->addMessageObserver(incomingClientMsgQueue,
                                        SIP_SUBSCRIBE_METHOD,
                                        FALSE, // no requests
                                        TRUE, // reponses
                                        TRUE, // incoming
                                        FALSE, // no outgoing
                                        eventName,
                                        NULL,
                                        NULL);
         userAgentp->addMessageObserver(incomingClientMsgQueue,
                                        SIP_NOTIFY_METHOD,
                                        TRUE, // requests
                                        FALSE, // not reponses
                                        TRUE, // incoming
                                        FALSE, // no outgoing
                                        eventName,
                                        NULL,
                                        NULL);
      }
示例#3
0
SipConfigServerAgent* SipConfigServerAgent::startAgents(const char* configFileName)
{
    int sipTcpPort;
    int sipUdpPort;
    int sipTlsPort;
    OsConfigDb configDb;

    if(configDb.loadFromFile(configFileName) == OS_SUCCESS)
    {
      osPrintf("Found config file: %s\n", configFileName);
    }
    else
    {
        configDb.set("SIP_SDS_UDP_PORT", "5090");
        configDb.set("SIP_SDS_TCP_PORT", "5090");
        configDb.set("SIP_SDS_TLS_PORT", "5091");
        configDb.set(CONFIG_SETTING_LOG_DIR, "");
        configDb.set(CONFIG_SETTING_LOG_LEVEL, "");
        configDb.set(CONFIG_SETTING_LOG_CONSOLE, "");

        if (configDb.storeToFile(configFileName) != OS_SUCCESS)
                      osPrintf("Could not store config file: %s\n", configFileName);
    }
    
    sipTcpPort = configDb.getPort("SIP_SDS_UDP_PORT") ;
    sipUdpPort = configDb.getPort("SIP_SDS_TCP_PORT") ;
    sipTlsPort = configDb.getPort("SIP_SDS_TLS_PORT") ;

    // Start the sip stack
    SipUserAgent* pAgent = new SipUserAgent(sipTcpPort,
        sipUdpPort,   
        sipTlsPort,
        NULL, // public IP address (nopt used in proxy)
        NULL, // default user (not used in proxy)
        NULL, // default SIP address (not used in proxy)
        NULL, // outbound proxy
        NULL, // directory server
        NULL, // registry server
        NULL, // auth scheme
        NULL, //auth realm
        NULL, // auth DB
        NULL, // auth user IDs
        NULL, // auth passwords
        NULL, // line mgr
        SIP_DEFAULT_RTT, // first resend timeout
        TRUE, // default to UA transaction
        SIPUA_DEFAULT_SERVER_UDP_BUFFER_SIZE, // socket layer read buffer size
        SIPUA_DEFAULT_SERVER_OSMSG_QUEUE_SIZE // OsServerTask message queue size
        );
    pAgent->start();

    // Start the SipConfigServerAgent
    SipConfigServerAgent* pConfigAgent = new SipConfigServerAgent(pAgent) ;
    pConfigAgent->start() ;

    return(pConfigAgent);
}
   void tearDown()
      {
         // Clean up to prevent use of the queue after it goes out of scope.
         userAgentp->removeMessageObserver(incomingClientMsgQueue);
         userAgentp->removeMessageObserver(incomingClientMsgQueue);

         OsTask::delay(1000);

         userAgentp->shutdown(TRUE);
         delete userAgentp;

         delete subServerp;
      }
   void setUp()
      {
         // Construct a SipUserAgent to provide the isMyHostAlias recognizer

         UserAgent = new SipUserAgent(0, 0, -1);

         UtlString internalDomainAlias("example.com:5060");
         UserAgent->setHostAliases(internalDomainAlias);

         UtlString internalHostAlias("internal.example.com:5060");
         UserAgent->setHostAliases(internalHostAlias);

         UtlString externalAlias("external.example.net:5060");
         UserAgent->setHostAliases(externalAlias);
      }
示例#6
0
    void testOnOffHook()
    {
        PsMsg *keyMsg;
        SipUserAgent *ua = CpTestSupport::newSipUserAgent();
        ua->start();
        CallManager *callmgr = CpTestSupport::newCallManager(ua);
        callmgr->start();

        keyMsg = new PsMsg(PsMsg::HOOKSW_STATE, NULL, PsHookswTask::OFF_HOOK, 0);
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        keyMsg = new PsMsg(PsMsg::BUTTON_DOWN, NULL, 0, '1');
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        keyMsg = new PsMsg(PsMsg::BUTTON_UP, NULL, 0, '1');
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        keyMsg = new PsMsg(PsMsg::BUTTON_DOWN, NULL, 0, '0');
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        keyMsg = new PsMsg(PsMsg::BUTTON_UP, NULL, 0, '0');
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        keyMsg = new PsMsg(PsMsg::BUTTON_DOWN, NULL, 0, '0');
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        keyMsg = new PsMsg(PsMsg::BUTTON_UP, NULL, 0, '0');
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        keyMsg = new PsMsg(PsMsg::BUTTON_DOWN, NULL, 0, '4');
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        keyMsg = new PsMsg(PsMsg::BUTTON_UP, NULL, 0, '4');
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        delete callmgr;
        delete ua;
    }
示例#7
0
    void testPickupCall()
    {
        PsMsg *keyMsg;
        SipUserAgent *ua = CpTestSupport::newSipUserAgent();
        ua->start();
        CallManager *callmgr = CpTestSupport::newCallManager(ua);
        callmgr->start();

        // Wait a little and pick up the hook assuming it is ringing
        OsTask::delay(30000);
        printf("Picking up ringing phone\n");

        keyMsg = new PsMsg(PsMsg::HOOKSW_STATE, NULL, PsHookswTask::OFF_HOOK, 0);
        callmgr->postMessage(*keyMsg);
        delete keyMsg;

        delete callmgr;
        delete ua;
    }
示例#8
0
   RequestLinterTest() :
      identity(""),
      requestUri("sip:[email protected]")
   {
      
      testUserAgent.setIsUserAgent(FALSE);
      testUserAgent.setUserAgentHeaderProperty("sipXecs/testproxy");
      testUserAgent.setForking(FALSE);  // Disable forking
      UtlString hostAliases("mydomainalias.com mydomainotheralias.com");
      testUserAgent.setHostAliases(hostAliases);

      OsConfigDb configDb;
      configDb.set("SIPX_PROXY_AUTHENTICATE_ALGORITHM", "MD5");
      configDb.set("SIPX_PROXY_DOMAIN_NAME", "mydomain.com");
      configDb.set("SIPX_PROXY_AUTHENTICATE_REALM", "mydomain.com");
      configDb.set("SIPX_PROXY_HOSTPORT", "mydomain.com");

      testSipRouter = new SipRouter(testUserAgent, mForwardingRules, configDb);
      spLinter->announceAssociatedSipRouter( testSipRouter );

   }
示例#9
0
// Constructor
SipPimClient::SipPimClient(SipUserAgent& userAgent,
                           Url& presentityAor)
{
    presentityAor.toString(mFromField);
    mPresentityAor = presentityAor;
    mpUserAgent = &userAgent;

    // Register to get incoming MESSAGE requests
    OsMsgQ* myQueue = getMessageQueue();
    userAgent.addMessageObserver(*myQueue,
                                SIP_MESSAGE_METHOD,
                                TRUE, // requests
                                FALSE, // responces
                                TRUE, // incoming
                                FALSE); // outgoing

}
示例#10
0
文件: main.cpp 项目: mranga/sipxecs
//
// The main entry point to the sipXpark
//
int main(int argc, char* argv[])
{
   // Configuration Database (used for OsSysLog)
   OsConfigDb configDb;

   // Register Signal handlers so we can perform graceful shutdown
   pt_signal(SIGINT,   sigHandler);    // Trap Ctrl-C on NT
   pt_signal(SIGILL,   sigHandler);
   pt_signal(SIGABRT,  sigHandler);    // Abort signal 6
   pt_signal(SIGFPE,   sigHandler);    // Floading Point Exception
   pt_signal(SIGSEGV,  sigHandler);    // Address access violations signal 11
   pt_signal(SIGTERM,  sigHandler);    // Trap kill -15 on UNIX
#if defined(__pingtel_on_posix__)
   pt_signal(SIGHUP,   sigHandler);    // Hangup
   pt_signal(SIGQUIT,  sigHandler);
   pt_signal(SIGPIPE,  SIG_IGN);    // Handle TCP Failure
   pt_signal(SIGBUS,   sigHandler);
   pt_signal(SIGSYS,   sigHandler);
   pt_signal(SIGXCPU,  sigHandler);
   pt_signal(SIGXFSZ,  sigHandler);
   pt_signal(SIGUSR1,  sigHandler);
   pt_signal(SIGUSR2,  sigHandler);
#endif

   UtlString argString;
   for (int argIndex = 1; argIndex < argc; argIndex++)
   {
      osPrintf("arg[%d]: %s\n", argIndex, argv[argIndex]);
      argString = argv[argIndex];
      NameValueTokenizer::frontBackTrim(&argString, "\t ");
      if(argString.compareTo("-v") == 0)
      {
         osPrintf("Version: %s (%s)\n", SIPXCHANGE_VERSION, SIPXCHANGE_VERSION_COMMENT);
         return(1);
      }
      else
      {
         osPrintf("usage: %s [-v]\nwhere:\n -v provides the software version\n",
         argv[0]);
         return(1);
      }
   }

   // Load configuration file file
   OsPath workingDirectory;
   if (OsFileSystem::exists(CONFIG_ETC_DIR))
   {
      workingDirectory = CONFIG_ETC_DIR;
      OsPath path(workingDirectory);
      path.getNativePath(workingDirectory);
   }
   else
   {
      OsPath path;
      OsFileSystem::getWorkingDirectory(path);
      path.getNativePath(workingDirectory);
   }

   UtlString fileName =  workingDirectory +
                         OsPathBase::separator +
                         CONFIG_SETTINGS_FILE;

   if (configDb.loadFromFile(fileName) != OS_SUCCESS)
   {
      exit(1);
   }

   // Initialize log file
   initSysLog(&configDb);

   // Read the user agent parameters from the config file.
   int UdpPort;
   if (configDb.get(CONFIG_SETTING_UDP_PORT, UdpPort) != OS_SUCCESS)
   {
      UdpPort = DEFAULT_UDP_PORT;
   }
   
   int TcpPort;
   if (configDb.get(CONFIG_SETTING_TCP_PORT, TcpPort) != OS_SUCCESS)
   {
      TcpPort = DEFAULT_TCP_PORT;
   }

   int HttpPort;
   if (configDb.get(CONFIG_SETTING_HTTP_PORT, HttpPort) != OS_SUCCESS)
   {
      HttpPort = DEFAULT_HTTP_PORT;
   }
   
   // Bind the SIP user agent to a port and start it up
   SipUserAgent* userAgent = new SipUserAgent(TcpPort, UdpPort);
   userAgent->start();

   UtlString domainName;
   configDb.get(CONFIG_SETTING_DOMAIN_NAME, domainName);

   int refreshTimeout;
   if (configDb.get(CONFIG_SETTING_REFRESH_INTERVAL, refreshTimeout) != OS_SUCCESS)
   {
      refreshTimeout = DEFAULT_REFRESH_INTERVAL;
   }

   // Create the Sip Dialog Monitor
   SipDialogMonitor dialogMonitor(userAgent,
                                  domainName,
                                  TcpPort,
                                  refreshTimeout,
                                  true);
   // Create a XmlRpcDispatch
   XmlRpcDispatch XmlRpcServer(HttpPort, false, "/RPC2");
   
   // Register all the XML-RPC methods
   DialogMonitorConfig xmlRpcMethods(&XmlRpcServer, &dialogMonitor);
    
   // Loop forever until signaled to shut down
   while (!gShutdownFlag)
   {
      OsTask::delay(2000);
   }

   // Shut down the sipUserAgent
   userAgent->shutdown(FALSE);

   while(!userAgent->isShutdownDone())
   {
      ;
   }

   delete userAgent;

   // Flush the log file
   OsSysLog::flush();

   // Say goodnight Gracie...
   return 0;
}
示例#11
0
文件: main.cpp 项目: chemeris/sipxecs
//
// The main entry point to the sipXpark
//
int main(int argc, char* argv[])
{
   // Configuration Database (used for OsSysLog)
   OsConfigDb configDb;

   // Register Signal handlers so we can perform graceful shutdown
   pt_signal(SIGINT,   sigHandler);    // Trap Ctrl-C on NT
   pt_signal(SIGILL,   sigHandler);
   pt_signal(SIGABRT,  sigHandler);    // Abort signal 6
   pt_signal(SIGFPE,   sigHandler);    // Floading Point Exception
   pt_signal(SIGSEGV,  sigHandler);    // Address access violations signal 11
   pt_signal(SIGTERM,  sigHandler);    // Trap kill -15 on UNIX
#if defined(__pingtel_on_posix__)
   pt_signal(SIGHUP,   sigHandler);    // Hangup
   pt_signal(SIGQUIT,  sigHandler);
   pt_signal(SIGPIPE,  SIG_IGN);    // Handle TCP Failure
   pt_signal(SIGBUS,   sigHandler);
   pt_signal(SIGSYS,   sigHandler);
   pt_signal(SIGXCPU,  sigHandler);
   pt_signal(SIGXFSZ,  sigHandler);
   pt_signal(SIGUSR1,  sigHandler);
   pt_signal(SIGUSR2,  sigHandler);
#endif

   UtlString argString;
   for(int argIndex = 1; argIndex < argc; argIndex++)
   {
      osPrintf("arg[%d]: %s\n", argIndex, argv[argIndex]);
      argString = argv[argIndex];
      NameValueTokenizer::frontBackTrim(&argString, "\t ");
      if(argString.compareTo("-v") == 0)
      {
         osPrintf("Version: %s (%s)\n", SIPXCHANGE_VERSION, SIPXCHANGE_VERSION_COMMENT);
         return(1);
      }
      else
      {
         osPrintf("usage: %s [-v]\nwhere:\n -v provides the software version\n",
         argv[0]);
         return(1);
      }
   }

   // Load configuration file file
   OsPath workingDirectory;
   if (OsFileSystem::exists(CONFIG_ETC_DIR))
   {
      workingDirectory = CONFIG_ETC_DIR;
      OsPath path(workingDirectory);
      path.getNativePath(workingDirectory);
   }
   else
   {
      OsPath path;
      OsFileSystem::getWorkingDirectory(path);
      path.getNativePath(workingDirectory);
   }

   UtlString fileName =  workingDirectory +
                         OsPathBase::separator +
                         CONFIG_SETTINGS_FILE;

   if (configDb.loadFromFile(fileName) != OS_SUCCESS)
   {
      exit(1);
   }

   // Initialize log file
   initSysLog(&configDb);

   // Read the user agent parameters from the config file.
   int UdpPort;
   if (configDb.get(CONFIG_SETTING_UDP_PORT, UdpPort) != OS_SUCCESS)
   {
      UdpPort = PRESENCE_DEFAULT_UDP_PORT;
   }

   int TcpPort;
   if (configDb.get(CONFIG_SETTING_TCP_PORT, TcpPort) != OS_SUCCESS)
   {
      TcpPort = PRESENCE_DEFAULT_TCP_PORT;
   }

   UtlString bindIp;
   if (configDb.get(CONFIG_SETTING_BIND_IP, bindIp) != OS_SUCCESS ||
         !OsSocket::isIp4Address(bindIp))
   {
      bindIp = PRESENCE_DEFAULT_BIND_IP;
   }

   // Bind the SIP user agent to a port and start it up
   SipUserAgent* userAgent = new SipUserAgent(TcpPort, UdpPort, PORT_NONE,
         NULL, NULL, bindIp );
   userAgent->start();

   if (!userAgent->isOk())
   {
      OsSysLog::add(LOG_FACILITY, PRI_EMERG, "SipUserAgent failed to initialize; requesting shutdown");
      gShutdownFlag = TRUE;
   }

   UtlString domainName;
   configDb.get(CONFIG_SETTING_DOMAIN_NAME, domainName);
   // Normalize SIP domain name to all lower case.
   domainName.toLower();

   // Create the SipPersistentSubscriptionMgr.
   SipPersistentSubscriptionMgr subscriptionMgr(SUBSCRIPTION_COMPONENT_PRESENCE,
                                                domainName);

   // Determine the name of the persistent file.
   UtlString pathName = SipXecsService::Path(SipXecsService::VarDirType,
                                             sPersistentFileName.data());

   // Create the Sip Presence Monitor, which handles all of the processing.
   SipPresenceMonitor presenceMonitor(userAgent,
                                      &subscriptionMgr,
                                      domainName,
                                      TcpPort,
                                      &configDb,
                                      true,
                                      pathName.data());

   // Loop forever until signaled to shut down
   while (!gShutdownFlag)
   {
      OsTask::delay(2000);
   }

   // Shut down the sipUserAgent
   userAgent->shutdown(FALSE);

   while(!userAgent->isShutdownDone())
   {
      ;
   }

   delete userAgent;

   // Flush the log file
   OsSysLog::flush();

   // Say goodnight Gracie...
   return 0;
}
示例#12
0
//
// Create the real Server, passing in the configured parameters
//
void ParkService::run()
{
    int UdpPort;
    int TcpPort;
    int RtpBase;
    UtlString bindIp;
    int MaxSessions;
    UtlBoolean OneButtonBLF;
    UtlString   domain;
    UtlString   realm;
    UtlString   user;
    SipLineMgr* lineMgr = NULL;
    int Lifetime;
    int BlindXferWait;
    int KeepAliveTime;

   loadConfig(
       UdpPort,
       TcpPort,
       RtpBase,
       bindIp,
       MaxSessions,
       OneButtonBLF,
       domain,
       realm,
       user,
       lineMgr,
       Lifetime,
       BlindXferWait,
       KeepAliveTime
       );

   // initialize other pieces

    // This is not configurable, as consultative transfers should
    // succeed or fail immediately.
    int ConsXferWait;
    ConsXferWait = CONS_XFER_WAIT;

    // Bind the SIP user agent to a port and start it up
    SipUserAgent* userAgent = new SipUserAgent(TcpPort,
                                               UdpPort,
                                               TcpPort+1,
                                               NULL, // publicAddress
                                               user.isNull() ? NULL : user.data(), // default user
                                               bindIp,
                                               domain.isNull() ? NULL : domain.data(), // outbound proxy
                                               NULL, // sipDirectoryServers (deprecated)
                                               NULL, // sipRegistryServers (deprecated)
                                               NULL, // authenicateRealm
                                               NULL, // authenticateDb
                                               NULL, // authorizeUserIds (deprecated)
                                               NULL, // authorizePasswords (deprecated)
                                               lineMgr
                                               );
    userAgent->setUserAgentHeaderProperty("sipXecs/park");
    userAgent->start();

    if (!userAgent->isOk())
    {
       OsSysLog::add(LOG_FACILITY, PRI_EMERG, "SipUserAgent failed to initialize, requesting shutdown");
       setShutdownFlag(true);
    }

    // Read the list of codecs from the configuration file.
    SdpCodecFactory codecFactory;
    initCodecs(&codecFactory, &getConfigDb());

    // Initialize and start up the media subsystem
    mpStartUp(MP_SAMPLE_RATE, MP_SAMPLES_PER_FRAME, 6 * MaxSessions, &getConfigDb());
    MpMediaTask::getMediaTask(MaxSessions);

#ifdef INCLUDE_RTCP
    CRTCManager::getRTCPControl();
#endif //INCLUDE_RTCP

    mpStartTasks();

    // Instantiate the call processing subsystem
    UtlString localAddress;
    int localPort ;
    userAgent->getLocalAddress(&localAddress, &localPort) ;
    if (localAddress.isNull())
        OsSocket::getHostIp(&localAddress);

    // Construct an address to be used in outgoing requests (primarily
    // INVITEs stimulated by REFERs).
    UtlString outgoingAddress;
    {
       char buffer[100];
       sprintf(buffer, "sip:sipXpark@%s:%d", localAddress.data(),
               portIsValid(UdpPort) ? UdpPort : TcpPort);
       outgoingAddress = buffer;
    }
    CallManager callManager(FALSE,
                           NULL,
                           TRUE,                              // early media in 180 ringing
                           &codecFactory,
                           RtpBase,                           // rtp start
                           RtpBase + (2 * MaxSessions),       // rtp end
                           localAddress,
                           localAddress,
                           userAgent,
                           0,                                 // sipSessionReinviteTimer
                           NULL,                              // mgcpStackTask
                           outgoingAddress,                   // defaultCallExtension
                           Connection::RING,                  // availableBehavior
                           NULL,                              // unconditionalForwardUrl
                           -1,                                // forwardOnNoAnswerSeconds
                           NULL,                              // forwardOnNoAnswerUrl
                           Connection::BUSY,                  // busyBehavior
                           NULL,                              // sipForwardOnBusyUrl
                           NULL,                              // speedNums
                           CallManager::SIP_CALL,             // phonesetOutgoingCallProtocol
                           4,                                 // numDialPlanDigits
                           CallManager::NEAR_END_HOLD,        // holdType
                           5000,                              // offeringDelay
                           "",                                // pLocal
                           CP_MAXIMUM_RINGING_EXPIRE_SECONDS, // inviteExpiresSeconds
                           QOS_LAYER3_LOW_DELAY_IP_TOS,       // expeditedIpTos
                           MaxSessions,                       // maxCalls
                           sipXmediaFactoryFactory(NULL));    // CpMediaInterfaceFactory



    // Create a listener (application) to deal with call
    // processing events (e.g. incoming call and hang ups)
    OrbitListener listener(&callManager, Lifetime, BlindXferWait, KeepAliveTime, ConsXferWait);

    callManager.addTaoListener(&listener);
    listener.start();

    // Create the SIP Subscribe Server
    SipPersistentSubscriptionMgr
       subscriptionMgr(SUBSCRIPTION_COMPONENT_PARK,
                       domain,
                       "subscription"); // Component for holding the subscription data
    SipSubscribeServerEventHandler policyHolder; // Component for granting the subscription rights
    SipPublishContentMgr publisher; // Component for publishing the event contents

    SipSubscribeServer subscribeServer(SipSubscribeServer::terminationReasonSilent,
                                       *userAgent, publisher,
                                       subscriptionMgr, policyHolder);
    subscribeServer.enableEventType(DIALOG_EVENT_TYPE, NULL, NULL, NULL,
                                    SipSubscribeServer::standardVersionCallback,
                                    TRUE // dialogEvents only produces full content.
       );
    subscribeServer.start();

    // Create the DialogEventPublisher.
    // Use the sipX domain as the hostport of resource-IDs of the
    // published events, as that will be the request-URIs of SUBSCRIBEs.
    DialogEventPublisher dialogEvents(&callManager, &publisher, domain, PORT_NONE, OneButtonBLF);
    callManager.addTaoListener(&dialogEvents);
    dialogEvents.start();

    // Start up the call processing system
    callManager.start();

    // Loop forever until signaled to shut down

    int numTwoSecIntervals = 0;
    int CleanLoopWaitTimeSecs = 10;

    while (!getShutdownFlag())
    {
       OsTask::delay(2000);

       if (2*numTwoSecIntervals >= CleanLoopWaitTimeSecs)
       {
           numTwoSecIntervals = 0;
           if (OsSysLog::willLog(FAC_PARK, PRI_DEBUG))
           {
               OsSysLog::add(LOG_FACILITY, PRI_DEBUG,
                             "park main "
                             "logging call status"
                             );
               callManager.printCalls(0) ;
               listener.dumpCallsAndTransfers();
           }
       }
       else
       {
           numTwoSecIntervals += 1;
       }

    }

}
示例#13
0
int main(int argc, char* argv[])
{
   const char* configFileName = "siptest-config";
   int proxyTcpPort;
   int proxyUdpPort;
   int proxyTlsPort;
   OsConfigDb configDb;

   // siptest uses osPrintf for output, so we have to un-suppress it.
   enableConsoleOutput(TRUE);

   if(configDb.loadFromFile(configFileName) == OS_SUCCESS)
   {
      osPrintf("Found config file: %s\n", configFileName);
   }
   else
   {
      configDb.set("SIP_TEST_UDP_PORT", "3000");
      configDb.set("SIP_TEST_TCP_PORT", "3000");
      configDb.set("SIP_TEST_TLS_PORT", "3001");

      if(configDb.storeToFile(configFileName) == OS_SUCCESS)
      {
         osPrintf("Could not write config file: %s\n", configFileName);
      }
   }

   proxyUdpPort = configDb.getPort("SIP_TEST_UDP_PORT") ;
   proxyTcpPort = configDb.getPort("SIP_TEST_TCP_PORT") ;
   proxyTlsPort = configDb.getPort("SIP_TEST_TLS_PORT") ;

   UtlBoolean commandStatus = CommandProcessor::COMMAND_SUCCESS;
   char buffer[1024];
   char* commandLine;
   CommandProcessor processor;

   SipLineMgr*    lineMgr = new SipLineMgr();
   SipRefreshMgr* refreshMgr = new SipRefreshMgr();

   lineMgr->StartLineMgr();
   lineMgr->initializeRefreshMgr( refreshMgr );

   SipUserAgent*  sipUA = new SipUserAgent( proxyTcpPort
                                            ,proxyUdpPort
                                            ,proxyTlsPort
                                            ,NULL         // default publicAddress
                                            ,NULL         // default defaultUser
                                            ,NULL         // default defaultSipAddress
                                            ,NULL         // default sipProxyServers
                                            ,NULL         // default sipDirectoryServers
                                            ,NULL         // default sipRegistryServers
                                            ,NULL         // default authenicateRealm
                                            ,NULL         // default authenticateDb
                                            ,NULL         // default authorizeUserIds
                                            ,NULL         // default authorizePasswords
                                            ,lineMgr
      );
   sipUA->allowMethod(SIP_REGISTER_METHOD);
   sipUA->allowMethod(SIP_SUBSCRIBE_METHOD);
   sipUA->allowMethod(SIP_NOTIFY_METHOD);

   sipUA->start();

   sipUA->startMessageLog();
   osPrintf( "SIP logging Started\n" );

   refreshMgr->init( sipUA );

   CommandMsgProcessor* msgProc = new CommandMsgProcessor(sipUA);
   msgProc->start();

   processor.registerCommand("help", new HelpCommand(&processor));
   processor.registerCommand("?", new HelpCommand(&processor));
   processor.registerCommand("history", new HistoryCommand(&processor));
   processor.registerCommand("send", new SipSendCommand(sipUA));
   processor.registerCommand("lsend", new SipLSendCommand());
   processor.registerCommand("get", new HttpGetCommand());
   processor.registerCommand("respond", new RespondCommand(msgProc));
   processor.registerCommand("rt", new RespondTemplate(msgProc));
   processor.registerCommand("rrespond", new ResendResponse(msgProc));
   processor.registerCommand("log", new SipLogCommand(*sipUA));
   processor.registerCommand("auth", new AuthCommand(lineMgr));
   processor.registerCommand("sleep", new SleepCommand());
   processor.registerCommand("quit", new ExitCommand());
   processor.registerCommand("exit", new ExitCommand());

   //Initialization
   UtlBoolean doPrompt = isatty(STDIN_FILENO);

   if ( doPrompt )
   {
      printf("Enter command or help/? for help\n");
      printf("SIPdriver: ");
   }

   for ( commandStatus = CommandProcessor::COMMAND_SUCCESS;
         (   commandStatus < CommandProcessor::COMMAND_FAILED_EXIT
             && commandStatus != CommandProcessor::COMMAND_SUCCESS_EXIT
             && (commandLine = fgets(buffer,1024,stdin))
            );
      )
   {
      //printf("GOT command line:\"%s\"\n", commandLine);
      commandStatus = processor.executeCommand(commandLine);
      //printf("command status: %d exit status: %d\n", commandStatus,
      //CommandProcessor::COMMAND_SUCCESS_EXIT);
      if ( doPrompt )
      {
         printf("SIPdriver: ");
      }
   }

   delete msgProc;
   delete sipUA;

   return CommandProcessor::COMMAND_SUCCESS_EXIT != commandStatus;
}
示例#14
0
StatusServer*
StatusServer::startStatusServer (
    const UtlString workingDir,
    const char* configFileName )
{
    int httpPort  = PORT_NONE;
    int httpsPort = PORT_NONE;
    int tcpPort   = PORT_NONE;
    int udpPort   = PORT_NONE;
    int tlsPort   = PORT_NONE;
    UtlString bindIp;
    UtlString defaultMaxExpiresTime;
    UtlString defaultMinExpiresTime;

    UtlString authAlgorithm;
    UtlString authQop;
    UtlString authRealm;
    UtlString authScheme;
    UtlString domainName;

    UtlBoolean isCredentialDB = TRUE;

    // if the configuration file exists, load the name value pairs
    if ( sConfigDb.loadFromFile(configFileName) == OS_SUCCESS )
    {
        Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                      "Found config file: %s", configFileName);
    } else
    {
       Os::Logger::instance().log(FAC_SIP, PRI_CRIT,
                     "Could not read config file: %s", configFileName);
       fprintf(stderr, "Could not read config file: %s", configFileName);
       exit(1);
    }

    Os::Logger::instance().log(LOG_FACILITY, PRI_INFO, "Starting - version: %s %s\n", VERSION, PACKAGE_REVISION);

    sConfigDb.get("SIP_STATUS_AUTHENTICATE_ALGORITHM", authAlgorithm);
    sConfigDb.get("SIP_STATUS_AUTHENTICATE_QOP", authQop);
    sConfigDb.get("SIP_STATUS_AUTHENTICATE_REALM", authRealm);
    sConfigDb.get("SIP_STATUS_AUTHENTICATE_SCHEME", authScheme);
    sConfigDb.get("SIP_STATUS_DOMAIN_NAME", domainName);
    sConfigDb.get("SIP_STATUS_HTTP_PORT", httpPort);
    sConfigDb.get("SIP_STATUS_HTTPS_PORT", httpsPort);
    sConfigDb.get("SIP_STATUS_MAX_EXPIRES", defaultMaxExpiresTime);
    sConfigDb.get("SIP_STATUS_MIN_EXPIRES", defaultMinExpiresTime);

    // SIP_STATUS_UDP_PORT
    udpPort = sConfigDb.getPort("SIP_STATUS_UDP_PORT") ;
    if ( udpPort == PORT_NONE )
    {
       udpPort = 5110;
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIP_STATUS_UDP_PORT : %d", udpPort);

    // SIP_STATUS_TCP_PORT
    tcpPort = sConfigDb.getPort("SIP_STATUS_TCP_PORT") ;
    if ( tcpPort == PORT_NONE )
    {
       tcpPort = 5110;
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIP_STATUS_TCP_PORT : %d", tcpPort);

    // SIP_STATUS_TLS_PORT
    tlsPort = sConfigDb.getPort("SIP_STATUS_TLS_PORT") ;
    if ( tlsPort == PORT_NONE )
    {
       tlsPort = 5111;
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIP_STATUS_TLS_PORT : %d", tlsPort);

    // SIP_STATUS_BIND_IP
    sConfigDb.get("SIP_STATUS_BIND_IP", bindIp) ;
    if ((bindIp.isNull()) || !OsSocket::isIp4Address(bindIp))
    {
       bindIp = "0.0.0.0";
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIP_STATUS_BIND_IP : %s", bindIp.data());

    UtlString separatedList;
    // Get the HTTP server Valid IP address database
    OsConfigDb* pValidIpAddressDB = new OsConfigDb();
    sConfigDb.get("SIP_STATUS_HTTP_VALID_IPS", separatedList);
    parseList ("SIP_STATUS_HTTP_VALID_IPS", separatedList, *pValidIpAddressDB);

    if( pValidIpAddressDB->isEmpty() )
    {
        delete pValidIpAddressDB;
        pValidIpAddressDB = NULL;
    }

    // Check for default values and, if not specified, set to defaults

    // SIP_STATUS_AUTHENTICATE_ALGORITHM
    if ( authAlgorithm.isNull() ) /* MD5/MD5SESS */
    {
        authAlgorithm.append("MD5");
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                  "SIP_STATUS_AUTHENTICATE_ALGORITHM : %s",
                  authAlgorithm.data());

    // SIP_STATUS_AUTHENTICATE_QOP
    if ( authQop.isNull() ) /* AUTH/AUTH-INT/NONE */
    {
        authQop.append("NONE");
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                  "SIP_STATUS_AUTHENTICATE_QOP : %s",
                  authQop.data());

    // SIP_STATUS_DOMAIN_NAME - need this before the SIP_STATUS_AUTHENTICATE_REALM
    // below since we get the domain name from the socket
    if ( domainName.isNull() )
    {
        OsSocket::getHostIp(&domainName);
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                  "SIP_STATUS_DOMAIN_NAME : %s",
                  domainName.data());

    // SIP_STATUS_AUTHENTICATE_REALM
    if(authRealm.isNull())
    {
       authRealm.append(domainName);
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                  "SIP_STATUS_AUTHENTICATE_REALM : %s",
                  authRealm.data());

    // SIP_STATUS_AUTHENTICATE_SCHEME (Hidden) NONE/DIGEST
    if ( authScheme.compareTo("NONE" , UtlString::ignoreCase) == 0 )
    {
       isCredentialDB = FALSE;
    }

    // SIP_STATUS_HTTPS_PORT - See if the SECURE one is set first
    OsStatus result;
    UtlString portStr;
    result = sConfigDb.get("SIP_STATUS_HTTPS_PORT", portStr);
    Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                  "startStatusServer : HTTPS port %s result %d",
                  portStr.data(), result);
    // If the key is missing or not set, set it to the default HTTPS port
    if ( result == OS_NOT_FOUND || portStr.isNull() )
    {
        httpsPort = HTTPS_SERVER_PORT;
    }

    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIP_STATUS_HTTPS_PORT : %d", httpsPort );

    // Only search for the non secure SIP_STATUS_HTTP_PORT
    // if the secure one is disabled
    if ( httpsPort == PORT_NONE )
    {
        // SIP_STATUS_HTTP_PORT
        result = sConfigDb.get("SIP_STATUS_HTTP_PORT", portStr);
        Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                      "startStatusServer : HTTP port %s result %d",
                      portStr.data(), result);
        // If the key is missing or not set, set it to the default HTTP port
        if ( result == OS_NOT_FOUND || portStr.isNull() )
        {
            httpPort = HTTP_SERVER_PORT;
        }
        Os::Logger::instance().log( FAC_SIP, PRI_INFO, "SIP_STATUS_HTTP_PORT : %d", httpPort );
    }

    int maxNumSrvRecords = -1;
    sConfigDb.get("SIP_STATUS_DNSSRV_MAX_DESTS", maxNumSrvRecords);
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIP_STATUS_DNSSRV_MAX_DESTS : %d",
              maxNumSrvRecords);
    // If explicitly set to a valid number
    if(maxNumSrvRecords > 0)
    {
        osPrintf("SIP_STATUS_DNSSRV_MAX_DESTS : %d\n", maxNumSrvRecords);
    }
    else
    {
        maxNumSrvRecords = 4;
    }

    int dnsSrvTimeout = -1; //seconds
    sConfigDb.get("SIP_STATUS_DNSSRV_TIMEOUT", dnsSrvTimeout);
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIP_STATUS_DNSSRV_TIMEOUT : %d",
              dnsSrvTimeout);
    // If explicitly set to a valid number
    if(dnsSrvTimeout > 0)
    {
        osPrintf("SIP_STATUS_DNSSRV_TIMEOUT : %d\n", dnsSrvTimeout);
    }
    else
    {
        dnsSrvTimeout = 4;
    }

    // SIP_STATUS_MAX_EXPIRES
    if ( defaultMaxExpiresTime.isNull() )
    {
        defaultMaxExpiresTime.append("604800"); // default to 1 week
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                  "SIP_STATUS_MAX_EXPIRES : %s",
                  defaultMaxExpiresTime.data());

    int maxExpiresTime = atoi(defaultMaxExpiresTime.data());

    // SIP_STATUS_MIN_EXPIRES
    if ( defaultMinExpiresTime.isNull() )
    {
        defaultMinExpiresTime.append("300");  // default to 300 seconds
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                  "SIP_STATUS_MIN_EXPIRES : %s",
                  defaultMinExpiresTime.data());


    int webServerPort = httpPort;
    UtlBoolean isSecureServer = false;

    // Determine whether we should start the web server or not.  Use the port
    // value as the decision point.  A valid port means enable.
    // If isSecureServer then start the port as a secure web server.
    OsServerSocket* serverSocket = NULL;
    HttpServer*     httpServer = NULL;
    if( portIsValid(webServerPort) )
    {
       if ( isSecureServer )
       {
#         ifdef HAVE_SSL
          serverSocket = new OsSSLServerSocket(50, webServerPort, bindIp);
          httpServer = new HttpServer(serverSocket,
                                      pValidIpAddressDB,
                                      false /* no persistent tcp connection */);
#         else /* ! HAVE_SSL */
          // SSL is not configured in, so we cannot open the requested
          // socket.
          Os::Logger::instance().log(FAC_SIP, PRI_CRIT,
                        "StatusServer::startStatusServer SSL not configured; "
                        "cannot open secure socket %d", webServerPort);
          httpServer = NULL;
#         endif /* HAVE_SSL */
       }
       else
       {
          serverSocket = new OsServerSocket(50, webServerPort, bindIp);
          httpServer = new HttpServer(serverSocket,
                                      pValidIpAddressDB );
       }
    }

    // Start the SIP stack
    SipUserAgent* sipUserAgent =
        new SipUserAgent(
            tcpPort,
            udpPort,
            tlsPort,
            NULL,   // public IP address (nopt used in proxy)
            NULL,   // default user (not used in proxy)
            bindIp,
            NULL,   // outbound proxy
            NULL,   // directory server
            NULL,   // registry server
            NULL,   // auth realm
            NULL,   // auth DB
            NULL,   // auth user IDs
            NULL,   // auth passwords
            NULL,   // line mgr
            SIP_DEFAULT_RTT, // first resend timeout
            TRUE,   // default to UA transaction
            SIPUA_DEFAULT_SERVER_UDP_BUFFER_SIZE, // socket layer read buffer size
            SIPUA_DEFAULT_SERVER_OSMSG_QUEUE_SIZE // OsServerTask message queue size
         );

    // No need to log the message as it goes in the syslog
    //sipUserAgent->startMessageLog(100000);
    sipUserAgent->setDnsSrvTimeout(dnsSrvTimeout);
    sipUserAgent->setMaxSrvRecords(maxNumSrvRecords);
    sipUserAgent->setUserAgentHeaderProperty("sipXecs/publisher");

    sipUserAgent->start();

    Notifier* notifier = new Notifier(sipUserAgent);

    // Start the status server
    StatusServer* status = new StatusServer(
                notifier,
                maxExpiresTime,
                domainName,
                defaultMinExpiresTime,
                isCredentialDB,
                authAlgorithm,
                authQop,
                authRealm,
                workingDir,
                serverSocket,
                httpServer);
    status->start();
    return(status);
}
示例#15
0
 // Primitive to send a SIP message to the AppearanceAgent server under test
 bool  sendToAppearanceAgentUnderTest( SipMessage& msg )
 {
    return pSipUserAgent->send( msg );
 }
示例#16
0
    void testRefreshMgrUATeardown()
    {
        for (int i=0; i<NUM_OF_RUNS; ++i)
        {
            SipLineMgr*    lineMgr = new SipLineMgr();
            SipRefreshMgr* refreshMgr = new SipRefreshMgr();

            lineMgr->startLineMgr();
            lineMgr->initializeRefreshMgr( refreshMgr );

            SipUserAgent* sipUA = new SipUserAgent( 5090
                                                    ,5090
                                                    ,5091
                                                    ,NULL     // default publicAddress
                                                    ,NULL     // default defaultUser
                                                    ,"127.0.0.1" // default defaultSipAddress
                                                    ,NULL     // default sipProxyServers
                                                    ,NULL     // default sipDirectoryServers
                                                    ,NULL     // default sipRegistryServers
                                                    ,NULL     // default authenicateRealm
                                                    ,NULL     // default authenticateDb
                                                    ,NULL     // default authorizeUserIds
                                                    ,NULL     // default authorizePasswords
                                                    ,lineMgr
                                                  );

            sipUA->start();
            refreshMgr->init(sipUA);


            CallManager *pCallManager =
                new CallManager(FALSE,
                                NULL, //LineMgr
                                TRUE, // early media in 180 ringing
                                NULL, // CodecFactory
                                9000, // rtp start
                                9002, // rtp end
                                "sip:[email protected]",
                                "sip:[email protected]",
                                sipUA, //SipUserAgent
                                0, // sipSessionReinviteTimer
                                NULL, // mgcpStackTask
                                NULL, // defaultCallExtension
                                Connection::RING, // availableBehavior
                                NULL, // unconditionalForwardUrl
                                -1, // forwardOnNoAnswerSeconds
                                NULL, // forwardOnNoAnswerUrl
                                Connection::BUSY, // busyBehavior
                                NULL, // sipForwardOnBusyUrl
                                NULL, // speedNums
                                CallManager::SIP_CALL, // phonesetOutgoingCallProtocol
                                4, // numDialPlanDigits
                                CallManager::NEAR_END_HOLD, // holdType
                                5000, // offeringDelay
                                "", // pLocal
                                CP_MAXIMUM_RINGING_EXPIRE_SECONDS, //inviteExpireSeconds
                                QOS_LAYER3_LOW_DELAY_IP_TOS, // expeditedIpTos
                                10, //maxCalls
                                sipXmediaFactoryFactory(NULL)); //pMediaFactory
#if 0
            printf("Starting CallManager\n");
#endif
            pCallManager->start();

            lineMgr->requestShutdown();
            refreshMgr->requestShutdown();
            sipUA->shutdown(TRUE);
            pCallManager->requestShutdown();

#if 0
            printf("Deleting CallManager\n");
#endif

            delete pCallManager;
            delete refreshMgr;
            delete lineMgr;
        }

        for (int i=0; i<NUM_OF_RUNS; ++i)
        {
            sipxDestroyMediaFactoryFactory() ;
        }
    }
示例#17
0
   // Basic server functionality test.
   // Checks that server answers SUBSCRIBES, sends NOTIFY, sends NOTIFY
   // when content changes.
   void basicSubscriptionTest()
      {
         // Verify that authentication and authorization are
         // disabled by default.
         {
            SipSubscribeServerEventHandler* eventHandler =
               subServerp->getEventHandler(eventName);
            CPPUNIT_ASSERT(eventHandler);

            SipMessage bogusSubscribeRequest;
            SipMessage bogusSubscribeResponse;
            CPPUNIT_ASSERT(eventHandler->isAuthenticated(bogusSubscribeRequest,
                                                         bogusSubscribeResponse));
            CPPUNIT_ASSERT(eventHandler->isAuthorized(bogusSubscribeRequest,
                                                      bogusSubscribeResponse));
         }

         // Send a SUBSCRIBE to the notifier.
         SipMessage mwiSubscribeRequest;
         {
            UtlString c;
            CallId::getNewCallId(c);
            mwiSubscribeRequest.setSubscribeData(notifier_aor, // request URI
                                                 subscriber_name_addr, // From
                                                 notifier_name_addr, // To
                                                 c, // Call-Id
                                                 0, // CSeq
                                                 eventName, // Event
                                                 mwiMimeType, // Accept
                                                 NULL, // Event id
                                                 subscriber_name_addr, // Contact
                                                 NULL, // Route
                                                 3600 // Expires
               );
         }

         CPPUNIT_ASSERT(subscriberUserAgentp->send(mwiSubscribeRequest));

         // We should get a 202 response and a NOTIFY request in the queue
         OsTime messageTimeout(1, 0);  // 1 second
         {
            const SipMessage* subscribeResponse;
            const SipMessage* notifyRequest;
            runListener(incomingClientMsgQueue,
                        *subscriberUserAgentp,
                        messageTimeout,
                        messageTimeout,
                        notifyRequest,
                        subscribeResponse,
                        SIP_OK_CODE,
                        FALSE,
                        0,
                        NULL);

            // We should have received a SUBSCRIBE response and a NOTIFY request.
            CPPUNIT_ASSERT(subscribeResponse);
            CPPUNIT_ASSERT(notifyRequest);

            // Check that the response code and CSeq method in the
            // subscribe response are OK.
            {
               CPPUNIT_ASSERT(subscribeResponse->getResponseStatusCode() ==
                              SIP_ACCEPTED_CODE);
               UtlString subscribeMethod;
               subscribeResponse->getCSeqField(NULL, &subscribeMethod);
               ASSERT_STR_EQUAL(SIP_SUBSCRIBE_METHOD, subscribeMethod.data());
            }

            // Check that the method in the notify request is OK.
            {
               UtlString notifyMethod;
               notifyRequest->getRequestMethod(&notifyMethod);
               ASSERT_STR_EQUAL(SIP_NOTIFY_METHOD, notifyMethod.data());
            }

            // Check that the Event header in the NOTIFY is the same as the
            // one in the SUBSCRIBE.
            {
               UtlString notifyEventHeader;
               UtlString subscribeEventHeader;
               notifyRequest->getEventField(notifyEventHeader);
               mwiSubscribeRequest.getEventField(subscribeEventHeader);
               ASSERT_STR_EQUAL(subscribeEventHeader, notifyEventHeader);
            }

            // The NOTIFY should have no body because none has been published yet.
            {
               const HttpBody* bodyPtr = notifyRequest->getBody();
               CPPUNIT_ASSERT(bodyPtr == NULL);
            }

            // The Contact in the subscribe response should be the notifier.
            ASSERT_STR_EQUAL(notifier_contact_name_addr,
                             subscribeResponse->
                                 getHeaderValue(0, SIP_CONTACT_FIELD));

            // The Contact in the NOTIFY should be the notifier.
            CPPUNIT_ASSERT(notifyRequest->
                           getHeaderValue(0, SIP_CONTACT_FIELD));
            ASSERT_STR_EQUAL(notifier_contact_name_addr,
                             notifyRequest->
                                 getHeaderValue(0, SIP_CONTACT_FIELD));
         }

         // Publish some content (mwiStateString) for this resourceID
         {
            HttpBody* newMwiBodyPtr = new HttpBody(mwiStateString,
                                                   strlen(mwiStateString),
                                                   mwiMimeType);
            SipPublishContentMgr* publishMgr = subServerp->getPublishMgr(eventName);
            CPPUNIT_ASSERT(publishMgr);
            publishMgr->publish(notifier_resource_id,
                                eventName,
                                eventName,
                                1,
                                &newMwiBodyPtr);
         }

         // Should get a NOTIFY queued up
         {
            const SipMessage* subscribeResponse;
            const SipMessage* secondNotify;
            runListener(incomingClientMsgQueue,
                        *subscriberUserAgentp,
                        messageTimeout,
                        messageTimeout,
                        secondNotify,
                        subscribeResponse,
                        SIP_OK_CODE,
                        FALSE,
                        0,
                        NULL);
            CPPUNIT_ASSERT(secondNotify);
            CPPUNIT_ASSERT(subscribeResponse == NULL);

            // Check that the body of the NOTIFY is what we expect (mwiStateString).
            {
               const HttpBody* secondNotifyBody = secondNotify->getBody();
               CPPUNIT_ASSERT(secondNotifyBody);
               ssize_t notifyBodySize;
               const char* notifyBodyBytes;
               secondNotifyBody->getBytes(&notifyBodyBytes, &notifyBodySize);
               CPPUNIT_ASSERT(notifyBodyBytes);
               ASSERT_STR_EQUAL(mwiStateString, notifyBodyBytes);
            }

            // Check that the Dialog Manager reports that the dialog handle is OK.
            {
               UtlString secondNotifyDialogHandle;
               secondNotify->getDialogHandle(secondNotifyDialogHandle);
               CPPUNIT_ASSERT(!secondNotifyDialogHandle.isNull());
               CPPUNIT_ASSERT(dialogMgrp->dialogExists(secondNotifyDialogHandle));
               CPPUNIT_ASSERT(dialogMgrp->countDialogs() == 1);
            }
         }

         // Create a new one-time SUBSCRIBE
         SipMessage oneTimeMwiSubscribeRequest;
         {
            UtlString c;
            CallId::getNewCallId(c);
            oneTimeMwiSubscribeRequest.
               setSubscribeData(notifier_aor, // request URI
                                subscriber_name_addr, // From
                                notifier_name_addr, // To
                                c, // Call-Id
                                0, // CSeq
                                eventName, // Event
                                mwiMimeType, // Accept
                                NULL, // Event id
                                subscriber_name_addr, // Contact
                                NULL, // Route
                                0 // Expires
                  );
         }

         CPPUNIT_ASSERT(subscriberUserAgentp->send(oneTimeMwiSubscribeRequest));

         {
            const SipMessage* oneTimeNotifyRequest;
            const SipMessage* oneTimeSubscribeResponse;
            runListener(incomingClientMsgQueue,
                        *subscriberUserAgentp,
                        messageTimeout,
                        messageTimeout,
                        oneTimeNotifyRequest,
                        oneTimeSubscribeResponse,
                        SIP_OK_CODE,
                        FALSE,
                        0,
                        NULL);

            // Validate the one time subscribe response and notify request
            CPPUNIT_ASSERT(oneTimeSubscribeResponse);
            CPPUNIT_ASSERT(oneTimeNotifyRequest);

            {
               CPPUNIT_ASSERT(oneTimeSubscribeResponse->getResponseStatusCode() ==
                              SIP_ACCEPTED_CODE);
               UtlString oneTimeSubscribeMethod;
               oneTimeSubscribeResponse->getCSeqField(NULL, &oneTimeSubscribeMethod);
               ASSERT_STR_EQUAL(SIP_SUBSCRIBE_METHOD, oneTimeSubscribeMethod.data());
               UtlString oneTimeSubscribeEventHeader;
               oneTimeSubscribeResponse->getEventField(oneTimeSubscribeEventHeader);
               // The Event: header never appears in responses -- see RFC 3265 section 7.2.
               // The "R" in the "where" column means that "Event" appears only in
               // requests -- see RFC 3261 table 2 and page 160.
               ASSERT_STR_EQUAL("", oneTimeSubscribeEventHeader);
            }

            {
               UtlString oneTimeNotifyMethod;
               oneTimeNotifyRequest->getRequestMethod(&oneTimeNotifyMethod);
               ASSERT_STR_EQUAL(SIP_NOTIFY_METHOD, oneTimeNotifyMethod.data());
               UtlString oneTimeNotifyEventHeader;
               oneTimeNotifyRequest->getEventField(oneTimeNotifyEventHeader);
               // The Event: header should appear in the NOTIFY.
               ASSERT_STR_EQUAL(SIP_EVENT_MESSAGE_SUMMARY, oneTimeNotifyEventHeader);
            }

            {
               const HttpBody* oneTimeBodyPtr = oneTimeNotifyRequest->getBody();
               CPPUNIT_ASSERT(oneTimeBodyPtr != NULL);
               const char* oneTimeBodyString;
               ssize_t oneTimeNotifyBodySize;
               oneTimeBodyPtr->getBytes(&oneTimeBodyString, &oneTimeNotifyBodySize);
               ASSERT_STR_EQUAL(mwiStateString, oneTimeBodyString);
            }

            {
               UtlString oneTimeNotifyDialogHandle;
               oneTimeNotifyRequest->getDialogHandle(oneTimeNotifyDialogHandle);
               CPPUNIT_ASSERT(!oneTimeNotifyDialogHandle.isNull());
               CPPUNIT_ASSERT(dialogMgrp->dialogExists(oneTimeNotifyDialogHandle));
               CPPUNIT_ASSERT(dialogMgrp->countDialogs() == 2);
               long now = OsDateTime::getSecsSinceEpoch();
               subMgrp->removeOldSubscriptions(now + 1);
               // The one time subscription should get garbage collected
               // leaving only the persistant 3600 second subscription
               CPPUNIT_ASSERT(dialogMgrp->countDialogs() == 1);
            }
         }
      }
示例#18
0
int main(int argc, char* argv[])
{
    int port;
    int expiration;
    char* targetURI;
    char* eventType;
    char* contentType;
    char* realm;
    char* user;
    char* password;

   // Initialize logging.
   OsSysLog::initialize(0, "test");
   OsSysLog::setOutputFile(0, "log");
   OsSysLog::setLoggingPriority(PRI_DEBUG);
   OsSysLog::setLoggingPriorityForFacility(FAC_SIP_INCOMING_PARSED, PRI_ERR);

   if (!parseArgs(argc, argv, &port, &expiration,
                  &targetURI, &eventType, &contentType,
                  &realm, &user, &password))
   {
       usage(argv[0]);
       exit(1);
   }

   // The domain name to call myself, obtained from the gethostname()
   // system call.
   char buffer[100];
   memset(buffer, 0, sizeof (buffer));
   // Do not allow gethostname to write over the last NUL in buffer[].
   gethostname(buffer, (sizeof (buffer)) - 1);
   UtlString myDomainName(buffer, strlen(buffer));
   // Use "example.com" if gethostname() failed.
   if (myDomainName.isNull())
   {
      myDomainName = "example.com";
   }

   UtlString fromString = "sip:dialogwatch@" + myDomainName;
   Url fromUri(fromString, TRUE);

   // Create the SIP Subscribe Client

   SipLineMgr lineMgr;

   // Add credentials if they were specified.
   if (realm)
   {
      UtlString id;
      id += "sip:";
      id += user;
      id += "@";
      id += realm;
      Url identity(id, TRUE);

      SipLine line( fromUri  // user entered url
                   ,identity // identity url
                   ,user     // user
                   ,TRUE     // visible
                   ,SipLine::LINE_STATE_PROVISIONED
                   ,TRUE     // auto enable
                   ,FALSE    // use call handling
         );

      lineMgr.addLine(line);

      UtlString cred_input;
      UtlString cred_digest;

      cred_input.append(user);
      cred_input.append(":");
      cred_input.append(realm);
      cred_input.append(":");
      cred_input.append(password);

      NetMd5Codec::encode(cred_input.data(), cred_digest);

      fprintf(stderr,
              "Adding identity '%s': user='******' realm='%s' password='******' H(A1)='%s'\n",
              identity.toString().data(), user, realm, password, cred_digest.data()
         );

      assert(lineMgr.addCredentialForLine(identity, realm, user, cred_digest,
                                          HTTP_DIGEST_AUTHENTICATION));
   }

   SipUserAgent* pSipUserAgent =
      new SipUserAgent(port, port, PORT_NONE,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       NULL,
                       &lineMgr);
   // Add the 'eventlist' extension, so dialogwatch can subscribe to
   // event lists.
   pSipUserAgent->allowExtension("eventlist");
   if (!pSipUserAgent->isOk())
   {
       fprintf(stderr, "Unable to bind to port %d\n", port);
       exit(1);
   }

   SipDialogMgr dialogManager;

   SipRefreshManager refreshMgr(*pSipUserAgent, dialogManager);
   refreshMgr.start();

   SipSubscribeClient sipSubscribeClient(*pSipUserAgent, dialogManager,
                                         refreshMgr);
   sipSubscribeClient.start();

   // Construct a name-addr from targetURI, in case it contains parameters.
   UtlString toUri;
   toUri = "<";
   toUri += targetURI;
   toUri += ">";
   UtlString earlyDialogHandle;

   fprintf(stderr,
           "resourceId '%s' fromString '%s' toUri '%s' event '%s' content-type '%s' port=%d expiration=%d\n",
           targetURI, fromString.data(), toUri.data(), eventType, contentType,
           port, expiration);

   UtlBoolean status =
      sipSubscribeClient.addSubscription(targetURI,
                                         eventType,
                                         contentType,
                                         fromString.data(),
                                         toUri.data(),
                                         NULL,
                                         expiration,
                                         (void *) NULL,
                                         subscriptionStateCallback,
                                         notifyEventCallback,
                                         earlyDialogHandle);

   if (!status)
   {
      fprintf(stderr, "Subscription attempt failed.\n");
      exit(1);
   }
   else
   {
      fprintf(stderr, "Subscription attempt succeeded.  Handle: '%s'\n",
              earlyDialogHandle.data());
   }

   while (1)
   {
      sleep(1000);
   }
}
示例#19
0
int proxy()
{
    int proxyTcpPort;
    int proxyUdpPort;
    int proxyTlsPort;
    UtlString bindIp;
    int maxForwards;    
    UtlString domainName;
    UtlString proxyRecordRoute;
    UtlString routeName;
    UtlString authScheme;    
    UtlString ipAddress;

    OsMsgQShared::setQueuePreference(OsMsgQShared::QUEUE_UNLIMITED);

    OsSocket::getHostIp(&ipAddress);

    OsPath ConfigfileName = SipXecsService::Path(SipXecsService::ConfigurationDirType,
                                                 CONFIG_SETTINGS_FILE);
    OsConfigDb configDb;

    if(OS_SUCCESS != configDb.loadFromFile(ConfigfileName))
    {      
       exit(1);
    }
    // Initialize the OsSysLog...
    initSysLog(&configDb);
    std::set_terminate(catch_global);

    configDb.get(CONFIG_SETTING_BIND_IP, bindIp);
    if ((bindIp.isNull()) || !OsSocket::isIp4Address(bindIp))
    {
       bindIp = "0.0.0.0";
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "%s: %s", CONFIG_SETTING_BIND_IP, 
          bindIp.data());
    osPrintf("%s: %s", CONFIG_SETTING_BIND_IP, bindIp.data());    

    UtlString hostname;
    configDb.get("SIPX_PROXY_HOST_NAME", hostname);
    if (!hostname.isNull())
    {
       // bias the selection of SRV records so that if the name of this host is an alternative,
       // it wins in any selection based on random weighting.
       SipSrvLookup::setOwnHostname(hostname);
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_HOST_NAME : %s", hostname.data());
    
    proxyUdpPort = configDb.getPort("SIPX_PROXY_UDP_PORT");
    if (!portIsValid(proxyUdpPort))
    {
       proxyUdpPort = 5060;
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_UDP_PORT : %d", proxyUdpPort);
    proxyTcpPort = configDb.getPort("SIPX_PROXY_TCP_PORT") ;
    if (!portIsValid(proxyTcpPort))
    {
       proxyTcpPort = 5060;
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_TCP_PORT : %d", proxyTcpPort);
    proxyTlsPort = configDb.getPort("SIPX_PROXY_TLS_PORT") ;
    if (!portIsValid(proxyTlsPort))
    {
       proxyTlsPort = 5061;
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_TLS_PORT : %d", proxyTlsPort);

    configDb.get("SIPX_PROXY_MAX_FORWARDS", maxForwards);
    if(maxForwards <= 0) maxForwards = SIP_DEFAULT_MAX_FORWARDS;
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_MAX_FORWARDS : %d", maxForwards);
    osPrintf("SIPX_PROXY_MAX_FORWARDS : %d\n", maxForwards);

    int branchTimeout = -1;
    configDb.get("SIPX_PROXY_BRANCH_TIMEOUT", branchTimeout);
    if(branchTimeout < 4)
    {
        branchTimeout = 24;
    }

    int defaultExpires;
    int defaultSerialExpires;
    configDb.get("SIPX_PROXY_DEFAULT_EXPIRES", defaultExpires);
    configDb.get("SIPX_PROXY_DEFAULT_SERIAL_EXPIRES", defaultSerialExpires);
    if(defaultExpires <= 0 ) 
    {
            defaultExpires = DEFAULT_SIP_TRANSACTION_EXPIRES;
    }
    else if(defaultExpires > DEFAULT_SIP_TRANSACTION_EXPIRES) 
    {
        Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                      "SipXproxymain::proxy "
                      "large default expires value: %d NOT RECOMMENDED",
                      defaultExpires);
    }
    if(defaultSerialExpires <= 0 ||
       defaultSerialExpires >= defaultExpires) 
    {
            defaultSerialExpires = DEFAULT_SIP_SERIAL_EXPIRES;
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_DEFAULT_EXPIRES : %d", defaultExpires);
    osPrintf("SIPX_PROXY_DEFAULT_EXPIRES : %d\n", defaultExpires);
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_DEFAULT_SERIAL_EXPIRES : %d", defaultSerialExpires);
    osPrintf("SIPX_PROXY_DEFAULT_SERIAL_EXPIRES : %d\n", defaultSerialExpires);
      
    UtlString hostAliases;
    configDb.get("SIPX_PROXY_HOST_ALIASES", hostAliases);
    if(hostAliases.isNull())
    {
       hostAliases = ipAddress;
       char portBuf[20];
       sprintf(portBuf, ":%d", proxyUdpPort);
       hostAliases.append(portBuf);

       if(!routeName.isNull())
       {
          hostAliases.append(" ");
          hostAliases.append(routeName);
          char portBuf[20];
          sprintf(portBuf, ":%d", proxyUdpPort);
          hostAliases.append(portBuf);
       }
       Os::Logger::instance().log(FAC_SIP, PRI_NOTICE,
                     "SIPX_PROXY_HOST_ALIASES not configured"
                     " using implied value: %s",
                     hostAliases.data());
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_HOST_ALIASES : %s",
                  hostAliases.data());

    UtlString enableCallStateObserverSetting;
    configDb.get(CONFIG_SETTING_CALL_STATE, enableCallStateObserverSetting);

    bool enableCallStateLogObserver;
    if (   (enableCallStateObserverSetting.isNull())
        || ((0 == enableCallStateObserverSetting.compareTo("disable", UtlString::ignoreCase)))
        )
    {
       enableCallStateLogObserver = false;
    }
    else if (0 == enableCallStateObserverSetting.compareTo("enable", UtlString::ignoreCase))
    {
       enableCallStateLogObserver = true;
    }
    else
    {
       enableCallStateLogObserver = false;
       Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SipXproxymain:: invalid configuration value for "
                     CONFIG_SETTING_CALL_STATE " '%s' - should be 'enable' or 'disable'",
                     enableCallStateObserverSetting.data()
                     );
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, CONFIG_SETTING_CALL_STATE " : %s",
                  enableCallStateLogObserver ? "ENABLE" : "DISABLE" );

    UtlString callStateLogFileName;

    if (enableCallStateLogObserver)
    {
       configDb.get(CONFIG_SETTING_CALL_STATE_LOG, callStateLogFileName);
       if (callStateLogFileName.isNull())
       {
          callStateLogFileName = CALL_STATE_LOG_FILE_DEFAULT;
       }
       Os::Logger::instance().log(FAC_SIP, PRI_INFO, CONFIG_SETTING_CALL_STATE_LOG " : %s",
                     callStateLogFileName.data());
    }
    
    // Check if CSE logging should go into a database
    UtlString enableCallStateDbObserverSetting;
    configDb.get(CONFIG_SETTING_CALL_STATE_DB, enableCallStateDbObserverSetting);

    bool enableCallStateDbObserver;
    if (   (enableCallStateDbObserverSetting.isNull())
        || ((0 == enableCallStateDbObserverSetting.compareTo("disable", UtlString::ignoreCase)))
        )
    {
       enableCallStateDbObserver = false;
    }
    else if (0 == enableCallStateDbObserverSetting.compareTo("enable", UtlString::ignoreCase))
    {
       enableCallStateDbObserver = true;
    }
    else
    {
       enableCallStateDbObserver = false;
       Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SipAuthProxyMain:: invalid configuration value for %s "
                     " '%s' - should be 'enable' or 'disable'",
                     CONFIG_SETTING_CALL_STATE_DB, enableCallStateDbObserverSetting.data()
                     );
    }
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "%s : %s", CONFIG_SETTING_CALL_STATE_DB,
                  enableCallStateDbObserver ? "ENABLE" : "DISABLE" );

    UtlString callStateDbHostName;
    UtlString callStateDbName;
    UtlString callStateDbUserName;
    UtlString callStateDbDriver;    
    if (enableCallStateDbObserver)
    {
       configDb.get(CONFIG_SETTING_CALL_STATE_DB_HOST, callStateDbHostName);
       if (callStateDbHostName.isNull())
       {
          callStateDbHostName = CALL_STATE_DATABASE_HOST;
       }
       Os::Logger::instance().log(FAC_SIP, PRI_INFO, "%s : %s", CONFIG_SETTING_CALL_STATE_DB_HOST,
                     callStateDbHostName.data());
                     
       configDb.get(CONFIG_SETTING_CALL_STATE_DB_NAME, callStateDbName);
       if (callStateDbName.isNull())
       {
          callStateDbName = CALL_STATE_DATABASE_NAME;
       }
       Os::Logger::instance().log(FAC_SIP, PRI_INFO, "%s : %s",  CONFIG_SETTING_CALL_STATE_DB_NAME,
                     callStateDbName.data());
                     
       configDb.get(CONFIG_SETTING_CALL_STATE_DB_USER, callStateDbUserName);
       if (callStateDbUserName.isNull())
       {
          callStateDbUserName = CALL_STATE_DATABASE_USER;
       }
       Os::Logger::instance().log(FAC_SIP, PRI_INFO, "%s : %s", CONFIG_SETTING_CALL_STATE_DB_USER,
                     callStateDbUserName.data());                                          
                     
       configDb.get(CONFIG_SETTING_CALL_STATE_DB_DRIVER, callStateDbDriver);
       if (callStateDbDriver.isNull())
       {
          callStateDbDriver = CALL_STATE_DATABASE_DRIVER;
       }
       Os::Logger::instance().log(FAC_SIP, PRI_INFO, "%s : %s",  CONFIG_SETTING_CALL_STATE_DB_DRIVER,
                     callStateDbDriver.data());                          
    }    
    
    // Select logging method - database takes priority over XML file
    if (enableCallStateLogObserver && enableCallStateDbObserver)
    {
       enableCallStateLogObserver = false;
       Os::Logger::instance().log(FAC_SIP, PRI_WARNING, "SipXproxymain:: both XML and database call state "
                     "logging was enabled - turning off XML log, only use database logging");       
    }

    // Set the maximum amount of time that TCP connections can
    // stay around when they are not used.
    int      staleTcpTimeout = 3600;
    UtlString staleTcpTimeoutStr;

    // Check for missing parameter or empty value
    configDb.get("SIPX_PROXY_STALE_TCP_TIMEOUT", staleTcpTimeoutStr);
    if (staleTcpTimeoutStr.isNull())
    {
        staleTcpTimeout = 3600;
    }
    else
    {
        // get the parameter value as an integer
        configDb.get("SIPX_PROXY_STALE_TCP_TIMEOUT", staleTcpTimeout);
    }

    if(staleTcpTimeout <= 0) staleTcpTimeout = -1;
    else if(staleTcpTimeout < 180) staleTcpTimeout = 180;
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_STALE_TCP_TIMEOUT : %d",
                  staleTcpTimeout);
    osPrintf("SIPX_PROXY_STALE_TCP_TIMEOUT : %d\n", staleTcpTimeout);

    int maxNumSrvRecords = -1;
    configDb.get("SIPX_PROXY_DNSSRV_MAX_DESTS", maxNumSrvRecords);
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_DNSSRV_MAX_DESTS : %d",
              maxNumSrvRecords);
    // If explicitly set to a valid number
    if(maxNumSrvRecords > 0)
    {
        osPrintf("SIPX_PROXY_DNSSRV_MAX_DESTS : %d\n", maxNumSrvRecords);
    }
    else
    {
        maxNumSrvRecords = 4;
    }

    int dnsSrvTimeout = -1; //seconds
    configDb.get("SIPX_PROXY_DNSSRV_TIMEOUT", dnsSrvTimeout);
    Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_DNSSRV_TIMEOUT : %d",
              dnsSrvTimeout);
    // If explicitly set to a valid number
    if(dnsSrvTimeout > 0)
    {
        osPrintf("SIPX_PROXY_DNSSRV_TIMEOUT : %d\n", dnsSrvTimeout);
    }
    else
    {
        dnsSrvTimeout = 4;
    }
    
    // This is an obnoxious special option to work around a 
    // problem with Sonus gateways.  The Sonus proxy or  redirect
    // server gives a list of possible gateways to recurse in a
    // 300 response.  It does not assign any Q values so the proxy
    // gets the impression that it should fork them all in parallel.
    // When this option is enabled we recurse only the one with the
    // highest Q value.
    UtlString recurseOnlyOne300String;
    configDb.get("SIPX_PROXY_SPECIAL_300", recurseOnlyOne300String);
    recurseOnlyOne300String.toLower();
    UtlBoolean recurseOnlyOne300 = FALSE;
    if(recurseOnlyOne300String.compareTo("enable") == 0) 
    {
        recurseOnlyOne300 = TRUE;
        Os::Logger::instance().log(FAC_SIP, PRI_INFO, "SIPX_PROXY_SPECIAL_300 : ENABLE");
        osPrintf("SIPX_PROXY_SPECIAL_300 : ENABLE\n");
    }
    
    OsPath fileName = SipXecsService::Path(SipXecsService::ConfigurationDirType,
                                            FORWARDING_RULES_FILENAME);

    ForwardRules forwardingRules;

    OsFile ruleFile(fileName);
    if(ruleFile.exists())
    {
        if(OS_SUCCESS != forwardingRules.loadMappings(fileName))
        {
            Os::Logger::instance().log(FAC_SIP, PRI_WARNING, "WARNING: Failed to load: %s",
                fileName.data());
            osPrintf("WARNING: Failed to load: %s\n", fileName.data());
        }
    }
    else
    {
        // forwardingrules.xml is not readable; no processing is possible.
        Os::Logger::instance().log(FAC_SIP, PRI_CRIT,
                      "forwarding rules '%s' not found -- exiting",
                      fileName.data());
        exit(1);
    }
 
#ifdef TEST_PRINT
    { // scope the test stuff
        SipMessage foo;
        const char* uri = "sip:10.1.20.3:5100";
        const char* method = SIP_ACK_METHOD;
        const char* eventType = SIP_EVENT_CONFIG;
        foo.setRequestData(method, 
                           uri, //uri, 
                           "sip:[email protected]", // fromField, 
                           "\"lajdflsdk ff\"<sip:[email protected]>", // toField, 
                           "lkadsj902387", // callId, 
                           123, // CSeq,
                           "sip:10.1.1.123");// contactUrl

        // Set the event type
        foo.setHeaderValue(SIP_EVENT_FIELD, 
                            eventType, // event type
                            0);

        Url msgUrl(uri);
        UtlString routeTo;
        UtlString routeType;
        bool authRequired;
        OsStatus routeStatus = forwardingRules.getRoute(msgUrl, 
                                                        foo, 
                                                        routeTo, 
                                                        routeType,
                                                        authRequired);

        Url msgRouteToUri(routeTo);
        osPrintf("Message:\n\tmethod: %s\n\turi: %s\n\tevent: %s\nRouted:\n\tstring: %s\n\turi: %s\n\ttype: %s\n",
            method, uri, eventType, routeTo.data(), msgRouteToUri.toString().data(), routeType.data());
        if(routeStatus != OS_SUCCESS) 
            osPrintf("forwardingRules.getRoute returned: %d\n",
                    routeStatus);
    }
#endif // TEST_PRINT
    
    // Start the sip stack
    SipUserAgent* pSipUserAgent = new SipUserAgent(
        proxyTcpPort,
        proxyUdpPort,
        proxyTlsPort,
        NULL, // public IP address (not used in proxy)
        NULL, // default user (not used in proxy)
        bindIp,
        NULL, // outbound proxy
        NULL, // directory server
        NULL, // registry server
        NULL, // auth realm
        NULL, // auth DB
        NULL, // auth user IDs
        NULL, // auth passwords
        NULL, // line mgr
        SIP_DEFAULT_RTT, // first resend timeout
        FALSE, // default to proxy transaction
        SIPUA_DEFAULT_SERVER_UDP_BUFFER_SIZE, // socket layer read buffer size
        SIPUA_DEFAULT_SERVER_OSMSG_QUEUE_SIZE, // OsServerTask message queue size
        FALSE, // Use Next Available Port
        TRUE,  // Perform message checks 
        TRUE,  // Use symmetric signaling
        SipUserAgent::HANDLE_OPTIONS_AUTOMATICALLY);


    if (!pSipUserAgent->isOk())
    {
        Os::Logger::instance().log(FAC_SIP, PRI_EMERG, "SipUserAgent reported a problem, setting shutdown flag...");
        gShutdownFlag = TRUE;
    }
    pSipUserAgent->setDnsSrvTimeout(dnsSrvTimeout);
    pSipUserAgent->setMaxSrvRecords(maxNumSrvRecords);
    pSipUserAgent->setUserAgentHeaderProperty("sipXecs/sipXproxy");
    pSipUserAgent->setMaxForwards(maxForwards);
    pSipUserAgent->setDefaultExpiresSeconds(defaultExpires);
    pSipUserAgent->setDefaultSerialExpiresSeconds(defaultSerialExpires);
    pSipUserAgent->setMaxTcpSocketIdleTime(staleTcpTimeout);
    pSipUserAgent->setHostAliases(hostAliases);
    pSipUserAgent->setRecurseOnlyOne300Contact(recurseOnlyOne300);
    // Do not start the SipUserAgent until its message listeners are
    // set up by the creation of the SipRouter below.
    
    UtlString buffer;

    // Create the CSE observer, either writing to file or database
    SipXProxyCseObserver* cseObserver = NULL;
    CallStateEventWriter* pEventWriter = NULL;    
    if (enableCallStateLogObserver)
    {
       // Set up the call state event log file
       pEventWriter = new CallStateEventWriter_XML(callStateLogFileName.data());
    }
    else if (enableCallStateDbObserver)
    {
       pEventWriter = new CallStateEventWriter_DB(callStateDbName.data(),
                                                  callStateDbHostName.data(),
                                                  callStateDbUserName,
                                                  callStateDbDriver);      
    }                                            
       
    if (pEventWriter)
    {
       // get the identifier for this observer
       int protocol = OsSocket::UDP;
       UtlString domainName;
       int port;
       pSipUserAgent->getViaInfo(protocol, domainName, port);

       char portString[12];
       sprintf(portString,":%d", port);
       domainName.append(portString);
       
       // and start the observer
       cseObserver = new SipXProxyCseObserver(*pSipUserAgent, domainName, pEventWriter);
       cseObserver->start();
    }
    else
    {
      // Only log error if any event logging was enabled
      if (enableCallStateLogObserver || enableCallStateDbObserver)
      {      
         Os::Logger::instance().log(FAC_SIP, PRI_ERR,
                       "SipAuthProxyMain:: EventWriter could not be allocated"
                       );
         enableCallStateLogObserver = false;
         enableCallStateDbObserver = false;
      }
    }

    // Create a router to route stuff either
    // to a local server or on out to the real world
    SipRouter* pRouter = new SipRouter(*pSipUserAgent, 
                                       forwardingRules,
                                       configDb);

    // Start the router running
    pRouter->start();

    // Do not exit, let the proxy do its stuff
    while( !gShutdownFlag ) {
        OsTask::delay(1000);
    }
 
    // This is a server task so gracefully shutdown the
    // router task by deleting it.
    delete pRouter ;

    // Stop the SipUserAgent.
    pSipUserAgent->shutdown();
    // And delete it, too.
    delete pSipUserAgent ;

    // flush and close the call state event log
    if (enableCallStateLogObserver || enableCallStateDbObserver)
    {
      if (cseObserver)
      {
         delete cseObserver;
      }
      if (pEventWriter)
      {
         delete pEventWriter;
      }
    }

    // End the singleton threads.
    OsTimer::terminateTimerService();
    OsStunAgentTask::releaseInstance();

    return 0 ;
}
示例#20
0
 // Primitive to send a SIP message to the RLS server under test
 bool  sendToRlsServerUnderTest( SipMessage& msg )
 {
    return pSipUserAgent->send( msg );
 }
    void subscribeMwiClientTest()
    {
        smClientExpiration = -1;
        smNumClientNotifiesReceived = 0;
        smLastClientNotifyReceived = NULL;
        smNumClientSubResponsesReceived = 0;
        smLastClientSubResponseReceived = NULL;


        UtlString resourceId("[email protected]:");
        UtlString eventTypeKey("message-summary");
        UtlString eventType(eventTypeKey);
        UtlString from("Frida<sip:111@localhost:");
        UtlString to("Tia<sip:222@localhost:");
        UtlString contact("sip:[email protected]:");
        char portString[20];
        sprintf(portString, "%d", UNIT_TEST_SIP_PORT);
        resourceId.append(portString);
        from.append(portString);
        from.append('>');
        to.append(portString);
        to.append('>');
        contact.append(portString);
        SipUserAgent* userAgent = new SipUserAgent(UNIT_TEST_SIP_PORT, UNIT_TEST_SIP_PORT);
        userAgent->start();

        // Set up the subscribe client
        SipDialogMgr* clientDialogMgr = new SipDialogMgr();
        SipRefreshManager* refreshMgr = new SipRefreshManager(*userAgent, *clientDialogMgr);
        refreshMgr->start();
        SipSubscribeClient* subClient = new SipSubscribeClient(*userAgent, *clientDialogMgr, *refreshMgr);
        subClient->start();

        // Set up the subscribe server
        SipSubscribeServer* subServer = 
           SipSubscribeServer::buildBasicServer(*userAgent, 
                                                eventType);
        SipSubscriptionMgr* subMgr = subServer->getSubscriptionMgr(eventType);
        SipDialogMgr* serverDialogMgr = subMgr->getDialogMgr();
        SipPublishContentMgr* contentMgr = subServer->getPublishMgr(eventType);
        HttpBody* preexistingBodyPtr = NULL;
        UtlBoolean isDefaultContent;

        subServer->start();
        // Enable the handler for the MWI server
        subServer->enableEventType(eventType, userAgent);

        //CPPUNIT_ASSERT(TRUE);
        //ASSERT_STR_EQUAL("a", "a");

        // Create a crude Subscription server/observer
        OsMsgQ incomingServerMsgQueue;
        // Register an interest in SUBSCRIBE requests 
        // for this event type
        userAgent->addMessageObserver(incomingServerMsgQueue,
                                    SIP_SUBSCRIBE_METHOD,
                                    TRUE, // requests
                                    FALSE, // no reponses
                                    TRUE, // incoming
                                    FALSE, // no outgoing
                                    eventType,
                                    NULL,
                                    NULL);

        OsMsgQ incomingClientMsgQueue;
        userAgent->addMessageObserver(incomingClientMsgQueue,
                                    SIP_SUBSCRIBE_METHOD,
                                    FALSE, // no requests
                                    TRUE, // reponses
                                    TRUE, // incoming
                                    FALSE, // no outgoing
                                    eventType,
                                    NULL,
                                    NULL);

        // Should not be any pre-existing content
        CPPUNIT_ASSERT(!contentMgr->getContent(resourceId, eventTypeKey, NULL, preexistingBodyPtr, 
            isDefaultContent));
        int numDefaultContent = -1;
        int numResourceSpecificContent = -1;
        int numCallbacksRegistered = -1;
        contentMgr->getStats(numDefaultContent,
                             numResourceSpecificContent,
                             numCallbacksRegistered);
        CPPUNIT_ASSERT(numDefaultContent == 0);
        CPPUNIT_ASSERT(numResourceSpecificContent == 0);
        CPPUNIT_ASSERT(numCallbacksRegistered == 1);

        // Create a subscribe request, send it and keep it refreshed
        UtlString earlyDialogHandle;
        CPPUNIT_ASSERT(subClient->addSubscription(resourceId,
                                                  eventType,
                                                  from,
                                                  to,
                                                  contact,
                                                  60, // seconds expiration
                                                  this,
                                                  subStateCallback,
                                                  notifyCallback,
                                                  earlyDialogHandle));


        contentMgr->getStats(numDefaultContent,
                             numResourceSpecificContent,
                             numCallbacksRegistered);
        CPPUNIT_ASSERT(numDefaultContent == 0);
        CPPUNIT_ASSERT(numResourceSpecificContent == 0);
        CPPUNIT_ASSERT(numCallbacksRegistered == 1);

        // See if a subscribe was sent and received
       /*OsTime messageTimeout(5, 0);  // 5 seconds
       OsMsg* osMessage = NULL;
       const SipMessage* subscribeResponse = NULL;
       const SipMessage* notifyRequest = NULL;
       incomingServerMsgQueue.receive(osMessage, messageTimeout);
       CPPUNIT_ASSERT(osMessage);
       int msgType = osMessage->getMsgType();
       int msgSubType = osMessage->getMsgSubType();
       CPPUNIT_ASSERT(msgType == OsMsg::PHONE_APP);
       CPPUNIT_ASSERT(msgSubType == SipMessage::NET_SIP_MESSAGE);
       const SipMessage* sipMessage = ((SipMessageEvent*)osMessage)->getMessage();
       int messageType = ((SipMessageEvent*)osMessage)->getMessageStatus();
       CPPUNIT_ASSERT(sipMessage);
       CPPUNIT_ASSERT(messageType == SipMessageEvent::APPLICATION);*/
       const SipMessage* serverSideSubRequest = NULL;
       CPPUNIT_ASSERT(removeMessage(incomingServerMsgQueue,
                     5000, // milliseconds
                     serverSideSubRequest));
       CPPUNIT_ASSERT(serverSideSubRequest); // Sub request got to server

       const SipMessage* clientSideSubResponse = NULL;
       CPPUNIT_ASSERT(removeMessage(incomingClientMsgQueue,
                      5000, // milliseconds
                      clientSideSubResponse));
       CPPUNIT_ASSERT(clientSideSubResponse);

       //UtlString clientStateString;
       //subClient->dumpStates(clientStateString);
       //printf("client states:\n%s\n", clientStateString.data());


        int waitIterations = 0;
        while(smLastClientNotifyReceived == NULL ||
            smLastClientSubResponseReceived == NULL)
        {
            OsTask::delay(100);
            waitIterations++;
            if(waitIterations >= 100)
            {
                break;
            }
        }

        CPPUNIT_ASSERT(smLastClientSubResponseReceived);
        CPPUNIT_ASSERT(smLastClientNotifyReceived);
        SipMessage* firstSubResponse = smLastClientSubResponseReceived;
        smLastClientSubResponseReceived = NULL;
        int firstSubCseq;
        firstSubResponse->getCSeqField(&firstSubCseq, NULL);
        SipMessage* firstNotifyRequest = smLastClientNotifyReceived;
        smLastClientNotifyReceived = NULL;
        int firstNotifyCseq;
        firstNotifyRequest->getCSeqField(&firstNotifyCseq, NULL);
        CPPUNIT_ASSERT(firstSubCseq == 1);
        CPPUNIT_ASSERT(firstNotifyCseq == 0);

        //subClient->dumpStates(clientStateString);
        //printf("client states:\n%s\n", clientStateString.data());

        //UtlString dialogMgrDumpString;
        //clientDialogMgr.toString(dialogMgrDumpString);
        //printf("Client Dialog manager dump 1:\n%s\n",
        //       dialogMgrDumpString.data());

        // The refresh manager should re-SUBSCRIBE
        // Wait for the next notify request and subscribe response
        int secondMessageWait = 60;
        int resendTimeout = 0.55 * secondMessageWait;
        if(resendTimeout < 40)
        {
            resendTimeout = 40;
        }
        for(int i = 0; i < secondMessageWait - 1; i++)
        {
            if(i == resendTimeout - 1)
            {
                printf("v");
            }
            else
            {
                printf("=");
            }
        }
        printf("v\n");
        SipMessage* secondSubResponse = NULL;
        SipMessage* secondNotifyRequest = NULL;

        while(secondNotifyRequest == NULL ||
            secondSubResponse == NULL)
        {
            OsTask::delay(1000);
            if(smLastClientSubResponseReceived)
            {
                secondSubResponse = smLastClientSubResponseReceived;
                smLastClientSubResponseReceived = NULL;
            }
            if(smLastClientNotifyReceived)
            {
                secondNotifyRequest = smLastClientNotifyReceived;
                smLastClientNotifyReceived = NULL;
            }
            printf(".");
            waitIterations++;
            if(waitIterations >= secondMessageWait)
            {
                printf("\n");
                break;
            }
        }

        //subClient->dumpStates(clientStateString);
        //printf("client states:\n%s\n", clientStateString.data());

        //clientDialogMgr.toString(dialogMgrDumpString);
        //printf("Client Dialog manager dump 2:\n%s\n",
        //       dialogMgrDumpString.data());

       CPPUNIT_ASSERT(removeMessage(incomingServerMsgQueue,
                     5000, // milliseconds
                     serverSideSubRequest));
       CPPUNIT_ASSERT(serverSideSubRequest); // Sub request got to server
       //UtlString subRequestDump;
       //int len;
       //serverSideSubRequest->getBytes(&subRequestDump, &len);
       //printf("server side sub request:\n%s\n",
       //    subRequestDump.data());

       CPPUNIT_ASSERT(removeMessage(incomingClientMsgQueue,
                      5000, // milliseconds
                      clientSideSubResponse));
       CPPUNIT_ASSERT(clientSideSubResponse); // Sub respon got to client
       //UtlString subResponseDump;
       //clientSideSubResponse->getBytes(&subResponseDump, &len);
       //printf("client side sub response:\n%s\n",
       //       subResponseDump.data());

        CPPUNIT_ASSERT(secondNotifyRequest);
        CPPUNIT_ASSERT(secondSubResponse);
        int secondSubCseq = -1;
        int secondNotifyCseq = -1;
        smLastClientSubResponseReceived = NULL;
        secondSubResponse->getCSeqField(&secondSubCseq, NULL);
        smLastClientNotifyReceived = NULL;
        secondNotifyRequest->getCSeqField(&secondNotifyCseq, NULL);
        CPPUNIT_ASSERT(firstSubCseq < secondSubCseq);
        CPPUNIT_ASSERT(firstNotifyCseq < secondNotifyCseq);

        // Unregister the queues so we stop receiving messages on them
        userAgent->removeMessageObserver(incomingServerMsgQueue);
        userAgent->removeMessageObserver(incomingClientMsgQueue);

        refreshMgr->requestShutdown();
        subClient->requestShutdown();

    }
示例#22
0
// Constructor
SipXProxyCseObserver::SipXProxyCseObserver(SipUserAgent&         sipUserAgent,
                                           const UtlString&      dnsName,
                                           CallStateEventWriter* pWriter
                                           ) :
   OsServerTask("SipXProxyCseObserver-%d", NULL, 2000),
   mpSipUserAgent(&sipUserAgent),
   mpBuilder(NULL),
   mpWriter(pWriter),
   mSequenceNumber(0),
   mFlushTimer(getMessageQueue(), 0)
{
   OsTime timeNow;
   OsDateTime::getCurTime(timeNow);
   UtlString event;
   
   if (mpWriter)
   {
      switch (pWriter->getLogType())
      {
      case CallStateEventWriter::CseLogFile:
         mpBuilder = new CallStateEventBuilder_XML(dnsName);
         break;
      case CallStateEventWriter::CseLogDatabase:
         mpBuilder = new CallStateEventBuilder_DB(dnsName);
         break;
      }
      if (mpBuilder)
      {
         if (pWriter->openLog())
         {
            mpBuilder->observerEvent(mSequenceNumber, timeNow, CallStateEventBuilder::ObserverReset,
                                     "SipXProxyCseObserver");      
            mpBuilder->finishElement(event);      

            if (!mpWriter->writeLog(event.data()))
            {      
               OsSysLog::add(FAC_SIP, PRI_ERR,
                             "SipXProxyCseObserver initial event log write failed - disabling writer");
               mpWriter = NULL;                 
            }
            else
            {
               mpWriter->flush(); // try to ensure that at least the sequence restart gets to the file 
            }
         }
         else
         {
            OsSysLog::add(FAC_SIP, PRI_ERR,
                          "SipXProxyCseObserver initial event log write failed - disabling writer");
            mpWriter = NULL;
            
            // Set correct state even if nothing is written
            mpBuilder->observerEvent(mSequenceNumber, timeNow, CallStateEventBuilder::ObserverReset, "");                 
            mpBuilder->finishElement(event);             
         }
      }
   }

   // set up periodic timer to flush log file
   mFlushTimer.periodicEvery(OsTime(), OsTime(SipXProxyCallStateFlushInterval, 0)) ;

  // Register to get incoming requests
   sipUserAgent.addMessageObserver(*getMessageQueue(),
                                   SIP_BYE_METHOD,
                                   TRUE, // Requests,
                                   FALSE, //Responses,
                                   TRUE, //Incoming,
                                   FALSE, //OutGoing,
                                   "", //eventName,
                                   NULL, // any session
                                   NULL // no observerData
                                   );
   sipUserAgent.addMessageObserver(*getMessageQueue(),
                                   SIP_INVITE_METHOD,
                                   TRUE, // Requests,
                                   TRUE, //Responses,
                                   TRUE, //Incoming,
                                   FALSE, //OutGoing,
                                   "", //eventName,
                                   NULL, // any session
                                   NULL // no observerData
                                   );
   sipUserAgent.addMessageObserver(*getMessageQueue(),
                                   SIP_REFER_METHOD,
                                   TRUE, // Requests,
                                   FALSE, //Responses,
                                   TRUE, //Incoming,
                                   FALSE, //OutGoing,
                                   "", //eventName,
                                   NULL, // any session
                                   NULL // no observerData
                                   );                                   
}
示例#23
0
   void instantiateAllTestFixtures( UtlString AppearanceGroupFile,
                                    //< Name of the appearance group file to use for the test.  The filename
                                    //< specified must exist in .../sipXrls/src/test/saadata/
                                    UtlString subscriptionDbName,
                                    //< Specifies the subscription DB to use for the test.  The name
                                    //< is used to select which of the files in .../sipXrls/src/test/saadata/
                                    //< will get used to preload the subscription IMDB.  The name provided here is the
                                    //< xml file in .../sipXrls/src/test/saadata/ without the ".xml" extension.
                                    UtlString credentialDbName,
                                    //< Specifies the credential DB to use for the test.  The name
                                    //< is used to select which of the files in .../sipXrls/src/test/saadata/
                                    //< will get used to preload the credential IMDB.  The name provided here is the
                                    //< xml file in .../sipXrls/src/test/saadata/ without the ".xml" extension.
                                    UtlString domainName
                                    //< Specify the domain name to use for the test
                                    )
   {
      mCredentialDbName = credentialDbName;
      // force copy of input files into the 'work' directory
      sipDbContext.inputFile( subscriptionDbName + ".xml" );
      sipDbContext.inputFile( credentialDbName + ".xml" );
      UtlString tempAppearanceGroupFile = UtlString(TEST_DATA_DIR) + "/" + AppearanceGroupFile;

      pSipUserAgent = new SipUserAgent( 45141, 45141, 45142
                                       ,"127.0.0.1"  // default publicAddress
                                       ,NULL         // default defaultUser
                                       ,"127.0.0.1" );  // default defaultSipAddress

      // Stop SipUserAgent from rejecting all SUBSCRIBEs
      pSipUserAgent->allowMethod(SIP_SUBSCRIBE_METHOD, true);

      SipXecsService* saaTestService = new SipXecsService("sipxsaaTest", "SIPX_SAA", "TestCase");

      pAppearanceAgentUnderTest = new AppearanceAgent(saaTestService,
                                       domainName, // domain
                                       "rlstest.test", // realm
                                       NULL,  // line manager
                                       45140, // TCP port
                                       45140, // UDP port
                                       45140, // TLS port
                                       "127.0.0.1", // Bind IP address
                                       &tempAppearanceGroupFile,
                                       (24 * 60 * 60), // Default subscription refresh interval
                                       (60 * 60), // Default subscription resubscribe interval.
                                       (40 * 60), // Default minimum subscription resubscribe interval.
                                       (20 * 60), // Default seized subscription resubscribe interval.
                                       250,  // publishing delay?
                                       20,   // The maximum number of reg subscriptions per group.
                                       32, 3600, 86400, // Subscribe server expiration parameters
                                       subscriptionDbName,
                                       credentialDbName );

      pUasOutputProcessor = new OutputProcessorFixture();

      pAppearanceAgentUnderTest->mServerUserAgent.addSipOutputProcessor( pUasOutputProcessor );

      UtlString proxyAddress;
      proxyAddress = "127.0.0.1:45140";

      pSipUserAgent->setProxyServers(proxyAddress.data());

      pAppearanceAgentUnderTest->start();
   }
示例#24
0
   // Test for XECS-243, Subscribe Server does not send NOTIFY when it
   // processes a re-SUBSCRIBE.
//*** Error scenario not yet reproduced.
   void resubscribeContentTest()
      {
         // Test MWI messages
         const char* mwiSubscribe =
            "SUBSCRIBE sip:111@localhost SIP/2.0\r\n"
            "From: <sip:[email protected]>;tag=1612c1612\r\n"
            "To: <sip:[email protected]>\r\n"
            "Cseq: 1 SUBSCRIBE\r\n"
            "Event: message-summary\r\n"
            "Accept: application/simple-message-summary\r\n"
            "Expires: 3600\r\n"
            "Date: Tue, 26 Apr 2005 14:59:30 GMT\r\n"
            "Max-Forwards: 20\r\n"
            "User-Agent: Pingtel/2.2.0 (VxWorks)\r\n"
            "Accept-Language: en\r\n"
            "Supported: sip-cc, sip-cc-01, timer, replaces\r\n"
            "Content-Length: 0\r\n"
            "\r\n";

         // Send a SUBSCRIBE to ourselves
         SipMessage mwiSubscribeRequest(mwiSubscribe);
         {
            UtlString c;
            CallId::getNewCallId(c);
            mwiSubscribeRequest.setCallIdField(c);
         }
         mwiSubscribeRequest.setSipRequestFirstHeaderLine(SIP_SUBSCRIBE_METHOD,
                                                          aor,
                                                          SIP_PROTOCOL_VERSION);
         mwiSubscribeRequest.setContactField(aor_name_addr);

         CPPUNIT_ASSERT(userAgentp->send(mwiSubscribeRequest));

         // We should get a 202 response and a NOTIFY request in the queue
         // Send a 500 response to the NOTIFY.
         OsTime messageTimeout(1, 0);  // 1 second
         {
            const SipMessage* subscribeResponse;
            const SipMessage* notifyRequest;
            runListener(incomingClientMsgQueue,
                        *userAgentp,
                        messageTimeout,
                        messageTimeout,
                        notifyRequest,
                        subscribeResponse,
                        SIP_SERVER_INTERNAL_ERROR_CODE,
                        FALSE,
                        0,
                        NULL);

            // We should have received a SUBSCRIBE response and a NOTIFY request.
            CPPUNIT_ASSERT(subscribeResponse);
            CPPUNIT_ASSERT(notifyRequest);

            CPPUNIT_ASSERT(subscribeResponse->getResponseStatusCode() ==
                           SIP_ACCEPTED_CODE);

            // The NOTIFY should have no body because none has been published yet.
            {
               const HttpBody* bodyPtr = notifyRequest->getBody();
               CPPUNIT_ASSERT(bodyPtr == NULL);
            }
         }

         // Send a re-SUBSCRIBE
         mwiSubscribeRequest.incrementCSeqNumber();
         // Leave the Expires header with the default value.

         CPPUNIT_ASSERT(userAgentp->send(mwiSubscribeRequest));

         // We should get a 202 response and a NOTIFY request in the queue
         {
            const SipMessage* subscribeResponse;
            const SipMessage* notifyRequest;
            runListener(incomingClientMsgQueue,
                        *userAgentp,
                        messageTimeout,
                        messageTimeout,
                        notifyRequest,
                        subscribeResponse,
                        SIP_OK_CODE,
                        FALSE,
                        0,
                        NULL);

            // We should have received a SUBSCRIBE response and a NOTIFY request.
            CPPUNIT_ASSERT(subscribeResponse);
            CPPUNIT_ASSERT(notifyRequest);

            CPPUNIT_ASSERT(subscribeResponse->getResponseStatusCode() ==
                           SIP_ACCEPTED_CODE);

            // The NOTIFY should have no body because none has been published yet.
            {
               const HttpBody* bodyPtr = notifyRequest->getBody();
               CPPUNIT_ASSERT(bodyPtr == NULL);
            }
         }
      }
示例#25
0
   // Test for XECS-247, When subscribe server receives 481 for a
   // NOTIFY, it does not terminate the subscription.
   // Test for XECS-282, When subscribe server receives 500 for a
   // NOTIFY, it does not terminate the subscription.
   // Verify that subscription is terminated when NOTIFY returns a variety
   // of error responses.  (Retry-After suppresses termination.  That case
   // is tested in terminateSubscriptionOnErrorRetryAfter.)
   void terminateSubscriptionOnError()
      {
         // Test MWI messages
         const char* mwiSubscribe =
            "SUBSCRIBE sip:111@localhost SIP/2.0\r\n"
            "From: <sip:[email protected]>;tag=1612c1612\r\n"
            "To: <sip:[email protected]>\r\n"
            "Cseq: 1 SUBSCRIBE\r\n"
            "Event: message-summary\r\n"
            "Accept: application/simple-message-summary\r\n"
            "Expires: 3600\r\n"
            "Date: Tue, 26 Apr 2005 14:59:30 GMT\r\n"
            "Max-Forwards: 20\r\n"
            "User-Agent: Pingtel/2.2.0 (VxWorks)\r\n"
            "Accept-Language: en\r\n"
            "Supported: sip-cc, sip-cc-01, timer, replaces\r\n"
            "Content-Length: 0\r\n"
            "\r\n";

         // Loop through this scenario for a series of response codes.
         int test_codes[] = { SIP_BAD_REQUEST_CODE,
                              SIP_NOT_FOUND_CODE,
                              SIP_BAD_TRANSACTION_CODE,
                              499,
                              SIP_SERVER_INTERNAL_ERROR_CODE,
                              SIP_SERVICE_UNAVAILABLE_CODE,
                              599,
                              SIP_GLOBAL_BUSY_CODE,
                              699 };
         for (unsigned int i = 0;
              i < sizeof (test_codes) / sizeof (test_codes[0]);
              i++)
         {
            // Send a SUBSCRIBE to ourselves
            SipMessage mwiSubscribeRequest(mwiSubscribe);
            {
               UtlString c;
               CallId::getNewCallId(c);
               mwiSubscribeRequest.setCallIdField(c);
            }
            mwiSubscribeRequest.setSipRequestFirstHeaderLine(SIP_SUBSCRIBE_METHOD,
                                                             aor,
                                                             SIP_PROTOCOL_VERSION);
            mwiSubscribeRequest.setContactField(aor_name_addr);
            mwiSubscribeRequest.incrementCSeqNumber();

            CPPUNIT_ASSERT(userAgentp->send(mwiSubscribeRequest));

            // We should get a 202 response and a NOTIFY request in the queue
            // Send the specified response to the NOTIFY.
            OsTime messageTimeout(1, 0);  // 1 second
            {
               const SipMessage* subscribeResponse;
               const SipMessage* notifyRequest;
               runListener(incomingClientMsgQueue,
                           *userAgentp,
                           messageTimeout,
                           messageTimeout,
                           notifyRequest,
                           subscribeResponse,
                           test_codes[i],
                           FALSE,
                           0,
                           NULL);

               // We should have received a SUBSCRIBE response and a NOTIFY request.
               CPPUNIT_ASSERT(subscribeResponse);

               // Extract the to-tag in the response, apply it to
               // mwiSubscribeRequest.
               Url toUrl;
               subscribeResponse->getToUrl(toUrl);
               UtlString toTag;
               toUrl.getFieldParameter("tag", toTag);
               mwiSubscribeRequest.setToFieldTag(toTag);

               CPPUNIT_ASSERT(notifyRequest);

               CPPUNIT_ASSERT(subscribeResponse->getResponseStatusCode() ==
                              SIP_ACCEPTED_CODE);
            }

            // Wait for the subscription to be ended.
            OsTask::delay(100);

            // Send a re-SUBSCRIBE in the existing dialog, to find out if the
            // subscription was terminated or not.
            mwiSubscribeRequest.incrementCSeqNumber();
            // Leave the Expires header with the default value.

            CPPUNIT_ASSERT(userAgentp->send(mwiSubscribeRequest));

            // We should get a 481 response and no NOTIFY, because the
            // subscription has been terminated.
            {
               const SipMessage* subscribeResponse;
               const SipMessage* notifyRequest;
               runListener(incomingClientMsgQueue,
                           *userAgentp,
                           messageTimeout,
                           messageTimeout,
                           notifyRequest,
                           subscribeResponse,
                           SIP_OK_CODE,
                           FALSE,
                           0,
                           NULL);

               // We should have received a SUBSCRIBE response and no NOTIFY request.
               CPPUNIT_ASSERT(subscribeResponse);
               CPPUNIT_ASSERT(subscribeResponse->getResponseStatusCode() ==
                              SIP_BAD_TRANSACTION_CODE);
               CPPUNIT_ASSERT(!notifyRequest);
            }
         }
      }
示例#26
0
   // XECS-1810: Verify that subscription is *not* terminated when NOTIFY
   // returns a Timeout error.
   void terminateSubscriptionOnErrorTimeout()
      {
         // Test MWI messages
         const char* mwiSubscribe =
            "SUBSCRIBE sip:111@localhost SIP/2.0\r\n"
            "From: <sip:[email protected]>;tag=1612c1612\r\n"
            "To: <sip:[email protected]>\r\n"
            "Cseq: 1 SUBSCRIBE\r\n"
            "Event: message-summary\r\n"
            "Accept: application/simple-message-summary\r\n"
            "Expires: 3600\r\n"
            "Date: Tue, 4 Nov 2008 15:59:30 GMT\r\n"
            "Max-Forwards: 20\r\n"
            "User-Agent: Pingtel/2.2.0 (VxWorks)\r\n"
            "Accept-Language: en\r\n"
            "Supported: sip-cc, sip-cc-01, timer, replaces\r\n"
            "Content-Length: 0\r\n"
            "\r\n";

         // Send a SUBSCRIBE to ourselves
         SipMessage mwiSubscribeRequest(mwiSubscribe);
         {
            UtlString c;
            CallId::getNewCallId(c);
            mwiSubscribeRequest.setCallIdField(c);
         }
         mwiSubscribeRequest.setSipRequestFirstHeaderLine(SIP_SUBSCRIBE_METHOD,
                                                          aor,
                                                          SIP_PROTOCOL_VERSION);
         mwiSubscribeRequest.setContactField(aor_name_addr);
         mwiSubscribeRequest.incrementCSeqNumber();

         CPPUNIT_ASSERT(userAgentp->send(mwiSubscribeRequest));

         // We should get a 202 response and a NOTIFY request in the queue
         // Send a Timeout error response to the NOTIFY.
         OsTime messageTimeout(1, 0);  // 1 second
         {
            const SipMessage* subscribeResponse;
            const SipMessage* notifyRequest;
            runListener(incomingClientMsgQueue,
                        *userAgentp,
                        messageTimeout,
                        messageTimeout,
                        notifyRequest,
                        subscribeResponse,
                        SIP_REQUEST_TIMEOUT_CODE,
                        FALSE,
                        0,
                        NULL);

            // We should have received a SUBSCRIBE response and a NOTIFY request.
            CPPUNIT_ASSERT(subscribeResponse);
            CPPUNIT_ASSERT(subscribeResponse->getResponseStatusCode() == SIP_ACCEPTED_CODE);
            CPPUNIT_ASSERT(notifyRequest);

            // Extract the to-tag in the response, apply it to mwiSubscribeRequest.
            // This allows the re-SUBSCRIBE below to be applied to the existing dialog.
            Url toUrl;
            subscribeResponse->getToUrl(toUrl);
            UtlString toTag;
            toUrl.getFieldParameter("tag", toTag);
            mwiSubscribeRequest.setToFieldTag(toTag);
         }

         // Send a re-SUBSCRIBE in the existing dialog, to find out if the
         // subscription was terminated or not.
         mwiSubscribeRequest.incrementCSeqNumber();
         // Leave the Expires header with the default value.

         CPPUNIT_ASSERT(userAgentp->send(mwiSubscribeRequest));

         // We should get a 202 response and a NOTIFY, because the Timeout
         // error suppresses the termination of the subscription.
         {
            const SipMessage* subscribeResponse;
            const SipMessage* notifyRequest;
            runListener(incomingClientMsgQueue,
                        *userAgentp,
                        messageTimeout,
                        messageTimeout,
                        notifyRequest,
                        subscribeResponse,
                        SIP_OK_CODE,
                        FALSE,
                        0,
                        NULL);

            // We should have received a SUBSCRIBE response and no NOTIFY request.
            CPPUNIT_ASSERT(subscribeResponse);
            CPPUNIT_ASSERT(notifyRequest);
            CPPUNIT_ASSERT(subscribeResponse->getResponseStatusCode() == SIP_ACCEPTED_CODE);
         }
      }
示例#27
0
   void instantiateAllTestFixtures( UtlString resourceListFile,
                                    //< Name of the resource list to use for the test.  The filename
                                    //< specified mus texist in .../sipXrls/src/test/rlsdata/
                                    UtlString subscriptionDbName, 
                                    //< Specifies the subscription DB to use for the test.  The name 
                                    //< is used to select which of the files in .../sipXrls/src/test/rlsdata/
                                    //< will get used to preload the subscription IMDB.  The name provided here is the 
                                    //< xml file in .../sipXrls/src/test/rlsdata/ without the ".xml" extension.
                                    UtlString credentialDbName,
                                    //< Specifies the credential DB to use for the test.  The name 
                                    //< is used to select which of the files in .../sipXrls/src/test/rlsdata/
                                    //< will get used to preload the credential IMDB.  The name provided here is the 
                                    //< xml file in .../sipXrls/src/test/rlsdata/ without the ".xml" extension.
                                    UtlString domianName,
                                    //< Specify the domain name to use for the test
                                    UtlBoolean routeAllRequestsToRlsServer
                                    //< Send all requests to either the RLS Server UA or the RLS Client UA
                                    //< The Client UA typically deals with the outgoing subscriptions and
                                    //< the Server UA deals witht the incoming subscriptions
                                    )
   {
      mCredentialDbName = credentialDbName;
      // force copy of input files into the 'work' directory
      sipDbContext.inputFile( subscriptionDbName + ".xml" );
      sipDbContext.inputFile( credentialDbName + ".xml" );
      UtlString tempResourceListFile = UtlString(TEST_DATA_DIR) + "/" + resourceListFile;

      pSipUserAgent = new SipUserAgent( 45141, 45141, 45142
                                       ,"127.0.0.1"  // default publicAddress
                                       ,NULL         // default defaultUser
                                       ,"127.0.0.1" );  // default defaultSipAddress

      // Stop SipUserAgent from rejecting all SUBSCRIBEs
      pSipUserAgent->allowMethod(SIP_SUBSCRIBE_METHOD, true);

      SipXecsService* rlsTestService = new SipXecsService("sipxrlsTest", "SIPX_RLS", "TestCase");

      pResourceServerUnderTest = new ResourceListServer(rlsTestService,
                                       domianName, // domain 
                                       "rlstest.test", // realm
                                       NULL, 
                                       DIALOG_EVENT_TYPE, 
                                      DIALOG_EVENT_CONTENT_TYPE,
                                       45140, // TCP port
                                       45140, // UDP port
                                       45140, // TLS port
                                       "127.0.0.1", // Bind IP address
                                       &tempResourceListFile,
                                       (60 * 60), // Default subscription resubscribe interval.
                                       (40 * 60), // Default minimum subscription resubscribe interval.
                                       250,  // publishing delay? 
                                       20,   // The maximum number of reg subscriptions per resource.
                                       20,   // The maximum number of contacts per reg subscription.
                                       20,   // The maximum number of resource instances per contact
                                       20,    // The maximum number of dialogs per resource instance
                                       32, 3600, 86400, // Subscribe server expiration parameters
                                       subscriptionDbName,
                                       credentialDbName );

      pUacOutputProcessor = new OutputProcessorFixture();
      pUasOutputProcessor = new OutputProcessorFixture();
      
      pResourceServerUnderTest->mClientUserAgent.addSipOutputProcessor( pUacOutputProcessor );
      pResourceServerUnderTest->mServerUserAgent.addSipOutputProcessor( pUasOutputProcessor );

      UtlString proxyAddress;
      if(routeAllRequestsToRlsServer)
      {
         proxyAddress = "127.0.0.1:45140";
      }
      else
      {
         int pPort;
         pResourceServerUnderTest->mClientUserAgent.getLocalAddress(&proxyAddress, &pPort);
         proxyAddress.append(':');
         proxyAddress.appendNumber(pPort);
      }

      pSipUserAgent->setProxyServers(proxyAddress.data());

      pResourceServerUnderTest->start();
   }
示例#28
0
   // Check the Contact header of responses to SUBSCRIBE.
   // Check the Contact header of NOTIFY.
   // XECS-297 and XECS-298.
   void responseContact()
      {
         // Test MWI messages
         const char* mwiSubscribe =
            "SUBSCRIBE sip:111@localhost SIP/2.0\r\n"
            "From: <sip:[email protected]>;tag=1612c1612\r\n"
            "To: <sip:[email protected]>\r\n"
            "Cseq: 1 SUBSCRIBE\r\n"
            "Event: message-summary\r\n"
            "Accept: application/simple-message-summary\r\n"
            "Expires: 3600\r\n"
            "Date: Tue, 26 Apr 2005 14:59:30 GMT\r\n"
            "Max-Forwards: 20\r\n"
            "User-Agent: Pingtel/2.2.0 (VxWorks)\r\n"
            "Accept-Language: en\r\n"
            "Supported: sip-cc, sip-cc-01, timer, replaces\r\n"
            "Content-Length: 0\r\n"
            "\r\n";

         // Send a SUBSCRIBE to ourselves
         SipMessage mwiSubscribeRequest(mwiSubscribe);
         {
            UtlString c;
            CallId::getNewCallId(c);
            mwiSubscribeRequest.setCallIdField(c);
         }
         mwiSubscribeRequest.setSipRequestFirstHeaderLine(SIP_SUBSCRIBE_METHOD,
                                                          aor,
                                                          SIP_PROTOCOL_VERSION);
         mwiSubscribeRequest.setContactField(aor_name_addr);

         CPPUNIT_ASSERT(userAgentp->send(mwiSubscribeRequest));

         // We should get a 202 response and a NOTIFY request in the queue
         // Send the specified response to the NOTIFY.
         OsTime messageTimeout(1, 0);  // 1 second
         {
            const SipMessage* subscribeResponse;
            const SipMessage* notifyRequest;
            runListener(incomingClientMsgQueue,
                        *userAgentp,
                        messageTimeout,
                        messageTimeout,
                        notifyRequest,
                        subscribeResponse,
                        SIP_OK_CODE,
                        FALSE,
                        0,
                        NULL);

            // We should have received a SUBSCRIBE response and a NOTIFY request.
            CPPUNIT_ASSERT(subscribeResponse);
            CPPUNIT_ASSERT(notifyRequest);

            CPPUNIT_ASSERT(subscribeResponse->getResponseStatusCode() ==
                           SIP_ACCEPTED_CODE);

            // Check the Contact headers.
            UtlString c;
            subscribeResponse->getContactField(0, c);
            ASSERT_STR_EQUAL(aor_contact_name_addr, c.data());
            notifyRequest->getContactField(0, c);
            ASSERT_STR_EQUAL(aor_contact_name_addr, c.data());
         }
      }
示例#29
0
文件: main.cpp 项目: astubbs/sipxecs
//
// The main entry point to the sipXpark
//
int main(int argc, char* argv[])
{
   // Block all signals in this the main thread.
   // Any threads created from now on will have all signals masked.
   OsTask::blockSignals();

   // Create a new task to wait for signals.  Only that task
   // will ever see a signal from the outside.
   SignalTask* signalTask = new SignalTask();
   signalTask->start();

    // Configuration Database (used for OsSysLog)
    OsConfigDb configDb;

    UtlString argString;
    for(int argIndex = 1; argIndex < argc; argIndex++)
    {
        osPrintf("arg[%d]: %s\n", argIndex, argv[argIndex]);
        argString = argv[argIndex];
        NameValueTokenizer::frontBackTrim(&argString, "\t ");
        if(argString.compareTo("-v") == 0)
        {
            osPrintf("Version: %s (%s)\n", SIPX_VERSION, SIPX_BUILD);
            return(1);
        } else
        {
           osPrintf("usage: %s [-v]\nwhere:\n -v provides the software version\n",
            argv[0]);
            return(1);
        }
    }

    // Load configuration file file
    OsPath workingDirectory;
    if (OsFileSystem::exists(CONFIG_ETC_DIR))
    {
        workingDirectory = CONFIG_ETC_DIR;
        OsPath path(workingDirectory);
        path.getNativePath(workingDirectory);
    } else
    {
        OsPath path;
        OsFileSystem::getWorkingDirectory(path);
        path.getNativePath(workingDirectory);
    }

    UtlString fileName =  workingDirectory +
      OsPathBase::separator +
      CONFIG_SETTINGS_FILE;

    if (configDb.loadFromFile(fileName) != OS_SUCCESS)
    {
       exit(1);
    }

    // Initialize log file
    initSysLog(&configDb);

    // Read the user agent parameters from the config file.
    int UdpPort;
    if (configDb.get(CONFIG_SETTING_UDP_PORT, UdpPort) != OS_SUCCESS)
        UdpPort = PARK_DEFAULT_UDP_PORT;

    int TcpPort;
    if (configDb.get(CONFIG_SETTING_TCP_PORT, TcpPort) != OS_SUCCESS)
        TcpPort = PARK_DEFAULT_TCP_PORT;

    int RtpBase;
    if (configDb.get(CONFIG_SETTING_RTP_PORT, RtpBase) != OS_SUCCESS)
        RtpBase = DEFAULT_RTP_PORT;

    UtlString bindIp;
    if (configDb.get(CONFIG_SETTING_BIND_IP, bindIp) != OS_SUCCESS ||
            !OsSocket::isIp4Address(bindIp))
        bindIp = PARK_DEFAULT_BIND_IP;

    int MaxSessions;
    if (configDb.get(CONFIG_SETTING_MAX_SESSIONS, MaxSessions) != OS_SUCCESS)
    {
        MaxSessions = DEFAULT_MAX_SESSIONS;
    }

    UtlBoolean OneButtonBLF =
       configDb.getBoolean(CONFIG_SETTING_ONE_BUTTON_BLF, DEFAULT_ONE_BUTTON_BLF);

    UtlString   domain;
    UtlString   realm;
    UtlString   user;

    SipLine*    line = NULL;
    SipLineMgr* lineMgr = NULL;

    OsConfigDb  domainConfiguration;
    OsPath      domainConfigPath = SipXecsService::domainConfigPath();

    if (OS_SUCCESS == domainConfiguration.loadFromFile(domainConfigPath.data()))
    {
       domainConfiguration.get(SipXecsService::DomainDbKey::SIP_DOMAIN_NAME, domain);
       domainConfiguration.get(SipXecsService::DomainDbKey::SIP_REALM, realm);

       if (!domain.isNull() && !realm.isNull())
       {
          CredentialDB* credentialDb;
          if ((credentialDb = CredentialDB::getInstance()))
          {
             Url identity;

             identity.setUserId(PARK_SERVER_ID_TOKEN);
             identity.setHostAddress(domain);

             UtlString ha1_authenticator;
             UtlString authtype;

             if (credentialDb->getCredential(identity, realm, user, ha1_authenticator, authtype))
             {
                if ((line = new SipLine( identity // user entered url
                                        ,identity // identity url
                                        ,user     // user
                                        ,TRUE     // visible
                                        ,SipLine::LINE_STATE_PROVISIONED
                                        ,TRUE     // auto enable
                                        ,FALSE    // use call handling
                                        )))
                {
                   if ((lineMgr = new SipLineMgr()))
                   {
                      if (lineMgr->addLine(*line))
                      {
                         if (lineMgr->addCredentialForLine( identity, realm, user, ha1_authenticator
                                                           ,HTTP_DIGEST_AUTHENTICATION
                                                           )
                             )
                         {
                            OsSysLog::add(LOG_FACILITY, PRI_INFO,
                                          "Added identity '%s': user='******' realm='%s'"
                                          ,identity.toString().data(), user.data(), realm.data()
                                          );
                         }
                         else
                         {
                            OsSysLog::add(LOG_FACILITY, PRI_ERR,
                                          "Error adding identity '%s': user='******' realm='%s'\n"
                                          "  escape and timeout from park may not work.",
                                          identity.toString().data(), user.data(), realm.data()
                                          );
                         }

                         lineMgr->setDefaultOutboundLine(identity);
                      }     // end addLine
                      else
                      {
                         OsSysLog::add(LOG_FACILITY, PRI_ERR,
                                       "addLine failed: "
                                       "  escape and timeout from park may not work."
                                       );
                      }
                   }
                   else
                   {
                      OsSysLog::add(LOG_FACILITY, PRI_ERR,
                                    "Constructing SipLineMgr failed:  "
                                    "  escape and timeout from park may not work."
                                    );
                   }
                }   // end new SipLine
                else
                {
                   OsSysLog::add(LOG_FACILITY, PRI_ERR,
                                 "Constructing SipLine failed:  "
                                 "  escape and timeout from park may not work."
                                 );
                }
             }  // end getCredential
             else
             {
                OsSysLog::add(LOG_FACILITY, PRI_ERR,
                              "No credential found for '%s@%s' in realm '%s'"
                              "; transfer functions will not work",
                              PARK_SERVER_ID_TOKEN, domain.data(), realm.data()
                              );
             }

             credentialDb->releaseInstance();
          }   // end credentialDB
          else
          {
             OsSysLog::add(LOG_FACILITY, PRI_ERR,
                           "Failed to open credentials database"
                           "; transfer functions will not work"
                           );
          }
       }    // end have domain and realm
       else
       {
          OsSysLog::add(LOG_FACILITY, PRI_ERR,
                        "Domain or Realm not configured:"
                        "\n  '%s' : '%s'\n  '%s' : '%s'"
                        "  transfer functions will not work.",
                        SipXecsService::DomainDbKey::SIP_DOMAIN_NAME, domain.data(),
                        SipXecsService::DomainDbKey::SIP_REALM, realm.data()
                        );
       }
    }       // end found domain config
    else
    {
       OsSysLog::add(LOG_FACILITY, PRI_ERR,
                     "main: failed to load domain configuration from '%s'",
                     domainConfigPath.data()
                     );
    }

    // Read Park Server parameters from the config file.
    int Lifetime, BlindXferWait, KeepAliveTime, ConsXferWait;
    if (configDb.get(CONFIG_SETTING_LIFETIME, Lifetime) != OS_SUCCESS)
    {
       Lifetime = DEFAULT_LIFETIME;
    }
    if (configDb.get(CONFIG_SETTING_BLIND_WAIT, BlindXferWait) != OS_SUCCESS)
    {
       BlindXferWait = DEFAULT_BLIND_WAIT;
    }
    if (configDb.get(CONFIG_SETTING_KEEPALIVE_TIME, KeepAliveTime) != OS_SUCCESS)
    {
       KeepAliveTime = DEFAULT_KEEPALIVE_TIME;
    }
    // This is not configurable, as consultative transfers should
    // succeed or fail immediately.
    ConsXferWait = CONS_XFER_WAIT;

    // Bind the SIP user agent to a port and start it up
    SipUserAgent* userAgent = new SipUserAgent(TcpPort,
                                               UdpPort,
                                               TcpPort+1,
                                               NULL, // publicAddress
                                               user.isNull() ? NULL : user.data(), // default user
                                               bindIp,
                                               domain.isNull() ? NULL : domain.data(), // outbound proxy
                                               NULL, // sipDirectoryServers (deprecated)
                                               NULL, // sipRegistryServers (deprecated)
                                               NULL, // authenticationScheme
                                               NULL, // authenicateRealm
                                               NULL, // authenticateDb
                                               NULL, // authorizeUserIds (deprecated)
                                               NULL, // authorizePasswords (deprecated)
                                               lineMgr
                                               );
    userAgent->setUserAgentHeaderProperty("sipXecs/park");
    userAgent->start();

    if (!userAgent->isOk())
    {
       OsSysLog::add(LOG_FACILITY, PRI_EMERG, "SipUserAgent failed to initialize, requesting shutdown");
       gShutdownFlag = TRUE;
    }

    // Read the list of codecs from the configuration file.
    SdpCodecFactory codecFactory;
    initCodecs(&codecFactory, &configDb);

    // Initialize and start up the media subsystem
    mpStartUp(MP_SAMPLE_RATE, MP_SAMPLES_PER_FRAME, 6 * MaxSessions, &configDb);
    MpMediaTask::getMediaTask(MaxSessions);

#ifdef INCLUDE_RTCP
    CRTCManager::getRTCPControl();
#endif //INCLUDE_RTCP

    mpStartTasks();

    // Instantiate the call processing subsystem
    UtlString localAddress;
    int localPort ;
    userAgent->getLocalAddress(&localAddress, &localPort) ;
    if (localAddress.isNull())
        OsSocket::getHostIp(&localAddress);

    // Construct an address to be used in outgoing requests (primarily
    // INVITEs stimulated by REFERs).
    UtlString outgoingAddress;
    {
       char buffer[100];
       sprintf(buffer, "sip:sipXpark@%s:%d", localAddress.data(),
               portIsValid(UdpPort) ? UdpPort : TcpPort);
       outgoingAddress = buffer;
    }
    CallManager callManager(FALSE,
                           NULL,
                           TRUE,                              // early media in 180 ringing
                           &codecFactory,
                           RtpBase,                           // rtp start
                           RtpBase + (2 * MaxSessions),       // rtp end
                           localAddress,
                           localAddress,
                           userAgent,
                           0,                                 // sipSessionReinviteTimer
                           NULL,                              // mgcpStackTask
                           outgoingAddress,                   // defaultCallExtension
                           Connection::RING,                  // availableBehavior
                           NULL,                              // unconditionalForwardUrl
                           -1,                                // forwardOnNoAnswerSeconds
                           NULL,                              // forwardOnNoAnswerUrl
                           Connection::BUSY,                  // busyBehavior
                           NULL,                              // sipForwardOnBusyUrl
                           NULL,                              // speedNums
                           CallManager::SIP_CALL,             // phonesetOutgoingCallProtocol
                           4,                                 // numDialPlanDigits
                           CallManager::NEAR_END_HOLD,        // holdType
                           5000,                              // offeringDelay
                           "",                                // pLocal
                           CP_MAXIMUM_RINGING_EXPIRE_SECONDS, // inviteExpiresSeconds
                           QOS_LAYER3_LOW_DELAY_IP_TOS,       // expeditedIpTos
                           MaxSessions,                       // maxCalls
                           sipXmediaFactoryFactory(NULL));    // CpMediaInterfaceFactory



    // Create a listener (application) to deal with call
    // processing events (e.g. incoming call and hang ups)
    OrbitListener listener(&callManager, Lifetime, BlindXferWait, KeepAliveTime, ConsXferWait);

    callManager.addTaoListener(&listener);
    listener.start();

    // Create the SIP Subscribe Server
    SipPersistentSubscriptionMgr
       subscriptionMgr(SUBSCRIPTION_COMPONENT_PARK,
                       domain,
                       "subscription"); // Component for holding the subscription data
    SipSubscribeServerEventHandler policyHolder; // Component for granting the subscription rights
    SipPublishContentMgr publisher; // Component for publishing the event contents

    SipSubscribeServer subscribeServer(*userAgent, publisher,
                                       subscriptionMgr, policyHolder);
    subscribeServer.enableEventType(DIALOG_EVENT_TYPE);
    subscribeServer.start();

    // Create the DialogEventPublisher.
    // Use the sipX domain as the hostport of resource-IDs of the
    // published events, as that will be the request-URIs of SUBSCRIBEs.
    DialogEventPublisher dialogEvents(&callManager, &publisher, domain, PORT_NONE, OneButtonBLF);
    callManager.addTaoListener(&dialogEvents);
    dialogEvents.start();

    // Start up the call processing system
    callManager.start();

    // Loop forever until signaled to shut down

    int numTwoSecIntervals = 0;
    int CleanLoopWaitTimeSecs = 10;

    while (!gShutdownFlag)
    {
       OsTask::delay(2000);

       if (2*numTwoSecIntervals >= CleanLoopWaitTimeSecs)
       {
           numTwoSecIntervals = 0;
           if (OsSysLog::willLog(FAC_PARK, PRI_DEBUG))
           {
               OsSysLog::add(LOG_FACILITY, PRI_DEBUG,
                             "park main "
                             "logging call status"
                             );
               callManager.printCalls(0) ;
               listener.dumpCallsAndTransfers();
           }
       }
       else
       {
           numTwoSecIntervals += 1;
       }

    }

    // Flush the log file
    OsSysLog::flush();

    // Say goodnight Gracie...
    return 0;
}
// Constructor
SipXProxyCseObserver::SipXProxyCseObserver(SipUserAgent&         sipUserAgent,
                                           const UtlString&      dnsName,
                                           CallStateEventWriter* pWriter
                                           ) :
   OsServerTask("SipXProxyCseObserver-%d", NULL, 2000),
   SipOutputProcessor( CSE_AGENT_OUTPUT_PROC_PRIO ),
   mpSipUserAgent(&sipUserAgent),
   mpBuilder(NULL),
   mpWriter(pWriter),
   mSequenceNumber(0),
   mFlushTimer(getMessageQueue(), 0),
   mCallTransMutex(OsMutex::Q_FIFO)
{
   OsTime timeNow;
   OsDateTime::getCurTime(timeNow);
   UtlString event;
   

   if (mpWriter)
   {
      switch (pWriter->getLogType())
      {
      case CallStateEventWriter::CseLogFile:
         mpBuilder = new CallStateEventBuilder_XML(dnsName);
         break;
      case CallStateEventWriter::CseLogDatabase:
         mpBuilder = new CallStateEventBuilder_DB(dnsName);
         break;
      }
      if (mpBuilder)
      {
         if (pWriter->openLog())
         {
            mpBuilder->observerEvent(mSequenceNumber, timeNow, CallStateEventBuilder::ObserverReset,
                                     "SipXProxyCseObserver");      
            mpBuilder->finishElement(event);      

            if (!mpWriter->writeLog(event.data()))
            {      
               Os::Logger::instance().log(FAC_SIP, PRI_ERR,
                             "SipXProxyCseObserver initial event log write failed - disabling writer");
               mpWriter = NULL;                 
            }
            else
            {
               mpWriter->flush(); // try to ensure that at least the sequence restart gets to the file 
            }
         }
         else
         {
            Os::Logger::instance().log(FAC_SIP, PRI_ERR,
                          "SipXProxyCseObserver initial event log write failed - disabling writer");
            mpWriter = NULL;
            
            // Set correct state even if nothing is written
            mpBuilder->observerEvent(mSequenceNumber, timeNow, CallStateEventBuilder::ObserverReset, "");                 
            mpBuilder->finishElement(event);             
         }
      }
   }

   // set up periodic timer to flush log file
   mFlushTimer.periodicEvery(OsTime(), OsTime(SipXProxyCallStateFlushInterval, 0)) ;

  // Register to get incoming requests
   sipUserAgent.addMessageObserver(*getMessageQueue(),
                                   SIP_BYE_METHOD,
                                   TRUE, // Requests,
                                   FALSE, //Responses,
                                   TRUE, //Incoming,
                                   FALSE, //OutGoing,
                                   "", //eventName,
                                   NULL, // any session
                                   NULL // no observerData
                                   );
   sipUserAgent.addMessageObserver(*getMessageQueue(),
                                   SIP_INVITE_METHOD,
                                   TRUE, // Requests,
                                   FALSE, //Responses,
                                   TRUE, //Incoming,
                                   FALSE, //OutGoing,
                                   "", //eventName,
                                   NULL, // any session
                                   NULL // no observerData
                                   );
   sipUserAgent.addMessageObserver(*getMessageQueue(),
                                   SIP_REFER_METHOD,
                                   TRUE, // Requests,
                                   FALSE, //Responses,
                                   TRUE, //Incoming,
                                   FALSE, //OutGoing,
                                   "", //eventName,
                                   NULL, // any session
                                   NULL // no observerData
                                   );                                   

   sipUserAgent.addSipOutputProcessor( this );

   // set up periodic timer to cleanup dead calls in the CallTransMap
   mpCleanupTimeoutCallback = new OsCallback((void*)this, CleanupTransMap);
   mpCleanupMapTimer = new OsTimer(*mpCleanupTimeoutCallback);
   mpCleanupMapTimer->periodicEvery(OsTime(), OsTime(SipXProxyCallStateCleanupInterval, 0)) ;
}