blob: b52c188e7811992daaf18f8191d976ba0e11371d [file] [log] [blame]
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
9 */
10
11#include <QApplication>
12#include <QMessageBox>
13#include <QDir>
14#include <QTimer>
Yingdi Yu0b0a7362014-08-05 16:31:30 -070015#include "controller.hpp"
Mengjin Yan391d7242014-08-28 20:51:55 -070016//#include "chatroom-discovery.h"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080017
18#ifndef Q_MOC_RUN
19#include <boost/filesystem.hpp>
20#include <boost/lexical_cast.hpp>
Yingdi Yufa0b6a02014-04-30 14:26:42 -070021#include <ndn-cxx/util/random.hpp>
Yingdi Yud45777b2014-10-16 23:54:11 -070022#include "invitation.hpp"
Yingdi Yu0b0a7362014-08-05 16:31:30 -070023#include "cryptopp.hpp"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080024#include "config.pb.h"
25#include "endorse-info.pb.h"
26#include "logging.h"
27#endif
28
Yingdi Yu0b0a7362014-08-05 16:31:30 -070029// INIT_LOGGER("chronos.Controller");
Yingdi Yu348f5ea2014-03-01 14:47:25 -080030
31Q_DECLARE_METATYPE(ndn::Name)
32Q_DECLARE_METATYPE(ndn::IdentityCertificate)
Yingdi Yu0b0a7362014-08-05 16:31:30 -070033Q_DECLARE_METATYPE(Chronos::EndorseInfo)
Yingdi Yu233a9722014-03-07 15:47:09 -080034Q_DECLARE_METATYPE(ndn::Interest)
35Q_DECLARE_METATYPE(size_t)
Mengjin Yan391d7242014-08-28 20:51:55 -070036Q_DECLARE_METATYPE(chronos::ChatroomInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080037
38namespace chronos {
39
Yingdi Yu0b0a7362014-08-05 16:31:30 -070040using std::string;
41
42using ndn::Face;
43using ndn::IdentityCertificate;
44using ndn::OnInterestValidated;
45using ndn::OnInterestValidationFailed;
Yingdi Yu17032f82014-03-25 15:48:23 -070046
Yingdi Yu348f5ea2014-03-01 14:47:25 -080047static const uint8_t ROUTING_PREFIX_SEPARATOR[2] = {0xF0, 0x2E};
48
49// constructor & destructor
50Controller::Controller(shared_ptr<Face> face,
Yingdi Yufa0b6a02014-04-30 14:26:42 -070051 QWidget* parent)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080052 : QDialog(parent)
53 , m_face(face)
Yingdi Yubaaaec02014-09-02 22:05:32 -070054 , m_localPrefixDetected(false)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080055 , m_invitationListenerId(0)
56 , m_contactManager(m_face)
Mengjin Yan391d7242014-08-28 20:51:55 -070057 , m_discoveryLogic(m_face,
58 bind(&Controller::updateDiscoveryList, this, _1, _2))
Yingdi Yu348f5ea2014-03-01 14:47:25 -080059 , m_settingDialog(new SettingDialog)
60 , m_startChatDialog(new StartChatDialog)
61 , m_profileEditor(new ProfileEditor)
62 , m_invitationDialog(new InvitationDialog)
63 , m_contactPanel(new ContactPanel)
64 , m_browseContactDialog(new BrowseContactDialog)
65 , m_addContactPanel(new AddContactPanel)
Mengjin Yan391d7242014-08-28 20:51:55 -070066 , m_chatroomDiscoveryDialog(new ChatroomDiscoveryDialog)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080067{
68 qRegisterMetaType<ndn::Name>("ndn.Name");
69 qRegisterMetaType<ndn::IdentityCertificate>("ndn.IdentityCertificate");
Yingdi Yu0b0a7362014-08-05 16:31:30 -070070 qRegisterMetaType<Chronos::EndorseInfo>("Chronos.EndorseInfo");
Yingdi Yu233a9722014-03-07 15:47:09 -080071 qRegisterMetaType<ndn::Interest>("ndn.Interest");
72 qRegisterMetaType<size_t>("size_t");
Mengjin Yan391d7242014-08-28 20:51:55 -070073 qRegisterMetaType<chronos::ChatroomInfo>("chronos.Chatroom");
Yingdi Yu348f5ea2014-03-01 14:47:25 -080074
75 connect(this, SIGNAL(localPrefixUpdated(const QString&)),
76 this, SLOT(onLocalPrefixUpdated(const QString&)));
Yingdi Yu233a9722014-03-07 15:47:09 -080077 connect(this, SIGNAL(invitationInterest(const ndn::Name&, const ndn::Interest&, size_t)),
78 this, SLOT(onInvitationInterest(const ndn::Name&, const ndn::Interest&, size_t)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -080079
80 // Connection to ContactManager
81 connect(this, SIGNAL(identityUpdated(const QString&)),
82 &m_contactManager, SLOT(onIdentityUpdated(const QString&)));
83 connect(&m_contactManager, SIGNAL(warning(const QString&)),
84 this, SLOT(onWarning(const QString&)));
85 connect(this, SIGNAL(refreshBrowseContact()),
86 &m_contactManager, SLOT(onRefreshBrowseContact()));
87 connect(&m_contactManager, SIGNAL(contactInfoFetchFailed(const QString&)),
88 this, SLOT(onWarning(const QString&)));
89 connect(&m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
90 this, SLOT(onContactIdListReady(const QStringList&)));
91
92 // Connection to SettingDialog
93 connect(this, SIGNAL(identityUpdated(const QString&)),
94 m_settingDialog, SLOT(onIdentityUpdated(const QString&)));
95 connect(m_settingDialog, SIGNAL(identityUpdated(const QString&)),
96 this, SLOT(onIdentityUpdated(const QString&)));
97 connect(m_settingDialog, SIGNAL(nickUpdated(const QString&)),
98 this, SLOT(onNickUpdated(const QString&)));
Yingdi Yubaaaec02014-09-02 22:05:32 -070099 connect(this, SIGNAL(localPrefixUpdated(const QString&)),
100 m_settingDialog, SLOT(onLocalPrefixUpdated(const QString&)));
101 connect(m_settingDialog, SIGNAL(prefixUpdated(const QString&)),
102 this, SLOT(onLocalPrefixConfigured(const QString&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800103
104 // Connection to ProfileEditor
105 connect(this, SIGNAL(closeDBModule()),
106 m_profileEditor, SLOT(onCloseDBModule()));
107 connect(this, SIGNAL(identityUpdated(const QString&)),
108 m_profileEditor, SLOT(onIdentityUpdated(const QString&)));
109 connect(m_profileEditor, SIGNAL(updateProfile()),
110 &m_contactManager, SLOT(onUpdateProfile()));
111
112 // Connection to StartChatDialog
113 connect(m_startChatDialog, SIGNAL(startChatroom(const QString&, bool)),
114 this, SLOT(onStartChatroom(const QString&, bool)));
115
116 // Connection to InvitationDialog
117 connect(m_invitationDialog, SIGNAL(invitationResponded(const ndn::Name&, bool)),
118 this, SLOT(onInvitationResponded(const ndn::Name&, bool)));
119
120 // Connection to AddContactPanel
121 connect(m_addContactPanel, SIGNAL(fetchInfo(const QString&)),
122 &m_contactManager, SLOT(onFetchContactInfo(const QString&)));
123 connect(m_addContactPanel, SIGNAL(addContact(const QString&)),
124 &m_contactManager, SLOT(onAddFetchedContact(const QString&)));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700125 connect(&m_contactManager, SIGNAL(contactEndorseInfoReady(const Chronos::EndorseInfo&)),
126 m_addContactPanel, SLOT(onContactEndorseInfoReady(const Chronos::EndorseInfo&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800127
128
129 // Connection to BrowseContactDialog
130 connect(m_browseContactDialog, SIGNAL(directAddClicked()),
131 this, SLOT(onDirectAdd()));
132 connect(m_browseContactDialog, SIGNAL(fetchIdCert(const QString&)),
133 &m_contactManager, SLOT(onFetchIdCert(const QString&)));
134 connect(m_browseContactDialog, SIGNAL(addContact(const QString&)),
135 &m_contactManager, SLOT(onAddFetchedContactIdCert(const QString&)));
136 connect(&m_contactManager, SIGNAL(idCertNameListReady(const QStringList&)),
137 m_browseContactDialog, SLOT(onIdCertNameListReady(const QStringList&)));
138 connect(&m_contactManager, SIGNAL(nameListReady(const QStringList&)),
139 m_browseContactDialog, SLOT(onNameListReady(const QStringList&)));
140 connect(&m_contactManager, SIGNAL(idCertReady(const ndn::IdentityCertificate&)),
141 m_browseContactDialog, SLOT(onIdCertReady(const ndn::IdentityCertificate&)));
142
143 // Connection to ContactPanel
144 connect(m_contactPanel, SIGNAL(waitForContactList()),
145 &m_contactManager, SLOT(onWaitForContactList()));
146 connect(m_contactPanel, SIGNAL(waitForContactInfo(const QString&)),
147 &m_contactManager, SLOT(onWaitForContactInfo(const QString&)));
148 connect(m_contactPanel, SIGNAL(removeContact(const QString&)),
149 &m_contactManager, SLOT(onRemoveContact(const QString&)));
150 connect(m_contactPanel, SIGNAL(updateAlias(const QString&, const QString&)),
151 &m_contactManager, SLOT(onUpdateAlias(const QString&, const QString&)));
152 connect(m_contactPanel, SIGNAL(updateIsIntroducer(const QString&, bool)),
153 &m_contactManager, SLOT(onUpdateIsIntroducer(const QString&, bool)));
154 connect(m_contactPanel, SIGNAL(updateEndorseCertificate(const QString&)),
155 &m_contactManager, SLOT(onUpdateEndorseCertificate(const QString&)));
156 connect(m_contactPanel, SIGNAL(warning(const QString&)),
157 this, SLOT(onWarning(const QString&)));
158 connect(this, SIGNAL(closeDBModule()),
159 m_contactPanel, SLOT(onCloseDBModule()));
160 connect(this, SIGNAL(identityUpdated(const QString&)),
161 m_contactPanel, SLOT(onIdentityUpdated(const QString&)));
162 connect(&m_contactManager, SIGNAL(contactAliasListReady(const QStringList&)),
163 m_contactPanel, SLOT(onContactAliasListReady(const QStringList&)));
164 connect(&m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
165 m_contactPanel, SLOT(onContactIdListReady(const QStringList&)));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700166 connect(&m_contactManager, SIGNAL(contactInfoReady(const QString&, const QString&,
167 const QString&, bool)),
168 m_contactPanel, SLOT(onContactInfoReady(const QString&, const QString&,
169 const QString&, bool)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800170
Mengjin Yan391d7242014-08-28 20:51:55 -0700171 // Connection to DiscoveryDialog
172 connect(this,
173 SIGNAL(discoverChatroomChanged(const chronos::ChatroomInfo&, bool)),
174 m_chatroomDiscoveryDialog,
175 SLOT(onDiscoverChatroomChanged(const chronos::ChatroomInfo&, bool)));
176 connect(m_chatroomDiscoveryDialog, SIGNAL(startChatroom(const QString&, bool)),
177 this, SLOT(onStartChatroom(const QString&, bool)));
178
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800179 initialize();
180
Yingdi Yu233a9722014-03-07 15:47:09 -0800181 createTrayIcon();
182
183 onUpdateLocalPrefixAction();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800184}
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700185
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800186Controller::~Controller()
187{
188 saveConf();
189}
190
191// public methods
192
193
194// private methods
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700195string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800196Controller::getDBName()
197{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700198 string dbName("chronos-");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800199
200 std::stringstream ss;
201 {
202 using namespace CryptoPP;
203
204 SHA256 hash;
205 StringSource(m_identity.wireEncode().wire(), m_identity.wireEncode().size(), true,
206 new HashFilter(hash, new HexEncoder(new FileSink(ss), false)));
207 }
208 dbName.append(ss.str()).append(".db");
209
210 return dbName;
211}
212
213void
214Controller::openDB()
215{
216 m_db = QSqlDatabase::addDatabase("QSQLITE");
217 QString path = (QDir::home().path());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700218 path.append(QDir::separator())
219 .append(".chronos")
220 .append(QDir::separator())
221 .append(getDBName().c_str());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800222 m_db.setDatabaseName(path);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800223
Yingdi Yu42125862014-08-07 17:04:28 -0700224 m_db.open();
225
226 // bool ok = m_db.open();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700227 // _LOG_DEBUG("DB opened: " << std::boolalpha << ok );
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800228}
229
230void
231Controller::initialize()
232{
233 loadConf();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700234
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800235 m_keyChain.createIdentity(m_identity);
236
237 openDB();
238
239 emit identityUpdated(QString(m_identity.toUri().c_str()));
240
241 setInvitationListener();
Mengjin Yan391d7242014-08-28 20:51:55 -0700242
243 m_discoveryLogic.sendDiscoveryInterest();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800244}
245
246void
247Controller::setInvitationListener()
248{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700249 if (m_invitationListenerId != 0)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800250 m_face->unsetInterestFilter(m_invitationListenerId);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700251
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800252 Name invitationPrefix;
253 Name routingPrefix = getInvitationRoutingPrefix();
254 size_t offset = 0;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700255 if (!routingPrefix.isPrefixOf(m_identity)) {
256 invitationPrefix.append(routingPrefix).append(ROUTING_PREFIX_SEPARATOR, 2);
257 offset = routingPrefix.size() + 1;
258 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800259 invitationPrefix.append(m_identity).append("CHRONOCHAT-INVITATION");
260
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700261 m_invitationListenerId = m_face->setInterestFilter(invitationPrefix,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700262 bind(&Controller::onInvitationInterestWrapper,
263 this, _1, _2, offset),
264 bind(&Controller::onInvitationRegisterFailed,
265 this, _1, _2));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800266}
267
268void
269Controller::loadConf()
270{
271 namespace fs = boost::filesystem;
272
273 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
274 fs::create_directories (chronosDir);
275
276 std::ifstream is((chronosDir / "config").c_str ());
277 ChronoChat::Conf conf;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700278 if (conf.ParseFromIstream(&is)) {
279 m_identity.clear();
280 m_identity.append(conf.identity());
281 if (conf.has_nick())
282 m_nick = conf.nick();
283 else
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800284 m_nick = m_identity.get(-1).toUri();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700285 }
286 else {
287 m_identity.clear();
288 // TODO: change below to system default;
289 m_identity.append("chronochat-tmp-identity")
290 .append(getRandomString());
291
292 m_nick = m_identity.get(-1).toUri();
293 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800294}
295
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700296void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800297Controller::saveConf()
298{
299 namespace fs = boost::filesystem;
300
301 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
302 fs::create_directories (chronosDir);
303
304 std::ofstream os((chronosDir / "config").c_str ());
305 ChronoChat::Conf conf;
306 conf.set_identity(m_identity.toUri());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700307 if (!m_nick.empty())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800308 conf.set_nick(m_nick);
309 conf.SerializeToOstream(&os);
310
311 os.close();
312}
313
314void
315Controller::createActions()
316{
317 m_startChatroom = new QAction(tr("Start new chat"), this);
318 connect(m_startChatroom, SIGNAL(triggered()), this, SLOT(onStartChatAction()));
319
Mengjin Yan391d7242014-08-28 20:51:55 -0700320 m_discoveryAction = new QAction(tr("Ongoing Chatrooms"), this);
321 connect(m_discoveryAction, SIGNAL(triggered()), this, SLOT(onDiscoveryAction()));
322
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800323 m_settingsAction = new QAction(tr("Settings"), this);
324 connect(m_settingsAction, SIGNAL(triggered()), this, SLOT(onSettingsAction()));
325
326 m_editProfileAction = new QAction(tr("Edit profile"), this);
327 connect(m_editProfileAction, SIGNAL(triggered()), this, SLOT(onProfileEditorAction()));
328
329 m_contactListAction = new QAction(tr("Contact List"), this);
330 connect(m_contactListAction, SIGNAL(triggered()), this, SLOT(onContactListAction()));
331
332 m_addContactAction = new QAction(tr("Add contact"), this);
333 connect(m_addContactAction, SIGNAL(triggered()), this, SLOT(onAddContactAction()));
334
335 m_updateLocalPrefixAction = new QAction(tr("Update local prefix"), this);
336 connect(m_updateLocalPrefixAction, SIGNAL(triggered()), this, SLOT(onUpdateLocalPrefixAction()));
337
338 m_minimizeAction = new QAction(tr("Mi&nimize"), this);
339 connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(onMinimizeAction()));
340
341 m_quitAction = new QAction(tr("Quit"), this);
342 connect(m_quitAction, SIGNAL(triggered()), this, SLOT(onQuitAction()));
Mengjin Yan391d7242014-08-28 20:51:55 -0700343
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800344}
345
346void
347Controller::createTrayIcon()
348{
349 createActions();
350
351 m_trayIconMenu = new QMenu(this);
352 m_trayIconMenu->addAction(m_startChatroom);
Mengjin Yan391d7242014-08-28 20:51:55 -0700353 m_trayIconMenu->addAction(m_discoveryAction);
354
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800355 m_trayIconMenu->addSeparator();
356 m_trayIconMenu->addAction(m_settingsAction);
357 m_trayIconMenu->addAction(m_editProfileAction);
358 m_trayIconMenu->addSeparator();
359 m_trayIconMenu->addAction(m_contactListAction);
360 m_trayIconMenu->addAction(m_addContactAction);
361 m_trayIconMenu->addSeparator();
362 m_trayIconMenu->addAction(m_updateLocalPrefixAction);
363 m_trayIconMenu->addSeparator();
364 m_trayIconMenu->addAction(m_minimizeAction);
365 m_closeMenu = m_trayIconMenu->addMenu("Close chatroom");
366 m_closeMenu->setEnabled(false);
367 m_trayIconMenu->addSeparator();
368 m_trayIconMenu->addAction(m_quitAction);
369
370 m_trayIcon = new QSystemTrayIcon(this);
371 m_trayIcon->setContextMenu(m_trayIconMenu);
372
373 m_trayIcon->setIcon(QIcon(":/images/icon_small.png"));
374 m_trayIcon->setToolTip("ChronoChat System Tray Icon");
375 m_trayIcon->setVisible(true);
376}
377
378void
379Controller::updateMenu()
380{
381 QMenu* menu = new QMenu(this);
382 QMenu* closeMenu = 0;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700383
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800384 menu->addAction(m_startChatroom);
Mengjin Yan391d7242014-08-28 20:51:55 -0700385 menu->addAction(m_discoveryAction);
386
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800387 menu->addSeparator();
388 menu->addAction(m_settingsAction);
389 menu->addAction(m_editProfileAction);
390 menu->addSeparator();
Yingdi Yu233a9722014-03-07 15:47:09 -0800391 menu->addAction(m_contactListAction);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800392 menu->addAction(m_addContactAction);
393 menu->addSeparator();
394 {
395 ChatActionList::const_iterator it = m_chatActionList.begin();
396 ChatActionList::const_iterator end = m_chatActionList.end();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700397 if (it != end) {
398 for (; it != end; it++)
399 menu->addAction(it->second);
400 menu->addSeparator();
401 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800402 }
403 menu->addAction(m_updateLocalPrefixAction);
404 menu->addSeparator();
405 menu->addAction(m_minimizeAction);
406 closeMenu = menu->addMenu("Close chatroom");
407 {
408 ChatActionList::const_iterator it = m_closeActionList.begin();
409 ChatActionList::const_iterator end = m_closeActionList.end();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700410 if (it == end)
411 closeMenu->setEnabled(false);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800412 else
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700413 for (; it != end; it++)
414 closeMenu->addAction(it->second);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800415 }
416 menu->addSeparator();
417 menu->addAction(m_quitAction);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700418
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800419 m_trayIcon->setContextMenu(menu);
420 delete m_trayIconMenu;
421 m_trayIconMenu = menu;
422 m_closeMenu = closeMenu;
423}
424
425void
426Controller::onLocalPrefix(const Interest& interest, Data& data)
427{
Yingdi Yu106be862014-08-29 09:03:18 -0700428 QString localPrefixStr("/private/local");
429 Name prefix;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800430
Yingdi Yu106be862014-08-29 09:03:18 -0700431 Block contentBlock = data.getContent();
432 try {
433 contentBlock.parse();
434
435 for (Block::element_const_iterator it = contentBlock.elements_begin();
436 it != contentBlock.elements_end(); it++) {
437 Name candidate;
438 candidate.wireDecode(*it);
439 if (candidate.isPrefixOf(m_identity)) {
440 prefix = candidate;
441 break;
442 }
443 }
444
445 if (prefix.empty()) {
446 if (contentBlock.elements_begin() != contentBlock.elements_end())
447 prefix.wireDecode(*contentBlock.elements_begin());
448 else
449 prefix = Name("/private/local");
450 }
451
452 localPrefixStr = QString::fromStdString(prefix.toUri());
453 }
454 catch (Block::Error& e) {
455 prefix = Name("/private/local");
456 }
457
458 if (m_localPrefix.empty() || m_localPrefix != prefix) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800459 emit localPrefixUpdated(localPrefixStr);
Mengjin Yan391d7242014-08-28 20:51:55 -0700460 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800461}
462
463void
464Controller::onLocalPrefixTimeout(const Interest& interest)
465{
466 QString localPrefixStr("/private/local");
467
468 Name localPrefix(localPrefixStr.toStdString());
Mengjin Yan391d7242014-08-28 20:51:55 -0700469 if (m_localPrefix.empty() || m_localPrefix != localPrefix) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800470 emit localPrefixUpdated(localPrefixStr);
Mengjin Yan391d7242014-08-28 20:51:55 -0700471 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800472}
473
474void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700475Controller::onInvitationInterestWrapper(const Name& prefix,
476 const Interest& interest,
477 size_t routingPrefixOffset)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800478{
Yingdi Yu233a9722014-03-07 15:47:09 -0800479 emit invitationInterest(prefix, interest, routingPrefixOffset);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800480}
481
482void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700483Controller::onInvitationRegisterFailed(const Name& prefix, const string& failInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800484{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700485 // _LOG_DEBUG("Controller::onInvitationRegisterFailed: " << failInfo);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800486}
487
488void
489Controller::onInvitationValidated(const shared_ptr<const Interest>& interest)
490{
491 Invitation invitation(interest->getName());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700492 // Should be obtained via a method of ContactManager.
493 string alias = invitation.getInviterCertificate().getPublicKeyName().getPrefix(-1).toUri();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800494
495 m_invitationDialog->setInvitation(alias, invitation.getChatroom(), interest->getName());
496 m_invitationDialog->show();
497}
498
499void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700500Controller::onInvitationValidationFailed(const shared_ptr<const Interest>& interest,
501 string failureInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800502{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700503 // _LOG_DEBUG("Invitation: " << interest->getName() <<
504 // " cannot not be validated due to: " << failureInfo);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800505}
506
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700507string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800508Controller::getRandomString()
509{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700510 uint32_t r = ndn::random::generateWord32();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800511 std::stringstream ss;
512 {
513 using namespace CryptoPP;
514 StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
515 new HexEncoder(new FileSink(ss), false));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700516
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800517 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700518 // for (int i = 0; i < 8; i++)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800519 // {
520 // uint32_t t = r & mask;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700521 // if (t < 10)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800522 // ss << static_cast<char>(t + 0x30);
523 // else
524 // ss << static_cast<char>(t + 0x57);
525 // r = r >> 4;
526 // }
527
528 return ss.str();
529}
530
531ndn::Name
532Controller::getInvitationRoutingPrefix()
533{
534 return Name("/ndn/broadcast");
535}
536
537void
538Controller::addChatDialog(const QString& chatroomName, ChatDialog* chatDialog)
539{
540 m_chatDialogList[chatroomName.toStdString()] = chatDialog;
Mengjin Yan391d7242014-08-28 20:51:55 -0700541 m_discoveryLogic.addLocalChatroom(*chatDialog->getChatroomInfo());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800542 connect(chatDialog, SIGNAL(closeChatDialog(const QString&)),
543 this, SLOT(onRemoveChatDialog(const QString&)));
544 connect(chatDialog, SIGNAL(showChatMessage(const QString&, const QString&, const QString&)),
545 this, SLOT(onShowChatMessage(const QString&, const QString&, const QString&)));
Yingdi Yu233a9722014-03-07 15:47:09 -0800546 connect(chatDialog, SIGNAL(resetIcon()),
547 this, SLOT(onResetIcon()));
Mengjin Yan391d7242014-08-28 20:51:55 -0700548 connect(chatDialog, SIGNAL(rosterChanged(const chronos::ChatroomInfo&)),
549 this, SLOT(onRosterChanged(const chronos::ChatroomInfo&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800550 connect(this, SIGNAL(localPrefixUpdated(const QString&)),
Yingdi Yud45777b2014-10-16 23:54:11 -0700551 chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
Yingdi Yubaaaec02014-09-02 22:05:32 -0700552 connect(this, SIGNAL(localPrefixConfigured(const QString&)),
Yingdi Yud45777b2014-10-16 23:54:11 -0700553 chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800554
555 QAction* chatAction = new QAction(chatroomName, this);
556 m_chatActionList[chatroomName.toStdString()] = chatAction;
Mengjin Yan391d7242014-08-28 20:51:55 -0700557 connect(chatAction, SIGNAL(triggered()),
Yingdi Yue8323b62014-09-02 17:24:15 -0700558 chatDialog, SLOT(onShow()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800559
560 QAction* closeAction = new QAction(chatroomName, this);
561 m_closeActionList[chatroomName.toStdString()] = closeAction;
Yingdi Yud45777b2014-10-16 23:54:11 -0700562 connect(closeAction, SIGNAL(triggered()),
563 chatDialog, SLOT(shutdown()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800564
565 updateMenu();
566}
567
Mengjin Yan391d7242014-08-28 20:51:55 -0700568void
569Controller::updateDiscoveryList(const ChatroomInfo& info, bool isAdd)
570{
571 emit discoverChatroomChanged(info, isAdd);
572}
573
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800574void
575Controller::onIdentityUpdated(const QString& identity)
576{
577 Name identityName(identity.toStdString());
578
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700579 while (!m_chatDialogList.empty()) {
580 ChatDialogList::const_iterator it = m_chatDialogList.begin();
581 onRemoveChatDialog(QString::fromStdString(it->first));
582 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800583
584 m_identity = identityName;
585 m_keyChain.createIdentity(m_identity);
Yingdi Yu233a9722014-03-07 15:47:09 -0800586 setInvitationListener();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800587
588 emit closeDBModule();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700589
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800590 QTimer::singleShot(500, this, SLOT(onIdentityUpdatedContinued()));
591
592}
593
594void
595Controller::onIdentityUpdatedContinued()
596{
597 QString connection = m_db.connectionName();
598 // _LOG_DEBUG("connection name: " << connection.toStdString());
599 QSqlDatabase::removeDatabase(connection);
600 m_db.close();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700601
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800602 openDB();
603
604 emit identityUpdated(QString(m_identity.toUri().c_str()));
605}
606
607void
608Controller::onContactIdListReady(const QStringList& list)
609{
610 ContactList contactList;
611
612 m_contactManager.getContactList(contactList);
613 m_validator.cleanTrustAnchor();
614
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700615 for (ContactList::const_iterator it = contactList.begin(); it != contactList.end(); it++)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800616 m_validator.addTrustAnchor((*it)->getPublicKeyName(), (*it)->getPublicKey());
617
618}
619
620void
621Controller::onNickUpdated(const QString& nick)
622{
623 m_nick = nick.toStdString();
624}
625
626void
627Controller::onLocalPrefixUpdated(const QString& localPrefix)
628{
Yingdi Yubaaaec02014-09-02 22:05:32 -0700629 QString privateLocalPrefix("/private/local");
630
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800631 m_localPrefix = Name(localPrefix.toStdString());
Yingdi Yubaaaec02014-09-02 22:05:32 -0700632
633 if (privateLocalPrefix != localPrefix)
634 m_localPrefixDetected = true;
635 else
636 m_localPrefixDetected = false;
637}
638
639void
640Controller::onLocalPrefixConfigured(const QString& prefix)
641{
642 if (!m_localPrefixDetected) {
643 m_localPrefix = Name(prefix.toStdString());
644 emit localPrefixConfigured(prefix);
645 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800646}
647
648void
649Controller::onStartChatAction()
650{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700651 string chatroom = "chatroom-" + getRandomString();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800652
653 m_startChatDialog->setChatroom(chatroom);
654 m_startChatDialog->show();
655 m_startChatDialog->raise();
656}
657
658void
Mengjin Yan391d7242014-08-28 20:51:55 -0700659Controller::onDiscoveryAction()
660{
661 m_discoveryLogic.sendDiscoveryInterest();
662
663 m_chatroomDiscoveryDialog->updateChatroomList();
664 m_chatroomDiscoveryDialog->show();
665 m_chatroomDiscoveryDialog->raise();
666}
667
668
669void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800670Controller::onSettingsAction()
671{
672 m_settingDialog->setNick(QString(m_nick.c_str()));
673 m_settingDialog->show();
674 m_settingDialog->raise();
675}
676
677void
678Controller::onProfileEditorAction()
679{
680 m_profileEditor->show();
681 m_profileEditor->raise();
682}
683
684void
685Controller::onAddContactAction()
686{
687 emit refreshBrowseContact();
688 m_browseContactDialog->show();
689 m_browseContactDialog->raise();
690}
691
692void
693Controller::onContactListAction()
694{
695 m_contactPanel->show();
696 m_contactPanel->raise();
697}
698
699void
700Controller::onDirectAdd()
701{
702 m_addContactPanel->show();
703 m_addContactPanel->raise();
704}
705
706void
707Controller::onUpdateLocalPrefixAction()
708{
709 // Name interestName();
Yingdi Yu106be862014-08-29 09:03:18 -0700710 Interest interest("/localhop/ndn-autoconf/routable-prefixes");
Yingdi Yua7876722014-03-25 14:46:55 -0700711 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800712 interest.setMustBeFresh(true);
713
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700714 m_face->expressInterest(interest,
715 bind(&Controller::onLocalPrefix, this, _1, _2),
716 bind(&Controller::onLocalPrefixTimeout, this, _1));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800717}
718
719void
720Controller::onMinimizeAction()
721{
722 m_settingDialog->hide();
723 m_startChatDialog->hide();
724 m_profileEditor->hide();
725 m_invitationDialog->hide();
726 m_addContactPanel->hide();
727
728 ChatDialogList::iterator it = m_chatDialogList.begin();
729 ChatDialogList::iterator end = m_chatDialogList.end();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700730 for (; it != end; it++)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800731 it->second->hide();
732}
733
734void
735Controller::onQuitAction()
736{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700737 while (!m_chatDialogList.empty()) {
738 ChatDialogList::const_iterator it = m_chatDialogList.begin();
Yingdi Yud45777b2014-10-16 23:54:11 -0700739 it->second->shutdown();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700740 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800741
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700742 if (m_invitationListenerId != 0)
Yingdi Yu233a9722014-03-07 15:47:09 -0800743 m_face->unsetInterestFilter(m_invitationListenerId);
744
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800745 delete m_settingDialog;
746 delete m_startChatDialog;
747 delete m_profileEditor;
748 delete m_invitationDialog;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700749 delete m_browseContactDialog;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800750 delete m_addContactPanel;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700751
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700752 m_face->getIoService().stop();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800753
754 QApplication::quit();
755}
756
757void
758Controller::onStartChatroom(const QString& chatroomName, bool secured)
759{
760 Name chatroomPrefix;
761 chatroomPrefix.append("ndn")
762 .append("broadcast")
763 .append("ChronoChat")
764 .append(chatroomName.toStdString());
765
766 // check if the chatroom exists
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700767 if (m_chatDialogList.find(chatroomName.toStdString()) != m_chatDialogList.end()) {
768 QMessageBox::information(this, tr("ChronoChat"),
769 tr("You are creating an existing chatroom."
770 "You can check it in the context memu."));
771 return;
772 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800773
Mengjin Yan391d7242014-08-28 20:51:55 -0700774 // TODO: We should create a chatroom specific key/cert
775 //(which should be created in the first half of this method
776 //, but let's use the default one for now.
777 // std::cout << "start chat room localprefix: " << m_localPrefix.toUri() << std::endl;
778 shared_ptr<IdentityCertificate> idCert
779 = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
Yingdi Yud45777b2014-10-16 23:54:11 -0700780
781 Name chatPrefix;
782 chatPrefix.append(m_identity).append("CHRONOCHAT-DATA").append(chatroomName.toStdString());
783
Mengjin Yan391d7242014-08-28 20:51:55 -0700784 ChatDialog* chatDialog
Yingdi Yud45777b2014-10-16 23:54:11 -0700785 = new ChatDialog(chatroomPrefix,
786 chatPrefix,
787 m_localPrefix,
788 chatroomName.toStdString(),
789 m_nick);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800790
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700791 addChatDialog(chatroomName, chatDialog);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800792 chatDialog->show();
793}
794
795void
Mengjin Yan391d7242014-08-28 20:51:55 -0700796Controller::onInvitationResponded(const ndn::Name& invitationName, bool accepted)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800797{
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700798 shared_ptr<Data> response = make_shared<Data>();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800799 shared_ptr<IdentityCertificate> chatroomCert;
800
801 // generate reply;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700802 if (accepted) {
803 Name responseName = invitationName;
804 responseName.append(m_localPrefix.wireEncode());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800805
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700806 response->setName(responseName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800807
Mengjin Yan391d7242014-08-28 20:51:55 -0700808 // We should create a particular certificate for this chatroom,
809 //but let's use default one for now.
810 chatroomCert
811 = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800812
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700813 response->setContent(chatroomCert->wireEncode());
814 response->setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700815 }
816 else {
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700817 response->setName(invitationName);
818 response->setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700819 }
820
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700821 m_keyChain.signByIdentity(*response, m_identity);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700822
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800823 // Check if we need a wrapper
824 Name invitationRoutingPrefix = getInvitationRoutingPrefix();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700825 if (invitationRoutingPrefix.isPrefixOf(m_identity))
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700826 m_face->put(*response);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700827 else {
828 Name wrappedName;
829 wrappedName.append(invitationRoutingPrefix)
830 .append(ROUTING_PREFIX_SEPARATOR, 2)
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700831 .append(response->getName());
Yingdi Yu233a9722014-03-07 15:47:09 -0800832
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700833 // _LOG_DEBUG("onInvitationResponded: prepare reply " << wrappedName);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700834
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700835 shared_ptr<Data> wrappedData = make_shared<Data>(wrappedName);
836 wrappedData->setContent(response->wireEncode());
837 wrappedData->setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800838
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700839 m_keyChain.signByIdentity(*wrappedData, m_identity);
840 m_face->put(*wrappedData);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700841 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800842
843 // create chatroom
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700844 if (accepted) {
845 Invitation invitation(invitationName);
846 Name chatroomPrefix;
847 chatroomPrefix.append("ndn")
848 .append("broadcast")
849 .append("ChronoChat")
850 .append(invitation.getChatroom());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800851
Mengjin Yan391d7242014-08-28 20:51:55 -0700852 //We should create a chatroom specific key/cert
853 //(which should be created in the first half of this method,
854 //but let's use the default one for now.
855 shared_ptr<IdentityCertificate> idCert
856 = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
Yingdi Yud45777b2014-10-16 23:54:11 -0700857
858 Name chatPrefix;
859 chatPrefix.append(m_identity).append("CHRONOCHAT-DATA").append(invitation.getChatroom());
860
Mengjin Yan391d7242014-08-28 20:51:55 -0700861 ChatDialog* chatDialog
Yingdi Yud45777b2014-10-16 23:54:11 -0700862 = new ChatDialog(chatroomPrefix,
863 chatPrefix,
864 m_localPrefix,
865 invitation.getChatroom(),
866 m_nick,
867 true);
868
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700869 chatDialog->addSyncAnchor(invitation);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800870
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700871 addChatDialog(QString::fromStdString(invitation.getChatroom()), chatDialog);
872 chatDialog->show();
873 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800874}
875
876void
877Controller::onShowChatMessage(const QString& chatroomName, const QString& from, const QString& data)
878{
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700879 m_trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(chatroomName),
880 QString("<%1>: %2").arg(from).arg(data),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800881 QSystemTrayIcon::Information, 20000);
882 m_trayIcon->setIcon(QIcon(":/images/note.png"));
883}
884
885void
Yingdi Yu233a9722014-03-07 15:47:09 -0800886Controller::onResetIcon()
887{
888 m_trayIcon->setIcon(QIcon(":/images/icon_small.png"));
889}
890
891void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800892Controller::onRemoveChatDialog(const QString& chatroomName)
893{
894 ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString());
895
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700896 if (it != m_chatDialogList.end()) {
897 ChatDialog* deletedChat = it->second;
898 if (deletedChat)
899 delete deletedChat;
900 m_chatDialogList.erase(it);
Mengjin Yan391d7242014-08-28 20:51:55 -0700901 m_discoveryLogic.removeLocalChatroom(Name::Component(chatroomName.toStdString()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800902
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700903 QAction* chatAction = m_chatActionList[chatroomName.toStdString()];
904 QAction* closeAction = m_closeActionList[chatroomName.toStdString()];
905 if (chatAction)
906 delete chatAction;
907 if (closeAction)
908 delete closeAction;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700909
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700910 m_chatActionList.erase(chatroomName.toStdString());
911 m_closeActionList.erase(chatroomName.toStdString());
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700912
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700913 updateMenu();
914 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800915}
916
917void
918Controller::onWarning(const QString& msg)
919{
920 QMessageBox::information(this, tr("ChronoChat"), msg);
921}
922
923void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700924Controller::onError(const QString& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800925{
926 QMessageBox::critical(this, tr("ChronoChat"), msg, QMessageBox::Ok);
927 exit(1);
928}
929
Yingdi Yu233a9722014-03-07 15:47:09 -0800930void
Mengjin Yan391d7242014-08-28 20:51:55 -0700931Controller::onInvitationInterest(const ndn::Name& prefix,
932 const ndn::Interest& interest,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700933 size_t routingPrefixOffset)
Yingdi Yu233a9722014-03-07 15:47:09 -0800934{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700935 // _LOG_DEBUG("onInvitationInterest: " << interest.getName());
936 shared_ptr<Interest> invitationInterest =
937 make_shared<Interest>(boost::cref(interest.getName().getSubName(routingPrefixOffset)));
Yingdi Yu233a9722014-03-07 15:47:09 -0800938
939 // check if the chatroom already exists;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700940 try {
Yingdi Yu233a9722014-03-07 15:47:09 -0800941 Invitation invitation(invitationInterest->getName());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700942 if (m_chatDialogList.find(invitation.getChatroom()) != m_chatDialogList.end())
Yingdi Yu233a9722014-03-07 15:47:09 -0800943 return;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700944 }
945 catch (Invitation::Error& e) {
946 // Cannot parse the invitation;
947 return;
948 }
Yingdi Yu233a9722014-03-07 15:47:09 -0800949
950 OnInterestValidated onValidated = bind(&Controller::onInvitationValidated, this, _1);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700951 OnInterestValidationFailed onValidationFailed = bind(&Controller::onInvitationValidationFailed,
952 this, _1, _2);
Yingdi Yu233a9722014-03-07 15:47:09 -0800953 m_validator.validate(*invitationInterest, onValidated, onValidationFailed);
954}
955
Mengjin Yan391d7242014-08-28 20:51:55 -0700956void
957Controller::onRosterChanged(const chronos::ChatroomInfo& info)
958{
959 m_discoveryLogic.addLocalChatroom(info);
960}
961
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800962} // namespace chronos
963
964#if WAF
965#include "controller.moc"
Yingdi Yu42125862014-08-07 17:04:28 -0700966// #include "controller.cpp.moc"
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800967#endif