Skip to content
Snippets Groups Projects
Select Git revision
  • f2f69ce0c60395367f5a40dacf5e3e07d35e5fef
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/releaseWindowsTestOne
  • release/windowsReleaseTest
  • release/releaseTest
  • release/releaseWindowsTest
  • release/201910
  • release/qt/201910
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • 4.0.0
  • 2.2.0
  • 2.1.0
  • 2.0.1
  • 2.0.0
  • 1.4.1
  • 1.4.0
  • 1.3.0
  • 1.2.0
  • 1.1.0
31 results

HistoryDock.h

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    To find the state of this project's repository at the time of any of these versions, check out the tags.
    sipaccount.cpp 24.06 KiB
    /*
     *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc.
    *
    *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
    *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
    *
    *  This program is free software; you can redistribute it and/or modify
    *  it under the terms of the GNU General Public License as published by
    *  the Free Software Foundation; either version 3 of the License, or
    *  (at your option) any later version.
    *
    *  This program is distributed in the hope that it will be useful,
    *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    *  GNU General Public License for more details.
    *
    *  You should have received a copy of the GNU General Public License
    *  along with this program; if not, write to the Free Software
    *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     *
     *  Additional permission under GNU GPL version 3 section 7:
     *
     *  If you modify this program, or any covered work, by linking or
     *  combining it with the OpenSSL project's OpenSSL library (or a
     *  modified version of that library), containing parts covered by the
     *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
     *  grants you additional permission to convey the resulting work.
     *  Corresponding Source for a non-source form of such a combination
     *  shall include the source code for the parts of OpenSSL used as well
     *  as that of the covered work.
    */
    
    #include "sipaccount.h"
    #include "manager.h"
    #include "user_cfg.h"
    #include <pwd.h>
    
    
    SIPAccount::SIPAccount (const AccountID& accountID)
            : Account (accountID, "sip")
    	, _routeSet("")
            , _regc (NULL)
            , _bRegister (false)
            , _registrationExpire ("")
            , _publishedSameasLocal (true)
            , _publishedIpAddress ("")
            , _localPort (atoi (DEFAULT_SIP_PORT))
            , _publishedPort (atoi (DEFAULT_SIP_PORT))
    	, _tlsListenerPort (atoi (DEFAULT_SIP_TLS_PORT))
            , _transportType (PJSIP_TRANSPORT_UNSPECIFIED)
            , _transport (NULL)
            , _resolveOnce (false)
            , _credentialCount (0)
            , _cred (NULL)
            , _realm (DEFAULT_REALM)
            , _authenticationUsername ("")
            , _tlsSetting (NULL)
    	, _dtmfType(OVERRTP)
            , _displayName ("")
            , _tlsEnable(false)
    	, _tlsPortStr("")
    	, _tlsCaListFile("")
    	, _tlsCertificateFile("")
    	, _tlsPrivateKeyFile("")
    	, _tlsPassword("")
            , _tlsMethod("")
    	, _tlsCiphers("")
    	, _tlsServerName("")
    	, _tlsVerifyServer(false)
    	, _tlsVerifyClient(false)
    	, _tlsRequireClientCertificate(false)
    	, _tlsNegotiationTimeoutSec("")
    	, _tlsNegotiationTimeoutMsec("")
    	, _stunServer("")
    	, _tlsEnabled(false)
    	, _stunEnabled(false)
    	, _routeset("")
    	  // , _realm("")
    	, _authenticationUsename("")
    	, _tlsListenerPort("5061")
    	, _dtmfType("")
    	, _srtpEnabled(false)
    	, _srtpKeyExchange("")
    	, _srtpFallback(false)
    	, _zrtpDisplaySas(false)
    	, _zrtpDisplaySasOnce(false)
    	, _zrtpHelloHash(false)
    	, _zrtpNotSuppWarning(false)
    {
        
        // IP2IP settings must be loaded before singleton instanciation, cannot call it here... 
    
        // _link = SIPVoIPLink::instance ("");
    
        /* Represents the number of SIP accounts connected the same link */
        // dynamic_cast<SIPVoIPLink*> (_link)->incrementClients();
    
    }
    
    SIPAccount::~SIPAccount()
    {
        /* One SIP account less connected to the sip voiplink */
        dynamic_cast<SIPVoIPLink*> (_link)->decrementClients();
    
        /* Delete accounts-related information */
        _regc = NULL;
        free (_cred);
        free (_tlsSetting);
    }
    
    void SIPAccount::serialize(Engine *engine) {
    
    
    }
    
    
    void SIPAccount::unserialize(Conf::MappingNode *map) 
    {
      Conf::ScalarNode *val;
      Conf::MappingNode *srtpMap;
      Conf::MappingNode *tlsMap;
      Conf::MappingNode *zrtpMap;
    
      val = (Conf::ScalarNode *)(map->getValue(aliasKey));
      _alias = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(typeKey));
      _type = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(idKey));
      _accountID = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(usernameKey));
      _username = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(passwordKey));
      _password = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(hostnameKey));
      _hostname = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(accountEnableKey));
      _enabled = val->getValue().compare("true") ? true : false;
      //  val = (Conf::ScalarNode *)(map->getValue(mailboxKey));
      
      val = (Conf::ScalarNode *)(map->getValue(codecsKey));
      // _codecOrder = val->getValue();
    
      val = (Conf::ScalarNode *)(map->getValue(expireKey));
      _registrationExpire = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(interfaceKey));
      _interface = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(portKey));
      _localPort = atoi(val->getValue().data());
      // val = (Conf::ScalarNode *)(map->getValue(mailboxKey));
      val = (Conf::ScalarNode *)(map->getValue(publishAddrKey));
      _publishedIpAddress = val->getValue();
      val = (Conf::ScalarNode *)(map->getValue(publishPortKey));
      _publishedPort = atoi(val->getValue().data());
      val = (Conf::ScalarNode *)(map->getValue(sameasLocalKey));
      _publishedSameasLocal = val->getValue().compare("true") ? true : false;
      val = (Conf::ScalarNode *)(map->getValue(resolveOnceKey));
      _resolveOnce = val->getValue().compare("true") ? true : false;
      val = (Conf::ScalarNode *)(map->getValue(dtmfTypeKey));
      // _dtmfType = atoi(val->getValue();
    
      // stun enabled
    
      // get srtp submap
      srtpMap = (Conf::MappingNode *)(map->getValue(srtpKey));
    
      val = (Conf::ScalarNode *)(srtpMap->getValue(srtpEnableKey));
      _srtpEnabled = val->getValue().compare("true") ? true : false;
      val = (Conf::ScalarNode *)(srtpMap->getValue(keyExchangeKey));
      _srtpKeyExchange = val->getValue();
      val = (Conf::ScalarNode *)(srtpMap->getValue(rtpFallbackKey));
      _srtpFallback = val->getValue().compare("true") ? true : false;
      
      // get zrtp submap
      zrtpMap = (Conf::MappingNode *)(map->getValue(zrtpKey));
    
      val = (Conf::ScalarNode *)(zrtpMap->getValue(displaySasKey));
      _zrtpDisplaySas = val->getValue().compare("true") ? true : false;
      val = (Conf::ScalarNode *)(zrtpMap->getValue(displaySasOnceKey));
      _zrtpDisplaySasOnce = val->getValue().compare("true") ? true : false;
      val = (Conf::ScalarNode *)(zrtpMap->getValue(helloHashEnabledKey));
      _zrtpHelloHash = val->getValue().compare("true") ? true : false;
      val = (Conf::ScalarNode *)(zrtpMap->getValue(notSuppWarningKey));
      _zrtpNotSuppWarning = val->getValue().compare("true") ? true : false;
    
      // get tls submap
      tlsMap = (Conf::MappingNode *)(map->getValue(tlsKey));
    
      val = (Conf::ScalarNode *)(tlsMap->getValue(tlsEnableKey));
      _tlsEnable = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(tlsPortKey));
      _tlsPortStr = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(certificateKey));
      _tlsCertificateFile = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(calistKey));
      _tlsCaListFile = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(ciphersKey));
      _tlsCiphers = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(methodKey));
      _tlsMethod = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(timeoutKey));
      _tlsNegotiationTimeoutSec = val->getValue();
      _tlsNegotiationTimeoutMsec = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(tlsPasswordKey));
      _tlsPassword = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(privateKeyKey));
      _tlsPrivateKeyFile = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(requireCertifKey));
      _tlsRequireClientCertificate = val->getValue().compare("true") ? true : false;
      val = (Conf::ScalarNode *)(tlsMap->getValue(serverKey));
      _tlsServerName = val->getValue();
      val = (Conf::ScalarNode *)(tlsMap->getValue(verifyClientKey));
      _tlsVerifyServer = val->getValue().compare("true") ? true : false;
      val = (Conf::ScalarNode *)(tlsMap->getValue(verifyServerKey));
      _tlsVerifyClient = val->getValue().compare("true") ? true : false;
    }
    
    
    // void SIPAccount::setVoIPLink(VoIPLink *link) {
    void SIPAccount::setVoIPLink() {
    
        _link = SIPVoIPLink::instance ("");
        dynamic_cast<SIPVoIPLink*> (_link)->incrementClients();
    
    }
    
    
    int SIPAccount::initCredential (void)
    {
        int credentialCount = 0;
        credentialCount = Manager::instance().getConfigInt (_accountID, CONFIG_CREDENTIAL_NUMBER);
        credentialCount += 1;
    
        bool md5HashingEnabled = false;
        int dataType = 0;
        md5HashingEnabled = Manager::instance().getConfigBool (PREFERENCES, CONFIG_MD5HASH);
        std::string digest;
    
        // Create the credential array
        pjsip_cred_info * cred_info = (pjsip_cred_info *) malloc (sizeof (pjsip_cred_info) * (credentialCount));
    
        if (cred_info == NULL) {
            _error ("SipAccount: Error: Failed to set cred_info for account %s", _accountID.c_str());
            return !SUCCESS;
        }
    
        pj_bzero (cred_info, sizeof (pjsip_cred_info) *credentialCount);
    
        // Use authentication username if provided
        if (!_authenticationUsername.empty()) {
            cred_info[0].username = pj_str (strdup (_authenticationUsername.c_str()));
        } else {
            cred_info[0].username = pj_str (strdup (_username.c_str()));
        }
    
        // Set password
        cred_info[0].data =  pj_str (strdup (_password.c_str()));
    
        // Set realm for that credential. * by default.
        cred_info[0].realm = pj_str (strdup (_realm.c_str()));
    
        // We want to make sure that the password is really
        // 32 characters long. Otherwise, pjsip will fail
        // on an assertion.
        if (md5HashingEnabled && _password.length() == 32) {
            dataType = PJSIP_CRED_DATA_DIGEST;
            _debug ("Setting digest ");
        } else {
            dataType = PJSIP_CRED_DATA_PLAIN_PASSWD;
        }
    
        // Set the datatype
        cred_info[0].data_type = dataType;
        
        // Set the secheme
        cred_info[0].scheme = pj_str ( (char*) "digest");
    
        int i;
    
        for (i = 1; i < credentialCount; i++) {
            std::string credentialIndex;
            std::stringstream streamOut;
            streamOut << i - 1;
            credentialIndex = streamOut.str();
    
            std::string section = std::string ("Credential") + std::string (":") + _accountID + std::string (":") + credentialIndex;
    
            std::string username = Manager::instance().getConfigString (section, USERNAME);
            std::string password = Manager::instance().getConfigString (section, PASSWORD);
            std::string realm = Manager::instance().getConfigString (section, REALM);
    
            cred_info[i].username = pj_str (strdup (username.c_str()));
            cred_info[i].data = pj_str (strdup (password.c_str()));
            cred_info[i].realm = pj_str (strdup (realm.c_str()));
    
            // We want to make sure that the password is really
            // 32 characters long. Otherwise, pjsip will fail
            // on an assertion.
    
            if (md5HashingEnabled && _password.length() == 32) {
                dataType = PJSIP_CRED_DATA_DIGEST;
                _debug ("Setting digest ");
            } else {
                dataType = PJSIP_CRED_DATA_PLAIN_PASSWD;
            }
    
            cred_info[i].data_type = dataType;
    
            cred_info[i].scheme = pj_str ( (char*) "digest");
    
            _debug ("Setting credential %d realm = %s passwd = %s username = %s data_type = %d", i, realm.c_str(), password.c_str(), username.c_str(), cred_info[i].data_type);
        }
    
        _credentialCount = credentialCount;
    
        _cred = cred_info;
    
        return SUCCESS;
    }
    
    
    int SIPAccount::registerVoIPLink()
    {
        _debug ("Account: Register account %s", getAccountID().c_str());
    
        // Init general settings
        // loadConfig();
    
        if (_hostname.length() >= PJ_MAX_HOSTNAME) {
            return !SUCCESS;
        }
    
        // Init set of additional credentials, if supplied by the user
        initCredential();
    
        // Init TLS settings if the user wants to use TLS
        bool tlsEnabled = Manager::instance().getConfigBool (_accountID, TLS_ENABLE);
    
        if (tlsEnabled) {
            _transportType = PJSIP_TRANSPORT_TLS;
            initTlsConfiguration();
        }
    
        // Init STUN settings for this account if the user selected it
        bool stunEnabled = Manager::instance().getConfigBool (_accountID, STUN_ENABLE);
    
        if (stunEnabled) {
            _transportType = PJSIP_TRANSPORT_START_OTHER;
            initStunConfiguration ();
        }
    
        // In our definition of the
        // ip2ip profile (aka Direct IP Calls),
        // no registration should be performed
        if (_accountID != IP2IP_PROFILE) {
            int status = _link->sendRegister (_accountID);
            ASSERT (status , SUCCESS);
        }
    
        return SUCCESS;
    }
    
    int SIPAccount::unregisterVoIPLink()
    {
        _debug ("Unregister account %s" , getAccountID().c_str());
    
        if (_accountID == IP2IP_PROFILE) {
            return true;
        }
    
        if (_link->sendUnregister (_accountID)) {
            setRegistrationInfo (NULL);
            return true;
        } else
            return false;
    
    }
    
    pjsip_ssl_method SIPAccount::sslMethodStringToPjEnum (const std::string& method)
    {
        if (method == "Default") {
            return PJSIP_SSL_UNSPECIFIED_METHOD;
        }
    
        if (method == "TLSv1") {
            return PJSIP_TLSV1_METHOD;
        }
    
        if (method == "SSLv2") {
            return PJSIP_SSLV2_METHOD;
        }
    
        if (method == "SSLv3") {
            return PJSIP_SSLV3_METHOD;
        }
    
        if (method == "SSLv23") {
            return PJSIP_SSLV23_METHOD;
        }
    
        return PJSIP_SSL_UNSPECIFIED_METHOD;
    }
    
    void SIPAccount::initTlsConfiguration (void)
    {
        /*
         * Initialize structure to zero
         */
        if (_tlsSetting) {
            free (_tlsSetting);
            _tlsSetting = NULL;
        }
    
        // TLS listener is unique and should be only modified through IP2IP_PROFILE
        std::string tlsPortStr = Manager::instance().getConfigString(_accountID, TLS_LISTENER_PORT);
        setTlsListenerPort(atoi(tlsPortStr.c_str()));
        
        _tlsSetting = (pjsip_tls_setting *) malloc (sizeof (pjsip_tls_setting));
    
        assert (_tlsSetting);
    
        pjsip_tls_setting_default (_tlsSetting);
    
        std::string tlsCaListFile = Manager::instance().getConfigString (_accountID, TLS_CA_LIST_FILE);
        std::string tlsCertificateFile = Manager::instance().getConfigString (_accountID, TLS_CERTIFICATE_FILE);
        std::string tlsPrivateKeyFile = Manager::instance().getConfigString (_accountID, TLS_PRIVATE_KEY_FILE);
        std::string tlsPassword = Manager::instance().getConfigString (_accountID, TLS_PASSWORD);
        std::string tlsMethod = Manager::instance().getConfigString (_accountID, TLS_METHOD);
        std::string tlsCiphers = Manager::instance().getConfigString (_accountID, TLS_CIPHERS);
        std::string tlsServerName = Manager::instance().getConfigString (_accountID, TLS_SERVER_NAME);
        bool tlsVerifyServer = Manager::instance().getConfigBool (_accountID, TLS_VERIFY_SERVER);
        bool tlsVerifyClient = Manager::instance().getConfigBool (_accountID, TLS_VERIFY_CLIENT);
        bool tlsRequireClientCertificate = Manager::instance().getConfigBool (_accountID, TLS_REQUIRE_CLIENT_CERTIFICATE);
        std::string tlsNegotiationTimeoutSec = Manager::instance().getConfigString (_accountID, TLS_NEGOTIATION_TIMEOUT_SEC);
        std::string tlsNegotiationTimeoutMsec = Manager::instance().getConfigString (_accountID, TLS_NEGOTIATION_TIMEOUT_MSEC);
    
        pj_cstr (&_tlsSetting->ca_list_file, tlsCaListFile.c_str());
        pj_cstr (&_tlsSetting->cert_file, tlsCertificateFile.c_str());
        pj_cstr (&_tlsSetting->privkey_file, tlsPrivateKeyFile.c_str());
        pj_cstr (&_tlsSetting->password, tlsPassword.c_str());
        _tlsSetting->method = sslMethodStringToPjEnum (tlsMethod);
        pj_cstr (&_tlsSetting->ciphers, tlsCiphers.c_str());
        pj_cstr (&_tlsSetting->server_name, tlsServerName.c_str());
    
        _tlsSetting->verify_server = (tlsVerifyServer == true) ? PJ_TRUE: PJ_FALSE;
        _tlsSetting->verify_client = (tlsVerifyClient == true) ? PJ_TRUE: PJ_FALSE;
        _tlsSetting->require_client_cert = (tlsRequireClientCertificate == true) ? PJ_TRUE: PJ_FALSE;
    
        _tlsSetting->timeout.sec = atol (tlsNegotiationTimeoutSec.c_str());
        _tlsSetting->timeout.msec = atol (tlsNegotiationTimeoutMsec.c_str());
    
    }
    
    void SIPAccount::initStunConfiguration (void)
    {
        size_t pos;
        std::string stunServer, serverName, serverPort;
    
        stunServer = Manager::instance().getConfigString (_accountID, STUN_SERVER);
    
        // Init STUN socket
        pos = stunServer.find (':');
    
        if (pos == std::string::npos) {
            _stunServerName = pj_str ( (char*) stunServer.data());
            _stunPort = PJ_STUN_PORT;
            //stun_status = pj_sockaddr_in_init (&stun_srv.ipv4, &stun_adr, (pj_uint16_t) 3478);
        } else {
            serverName = stunServer.substr (0, pos);
            serverPort = stunServer.substr (pos + 1);
            _stunPort = atoi (serverPort.data());
            _stunServerName = pj_str ( (char*) serverName.data());
            //stun_status = pj_sockaddr_in_init (&stun_srv.ipv4, &stun_adr, (pj_uint16_t) nPort);
        }
    }
    
    void SIPAccount::loadConfig()
    {
        // Load primary credential
        setUsername (Manager::instance().getConfigString (_accountID, USERNAME));
        setRouteSet(Manager::instance().getConfigString(_accountID, ROUTESET));
        setPassword (Manager::instance().getConfigString (_accountID, PASSWORD));
        _authenticationUsername = Manager::instance().getConfigString (_accountID, AUTHENTICATION_USERNAME);
        _realm = Manager::instance().getConfigString (_accountID, REALM);
        _resolveOnce = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_RESOLVE_ONCE) == "1" ? true : false;
    
        // Load general account settings
        setHostname (Manager::instance().getConfigString (_accountID, HOSTNAME));
    
        if (Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE).empty()) {
            _registrationExpire = DFT_EXPIRE_VALUE;
        } else {
            _registrationExpire = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE);
        }
    
        // Load network settings
        // Local parameters
    
        // Load local interface
        setLocalInterface(Manager::instance().getConfigString (_accountID, LOCAL_INTERFACE));
    
        std::string localPort = Manager::instance().getConfigString (_accountID, LOCAL_PORT);
        setLocalPort (atoi (localPort.c_str()));
    
    
        // Published parameters
        setPublishedSameasLocal (Manager::instance().getConfigString (_accountID, PUBLISHED_SAMEAS_LOCAL) == TRUE_STR ? true : false);
    
        std::string publishedPort = Manager::instance().getConfigString (_accountID, PUBLISHED_PORT);
    
        setPublishedPort (atoi (publishedPort.c_str()));
    
        setPublishedAddress (Manager::instance().getConfigString (_accountID, PUBLISHED_ADDRESS));
    
        if(Manager::instance().getConfigString (_accountID, ACCOUNT_DTMF_TYPE) == OVERRTPSTR)
        	_dtmfType = OVERRTP;
    	else
    		_dtmfType = SIPINFO;
    
        // Init TLS settings if the user wants to use TLS
        bool tlsEnabled = Manager::instance().getConfigBool (_accountID, TLS_ENABLE);
    
        if (tlsEnabled) {
            initTlsConfiguration();
            _transportType = PJSIP_TRANSPORT_TLS;
        } else {
            _transportType = PJSIP_TRANSPORT_UDP;
        }
    
        // Account generic
        Account::loadConfig();
    }
    
    bool SIPAccount::fullMatch (const std::string& username, const std::string& hostname)
    {
        return (userMatch (username) && hostnameMatch (hostname));
    }
    
    bool SIPAccount::userMatch (const std::string& username)
    {
        if (username.empty()) {
            return false;
        }
    
        return (username == getUsername());
    }
    
    bool SIPAccount::hostnameMatch (const std::string& hostname)
    {
        return (hostname == getHostname());
    }
    
    std::string SIPAccount::getMachineName (void)
    {
        std::string hostname;
        hostname = std::string (pj_gethostname()->ptr, pj_gethostname()->slen);
        return hostname;
    }
    
    std::string SIPAccount::getLoginName (void)
    {
        std::string username;
    
        uid_t uid = getuid();
    
        struct passwd * user_info = NULL;
        user_info = getpwuid (uid);
    
        if (user_info != NULL) {
            username = user_info->pw_name;
        }
    
        return username;
    }
    
    std::string SIPAccount::getTransportMapKey(void)
    {
        
        std::stringstream out;
        out << getLocalPort();
        std::string localPort = out.str();
    
        return localPort;
    }
    
    
    std::string SIPAccount::getFromUri (void)
    {
        char uri[PJSIP_MAX_URL_SIZE];
    
        std::string scheme;
        std::string transport;
        std::string username = _username;
        std::string hostname = _hostname;
    
        // UDP does not require the transport specification
    
        if (_transportType == PJSIP_TRANSPORT_TLS) {
            scheme = "sips:";
            transport = ";transport=" + std::string (pjsip_transport_get_type_name (_transportType));
        } else {
            scheme = "sip:";
            transport = "";
        }
    
        // Get login name if username is not specified
        if (_username.empty()) {
            username = getLoginName();
        }
    
    
        // Get machine hostname if not provided
        if (_hostname.empty()) {
          hostname = getMachineName();
        }
    
    
        int len = pj_ansi_snprintf (uri, PJSIP_MAX_URL_SIZE,
    
                                    "<%s%s@%s%s>",
                                    scheme.c_str(),
                                    username.c_str(),
                                    hostname.c_str(),
                                    transport.c_str());
    
        return std::string (uri, len);
    }
    
    std::string SIPAccount::getToUri (const std::string& username)
    {
        char uri[PJSIP_MAX_URL_SIZE];
    
        std::string scheme;
        std::string transport;
        std::string hostname = "";
    
        // UDP does not require the transport specification
    
        if (_transportType == PJSIP_TRANSPORT_TLS) {
            scheme = "sips:";
            transport = ";transport=" + std::string (pjsip_transport_get_type_name (_transportType));
        } else {
            scheme = "sip:";
            transport = "";
        }
    
        // Check if scheme is already specified
        if (username.find ("sip") == 0) {
            scheme = "";
        }
    
        // Check if hostname is already specified
        if (username.find ("@") == std::string::npos) {
            // hostname not specified
    	hostname = _hostname;
        }
    
        int len = pj_ansi_snprintf (uri, PJSIP_MAX_URL_SIZE,
    
                                    "<%s%s%s%s%s>",
                                    scheme.c_str(),
                                    username.c_str(),
                                    (hostname.empty()) ? "" : "@",
                                    hostname.c_str(),
                                    transport.c_str());
    
        return std::string (uri, len);
    }
    
    std::string SIPAccount::getServerUri (void)
    {
        char uri[PJSIP_MAX_URL_SIZE];
    
        std::string scheme;
        std::string transport;
        std::string hostname = _hostname;
    
        // UDP does not require the transport specification
    
        if (_transportType == PJSIP_TRANSPORT_TLS) {
            scheme = "sips:";
            transport = ";transport=" + std::string (pjsip_transport_get_type_name (_transportType));
        } else {
            scheme = "sip:";
            transport = "";
        }
    
        int len = pj_ansi_snprintf (uri, PJSIP_MAX_URL_SIZE,
                                    "<%s%s%s>",
                                    scheme.c_str(),
                                    hostname.c_str(),
                                    transport.c_str());
    
        return std::string (uri, len);
    }
    
    std::string SIPAccount::getContactHeader (const std::string& address, const std::string& port)
    {
        char contact[PJSIP_MAX_URL_SIZE];
        const char * beginquote, * endquote;
    
        std::string scheme;
        std::string transport;
    
        // if IPV6, should be set to []
        beginquote = endquote = "";
    
        // UDP does not require the transport specification
    
        if (_transportType == PJSIP_TRANSPORT_TLS) {
            scheme = "sips:";
            transport = ";transport=" + std::string (pjsip_transport_get_type_name (_transportType));
        } else {
            scheme = "sip:";
            transport = "";
        }
    
        _displayName = Manager::instance().getConfigString (_accountID, DISPLAY_NAME);
    
        _debug ("Display Name: %s", _displayName.c_str());
    
        int len = pj_ansi_snprintf (contact, PJSIP_MAX_URL_SIZE,
    
                                    "%s%s<%s%s%s%s%s%s:%d%s>",
                                    _displayName.c_str(),
                                    (_displayName.empty() ? "" : " "),
                                    scheme.c_str(),
                                    _username.c_str(),
                                    (_username.empty() ? "":"@"),
                                    beginquote,
                                    address.c_str(),
                                    endquote,
                                    atoi (port.c_str()),
                                    transport.c_str());
    
        return std::string (contact, len);
    }