diff --git a/bin/dbus/cx.ring.Ring.CallManager.xml b/bin/dbus/cx.ring.Ring.CallManager.xml
index 526ace11aa45535d1e3378c771e22517e22d7dc7..b5cebc337b97e053d515add9a14065351865a374 100644
--- a/bin/dbus/cx.ring.Ring.CallManager.xml
+++ b/bin/dbus/cx.ring.Ring.CallManager.xml
@@ -35,9 +35,16 @@
               </tp:docstring>
             </arg>
             <arg type="b" name="refuseSucceeded" direction="out"/>
-
         </method>
 
+        <signal name="SmartInfo" tp:name-for-bindings="SmartInfo">
+            <tp:docstring>
+              Once enabled using the startSmartInfo method, this signal is emitted every refreshTimeMS
+            </tp:docstring>
+             <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="MapStringString"/>
+             <arg type="a{ss}" name="info" direction="out" />
+       </signal>
+
         <method name="accept" tp:name-for-bindings="accept">
             <tp:docstring>
               Answer an incoming call. Automatically puts the current call on HOLD.
@@ -344,6 +351,23 @@
             </arg>
         </method>
 
+        <method name="startSmartInfo" tp:name-for-bindings="startSmartInfo">
+            <tp:docstring>
+              Start sending the signal smartInfo
+            </tp:docstring>
+            <arg type="u" name="refreshTimeMs" direction="in">
+              <tp:docstring>
+                Set the sending time (in milliseconds) of the signal.
+              </tp:docstring>
+            </arg>
+        </method>
+
+        <method name="stopSmartInfo" tp:name-for-bindings="stopSmartInfo">
+            <tp:docstring>
+              Stop sending the signal smartInfo
+            </tp:docstring>
+        </method>
+
         <method name="getIsRecording" tp:name-for-bindings="getIsRecording">
             <tp:docstring>
               Tells whether or not a call is being recorded.
diff --git a/bin/dbus/dbuscallmanager.cpp b/bin/dbus/dbuscallmanager.cpp
index 843680f7c7d14e1a63f37564e126bfd65a9e4f0e..6d71f5291c7b9a811d3b0803ba2dd5f13c361ed7 100644
--- a/bin/dbus/dbuscallmanager.cpp
+++ b/bin/dbus/dbuscallmanager.cpp
@@ -283,3 +283,15 @@ DBusCallManager::sendTextMessage(const std::string& callID, const std::map<std::
 {
     DRing::sendTextMessage(callID, messages, "Me", isMixed);
 }
+
+void
+DBusCallManager::startSmartInfo(const uint32_t& refreshTimeMs)
+{
+    DRing::startSmartInfo(refreshTimeMs);
+}
+
+void
+DBusCallManager::stopSmartInfo()
+{
+    DRing::stopSmartInfo();
+}
diff --git a/bin/dbus/dbuscallmanager.h b/bin/dbus/dbuscallmanager.h
index ebef2d6f46b145e9515539db520b1b3907bce133..69363f9e766e4b0d40da2fcb7d7bc86e66d5ed1f 100644
--- a/bin/dbus/dbuscallmanager.h
+++ b/bin/dbus/dbuscallmanager.h
@@ -97,6 +97,8 @@ class DBusCallManager :
         void requestGoClear(const std::string& callID);
         void acceptEnrollment(const std::string& callID, const bool& accepted);
         void sendTextMessage(const std::string& callID, const std::map<std::string, std::string>& messages, const bool& isMixed);
+        void startSmartInfo(const uint32_t& refreshTimeMs);
+        void stopSmartInfo();
 };
 
 #endif // __RING_CALLMANAGER_H__
diff --git a/bin/dbus/dbusclient.cpp b/bin/dbus/dbusclient.cpp
index f049f455dbbf7a5010a5bc4d934b7250e189e68f..61886b11bb50a118fa510b2b634d4ebbe65ba862 100644
--- a/bin/dbus/dbusclient.cpp
+++ b/bin/dbus/dbusclient.cpp
@@ -166,7 +166,8 @@ DBusClient::initLibrary(int flags)
         exportable_callback<CallSignal::RtcpReportReceived>(bind(&DBusCallManager::onRtcpReportReceived, 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::VideoMuted>(bind(&DBusCallManager::videoMuted, callM, _1, _2)),
+        exportable_callback<CallSignal::SmartInfo>(bind(&DBusCallManager::SmartInfo, callM, _1))
     };
 
     // Configuration event handlers
diff --git a/src/Makefile.am b/src/Makefile.am
index c26886ee551377344d812ffa29768a204c958493..c77f35c83831f565a5222133f754a994039a26ac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -126,7 +126,9 @@ libring_la_SOURCES = \
 		string_utils.cpp \
 		rw_mutex.h \
 		ring_api.cpp \
-		rational.h
+		rational.h \
+		smartools.cpp \
+		smartools.h
 
 if HAVE_WIN32
 libring_la_SOURCES += \
diff --git a/src/client/callmanager.cpp b/src/client/callmanager.cpp
index 9882973892eb3fdc1c8a36153736c0572132c549..2170c15f4509cb63fa55439c90fe114b313e6890 100644
--- a/src/client/callmanager.cpp
+++ b/src/client/callmanager.cpp
@@ -33,6 +33,8 @@
 #include "logger.h"
 #include "manager.h"
 
+#include "smartools.h"
+
 namespace DRing {
 
 void
@@ -142,6 +144,18 @@ removeConference(const std::string& conference_id)
    ring::Manager::instance().removeConference(conference_id);
 }
 
+void
+startSmartInfo(uint32_t refreshTimeMs)
+{
+    ring::Smartools::getInstance().start(std::chrono::milliseconds(refreshTimeMs));
+}
+
+void
+stopSmartInfo()
+{
+    ring::Smartools::getInstance().stop();
+}
+
 bool
 addParticipant(const std::string& callID, const std::string& confID)
 {
diff --git a/src/client/ring_signal.cpp b/src/client/ring_signal.cpp
index d8f91e9dce638abdc473b42e63301b88a98347e4..766f88e5d16e8d48bb0b307972301070c5ee14f9 100644
--- a/src/client/ring_signal.cpp
+++ b/src/client/ring_signal.cpp
@@ -53,6 +53,7 @@ getSignalHandlers()
         exported_callback<DRing::CallSignal::PeerHold>(),
         exported_callback<DRing::CallSignal::VideoMuted>(),
         exported_callback<DRing::CallSignal::AudioMuted>(),
+        exported_callback<DRing::CallSignal::SmartInfo>(),
 
         /* Configuration */
         exported_callback<DRing::ConfigurationSignal::VolumeChanged>(),
diff --git a/src/dring/callmanager_interface.h b/src/dring/callmanager_interface.h
index a1c1cba9079e9ab7e58672617701f5aa6a1f63c7..1c49dddaf8446a2b57184788848562a47c8cda55 100644
--- a/src/dring/callmanager_interface.h
+++ b/src/dring/callmanager_interface.h
@@ -67,6 +67,10 @@ std::vector<std::string> getDisplayNames(const std::string& confID);
 std::string getConferenceId(const std::string& callID);
 std::map<std::string, std::string> getConferenceDetails(const std::string& callID);
 
+/* Statistic related methods */
+void startSmartInfo(uint32_t refreshTimeMs);
+void stopSmartInfo();
+
 /* File Playback methods */
 bool startRecordedFilePlayback(const std::string& filepath);
 void stopRecordedFilePlayback(const std::string& filepath);
@@ -200,8 +204,12 @@ struct CallSignal {
                 constexpr static const char* name = "AudioMuted";
                 using cb_type = void(const std::string&, bool);
         };
+        struct SmartInfo {
+                constexpr static const char* name = "SmartInfo";
+                using cb_type = void(const std::map<std::string, std::string>&);
+        };
 };
 
-} // namespace DRing
+}; // namespace DRing
 
 #endif // DRING_CALLMANAGERI_H
diff --git a/src/manager.h b/src/manager.h
index 886718480f7ca67770c69e89aa55279c638bf468..166bdc67ac9f28274e023f491d14bf48f099f4cf 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -61,7 +61,6 @@ class YamlEmitter;
 namespace video {
 class SinkClient;
 }
-
 class PluginManager;
 class AudioFile;
 class DTMF;
@@ -769,6 +768,12 @@ class Manager {
          */
         std::vector<std::string> loadAccountOrder() const;
 
+        /**
+         * Get the Call referred by callID. If the Call does not exist, return
+         * empty std::shared_ptr<Call> instance
+         */
+        std::shared_ptr<Call> getCallFromCallID(const std::string &callID) const;
+
     private:
         std::atomic_bool autoAnswer_ {false};
 
@@ -779,10 +784,6 @@ class Manager {
         // Set the ringtone or recorded call to be played
         void updateAudioFile(const std::string &file, int sampleRate);
 
-        /**
-         * Get the Call referred to by callID. If the Call does not exist, return NULL
-         */
-        std::shared_ptr<Call> getCallFromCallID(const std::string &callID) const;
 
         /**
          * Process remaining participant given a conference and the current call id.
diff --git a/src/media/audio/audio_rtp_session.cpp b/src/media/audio/audio_rtp_session.cpp
index cd76ee5bdd5c50ea2832b5bc4fba315d81f53d2e..7474886ae5e03b773fafe8c6ba42c36bb117b8b0 100644
--- a/src/media/audio/audio_rtp_session.cpp
+++ b/src/media/audio/audio_rtp_session.cpp
@@ -37,6 +37,7 @@
 #include "audio/ringbufferpool.h"
 #include "audio/resampler.h"
 #include "manager.h"
+#include "smartools.h"
 #include <sstream>
 
 namespace ring {
@@ -166,6 +167,7 @@ AudioSender::process()
         resampledData_.setFormat(accountAudioCodec->audioformat);
         resampledData_.resize(samplesToGet);
         resampler_->resample(micData_, resampledData_);
+        Smartools::getInstance().setLocalAudioCodec(audioEncoder_->getEncoderName());
         if (audioEncoder_->encode_audio(resampledData_) < 0)
             RING_ERR("encoding failed");
     } else {
@@ -281,6 +283,8 @@ AudioReceiveThread::process()
         case MediaDecoder::Status::FrameFinished:
             audioDecoder_->writeToRingBuffer(decodedFrame, *ringbuffer_,
                                              mainBuffFormat);
+            // Refresh the remote audio codec in the callback SmartInfo
+            Smartools::getInstance().setRemoteAudioCodec(audioDecoder_->getDecoderName());
             return;
 
         case MediaDecoder::Status::DecodeError:
diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp
index 15855bf3ab51057a883e2e5e3dd68181fe91e19a..29ae832c6f2107fb5536f56802a2955cf763f71d 100644
--- a/src/media/media_decoder.cpp
+++ b/src/media/media_decoder.cpp
@@ -416,6 +416,9 @@ int MediaDecoder::getWidth() const
 int MediaDecoder::getHeight() const
 { return decoderCtx_->height; }
 
+std::string MediaDecoder::getDecoderName() const
+{ return decoderCtx_->codec->name; }
+
 rational<double>
 MediaDecoder::getFps() const
 {
diff --git a/src/media/media_decoder.h b/src/media/media_decoder.h
index f2076614aa132962153ae989222967fe1140c21e..7012bc38bc0c66160435a610d10ff92103111dac 100644
--- a/src/media/media_decoder.h
+++ b/src/media/media_decoder.h
@@ -81,6 +81,8 @@ class MediaDecoder {
 
         int getWidth() const;
         int getHeight() const;
+        std::string getDecoderName() const;
+
         rational<double> getFps() const;
         int getPixelFormat() const;
 
diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp
index cb7ce16981141c913e89ef1aea0a4d1df6f93148..81d3bdb508d265d632801e6f3e28c7257a8233ae 100644
--- a/src/media/media_encoder.cpp
+++ b/src/media/media_encoder.cpp
@@ -116,6 +116,12 @@ MediaEncoder::getLastSeqValue()
         return 0;
 }
 
+std::string
+MediaEncoder::getEncoderName() const
+{
+    return encoderCtx_->codec->name;
+}
+
 void
 MediaEncoder::openOutput(const char *filename,
                          const ring::MediaDescription& args)
diff --git a/src/media/media_encoder.h b/src/media/media_encoder.h
index 03f374910a28f2d3548e3b0b97c3f71fbb05bab3..6f736b29479290dd6730bef292704f7f1dca6244 100644
--- a/src/media/media_encoder.h
+++ b/src/media/media_encoder.h
@@ -84,6 +84,7 @@ public:
     void setMuted(bool isMuted);
     void setInitSeqVal(uint16_t seqVal);
     uint16_t getLastSeqValue();
+    std::string getEncoderName() const;
 
     bool useCodec(const AccountCodecInfo* codec) const noexcept;
 
diff --git a/src/media/video/sinkclient.cpp b/src/media/video/sinkclient.cpp
index 3c2d4c3a2d7bd629269aac07e26a404e385e1e26..bdce0753c87ef0e2c617b13a290f7e55cd5f4b4e 100644
--- a/src/media/video/sinkclient.cpp
+++ b/src/media/video/sinkclient.cpp
@@ -37,6 +37,7 @@
 #include "dring/videomanager_interface.h"
 #include "libav_utils.h"
 #include "video_scaler.h"
+#include "smartools.h"
 
 #ifndef _WIN32
 #include <sys/mman.h>
@@ -321,13 +322,18 @@ SinkClient::update(Observable<std::shared_ptr<VideoFrame>>* /*obs*/,
     const std::chrono::duration<double> seconds = currentTime - lastFrameDebug_;
     ++frameCount_;
     if (seconds.count() > 1) {
-        RING_DBG("%s: FPS %f", id_.c_str(), frameCount_ / seconds.count());
+        std::ostringstream fps;
+        fps << frameCount_ / seconds.count();
+        // Send the framerate in smartInfo
+        Smartools::getInstance().setFrameRate(id_, fps.str());
         frameCount_ = 0;
         lastFrameDebug_ = currentTime;
     }
 #endif
 
 #if HAVE_SHM
+    // Send the resolution in smartInfo
+    Smartools::getInstance().setResolution(id_, f.width(), f.height());
     shm_->renderFrame(f);
 #endif
 
diff --git a/src/media/video/sinkclient.h b/src/media/video/sinkclient.h
index 222ebcbef6851f064c989f4d67ae846dbe5e8c24..1f64d345c3493c71ec198129f1d11f13b996cb30 100644
--- a/src/media/video/sinkclient.h
+++ b/src/media/video/sinkclient.h
@@ -33,6 +33,8 @@
 #include <vector>
 #include <memory>
 
+#define DEBUG_FPS
+
 namespace ring { namespace video {
 
 #if HAVE_SHM
diff --git a/src/media/video/video_receive_thread.cpp b/src/media/video/video_receive_thread.cpp
index 20aa1dd3a0bf5eb46fb5e2a0b338e4f811b693bd..286f781e2ef18a0492339948f42f9faf0a414f20 100644
--- a/src/media/video/video_receive_thread.cpp
+++ b/src/media/video/video_receive_thread.cpp
@@ -27,6 +27,7 @@
 #include "client/videomanager.h"
 #include "sinkclient.h"
 #include "logger.h"
+#include "smartools.h"
 
 #include <unistd.h>
 #include <map>
@@ -119,6 +120,9 @@ bool VideoReceiveThread::setup()
     if (!conf)
         exitConference();
 
+    // Send remote video codec in SmartInfo
+    Smartools::getInstance().setRemoteVideoCodec(videoDecoder_->getDecoderName(), id_);
+
     return true;
 }
 
diff --git a/src/media/video/video_sender.cpp b/src/media/video/video_sender.cpp
index d5ad9886faef6fc5b64ad9407bf9c0f176ec54e8..45e4ba6919bffbdd4bd30e31b1b98a65e20acde7 100644
--- a/src/media/video/video_sender.cpp
+++ b/src/media/video/video_sender.cpp
@@ -26,6 +26,7 @@
 #include "client/videomanager.h"
 #include "logger.h"
 #include "manager.h"
+#include "smartools.h"
 
 #include <map>
 #include <unistd.h>
@@ -67,6 +68,9 @@ VideoSender::encodeAndSendVideo(VideoFrame& input_frame)
 
     if (videoEncoder_->encode(input_frame, is_keyframe, frameNumber_++) < 0)
         RING_ERR("encoding failed");
+
+    // Send local video codec in SmartInfo
+    Smartools::getInstance().setLocalVideoCodec(videoEncoder_->getEncoderName());
 }
 
 void
diff --git a/src/smartools.cpp b/src/smartools.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ce579f0aa876bc5052845c25cd6cf3a3ea8c7f19
--- /dev/null
+++ b/src/smartools.cpp
@@ -0,0 +1,139 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Olivier Grégoire <olivier.gregoire@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+#include "smartools.h"
+#include "media/media_decoder.h"
+#include "media/video/video_input.h"
+#include "media/video/video_device.h"
+#include "dring/callmanager_interface.h"
+#include "client/ring_signal.h"
+#include "string_utils.h"
+
+namespace ring {
+
+Smartools& Smartools::getInstance()
+{
+    // Meyers-Singleton
+    static Smartools instance_;
+    return instance_;
+}
+
+// Launch process() in new thread
+Smartools::Smartools()
+: loop_([this] { return true; }, [this] { process(); }, [] {})
+{}
+
+void
+Smartools::sendInfo()
+{
+    std::lock_guard<std::mutex> lk(mutexInfo_);
+    emitSignal<DRing::CallSignal::SmartInfo>(information_);
+    information_.clear();
+}
+
+void
+Smartools::process()
+{
+    // Send the signal SmartInfo
+    Smartools::sendInfo();
+    std::this_thread::sleep_for(refreshTimeMs_);
+}
+
+void
+Smartools::start(std::chrono::milliseconds refreshTimeMs)
+{
+    RING_DBG("Start SmartInfo");
+    refreshTimeMs_ = refreshTimeMs;
+    loop_.stop();
+    loop_.start();
+}
+
+void
+Smartools::stop()
+{
+    std::lock_guard<std::mutex> lk(mutexInfo_);
+    RING_DBG("Stop SmartInfo");
+    loop_.stop();
+    information_.clear();
+}
+
+
+//Set all the information in the map
+
+void
+Smartools::setFrameRate(const std::string& id, const std::string& fps)
+{
+    std::lock_guard<std::mutex> lk(mutexInfo_);
+    if(id == "local"){
+        information_["local FPS"]= fps;
+    } else {
+        information_["remote FPS"]= fps;
+    }
+}
+
+void
+Smartools::setResolution(const std::string& id, int width, int height)
+{
+    std::lock_guard<std::mutex> lk(mutexInfo_);
+    if(id == "local"){
+        information_["local width"] = to_string(width);
+        information_["local height"] = to_string(height);
+    } else {
+        information_["remote width"] = to_string(width);
+        information_["remote height"] = to_string(height);
+    }
+}
+
+void
+Smartools::setRemoteAudioCodec(const std::string& remoteAudioCodec)
+{
+    std::lock_guard<std::mutex> lk(mutexInfo_);
+    information_["remote audio codec"]= remoteAudioCodec;
+}
+
+void
+Smartools::setLocalAudioCodec(const std::string& localAudioCodec)
+{
+    std::lock_guard<std::mutex> lk(mutexInfo_);
+    information_["local audio codec"]= localAudioCodec;
+}
+
+void
+Smartools::setLocalVideoCodec(const std::string& localVideoCodec)
+{
+    std::lock_guard<std::mutex> lk(mutexInfo_);
+    information_["local video codec"]= localVideoCodec;
+}
+
+void
+Smartools::setRemoteVideoCodec(const std::string& remoteVideoCodec, const std::string& callID)
+{
+    std::lock_guard<std::mutex> lk(mutexInfo_);
+    information_["remote video codec"]= remoteVideoCodec;
+    auto confID = Manager::instance().getCallFromCallID(callID)->getConfId();
+    if (confID != ""){
+        information_["type"]= "conference";
+        information_["callID"]= confID;
+    } else {
+        information_["type"]= "no conference";
+        information_["callID"]= callID;
+    }
+ }
+
+ } // end namespace ring
diff --git a/src/smartools.h b/src/smartools.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d3b6bf8c832519bb1b930f7b7954cb193efd663
--- /dev/null
+++ b/src/smartools.h
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Olivier Grégoire <olivier.gregoire@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+#pragma once
+
+#include "threadloop.h"
+#include "manager.h"
+#include <string>
+
+namespace ring {
+class Smartools
+{
+    public:
+        static Smartools& getInstance();
+        void start(std::chrono::milliseconds refreshTimeMs);
+        void stop();
+        void setFrameRate(const std::string& id, const std::string& fps);
+        void setResolution(const std::string& id, int width, int height);
+        void setLocalVideoCodec(const std::string& localVideoCodec);
+        void setRemoteVideoCodec(const std::string& remoteVideoCodec, const std::string& callID);
+        void setRemoteAudioCodec(const std::string& remoteAudioCodec);
+        void setLocalAudioCodec(const std::string& remoteAudioCodec);
+        void sendInfo();
+
+    private:
+        Smartools();
+        void process();
+        std::map<std::string, std::string> information_;
+        std::mutex mutexInfo_; // Protect information_ from multithreading
+        std::chrono::milliseconds refreshTimeMs_;
+        ThreadLoop loop_; // Has to be last member
+};
+} //ring namespace