Example #1
0
// Read config information.
void SipRedirectorISN::readConfig(OsConfigDb& configDb)
{
   if (configDb.get("BASE_DOMAIN", mBaseDomain) != OS_SUCCESS ||
       mBaseDomain.isNull())
   {
      OsSysLog::add(FAC_SIP, PRI_CRIT,
                    "%s::readConfig "
                    "BASE_DOMAIN parameter missing or empty",
                    mLogName.data());
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig "
                    "BASE_DOMAIN is '%s'", mLogName.data(), mBaseDomain.data());
   }

   if (configDb.get("PREFIX", mPrefix) != OS_SUCCESS ||
       mPrefix.isNull())
   {
      OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig "
                    "dialing prefix is empty", mLogName.data());
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig "
                    "dialing prefix is '%s'", mLogName.data(), mPrefix.data());
   }
}
/// Read (or re-read) the configuration.
void
MSFT_ExchangeTransferHack::readConfig( OsConfigDb& configDb /**< a subhash of the individual configuration
                                                             * parameters for this instance of this plugin. */
                                      )
{
   /*
    * @note
    * The parent service may call the readConfig method at any time to
    * indicate that the configuration may have changed.  The plugin
    * should reinitialize itself based on the configuration that exists when
    * this is called.  The fact that it is a subhash means that whatever prefix
    * is used to identify the plugin (see PluginHooks) has been removed (see the
    * examples in PluginHooks::readConfig).
    */
   Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "MSFT_ExchangeTransferHack[%s]::readConfig",
                 mInstanceName.data()
                 );

   if (mUserAgentRegEx)
   {
      delete mUserAgentRegEx;
      mUserAgentRegEx = NULL;
   }

   UtlString recognizer;
   if (configDb.get(RecognizerConfigKey, recognizer) && !recognizer.isNull())
   {
      Os::Logger::instance().log( FAC_SIP, PRI_INFO
                    ,"MSFT_ExchangeTransferHack[%s]::readConfig "
                    " recognizer %s : '%s'"
                    ,mInstanceName.data(), RecognizerConfigKey
                    ,recognizer.data()
                    );
      
      try
      {
         mUserAgentRegEx = new RegEx(recognizer.data());
      }
      catch(const char* compileError)
      {
         Os::Logger::instance().log( FAC_SIP, PRI_ERR
                       ,"MSFT_ExchangeTransferHack[%s]::readConfig "
                       " Invalid recognizer expression '%s' : %s"
                       ,mInstanceName.data()
                       ,recognizer.data()
                       ,compileError
                       );
         mUserAgentRegEx = NULL;
      }
   }
   else
   {
      Os::Logger::instance().log( FAC_SIP, PRI_NOTICE
                    ,"MSFT_ExchangeTransferHack[%s]::readConfig "
                    " no recognizer '%s'"
                    ,mInstanceName.data(), RecognizerConfigKey
                    );
   }
}
/// Read (or re-read) the authorization rules.
void
TransferControl::readConfig( OsConfigDb& configDb /**< a subhash of the individual configuration
                                                    * parameters for this instance of this plugin. */
                             )
{
   /*
    * @note
    * The parent service may call the readConfig method at any time to
    * indicate that the configuration may have changed.  The plugin
    * should reinitialize itself based on the configuration that exists when
    * this is called.  The fact that it is a subhash means that whatever prefix
    * is used to identify the plugin (see PluginHooks) has been removed (see the
    * examples in PluginHooks::readConfig).
    */
   Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "TransferControl[%s]::readConfig",
                 mInstanceName.data()
                 );
   if (configDb.get(RecognizerConfigKey1, server1) && !server1.isNull())
   {
      Os::Logger::instance().log(FAC_SIP,PRI_INFO
                    ,"TransferControl[%s]::readConfig "
                    " server %s : '%s'"
                    ,mInstanceName.data(), RecognizerConfigKey1
                    ,server1.data()
                    );
   }
   if (configDb.get(RecognizerConfigKey2, server2) && !server2.isNull())
   {
      Os::Logger::instance().log(FAC_SIP,PRI_INFO
                    ,"TransferControl[%s]::readConfig "
                    " server %s : '%s'"
                    ,mInstanceName.data(), RecognizerConfigKey2
                    ,server2.data()
                    );
   }
}
Example #4
0
/// constructor
SharedSecret::SharedSecret(OsConfigDb& domainConfigDb)
{
   UtlString base64secret;

   if (OS_SUCCESS == domainConfigDb.get(SipXecsService::DomainDbKey::SHARED_SECRET, base64secret))
   {
      if (   !NetBase64Codec::decode(base64secret, *this)
          || isNull()
          )
      {
         Os::Logger::instance().log(FAC_KERNEL, PRI_CRIT,
                       "SharedSecret::_ invalid value '%s' for '%s' found in '%s'; aborting",
                       base64secret.data(),
                       SipXecsService::DomainDbKey::SHARED_SECRET,
                       domainConfigDb.getIdentityLabel());

         // We assume that if the component wants a signing secret for some security-critical
         // purpose.  Rather than continue without this security-critical data, stop.
         assert(false);
      }
      else
      {
         Os::Logger::instance().log(FAC_KERNEL, PRI_DEBUG,
                       "SharedSecret::_ loaded from '%s' length %zu",
                       domainConfigDb.getIdentityLabel(), length());
      }
   }
   else
   {
      Os::Logger::instance().log(FAC_KERNEL, PRI_CRIT,
                    "SharedSecret::_ no value for '%s' found in '%s'; using fixed value",
                    SipXecsService::DomainDbKey::SHARED_SECRET, domainConfigDb.getIdentityLabel());

      // We assume that if the component wants a signing secret for some security-critical
      // purpose.  Rather than continue without this security-critical data, stop.
      // @TODO assert(false);
   }
};
Example #5
0
void SipXecsService::setLogPriority(const OsConfigDb& configSettings, // configuration data
                                    const char* servicePrefix, /* the string "_LOG_LEVEL" is
                                                                * appended to this prefix to
                                                                * find the config directive that
                                                                * sets the level */
                                    OsSysLogPriority defaultLevel // default default is "NOTICE"
                                   )
{
    UtlString logLevel;
    UtlString logLevelTag(servicePrefix);
    logLevelTag.append(LogLevelSuffix);

    configSettings.get(logLevelTag, logLevel);

    OsSysLogPriority priority;
    if ( logLevel.isNull() )
    {
        OsSysLog::add(FAC_KERNEL,PRI_WARNING,
                      "SipXecsService::setLogPriority: %s not found, using '%s'",
                      logLevelTag.data(), OsSysLog::priorityName(defaultLevel)
                     );

        priority = defaultLevel;
    }
    else if ( ! OsSysLog::priority(logLevel.data(), priority))
    {
        OsSysLog::add(FAC_KERNEL,PRI_ERR,
                      "SipXecsService::setLogPriority: %s value '%s' is invalid, using '%s'",
                      logLevelTag.data(), logLevel.data(), OsSysLog::priorityName(defaultLevel)
                     );

        priority = defaultLevel;

    }

    OsSysLog::setLoggingPriority(priority);
}
Example #6
0
// Read config information.
void SipRedirectorRegDB::readConfig(OsConfigDb& configDb)
{
   configDb.get("MAPPING_FILE", mMappingFileName);
}
Example #7
0
// Initializer
OsStatus
SipRedirectorJoin::initialize(OsConfigDb& configDb,
                              int redirectorNo,
                              const UtlString& localDomainHost)
{
   // If the join redirection is active, set up the machinery
   // to execute it.
   if (mRedirectorActive == OS_SUCCESS)
   {
      // Get and save our domain name.
      mDomain = localDomainHost;

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

      
      // Authentication Realm Name
      UtlString realm;
      configDb.get("SIP_REGISTRAR_AUTHENTICATE_REALM", realm);
      // Get SipLineMgr containing the credentials for REGISTRAR_ID_TOKEN.
      SipLineMgr* lineMgr = addCredentials(mDomain, realm);

      // Create a SIP user agent to generate SUBSCRIBEs and receive NOTIFYs,
      // and save a pointer to it.
      // Having a separate user agent ensures that the NOTIFYs are not
      // processed for redirection, but rather we can act as a UAS to
      // process them.
      mpSipUserAgent = new SipUserAgent(
         // Let the system choose the port numbers.
         PORT_DEFAULT, // sipTcpPort
         PORT_DEFAULT, // sipUdpPort
         PORT_DEFAULT, // sipTlsPort
         NULL, // publicAddress
         NULL, // defaultUser
         bindIp, // defaultSipAddress
         NULL, // sipProxyServers
         NULL, // sipDirectoryServers
         NULL, // sipRegistryServers
         NULL, // authenicateRealm
         NULL, // authenticateDb
         NULL, // authorizeUserIds
         NULL, // authorizePasswords
         lineMgr, // lineMgr
         SIP_DEFAULT_RTT, // sipFirstResendTimeout
         TRUE, // defaultToUaTransactions
         -1, // readBufferSize
         OsServerTask::DEF_MAX_MSGS, // queueSize
         FALSE // bUseNextAvailablePort
         );
      mpSipUserAgent->setUserAgentHeaderProperty("sipXecs/redirectorJoin");
      mpSipUserAgent->start();

      // Initialize the CSeq counter to an arbitrary acceptable value.
      mCSeq = 14711;

      // Create and start the task to receive NOTIFYs.
      mTask = new SipRedirectorJoinTask(mpSipUserAgent, redirectorNo);
      mTask->start();
   }

   return mRedirectorActive;
}
// Read config information.
void SipRedirectorPresenceRouting::readConfig(OsConfigDb& configDb)
{
    // extract the realm information from the config DB - we need this part
    // to do the credentials db look-up.
    if ((configDb.get(CONFIG_SETTING_REALM, mRealm) != OS_SUCCESS) ||
         mRealm.isNull())
    {
        OsSysLog::add(FAC_SIP, PRI_ERR,
                     "%s::readConfig No Realm specified in the configuration",
                     mLogName.data());
    }
    else
    {
        OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig mRealm = '%s'",
                    mLogName.data(), mRealm.data() );
   }

    mbForwardToVmOnBusy = configDb.getBoolean(CONFIG_SETTING_VOICEMAIL_ON_BUSY, FALSE);
    OsSysLog::add(FAC_SIP, PRI_INFO,
                 "%s::readConfig mbForwardToVmOnBusy = %d",
                 mLogName.data(), mbForwardToVmOnBusy);

    
    UtlString prefsFilename;
    configDb.get(CONFIG_SETTING_USER_PREFS_FILE, prefsFilename);
    OsSysLog::add(FAC_SIP, PRI_INFO,
                 "%s::readConfig prefsFilename = %s",
                 mLogName.data(), prefsFilename.data());
    mUserPrefs.loadPrefs( prefsFilename );
    
    UtlString openFirePresenceServerUrlAsString;
    if ((configDb.get(CONFIG_OPENFIRE_PRESENCE_SERVER_URL, openFirePresenceServerUrlAsString) != OS_SUCCESS) ||
          openFirePresenceServerUrlAsString.isNull())
    {
       OsSysLog::add(FAC_SIP, PRI_ERR,
                     "%s::readConfig No URL specified for openfire presence server in the configuration",
                     mLogName.data());
    }
    else
    {
        OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig openFirePresenceServerUrlAsString = '%s'",
                    mLogName.data(), openFirePresenceServerUrlAsString.data() );
        mOpenFirePresenceServerUrl.fromString( openFirePresenceServerUrlAsString );
    }

    UtlString presenceMonitorServerUrlAsString;
    if ((configDb.get(CONFIG_PRESENCE_MONITOR_SERVER_URL, presenceMonitorServerUrlAsString) != OS_SUCCESS) ||
           presenceMonitorServerUrlAsString.isNull())
    {
         OsSysLog::add(FAC_SIP, PRI_ERR,
                       "%s::readConfig No URL specified for local presence monitor server in the configuration",
                       mLogName.data());
    }
    else
    {
        OsSysLog::add(FAC_SIP, PRI_INFO,
                      "%s::readConfig presenceMonitorServerUrlAsString = '%s'",
                      mLogName.data(), presenceMonitorServerUrlAsString.data() );
        mLocalPresenceMonitorServerUrl.fromString( presenceMonitorServerUrlAsString );
    }
}
Example #9
0
//
// The main entry point to sipXrls.
//
int main(int argc, char* argv[])
{
   // 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", VERSION, PACKAGE_REVISION);
         return 1;
      }
      else
      {
         osPrintf("usage: %s [-v]\nwhere:\n -v provides the software version\n",
                  argv[0]);
         return 1;
      }
   }

   // Load configuration 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)
   {
      fprintf(stderr, "Failed to load config DB from file '%s'",
              fileName.data());
      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 = RLS_DEFAULT_UDP_PORT;
   }

   int tcpPort;
   if (configDb.get(CONFIG_SETTING_TCP_PORT, tcpPort) != OS_SUCCESS)
   {
      tcpPort = RLS_DEFAULT_TCP_PORT;
   }

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

   UtlString resourceListFile;
   if ((configDb.get(CONFIG_SETTING_RLS_FILE, resourceListFile) !=
        OS_SUCCESS) ||
       resourceListFile.isNull())
   {
      Os::Logger::instance().log(LOG_FACILITY, PRI_CRIT,
                    "Resource list file name is not configured");
      return 1;
   }

   UtlString domainName;
   if ((configDb.get(CONFIG_SETTING_DOMAIN_NAME, domainName) !=
        OS_SUCCESS) ||
       domainName.isNull())
   {
      Os::Logger::instance().log(LOG_FACILITY, PRI_CRIT,
                    "Resource domain name is not configured");
      return 1;
   }

   UtlString realm;
   if ((configDb.get(CONFIG_SETTING_AUTHENTICATE_REALM, realm) !=
        OS_SUCCESS) ||
       realm.isNull())
   {
      Os::Logger::instance().log(LOG_FACILITY, PRI_CRIT,
                    "Resource realm is not configured");
      return 1;
   }

   int resubscribeInterval;
   if (configDb.get(CONFIG_SETTING_RESUBSCRIBE_INTERVAL, resubscribeInterval) != OS_SUCCESS)
   {
      resubscribeInterval = RLS_DEFAULT_RESUBSCRIBE_INTERVAL;
   }

   int minResubscribeInterval;
   if (configDb.get(CONFIG_SETTING_MIN_RESUBSCRIBE_INTERVAL, minResubscribeInterval) != OS_SUCCESS)
   {
       minResubscribeInterval = RLS_DEFAULT_MIN_RESUBSCRIBE_INTERVAL;
   }

   int serverMinExpiration;
   if (configDb.get(CONFIG_SETTING_SERVER_MIN_EXPIRATION, serverMinExpiration) != OS_SUCCESS)
   {
       serverMinExpiration = RLS_DEFAULT_SERVER_MIN_EXPIRATION;
   }

   int serverDefaultExpiration;
   if (configDb.get(CONFIG_SETTING_SERVER_DEFAULT_EXPIRATION, serverDefaultExpiration) != OS_SUCCESS)
   {
       serverDefaultExpiration = RLS_DEFAULT_SERVER_DEFAULT_EXPIRATION;
   }

   int serverMaxExpiration;
   if (configDb.get(CONFIG_SETTING_SERVER_MAX_EXPIRATION, serverMaxExpiration) != OS_SUCCESS)
   {
       serverMaxExpiration = RLS_DEFAULT_SERVER_MAX_EXPIRATION;
   }

   // add the ~~sipXrls credentials so that sipXrls can respond to challenges
   SipLineMgr* lineMgr = addCredentials(domainName, realm);
   if(NULL == lineMgr)
   {
      return 1;
   }

   if (!gShutdownFlag)
   {
      // Initialize the ResourceListServer.
      ResourceListServer rls(domainName, realm, lineMgr,
                             DIALOG_EVENT_TYPE, DIALOG_EVENT_CONTENT_TYPE,
                             tcpPort, udpPort, PORT_NONE, bindIp,
                             &resourceListFile,
                             resubscribeInterval, minResubscribeInterval,
                             RLS_PUBLISH_DELAY,
                             20, 20, 20, 20,
                             serverMinExpiration,
                             serverDefaultExpiration,
                             serverMaxExpiration);
      rls.start();

      // Loop forever until signaled to shut down
      while (!Os::UnixSignals::instance().isTerminateSignalReceived() && !gShutdownFlag)
      {
         OsTask::delay(2000);
         // See if the list configuration file has changed.
         rls.getResourceListFileReader().refresh();
      }

      // Shut down the server.
      rls.shutdown();
   }

   lineMgr->requestShutdown();
   
   while (!lineMgr->isShutDown())
   {
      OsTask::delay(100);
   }
   
   // Delete the LineMgr Object
   delete lineMgr;

   
   // Flush the log file
   Os::Logger::instance().flush();
   
   
		    
   // Say goodnight Gracie...
   return 0;
}
Example #10
0
//
// Pull out important parameters from the config DB.
// These parameters are set at runtime and cannot be changed without a restart.
//
UtlBoolean ParkService::loadConfig(
    int& UdpPort,
    int& TcpPort,
    int& RtpBase,
    UtlString& bindIp,
    int& MaxSessions,
    UtlBoolean& OneButtonBLF,
    UtlString&   domain,
    UtlString&   realm,
    UtlString&   user,
    SipLineMgr* lineMgr,
    int& Lifetime,
    int& BlindXferWait,
    int& KeepAliveTime
    )
{
   UtlBoolean ret = true;

   // SipXecsService owns the main configDb
   OsConfigDb& configDb = getConfigDb();

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

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

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

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

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

    OneButtonBLF =
       configDb.getBoolean(CONFIG_SETTING_ONE_BUTTON_BLF, DEFAULT_ONE_BUTTON_BLF);

    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 ((lineMgr = new SipLineMgr()))
                {
                   SipLine line(identity // user entered url
                                ,identity // identity url
                                ,user     // user
                                ,TRUE     // visible
                                ,SipLine::LINE_STATE_PROVISIONED
                                ,TRUE     // auto enable
                                ,FALSE    // use call handling
                      );

                   if (lineMgr->addLine(line))
                   {
                      lineMgr->startLineMgr();
                      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 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.
    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;
    }

   return ret;
}
int supervisorMain(bool bOriginalSupervisor)
{
    // Create forked process which will do nothing unless parent dies.  Parent continues with initialization.
    forkSupervisorInWaiting();

    // Drop privileges down to the specified user & group
    const char * sipxpbxuser = SipXecsService::User();
    const char * sipxpbxgroup = SipXecsService::Group();

    if (NULL == sipxpbxuser || 0 == strlen(sipxpbxuser))
    {
       osPrintf("sipXsupervisor: Failed to setuid(%s), username not defined.\n",
          sipxpbxuser);
       return 2;
    }
    if (NULL == sipxpbxgroup || 0 == strlen(sipxpbxgroup))
    {
       osPrintf("sipXsupervisor: Failed to setgid(%s), groupname not defined.\n",
          sipxpbxgroup);
       return 2;
    }

    struct group * grp = getgrnam(sipxpbxgroup);
    if (NULL == grp)
    {
       if (0 != errno)
       {
          osPrintf("getgrnam(%s) failed, errno = %d.",
             sipxpbxgroup, errno);
       }
       else
       {
          osPrintf(
             "sipXsupervisor: getgrnam(%s) failed, user does not exist.",
                sipxpbxgroup);
       }
       return 3;
    }

    struct passwd * pwd = getpwnam(sipxpbxuser);
    if (NULL == pwd)
    {
       if (0 != errno)
       {
          osPrintf("getpwnam(%s) failed, errno = %d.",
             sipxpbxuser, errno);
       }
       else
       {
          osPrintf(
             "sipXsupervisor: getpwnam(%s) failed, user does not exist.",
                sipxpbxuser);
       }
       return 3;
    }

    // Change group first, cause once user is changed this cannot be done.
    if (0 != setgid(grp->gr_gid))
    {
       osPrintf("sipXsupervisor: setgid(%d) failed, errno = %d.",
          (int)grp->gr_gid, errno);
       return 4;
    }

    if (0 != setuid(pwd->pw_uid))
    {
       osPrintf("sipXsupervisor: setuid(%d) failed, errno = %d.",
          (int)pwd->pw_uid, errno);
       return 4;
    }


# if 0
// Only output problems.  This keeps the startup output clean.
    osPrintf("sipXsupervisor: Dropped privileges with setuid(%s)/setgid(%s).",
       sipxpbxuser, sipxpbxgroup);
#endif

    OsMsgQShared::setQueuePreference(OsMsgQShared::QUEUE_UNLIMITED);

    // Block all signals in this the main thread
    // Any threads created after this 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() ;

    // All osPrintf output should go to the console until the log file is initialized.
    enableConsoleOutput(true);

    // Initialize the log file.
    Os::LoggerHelper::instance().processName = "Supervisor";
    UtlString logFile = SipXecsService::Path(SipXecsService::LogDirType, "sipxsupervisor.log");
    Os::LoggerHelper::instance().initialize(PRI_DEBUG, logFile.data());

    if (!bOriginalSupervisor)
    {
       Os::Logger::instance().log(FAC_SUPERVISOR, PRI_CRIT,
                     "Restarting sipxsupervisor after unexpected shutdown");
    }
    Os::Logger::instance().log(FAC_SUPERVISOR, PRI_NOTICE,
                  ">>>>> Starting sipxsupervisor version %s",
                  VERSION);

    // Now that the log file is initialized, stop sending osPrintf to the console.
    // All relevant log messages from this point on must use Os::Logger::instance().log().
    enableConsoleOutput(false);
    fflush(NULL); // Flush all output so children don't get a buffer of output

    // Open the supervisor configuration file
    OsConfigDb supervisorConfiguration;
    OsPath supervisorConfigPath = SipXecsService::Path(SipXecsService::ConfigurationDirType,
                                                       CONFIG_SETTINGS_FILE);
    if (OS_SUCCESS != supervisorConfiguration.loadFromFile(supervisorConfigPath.data()))
    {
       Os::Logger::instance().log(FAC_SUPERVISOR,PRI_WARNING,
                     "Failed to open supervisor configuration file at '%s'",
                     supervisorConfigPath.data()
                     );
    }

    // Set logging based on the supervisor configuration - TODO change default to "NOTICE" ?
    OsSysLogPriority logPri = SipXecsService::setLogPriority(supervisorConfiguration, SUPERVISOR_PREFIX, PRI_INFO );
    Os::Logger::instance().setLoggingPriorityForFacility(FAC_ALARM, logPri);

    // Open the domain configuration file
    OsConfigDb domainConfiguration;
    OsPath domainConfigPath = SipXecsService::domainConfigPath();
    if (OS_SUCCESS != domainConfiguration.loadFromFile(domainConfigPath.data()))
    {
       Os::Logger::instance().log(FAC_SUPERVISOR,PRI_ERR,
                     "Failed to open domain configuration '%s'",
                     domainConfigPath.data()
                     );
    }
    // @TODO const char* managementIpBindAddress;
    int managementPortNumber;
    managementPortNumber = domainConfiguration.getPort(SipXecsService::DomainDbKey::SUPERVISOR_PORT);
    if (PORT_NONE == managementPortNumber)
    {
       Os::Logger::instance().log(FAC_SUPERVISOR,PRI_WARNING,
                     "%s not configured in '%s', using default: %d",
                     SipXecsService::DomainDbKey::SUPERVISOR_PORT,
                     domainConfigPath.data(), DEFAULT_SUPERVISOR_PORT
                     );
       managementPortNumber=DEFAULT_SUPERVISOR_PORT;
    }
    else if (PORT_DEFAULT == managementPortNumber)
    {
       Os::Logger::instance().log(FAC_SUPERVISOR,PRI_NOTICE,"%s set to default: %d",
                     SipXecsService::DomainDbKey::SUPERVISOR_PORT, DEFAULT_SUPERVISOR_PORT
                     );
       managementPortNumber=DEFAULT_SUPERVISOR_PORT;
    }

    UtlSList allowedPeers;
    UtlString configHosts;
    domainConfiguration.get(SipXecsService::DomainDbKey::CONFIG_HOSTS, configHosts);
    if (!configHosts.isNull())
    {
       UtlString hostName;
       for (int hostIndex = 0;
            NameValueTokenizer::getSubField(configHosts.data(), hostIndex, ", \t", &hostName);
            hostIndex++)
       {
          // Found at least one config hostname.
          if (!allowedPeers.contains(&hostName))
          {
             Os::Logger::instance().log(FAC_SUPERVISOR,PRI_DEBUG,
                           "%s value '%s'",
                           SipXecsService::DomainDbKey::CONFIG_HOSTS,
                           hostName.data()
                           );
             allowedPeers.insert(new UtlString(hostName));
          }
       }
    }
    else
    {
       Os::Logger::instance().log(FAC_SUPERVISOR,PRI_ERR,
                     "%s not configured in '%s'",
                     SipXecsService::DomainDbKey::CONFIG_HOSTS, domainConfigPath.data()
                     );
    }

    UtlString superHost;
    supervisorConfiguration.get(SUPERVISOR_HOST, superHost);
    if (!superHost.isNull())
    {
       if (!allowedPeers.contains(&superHost))
       {
          allowedPeers.insert(new UtlString(superHost));
       }
    }
    else
    {
       Os::Logger::instance().log(FAC_SUPERVISOR,PRI_ERR,
                     "%s not configured in '%s'",
                     SUPERVISOR_HOST, supervisorConfigPath.data()
                     );
    }

    if (allowedPeers.isEmpty())
    {
       Os::Logger::instance().log(FAC_SUPERVISOR,PRI_ERR,
                     "No configuration peers configured.");
    }

    if (!cAlarmServer::getInstance()->init())
    {
       Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR,
             "sipXsupervisor failed to init AlarmServer");
    }

    // Initialize management interfaces on the TLS socket
    OsSSLServerSocket serverSocket(50, managementPortNumber /*@TODO managementIpBindAddress */);
    HttpServer        httpServer(&serverSocket); // set up but don't start https server
    XmlRpcDispatch    xmlRpcDispatcher(&httpServer); // attach xml-rpc service to https
    pSipxRpcImpl = new SipxRpc(&xmlRpcDispatcher, allowedPeers); // register xml-rpc methods
    HttpFileAccess    fileAccessService(&httpServer, pSipxRpcImpl); // attach file xfer to https

    if (serverSocket.isOk())
    {
       Os::Logger::instance().log(FAC_SUPERVISOR, PRI_DEBUG, "Starting Management HTTP Server");
       httpServer.start();
    }
    else
    {
       Os::Logger::instance().log(FAC_SUPERVISOR, PRI_ERR, "Management listening socket failure");
    }

    // Read the process definitions.
    UtlString processDefinitionDirectory =
       SipXecsService::Path(SipXecsService::DataDirType, "process.d");
    SipxProcessManager* processManager = SipxProcessManager::getInstance();
    processManager->instantiateProcesses(processDefinitionDirectory);

    // 3.0 had different process def files.  The only important thing in them is the
    // state of the services.  Transfer this state to the new process def files.
    upgradeFrom3_0();

    doWaitLoop();

    // Successful run.
    return 0;
}
Example #12
0
//
// 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;
}
Example #13
0
// Constructor
SipRegistrar::SipRegistrar(OsConfigDb* configDb) :
   OsServerTask("SipRegistrar", NULL, SIPUA_DEFAULT_SERVER_OSMSG_QUEUE_SIZE),
   mConfigDb(configDb),
   mRegistrationDB(RegistrationDB::getInstance()), // implicitly loads database
   mHttpServer(NULL),
   mXmlRpcDispatch(NULL),
   mReplicationConfigured(false),
   mSipUserAgent(NULL),
   mRedirectServer(NULL),
   mRedirectMsgQ(NULL),
   // Create the SipRegistrarServer object so it will be available immediately,
   // but don't start the associated thread until the registrar is operational.
   mRegistrarServer(new SipRegistrarServer(*this)),
   mRegistrarMsgQ(NULL),
   mRegistrarInitialSync(NULL),
   mRegistrarSync(NULL),
   mRegisterEventServer(NULL),
   mRegistrarTest(NULL),
   mRegistrarPersist(NULL)
{
   OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipRegistrar::SipRegistrar constructed.");

   mHttpPort = mConfigDb->getPort("SIP_REGISTRAR_XMLRPC_PORT");
   if (PORT_NONE == mHttpPort)
   {
      OsSysLog::add(FAC_SIP, PRI_NOTICE,
                    "SipRegistrar::SipRegistrar"
                    " SIP_REGISTRAR_XMLRPC_PORT == PORT_NONE :"
                    " peer synchronization disabled"
                    );
   }
   else // HTTP/RPC port is configured
   {
      if (PORT_DEFAULT == mHttpPort)
      {
         mHttpPort = SIP_REGISTRAR_DEFAULT_XMLRPC_PORT;
      }

      configurePeers();
   }

   // Some phones insist (incorrectly) on putting the proxy port number on urls;
   // we get it from the configuration so that we can ignore it.
   mProxyNormalPort = mConfigDb->getPort("SIP_REGISTRAR_PROXY_PORT");
   if (mProxyNormalPort == PORT_DEFAULT)
   {
      mProxyNormalPort = SIP_PORT;
   }
    
   // Domain Name
   mConfigDb->get("SIP_REGISTRAR_DOMAIN_NAME", mDefaultDomain);
   if ( mDefaultDomain.isNull() )
   {
      OsSocket::getHostIp(&mDefaultDomain);
      OsSysLog::add(FAC_SIP, PRI_CRIT,
                    "SIP_REGISTRAR_DOMAIN_NAME not configured using IP '%s'",
                    mDefaultDomain.data()
                    );
   }
   // get the url parts for the domain
   Url defaultDomainUrl(mDefaultDomain);
   mDefaultDomainPort = defaultDomainUrl.getHostPort();
   defaultDomainUrl.getHostAddress(mDefaultDomainHost);
   // make sure that the unspecified domain name is also valid
   addValidDomain(mDefaultDomainHost, mDefaultDomainPort);

   // read the domain configuration
   OsConfigDb domainConfig;
   domainConfig.loadFromFile(SipXecsService::domainConfigPath());


   // Domain Aliases
   //   (other domain names that this registrar accepts as valid in the request URI)
   UtlString domainAliases;
   domainConfig.get(SipXecsService::DomainDbKey::SIP_DOMAIN_ALIASES, domainAliases);

   if (!domainAliases.isNull())
   {
      OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipRegistrar::SipRegistrar "
                    "SIP_DOMAIN_ALIASES : %s", domainAliases.data());
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_ERR, "SipRegistrar::SipRegistrar "
                    "SIP_DOMAIN_ALIASES not found.");
   }

   UtlString aliasString;
   int aliasIndex = 0;
   while(NameValueTokenizer::getSubField(domainAliases.data(), aliasIndex,
                                         ", \t", &aliasString))
   {
      Url aliasUrl(aliasString);
      UtlString hostAlias;
      aliasUrl.getHostAddress(hostAlias);
      int port = aliasUrl.getHostPort();

      addValidDomain(hostAlias,port);
      aliasIndex++;
   }
   
   mConfigDb->get("SIP_REGISTRAR_BIND_IP", mBindIp);
   if ((mBindIp.isNull()) || !OsSocket::isIp4Address(mBindIp))
   {
	  mBindIp = "0.0.0.0";
   }   
}
Example #14
0
/// Read (or re-read) the authorization rules.
void
SubscriptionAuth::readConfig( OsConfigDb& configDb /**< a subhash of the individual configuration
                                                    * parameters for this instance of this plugin. */
                             )
{
   /*
    * @note
    * The parent service may call the readConfig method at any time to
    * indicate that the configuration may have changed.  The plugin
    * should reinitialize itself based on the configuration that exists when
    * this is called.  The fact that it is a subhash means that whatever prefix
    * is used to identify the plugin (see PluginHooks) has been removed (see the
    * examples in PluginHooks::readConfig).
    */
   OsSysLog::add(FAC_SIP, PRI_DEBUG, "SubscriptionAuth[%s]::readConfig",
                 mInstanceName.data()
                 );

   mEventPackagesRequiringAuthentication.destroyAll();
   mTargetsExemptedFromAuthentication.destroyAll();

   UtlString eventPackagesRequiringAuthentication;
   if (configDb.get(EventsRequiringAuthenticationKey, 
                    eventPackagesRequiringAuthentication) && 
        !eventPackagesRequiringAuthentication.isNull())
   {
      OsSysLog::add( FAC_SIP, PRI_INFO
                    ,"SubscriptionAuth[%s]::readConfig "
                    "  %s = '%s'"
                    ,mInstanceName.data(), EventsRequiringAuthenticationKey
                    ,eventPackagesRequiringAuthentication.data()
                    );
      
      int eventPackageIndex = 0;
      UtlString eventPackageName;
      while(NameValueTokenizer::getSubField(eventPackagesRequiringAuthentication.data(), 
                                            eventPackageIndex,
                                            ", \t", &eventPackageName))
      {
         mEventPackagesRequiringAuthentication.insert( new UtlString( eventPackageName ) );
         eventPackageIndex++;
      }
   }
   else
   {
      OsSysLog::add( FAC_SIP, PRI_NOTICE
                    ,"SubscriptionAuth[%s]::readConfig "
                    "  %s not found - no subscription will be challenged by this plug-in"
                    ,mInstanceName.data(), EventsRequiringAuthenticationKey
                    );
   }

   UtlString targetsExemptedFromAuthentication;
   if (configDb.get(TargetsExemptedFromAuthenticationKey, 
                    targetsExemptedFromAuthentication) &&
       !targetsExemptedFromAuthentication.isNull())
   {
      OsSysLog::add( FAC_SIP, PRI_INFO
                    ,"SubscriptionAuth[%s]::readConfig "
                    "  %s = '%s'"
                    ,mInstanceName.data(), TargetsExemptedFromAuthenticationKey
                    ,targetsExemptedFromAuthentication.data()
                    );
      
      int targetIndex = 0;
      UtlString targetName;
      while(NameValueTokenizer::getSubField(targetsExemptedFromAuthentication.data(), 
                                            targetIndex,
                                            ", \t", &targetName))
      {
         RegEx* targetRegEx;
         targetIndex++;
         try
         {
            targetRegEx = new RegEx(targetName.data());
            mTargetsExemptedFromAuthentication.insert(targetRegEx);
         }
         catch(const char* compileError)
         {
            OsSysLog::add(FAC_SIP, PRI_ERR
                          ,"SubscriptionAuth[%s]::readConfig Invalid recognizer expression '%s' for '%s': %s"
                          ,mInstanceName.data()
                          ,targetName.data()
                          ,TargetsExemptedFromAuthenticationKey
                          ,compileError
                          );
         }
      }
   }
}
Example #15
0
// Read config information.
void SipRedirectorGateway::readConfig(OsConfigDb& configDb)
{
   UtlString string;
   char *endptr;

   mReturn = OS_SUCCESS;

   if (configDb.get("MAPPING_FILE", mMappingFileName) != OS_SUCCESS ||
       mMappingFileName.isNull())
   {
      OsSysLog::add(FAC_SIP, PRI_CRIT,
                    "%s::readConfig "
                    "MAPPING_FILE parameter '%s' missing or empty",
                    mLogName.data(), mMappingFileName.data());
      mReturn = OS_FAILED;
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig "
                    "MAPPING_FILE is '%s'",
                    mLogName.data(), mMappingFileName.data());
   }

   if (configDb.get("PREFIX", mPrefix) != OS_SUCCESS ||
       mPrefix.isNull())
   {
      OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig "
                    "dialing prefix is empty", mLogName.data());
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig "
                    "dialing prefix is '%s'", mLogName.data(), mPrefix.data());
   }

   if (configDb.get("DIGITS", string) == OS_SUCCESS &&
       !string.isNull() &&
       (mDigits = strtol(string.data(), &endptr, 10),
        endptr - string.data() == string.length() &&
        mDigits >= 1 && mDigits <= 10))
   {
      OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig "
                    "variable digit count is %d", mLogName.data(), mDigits);
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_CRIT,
                    "%s::readConfig "
                    "variable digit count is missing, empty, "
                    "or out of range (1 to 10)",
                    mLogName.data());
      mReturn = OS_FAILED;
   }

   if (configDb.get("PORT", string) == OS_SUCCESS &&
       !string.isNull() &&
       (mPort = strtol(string.data(), &endptr, 10),
        endptr - string.data() == string.length() &&
        mPort >= 1 && mPort <= 65535))
   {
      OsSysLog::add(FAC_SIP, PRI_INFO,
                    "%s::readConfig "
                    "listening port is %d", mLogName.data(), mPort);
   }
   else
   {
      OsSysLog::add(FAC_SIP, PRI_CRIT,
                    "%s::readConfig "
                    "listening port '%s' is missing, empty, "
                    "or out of range (1 to 65535)",
                    mLogName.data(), string.data());
      mReturn = OS_FAILED;
   }
}
Example #16
0
//
// The main entry point to sipXsaa.
//
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", 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.
   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 = SAA_DEFAULT_UDP_PORT;
   }

   int tcpPort;
   if (configDb.get(CONFIG_SETTING_TCP_PORT, tcpPort) != OS_SUCCESS)
   {
      tcpPort = SAA_DEFAULT_TCP_PORT;
   }

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

   UtlString appearanceGroupFile;
   if ((configDb.get(CONFIG_SETTING_SAA_FILE, appearanceGroupFile) !=
        OS_SUCCESS) ||
       appearanceGroupFile.isNull())
   {
      OsSysLog::add(LOG_FACILITY, PRI_CRIT,
                    "Appearance group file name is not configured");
      return 1;
   }

   UtlString domainName;
   if ((configDb.get(CONFIG_SETTING_DOMAIN_NAME, domainName) !=
        OS_SUCCESS) ||
       domainName.isNull())
   {
      OsSysLog::add(LOG_FACILITY, PRI_CRIT,
                    "Resource domain name is not configured");
      return 1;
   }

   UtlString realm;
   if ((configDb.get(CONFIG_SETTING_AUTHENTICATE_REALM, realm) !=
        OS_SUCCESS) ||
       realm.isNull())
   {
      OsSysLog::add(LOG_FACILITY, PRI_CRIT,
                    "Resource realm is not configured");
      return 1;
   }

   int refreshInterval;
   if (configDb.get(CONFIG_SETTING_REFRESH_INTERVAL, refreshInterval) != OS_SUCCESS)
   {
      refreshInterval = SAA_DEFAULT_REFRESH_INTERVAL;
   }

   int resubscribeInterval;
   if (configDb.get(CONFIG_SETTING_RESUBSCRIBE_INTERVAL, resubscribeInterval) != OS_SUCCESS)
   {
      resubscribeInterval = SAA_DEFAULT_RESUBSCRIBE_INTERVAL;
   }

   int minResubscribeInterval;
   if (configDb.get(CONFIG_SETTING_MIN_RESUBSCRIBE_INTERVAL, minResubscribeInterval) != OS_SUCCESS)
   {
       minResubscribeInterval = SAA_DEFAULT_MIN_RESUBSCRIBE_INTERVAL;
   }

   // shorter expiration while the shared line is "seized" by a set
   int seizedResubscribeInterval;
   if (configDb.get(CONFIG_SETTING_SEIZED_RESUBSCRIBE_INTERVAL, seizedResubscribeInterval) != OS_SUCCESS)
   {
      seizedResubscribeInterval = SAA_DEFAULT_SEIZED_RESUBSCRIBE_INTERVAL;
   }

   int serverMinExpiration;
   if (configDb.get(CONFIG_SETTING_SERVER_MIN_EXPIRATION, serverMinExpiration) != OS_SUCCESS)
   {
       serverMinExpiration = SAA_DEFAULT_SERVER_MIN_EXPIRATION;
   }

   int serverDefaultExpiration;
   if (configDb.get(CONFIG_SETTING_SERVER_DEFAULT_EXPIRATION, serverDefaultExpiration) != OS_SUCCESS)
   {
       serverDefaultExpiration = SAA_DEFAULT_SERVER_DEFAULT_EXPIRATION;
   }

   int serverMaxExpiration;
   if (configDb.get(CONFIG_SETTING_SERVER_MAX_EXPIRATION, serverMaxExpiration) != OS_SUCCESS)
   {
       serverMaxExpiration = SAA_DEFAULT_SERVER_MAX_EXPIRATION;
   }

   // add the ~~sipXsaa credentials so that sipXsaa can respond to challenges
   SipLineMgr* lineMgr = addCredentials(domainName, realm);
   if(NULL == lineMgr)
   {
      return 1;
   }

   if (!gShutdownFlag)
   {
      // Initialize the AppearanceAgent.
      // (Use tcpPort as the TLS port, too.)
      AppearanceAgent saa(domainName, realm, lineMgr,
                          tcpPort, udpPort, tcpPort, bindIp,
                          &appearanceGroupFile,
                          refreshInterval,
                          resubscribeInterval, minResubscribeInterval, seizedResubscribeInterval,
                          SAA_PUBLISH_DELAY,
                          20,
                          serverMinExpiration,
                          serverDefaultExpiration,
                          serverMaxExpiration);
      saa.start();

      // Loop forever until signaled to shut down
      while (!gShutdownFlag)
      {
         OsTask::delay(2 * OsTime::MSECS_PER_SEC);
         // See if the list configuration file has changed.
         saa.getAppearanceGroupFileReader().refresh();
      }

      // Shut down the server.
      saa.shutdown();
   }

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

   // Delete the LineMgr Object
   delete lineMgr;

   // Say goodnight Gracie...
   return 0;
}
Example #17
0
// Constructor
SipPresenceMonitor::SipPresenceMonitor(SipUserAgent* userAgent,
                                       SipSubscriptionMgr* subscriptionMgr,
                                       UtlString& domainName,
                                       int hostPort,
                                       OsConfigDb* configFile,
                                       bool toBePublished,
                                       const char* persistentFile) :
   mpUserAgent(userAgent),
   mDomainName(domainName),
   mToBePublished(toBePublished),
   mLock(OsBSem::Q_PRIORITY, OsBSem::FULL),
   mpSubscriptionMgr(subscriptionMgr),
   mPersistentFile(persistentFile),
   mPersistenceTimer(mPersistTask.getMessageQueue(), 0),
   mPersistTask(this)
{
   // Read the persistent file to initialize mPersenceEventList, if
   // one is supplied.
   if (!mPersistentFile.isNull())
   {
      readPersistentFile();
   }

   char buffer[80];
   sprintf(buffer, "@%s:%d", mDomainName.data(), hostPort);
   mHostAndPort = UtlString(buffer);

   UtlString localAddress;
   OsSocket::getHostIp(&localAddress);

   OsConfigDb configDb;
   configDb.set("PHONESET_MAX_ACTIVE_CALLS_ALLOWED", 2*MAX_CONNECTIONS);

#ifdef INCLUDE_RTCP
   CRTCManager::getRTCPControl();
#endif //INCLUDE_RTCP
   // Start the media processing tasks.
   mpStartTasks();

   // Instantiate the call processing subsystem
   mpCallManager = new CallManager(FALSE,
                                   NULL,
                                   TRUE,                              // early media in 180 ringing
                                   &mCodecFactory,
                                   RTP_START_PORT,                    // rtp start
                                   RTP_START_PORT + (2*MAX_CONNECTIONS), // rtp end
                                   localAddress,
                                   localAddress,
                                   mpUserAgent,
                                   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, // inviteExpiresSeconds
                                   QOS_LAYER3_LOW_DELAY_IP_TOS,       // expeditedIpTos
                                   MAX_CONNECTIONS,                   // maxCalls
                                   sipXmediaFactoryFactory(&configDb));    // CpMediaInterfaceFactory

   mpDialInServer = new PresenceDialInServer(mpCallManager, configFile);
   mpCallManager->addTaoListener(mpDialInServer);
   mpDialInServer->start();

   // Start the call processing system
   mpCallManager->start();

   // Add self to the presence dial-in server for state change notification
   mpDialInServer->addStateChangeNotifier("Presence_Dial_In_Server", this);

   if (mToBePublished)
   {
      // Create the SIP Subscribe Server
      mpSubscribeServer = new SipSubscribeServer(*mpUserAgent, mSipPublishContentMgr,
                                                 *mpSubscriptionMgr, mPolicyHolder);
      // Arrange to generate default content for presence events.
      mSipPublishContentMgr.publishDefault(PRESENCE_EVENT_TYPE, PRESENCE_EVENT_TYPE,
                                           new PresenceDefaultConstructor);
      mpSubscribeServer->enableEventType(PRESENCE_EVENT_TYPE);
      mpSubscribeServer->start();
   }

   // Enable the xmlrpc sign-in/sign-out
   int HttpPort;
   if (configDb.get(CONFIG_SETTING_HTTP_PORT, HttpPort) != OS_SUCCESS)
   {
      HttpPort = PRESENCE_DEFAULT_HTTP_PORT;
   }

   mpXmlRpcSignIn = new XmlRpcSignIn(this, HttpPort);

   // Start the persist task.
   if (!mPersistentFile.isNull())
   {
      mPersistTask.start();
   }
}
Example #18
0
// Read config information.
void SipRedirectorMapping::readConfig(OsConfigDb& configDb)
{
   configDb.get("MEDIA_SERVER", mMediaServer);
   configDb.get("VOICEMAIL_SERVER", mVoicemailServer);
   configDb.get("MAPPING_RULES_FILENAME", mFileName);
}
Example #19
0
// Read config information.
void SipRedirectorJoin::readConfig(OsConfigDb& configDb)
{
   // The return status.
   // It will be OS_SUCCESS if this redirector is configured to do any work,
   // and OS_FAILED if not.
   mRedirectorActive = OS_FAILED;

   // Fetch the configuration parameters for the workaround features.
   // Defaults are set to match the previous behavior of the code.

   // One-second subscriptions.
   mOneSecondSubscription = configDb.getBoolean(CONFIG_SETTING_1_SEC, TRUE);
   Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                 "%s::readConfig mOneSecondSubscription = %d",
                 mLogName.data(), mOneSecondSubscription);

   // Fetch the call join festure code from the config file.
   // If it is null, it doesn't count.
   if ((configDb.get(CONFIG_SETTING_JOIN_CODE, mCallJoinCode) !=
        OS_SUCCESS) ||
       mCallJoinCode.isNull())
   {
      Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                    "%s::readConfig No call join feature code specified",
                    mLogName.data());
   }
   else
   {
      // Call join feature code is configured.
      // Initialize the system.
      Os::Logger::instance().log(FAC_SIP, PRI_INFO,
                    "%s::readConfig Call join feature code is '%s'",
                    mLogName.data(), mCallJoinCode.data());
      mRedirectorActive = OS_SUCCESS;

      // Record the two user-names that are excluded as being pick-up requests.
      mExcludedUser1 = mCallJoinCode;
      mExcludedUser1.append("*");
      mExcludedUser2 = mCallJoinCode;
      mExcludedUser2.append("#");
   }

   // Get the wait time for NOTIFYs in response to our SUBSCRIBEs.
   // Set the default value, to be overridden if the user specifies a valid
   // value.
   mWaitSecs = DEFAULT_WAIT_TIME_SECS;
   mWaitUSecs = DEFAULT_WAIT_TIME_USECS;
   Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                 "%s::readConfig Default wait time is %d.%06d",
                 mLogName.data(), mWaitSecs, mWaitUSecs);
   // Fetch the parameter value.
   UtlString waitUS;
   float waitf;
   if (configDb.get(CONFIG_SETTING_WAIT, waitUS) == OS_SUCCESS)
   {
      Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                    "%s::readConfig " CONFIG_SETTING_WAIT " is '%s'",
                    mLogName.data(), waitUS.data());
      // Parse the value, checking for errors.
      unsigned int char_count;
      sscanf(waitUS.data(), " %f %n", &waitf, &char_count);
      if (char_count != waitUS.length())
      {
         Os::Logger::instance().log(FAC_SIP, PRI_ERR,
                       "%s::readConfig Invalid format for "
                       CONFIG_SETTING_WAIT " '%s'",
                       mLogName.data(), waitUS.data());
      }
      else if (
         // Check that the value is in range.
         !(waitf >= MIN_WAIT_TIME && waitf <= MAX_WAIT_TIME))
      {
         Os::Logger::instance().log(FAC_SIP, PRI_ERR,
                       "%s::readConfig " CONFIG_SETTING_WAIT
                       " (%f) outside allowed range (%f to %f)",
                       mLogName.data(), waitf, MIN_WAIT_TIME, MAX_WAIT_TIME);
      }
      else
      {
         // Extract the seconds and microseconds, being careful to round
         // because the conversion from character data may have
         // been inexact.
         // Since waitf <= 100, usecs <= 100,000,000.
         int usecs = (int)((waitf * 1000000) + 0.0000005);
         mWaitSecs = usecs / 1000000;
         mWaitUSecs = usecs % 1000000;
         Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                       "%s::readConfig Wait time is %d.%06d",
                       mLogName.data(), mWaitSecs, mWaitUSecs);
      }
   }
}
Example #20
0
//
// 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;
}
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 ;
}
Example #22
0
    void testManipulators()
    {
        OsConfigDb *pDb = new OsConfigDb();
        pDb->set("Key1", "Value1");
        CPPUNIT_ASSERT_MESSAGE("verify that the database is not empty", 
                               !pDb->isEmpty());
        CPPUNIT_ASSERT_MESSAGE("has one entry", pDb->numEntries()==1);
                                                                                
        // test the remove() method
        //
        // We put the following block in its own scope so that the UtlString
        // reference (stored in "value") is released as a side effect of going
        // out of scope.  Otherwise, it will look like a memory leak.
        {
            UtlString value;
                                                                                
            pDb->remove("Key1");
            CPPUNIT_ASSERT_MESSAGE("verify that it looks empty", pDb->isEmpty());
            CPPUNIT_ASSERT_MESSAGE("has zero entries", pDb->numEntries()==0);
                                                                                
            pDb->set("Key1", "Value1");   // add the entry back
            pDb->set("Key1", "Value1b");  // change the value for an existing entry
            CPPUNIT_ASSERT_MESSAGE("verify that the database is not empty", 
                                   !pDb->isEmpty());
            CPPUNIT_ASSERT_EQUAL_MESSAGE("has one entry", 1, pDb->numEntries());
                                                                                
            OsStatus res = pDb->get("Key1", value);
            CPPUNIT_ASSERT(res == OS_SUCCESS);
            CPPUNIT_ASSERT_MESSAGE("that contains the revised value", 
                value.compareTo("Value1b") == 0);
                                                                                
            pDb->set("Key2", "Value2");
            pDb->set("Key3", "Value3");
            pDb->set("Key4", "Value4");
            CPPUNIT_ASSERT_MESSAGE("check the number of entries", 
                                   pDb->numEntries()==4);
            value.remove(0);
        }
                                                                                
        // test the storeToFile() method
        pDb->storeToFile("tmpdb");         // store the config db to the file
        delete pDb;                   // delete the database
                                                                                
        // test the loadFromFile() method
        //
        // We put the following block in its own scope so that the UtlString
        // reference (stored in "value") is released as a side effect of going
        // out of scope.  Otherwise, it will look like a memory leak.
        {
            UtlString  value;
            
            pDb = new OsConfigDb();       // create an empty database
            pDb->loadFromFile("tmpdb");        // load the data from a file
        }
                                                                                
        CPPUNIT_ASSERT_MESSAGE("verify the database is not empty", 
                               !pDb->isEmpty());

        CPPUNIT_ASSERT_MESSAGE("has four entries", pDb->numEntries()==4);

        UtlString value;
        OsStatus res = pDb->get("Key1", value);
        CPPUNIT_ASSERT_MESSAGE("contains correct data", 
            res == OS_SUCCESS && value.compareTo("Value1b") == 0);

        res = pDb->get("Key2", value);
        CPPUNIT_ASSERT_MESSAGE("contains correct data",
            res == OS_SUCCESS && value.compareTo("Value2") == 0);

        res = pDb->get("Key3", value);
        CPPUNIT_ASSERT_MESSAGE("contains correct data",
            res == OS_SUCCESS && value.compareTo("Value3") == 0);

        res = pDb->get("Key4", value);
        CPPUNIT_ASSERT_MESSAGE("contains correct data",
            res == OS_SUCCESS && value.compareTo("Value4") == 0);

        delete pDb;                   // delete the database
        value.remove(0);
    }
// Read config information.
void SipRedirectorFallback::readConfig(OsConfigDb& configDb)
{
   configDb.get("MAPPING_RULES_FILENAME", mFileName);
   mAllowUnbound = configDb.getBoolean("ALLOW_UNBOUND", false);
}
Example #24
0
//
// 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;
}
Example #25
0
UtlBoolean
SipRedirectServer::initialize(OsConfigDb& configDb
                              ///< Configuration parameters
                              )
{
   configDb.get("SIP_REGISTRAR_DOMAIN_NAME", mDefaultDomain);

   mProxyNormalPort = configDb.getPort("SIP_REGISTRAR_PROXY_PORT");
   if (mProxyNormalPort == PORT_DEFAULT)
   {
      mProxyNormalPort = SIP_PORT;
   }
   mAckRouteToProxy.insert(0, "<");
   mAckRouteToProxy.append(mDefaultDomain);
   mAckRouteToProxy.append(";lr>");

   // Load the list of redirect processors.
   mRedirectPlugins.readConfig(configDb);
   mRedirectorCount = mRedirectPlugins.entries();

   // Call their ::initialize() methods.
   mpConfiguredRedirectors = new RedirectorDescriptor[ mRedirectorCount ];
   PluginIterator iterator(mRedirectPlugins);
   RedirectPlugin* redirector;
   UtlString redirectorName;
   bool bAuthorityLevelDbAvailable;
   UtlString authorityLevelDbPrefix = RedirectPlugin::Prefix;
   authorityLevelDbPrefix.append( AuthorityLevelPrefix );
   authorityLevelDbPrefix.append( '.' );
   OsConfigDb authorityLevelDb;

   bAuthorityLevelDbAvailable = ( configDb.getSubHash( authorityLevelDbPrefix, authorityLevelDb ) == OS_SUCCESS );
   int i;       // Iterator sequence number.

   for (i = 0; (redirector = static_cast <RedirectPlugin*> (iterator.next( &redirectorName )));
        i++)
   {
      mpConfiguredRedirectors[i].name = redirectorName;
      if( ( mpConfiguredRedirectors[i].bActive =
             ( redirector->initialize(configDb, i, mDefaultDomain) == OS_SUCCESS ) ) )
      {
         redirector->setUserAgent(mpSipUserAgent);
         int authorityLevel;
         if( bAuthorityLevelDbAvailable         &&
             authorityLevelDb.get( redirectorName, authorityLevel ) == OS_SUCCESS )
         {
            mpConfiguredRedirectors[i].authorityLevel = authorityLevel;
         }
         else
         {
            mpConfiguredRedirectors[i].authorityLevel = LOWEST_AUTHORITY_LEVEL;
         }
         Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                       "SipRedirectServer::initialize "
                       "Initialized redirector %s (authority level = %zd)", redirectorName.data(), mpConfiguredRedirectors[i].authorityLevel );
      }
      else
      {
         Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                       "SipRedirectServer::initialize "
                       "Redirector %s is inactive ", redirectorName.data() );
      }
   }
   return true;
}
Example #26
0
   virtual bool execute(const HttpRequestContext& requestContext, ///< request context
                        UtlSList& params,                         ///< request param list
                        void* userData,                           ///< user data
                        XmlRpcResponse& response,                 ///< request response
                        ExecutionStatus& status
                        )
      {
         UtlString* dbName = dynamic_cast<UtlString*>(params.at(0));

         if (dbName && !dbName->isNull())
         {
            OsReadLock lock(*ConfigRPC::spDatabaseLock);

            // find the dataset registered with this name
            ConfigRPC* db = ConfigRPC::find(*dbName);
            if (db)
            {
               // check with the application to see if this request is authorized on this dataset
               status = db->mCallback->accessAllowed(requestContext, ConfigRPC_Callback::Get);
               if ( XmlRpcMethod::OK == status )
               {
                  // read in the dataset
                  OsConfigDb dataset;
                  OsStatus datasetStatus = db->load(dataset);
                  if ( OS_SUCCESS == datasetStatus )
                  {
                     // get the list of names that the request is asking for
                     UtlContainable* secondParam = params.at(1);
                     if ( secondParam )
                     {
                        UtlSList* nameList = dynamic_cast<UtlSList*>(secondParam);
                        if (nameList)
                        {
                           /*
                            * Iterate over the requested names
                            * - All must be present or the request is an error
                            * - For each name found, add the name and value to the
                            *   selectedParams hash to be returned in a success response.
                            */
                           UtlHashMap selectedParams;
                           UtlSListIterator requestedNames(*nameList);
                           UtlString* requestedName = NULL;
                           bool allNamesFound = true;

                           while (   allNamesFound
                                  && (requestedName = dynamic_cast<UtlString*>(requestedNames()))
                                  )
                           {
                              UtlString* paramValue = new UtlString();
                              if ( OS_SUCCESS == dataset.get(*requestedName, *paramValue) )
                              {
                                 UtlString* paramName  = new UtlString(*requestedName);
                                 // put it into the results
                                 selectedParams.insertKeyAndValue(paramName, paramValue);
                              }
                              else
                              {
                                 allNamesFound = false;
                                 delete paramValue;
                              }
                           }

                           if (allNamesFound)
                           {
                              // all were found - return the name/value pairs
                              response.setResponse(&selectedParams);
                           }
                           else
                           {
                              // at least one name was not found - return an error.
                              UtlString faultMsg;
                              faultMsg.append("parameter name '");
                              faultMsg.append(*requestedName);
                              faultMsg.append("' not found");
                              response.setFault(ConfigRPC::nameNotFound, faultMsg.data());
                              status = XmlRpcMethod::FAILED;
                           }

                           selectedParams.destroyAll();
                        }
                        else
                        {
                           // The second parameter was not a list
                           response.setFault( ConfigRPC::invalidType
                                             ,"namelist parameter is not an array"
                                             );
                           status = XmlRpcMethod::FAILED;
                        }
                     }
                     else // no parameter names specified
                     {
                        // return all names
                        UtlHashMap allParams;
                        UtlString  lastKey;
                        OsStatus   iterateStatus;
                        UtlString* paramName;
                        UtlString* paramValue;
                        bool       notEmpty = false;

                        for ( ( paramName  = new UtlString()
                               ,paramValue = new UtlString()
                               ,iterateStatus = dataset.getNext(lastKey, *paramName, *paramValue)
                               );
                              OS_SUCCESS == iterateStatus;
                              ( lastKey       = *paramName
                               ,paramName     = new UtlString()
                               ,paramValue    = new UtlString()
                               ,iterateStatus = dataset.getNext(lastKey, *paramName, *paramValue)
                               )
                             )
                        {
                           notEmpty = true; // got at least one parameter
                           // put it into the result array
                           allParams.insertKeyAndValue(paramName, paramValue);
                        }
                        // on the final iteration these were not used
                        delete paramName;
                        delete paramValue;

                        if (notEmpty)
                        {
                           response.setResponse(&allParams);
                           allParams.destroyAll();
                        }
                        else
                        {
                           // there is no way to send a well-formed but empty response,
                           // so a 'get all' on an empty dataset returns a fault.
                           UtlString faultMsg;
                           faultMsg.append("dataset '");
                           faultMsg.append(*dbName);
                           faultMsg.append("' has no parameters");
                           response.setFault(ConfigRPC::emptyDataset, faultMsg);
                           status = XmlRpcMethod::FAILED;
                        }
                     }
                  }
                  else
                  {
                     UtlString faultMsg("dataset load failed");
                     response.setFault(ConfigRPC::loadFailed, faultMsg);
                     status = XmlRpcMethod::FAILED;
                  }
               }
               else
               {
                  UtlString faultMsg("Access Denied");
                  response.setFault(XmlRpcMethod::FAILED, faultMsg.data());
               }
            }
            else
            {
               UtlString faultMsg;
               faultMsg.append("db lookup failed for '");
               faultMsg.append(*dbName);
               faultMsg.append("'");
               response.setFault( XmlRpcResponse::UnregisteredMethod, faultMsg.data());
               status = XmlRpcMethod::FAILED;
            }
         }
         else
         {
            response.setFault( XmlRpcResponse::EmptyParameterValue
                              ,"'dbname' parameter is missing or invalid type"
                              );
            status = XmlRpcMethod::FAILED;
         }

         return true;
      }
Example #27
0
// Constructor
SipRegistrar::SipRegistrar(OsConfigDb* configDb) :
   OsServerTask("SipRegistrar", NULL, SIPUA_DEFAULT_SERVER_OSMSG_QUEUE_SIZE),
   mConfigDb(configDb),
   mSipUserAgent(NULL),
   mRedirectServer(NULL),
   mRedirectMsgQ(NULL),
   // Create the SipRegistrarServer object so it will be available immediately,
   // but don't start the associated thread until the registrar is operational.
   mRegistrarServer(new SipRegistrarServer(*this)),
   mRegistrarMsgQ(NULL),
   mRegisterEventServer(NULL),
   mRegistrarPersist(NULL),
   mpRegDb(NULL),
   mpSubscribeDb(NULL),
   mpEntityDb(NULL)
{
   Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::SipRegistrar constructed.");


   // Some phones insist (incorrectly) on putting the proxy port number on urls;
   // we get it from the configuration so that we can ignore it.
   mProxyNormalPort = mConfigDb->getPort("SIP_REGISTRAR_PROXY_PORT");
   if (mProxyNormalPort == PORT_DEFAULT)
   {
      mProxyNormalPort = SIP_PORT;
   }

   // Domain Name
   mConfigDb->get("SIP_REGISTRAR_DOMAIN_NAME", mDefaultDomain);
   if ( mDefaultDomain.isNull() )
   {
      OsSocket::getHostIp(&mDefaultDomain);
      Os::Logger::instance().log(FAC_SIP, PRI_CRIT,
                    "SIP_REGISTRAR_DOMAIN_NAME not configured using IP '%s'",
                    mDefaultDomain.data()
                    );
   }
   // get the url parts for the domain
   Url defaultDomainUrl(mDefaultDomain);
   mDefaultDomainPort = defaultDomainUrl.getHostPort();
   defaultDomainUrl.getHostAddress(mDefaultDomainHost);
   // make sure that the unspecified domain name is also valid
   addValidDomain(mDefaultDomainHost, mDefaultDomainPort);

   // read the domain configuration
   OsConfigDb domainConfig;
   domainConfig.loadFromFile(SipXecsService::domainConfigPath());


   // Domain Aliases
   //   (other domain names that this registrar accepts as valid in the request URI)
   UtlString domainAliases;
   domainConfig.get(SipXecsService::DomainDbKey::SIP_DOMAIN_ALIASES, domainAliases);

   if (!domainAliases.isNull())
   {
      Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::SipRegistrar "
                    "SIP_DOMAIN_ALIASES : %s", domainAliases.data());
   }
   else
   {
      Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SipRegistrar::SipRegistrar "
                    "SIP_DOMAIN_ALIASES not found.");
   }

   UtlString aliasString;
   int aliasIndex = 0;
   while(NameValueTokenizer::getSubField(domainAliases.data(), aliasIndex,
                                         ", \t", &aliasString))
   {
      Url aliasUrl(aliasString);
      UtlString hostAlias;
      aliasUrl.getHostAddress(hostAlias);
      int port = aliasUrl.getHostPort();

      addValidDomain(hostAlias,port);
      aliasIndex++;
   }

   mongo::ConnectionString mongoConn = MongoDB::ConnectionInfo::connectionStringFromFile();
   mpRegDb = new RegDB(MongoDB::ConnectionInfo(mongoConn, RegDB::NS));
   mpSubscribeDb = new SubscribeDB(MongoDB::ConnectionInfo(mongoConn, SubscribeDB::NS));
   mpEntityDb = new EntityDB(MongoDB::ConnectionInfo(mongoConn, EntityDB::NS));

   mConfigDb->get("SIP_REGISTRAR_BIND_IP", mBindIp);
   if ((mBindIp.isNull()) || !OsSocket::isIp4Address(mBindIp))
   {
	  mBindIp = "0.0.0.0";
   }
}
Example #28
0
 virtual void readConfig(OsConfigDb& configDb)
 {
    configDb.get("BEHAVIOR", mBehavior );
 }