diff --git a/bin/dbus/cx.ring.Ring.CallManager.xml b/bin/dbus/cx.ring.Ring.CallManager.xml
index c9d9f7143ab0ccb8be6aa42ecd20c84688e74e4c..93c9eaab07eb1f852202b280fe5a6a80e3eb9565 100644
--- a/bin/dbus/cx.ring.Ring.CallManager.xml
+++ b/bin/dbus/cx.ring.Ring.CallManager.xml
@@ -718,9 +718,19 @@
                 The account ID.
               </tp:docstring>
             </arg>
-            <arg type="i" name="count">
+            <arg type="i" name="newCount">
               <tp:docstring>
-                The number of waiting messages.
+                The number of new messages.
+              </tp:docstring>
+            </arg>
+            <arg type="i" name="oldCount">
+              <tp:docstring>
+                The number of old messages.
+              </tp:docstring>
+            </arg>
+            <arg type="i" name="urgentCount">
+              <tp:docstring>
+                The number of urgent messages.
               </tp:docstring>
             </arg>
         </signal>
diff --git a/bin/dbus/dbusclient.cpp b/bin/dbus/dbusclient.cpp
index b8ce3c5ac27fc723e5b38460f9ac0c44192779fe..f2cc0182f97e703f13679b60ba39861f71b38d86 100644
--- a/bin/dbus/dbusclient.cpp
+++ b/bin/dbus/dbusclient.cpp
@@ -143,7 +143,7 @@ DBusClient::initLibrary(int flags)
         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)),
+        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)),
diff --git a/bin/jni/callmanager.i b/bin/jni/callmanager.i
index 4f2955e708f475249cf1b099b067d81bb22d58ef..41202f0142c9d3fef89fded049a638b07174d9b5 100644
--- a/bin/jni/callmanager.i
+++ b/bin/jni/callmanager.i
@@ -32,7 +32,7 @@ public:
     virtual void transferFailed(void){}
     virtual void transferSucceeded(void){}
     virtual void recordPlaybackStopped(const std::string& path){}
-    virtual void voiceMailNotify(const std::string& call_id, int nd_msg){}
+    virtual void voiceMailNotify(const std::string& accountId, int newCount, int oldCount, int urgentCount){}
     virtual void incomingMessage(const std::string& id, const std::string& from, const std::map<std::string, std::string>& messages){}
     virtual void incomingCall(const std::string& account_id, const std::string& call_id, const std::string& from){}
     virtual void recordPlaybackFilepath(const std::string& id, const std::string& filename){}
@@ -118,7 +118,7 @@ public:
     virtual void transferFailed(void){}
     virtual void transferSucceeded(void){}
     virtual void recordPlaybackStopped(const std::string& path){}
-    virtual void voiceMailNotify(const std::string& call_id, int nd_msg){}
+    virtual void voiceMailNotify(const std::string& accountId, int newCount, int oldCount, int urgentCount){}
     virtual void incomingMessage(const std::string& id, const std::string& from, const std::map<std::string, std::string>& messages){}
     virtual void incomingCall(const std::string& account_id, const std::string& call_id, const std::string& from){}
     virtual void recordPlaybackFilepath(const std::string& id, const std::string& filename){}
diff --git a/bin/jni/jni_interface.i b/bin/jni/jni_interface.i
index 8a0fcf4515dac9ac304055b85895083eb58bfbc9..fc35f93a2375bb58de8ca5caed1ac904a3e7c5f3 100644
--- a/bin/jni/jni_interface.i
+++ b/bin/jni/jni_interface.i
@@ -227,7 +227,7 @@ void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM
         exportable_callback<CallSignal::TransferFailed>(bind(&Callback::transferFailed, callM)),
         exportable_callback<CallSignal::TransferSucceeded>(bind(&Callback::transferSucceeded, callM)),
         exportable_callback<CallSignal::RecordPlaybackStopped>(bind(&Callback::recordPlaybackStopped, callM, _1)),
-        exportable_callback<CallSignal::VoiceMailNotify>(bind(&Callback::voiceMailNotify, callM, _1, _2)),
+        exportable_callback<CallSignal::VoiceMailNotify>(bind(&Callback::voiceMailNotify, callM, _1, _2, _3, _4)),
         exportable_callback<CallSignal::IncomingMessage>(bind(&Callback::incomingMessage, callM, _1, _2, _3)),
         exportable_callback<CallSignal::IncomingCall>(bind(&Callback::incomingCall, callM, _1, _2, _3)),
         exportable_callback<CallSignal::RecordPlaybackFilepath>(bind(&Callback::recordPlaybackFilepath, callM, _1, _2)),
diff --git a/bin/nodejs/callmanager.i b/bin/nodejs/callmanager.i
index 9ca9f6a32ff06a4047c080557e5a992962b43dba..3e6aeb297ade697959a593c7151a02431fc34283 100644
--- a/bin/nodejs/callmanager.i
+++ b/bin/nodejs/callmanager.i
@@ -32,7 +32,7 @@ public:
     virtual void transferFailed(void){}
     virtual void transferSucceeded(void){}
     virtual void recordPlaybackStopped(const std::string& path){}
-    virtual void voiceMailNotify(const std::string& call_id, int nd_msg){}
+    virtual void voiceMailNotify(const std::string& accountId, int newCount, int oldCount, int urgentCount){}
     virtual void incomingMessage(const std::string& id, const std::string& from, const std::map<std::string, std::string>& messages){}
     virtual void incomingCall(const std::string& account_id, const std::string& call_id, const std::string& from){}
     virtual void recordPlaybackFilepath(const std::string& id, const std::string& filename){}
@@ -118,7 +118,7 @@ public:
     virtual void transferFailed(void){}
     virtual void transferSucceeded(void){}
     virtual void recordPlaybackStopped(const std::string& path){}
-    virtual void voiceMailNotify(const std::string& call_id, int nd_msg){}
+    virtual void voiceMailNotify(const std::string& accountId, int newCount, int oldCount, int urgentCount){}
     virtual void incomingMessage(const std::string& id, const std::string& from, const std::map<std::string, std::string>& messages){}
     virtual void incomingCall(const std::string& account_id, const std::string& call_id, const std::string& from){}
     virtual void recordPlaybackFilepath(const std::string& id, const std::string& filename){}
diff --git a/bin/nodejs/nodejs_interface.i b/bin/nodejs/nodejs_interface.i
index 4ba384a374021eeec94b8b7f157ca199934ae576..2b46a2c438109fffb8f75f10ba223945f2be175d 100644
--- a/bin/nodejs/nodejs_interface.i
+++ b/bin/nodejs/nodejs_interface.i
@@ -134,6 +134,7 @@ void init(const v8::Handle<v8::Value> &funcMap){
     const std::map<std::string, SharedCallback> callEvHandlers = {
         exportable_callback<CallSignal::StateChange>(bind(&callStateChanged, _1, _2, _3)),
         exportable_callback<CallSignal::IncomingMessage>(bind(&incomingMessage, _1, _2, _3)),
+        exportable_callback<CallSignal::VoiceMailNotify>(bind(&voiceMailNotify, _1, _2, _3, _4)),
         exportable_callback<CallSignal::IncomingCall>(bind(&incomingCall, _1, _2, _3)),
         exportable_callback<CallSignal::NewCallCreated>(bind(&newCallCreated, _1, _2, _3))
     };
diff --git a/src/dring/callmanager_interface.h b/src/dring/callmanager_interface.h
index d99a3d54c4ae6a8cf7b00fd219e4ac4115635852..4a50f2b5c7680fa9c3cb114821d0f928ca12af21 100644
--- a/src/dring/callmanager_interface.h
+++ b/src/dring/callmanager_interface.h
@@ -123,7 +123,7 @@ struct DRING_PUBLIC CallSignal {
         };
         struct DRING_PUBLIC VoiceMailNotify {
                 constexpr static const char* name = "VoiceMailNotify";
-                using cb_type = void(const std::string&, int32_t);
+                using cb_type = void(const std::string&, int32_t, int32_t, int32_t);
         };
         struct DRING_PUBLIC IncomingMessage {
                 constexpr static const char* name = "IncomingMessage";
diff --git a/src/manager.cpp b/src/manager.cpp
index 01862b792ad315a901caa62ddb2a0fad71dbdb38..8a36555a11c07d5c13b01aa05898f2668b57b96a 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -2115,14 +2115,6 @@ Manager::callFailure(Call& call)
     removeAudio(call);
 }
 
-//THREAD=VoIP
-void
-Manager::startVoiceMessageNotification(const std::string& accountId,
-                                           int nb_msg)
-{
-    emitSignal<DRing::CallSignal::VoiceMailNotify>(accountId, nb_msg);
-}
-
 /**
  * Multi Thread
  */
diff --git a/src/manager.h b/src/manager.h
index 0052001c2dc7c792fb5d3ad0ca0bac805aff787d..2e463522a15c661cecc2eee20a2bfcbcb50688aa 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -375,13 +375,6 @@ class Manager {
                                  const std::map<std::string, std::string>& messages,
                                  const std::string& from, bool isMixed);
 
-        /**
-         * Notify the client he has voice mails
-         * @param accountId   The account identifier
-         * @param nb_msg The number of messages
-         */
-        void startVoiceMessageNotification(const std::string& accountId, int nb_msg);
-
         /**
          * ConfigurationManager - Send registration request
          * @param accountId The account to register/unregister
diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp
index c25221979b75abd2ee4fd65c433806efdb82615e..7ac7cd66d1b0fe63fc6cc0137ae03faf71ec9e91 100644
--- a/src/sip/sipvoiplink.cpp
+++ b/src/sip/sipvoiplink.cpp
@@ -223,11 +223,23 @@ transaction_request_cb(pjsip_rx_data *rdata)
 
         if (request.find("NOTIFY") != std::string::npos) {
             if (body and body->data) {
-                int voicemail = 0;
-                int ret = sscanf((const char*) body->data, "Voice-Message: %d/", &voicemail);
-
-                if (ret == 1 and voicemail != 0)
-                    Manager::instance().startVoiceMessageNotification(account_id, voicemail);
+                int newCount { 0 };
+                int oldCount { 0 };
+                int urgentCount { 0 };
+
+                std::string sp = std::string(static_cast<char*>(body->data));
+                auto pos = sp.find("Voice-Message: ");
+                sp = sp.substr(pos);
+
+                int ret = sscanf(sp.c_str() , "Voice-Message: %d/%d (%d/",
+                    &newCount,
+                    &oldCount,
+                    &urgentCount);
+
+                // According to rfc3842
+                // urgent messages are optional
+                if (ret >= 2)
+                    emitSignal<DRing::CallSignal::VoiceMailNotify>(account_id, newCount, oldCount, urgentCount);
             }
         } else if (request.find("MESSAGE") != std::string::npos) {
             // Reply 200 immediately (RFC 3428, ch. 7)