diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index 43d2191965c01984eab7fa1acaf95116973f3722..1a55a5e4b88ed8a6fee4397c21e39aeb26f8e2b6 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -276,10 +276,6 @@ void SIPCall::answer()
         throw std::runtime_error("Could not send invite request answer (200 OK)");
     }
 
-    if (iceTransport_->isStarted())
-        waitForIceNegotiation(DEFAULT_ICE_NEGO_TIMEOUT);
-    startAllMedia();
-
     setConnectionState(CONNECTED);
     setState(ACTIVE);
 }
@@ -665,9 +661,6 @@ void
 SIPCall::onAnswered()
 {
     if (getConnectionState() != Call::CONNECTED) {
-        if (iceTransport_->isStarted())
-            waitForIceNegotiation(DEFAULT_ICE_NEGO_TIMEOUT);
-        startAllMedia();
         setConnectionState(Call::CONNECTED);
         setState(Call::ACTIVE);
         Manager::instance().peerAnsweredCall(*this);
@@ -818,16 +811,28 @@ SIPCall::stopAllMedia()
 void
 SIPCall::onMediaUpdate()
 {
+    stopAllMedia();
     openPortsUPnP();
 
-    // Handle possible ICE transport
-    if (!startIce())
-        RING_WARN("ICE not started");
-
-    if (getState() == ACTIVE) {
-        // TODO apply changes without restarting everything
-        RING_WARN("Restarting medias");
-        stopAllMedia();
+    if (startIce()) {
+        auto this_ = std::static_pointer_cast<SIPCall>(shared_from_this());
+        auto iceTimeout = std::chrono::steady_clock::now() + std::chrono::seconds {10};
+        Manager::instance().addTask([=] {
+            /* First step: wait for an ICE transport for SIP channel */
+            if (this_->iceTransport_->isFailed() or std::chrono::steady_clock::now() >= iceTimeout) {
+                RING_DBG("ice init failed (or timeout)");
+                this_->setConnectionState(Call::DISCONNECTED);
+                Manager::instance().callFailure(*this_); // signal client
+                this_->removeCall();
+                return false;
+            }
+            if (not this_->iceTransport_->isRunning())
+                return true;
+            startAllMedia();
+            return false;
+        });
+    } else {
+        RING_WARN("Starting medias without ICE");
         startAllMedia();
     }
 }