add upnp/natpmp support

Change-Id: I4945a7df3a30cb39d81a33fc7a32e9fea600bdff
diff --git a/src/upnp/protocol/natpmp/nat_pmp.cpp b/src/upnp/protocol/natpmp/nat_pmp.cpp
index 599205e..2f48713 100644
--- a/src/upnp/protocol/natpmp/nat_pmp.cpp
+++ b/src/upnp/protocol/natpmp/nat_pmp.cpp
@@ -21,11 +21,11 @@
 namespace dhtnet {
 namespace upnp {
 
-NatPmp::NatPmp()
+NatPmp::NatPmp(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger)
+ : UPnPProtocol(logger), ioContext(ctx), searchForIgdTimer_(*ctx)
 {
     // JAMI_DBG("NAT-PMP: Instance [%p] created", this);
-    runOnNatPmpQueue([this] {
-        threadId_ = getCurrentThread();
+    ioContext->dispatch([this] {
         igd_ = std::make_shared<PMPIGD>();
     });
 }
@@ -38,15 +38,6 @@
 void
 NatPmp::initNatPmp()
 {
-    if (not isValidThread()) {
-        runOnNatPmpQueue([w = weak()] {
-            if (auto pmpThis = w.lock()) {
-                pmpThis->initNatPmp();
-            }
-        });
-        return;
-    }
-
     initialized_ = false;
 
     {
@@ -82,8 +73,7 @@
             err = NATPMP_ERR_CANNOTGETGATEWAY;
         } else {
             // JAMI_WARN("NAT-PMP: Trying to initialize using detected gateway %s",
-                      localGw.toString().c_str());
-
+            //          localGw.toString().c_str());
             struct in_addr inaddr;
             inet_pton(AF_INET, localGw.toString().c_str(), &inaddr);
             err = initnatpmp(&natpmpHdl_, 1, inaddr.s_addr);
@@ -119,17 +109,6 @@
 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;
 }
 
@@ -152,10 +131,8 @@
     std::unique_lock<std::mutex> lk(natpmpMutex_);
     std::condition_variable cv {};
 
-    runOnNatPmpQueue([w = weak(), &cv = cv] {
-        if (auto pmpThis = w.lock()) {
-            pmpThis->terminate(cv);
-        }
+    ioContext->dispatch([&] {
+        terminate(cv);
     });
 
     if (cv.wait_for(lk, std::chrono::seconds(10), [this] { return shutdownComplete_; })) {
@@ -175,15 +152,6 @@
 void
 NatPmp::clearIgds()
 {
-    if (not isValidThread()) {
-        runOnNatPmpQueue([w = weak()] {
-            if (auto pmpThis = w.lock()) {
-                pmpThis->clearIgds();
-            }
-        });
-        return;
-    }
-
     bool do_close = false;
 
     if (igd_) {
@@ -194,8 +162,7 @@
     }
 
     initialized_ = false;
-    if (searchForIgdTimer_)
-        searchForIgdTimer_->cancel();
+    searchForIgdTimer_.cancel();
 
     igdSearchCounter_ = 0;
 
@@ -208,15 +175,6 @@
 void
 NatPmp::searchForIgd()
 {
-    if (not isValidThread()) {
-        runOnNatPmpQueue([w = weak()] {
-            if (auto pmpThis = w.lock()) {
-                pmpThis->searchForIgd();
-            }
-        });
-        return;
-    }
-
     if (not initialized_) {
         initNatPmp();
     }
@@ -227,12 +185,11 @@
             // 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_);
+            searchForIgdTimer_.expires_after(NATPMP_SEARCH_RETRY_UNIT * igdSearchCounter_);
+            searchForIgdTimer_.async_wait([this](const asio::error_code& ec) {
+                if (!ec)
+                    searchForIgd();
+            });
         } else {
             // JAMI_WARN("NAT-PMP: Setup failed after %u trials. NAT-PMP will be disabled!",
             //           MAX_RESTART_SEARCH_RETRIES);
@@ -291,14 +248,14 @@
 NatPmp::requestMappingAdd(const Mapping& mapping)
 {
     // Process on nat-pmp thread.
-    if (not isValidThread()) {
-        runOnNatPmpQueue([w = weak(), mapping] {
+    /*if (not isValidThread()) {
+        ioContext->post([w = weak(), mapping] {
             if (auto pmpThis = w.lock()) {
                 pmpThis->requestMappingAdd(mapping);
             }
         });
         return;
-    }
+    }*/
 
     Mapping map(mapping);
     assert(map.getIgd());
@@ -329,14 +286,14 @@
 NatPmp::requestMappingRenew(const Mapping& mapping)
 {
     // Process on nat-pmp thread.
-    if (not isValidThread()) {
-        runOnNatPmpQueue([w = weak(), mapping] {
+    /*if (not isValidThread()) {
+        ioContext->post([w = weak(), mapping] {
             if (auto pmpThis = w.lock()) {
                 pmpThis->requestMappingRenew(mapping);
             }
         });
         return;
-    }
+    }*/
 
     Mapping map(mapping);
     auto err = addPortMapping(map);
@@ -401,7 +358,7 @@
 int
 NatPmp::sendMappingRequest(const Mapping& mapping, uint32_t& lifetime)
 {
-    CHECK_VALID_THREAD();
+    //CHECK_VALID_THREAD();
 
     int err = sendnewportmappingrequest(&natpmpHdl_,
                                         mapping.getType() == PortType::UDP ? NATPMP_PROTOCOL_UDP
@@ -478,16 +435,12 @@
 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;
-    }
+    ioContext->dispatch([w = weak(), mapping] {
+        if (auto pmpThis = w.lock()) {
+            Mapping map {mapping};
+            pmpThis->removePortMapping(map);
+        }
+    });
 }
 
 void
@@ -522,7 +475,7 @@
 void
 NatPmp::getIgdPublicAddress()
 {
-    CHECK_VALID_THREAD();
+    //CHECK_VALID_THREAD();
 
     // Set the public address for this IGD if it does not
     // have one already.
@@ -585,7 +538,7 @@
 void
 NatPmp::removeAllMappings()
 {
-    CHECK_VALID_THREAD();
+    //CHECK_VALID_THREAD();
 
     // JAMI_WARN("NAT-PMP: Send request to close all existing mappings to IGD %s",
     //           igd_->toString().c_str());
@@ -721,7 +674,7 @@
     if (observer_ == nullptr)
         return;
     // Process the response on the context thread.
-    runOnUpnpContextQueue([obs = observer_, igd = igd_, event] { obs->onIgdUpdated(igd, event); });
+    ioContext->post([obs = observer_, igd = igd_, event] { obs->onIgdUpdated(igd, event); });
 }
 
 void
@@ -731,7 +684,7 @@
         return;
 
     // Process the response on the context thread.
-    runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingAdded(igd, map); });
+    ioContext->post([obs = observer_, igd = igd_, map] { obs->onMappingAdded(igd, map); });
 }
 
 void
@@ -741,7 +694,7 @@
         return;
 
     // Process the response on the context thread.
-    runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRequestFailed(map); });
+    ioContext->post([obs = observer_, igd = igd_, map] { obs->onMappingRequestFailed(map); });
 }
 
 void
@@ -751,7 +704,7 @@
         return;
 
     // Process the response on the context thread.
-    runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRenewed(igd, map); });
+    ioContext->post([obs = observer_, igd = igd_, map] { obs->onMappingRenewed(igd, map); });
 }
 
 void
@@ -761,7 +714,7 @@
         return;
 
     // Process the response on the context thread.
-    runOnUpnpContextQueue([obs = observer_, igd = igd_, map] { obs->onMappingRemoved(igd, map); });
+    ioContext->post([obs = observer_, igd = igd_, map] { obs->onMappingRemoved(igd, map); });
 }
 
 } // namespace upnp
diff --git a/src/upnp/protocol/natpmp/nat_pmp.h b/src/upnp/protocol/natpmp/nat_pmp.h
index 30642a0..fbc2fc0 100644
--- a/src/upnp/protocol/natpmp/nat_pmp.h
+++ b/src/upnp/protocol/natpmp/nat_pmp.h
@@ -16,14 +16,10 @@
  */
 #pragma once
 
-#include "connectivity/upnp/protocol/upnp_protocol.h"
-#include "connectivity/upnp/protocol/igd.h"
+#include "../upnp_protocol.h"
+#include "../igd.h"
 #include "pmp_igd.h"
-
-#include "logger.h"
-#include "connectivity/ip_utils.h"
-#include "noncopyable.h"
-#include "compiler_intrinsics.h"
+#include "ip_utils.h"
 
 // uncomment to enable native natpmp error messages
 //#define ENABLE_STRNATPMPERR 1
@@ -53,7 +49,7 @@
 class NatPmp : public UPnPProtocol
 {
 public:
-    NatPmp();
+    NatPmp(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger);
     ~NatPmp();
 
     // Set the observer.
@@ -94,21 +90,11 @@
     void terminate() override;
 
 private:
-    NON_COPYABLE(NatPmp);
+    NatPmp& operator=(const NatPmp&) = delete;
+    NatPmp(const NatPmp&) = delete;
 
     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();
@@ -147,8 +133,8 @@
     // Data members
     std::shared_ptr<PMPIGD> igd_;
     natpmp_t natpmpHdl_;
-    ScheduledExecutor natpmpScheduler_ {"natpmp"};
-    std::shared_ptr<Task> searchForIgdTimer_ {};
+    std::shared_ptr<asio::io_context> ioContext;
+    asio::steady_timer searchForIgdTimer_;
     unsigned int igdSearchCounter_ {0};
     UpnpMappingObserver* observer_ {nullptr};
     IpAddr hostAddress_ {};
diff --git a/src/upnp/protocol/natpmp/pmp_igd.h b/src/upnp/protocol/natpmp/pmp_igd.h
index df1c44b..1ca7fe7 100644
--- a/src/upnp/protocol/natpmp/pmp_igd.h
+++ b/src/upnp/protocol/natpmp/pmp_igd.h
@@ -17,8 +17,7 @@
 #pragma once
 
 #include "../igd.h"
-#include "noncopyable.h"
-#include "connectivity/ip_utils.h"
+#include "ip_utils.h"
 
 #include <map>
 #include <atomic>