示例#1
0
文件: main.cpp 项目: astubbs/sipxecs
//
// The main entry point to the sipXpark
//
int main(int argc, char* argv[])
{
   // Block all signals in this the main thread.
   // Any threads created from now on will have all signals masked.
   OsTask::blockSignals();

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

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

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

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

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

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

    // Initialize log file
    initSysLog(&configDb);

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

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

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

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

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

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

    UtlString   domain;
    UtlString   realm;
    UtlString   user;

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

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

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

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

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

             UtlString ha1_authenticator;
             UtlString authtype;

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

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

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

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

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

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

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

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

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

    mpStartTasks();

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

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



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

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

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

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

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

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

    // Loop forever until signaled to shut down

    int numTwoSecIntervals = 0;
    int CleanLoopWaitTimeSecs = 10;

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

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

    }

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

    // Say goodnight Gracie...
    return 0;
}
   // Adds an 'Authorization' header to the supplied request based on the challenge
   // contained in the supplied response.  In order to succeed, the SIP identity
   // designated in the From header of the request must have an entry in the 
   // credential database supplied to instantiateAllTestFixtures() 
   bool addCredentialsToRequest( SipMessage& request, const SipMessage& response )
   {
      bool result = false;
      CredentialDB* pCredDB = CredentialDB::getInstance( mCredentialDbName );
      if( pCredDB )
      {
         // retrieve information in the Www-authenticate: header
         UtlString dummy, nonce, realm;
         if( response.getAuthenticateData( &dummy,
                                           &realm,
                                           &nonce,
                                           &dummy,
                                           &dummy,
                                           &dummy,
                                           HttpMessage::SERVER,
                                           0 ) )
         {
            // look for credentials belonging to the requesting user.
            Url fromUrl;
            UtlString userId;
            UtlString authTypeDB;
            UtlString passTokenDB;
            UtlString fromUriAsString;
            UtlString user;

            request.getFromUrl(fromUrl); 
            fromUrl.getUserId( user );
            fromUrl.getUri( fromUriAsString );

            if( pCredDB->getCredential(fromUrl,
                                       realm,
                                       userId,
                                       passTokenDB,
                                       authTypeDB) )
            {
               // generate response hash
               // TBD - 25-jan-2010 work might be needed if these tests are re-enabled
               UtlString responseHash;
               UtlString method;

               request.getRequestMethod(&method);
               HttpMessage::buildMd5Digest(passTokenDB.data(),
                                           HTTP_MD5_ALGORITHM,
                                           nonce.data(),
                                           NULL, // client nonce
                                           "00000001", // nonce count
                                           "",
                                           method.data(),
                                           fromUriAsString.data(),
                                           NULL,
                                           &responseHash
                                           );
               
               // add authorization header
               request.removeHeader( HTTP_AUTHORIZATION_FIELD, 0);
               request.setDigestAuthorizationData(         user.data(),
                                                           realm.data(),
                                                           nonce.data(),
                                                           fromUriAsString.data(),
                                                           responseHash.data(),
                                                           HTTP_MD5_ALGORITHM,
                                                           NULL,//clientNonce.data(),
                                                           NULL,
                                                           HTTP_QOP_AUTH,
                                                           "00000001", // nonce count
                                                           HttpMessage::SERVER
                                                           );  
               result = true;
            }
         }
      }
      return result;
   }
示例#3
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;
}
示例#4
0
// Get and add the credentials for sipXregistrar
SipLineMgr* 
SipRedirectorJoin::addCredentials (UtlString domain, UtlString realm)
{
   SipLine* line = NULL;
   SipLineMgr* lineMgr = NULL;
   UtlString user;

   CredentialDB* credentialDb;
   if ((credentialDb = CredentialDB::getInstance()))
   {
      Url identity;

      identity.setUserId(REGISTRAR_ID_TOKEN);
      identity.setHostAddress(domain);
      UtlString ha1_authenticator;
      UtlString authtype;
      bool bSuccess = false;
      
      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
                                                    )
                      )
                  {
                     lineMgr->setDefaultOutboundLine(identity);
                     bSuccess = true;

                     OsSysLog::add(FAC_SIP, PRI_INFO,
                                   "Added identity '%s': user='******' realm='%s'"
                                   ,identity.toString().data(), user.data(), realm.data()
                                   );
                  }
                  else
                  {
                     OsSysLog::add(FAC_SIP, PRI_ERR,
                                   "Error adding identity '%s': user='******' realm='%s'\n"
                                   "Call Join feature will not work!",
                                   identity.toString().data(), user.data(), realm.data()
                                   );
                  }
               }
               else
               {
                  OsSysLog::add(FAC_SIP, PRI_ERR, "addLine failed. Call Join feature will not work!" );
               }
            }
            else
            {
               OsSysLog::add(FAC_SIP, PRI_ERR,
                             "Constructing SipLineMgr failed. Call Join feature will not work!" );
            }
         }
         else
         {
            OsSysLog::add(FAC_SIP, PRI_ERR,
                          "Constructing SipLine failed. Call Join feature will not work!" );
         }
      }
      else
      {
         OsSysLog::add(FAC_SIP, PRI_ERR,
                       "No credential found for '%s' in realm '%s'. "
                       "Call Join feature will not work!"
                       ,identity.toString().data(), realm.data()
                       );
      }
      
      if( !bSuccess )
      {
         delete line;
         line = NULL;
         
         delete lineMgr;
         lineMgr = NULL;         
      }
   }

   credentialDb->releaseInstance();

   return lineMgr;
}