diff --git a/src/chatroom-discovery-backend.cpp b/src/chatroom-discovery-backend.cpp
new file mode 100644
index 0000000..e7ed3ea
--- /dev/null
+++ b/src/chatroom-discovery-backend.cpp
@@ -0,0 +1,455 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
+ *         Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "chatroom-discovery-backend.hpp"
+#include <QStringList>
+
+
+#ifndef Q_MOC_RUN
+
+#endif
+
+namespace chronochat {
+
+static const time::milliseconds FRESHNESS_PERIOD(60000);
+static const time::seconds REFRESH_INTERVAL(60);
+static const time::seconds HELLO_INTERVAL(60);
+static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
+// a count enforced when a manager himself find another one publish chatroom data
+static const int MAXIMUM_COUNT = 3;
+static const int IDENTITY_OFFSET = -1;
+
+ChatroomDiscoveryBackend::ChatroomDiscoveryBackend(const Name& routingPrefix,
+                                                   const Name& identity,
+                                                   QObject* parent)
+  : QThread(parent)
+  , m_routingPrefix(routingPrefix)
+  , m_identity(identity)
+  , m_randomGenerator(static_cast<unsigned int>(std::time(0)))
+  , m_rangeUniformRandom(m_randomGenerator, boost::uniform_int<>(500,2000))
+  , m_shouldResume(false)
+{
+  m_discoveryPrefix.append("ndn")
+    .append("broadcast")
+    .append("ChronoChat")
+    .append("Discovery");
+  m_userDiscoveryPrefix.append(m_identity).append("CHRONOCHAT-DISCOVERYDATA");
+  updatePrefixes();
+}
+
+ChatroomDiscoveryBackend::~ChatroomDiscoveryBackend()
+{
+}
+
+void
+ChatroomDiscoveryBackend::run()
+{
+  bool shouldResume = false;
+  do {
+    initializeSync();
+
+    if (m_face == nullptr)
+      break;
+
+    m_face->getIoService().run();
+
+    m_mutex.lock();
+    shouldResume = m_shouldResume;
+    m_shouldResume = false;
+    m_mutex.unlock();
+
+  } while (shouldResume);
+
+  std::cerr << "Bye!" << std::endl;
+}
+
+void
+ChatroomDiscoveryBackend::initializeSync()
+{
+  BOOST_ASSERT(m_sock == nullptr);
+
+  m_face = shared_ptr<ndn::Face>(new ndn::Face);
+  m_scheduler = unique_ptr<ndn::Scheduler>(new ndn::Scheduler(m_face->getIoService()));
+
+  m_sock = make_shared<chronosync::Socket>(m_discoveryPrefix,
+                                           Name(),
+                                           ref(*m_face),
+                                           bind(&ChatroomDiscoveryBackend::processSyncUpdate,
+                                                this, _1));
+
+  // add an timer to refresh front end
+  if (m_refreshPanelId != nullptr) {
+    m_scheduler->cancelEvent(m_refreshPanelId);
+  }
+  m_refreshPanelId = m_scheduler->scheduleEvent(REFRESH_INTERVAL,
+                                                [this] { sendChatroomList(); });
+}
+
+void
+ChatroomDiscoveryBackend::close()
+{
+  m_scheduler->cancelAllEvents();
+  m_refreshPanelId.reset();
+  m_chatroomList.clear();
+  m_sock.reset();
+}
+
+void
+ChatroomDiscoveryBackend::processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates)
+{
+  if (updates.empty()) {
+    return;
+  }
+  for (const auto& update : updates) {
+    m_sock->fetchData(update.session, update.high,
+                      bind(&ChatroomDiscoveryBackend::processChatroomData, this, _1), 2);
+  }
+}
+
+void
+ChatroomDiscoveryBackend::processChatroomData(const ndn::shared_ptr<const ndn::Data>& data)
+{
+  // extract chatroom name by get(-3)
+  Name::Component chatroomName = data->getName().get(-3);
+  auto it = m_chatroomList.find(chatroomName);
+  if (it == m_chatroomList.end()) {
+    m_chatroomList[chatroomName].chatroomName = chatroomName.toUri();
+    m_chatroomList[chatroomName].count = 0;
+    m_chatroomList[chatroomName].isPrint = false;
+    m_chatroomList[chatroomName].isParticipant = false;
+    m_chatroomList[chatroomName].isManager = false;
+    it = m_chatroomList.find(chatroomName);
+  }
+  // If the user is the manager of this chatroom, he should not receive any data from this chatroom
+  if (it->second.isManager) {
+    if (it->second.count < MAXIMUM_COUNT) {
+      it->second.count++;
+      return;
+    }
+    else {
+      it->second.count = 0;
+      if (m_routableUserDiscoveryPrefix < data->getName()) {
+        // when two managers exist, the one with "smaller" name take the control
+        sendUpdate(chatroomName);
+        return;
+      }
+      else {
+        if (it->second.helloTimeoutEventId != nullptr) {
+          m_scheduler->cancelEvent(it->second.helloTimeoutEventId);
+        }
+        it->second.helloTimeoutEventId = nullptr;
+        it->second.isManager = false;
+      }
+
+    }
+  }
+
+  else if (it->second.isParticipant) {
+    if (it->second.localChatroomTimeoutEventId != nullptr)
+      m_scheduler->cancelEvent(it->second.localChatroomTimeoutEventId);
+
+    // If a user start a random timer it means that he think his own chatroom is not alive
+    // But when he receive some packet, it means that this chatroom is alive, so he can
+    // cancel the timer
+    if (it->second.managerSelectionTimeoutEventId != nullptr)
+      m_scheduler->cancelEvent(it->second.managerSelectionTimeoutEventId);
+    it->second.managerSelectionTimeoutEventId = nullptr;
+
+    it->second.localChatroomTimeoutEventId =
+      m_scheduler->scheduleEvent(HELLO_INTERVAL * 3,
+                                 bind(&ChatroomDiscoveryBackend::localSessionTimeout,
+                                      this, chatroomName));
+  }
+  else {
+    if (!data->getContent().empty()) {
+      ChatroomInfo chatroom;
+      chatroom.wireDecode(data->getContent().blockFromValue());
+      it->second.info = chatroom;
+    }
+
+    if (it->second.remoteChatroomTimeoutEventId != nullptr)
+      m_scheduler->cancelEvent(it->second.remoteChatroomTimeoutEventId);
+
+    it->second.remoteChatroomTimeoutEventId =
+      m_scheduler->scheduleEvent(HELLO_INTERVAL * 5,
+                                 bind(&ChatroomDiscoveryBackend::remoteSessionTimeout,
+                                      this, chatroomName));
+  }
+  // if this is a chatroom that haven't been print on the discovery panel, print it.
+  if(!it->second.isPrint) {
+    sendChatroomList();
+    it->second.isPrint = true;
+  }
+}
+
+void
+ChatroomDiscoveryBackend::localSessionTimeout(const Name::Component& chatroomName)
+{
+  auto it = m_chatroomList.find(chatroomName);
+  if (it == m_chatroomList.end() || it->second.isParticipant == false)
+    return;
+  it->second.managerSelectionTimeoutEventId =
+    m_scheduler->scheduleEvent(time::milliseconds(m_rangeUniformRandom()),
+                               bind(&ChatroomDiscoveryBackend::randomSessionTimeout,
+                                    this, chatroomName));
+}
+
+void
+ChatroomDiscoveryBackend::remoteSessionTimeout(const Name::Component& chatroomName)
+{
+  m_chatroomList.erase(chatroomName);
+}
+
+void
+ChatroomDiscoveryBackend::randomSessionTimeout(const Name::Component& chatroomName)
+{
+  Name prefix = m_routableUserDiscoveryPrefix;
+  prefix.append(chatroomName);
+  m_sock->addSyncNode(prefix);
+
+  emit chatroomInfoRequest(chatroomName.toUri(), true);
+}
+
+void
+ChatroomDiscoveryBackend::sendUpdate(const Name::Component& chatroomName)
+{
+  auto it = m_chatroomList.find(chatroomName);
+  if (it != m_chatroomList.end() && it->second.isManager) {
+    ndn::Block buf = it->second.info.wireEncode();
+
+    if (it->second.helloTimeoutEventId != nullptr) {
+      m_scheduler->cancelEvent(it->second.helloTimeoutEventId);
+    }
+
+    m_sock->publishData(buf.wire(), buf.size(), FRESHNESS_PERIOD, it->second.chatroomPrefix);
+
+    it->second.helloTimeoutEventId =
+      m_scheduler->scheduleEvent(HELLO_INTERVAL,
+                                 bind(&ChatroomDiscoveryBackend::sendUpdate, this, chatroomName));
+    // if this is a chatroom that haven't been print on the discovery panel, print it.
+    if(!it->second.isPrint) {
+      sendChatroomList();
+      it->second.isPrint = true;
+    }
+  }
+}
+
+void
+ChatroomDiscoveryBackend::updatePrefixes()
+{
+  Name temp;
+  if (m_routingPrefix.isPrefixOf(m_userDiscoveryPrefix))
+    temp = m_userDiscoveryPrefix;
+  else
+    temp.append(m_routingPrefix)
+      .append(ROUTING_HINT_SEPARATOR, 2)
+      .append(m_userDiscoveryPrefix);
+
+  Name routableIdentity = m_routableUserDiscoveryPrefix.getPrefix(IDENTITY_OFFSET);
+  for (auto& chatroom : m_chatroomList) {
+    if (chatroom.second.isParticipant) {
+      chatroom.second.info.removeParticipant(routableIdentity);
+      chatroom.second.info.addParticipant(temp.getPrefix(IDENTITY_OFFSET));
+    }
+  }
+  m_routableUserDiscoveryPrefix = temp;
+}
+
+void
+ChatroomDiscoveryBackend::updateRoutingPrefix(const QString& routingPrefix)
+{
+  Name newRoutingPrefix(routingPrefix.toStdString());
+  if (!newRoutingPrefix.empty() && newRoutingPrefix != m_routingPrefix) {
+    // Update localPrefix
+    m_routingPrefix = newRoutingPrefix;
+
+    updatePrefixes();
+
+    m_mutex.lock();
+    m_shouldResume = true;
+    m_mutex.unlock();
+
+    close();
+
+    m_face->getIoService().stop();
+  }
+}
+
+void
+ChatroomDiscoveryBackend::onEraseInRoster(ndn::Name sessionPrefix,
+                                          ndn::Name::Component chatroomName)
+{
+  auto it = m_chatroomList.find(chatroomName);
+  if (it != m_chatroomList.end()) {
+    it->second.info.removeParticipant(sessionPrefix);
+    if (it->second.info.getParticipants().size() == 0) {
+      // Before deleting the chatroom, cancel the hello event timer if exist
+      if (it->second.helloTimeoutEventId != nullptr)
+        m_scheduler->cancelEvent(it->second.helloTimeoutEventId);
+
+      m_chatroomList.erase(chatroomName);
+      Name prefix = sessionPrefix;
+      prefix.append("CHRONOCHAT-DISCOVERYDATA").append(chatroomName);
+      m_sock->removeSyncNode(prefix);
+      sendChatroomList();
+      return;
+    }
+
+    if (sessionPrefix.isPrefixOf(m_routableUserDiscoveryPrefix)) {
+      it->second.isParticipant = false;
+      it->second.isManager = false;
+      it->second.isPrint = false;
+      it->second.count = 0;
+      if (it->second.helloTimeoutEventId != nullptr)
+        m_scheduler->cancelEvent(it->second.helloTimeoutEventId);
+      it->second.helloTimeoutEventId = nullptr;
+
+      if (it->second.localChatroomTimeoutEventId != nullptr)
+        m_scheduler->cancelEvent(it->second.localChatroomTimeoutEventId);
+      it->second.localChatroomTimeoutEventId = nullptr;
+
+      it->second.remoteChatroomTimeoutEventId =
+      m_scheduler->scheduleEvent(HELLO_INTERVAL * 5,
+                                bind(&ChatroomDiscoveryBackend::remoteSessionTimeout,
+                                     this, chatroomName));
+    }
+
+    if (it->second.isManager) {
+      sendUpdate(chatroomName);
+    }
+  }
+}
+
+void
+ChatroomDiscoveryBackend::onAddInRoster(ndn::Name sessionPrefix,
+                                        ndn::Name::Component chatroomName)
+{
+  auto it = m_chatroomList.find(chatroomName);
+  if (it != m_chatroomList.end()) {
+    it->second.info.addParticipant(sessionPrefix);
+    if (it->second.isManager)
+      sendUpdate(chatroomName);
+  }
+  else {
+    m_chatroomList[chatroomName].chatroomName = chatroomName.toUri();
+    m_chatroomList[chatroomName].info.setName(chatroomName);
+    m_chatroomList[chatroomName].info.addParticipant(sessionPrefix);
+  }
+}
+
+void
+ChatroomDiscoveryBackend::onNewChatroomForDiscovery(Name::Component chatroomName)
+{
+  Name newPrefix = m_routableUserDiscoveryPrefix;
+  newPrefix.append(chatroomName);
+  auto it = m_chatroomList.find(chatroomName);
+  if (it == m_chatroomList.end()) {
+    m_chatroomList[chatroomName].chatroomPrefix = newPrefix;
+    m_chatroomList[chatroomName].isParticipant = true;
+    m_chatroomList[chatroomName].isManager = false;
+    m_chatroomList[chatroomName].count = 0;
+    m_chatroomList[chatroomName].isPrint = false;
+    m_scheduler->scheduleEvent(time::milliseconds(600),
+                               bind(&ChatroomDiscoveryBackend::randomSessionTimeout, this,
+                                    chatroomName));
+  }
+  else {
+    // Entering an existing chatroom
+    it->second.isParticipant = true;
+    it->second.isManager = false;
+    it->second.chatroomPrefix = newPrefix;
+
+    if (it->second.remoteChatroomTimeoutEventId != nullptr)
+      m_scheduler->cancelEvent(it->second.remoteChatroomTimeoutEventId);
+    it->second.isPrint = false;
+    it->second.remoteChatroomTimeoutEventId = nullptr;
+
+    it->second.localChatroomTimeoutEventId =
+      m_scheduler->scheduleEvent(HELLO_INTERVAL * 3,
+                                 bind(&ChatroomDiscoveryBackend::localSessionTimeout,
+                                      this, chatroomName));
+    emit chatroomInfoRequest(chatroomName.toUri(), false);
+  }
+}
+
+void
+ChatroomDiscoveryBackend::onRespondChatroomInfoRequest(ChatroomInfo chatroomInfo, bool isManager)
+{
+  if (isManager)
+    chatroomInfo.setManager(m_routableUserDiscoveryPrefix.getPrefix(IDENTITY_OFFSET));
+  Name::Component chatroomName = chatroomInfo.getName();
+  m_chatroomList[chatroomName].chatroomName = chatroomName.toUri();
+  m_chatroomList[chatroomName].isManager = isManager;
+  m_chatroomList[chatroomName].count = 0;
+  m_chatroomList[chatroomName].info = chatroomInfo;
+  sendChatroomList();
+  onAddInRoster(m_routableUserDiscoveryPrefix.getPrefix(IDENTITY_OFFSET), chatroomName);
+}
+
+void
+ChatroomDiscoveryBackend::onIdentityUpdated(const QString& identity)
+{
+  m_chatroomList.clear();
+  m_identity = Name(identity.toStdString());
+  m_userDiscoveryPrefix.clear();
+  m_userDiscoveryPrefix.append(m_identity).append("CHRONOCHAT-DISCOVERYDATA");
+  updatePrefixes();
+
+  m_mutex.lock();
+  m_shouldResume = true;
+  m_mutex.unlock();
+
+  close();
+
+  m_face->getIoService().stop();
+}
+
+void
+ChatroomDiscoveryBackend::sendChatroomList()
+{
+  QStringList chatroomList;
+  for (const auto& chatroom : m_chatroomList) {
+    chatroomList << QString::fromStdString(chatroom.first.toUri());
+  }
+
+  emit chatroomListReady(chatroomList);
+  if (m_refreshPanelId != nullptr) {
+    m_scheduler->cancelEvent(m_refreshPanelId);
+  }
+  m_refreshPanelId = m_scheduler->scheduleEvent(REFRESH_INTERVAL,
+                                                [this] { sendChatroomList(); });
+}
+
+void
+ChatroomDiscoveryBackend::onWaitForChatroomInfo(const QString& chatroomName)
+{
+  auto chatroom = m_chatroomList.find(Name::Component(chatroomName.toStdString()));
+  if (chatroom != m_chatroomList.end())
+    emit chatroomInfoReady(chatroom->second.info);
+}
+
+void
+ChatroomDiscoveryBackend::shutdown()
+{
+  m_mutex.lock();
+  m_shouldResume = false;
+  m_mutex.unlock();
+
+  close();
+
+  m_face->getIoService().stop();
+}
+
+
+} // namespace chronochat
+
+#if WAF
+#include "chatroom-discovery-backend.moc"
+#endif
