diff --git a/bin/dbus/cx.ring.Ring.CallManager.xml b/bin/dbus/cx.ring.Ring.CallManager.xml
index 2e59bcfa04fc1ca5af64e0926425ead7a46ab4bb..0ae9e74ed4996664b6da3a1da1964c6f53c9cfac 100644
--- a/bin/dbus/cx.ring.Ring.CallManager.xml
+++ b/bin/dbus/cx.ring.Ring.CallManager.xml
@@ -856,7 +856,7 @@
         <signal name="secureSdesOff" tp:name-for-bindings="secureSdesOff">
             <tp:added version="0.9.7"/>
             <tp:docstring>
-              <p>Sinal sent to notify that SDES session failed.</p>
+              <p>Signal sent to notify that SDES session failed.</p>
               <p>Media transmission is not encrypted.</p>
             </tp:docstring>
             <arg type="s" name="callID" />
@@ -919,5 +919,15 @@
             <arg type="s" name="peerNumber" />
             <arg type="b" name="remoteRecordingState" />
         </signal>
+
+        <signal name="mediaNegotiationStatus" tp:name-for-bindings="mediaNegotiationStatus">
+            <tp:added version="9.10.0"/>
+            <tp:docstring>
+              <p>Report mediation negotation status.</p>
+            </tp:docstring>
+            <arg type="s" name="callID" />
+            <arg type="s" name="event" />
+        </signal>
+
     </interface>
 </node>
diff --git a/bin/dbus/dbusclient.cpp b/bin/dbus/dbusclient.cpp
index 8d7c9f4173b8ca75e7f3bcbaa9a334fa72ce93c4..5771092feb6be72ae8f56f1923825c344514da3e 100644
--- a/bin/dbus/dbusclient.cpp
+++ b/bin/dbus/dbusclient.cpp
@@ -148,39 +148,58 @@ DBusClient::initLibrary(int flags)
     auto confM = configurationManager_.get();
     auto presM = presenceManager_.get();
 
-#ifdef ENABLE_PLUGIN
-    auto plugM = pluginManagerInterface_.get();
-#endif
 #ifdef ENABLE_VIDEO
     using DRing::VideoSignal;
     auto videoM = videoManager_.get();
 #endif
 
     // Call event handlers
-    const std::map<std::string, SharedCallback> callEvHandlers = {
-        exportable_callback<CallSignal::StateChange>(bind(&DBusCallManager::callStateChanged, callM, _1, _2, _3)),
-        exportable_callback<CallSignal::TransferFailed>(bind(&DBusCallManager::transferFailed, callM)),
-        exportable_callback<CallSignal::TransferSucceeded>(bind(&DBusCallManager::transferSucceeded, callM)),
-        exportable_callback<CallSignal::RecordPlaybackStopped>(bind(&DBusCallManager::recordPlaybackStopped, callM, _1)),
-        exportable_callback<CallSignal::VoiceMailNotify>(bind(&DBusCallManager::voiceMailNotify, callM, _1, _2, _3, _4)),
-        exportable_callback<CallSignal::IncomingMessage>(bind(&DBusCallManager::incomingMessage, callM, _1, _2, _3)),
-        exportable_callback<CallSignal::IncomingCall>(bind(&DBusCallManager::incomingCall, callM, _1, _2, _3)),
-        exportable_callback<CallSignal::RecordPlaybackFilepath>(bind(&DBusCallManager::recordPlaybackFilepath, callM, _1, _2)),
-        exportable_callback<CallSignal::ConferenceCreated>(bind(&DBusCallManager::conferenceCreated, callM, _1)),
-        exportable_callback<CallSignal::ConferenceChanged>(bind(&DBusCallManager::conferenceChanged, callM, _1, _2)),
-        exportable_callback<CallSignal::UpdatePlaybackScale>(bind(&DBusCallManager::updatePlaybackScale, callM, _1, _2, _3)),
-        exportable_callback<CallSignal::ConferenceRemoved>(bind(&DBusCallManager::conferenceRemoved, callM, _1)),
-        exportable_callback<CallSignal::RecordingStateChanged>(bind(&DBusCallManager::recordingStateChanged, callM, _1, _2)),
-        exportable_callback<CallSignal::SecureSdesOn>(bind(&DBusCallManager::secureSdesOn, callM, _1)),
-        exportable_callback<CallSignal::SecureSdesOff>(bind(&DBusCallManager::secureSdesOff, callM, _1)),
-        exportable_callback<CallSignal::RtcpReportReceived>(bind(&DBusCallManager::onRtcpReportReceived, callM, _1, _2)),
-        exportable_callback<CallSignal::OnConferenceInfosUpdated>(bind(&DBusCallManager::onConferenceInfosUpdated, callM, _1, _2)),
-        exportable_callback<CallSignal::PeerHold>(bind(&DBusCallManager::peerHold, callM, _1, _2)),
-        exportable_callback<CallSignal::AudioMuted>(bind(&DBusCallManager::audioMuted, callM, _1, _2)),
-        exportable_callback<CallSignal::VideoMuted>(bind(&DBusCallManager::videoMuted, callM, _1, _2)),
-        exportable_callback<CallSignal::SmartInfo>(bind(&DBusCallManager::SmartInfo, callM, _1)),
-        exportable_callback<CallSignal::RemoteRecordingChanged>(bind(&DBusCallManager::remoteRecordingChanged, callM, _1, _2, _3))
-    };
+    const std::map<std::string, SharedCallback> callEvHandlers
+        = {exportable_callback<CallSignal::StateChange>(
+               bind(&DBusCallManager::callStateChanged, callM, _1, _2, _3)),
+           exportable_callback<CallSignal::TransferFailed>(
+               bind(&DBusCallManager::transferFailed, callM)),
+           exportable_callback<CallSignal::TransferSucceeded>(
+               bind(&DBusCallManager::transferSucceeded, callM)),
+           exportable_callback<CallSignal::RecordPlaybackStopped>(
+               bind(&DBusCallManager::recordPlaybackStopped, callM, _1)),
+           exportable_callback<CallSignal::VoiceMailNotify>(
+               bind(&DBusCallManager::voiceMailNotify, callM, _1, _2, _3, _4)),
+           exportable_callback<CallSignal::IncomingMessage>(
+               bind(&DBusCallManager::incomingMessage, callM, _1, _2, _3)),
+           exportable_callback<CallSignal::IncomingCall>(
+               bind(&DBusCallManager::incomingCall, callM, _1, _2, _3)),
+           exportable_callback<CallSignal::RecordPlaybackFilepath>(
+               bind(&DBusCallManager::recordPlaybackFilepath, callM, _1, _2)),
+           exportable_callback<CallSignal::ConferenceCreated>(
+               bind(&DBusCallManager::conferenceCreated, callM, _1)),
+           exportable_callback<CallSignal::ConferenceChanged>(
+               bind(&DBusCallManager::conferenceChanged, callM, _1, _2)),
+           exportable_callback<CallSignal::UpdatePlaybackScale>(
+               bind(&DBusCallManager::updatePlaybackScale, callM, _1, _2, _3)),
+           exportable_callback<CallSignal::ConferenceRemoved>(
+               bind(&DBusCallManager::conferenceRemoved, callM, _1)),
+           exportable_callback<CallSignal::RecordingStateChanged>(
+               bind(&DBusCallManager::recordingStateChanged, callM, _1, _2)),
+           exportable_callback<CallSignal::SecureSdesOn>(
+               bind(&DBusCallManager::secureSdesOn, callM, _1)),
+           exportable_callback<CallSignal::SecureSdesOff>(
+               bind(&DBusCallManager::secureSdesOff, callM, _1)),
+           exportable_callback<CallSignal::RtcpReportReceived>(
+               bind(&DBusCallManager::onRtcpReportReceived, callM, _1, _2)),
+           exportable_callback<CallSignal::OnConferenceInfosUpdated>(
+               bind(&DBusCallManager::onConferenceInfosUpdated, callM, _1, _2)),
+           exportable_callback<CallSignal::PeerHold>(
+               bind(&DBusCallManager::peerHold, callM, _1, _2)),
+           exportable_callback<CallSignal::AudioMuted>(
+               bind(&DBusCallManager::audioMuted, callM, _1, _2)),
+           exportable_callback<CallSignal::VideoMuted>(
+               bind(&DBusCallManager::videoMuted, callM, _1, _2)),
+           exportable_callback<CallSignal::SmartInfo>(bind(&DBusCallManager::SmartInfo, callM, _1)),
+           exportable_callback<CallSignal::RemoteRecordingChanged>(
+               bind(&DBusCallManager::remoteRecordingChanged, callM, _1, _2, _3)),
+           exportable_callback<CallSignal::MediaNegotiationStatus>(
+               bind(&DBusCallManager::mediaNegotiationStatus, callM, _1, _2))};
 
     // Configuration event handlers
     const std::map<std::string, SharedCallback> configEvHandlers = {
diff --git a/bin/jni/callmanager.i b/bin/jni/callmanager.i
index a9fc887cd841750628ec849913c4ca66b3a627d7..745dcaad85abd90dffc59dc14c5702978c75b2ec 100644
--- a/bin/jni/callmanager.i
+++ b/bin/jni/callmanager.i
@@ -49,6 +49,7 @@ public:
     virtual void peerHold(const std::string& call_id, bool holding){}
     virtual void connectionUpdate(const std::string& id, int state){}
     virtual void remoteRecordingChanged(const std::string& call_id, const std::string& peer_number, bool state){}
+    virtual void mediaNegotiationStatus(const std::string& call_id, const std::string& event){}
 };
 
 
@@ -144,5 +145,5 @@ public:
     virtual void peerHold(const std::string& call_id, bool holding){}
     virtual void connectionUpdate(const std::string& id, int state){}
     virtual void remoteRecordingChanged(const std::string& call_id, const std::string& peer_number, bool state){}
-
+    virtual void mediaNegotiationStatus(const std::string& call_id, const std::string& event){}
 };
diff --git a/bin/jni/jni_interface.i b/bin/jni/jni_interface.i
index 89ad82fae732f81db1798d9c08db04c39b1cdbb8..f846733a60b44286cc0a6161541a7a60b1d9db3a 100644
--- a/bin/jni/jni_interface.i
+++ b/bin/jni/jni_interface.i
@@ -252,7 +252,8 @@ void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM
         exportable_callback<CallSignal::OnConferenceInfosUpdated>(bind(&Callback::onConferenceInfosUpdated, callM, _1, _2)),
         exportable_callback<CallSignal::PeerHold>(bind(&Callback::peerHold, callM, _1, _2)),
         exportable_callback<CallSignal::ConnectionUpdate>(bind(&Callback::connectionUpdate, callM, _1, _2)),
-        exportable_callback<CallSignal::RemoteRecordingChanged>(bind(&Callback::remoteRecordingChanged, callM, _1, _2, _3))
+        exportable_callback<CallSignal::RemoteRecordingChanged>(bind(&Callback::remoteRecordingChanged, callM, _1, _2, _3)),
+        exportable_callback<CallSignal::MediaNegotiationStatus>(bind(&Callback::mediaNegotiationStatus, callM, _1, _2))
     };
 
     // Configuration event handlers
diff --git a/src/client/ring_signal.cpp b/src/client/ring_signal.cpp
index 79a1d86cb5442fda7cd57de688ac0248e1288962..a6e8a949669cd24e550079844c4ad40f1de7fdb0 100644
--- a/src/client/ring_signal.cpp
+++ b/src/client/ring_signal.cpp
@@ -50,6 +50,7 @@ getSignalHandlers()
         exported_callback<DRing::CallSignal::ConnectionUpdate>(),
         exported_callback<DRing::CallSignal::OnConferenceInfosUpdated>(),
         exported_callback<DRing::CallSignal::RemoteRecordingChanged>(),
+        exported_callback<DRing::CallSignal::MediaNegotiationStatus>(),
 
         /* Configuration */
         exported_callback<DRing::ConfigurationSignal::VolumeChanged>(),
diff --git a/src/dring/callmanager_interface.h b/src/dring/callmanager_interface.h
index 239c2e6a136415332cfcad9b01eac4574407eed8..f68d94b2dbea4a578644b2f6efa9dbecdb17e52f 100644
--- a/src/dring/callmanager_interface.h
+++ b/src/dring/callmanager_interface.h
@@ -245,6 +245,12 @@ struct DRING_PUBLIC CallSignal
         constexpr static const char* name = "RemoteRecordingChanged";
         using cb_type = void(const std::string&, const std::string&, bool);
     };
+    // Report media negotiation status
+    struct DRING_PUBLIC MediaNegotiationStatus
+    {
+        constexpr static const char* name = "MediaNegotiationStatus";
+        using cb_type = void(const std::string&, const std::string&);
+    };
 };
 
 } // namespace DRing
diff --git a/src/media/media_attribute.h b/src/media/media_attribute.h
index 234b47f5b3043d75725e3f86dd890765889439e6..a6262a6ceb97083b50ce994b400a5b14d2a1816b 100644
--- a/src/media/media_attribute.h
+++ b/src/media/media_attribute.h
@@ -98,4 +98,9 @@ constexpr static auto AUDIO = "MEDIA_TYPE_AUDIO";
 constexpr static auto VIDEO = "MEDIA_TYPE_VIDEO";
 } // namespace MediaAttributeValue
 
+namespace MediaNegotiationStatusEvents {
+constexpr static auto NEGOTIATION_SUCCESS = "NEGOTIATION_SUCCESS";
+constexpr static auto NEGOTIATION_FAIL = "NEGOTIATION_FAIL";
+} // namespace MediaNegotiationStatusEvents
+
 } // namespace jami
diff --git a/src/media/media_codec.h b/src/media/media_codec.h
index e193d611170b64ac695d82ebd327ccf8839f9e5a..57f678224fe5982438b367afb73518cbdb138f40 100644
--- a/src/media/media_codec.h
+++ b/src/media/media_codec.h
@@ -300,5 +300,4 @@ struct MediaDescription
     /** Crypto parameters */
     CryptoAttribute crypto {};
 };
-
 } // namespace jami