blob: d99b7a66c98c4f9c9295f37f20c9b1ceb1b149d1 [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 Yu0b0a7362014-08-05 16:31:30 -070022#include "cryptopp.hpp"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080023#include "config.pb.h"
24#include "endorse-info.pb.h"
25#include "logging.h"
26#endif
27
Yingdi Yu0b0a7362014-08-05 16:31:30 -070028// INIT_LOGGER("chronos.Controller");
Yingdi Yu348f5ea2014-03-01 14:47:25 -080029
30Q_DECLARE_METATYPE(ndn::Name)
31Q_DECLARE_METATYPE(ndn::IdentityCertificate)
Yingdi Yu0b0a7362014-08-05 16:31:30 -070032Q_DECLARE_METATYPE(Chronos::EndorseInfo)
Yingdi Yu233a9722014-03-07 15:47:09 -080033Q_DECLARE_METATYPE(ndn::Interest)
34Q_DECLARE_METATYPE(size_t)
Mengjin Yan391d7242014-08-28 20:51:55 -070035Q_DECLARE_METATYPE(chronos::ChatroomInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080036
37namespace chronos {
38
Yingdi Yu0b0a7362014-08-05 16:31:30 -070039using std::string;
40
41using ndn::Face;
42using ndn::IdentityCertificate;
43using ndn::OnInterestValidated;
44using ndn::OnInterestValidationFailed;
Yingdi Yu17032f82014-03-25 15:48:23 -070045
Yingdi Yu348f5ea2014-03-01 14:47:25 -080046static const uint8_t ROUTING_PREFIX_SEPARATOR[2] = {0xF0, 0x2E};
47
48// constructor & destructor
49Controller::Controller(shared_ptr<Face> face,
Yingdi Yufa0b6a02014-04-30 14:26:42 -070050 QWidget* parent)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080051 : QDialog(parent)
52 , m_face(face)
Yingdi Yubaaaec02014-09-02 22:05:32 -070053 , m_localPrefixDetected(false)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080054 , m_invitationListenerId(0)
55 , m_contactManager(m_face)
Mengjin Yan391d7242014-08-28 20:51:55 -070056 , m_discoveryLogic(m_face,
57 bind(&Controller::updateDiscoveryList, this, _1, _2))
Yingdi Yu348f5ea2014-03-01 14:47:25 -080058 , m_settingDialog(new SettingDialog)
59 , m_startChatDialog(new StartChatDialog)
60 , m_profileEditor(new ProfileEditor)
61 , m_invitationDialog(new InvitationDialog)
62 , m_contactPanel(new ContactPanel)
63 , m_browseContactDialog(new BrowseContactDialog)
64 , m_addContactPanel(new AddContactPanel)
Mengjin Yan391d7242014-08-28 20:51:55 -070065 , m_chatroomDiscoveryDialog(new ChatroomDiscoveryDialog)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080066{
67 qRegisterMetaType<ndn::Name>("ndn.Name");
68 qRegisterMetaType<ndn::IdentityCertificate>("ndn.IdentityCertificate");
Yingdi Yu0b0a7362014-08-05 16:31:30 -070069 qRegisterMetaType<Chronos::EndorseInfo>("Chronos.EndorseInfo");
Yingdi Yu233a9722014-03-07 15:47:09 -080070 qRegisterMetaType<ndn::Interest>("ndn.Interest");
71 qRegisterMetaType<size_t>("size_t");
Mengjin Yan391d7242014-08-28 20:51:55 -070072 qRegisterMetaType<chronos::ChatroomInfo>("chronos.Chatroom");
Yingdi Yu348f5ea2014-03-01 14:47:25 -080073
74 connect(this, SIGNAL(localPrefixUpdated(const QString&)),
75 this, SLOT(onLocalPrefixUpdated(const QString&)));
Yingdi Yu233a9722014-03-07 15:47:09 -080076 connect(this, SIGNAL(invitationInterest(const ndn::Name&, const ndn::Interest&, size_t)),
77 this, SLOT(onInvitationInterest(const ndn::Name&, const ndn::Interest&, size_t)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -080078
79 // Connection to ContactManager
80 connect(this, SIGNAL(identityUpdated(const QString&)),
81 &m_contactManager, SLOT(onIdentityUpdated(const QString&)));
82 connect(&m_contactManager, SIGNAL(warning(const QString&)),
83 this, SLOT(onWarning(const QString&)));
84 connect(this, SIGNAL(refreshBrowseContact()),
85 &m_contactManager, SLOT(onRefreshBrowseContact()));
86 connect(&m_contactManager, SIGNAL(contactInfoFetchFailed(const QString&)),
87 this, SLOT(onWarning(const QString&)));
88 connect(&m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
89 this, SLOT(onContactIdListReady(const QStringList&)));
90
91 // Connection to SettingDialog
92 connect(this, SIGNAL(identityUpdated(const QString&)),
93 m_settingDialog, SLOT(onIdentityUpdated(const QString&)));
94 connect(m_settingDialog, SIGNAL(identityUpdated(const QString&)),
95 this, SLOT(onIdentityUpdated(const QString&)));
96 connect(m_settingDialog, SIGNAL(nickUpdated(const QString&)),
97 this, SLOT(onNickUpdated(const QString&)));
Yingdi Yubaaaec02014-09-02 22:05:32 -070098 connect(this, SIGNAL(localPrefixUpdated(const QString&)),
99 m_settingDialog, SLOT(onLocalPrefixUpdated(const QString&)));
100 connect(m_settingDialog, SIGNAL(prefixUpdated(const QString&)),
101 this, SLOT(onLocalPrefixConfigured(const QString&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800102
103 // Connection to ProfileEditor
104 connect(this, SIGNAL(closeDBModule()),
105 m_profileEditor, SLOT(onCloseDBModule()));
106 connect(this, SIGNAL(identityUpdated(const QString&)),
107 m_profileEditor, SLOT(onIdentityUpdated(const QString&)));
108 connect(m_profileEditor, SIGNAL(updateProfile()),
109 &m_contactManager, SLOT(onUpdateProfile()));
110
111 // Connection to StartChatDialog
112 connect(m_startChatDialog, SIGNAL(startChatroom(const QString&, bool)),
113 this, SLOT(onStartChatroom(const QString&, bool)));
114
115 // Connection to InvitationDialog
116 connect(m_invitationDialog, SIGNAL(invitationResponded(const ndn::Name&, bool)),
117 this, SLOT(onInvitationResponded(const ndn::Name&, bool)));
118
119 // Connection to AddContactPanel
120 connect(m_addContactPanel, SIGNAL(fetchInfo(const QString&)),
121 &m_contactManager, SLOT(onFetchContactInfo(const QString&)));
122 connect(m_addContactPanel, SIGNAL(addContact(const QString&)),
123 &m_contactManager, SLOT(onAddFetchedContact(const QString&)));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700124 connect(&m_contactManager, SIGNAL(contactEndorseInfoReady(const Chronos::EndorseInfo&)),
125 m_addContactPanel, SLOT(onContactEndorseInfoReady(const Chronos::EndorseInfo&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800126
127
128 // Connection to BrowseContactDialog
129 connect(m_browseContactDialog, SIGNAL(directAddClicked()),
130 this, SLOT(onDirectAdd()));
131 connect(m_browseContactDialog, SIGNAL(fetchIdCert(const QString&)),
132 &m_contactManager, SLOT(onFetchIdCert(const QString&)));
133 connect(m_browseContactDialog, SIGNAL(addContact(const QString&)),
134 &m_contactManager, SLOT(onAddFetchedContactIdCert(const QString&)));
135 connect(&m_contactManager, SIGNAL(idCertNameListReady(const QStringList&)),
136 m_browseContactDialog, SLOT(onIdCertNameListReady(const QStringList&)));
137 connect(&m_contactManager, SIGNAL(nameListReady(const QStringList&)),
138 m_browseContactDialog, SLOT(onNameListReady(const QStringList&)));
139 connect(&m_contactManager, SIGNAL(idCertReady(const ndn::IdentityCertificate&)),
140 m_browseContactDialog, SLOT(onIdCertReady(const ndn::IdentityCertificate&)));
141
142 // Connection to ContactPanel
143 connect(m_contactPanel, SIGNAL(waitForContactList()),
144 &m_contactManager, SLOT(onWaitForContactList()));
145 connect(m_contactPanel, SIGNAL(waitForContactInfo(const QString&)),
146 &m_contactManager, SLOT(onWaitForContactInfo(const QString&)));
147 connect(m_contactPanel, SIGNAL(removeContact(const QString&)),
148 &m_contactManager, SLOT(onRemoveContact(const QString&)));
149 connect(m_contactPanel, SIGNAL(updateAlias(const QString&, const QString&)),
150 &m_contactManager, SLOT(onUpdateAlias(const QString&, const QString&)));
151 connect(m_contactPanel, SIGNAL(updateIsIntroducer(const QString&, bool)),
152 &m_contactManager, SLOT(onUpdateIsIntroducer(const QString&, bool)));
153 connect(m_contactPanel, SIGNAL(updateEndorseCertificate(const QString&)),
154 &m_contactManager, SLOT(onUpdateEndorseCertificate(const QString&)));
155 connect(m_contactPanel, SIGNAL(warning(const QString&)),
156 this, SLOT(onWarning(const QString&)));
157 connect(this, SIGNAL(closeDBModule()),
158 m_contactPanel, SLOT(onCloseDBModule()));
159 connect(this, SIGNAL(identityUpdated(const QString&)),
160 m_contactPanel, SLOT(onIdentityUpdated(const QString&)));
161 connect(&m_contactManager, SIGNAL(contactAliasListReady(const QStringList&)),
162 m_contactPanel, SLOT(onContactAliasListReady(const QStringList&)));
163 connect(&m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
164 m_contactPanel, SLOT(onContactIdListReady(const QStringList&)));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700165 connect(&m_contactManager, SIGNAL(contactInfoReady(const QString&, const QString&,
166 const QString&, bool)),
167 m_contactPanel, SLOT(onContactInfoReady(const QString&, const QString&,
168 const QString&, bool)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800169
Mengjin Yan391d7242014-08-28 20:51:55 -0700170 // Connection to DiscoveryDialog
171 connect(this,
172 SIGNAL(discoverChatroomChanged(const chronos::ChatroomInfo&, bool)),
173 m_chatroomDiscoveryDialog,
174 SLOT(onDiscoverChatroomChanged(const chronos::ChatroomInfo&, bool)));
175 connect(m_chatroomDiscoveryDialog, SIGNAL(startChatroom(const QString&, bool)),
176 this, SLOT(onStartChatroom(const QString&, bool)));
177
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800178 initialize();
179
Yingdi Yu233a9722014-03-07 15:47:09 -0800180 createTrayIcon();
181
182 onUpdateLocalPrefixAction();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800183}
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700184
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800185Controller::~Controller()
186{
187 saveConf();
188}
189
190// public methods
191
192
193// private methods
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700194string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800195Controller::getDBName()
196{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700197 string dbName("chronos-");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800198
199 std::stringstream ss;
200 {
201 using namespace CryptoPP;
202
203 SHA256 hash;
204 StringSource(m_identity.wireEncode().wire(), m_identity.wireEncode().size(), true,
205 new HashFilter(hash, new HexEncoder(new FileSink(ss), false)));
206 }
207 dbName.append(ss.str()).append(".db");
208
209 return dbName;
210}
211
212void
213Controller::openDB()
214{
215 m_db = QSqlDatabase::addDatabase("QSQLITE");
216 QString path = (QDir::home().path());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700217 path.append(QDir::separator())
218 .append(".chronos")
219 .append(QDir::separator())
220 .append(getDBName().c_str());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800221 m_db.setDatabaseName(path);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800222
Yingdi Yu42125862014-08-07 17:04:28 -0700223 m_db.open();
224
225 // bool ok = m_db.open();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700226 // _LOG_DEBUG("DB opened: " << std::boolalpha << ok );
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800227}
228
229void
230Controller::initialize()
231{
232 loadConf();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700233
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800234 m_keyChain.createIdentity(m_identity);
235
236 openDB();
237
238 emit identityUpdated(QString(m_identity.toUri().c_str()));
239
240 setInvitationListener();
Mengjin Yan391d7242014-08-28 20:51:55 -0700241
242 m_discoveryLogic.sendDiscoveryInterest();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800243}
244
245void
246Controller::setInvitationListener()
247{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700248 if (m_invitationListenerId != 0)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800249 m_face->unsetInterestFilter(m_invitationListenerId);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700250
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800251 Name invitationPrefix;
252 Name routingPrefix = getInvitationRoutingPrefix();
253 size_t offset = 0;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700254 if (!routingPrefix.isPrefixOf(m_identity)) {
255 invitationPrefix.append(routingPrefix).append(ROUTING_PREFIX_SEPARATOR, 2);
256 offset = routingPrefix.size() + 1;
257 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800258 invitationPrefix.append(m_identity).append("CHRONOCHAT-INVITATION");
259
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700260 m_invitationListenerId = m_face->setInterestFilter(invitationPrefix,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700261 bind(&Controller::onInvitationInterestWrapper,
262 this, _1, _2, offset),
263 bind(&Controller::onInvitationRegisterFailed,
264 this, _1, _2));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800265}
266
267void
268Controller::loadConf()
269{
270 namespace fs = boost::filesystem;
271
272 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
273 fs::create_directories (chronosDir);
274
275 std::ifstream is((chronosDir / "config").c_str ());
276 ChronoChat::Conf conf;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700277 if (conf.ParseFromIstream(&is)) {
278 m_identity.clear();
279 m_identity.append(conf.identity());
280 if (conf.has_nick())
281 m_nick = conf.nick();
282 else
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800283 m_nick = m_identity.get(-1).toUri();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700284 }
285 else {
286 m_identity.clear();
287 // TODO: change below to system default;
288 m_identity.append("chronochat-tmp-identity")
289 .append(getRandomString());
290
291 m_nick = m_identity.get(-1).toUri();
292 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800293}
294
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700295void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800296Controller::saveConf()
297{
298 namespace fs = boost::filesystem;
299
300 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
301 fs::create_directories (chronosDir);
302
303 std::ofstream os((chronosDir / "config").c_str ());
304 ChronoChat::Conf conf;
305 conf.set_identity(m_identity.toUri());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700306 if (!m_nick.empty())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800307 conf.set_nick(m_nick);
308 conf.SerializeToOstream(&os);
309
310 os.close();
311}
312
313void
314Controller::createActions()
315{
316 m_startChatroom = new QAction(tr("Start new chat"), this);
317 connect(m_startChatroom, SIGNAL(triggered()), this, SLOT(onStartChatAction()));
318
Mengjin Yan391d7242014-08-28 20:51:55 -0700319 m_discoveryAction = new QAction(tr("Ongoing Chatrooms"), this);
320 connect(m_discoveryAction, SIGNAL(triggered()), this, SLOT(onDiscoveryAction()));
321
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800322 m_settingsAction = new QAction(tr("Settings"), this);
323 connect(m_settingsAction, SIGNAL(triggered()), this, SLOT(onSettingsAction()));
324
325 m_editProfileAction = new QAction(tr("Edit profile"), this);
326 connect(m_editProfileAction, SIGNAL(triggered()), this, SLOT(onProfileEditorAction()));
327
328 m_contactListAction = new QAction(tr("Contact List"), this);
329 connect(m_contactListAction, SIGNAL(triggered()), this, SLOT(onContactListAction()));
330
331 m_addContactAction = new QAction(tr("Add contact"), this);
332 connect(m_addContactAction, SIGNAL(triggered()), this, SLOT(onAddContactAction()));
333
334 m_updateLocalPrefixAction = new QAction(tr("Update local prefix"), this);
335 connect(m_updateLocalPrefixAction, SIGNAL(triggered()), this, SLOT(onUpdateLocalPrefixAction()));
336
337 m_minimizeAction = new QAction(tr("Mi&nimize"), this);
338 connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(onMinimizeAction()));
339
340 m_quitAction = new QAction(tr("Quit"), this);
341 connect(m_quitAction, SIGNAL(triggered()), this, SLOT(onQuitAction()));
Mengjin Yan391d7242014-08-28 20:51:55 -0700342
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800343}
344
345void
346Controller::createTrayIcon()
347{
348 createActions();
349
350 m_trayIconMenu = new QMenu(this);
351 m_trayIconMenu->addAction(m_startChatroom);
Mengjin Yan391d7242014-08-28 20:51:55 -0700352 m_trayIconMenu->addAction(m_discoveryAction);
353
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800354 m_trayIconMenu->addSeparator();
355 m_trayIconMenu->addAction(m_settingsAction);
356 m_trayIconMenu->addAction(m_editProfileAction);
357 m_trayIconMenu->addSeparator();
358 m_trayIconMenu->addAction(m_contactListAction);
359 m_trayIconMenu->addAction(m_addContactAction);
360 m_trayIconMenu->addSeparator();
361 m_trayIconMenu->addAction(m_updateLocalPrefixAction);
362 m_trayIconMenu->addSeparator();
363 m_trayIconMenu->addAction(m_minimizeAction);
364 m_closeMenu = m_trayIconMenu->addMenu("Close chatroom");
365 m_closeMenu->setEnabled(false);
366 m_trayIconMenu->addSeparator();
367 m_trayIconMenu->addAction(m_quitAction);
368
369 m_trayIcon = new QSystemTrayIcon(this);
370 m_trayIcon->setContextMenu(m_trayIconMenu);
371
372 m_trayIcon->setIcon(QIcon(":/images/icon_small.png"));
373 m_trayIcon->setToolTip("ChronoChat System Tray Icon");
374 m_trayIcon->setVisible(true);
375}
376
377void
378Controller::updateMenu()
379{
380 QMenu* menu = new QMenu(this);
381 QMenu* closeMenu = 0;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700382
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800383 menu->addAction(m_startChatroom);
Mengjin Yan391d7242014-08-28 20:51:55 -0700384 menu->addAction(m_discoveryAction);
385
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800386 menu->addSeparator();
387 menu->addAction(m_settingsAction);
388 menu->addAction(m_editProfileAction);
389 menu->addSeparator();
Yingdi Yu233a9722014-03-07 15:47:09 -0800390 menu->addAction(m_contactListAction);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800391 menu->addAction(m_addContactAction);
392 menu->addSeparator();
393 {
394 ChatActionList::const_iterator it = m_chatActionList.begin();
395 ChatActionList::const_iterator end = m_chatActionList.end();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700396 if (it != end) {
397 for (; it != end; it++)
398 menu->addAction(it->second);
399 menu->addSeparator();
400 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800401 }
402 menu->addAction(m_updateLocalPrefixAction);
403 menu->addSeparator();
404 menu->addAction(m_minimizeAction);
405 closeMenu = menu->addMenu("Close chatroom");
406 {
407 ChatActionList::const_iterator it = m_closeActionList.begin();
408 ChatActionList::const_iterator end = m_closeActionList.end();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700409 if (it == end)
410 closeMenu->setEnabled(false);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800411 else
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700412 for (; it != end; it++)
413 closeMenu->addAction(it->second);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800414 }
415 menu->addSeparator();
416 menu->addAction(m_quitAction);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700417
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800418 m_trayIcon->setContextMenu(menu);
419 delete m_trayIconMenu;
420 m_trayIconMenu = menu;
421 m_closeMenu = closeMenu;
422}
423
424void
425Controller::onLocalPrefix(const Interest& interest, Data& data)
426{
Yingdi Yu106be862014-08-29 09:03:18 -0700427 QString localPrefixStr("/private/local");
428 Name prefix;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800429
Yingdi Yu106be862014-08-29 09:03:18 -0700430 Block contentBlock = data.getContent();
431 try {
432 contentBlock.parse();
433
434 for (Block::element_const_iterator it = contentBlock.elements_begin();
435 it != contentBlock.elements_end(); it++) {
436 Name candidate;
437 candidate.wireDecode(*it);
438 if (candidate.isPrefixOf(m_identity)) {
439 prefix = candidate;
440 break;
441 }
442 }
443
444 if (prefix.empty()) {
445 if (contentBlock.elements_begin() != contentBlock.elements_end())
446 prefix.wireDecode(*contentBlock.elements_begin());
447 else
448 prefix = Name("/private/local");
449 }
450
451 localPrefixStr = QString::fromStdString(prefix.toUri());
452 }
453 catch (Block::Error& e) {
454 prefix = Name("/private/local");
455 }
456
457 if (m_localPrefix.empty() || m_localPrefix != prefix) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800458 emit localPrefixUpdated(localPrefixStr);
Mengjin Yan391d7242014-08-28 20:51:55 -0700459 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800460}
461
462void
463Controller::onLocalPrefixTimeout(const Interest& interest)
464{
465 QString localPrefixStr("/private/local");
466
467 Name localPrefix(localPrefixStr.toStdString());
Mengjin Yan391d7242014-08-28 20:51:55 -0700468 if (m_localPrefix.empty() || m_localPrefix != localPrefix) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800469 emit localPrefixUpdated(localPrefixStr);
Mengjin Yan391d7242014-08-28 20:51:55 -0700470 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800471}
472
473void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700474Controller::onInvitationInterestWrapper(const Name& prefix,
475 const Interest& interest,
476 size_t routingPrefixOffset)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800477{
Yingdi Yu233a9722014-03-07 15:47:09 -0800478 emit invitationInterest(prefix, interest, routingPrefixOffset);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800479}
480
481void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700482Controller::onInvitationRegisterFailed(const Name& prefix, const string& failInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800483{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700484 // _LOG_DEBUG("Controller::onInvitationRegisterFailed: " << failInfo);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800485}
486
487void
488Controller::onInvitationValidated(const shared_ptr<const Interest>& interest)
489{
490 Invitation invitation(interest->getName());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700491 // Should be obtained via a method of ContactManager.
492 string alias = invitation.getInviterCertificate().getPublicKeyName().getPrefix(-1).toUri();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800493
494 m_invitationDialog->setInvitation(alias, invitation.getChatroom(), interest->getName());
495 m_invitationDialog->show();
496}
497
498void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700499Controller::onInvitationValidationFailed(const shared_ptr<const Interest>& interest,
500 string failureInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800501{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700502 // _LOG_DEBUG("Invitation: " << interest->getName() <<
503 // " cannot not be validated due to: " << failureInfo);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800504}
505
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700506string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800507Controller::getRandomString()
508{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700509 uint32_t r = ndn::random::generateWord32();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800510 std::stringstream ss;
511 {
512 using namespace CryptoPP;
513 StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
514 new HexEncoder(new FileSink(ss), false));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700515
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800516 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700517 // for (int i = 0; i < 8; i++)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800518 // {
519 // uint32_t t = r & mask;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700520 // if (t < 10)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800521 // ss << static_cast<char>(t + 0x30);
522 // else
523 // ss << static_cast<char>(t + 0x57);
524 // r = r >> 4;
525 // }
526
527 return ss.str();
528}
529
530ndn::Name
531Controller::getInvitationRoutingPrefix()
532{
533 return Name("/ndn/broadcast");
534}
535
536void
537Controller::addChatDialog(const QString& chatroomName, ChatDialog* chatDialog)
538{
539 m_chatDialogList[chatroomName.toStdString()] = chatDialog;
Mengjin Yan391d7242014-08-28 20:51:55 -0700540 m_discoveryLogic.addLocalChatroom(*chatDialog->getChatroomInfo());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800541 connect(chatDialog, SIGNAL(closeChatDialog(const QString&)),
542 this, SLOT(onRemoveChatDialog(const QString&)));
543 connect(chatDialog, SIGNAL(showChatMessage(const QString&, const QString&, const QString&)),
544 this, SLOT(onShowChatMessage(const QString&, const QString&, const QString&)));
Yingdi Yu233a9722014-03-07 15:47:09 -0800545 connect(chatDialog, SIGNAL(resetIcon()),
546 this, SLOT(onResetIcon()));
Mengjin Yan391d7242014-08-28 20:51:55 -0700547 connect(chatDialog, SIGNAL(rosterChanged(const chronos::ChatroomInfo&)),
548 this, SLOT(onRosterChanged(const chronos::ChatroomInfo&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800549 connect(this, SIGNAL(localPrefixUpdated(const QString&)),
550 chatDialog, SLOT(onLocalPrefixUpdated(const QString&)));
Yingdi Yubaaaec02014-09-02 22:05:32 -0700551 connect(this, SIGNAL(localPrefixConfigured(const QString&)),
552 chatDialog, SLOT(onLocalPrefixUpdated(const QString&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800553
554 QAction* chatAction = new QAction(chatroomName, this);
555 m_chatActionList[chatroomName.toStdString()] = chatAction;
Mengjin Yan391d7242014-08-28 20:51:55 -0700556 connect(chatAction, SIGNAL(triggered()),
Yingdi Yue8323b62014-09-02 17:24:15 -0700557 chatDialog, SLOT(onShow()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800558
559 QAction* closeAction = new QAction(chatroomName, this);
560 m_closeActionList[chatroomName.toStdString()] = closeAction;
561 connect(closeAction, SIGNAL(triggered()), chatDialog, SLOT(onClose()));
562
563 updateMenu();
564}
565
Mengjin Yan391d7242014-08-28 20:51:55 -0700566void
567Controller::updateDiscoveryList(const ChatroomInfo& info, bool isAdd)
568{
569 emit discoverChatroomChanged(info, isAdd);
570}
571
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800572void
573Controller::onIdentityUpdated(const QString& identity)
574{
575 Name identityName(identity.toStdString());
576
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700577 while (!m_chatDialogList.empty()) {
578 ChatDialogList::const_iterator it = m_chatDialogList.begin();
579 onRemoveChatDialog(QString::fromStdString(it->first));
580 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800581
582 m_identity = identityName;
583 m_keyChain.createIdentity(m_identity);
Yingdi Yu233a9722014-03-07 15:47:09 -0800584 setInvitationListener();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800585
586 emit closeDBModule();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700587
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800588 QTimer::singleShot(500, this, SLOT(onIdentityUpdatedContinued()));
589
590}
591
592void
593Controller::onIdentityUpdatedContinued()
594{
595 QString connection = m_db.connectionName();
596 // _LOG_DEBUG("connection name: " << connection.toStdString());
597 QSqlDatabase::removeDatabase(connection);
598 m_db.close();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700599
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800600 openDB();
601
602 emit identityUpdated(QString(m_identity.toUri().c_str()));
603}
604
605void
606Controller::onContactIdListReady(const QStringList& list)
607{
608 ContactList contactList;
609
610 m_contactManager.getContactList(contactList);
611 m_validator.cleanTrustAnchor();
612
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700613 for (ContactList::const_iterator it = contactList.begin(); it != contactList.end(); it++)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800614 m_validator.addTrustAnchor((*it)->getPublicKeyName(), (*it)->getPublicKey());
615
616}
617
618void
619Controller::onNickUpdated(const QString& nick)
620{
621 m_nick = nick.toStdString();
622}
623
624void
625Controller::onLocalPrefixUpdated(const QString& localPrefix)
626{
Yingdi Yubaaaec02014-09-02 22:05:32 -0700627 QString privateLocalPrefix("/private/local");
628
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800629 m_localPrefix = Name(localPrefix.toStdString());
Yingdi Yubaaaec02014-09-02 22:05:32 -0700630
631 if (privateLocalPrefix != localPrefix)
632 m_localPrefixDetected = true;
633 else
634 m_localPrefixDetected = false;
635}
636
637void
638Controller::onLocalPrefixConfigured(const QString& prefix)
639{
640 if (!m_localPrefixDetected) {
641 m_localPrefix = Name(prefix.toStdString());
642 emit localPrefixConfigured(prefix);
643 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800644}
645
646void
647Controller::onStartChatAction()
648{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700649 string chatroom = "chatroom-" + getRandomString();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800650
651 m_startChatDialog->setChatroom(chatroom);
652 m_startChatDialog->show();
653 m_startChatDialog->raise();
654}
655
656void
Mengjin Yan391d7242014-08-28 20:51:55 -0700657Controller::onDiscoveryAction()
658{
659 m_discoveryLogic.sendDiscoveryInterest();
660
661 m_chatroomDiscoveryDialog->updateChatroomList();
662 m_chatroomDiscoveryDialog->show();
663 m_chatroomDiscoveryDialog->raise();
664}
665
666
667void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800668Controller::onSettingsAction()
669{
670 m_settingDialog->setNick(QString(m_nick.c_str()));
671 m_settingDialog->show();
672 m_settingDialog->raise();
673}
674
675void
676Controller::onProfileEditorAction()
677{
678 m_profileEditor->show();
679 m_profileEditor->raise();
680}
681
682void
683Controller::onAddContactAction()
684{
685 emit refreshBrowseContact();
686 m_browseContactDialog->show();
687 m_browseContactDialog->raise();
688}
689
690void
691Controller::onContactListAction()
692{
693 m_contactPanel->show();
694 m_contactPanel->raise();
695}
696
697void
698Controller::onDirectAdd()
699{
700 m_addContactPanel->show();
701 m_addContactPanel->raise();
702}
703
704void
705Controller::onUpdateLocalPrefixAction()
706{
707 // Name interestName();
Yingdi Yu106be862014-08-29 09:03:18 -0700708 Interest interest("/localhop/ndn-autoconf/routable-prefixes");
Yingdi Yua7876722014-03-25 14:46:55 -0700709 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800710 interest.setMustBeFresh(true);
711
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700712 m_face->expressInterest(interest,
713 bind(&Controller::onLocalPrefix, this, _1, _2),
714 bind(&Controller::onLocalPrefixTimeout, this, _1));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800715}
716
717void
718Controller::onMinimizeAction()
719{
720 m_settingDialog->hide();
721 m_startChatDialog->hide();
722 m_profileEditor->hide();
723 m_invitationDialog->hide();
724 m_addContactPanel->hide();
725
726 ChatDialogList::iterator it = m_chatDialogList.begin();
727 ChatDialogList::iterator end = m_chatDialogList.end();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700728 for (; it != end; it++)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800729 it->second->hide();
730}
731
732void
733Controller::onQuitAction()
734{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700735 while (!m_chatDialogList.empty()) {
736 ChatDialogList::const_iterator it = m_chatDialogList.begin();
737 onRemoveChatDialog(QString::fromStdString(it->first));
738 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800739
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700740 if (m_invitationListenerId != 0)
Yingdi Yu233a9722014-03-07 15:47:09 -0800741 m_face->unsetInterestFilter(m_invitationListenerId);
742
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800743 delete m_settingDialog;
744 delete m_startChatDialog;
745 delete m_profileEditor;
746 delete m_invitationDialog;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700747 delete m_browseContactDialog;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800748 delete m_addContactPanel;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700749
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700750 m_face->getIoService().stop();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800751
752 QApplication::quit();
753}
754
755void
756Controller::onStartChatroom(const QString& chatroomName, bool secured)
757{
758 Name chatroomPrefix;
759 chatroomPrefix.append("ndn")
760 .append("broadcast")
761 .append("ChronoChat")
762 .append(chatroomName.toStdString());
763
764 // check if the chatroom exists
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700765 if (m_chatDialogList.find(chatroomName.toStdString()) != m_chatDialogList.end()) {
766 QMessageBox::information(this, tr("ChronoChat"),
767 tr("You are creating an existing chatroom."
768 "You can check it in the context memu."));
769 return;
770 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800771
Mengjin Yan391d7242014-08-28 20:51:55 -0700772 // TODO: We should create a chatroom specific key/cert
773 //(which should be created in the first half of this method
774 //, but let's use the default one for now.
775 // std::cout << "start chat room localprefix: " << m_localPrefix.toUri() << std::endl;
776 shared_ptr<IdentityCertificate> idCert
777 = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
778 ChatDialog* chatDialog
779 = new ChatDialog(&m_contactManager, m_face, *idCert, chatroomPrefix
780 , m_localPrefix, m_nick, secured);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800781
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700782 addChatDialog(chatroomName, chatDialog);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800783 chatDialog->show();
784}
785
786void
Mengjin Yan391d7242014-08-28 20:51:55 -0700787Controller::onInvitationResponded(const ndn::Name& invitationName, bool accepted)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800788{
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700789 shared_ptr<Data> response = make_shared<Data>();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800790 shared_ptr<IdentityCertificate> chatroomCert;
791
792 // generate reply;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700793 if (accepted) {
794 Name responseName = invitationName;
795 responseName.append(m_localPrefix.wireEncode());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800796
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700797 response->setName(responseName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800798
Mengjin Yan391d7242014-08-28 20:51:55 -0700799 // We should create a particular certificate for this chatroom,
800 //but let's use default one for now.
801 chatroomCert
802 = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800803
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700804 response->setContent(chatroomCert->wireEncode());
805 response->setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700806 }
807 else {
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700808 response->setName(invitationName);
809 response->setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700810 }
811
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700812 m_keyChain.signByIdentity(*response, m_identity);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700813
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800814 // Check if we need a wrapper
815 Name invitationRoutingPrefix = getInvitationRoutingPrefix();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700816 if (invitationRoutingPrefix.isPrefixOf(m_identity))
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700817 m_face->put(*response);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700818 else {
819 Name wrappedName;
820 wrappedName.append(invitationRoutingPrefix)
821 .append(ROUTING_PREFIX_SEPARATOR, 2)
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700822 .append(response->getName());
Yingdi Yu233a9722014-03-07 15:47:09 -0800823
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700824 // _LOG_DEBUG("onInvitationResponded: prepare reply " << wrappedName);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700825
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700826 shared_ptr<Data> wrappedData = make_shared<Data>(wrappedName);
827 wrappedData->setContent(response->wireEncode());
828 wrappedData->setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800829
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700830 m_keyChain.signByIdentity(*wrappedData, m_identity);
831 m_face->put(*wrappedData);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700832 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800833
834 // create chatroom
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700835 if (accepted) {
836 Invitation invitation(invitationName);
837 Name chatroomPrefix;
838 chatroomPrefix.append("ndn")
839 .append("broadcast")
840 .append("ChronoChat")
841 .append(invitation.getChatroom());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800842
Mengjin Yan391d7242014-08-28 20:51:55 -0700843 //We should create a chatroom specific key/cert
844 //(which should be created in the first half of this method,
845 //but let's use the default one for now.
846 shared_ptr<IdentityCertificate> idCert
847 = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
848 ChatDialog* chatDialog
849 = new ChatDialog(&m_contactManager, m_face, *idCert,
850 chatroomPrefix, m_localPrefix, m_nick, true);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700851 chatDialog->addSyncAnchor(invitation);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800852
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700853 addChatDialog(QString::fromStdString(invitation.getChatroom()), chatDialog);
854 chatDialog->show();
855 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800856}
857
858void
859Controller::onShowChatMessage(const QString& chatroomName, const QString& from, const QString& data)
860{
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700861 m_trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(chatroomName),
862 QString("<%1>: %2").arg(from).arg(data),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800863 QSystemTrayIcon::Information, 20000);
864 m_trayIcon->setIcon(QIcon(":/images/note.png"));
865}
866
867void
Yingdi Yu233a9722014-03-07 15:47:09 -0800868Controller::onResetIcon()
869{
870 m_trayIcon->setIcon(QIcon(":/images/icon_small.png"));
871}
872
873void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800874Controller::onRemoveChatDialog(const QString& chatroomName)
875{
876 ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString());
877
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700878 if (it != m_chatDialogList.end()) {
879 ChatDialog* deletedChat = it->second;
880 if (deletedChat)
881 delete deletedChat;
882 m_chatDialogList.erase(it);
Mengjin Yan391d7242014-08-28 20:51:55 -0700883 m_discoveryLogic.removeLocalChatroom(Name::Component(chatroomName.toStdString()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800884
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700885 QAction* chatAction = m_chatActionList[chatroomName.toStdString()];
886 QAction* closeAction = m_closeActionList[chatroomName.toStdString()];
887 if (chatAction)
888 delete chatAction;
889 if (closeAction)
890 delete closeAction;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700891
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700892 m_chatActionList.erase(chatroomName.toStdString());
893 m_closeActionList.erase(chatroomName.toStdString());
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700894
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700895 updateMenu();
896 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800897}
898
899void
900Controller::onWarning(const QString& msg)
901{
902 QMessageBox::information(this, tr("ChronoChat"), msg);
903}
904
905void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700906Controller::onError(const QString& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800907{
908 QMessageBox::critical(this, tr("ChronoChat"), msg, QMessageBox::Ok);
909 exit(1);
910}
911
Yingdi Yu233a9722014-03-07 15:47:09 -0800912void
Mengjin Yan391d7242014-08-28 20:51:55 -0700913Controller::onInvitationInterest(const ndn::Name& prefix,
914 const ndn::Interest& interest,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700915 size_t routingPrefixOffset)
Yingdi Yu233a9722014-03-07 15:47:09 -0800916{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700917 // _LOG_DEBUG("onInvitationInterest: " << interest.getName());
918 shared_ptr<Interest> invitationInterest =
919 make_shared<Interest>(boost::cref(interest.getName().getSubName(routingPrefixOffset)));
Yingdi Yu233a9722014-03-07 15:47:09 -0800920
921 // check if the chatroom already exists;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700922 try {
Yingdi Yu233a9722014-03-07 15:47:09 -0800923 Invitation invitation(invitationInterest->getName());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700924 if (m_chatDialogList.find(invitation.getChatroom()) != m_chatDialogList.end())
Yingdi Yu233a9722014-03-07 15:47:09 -0800925 return;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700926 }
927 catch (Invitation::Error& e) {
928 // Cannot parse the invitation;
929 return;
930 }
Yingdi Yu233a9722014-03-07 15:47:09 -0800931
932 OnInterestValidated onValidated = bind(&Controller::onInvitationValidated, this, _1);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700933 OnInterestValidationFailed onValidationFailed = bind(&Controller::onInvitationValidationFailed,
934 this, _1, _2);
Yingdi Yu233a9722014-03-07 15:47:09 -0800935 m_validator.validate(*invitationInterest, onValidated, onValidationFailed);
936}
937
Mengjin Yan391d7242014-08-28 20:51:55 -0700938void
939Controller::onRosterChanged(const chronos::ChatroomInfo& info)
940{
941 m_discoveryLogic.addLocalChatroom(info);
942}
943
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800944} // namespace chronos
945
946#if WAF
947#include "controller.moc"
Yingdi Yu42125862014-08-07 17:04:28 -0700948// #include "controller.cpp.moc"
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800949#endif