diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2685123ca149bcaaa8f311f9c31abe6bfe6f5e76
--- /dev/null
+++ b/daemon/src/sip/siptransport.cpp
@@ -0,0 +1,555 @@
+/*
+ *  Copyright (C) [2004, 2012] Savoir-Faire Linux Inc.
+ *
+ *  Author: Alexandre Savard <alexandre.savard@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 <map>
+
+#include <pjsip.h>
+#include <pjlib.h>
+#include <pjsip_ua.h>
+#include <pjlib-util.h>
+#include <pjnath.h>
+#include <pjnath/stun_config.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <linux/if.h>
+
+#include "siptransport.h"
+#include "manager.h"
+
+#include "sip/sdp.h"
+#include "sipcall.h"
+#include "sipaccount.h"
+#include "eventthread.h"
+#include "sdes_negotiator.h"
+
+#include "dbus/dbusmanager.h"
+#include "dbus/callmanager.h"
+#include "dbus/configurationmanager.h"
+
+static pjsip_transport *localUDPTransport_ = NULL; /** The default transport (5060) */
+
+std::string SipTransport::getSIPLocalIP()
+{
+    pj_sockaddr ip_addr;
+
+    if (pj_gethostip(pj_AF_INET(), &ip_addr) == PJ_SUCCESS)
+        return pj_inet_ntoa(ip_addr.ipv4.sin_addr);
+    else  {
+        ERROR("SipTransport: Could not get local IP");
+        return "";
+    }
+}
+
+std::vector<std::string> SipTransport::getAllIpInterfaceByName()
+{
+    static ifreq ifreqs[20];
+    ifconf ifconf;
+
+    std::vector<std::string> ifaceList;
+    ifaceList.push_back("default");
+
+    ifconf.ifc_buf = (char*) (ifreqs);
+    ifconf.ifc_len = sizeof(ifreqs);
+
+    int sock = socket(AF_INET,SOCK_STREAM,0);
+
+    if (sock >= 0) {
+        if (ioctl(sock, SIOCGIFCONF, &ifconf) >= 0)
+            for (unsigned i = 0; i < ifconf.ifc_len / sizeof(ifreq); ++i)
+                ifaceList.push_back(std::string(ifreqs[i].ifr_name));
+
+        close(sock);
+    }
+
+    return ifaceList;
+}
+
+std::string SipTransport::getInterfaceAddrFromName(const std::string &ifaceName)
+{
+    int fd = socket(AF_INET, SOCK_DGRAM,0);
+
+    if (fd < 0) {
+        ERROR("SipTransport: Error: could not open socket: %m");
+        return "";
+    }
+
+    ifreq ifr;
+    strcpy(ifr.ifr_name, ifaceName.c_str());
+    memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
+    ifr.ifr_addr.sa_family = AF_INET;
+
+    ioctl(fd, SIOCGIFADDR, &ifr);
+    close(fd);
+
+    sockaddr_in *saddr_in = (sockaddr_in *) &ifr.ifr_addr;
+    return inet_ntoa(saddr_in->sin_addr);
+}
+
+std::vector<std::string> SipTransport::getAllIpInterface()
+{
+    pj_sockaddr addrList[16];
+    unsigned addrCnt = PJ_ARRAY_SIZE(addrList);
+
+    std::vector<std::string> ifaceList;
+
+    if (pj_enum_ip_interface(pj_AF_INET(), &addrCnt, addrList) == PJ_SUCCESS) {
+        for (unsigned i = 0; i < addrCnt; i++) {
+            char addr[PJ_INET_ADDRSTRLEN];
+            pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0);
+            ifaceList.push_back(std::string(addr));
+        }
+    }
+
+    return ifaceList;
+}
+
+SipTransport::SipTransport(pjsip_endpoint *endpt, pj_caching_pool *cp, pj_pool_t *pool) : transportMap_(), stunSocketMap_(), cp_(cp), pool_(pool), endpt_(endpt)
+{
+}
+
+SipTransport::~SipTransport()
+{
+}
+
+pj_bool_t
+stun_sock_on_status_cb(pj_stun_sock * /*stun_sock*/, pj_stun_sock_op op,
+                       pj_status_t status)
+{
+    switch (op) {
+        case PJ_STUN_SOCK_DNS_OP:
+            DEBUG("SipTransport: Stun operation dns resolution");
+            break;
+        case PJ_STUN_SOCK_BINDING_OP:
+            DEBUG("SipTransport: Stun operation binding");
+            break;
+        case PJ_STUN_SOCK_KEEP_ALIVE_OP:
+            DEBUG("SipTransport: Stun operation keep alive");
+            break;
+        case PJ_STUN_SOCK_MAPPED_ADDR_CHANGE:
+            DEBUG("SipTransport: Stun operation address mapping change");
+            break;
+        default:
+            DEBUG("SipTransport: Stun unknown operation");
+            break;
+    }
+
+    if (status == PJ_SUCCESS) {
+        DEBUG("SipTransport: Stun operation success");
+    } else {
+        ERROR("SipTransport: Stun operation failure");
+    }
+
+    // Always return true so the stun transport registration retry even on failure
+    return true;
+}
+
+static pj_bool_t
+stun_sock_on_rx_data_cb(pj_stun_sock * /*stun_sock*/, void * /*pkt*/,
+                        unsigned /*pkt_len*/,
+                        const pj_sockaddr_t * /*src_addr*/,
+                        unsigned /*addr_len*/)
+{
+    return PJ_TRUE;
+}
+
+
+pj_status_t SipTransport::createStunResolver(pj_str_t serverName, pj_uint16_t port)
+{
+    pj_stun_config stunCfg;
+    pj_stun_config_init(&stunCfg, &cp_->factory, 0, pjsip_endpt_get_ioqueue(endpt_), pjsip_endpt_get_timer_heap(endpt_));
+
+    DEBUG("***************** Create Stun Resolver *********************");
+
+    static const pj_stun_sock_cb stun_sock_cb = {
+        stun_sock_on_rx_data_cb,
+        NULL,
+        stun_sock_on_status_cb
+    };
+
+    pj_stun_sock *stun_sock;
+    std::string stunResolverName(serverName.ptr, serverName.slen);
+    pj_status_t status = pj_stun_sock_create(&stunCfg, stunResolverName.c_str(), pj_AF_INET(), &stun_sock_cb, NULL, NULL, &stun_sock);
+
+    // store socket inside list
+    DEBUG("     insert %s resolver in map", stunResolverName.c_str());
+    stunSocketMap_.insert(std::pair<std::string, pj_stun_sock *>(stunResolverName, stun_sock));
+
+    if (status != PJ_SUCCESS) {
+        char errmsg[PJ_ERR_MSG_SIZE];
+        pj_strerror(status, errmsg, sizeof(errmsg));
+        ERROR("SipTransport: Error creating STUN socket for %.*s: %s", (int) serverName.slen, serverName.ptr, errmsg);
+        return status;
+    }
+
+    status = pj_stun_sock_start(stun_sock, &serverName, port, NULL);
+
+    if (status != PJ_SUCCESS) {
+        char errmsg[PJ_ERR_MSG_SIZE];
+        pj_strerror(status, errmsg, sizeof(errmsg));
+        DEBUG("SipTransport: Error starting STUN socket for %.*s: %s", (int) serverName.slen, serverName.ptr, errmsg);
+        pj_stun_sock_destroy(stun_sock);
+    }
+
+    return status;
+}
+
+pj_status_t SipTransport::destroyStunResolver(const std::string serverName)
+{
+    std::map<std::string, pj_stun_sock *>::iterator it;
+    it = stunSocketMap_.find(serverName);
+
+    DEBUG("***************** Destroy Stun Resolver *********************");
+
+    if (it != stunSocketMap_.end()) {
+        DEBUG("SipTransport: Deleting stun resolver %s", it->first.c_str());
+        pj_stun_sock_destroy(it->second);
+        stunSocketMap_.erase(it);
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+void SipTransport::createTlsListener(pj_uint16_t tlsListenerPort, pjsip_tls_setting *tlsSetting, pjsip_tpfactory **listener)
+{
+    pj_sockaddr_in local_addr;
+    pj_sockaddr_in_init(&local_addr, 0, 0);
+    local_addr.sin_port = pj_htons(tlsListenerPort);
+
+    if (tlsSetting == NULL) {
+        ERROR("SipTransport: Error TLS settings not specified");
+        return;
+    }
+
+    if (listener == NULL) {
+        ERROR("SipTransport: Error no pointer to store new TLS listener");
+        return;
+    }
+
+    pj_str_t pjAddress;
+    pj_cstr(&pjAddress, PJ_INADDR_ANY);
+    pj_sockaddr_in_set_str_addr(&local_addr, &pjAddress);
+    std::string localIP(getSIPLocalIP());
+
+    pjsip_host_port a_name = {
+        pj_str((char*) localIP.c_str()),
+        local_addr.sin_port
+    };
+
+    pjsip_tls_transport_start(endpt_, tlsSetting, &local_addr, &a_name, 1, listener);
+}
+
+
+pjsip_transport *
+SipTransport::createTlsTransport(const std::string &remoteAddr,
+                                pj_uint16_t tlsListenerPort,
+                                pjsip_tls_setting *tlsSettings)
+{
+    pjsip_transport *transport = NULL;
+
+    pj_str_t remote;
+    pj_cstr(&remote, remoteAddr.c_str());
+
+    pj_sockaddr_in rem_addr;
+    pj_sockaddr_in_init(&rem_addr, &remote, (pj_uint16_t) DEFAULT_SIP_TLS_PORT);
+
+    // The local tls listener
+    static pjsip_tpfactory *localTlsListener = NULL;
+
+    if (localTlsListener == NULL)
+        createTlsListener(tlsListenerPort, tlsSettings, &localTlsListener);
+
+    pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr,
+                                  sizeof rem_addr, NULL, &transport);
+
+    if (transport == NULL)
+        ERROR("SipTransport: Could not create new TLS transport\n");
+
+    return transport;
+}
+
+void SipTransport::createSipTransport(SIPAccount *account)
+{
+    if (account == NULL) {
+        ERROR("SipTransport: Account is NULL while creating sip transport");
+        return;
+    }
+
+    shutdownSipTransport(account);
+
+    if (account->isTlsEnabled()) {
+        std::string remoteSipUri(account->getServerUri());
+        static const char SIPS_PREFIX[] = "<sips:";
+        size_t sips = remoteSipUri.find(SIPS_PREFIX) + (sizeof SIPS_PREFIX) - 1;
+        size_t trns = remoteSipUri.find(";transport");
+        std::string remoteAddr(remoteSipUri.substr(sips, trns-sips));
+
+        pjsip_transport *transport = createTlsTransport(remoteAddr, account->getTlsListenerPort(), account->getTlsSetting());
+        account->transport_ = transport;
+    } else if (account->isStunEnabled()) {
+        pjsip_transport *transport = createStunTransport(account->getStunServerName(), account->getStunPort());
+        account->transport_ = transport;
+    }
+    else {
+        pjsip_transport *transport = createUdpTransport(account->getLocalInterface(), account->getLocalPort());
+        account->transport_ = transport;
+    }
+
+    if (!account->transport_) {
+        // Could not create new transport, this transport may already exists
+        account->transport_ = transportMap_[account->getLocalPort()];
+
+        if (account->transport_)
+            pjsip_transport_add_ref(account->transport_);
+        else {
+            account->transport_ = localUDPTransport_;
+            account->setLocalPort(localUDPTransport_->local_name.port);
+        }
+    }
+}
+
+void SipTransport::createDefaultSipUdpTransport()
+{
+    pj_uint16_t port = 0;
+    int counter = 0;
+
+    DEBUG("SipTransport: Create default sip udp transport");
+
+    SIPAccount *account = Manager::instance().getIP2IPAccount();
+
+    pjsip_transport *transport = NULL;
+    static const int DEFAULT_TRANSPORT_ATTEMPTS = 5;
+    for (; transport == NULL and counter < DEFAULT_TRANSPORT_ATTEMPTS; ++counter) {
+        // if default udp transport fails to init on 5060, try other ports
+        // with 2 step size increment (i.e. 5062, 5064, ...)
+        port = account->getLocalPort() + (counter * 2);
+        transport = createUdpTransport(account->getLocalInterface(), port);
+    }
+
+    if (transport == NULL) {
+        ERROR("SipTransport: Create UDP transport");
+        return;
+    }
+
+    DEBUG("SipTransport: Created default sip transport on %d", port);
+
+    // set transport for this account
+    account->transport_ = transport;
+
+    // set local udp transport
+    localUDPTransport_ = account->transport_;
+}
+
+
+pjsip_transport *SipTransport::createUdpTransport(std::string interface, unsigned int port)
+{
+    // init socket to bind this transport to
+    pj_sockaddr_in bound_addr;
+    pj_bzero(&bound_addr, sizeof(bound_addr));
+    pj_uint16_t listeningPort = (pj_uint16_t) port;
+    bound_addr.sin_port = pj_htons(listeningPort);
+    bound_addr.sin_family = PJ_AF_INET;
+
+    DEBUG("SipTransport: Create UDP transport on %s:%d", interface.c_str(), port);
+
+    // determine the ip address for this transport
+    static const char * const DEFAULT_INTERFACE = "default";
+    std::string listeningAddress;
+    if (interface == DEFAULT_INTERFACE) {
+        listeningAddress = getSIPLocalIP();
+        bound_addr.sin_addr.s_addr = pj_htonl(PJ_INADDR_ANY);
+    } else {
+        listeningAddress = getInterfaceAddrFromName(interface);
+        bound_addr.sin_addr = pj_inet_addr2(listeningAddress.c_str());
+    }
+
+    if (listeningAddress.empty()) {
+        ERROR("SipTransport: Could not determine ip address for this transport");
+        return NULL;
+    }
+
+    if (listeningPort == 0) {
+        ERROR("SipTransport: Could not determine port for this transport");
+        return NULL;
+    }
+
+    DEBUG("SipTransport: Listening address %s, listening port %d", listeningAddress.c_str(), listeningPort);
+    // The published address for this transport
+    const pjsip_host_port a_name = {
+        pj_str((char*) listeningAddress.c_str()),
+        listeningPort
+    };
+
+    pjsip_transport *transport = NULL;
+    pj_status_t status = pjsip_udp_transport_start(endpt_, &bound_addr, &a_name, 1, &transport);
+    if (status != PJ_SUCCESS) {
+        ERROR("SipTransport: Could not create UDP transport for port %u", port);
+        return NULL;
+    }
+
+    // dump debug information to stdout
+    pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
+    transportMap_[listeningPort] = transport;
+
+    return transport;
+}
+
+pjsip_tpselector *SipTransport::initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const
+{
+    assert(transport);
+    pjsip_tpselector *tp = (pjsip_tpselector *) pj_pool_zalloc(tp_pool, sizeof(pjsip_tpselector));
+    tp->type = PJSIP_TPSELECTOR_TRANSPORT;
+    tp->u.transport = transport;
+    return tp;
+}
+
+pjsip_transport *SipTransport::createStunTransport(pj_str_t serverName, pj_uint16_t port)
+{
+    pjsip_transport *transport;
+
+    DEBUG("SipTransport: Create stun transport  server name: %s, port: %d", serverName, port);// account->getStunPort());
+    if (createStunResolver(serverName, port) != PJ_SUCCESS) {
+        ERROR("SipTransport: Can't resolve STUN server");
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure("");
+        return NULL;
+    }
+
+    pj_sock_t sock = PJ_INVALID_SOCKET;
+
+    pj_sockaddr_in boundAddr;
+
+    if (pj_sockaddr_in_init(&boundAddr, &serverName, 0) != PJ_SUCCESS) {
+        ERROR("SipTransport: Can't initialize IPv4 socket on %*s:%i", serverName.slen, serverName.ptr, port);
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure("");
+        return NULL;
+    }
+
+    if (pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock) != PJ_SUCCESS) {
+        ERROR("SipTransport: Can't create or bind socket");
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure("");
+        return NULL;
+    }
+
+    // Query the mapped IP address and port on the 'outside' of the NAT
+    pj_sockaddr_in pub_addr;
+
+    if (pjstun_get_mapped_addr(&cp_->factory, 1, &sock, &serverName, port, &serverName, port, &pub_addr) != PJ_SUCCESS) {
+        ERROR("SipTransport: Can't contact STUN server");
+        pj_sock_close(sock);
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure("");
+        return NULL;
+    }
+
+    pjsip_host_port a_name = {
+        pj_str(pj_inet_ntoa(pub_addr.sin_addr)),
+        pj_ntohs(pub_addr.sin_port)
+    };
+
+    pjsip_udp_transport_attach2(endpt_, PJSIP_TRANSPORT_UDP, sock, &a_name, 1,
+                                &transport);
+
+    pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
+
+    return transport;
+}
+
+void SipTransport::shutdownSipTransport(SIPAccount *account)
+{
+    if (account->isStunEnabled()) {
+        pj_str_t stunServerName = account->getStunServerName();
+        std::string server(stunServerName.ptr, stunServerName.slen);
+        destroyStunResolver(server);
+    }
+
+    if (account->transport_) {
+        pjsip_transport_dec_ref(account->transport_);
+        account->transport_ = NULL;
+    }
+}
+
+void SipTransport::findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &addr, std::string &port) const
+{
+    // Initialize the sip port with the default SIP port
+    std::stringstream ss;
+    ss << DEFAULT_SIP_PORT;
+    port = ss.str();
+
+    // Initialize the sip address with the hostname
+    const pj_str_t *pjMachineName = pj_gethostname();
+    addr = std::string(pjMachineName->ptr, pjMachineName->slen);
+
+    // Update address and port with active transport
+    if (!transport) {
+        ERROR("SipTransport: Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
+        return;
+    }
+
+    // get the transport manager associated with the SIP enpoint
+    pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt_);
+    if (!tpmgr) {
+        ERROR("SipTransport: Transport manager is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
+        return;
+    }
+
+    // initialize a transport selector
+    // TODO Need to determine why we exclude TLS here...
+    // if (transportType == PJSIP_TRANSPORT_UDP and transport_)
+    pjsip_tpselector *tp_sel = initTransportSelector(transport, pool_);
+    if (!tp_sel) {
+        ERROR("SipTransport: Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str());
+        return;
+    }
+
+    pj_str_t localAddress = {0,0};
+    int i_port = 0;
+
+    // Find the local address and port for this transport
+    if (pjsip_tpmgr_find_local_addr(tpmgr, pool_, transportType, tp_sel, &localAddress, &i_port) != PJ_SUCCESS) {
+        WARN("SipTransport: Could not retrieve local address and port from transport, using %s:%s", addr.c_str(), port.c_str());
+        return;
+    }
+
+    // Update local address based on the transport type
+    addr = std::string(localAddress.ptr, localAddress.slen);
+
+    // Fallback on local ip provided by pj_gethostip()
+    if (addr == "0.0.0.0")
+        addr = getSIPLocalIP();
+
+    // Determine the local port based on transport information
+    ss.str("");
+    ss << i_port;
+    port = ss.str();
+}
diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h
new file mode 100644
index 0000000000000000000000000000000000000000..d5893fe2a585214d91348e0077bb6a94e5722cb1
--- /dev/null
+++ b/daemon/src/sip/siptransport.h
@@ -0,0 +1,198 @@
+/*
+ *  Copyright (C) [2004, 2012] Savoir-Faire Linux Inc.
+ *
+ *  Author: Alexandre Savard <alexandre.savard@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.
+ */
+
+#ifndef SIPTRANSPORT_H_
+#define SIPTRANSPORT_H_
+
+#include <string>
+
+#include <pjsip.h>
+#include <pjlib.h>
+#include <pjsip_ua.h>
+#include <pjlib-util.h>
+#include <pjnath.h>
+#include <pjnath/stun_config.h>
+
+#include "sipaccount.h"
+
+class SipTransport {
+    public:
+        SipTransport(pjsip_endpoint *endpt, pj_caching_pool *cp, pj_pool_t *pool);
+
+        ~SipTransport();
+
+        static std::string getSIPLocalIP(void);
+
+        /**
+        * List all the interfaces on the system and return
+        * a vector list containing their name (eth0, eth0:1 ...).
+        * @param void
+        * @return std::vector<std::string> A std::string vector
+        * of interface name available on all of the interfaces on
+        * the system.
+        */
+        static std::vector<std::string> getAllIpInterfaceByName(void);
+
+        /**
+         * List all the interfaces on the system and return
+         * a vector list containing their name (eth0, eth0:1 ...).
+         * @param void
+         * @return std::vector<std::string> A std::string vector
+         * of interface name available on all of the interfaces on
+         * the system.
+         */
+        static std::string getInterfaceAddrFromName(const std::string &ifaceName);
+
+        /**
+         * List all the interfaces on the system and return
+         * a vector list containing their IPV4 address.
+         * @param void
+         * @return std::vector<std::string> A std::string vector
+         * of IPV4 address available on all of the interfaces on
+         * the system.
+         */
+        static std::vector<std::string> getAllIpInterface();
+
+        void setEndpoint(pjsip_endpoint *endpt) {
+            endpt_ = endpt;
+        }
+
+        void setCachingPool(pj_caching_pool *cp) {
+            cp_ = cp;
+        }
+
+        void setPool(pj_pool_t *pool) {
+            pool_ = pool;
+        }
+
+        /**
+         * Create a new stun resolver. Store it inside the array. Resolve public address for this
+         * server name.
+         * @param serverName The name of the stun server
+         * @param port number
+         */
+        pj_status_t createStunResolver(pj_str_t serverName, pj_uint16_t port);
+
+        pj_status_t destroyStunResolver(const std::string serverName);
+
+        /**
+         * General Sip transport creation method according to the
+         * transport type specified in account settings
+         * @param account The account for which a transport must be created.
+         */
+        void createSipTransport(SIPAccount *account);
+
+        void createDefaultSipUdpTransport(void);
+
+        /**
+        * Create SIP UDP transport from account's setting
+        * @param account The account for which a transport must be created.
+        */
+        pjsip_transport *createUdpTransport(std::string interface, unsigned int port);
+
+        /**
+         * Initialize the transport selector
+         * @param transport		A transport associated with an account
+         *
+         * @return          	A pointer to the transport selector structure
+         */
+        pjsip_tpselector *initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const;
+
+        /**
+         * Create The default TLS listener which is global to the application. This means that
+         * only one TLS connection can be established for the momment.
+         * @param the port number to create the TCP socket
+         * @param pjsip's tls settings for the transport to be created which contains:
+         *      - path to ca certificate list file
+         *      - path to certertificate file
+         *      - path to private key file
+         *      - the password for the file
+         *      - the TLS method
+         * @param a pointer to store the listener created, in our case this is a static pointer
+         */
+        void createTlsListener(pj_uint16_t, pjsip_tls_setting *, pjsip_tpfactory **);
+
+        /**
+         * Create a connection oriented TLS transport and register to the specified remote address.
+         * First, initialize the TLS listener sole instance. This means that, for the momment, only one TLS transport
+         * is allowed to be created in the application. Any subsequent account attempting to
+         * register a new using this transport even if new settings are specified.
+         * @param the remote address for this transport to be connected
+         * @param the local port to initialize the TCP socket
+         * @param pjsip's tls transport parameters
+         */
+        pjsip_transport *
+        createTlsTransport(const std::string &remoteAddr,
+                           pj_uint16_t tlsListenerPort,
+                           pjsip_tls_setting *tlsSetting);
+
+        /**
+         * Create a UDP transport using stun server to resove public address
+         * @param account The account for which a transport must be created.
+         */
+        pjsip_transport *createStunTransport(pj_str_t serverName, pj_uint16_t port);
+
+        /**
+         * This function unset the transport for a given account.
+         */
+        void shutdownSipTransport(SIPAccount *account);
+
+        /**
+         * Get the correct address to use (ie advertised) from
+         * a uri. The corresponding transport that should be used
+         * with that uri will be discovered.
+         *
+         * @param uri The uri from which we want to discover the address to use
+         * @param transport The transport to use to discover the address
+         */
+        void findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &address, std::string &port) const;
+
+    private:
+
+        /**
+         * UDP Transports are stored in this map in order to retreive them in case
+         * several accounts would share the same port number.
+         */
+        std::map<pj_uint16_t, pjsip_transport*> transportMap_;
+
+        /**
+         * Stun resolver array
+         */
+        std::map<std::string, pj_stun_sock *> stunSocketMap_;
+
+        pj_caching_pool *cp_;
+
+        pj_pool_t *pool_;
+
+        pjsip_endpoint *endpt_;
+};
+
+#endif // SIPTRANSPORT_H_