diff --git a/bin/dbus/cx.ring.Ring.CallManager.xml b/bin/dbus/cx.ring.Ring.CallManager.xml
index 5835a672aa2b86b161ff2da801eaa1571ef7f224..3a8de89028a2020a185656247e2c5bb74ef43a09 100644
--- a/bin/dbus/cx.ring.Ring.CallManager.xml
+++ b/bin/dbus/cx.ring.Ring.CallManager.xml
@@ -242,6 +242,16 @@
             <arg type="b" name="addSucceeded" direction="out"/>
         </method>
 
+        <method name="detachLocalParticipant" tp:name-for-bindings="detachLocalParticipant">
+            <tp:added version="3.0.0"/>
+            <tp:docstring>
+                Detach local participant from the conference.
+                Remote participants are placed in hold.
+                The signal <tp:member-ref>conferenceChanged</tp:member-ref> is emited.
+            </tp:docstring>
+            <arg type="b" name="detachSucceeded" direction="out"/>
+        </method>
+
         <method name="detachParticipant" tp:name-for-bindings="detachParticipant">
             <tp:added version="0.9.7"/>
             <tp:docstring>
diff --git a/bin/dbus/dbuscallmanager.cpp b/bin/dbus/dbuscallmanager.cpp
index 94bfd42d11e1d70b72b97532b35c3713e8939565..ba13e13fd99f55d3adf3250d6387ea3cab26e58c 100644
--- a/bin/dbus/dbuscallmanager.cpp
+++ b/bin/dbus/dbuscallmanager.cpp
@@ -128,6 +128,12 @@ DBusCallManager::addMainParticipant(const std::string& confID) -> decltype(DRing
     return DRing::addMainParticipant(confID);
 }
 
+auto
+DBusCallManager::detachLocalParticipant() -> decltype(DRing::detachLocalParticipant())
+{
+    return DRing::detachLocalParticipant();
+}
+
 auto
 DBusCallManager::detachParticipant(const std::string& callID) -> decltype(DRing::detachParticipant(callID))
 {
diff --git a/bin/dbus/dbuscallmanager.h b/bin/dbus/dbuscallmanager.h
index 387e2a8df9cb4a9f274f0768912814ae48d9dafd..db70c044c65c665c6647187b93281d76055b6763 100644
--- a/bin/dbus/dbuscallmanager.h
+++ b/bin/dbus/dbuscallmanager.h
@@ -71,6 +71,7 @@ class DBusCallManager :
         bool isConferenceParticipant(const std::string& call_id);
         bool addParticipant(const std::string& callID, const std::string& confID);
         bool addMainParticipant(const std::string& confID);
+        bool detachLocalParticipant();
         bool detachParticipant(const std::string& callID);
         bool joinConference(const std::string& sel_confID, const std::string& drag_confID);
         bool hangUpConference(const std::string& confID);
diff --git a/src/client/callmanager.cpp b/src/client/callmanager.cpp
index 9d807863da991ea0516c50c43a3e8dc816d9f4c6..b0d43b82a32c89e003ce7bb3781ce36dc1e806bb 100644
--- a/src/client/callmanager.cpp
+++ b/src/client/callmanager.cpp
@@ -168,6 +168,12 @@ addMainParticipant(const std::string& confID)
     return ring::Manager::instance().addMainParticipant(confID);
 }
 
+bool
+detachLocalParticipant()
+{
+    return ring::Manager::instance().detachLocalParticipant();
+}
+
 bool
 detachParticipant(const std::string& callID)
 {
diff --git a/src/dring/callmanager_interface.h b/src/dring/callmanager_interface.h
index fa578a68c521ac47727cd59f0a3d819773acfd94..2b6a54999708d819ca6d26e819270d00ec3e31cc 100644
--- a/src/dring/callmanager_interface.h
+++ b/src/dring/callmanager_interface.h
@@ -56,6 +56,7 @@ void createConfFromParticipantList(const std::vector<std::string>& participants)
 bool isConferenceParticipant(const std::string& call_id);
 bool addParticipant(const std::string& callID, const std::string& confID);
 bool addMainParticipant(const std::string& confID);
+bool detachLocalParticipant();
 bool detachParticipant(const std::string& callID);
 bool joinConference(const std::string& sel_confID, const std::string& drag_confID);
 bool hangUpConference(const std::string& confID);
diff --git a/src/manager.cpp b/src/manager.cpp
index e3f91c25f43b9645bdb0ed0cff09d6b9587f4067..5fb44feb9898f7363cf23659ad79410e3b01e81e 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -509,7 +509,7 @@ Manager::outgoingCall(const std::string& preferred_account_id,
         if (not isConference(current_call_id) and not isConferenceParticipant(current_call_id))
             onHoldCall(current_call_id);
         else if (isConference(current_call_id) and not isConferenceParticipant(call_id))
-            detachParticipant(RingBufferPool::DEFAULT_ID);
+            detachLocalParticipant();
     }
 
     switchCall(call);
@@ -547,7 +547,7 @@ Manager::answerCall(const std::string& call_id)
         } else if (isConference(current_call_id) and not isConferenceParticipant(call_id)) {
             // if we are talking to a conference and we are answering an incoming call
             RING_DBG("Detach main participant from conference");
-            detachParticipant(RingBufferPool::DEFAULT_ID);
+            detachLocalParticipant();
         }
     }
 
@@ -706,7 +706,7 @@ Manager::offHoldCall(const std::string& callId)
             onHoldCall(currentCallId);
         } else if (isConference(currentCallId) and not isConferenceParticipant(callId)) {
             holdConference(currentCallId);
-            detachParticipant(RingBufferPool::DEFAULT_ID);
+            detachLocalParticipant();
         }
     }
 
@@ -971,7 +971,7 @@ Manager::addParticipant(const std::string& callId,
     // detach from prior communication and switch to this conference
     if (current_call_id != callId) {
         if (isConference(current_call_id))
-            detachParticipant(RingBufferPool::DEFAULT_ID);
+            detachLocalParticipant();
         else
             onHoldCall(current_call_id);
     }
@@ -1022,7 +1022,7 @@ Manager::addMainParticipant(const std::string& conference_id)
         std::string current_call_id(getCurrentCallId());
 
         if (isConference(current_call_id))
-            detachParticipant(RingBufferPool::DEFAULT_ID);
+            detachLocalParticipant();
         else
             onHoldCall(current_call_id);
     }
@@ -1127,7 +1127,7 @@ Manager::joinParticipant(const std::string& callId1, const std::string& callId2)
     auto current_call_id = getCurrentCallId();
     if ((current_call_id != callId1) and (current_call_id != callId2)) {
         if (isConference(current_call_id))
-            detachParticipant(RingBufferPool::DEFAULT_ID);
+            detachLocalParticipant();
         else
             onHoldCall(current_call_id); // currently in a call
     }
@@ -1191,67 +1191,63 @@ Manager::createConfFromParticipantList(const std::vector< std::string > &partici
 }
 
 bool
-Manager::detachParticipant(const std::string& call_id)
+Manager::detachLocalParticipant()
 {
-    const std::string current_call_id(getCurrentCallId());
-
-    if (call_id != RingBufferPool::DEFAULT_ID) {
-        auto call = getCallFromCallID(call_id);
-        if (!call) {
-            RING_ERR("Could not find call %s", call_id.c_str());
-            return false;
-        }
-
-        auto conf = getConferenceFromCallID(call_id);
-
-        if (conf == nullptr) {
-            RING_ERR("Call is not conferencing, cannot detach");
-            return false;
-        }
-
-        std::map<std::string, std::string> call_details(getCallDetails(call_id));
-        std::map<std::string, std::string>::iterator iter_details(call_details.find("CALL_STATE"));
-
-        if (iter_details == call_details.end()) {
-            RING_ERR("Could not find CALL_STATE");
-            return false;
-        }
-
-        // Don't hold ringing calls when detaching them from conferences
-        if (iter_details->second != "RINGING")
-            onHoldCall(call_id);
-
-        removeParticipant(call_id);
-
-    } else {
-        RING_DBG("Unbind main participant from conference");
-        getRingBufferPool().unBindAll(RingBufferPool::DEFAULT_ID);
+    RING_DBG("Unbind local participant from conference");
+    const auto& current_call_id = getCurrentCallId();
 
-        if (not isConference(current_call_id)) {
-            RING_ERR("Current call id (%s) is not a conference", current_call_id.c_str());
-            return false;
-        }
+    if (not isConference(current_call_id)) {
+        RING_ERR("Current call id (%s) is not a conference", current_call_id.c_str());
+        return false;
+    }
 
-        ConferenceMap::iterator iter = conferenceMap_.find(current_call_id);
+    auto iter = conferenceMap_.find(current_call_id);
+    if (iter == conferenceMap_.end() or iter->second == nullptr) {
+        RING_ERR("Conference is NULL");
+        return false;
+    }
 
-        auto conf = iter->second;
-        if (iter == conferenceMap_.end() or conf == 0) {
-            RING_DBG("Conference is NULL");
-            return false;
-        }
+    getRingBufferPool().unBindAll(RingBufferPool::DEFAULT_ID);
 
-        if (conf->getState() == Conference::ACTIVE_ATTACHED)
+    auto conf = iter->second;
+    switch (conf->getState()) {
+        case Conference::ACTIVE_ATTACHED:
             conf->setState(Conference::ACTIVE_DETACHED);
-        else if (conf->getState() == Conference::ACTIVE_ATTACHED_REC)
+            break;
+        case Conference::ACTIVE_ATTACHED_REC:
             conf->setState(Conference::ACTIVE_DETACHED_REC);
-        else
+            break;
+        default:
             RING_WARN("Undefined behavior, invalid conference state in detach participant");
+    }
 
-        emitSignal<DRing::CallSignal::ConferenceChanged>(conf->getConfID(), conf->getStateStr());
+    emitSignal<DRing::CallSignal::ConferenceChanged>(conf->getConfID(), conf->getStateStr());
 
-        unsetCurrentCall();
+    unsetCurrentCall();
+}
+
+bool
+Manager::detachParticipant(const std::string& call_id)
+{
+    RING_DBG("Detach participant %s", call_id.c_str());
+
+    auto call = getCallFromCallID(call_id);
+    if (!call) {
+        RING_ERR("Could not find call %s", call_id.c_str());
+        return false;
+    }
+
+    auto conf = getConferenceFromCallID(call_id);
+    if (!conf) {
+        RING_ERR("Call is not conferencing, cannot detach");
+        return false;
     }
 
+    // Don't hold ringing calls when detaching them from conferences
+    if (call->getStateStr() != "RINGING")
+        onHoldCall(call_id);
+
+    removeParticipant(call_id);
     return true;
 }
 
diff --git a/src/manager.h b/src/manager.h
index ef4a36d2602047221d8625d52cc8c05e7e0d1dce..88f24910841c0ef5730985ee2057fcff8683f7c2 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -308,6 +308,12 @@ class Manager {
          */
         bool detachParticipant(const std::string& call_id);
 
+        /**
+         * Detach the local participant from curent conference.
+         * Remote participants are placed in hold.
+         */
+        bool detachLocalParticipant();
+
         /**
          * Remove the conference participant from a conference
          * @param call id