diff --git a/src/upnp/protocol/natpmp/nat_pmp.cpp b/src/upnp/protocol/natpmp/nat_pmp.cpp
new file mode 100644
index 0000000..21f11ee
--- /dev/null
+++ b/src/upnp/protocol/natpmp/nat_pmp.cpp
@@ -0,0 +1,775 @@
+/*
+ *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
+ *
+ *  Author: Eden Abitbol <eden.abitbol@savoirfairelinux.com>
+ *  Author: Mohamed Chibani <mohamed.chibani@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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include "nat_pmp.h"
+
+#if HAVE_LIBNATPMP
+
+namespace jami {
+namespace upnp {
+
+NatPmp::NatPmp()
+{
+    JAMI_DBG("NAT-PMP: Instance [%p] created", this);
+    runOnNatPmpQueue([this] {
+        threadId_ = getCurrentThread();
+        igd_ = std::make_shared<PMPIGD>();
+    });
+}
+
+NatPmp::~NatPmp()
+{
+    JAMI_DBG("NAT-PMP: Instance [%p] destroyed", this);
+}
+
+void
+NatPmp::initNatPmp()
+{
+    if (not isValidThread()) {
+        runOnNatPmpQueue([w = weak()] {
+            if (auto pmpThis = w.lock()) {
+                pmpThis->initNatPmp();
+            }
+        });
+        return;
+    }
+
+    initialized_ = false;
+
+    {
+        std::lock_guard<std::mutex> lock(natpmpMutex_);
+        hostAddress_ = ip_utils::getLocalAddr(AF_INET);
+    }
+
+    // Local address must be valid.
+    if (not getHostAddress() or getHostAddress().isLoopback()) {
+        JAMI_WARN("NAT-PMP: Does not have a valid local address!");
+        return;
+    }
+
+    assert(igd_);
+    if (igd_->isValid()) {
+        igd_->setValid(false);
+        processIgdUpdate(UpnpIgdEvent::REMOVED);
+    }
+
+    igd_->setLocalIp(IpAddr());
+    igd_->setPublicIp(IpAddr());
+    igd_->setUID("");
+
+    JAMI_DBG("NAT-PMP: Trying to initialize IGD");
+
+    int err = initnatpmp(&natpmpHdl_, 0, 0);
+
+    if (err < 0) {
+        JAMI_WARN("NAT-PMP: Initializing IGD using default gateway failed!");
+        const auto& localGw = ip_utils::getLocalGateway();
+        if (not localGw) {
+            JAMI_WARN("NAT-PMP: Couldn't find valid gateway on local host");
+            err = NATPMP_ERR_CANNOTGETGATEWAY;
+        } else {
+            JAMI_WARN("NAT-PMP: Trying to initialize using detected gateway %s",
+                      localGw.toString().c_str());
+
+            struct in_addr inaddr;
+            inet_pton(AF_INET, localGw.toString().c_str(), &inaddr);
+            err = initnatpmp(&natpmpHdl_, 1, inaddr.s_addr);
+        }
+    }
+
+    if (err < 0) {
+        JAMI_ERR("NAT-PMP: Can't initialize libnatpmp -> %s", getNatPmpErrorStr(err));
+        return;
+    }
+
+    char addrbuf[INET_ADDRSTRLEN];
+    inet_ntop(AF_INET, &natpmpHdl_.gateway, addrbuf, sizeof(addrbuf));
+    IpAddr igdAddr(addrbuf);
+    JAMI_DBG("NAT-PMP: Initialized on gateway %s", igdAddr.toString().c_str());
+
+    // Set the local (gateway) address.
+    igd_->setLocalIp(igdAddr);
+    // NAT-PMP protocol does not have UID, but we will set generic
+    // one debugging purposes.
+    igd_->setUID("NAT-PMP Gateway");
+
+    // Search and set the public address.
+    getIgdPublicAddress();
+
+    // Update and notify.
+    if (igd_->isValid()) {
+        initialized_ = true;
+        processIgdUpdate(UpnpIgdEvent::ADDED);
+    };
+}
+
+void
+NatPmp::setObserver(UpnpMappingObserver* obs)
+{
+    if (not isValidThread()) {
+        runOnNatPmpQueue([w = weak(), obs] {
+            if (auto pmpThis = w.lock()) {
+                pmpThis->setObserver(obs);
+            }
+        });
+        return;
+    }
+
+    JAMI_DBG("NAT-PMP: Setting observer to %p", obs);
+
+    observer_ = obs;
+}
+
+void
+NatPmp::terminate(std::condition_variable& cv)
+{
+    initialized_ = false;
+    observer_ = nullptr;
+
+    {
+        std::lock_guard<std::mutex> lock(natpmpMutex_);
+        shutdownComplete_ = true;
+        cv.notify_one();
+    }
+}
+
+void
+NatPmp::terminate()
+{
+    std::unique_lock<std::mutex> lk(natpmpMutex_);
+    std::condition_variable cv {};
+
+    runOnNatPmpQueue([w = weak(), &cv = cv] {
+        if (auto pmpThis = w.lock()) {
+            pmpThis->terminate(cv);
+        }
+    });
+
+    if (cv.wait_for(lk, std::chrono::seconds(10), [this] { return shutdownComplete_; })) {
+        JAMI_DBG("NAT-PMP: Shutdown completed");
+    } else {
+        JAMI_ERR("NAT-PMP: Shutdown timed-out");
+    }
+}
+
+const IpAddr
+NatPmp::getHostAddress() const
+{
+    std::lock_guard<std::mutex> lock(natpmpMutex_);
+    return hostAddress_;
+}
+
+void
+NatPmp::clearIgds()
+{
+    if (not isValidThread()) {
+        runOnNatPmpQueue([w = weak()] {
+            if (auto pmpThis = w.lock()) {
+                pmpThis->clearIgds();
+            }
+        });
+        return;
+    }
+
+    bool do_close = false;
+
+    if (igd_) {
+        if (igd_->isValid()) {
+            do_close = true;
+        }
+        igd_->setValid(false);
+    }
+
+    initialized_ = false;
+    if (searchForIgdTimer_)
+        searchForIgdTimer_->cancel();
+
+    igdSearchCounter_ = 0;
+
+    if (do_close) {
+        closenatpmp(&natpmpHdl_);
+        memset(&natpmpHdl_, 0, sizeof(natpmpHdl_));
+    }
+}
+
+void
+NatPmp::searchForIgd()
+{
+    if (not isValidThread()) {
+        runOnNatPmpQueue([w = weak()] {
+            if (auto pmpThis = w.lock()) {
+                pmpThis->searchForIgd();
+            }
+        });
+        return;
+    }
+
+    if (not initialized_) {
+        initNatPmp();
+    }
+
+    // Schedule a retry in case init failed.
+    if (not initialized_) {
+        if (igdSearchCounter_++ < MAX_RESTART_SEARCH_RETRIES) {
+            JAMI_DBG("NAT-PMP: Start search for IGDs. Attempt %i", igdSearchCounter_);
+
+            // Cancel the current timer (if any) and re-schedule.
+            if (searchForIgdTimer_)
+                searchForIgdTimer_->cancel();
+
+            searchForIgdTimer_ = getNatpmpScheduler()->scheduleIn([this] { searchForIgd(); },
+                                                                  NATPMP_SEARCH_RETRY_UNIT
+                                                                      * igdSearchCounter_);
+        } else {
+            JAMI_WARN("NAT-PMP: Setup failed after %u trials. NAT-PMP will be disabled!",
+                      MAX_RESTART_SEARCH_RETRIES);
+        }
+    }
+}
+
+std::list<std::shared_ptr<IGD>>
+NatPmp::getIgdList() const
+{
+    std::lock_guard<std::mutex> lock(natpmpMutex_);
+    std::list<std::shared_ptr<IGD>> igdList;
+    if (igd_->isValid())
+        igdList.emplace_back(igd_);
+    return igdList;
+}
+
+bool
+NatPmp::isReady() const
+{
+    if (observer_ == nullptr) {
+        JAMI_ERR("NAT-PMP: the observer is not set!");
+        return false;
+    }
+
+    // Must at least have a valid local address.
+    if (not getHostAddress() or getHostAddress().isLoopback())
+        return false;
+
+    return igd_ and igd_->isValid();
+}
+
+void
+NatPmp::incrementErrorsCounter(const std::shared_ptr<IGD>& igdIn)
+{
+    if (not validIgdInstance(igdIn)) {
+        return;
+    }
+
+    if (not igd_->isValid()) {
+        // Already invalid. Nothing to do.
+        return;
+    }
+
+    if (not igd_->incrementErrorsCounter()) {
+        // Disable this IGD.
+        igd_->setValid(false);
+        // Notify the listener.
+        JAMI_WARN("NAT-PMP: No more valid IGD!");
+
+        processIgdUpdate(UpnpIgdEvent::INVALID_STATE);
+    }
+}
+
+void
+NatPmp::requestMappingAdd(const Mapping& mapping)
+{
+    // Process on nat-pmp thread.
+    if (not isValidThread()) {
+        runOnNatPmpQueue([w = weak(), mapping] {
+            if (auto pmpThis = w.lock()) {
+                pmpThis->requestMappingAdd(mapping);
+            }
+        });
+        return;
+    }
+
+    Mapping map(mapping);
+    assert(map.getIgd());
+    auto err = addPortMapping(map);
+    if (err < 0) {
+        JAMI_WARN("NAT-PMP: Request for mapping %s on %s failed with error %i: %s",
+                  map.toString().c_str(),
+                  igd_->toString().c_str(),
+                  err,
+                  getNatPmpErrorStr(err));
+
+        if (isErrorFatal(err)) {
+            // Fatal error, increment the counter.
+            incrementErrorsCounter(igd_);
+        }
+        // Notify the listener.
+        processMappingRequestFailed(std::move(map));
+    } else {
+        JAMI_DBG("NAT-PMP: Request for mapping %s on %s succeeded",
+                 map.toString().c_str(),
+                 igd_->toString().c_str());
+        // Notify the listener.
+        processMappingAdded(std::move(map));
+    }
+}
+
+void
+NatPmp::requestMappingRenew(const Mapping& mapping)
+{
+    // Process on nat-pmp thread.
+    if (not isValidThread()) {
+        runOnNatPmpQueue([w = weak(), mapping] {
+            if (auto pmpThis = w.lock()) {
+                pmpThis->requestMappingRenew(mapping);
+            }
+        });
+        return;
+    }
+
+    Mapping map(mapping);
+    auto err = addPortMapping(map);
+    if (err < 0) {
+        JAMI_WARN("NAT-PMP: Renewal request for mapping %s on %s failed with error %i: %s",
+                  map.toString().c_str(),
+                  igd_->toString().c_str(),
+                  err,
+                  getNatPmpErrorStr(err));
+        // Notify the listener.
+        processMappingRequestFailed(std::move(map));
+
+        if (isErrorFatal(err)) {
+            // Fatal error, increment the counter.
+            incrementErrorsCounter(igd_);
+        }
+    } else {
+        JAMI_DBG("NAT-PMP: Renewal request for mapping %s on %s succeeded",
+                 map.toString().c_str(),
+                 igd_->toString().c_str());
+        // Notify the listener.
+        processMappingRenewed(map);
+    }
+}
+
+int
+NatPmp::readResponse(natpmp_t& handle, natpmpresp_t& response)
+{
+    int err = 0;
+    unsigned readRetriesCounter = 0;
+
+    while (true) {
+        if (readRetriesCounter++ > MAX_READ_RETRIES) {
+            err = NATPMP_ERR_SOCKETERROR;
+            break;
+        }
+
+        fd_set fds;
+        struct timeval timeout;
+        FD_ZERO(&fds);
+        FD_SET(handle.s, &fds);
+        getnatpmprequesttimeout(&handle, &timeout);
+        // Wait for data.
+        if (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == -1) {
+            err = NATPMP_ERR_SOCKETERROR;
+            break;
+        }
+
+        // Read the data.
+        err = readnatpmpresponseorretry(&handle, &response);
+
+        if (err == NATPMP_TRYAGAIN) {
+            std::this_thread::sleep_for(std::chrono::milliseconds(TIMEOUT_BEFORE_READ_RETRY));
+        } else {
+            break;
+        }
+    }
+
+    return err;
+}
+
+int
+NatPmp::sendMappingRequest(const Mapping& mapping, uint32_t& lifetime)
+{
+    CHECK_VALID_THREAD();
+
+    int err = sendnewportmappingrequest(&natpmpHdl_,
+                                        mapping.getType() == PortType::UDP ? NATPMP_PROTOCOL_UDP
+                                                                           : NATPMP_PROTOCOL_TCP,
+                                        mapping.getInternalPort(),
+                                        mapping.getExternalPort(),
+                                        lifetime);
+
+    if (err < 0) {
+        JAMI_ERR("NAT-PMP: Send mapping request failed with error %s %i",
+                 getNatPmpErrorStr(err),
+                 errno);
+        return err;
+    }
+
+    unsigned readRetriesCounter = 0;
+
+    while (readRetriesCounter++ < MAX_READ_RETRIES) {
+        // Read the response
+        natpmpresp_t response;
+        err = readResponse(natpmpHdl_, response);
+
+        if (err < 0) {
+            JAMI_WARN("NAT-PMP: Read response on IGD %s failed with error %s",
+                      igd_->toString().c_str(),
+                      getNatPmpErrorStr(err));
+        } else if (response.type != NATPMP_RESPTYPE_TCPPORTMAPPING
+                   and response.type != NATPMP_RESPTYPE_UDPPORTMAPPING) {
+            JAMI_ERR("NAT-PMP: Unexpected response type (%i) for mapping %s from IGD %s.",
+                     response.type,
+                     mapping.toString().c_str(),
+                     igd_->toString().c_str());
+            // Try to read again.
+            continue;
+        }
+
+        lifetime = response.pnu.newportmapping.lifetime;
+        // Done.
+        break;
+    }
+
+    return err;
+}
+
+int
+NatPmp::addPortMapping(Mapping& mapping)
+{
+    auto const& igdIn = mapping.getIgd();
+    assert(igdIn);
+    assert(igdIn->getProtocol() == NatProtocolType::NAT_PMP);
+
+    if (not igdIn->isValid() or not validIgdInstance(igdIn)) {
+        mapping.setState(MappingState::FAILED);
+        return NATPMP_ERR_INVALIDARGS;
+    }
+
+    mapping.setInternalAddress(getHostAddress().toString());
+
+    uint32_t lifetime = MAPPING_ALLOCATION_LIFETIME;
+    int err = sendMappingRequest(mapping, lifetime);
+
+    if (err < 0) {
+        mapping.setState(MappingState::FAILED);
+        return err;
+    }
+
+    // Set the renewal time and update.
+    mapping.setRenewalTime(sys_clock::now() + std::chrono::seconds(lifetime * 4 / 5));
+    mapping.setState(MappingState::OPEN);
+
+    return 0;
+}
+
+void
+NatPmp::requestMappingRemove(const Mapping& mapping)
+{
+    // Process on nat-pmp thread.
+    if (not isValidThread()) {
+        runOnNatPmpQueue([w = weak(), mapping] {
+            if (auto pmpThis = w.lock()) {
+                Mapping map {mapping};
+                pmpThis->removePortMapping(map);
+            }
+        });
+        return;
+    }
+}
+
+void
+NatPmp::removePortMapping(Mapping& mapping)
+{
+    auto igdIn = mapping.getIgd();
+    assert(igdIn);
+    if (not igdIn->isValid()) {
+        return;
+    }
+
+    if (not validIgdInstance(igdIn)) {
+        return;
+    }
+
+    Mapping mapToRemove(mapping);
+
+    uint32_t lifetime = 0;
+    int err = sendMappingRequest(mapping, lifetime);
+
+    if (err < 0) {
+        // Nothing to do if the request fails, just log the error.
+        JAMI_WARN("NAT-PMP: Send remove request failed with error %s. Ignoring",
+                  getNatPmpErrorStr(err));
+    }
+
+    // Update and notify the listener.
+    mapToRemove.setState(MappingState::FAILED);
+    processMappingRemoved(std::move(mapToRemove));
+}
+
+void
+NatPmp::getIgdPublicAddress()
+{
+    CHECK_VALID_THREAD();
+
+    // Set the public address for this IGD if it does not
+    // have one already.
+    if (igd_->getPublicIp()) {
+        JAMI_WARN("NAT-PMP: IGD %s already have a public address (%s)",
+                  igd_->toString().c_str(),
+                  igd_->getPublicIp().toString().c_str());
+        return;
+    }
+    assert(igd_->getProtocol() == NatProtocolType::NAT_PMP);
+
+    int err = sendpublicaddressrequest(&natpmpHdl_);
+
+    if (err < 0) {
+        JAMI_ERR("NAT-PMP: send public address request on IGD %s failed with error: %s",
+                 igd_->toString().c_str(),
+                 getNatPmpErrorStr(err));
+
+        if (isErrorFatal(err)) {
+            // Fatal error, increment the counter.
+            incrementErrorsCounter(igd_);
+        }
+        return;
+    }
+
+    natpmpresp_t response;
+    err = readResponse(natpmpHdl_, response);
+
+    if (err < 0) {
+        JAMI_WARN("NAT-PMP: Read response on IGD %s failed - %s",
+                  igd_->toString().c_str(),
+                  getNatPmpErrorStr(err));
+        return;
+    }
+
+    if (response.type != NATPMP_RESPTYPE_PUBLICADDRESS) {
+        JAMI_ERR("NAT-PMP: Unexpected response type (%i) for public address request from IGD %s.",
+                 response.type,
+                 igd_->toString().c_str());
+        return;
+    }
+
+    IpAddr publicAddr(response.pnu.publicaddress.addr);
+
+    if (not publicAddr) {
+        JAMI_ERR("NAT-PMP: IGD %s returned an invalid public address %s",
+                 igd_->toString().c_str(),
+                 publicAddr.toString().c_str());
+    }
+
+    // Update.
+    igd_->setPublicIp(publicAddr);
+    igd_->setValid(true);
+
+    JAMI_DBG("NAT-PMP: Setting IGD %s public address to %s",
+             igd_->toString().c_str(),
+             igd_->getPublicIp().toString().c_str());
+}
+
+void
+NatPmp::removeAllMappings()
+{
+    CHECK_VALID_THREAD();
+
+    JAMI_WARN("NAT-PMP: Send request to close all existing mappings to IGD %s",
+              igd_->toString().c_str());
+
+    int err = sendnewportmappingrequest(&natpmpHdl_, NATPMP_PROTOCOL_TCP, 0, 0, 0);
+    if (err < 0) {
+        JAMI_WARN("NAT-PMP: Send close all TCP mappings request failed with error %s",
+                  getNatPmpErrorStr(err));
+    }
+    err = sendnewportmappingrequest(&natpmpHdl_, NATPMP_PROTOCOL_UDP, 0, 0, 0);
+    if (err < 0) {
+        JAMI_WARN("NAT-PMP: Send close all UDP mappings request failed with error %s",
+                  getNatPmpErrorStr(err));
+    }
+}
+
+const char*
+NatPmp::getNatPmpErrorStr(int errorCode) const
+{
+#ifdef ENABLE_STRNATPMPERR
+    return strnatpmperr(errorCode);
+#else
+    switch (errorCode) {
+    case NATPMP_ERR_INVALIDARGS:
+        return "INVALIDARGS";
+        break;
+    case NATPMP_ERR_SOCKETERROR:
+        return "SOCKETERROR";
+        break;
+    case NATPMP_ERR_CANNOTGETGATEWAY:
+        return "CANNOTGETGATEWAY";
+        break;
+    case NATPMP_ERR_CLOSEERR:
+        return "CLOSEERR";
+        break;
+    case NATPMP_ERR_RECVFROM:
+        return "RECVFROM";
+        break;
+    case NATPMP_ERR_NOPENDINGREQ:
+        return "NOPENDINGREQ";
+        break;
+    case NATPMP_ERR_NOGATEWAYSUPPORT:
+        return "NOGATEWAYSUPPORT";
+        break;
+    case NATPMP_ERR_CONNECTERR:
+        return "CONNECTERR";
+        break;
+    case NATPMP_ERR_WRONGPACKETSOURCE:
+        return "WRONGPACKETSOURCE";
+        break;
+    case NATPMP_ERR_SENDERR:
+        return "SENDERR";
+        break;
+    case NATPMP_ERR_FCNTLERROR:
+        return "FCNTLERROR";
+        break;
+    case NATPMP_ERR_GETTIMEOFDAYERR:
+        return "GETTIMEOFDAYERR";
+        break;
+    case NATPMP_ERR_UNSUPPORTEDVERSION:
+        return "UNSUPPORTEDVERSION";
+        break;
+    case NATPMP_ERR_UNSUPPORTEDOPCODE:
+        return "UNSUPPORTEDOPCODE";
+        break;
+    case NATPMP_ERR_UNDEFINEDERROR:
+        return "UNDEFINEDERROR";
+        break;
+    case NATPMP_ERR_NOTAUTHORIZED:
+        return "NOTAUTHORIZED";
+        break;
+    case NATPMP_ERR_NETWORKFAILURE:
+        return "NETWORKFAILURE";
+        break;
+    case NATPMP_ERR_OUTOFRESOURCES:
+        return "OUTOFRESOURCES";
+        break;
+    case NATPMP_TRYAGAIN:
+        return "TRYAGAIN";
+        break;
+    default:
+        return "UNKNOWNERR";
+        break;
+    }
+#endif
+}
+
+bool
+NatPmp::isErrorFatal(int error)
+{
+    switch (error) {
+    case NATPMP_ERR_INVALIDARGS:
+    case NATPMP_ERR_SOCKETERROR:
+    case NATPMP_ERR_CANNOTGETGATEWAY:
+    case NATPMP_ERR_CLOSEERR:
+    case NATPMP_ERR_RECVFROM:
+    case NATPMP_ERR_NOGATEWAYSUPPORT:
+    case NATPMP_ERR_CONNECTERR:
+    case NATPMP_ERR_SENDERR:
+    case NATPMP_ERR_UNDEFINEDERROR:
+    case NATPMP_ERR_UNSUPPORTEDVERSION:
+    case NATPMP_ERR_UNSUPPORTEDOPCODE:
+    case NATPMP_ERR_NOTAUTHORIZED:
+    case NATPMP_ERR_NETWORKFAILURE:
+    case NATPMP_ERR_OUTOFRESOURCES:
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool
+NatPmp::validIgdInstance(const std::shared_ptr<IGD>& igdIn)
+{
+    if (igd_.get() != igdIn.get()) {
+        JAMI_ERR("NAT-PMP: IGD (%s) does not match local instance (%s)",
+                 igdIn->toString().c_str(),
+                 igd_->toString().c_str());
+        return false;
+    }
+
+    return true;
+}
+
+void
+NatPmp::processIgdUpdate(UpnpIgdEvent event)
+{
+    if (igd_->isValid()) {
+        // Remove all current mappings if any.
+        removeAllMappings();
+    }
+
+    if (observer_ == nullptr)
+        return;
+    // Process the response on the context thread.
+    runOnUpnpContextQueue([obs = observer_, igd = igd_, event] { obs->onIgdUpdated(igd, event); });
+}
+
+void
+NatPmp::processMappingAdded(const Mapping& map)
+{
+    if (observer_ == nullptr)
+        return;
+
+    // Process the response on the context thread.
+    runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingAdded(igd, map); });
+}
+
+void
+NatPmp::processMappingRequestFailed(const Mapping& map)
+{
+    if (observer_ == nullptr)
+        return;
+
+    // Process the response on the context thread.
+    runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRequestFailed(map); });
+}
+
+void
+NatPmp::processMappingRenewed(const Mapping& map)
+{
+    if (observer_ == nullptr)
+        return;
+
+    // Process the response on the context thread.
+    runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRenewed(igd, map); });
+}
+
+void
+NatPmp::processMappingRemoved(const Mapping& map)
+{
+    if (observer_ == nullptr)
+        return;
+
+    // Process the response on the context thread.
+    runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRemoved(igd, map); });
+}
+
+} // namespace upnp
+} // namespace jami
+
+#endif //-- #if HAVE_LIBNATPMP
diff --git a/src/upnp/protocol/natpmp/nat_pmp.h b/src/upnp/protocol/natpmp/nat_pmp.h
new file mode 100644
index 0000000..68fd28b
--- /dev/null
+++ b/src/upnp/protocol/natpmp/nat_pmp.h
@@ -0,0 +1,174 @@
+/*
+ *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
+ *
+ *  Author: Eden Abitbol <eden.abitbol@savoirfairelinux.com>
+ *  Author: Mohamed Chibani <mohamed.chibani@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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#pragma once
+
+#include "connectivity/upnp/protocol/upnp_protocol.h"
+#include "connectivity/upnp/protocol/igd.h"
+#include "pmp_igd.h"
+
+#include "logger.h"
+#include "connectivity/ip_utils.h"
+#include "noncopyable.h"
+#include "compiler_intrinsics.h"
+
+// uncomment to enable native natpmp error messages
+//#define ENABLE_STRNATPMPERR 1
+#include <natpmp.h>
+
+#include <atomic>
+#include <thread>
+
+namespace jami {
+class IpAddr;
+}
+
+namespace jami {
+namespace upnp {
+
+// Requested lifetime in seconds. The actual lifetime might be different.
+constexpr static unsigned int MAPPING_ALLOCATION_LIFETIME {60 * 60};
+// Max number of IGD search attempts before failure.
+constexpr static unsigned int MAX_RESTART_SEARCH_RETRIES {3};
+// Time-out between two successive read response.
+constexpr static auto TIMEOUT_BEFORE_READ_RETRY {std::chrono::milliseconds(300)};
+// Max number of read attempts before failure.
+constexpr static unsigned int MAX_READ_RETRIES {3};
+// Base unit for the timeout between two successive IGD search.
+constexpr static auto NATPMP_SEARCH_RETRY_UNIT {std::chrono::seconds(10)};
+
+class NatPmp : public UPnPProtocol
+{
+public:
+    NatPmp();
+    ~NatPmp();
+
+    // Set the observer.
+    void setObserver(UpnpMappingObserver* obs) override;
+
+    // Returns the protocol type.
+    NatProtocolType getProtocol() const override { return NatProtocolType::NAT_PMP; }
+
+    // Get protocol type as string.
+    char const* getProtocolName() const override { return "NAT-PMP"; }
+
+    // Notifies a change in network.
+    void clearIgds() override;
+
+    // Renew pmp_igd.
+    void searchForIgd() override;
+
+    // Get the IGD list.
+    std::list<std::shared_ptr<IGD>> getIgdList() const override;
+
+    // Return true if it has at least one valid IGD.
+    bool isReady() const override;
+
+    // Request a new mapping.
+    void requestMappingAdd(const Mapping& mapping) override;
+
+    // Renew an allocated mapping.
+    void requestMappingRenew(const Mapping& mapping) override;
+
+    // Removes a mapping.
+    void requestMappingRemove(const Mapping& mapping) override;
+
+    // Get the host (local) address.
+    const IpAddr getHostAddress() const override;
+
+    // Terminate. Nothing to do here, the clean-up is done when
+    // the IGD is cleared.
+    void terminate() override;
+
+private:
+    NON_COPYABLE(NatPmp);
+
+    std::weak_ptr<NatPmp> weak() { return std::static_pointer_cast<NatPmp>(shared_from_this()); }
+
+    // Helpers to run tasks on NAT-PMP internal execution queue.
+    ScheduledExecutor* getNatpmpScheduler() { return &natpmpScheduler_; }
+    template<typename Callback>
+    void runOnNatPmpQueue(Callback&& cb)
+    {
+        natpmpScheduler_.run([cb = std::forward<Callback>(cb)]() mutable { cb(); });
+    }
+
+    // Helpers to run tasks on UPNP context execution queue.
+    ScheduledExecutor* getUpnContextScheduler() { return UpnpThreadUtil::getScheduler(); }
+
+    void terminate(std::condition_variable& cv);
+
+    void initNatPmp();
+    void getIgdPublicAddress();
+    void removeAllMappings();
+    int readResponse(natpmp_t& handle, natpmpresp_t& response);
+    int sendMappingRequest(const Mapping& mapping, uint32_t& lifetime);
+
+    // Adds a port mapping.
+    int addPortMapping(Mapping& mapping);
+    // Removes a port mapping.
+    void removePortMapping(Mapping& mapping);
+
+    // True if the error is fatal.
+    bool isErrorFatal(int error);
+    // Gets NAT-PMP error code string.
+    const char* getNatPmpErrorStr(int errorCode) const;
+    // Get local getaway.
+    std::unique_ptr<IpAddr> getLocalGateway() const;
+
+    // Helpers to process user's callbacks
+    void processIgdUpdate(UpnpIgdEvent event);
+    void processMappingAdded(const Mapping& map);
+    void processMappingRequestFailed(const Mapping& map);
+    void processMappingRenewed(const Mapping& map);
+    void processMappingRemoved(const Mapping& map);
+
+    // Check if the IGD has a local match
+    bool validIgdInstance(const std::shared_ptr<IGD>& igdIn);
+
+    // Increment errors counter.
+    void incrementErrorsCounter(const std::shared_ptr<IGD>& igd);
+
+    std::atomic_bool initialized_ {false};
+
+    // Data members
+    std::shared_ptr<PMPIGD> igd_;
+    natpmp_t natpmpHdl_;
+    ScheduledExecutor natpmpScheduler_ {"natpmp"};
+    std::shared_ptr<Task> searchForIgdTimer_ {};
+    unsigned int igdSearchCounter_ {0};
+    UpnpMappingObserver* observer_ {nullptr};
+    IpAddr hostAddress_ {};
+
+    // Calls from other threads that does not need synchronous access are
+    // rescheduled on the NatPmp private queue. This will avoid the need to
+    // protect most of the data members of this class.
+    // For some internal members (such as the igd instance and the host
+    // address) that need to be synchronously accessed, are protected by
+    // this mutex.
+    mutable std::mutex natpmpMutex_;
+
+    // Shutdown synchronization
+    bool shutdownComplete_ {false};
+};
+
+} // namespace upnp
+} // namespace jami
diff --git a/src/upnp/protocol/natpmp/pmp_igd.cpp b/src/upnp/protocol/natpmp/pmp_igd.cpp
new file mode 100644
index 0000000..ac8b698
--- /dev/null
+++ b/src/upnp/protocol/natpmp/pmp_igd.cpp
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
+ *
+ *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
+ *  Author: Eden Abitbol <eden.abitbol@savoirfairelinux.com>
+ *  Author: Mohamed Chibani <mohamed.chibani@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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include "pmp_igd.h"
+
+#include <algorithm>
+
+namespace jami {
+namespace upnp {
+
+PMPIGD::PMPIGD()
+    : IGD(NatProtocolType::NAT_PMP)
+{}
+
+PMPIGD::PMPIGD(const PMPIGD& other)
+    : PMPIGD()
+{
+    assert(protocol_ == NatProtocolType::NAT_PMP);
+    // protocol_ = other.protocol_;
+    localIp_ = other.localIp_;
+    publicIp_ = other.publicIp_;
+    uid_ = other.uid_;
+}
+
+bool
+PMPIGD::operator==(IGD& other) const
+{
+    return getPublicIp() == other.getPublicIp() and getLocalIp() == other.getLocalIp();
+}
+
+bool
+PMPIGD::operator==(PMPIGD& other) const
+{
+    return getPublicIp() == other.getPublicIp() and getLocalIp() == other.getLocalIp();
+}
+
+const std::string
+PMPIGD::toString() const
+{
+    return getLocalIp().toString();
+}
+
+} // namespace upnp
+} // namespace jami
diff --git a/src/upnp/protocol/natpmp/pmp_igd.h b/src/upnp/protocol/natpmp/pmp_igd.h
new file mode 100644
index 0000000..a70e7ee
--- /dev/null
+++ b/src/upnp/protocol/natpmp/pmp_igd.h
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
+ *
+ *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
+ *  Author: Eden Abitbol <eden.abitbol@savoirfairelinux.com>
+ *  Author: Mohamed Chibani <mohamed.chibani@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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+#pragma once
+
+#include "../igd.h"
+#include "noncopyable.h"
+#include "connectivity/ip_utils.h"
+
+#include <map>
+#include <atomic>
+#include <string>
+#include <chrono>
+#include <functional>
+
+namespace jami {
+namespace upnp {
+
+class PMPIGD : public IGD
+{
+public:
+    PMPIGD();
+    PMPIGD(const PMPIGD&);
+    ~PMPIGD() = default;
+
+    PMPIGD& operator=(PMPIGD&& other) = delete;
+    PMPIGD& operator=(PMPIGD& other) = delete;
+
+    bool operator==(IGD& other) const;
+    bool operator==(PMPIGD& other) const;
+
+    const std::string toString() const override;
+};
+
+} // namespace upnp
+} // namespace jami
