From f895de09375d2b57d6187fdcfbf319718d548eb6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Fri, 26 Aug 2022 13:24:11 -0400
Subject: [PATCH] jamiaccount: do not stop all subcall if one fails

+ In jamiaccount, if a requestSIPConnection was failing, all subcalls
were stopped causing the main call to fail if not connected. In this
patch we only stop the subcall linked to that request.
+ In connectionmanager, if a request failed, we stopped all other
connections instead of just using the id of the request.

This fix calls whenever somebody called a contact right after the
contact changed its connectivity (and the keep-alive is not sent).

Change-Id: I0d9b14795aad37363de992cb29d4d4ca44668285
---
 src/jamidht/connectionmanager.cpp | 10 +++++-----
 src/jamidht/jamiaccount.cpp       | 16 ++++++++++------
 src/jamidht/jamiaccount.h         |  8 +++++---
 src/sip/sipcall.h                 | 17 +++++++++--------
 4 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/src/jamidht/connectionmanager.cpp b/src/jamidht/connectionmanager.cpp
index 79c0447396..a9dcd74ca5 100644
--- a/src/jamidht/connectionmanager.cpp
+++ b/src/jamidht/connectionmanager.cpp
@@ -502,18 +502,18 @@ ConnectionManager::Impl::connectDevice(const std::shared_ptr<dht::crypto::Certif
         }
         if (noNewSocket) {
             // If no new socket is specified, we don't try to generate a new socket
-            for (const auto& pending : sthis->extractPendingCallbacks(deviceId))
+            for (const auto& pending : sthis->extractPendingCallbacks(deviceId, vid))
                 pending.cb(nullptr, deviceId);
             return;
         }
 
         // Note: used when the ice negotiation fails to erase
         // all stored structures.
-        auto eraseInfo = [w, cbId, deviceId] {
+        auto eraseInfo = [w, cbId] {
             if (auto shared = w.lock()) {
                 // If no new socket is specified, we don't try to generate a new socket
-                for (const auto& pending : shared->extractPendingCallbacks(deviceId))
-                    pending.cb(nullptr, deviceId);
+                for (const auto& pending : shared->extractPendingCallbacks(cbId.first, cbId.second))
+                    pending.cb(nullptr, cbId.first);
                 std::lock_guard<std::mutex> lk(shared->infosMtx_);
                 shared->infos_.erase(cbId);
             }
@@ -904,7 +904,7 @@ ConnectionManager::Impl::onDhtPeerRequest(const PeerConnectionRequest& req,
         auto eraseInfo = [w, id = req.id, deviceId] {
             if (auto shared = w.lock()) {
                 // If no new socket is specified, we don't try to generate a new socket
-                for (const auto& pending : shared->extractPendingCallbacks(deviceId))
+                for (const auto& pending : shared->extractPendingCallbacks(deviceId, id))
                     pending.cb(nullptr, deviceId);
                 if (shared->connReadyCb_)
                     shared->connReadyCb_(deviceId, "", nullptr);
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index 5b9a64c03b..f253b08d72 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -569,14 +569,14 @@ JamiAccount::startOutgoingCall(const std::shared_ptr<SIPCall>& call, const std::
             dev_call->setIceMedia(call->getIceMedia());
             {
                 std::lock_guard<std::mutex> lk(pendingCallsMutex_);
-                pendingCalls_[deviceId].emplace_back(std::move(dev_call));
+                pendingCalls_[deviceId].emplace_back(dev_call);
             }
 
             JAMI_WARN("[call %s] No channeled socket with this peer. Send request",
                       call->getCallId().c_str());
             // Else, ask for a channel (for future calls/text messages)
             auto type = call->hasVideo() ? "videoCall" : "audioCall";
-            requestSIPConnection(toUri, deviceId, type, true);
+            requestSIPConnection(toUri, deviceId, type, true, dev_call);
         };
 
     std::vector<std::shared_ptr<ChannelSocket>> channels;
@@ -2944,7 +2944,8 @@ JamiAccount::setMessageDisplayed(const std::string& conversationUri,
     std::string conversationId = {};
     if (uri.scheme() == Uri::Scheme::SWARM)
         conversationId = uri.authority();
-    auto sendMessage = status == (int) DRing::Account::MessageStates::DISPLAYED && isReadReceiptEnabled();
+    auto sendMessage = status == (int) DRing::Account::MessageStates::DISPLAYED
+                       && isReadReceiptEnabled();
     if (!conversationId.empty())
         sendMessage &= convModule()->onMessageDisplayed(getUsername(), conversationId, messageId);
     if (sendMessage)
@@ -3873,7 +3874,8 @@ void
 JamiAccount::requestSIPConnection(const std::string& peerId,
                                   const DeviceId& deviceId,
                                   const std::string& connectionType,
-                                  bool forceNewConnection)
+                                  bool forceNewConnection,
+                                  const std::shared_ptr<SIPCall>& pc)
 {
     JAMI_DBG("[Account %s] Request SIP connection to peer %s on device %s",
              getAccountID().c_str(),
@@ -3909,7 +3911,8 @@ JamiAccount::requestSIPConnection(const std::string& peerId,
     connectionManager_->connectDevice(
         deviceId,
         "sip",
-        [w = weak(), id](std::shared_ptr<ChannelSocket> socket, const DeviceId&) {
+        [w = weak(), id, pc = std::move(pc)](std::shared_ptr<ChannelSocket> socket,
+                                             const DeviceId&) {
             if (socket)
                 return;
             auto shared = w.lock();
@@ -3919,7 +3922,8 @@ JamiAccount::requestSIPConnection(const std::string& peerId,
             // connectDevice didn't get any response from the DHT.
             // Stop searching pending call.
             shared->callConnectionClosed(id.second, true);
-            shared->forEachPendingCall(id.second, [](const auto& pc) { pc->onFailure(); });
+            if (pc)
+                pc->onFailure();
         },
         false,
         forceNewConnection,
diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h
index f9eb1f832a..555350beca 100644
--- a/src/jamidht/jamiaccount.h
+++ b/src/jamidht/jamiaccount.h
@@ -871,15 +871,17 @@ private:
 
     /**
      * Ask a device to open a channeled SIP socket
-     * @param peerId        The contact who owns the device
-     * @param deviceId      The device to ask
+     * @param peerId             The contact who owns the device
+     * @param deviceId           The device to ask
      * @param forceNewConnection If we want a new SIP connection
+     * @param pc                 A pending call to stop if the request fails
      * @note triggers cacheSIPConnection
      */
     void requestSIPConnection(const std::string& peerId,
                               const DeviceId& deviceId,
                               const std::string& connectionType,
-                              bool forceNewConnection = false);
+                              bool forceNewConnection = false,
+                              const std::shared_ptr<SIPCall>& pc = {});
     /**
      * Store a new SIP connection into sipConnections_
      * @param channel   The new sip channel
diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h
index dc7b74d559..a281c35ac8 100644
--- a/src/sip/sipcall.h
+++ b/src/sip/sipcall.h
@@ -315,6 +315,15 @@ public:
 
     std::unique_ptr<pjsip_inv_session, InvSessionDeleter> inviteSession_;
 
+    inline std::weak_ptr<const SIPCall> weak() const
+    {
+        return std::weak_ptr<const SIPCall>(shared());
+    }
+    inline std::weak_ptr<SIPCall> weak()
+    {
+        return std::weak_ptr<SIPCall>(shared());
+    }
+
 private:
     void generateMediaPorts();
 
@@ -430,14 +439,6 @@ private:
     {
         return std::static_pointer_cast<SIPCall>(shared_from_this());
     }
-    inline std::weak_ptr<const SIPCall> weak() const
-    {
-        return std::weak_ptr<const SIPCall>(shared());
-    }
-    inline std::weak_ptr<SIPCall> weak()
-    {
-        return std::weak_ptr<SIPCall>(shared());
-    }
 
     // Peer's User-Agent.
     std::string peerUserAgent_ {};
-- 
GitLab