blob: 93d7dd004ec3454d8f88fc64efddd4b6052b3998 [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: Zhenkai Zhu <zhenkai@cs.ucla.edu>
9 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
10 * Yingdi Yu <yingdi@cs.ucla.edu>
11 */
12
Yingdi Yu0b0a7362014-08-05 16:31:30 -070013#include "chat-dialog.hpp"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080014#include "ui_chat-dialog.h"
15
16#include <QScrollBar>
17#include <QMessageBox>
18#include <QCloseEvent>
19
20#ifndef Q_MOC_RUN
21#include <sync-intro-certificate.h>
22#include <boost/random/random_device.hpp>
23#include <boost/random/uniform_int_distribution.hpp>
Yingdi Yufa0b6a02014-04-30 14:26:42 -070024#include <ndn-cxx/util/random.hpp>
Yingdi Yu0b0a7362014-08-05 16:31:30 -070025#include <ndn-cxx/encoding/buffer-stream.hpp>
26#include "cryptopp.hpp"
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -070027#include <queue>
Yingdi Yu348f5ea2014-03-01 14:47:25 -080028#include "logging.h"
29#endif
30
Yingdi Yu348f5ea2014-03-01 14:47:25 -080031
Yingdi Yu0b0a7362014-08-05 16:31:30 -070032// INIT_LOGGER("ChatDialog");
Yingdi Yu348f5ea2014-03-01 14:47:25 -080033
34Q_DECLARE_METATYPE(std::vector<Sync::MissingDataInfo> )
Yingdi Yu233a9722014-03-07 15:47:09 -080035Q_DECLARE_METATYPE(ndn::shared_ptr<const ndn::Data>)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080036Q_DECLARE_METATYPE(ndn::Interest)
37Q_DECLARE_METATYPE(size_t)
38
Yingdi Yu0b0a7362014-08-05 16:31:30 -070039
40namespace chronos {
41
42using std::vector;
43using std::string;
44using std::map;
45using std::queue;
46
47using ndn::IdentityCertificate;
48using ndn::SecRuleRelative;
49using ndn::Face;
50using ndn::OBufferStream;
51using ndn::OnDataValidated;
52using ndn::OnDataValidationFailed;
53
54
55static const int HELLO_INTERVAL = FRESHNESS * 3 / 4;
56static const uint8_t CHRONOS_RP_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
57
Yingdi Yu348f5ea2014-03-01 14:47:25 -080058ChatDialog::ChatDialog(ContactManager* contactManager,
59 shared_ptr<Face> face,
60 const IdentityCertificate& myCertificate,
61 const Name& chatroomPrefix,
Yingdi Yufa0b6a02014-04-30 14:26:42 -070062 const Name& localPrefix,
Yingdi Yu17032f82014-03-25 15:48:23 -070063 const std::string& nick,
Yingdi Yu348f5ea2014-03-01 14:47:25 -080064 bool withSecurity,
Yingdi Yufa0b6a02014-04-30 14:26:42 -070065 QWidget* parent)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080066 : QDialog(parent)
67 , ui(new Ui::ChatDialog)
68 , m_contactManager(contactManager)
69 , m_face(face)
70 , m_myCertificate(myCertificate)
Yingdi Yu0b0a7362014-08-05 16:31:30 -070071 , m_chatroomName(chatroomPrefix.get(-1).toUri())
Yingdi Yu348f5ea2014-03-01 14:47:25 -080072 , m_chatroomPrefix(chatroomPrefix)
73 , m_localPrefix(localPrefix)
74 , m_useRoutablePrefix(false)
75 , m_nick(nick)
Yingdi Yua7876722014-03-25 14:46:55 -070076 , m_lastMsgTime(time::toUnixTimestamp(time::system_clock::now()).count())
Yingdi Yu348f5ea2014-03-01 14:47:25 -080077 , m_joined(false)
78 , m_sock(NULL)
Yingdi Yua7876722014-03-25 14:46:55 -070079 , m_session(static_cast<uint64_t>(time::toUnixTimestamp(time::system_clock::now()).count()))
Yingdi Yu348f5ea2014-03-01 14:47:25 -080080 , m_inviteListDialog(new InviteListDialog)
Mengjin Yanaec70742014-08-25 10:37:45 -070081 //ymj
82 //, m_trustModel(withSecurity)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080083{
84 qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
Yingdi Yu233a9722014-03-07 15:47:09 -080085 qRegisterMetaType<ndn::shared_ptr<const ndn::Data> >("ndn.DataPtr");
Yingdi Yu348f5ea2014-03-01 14:47:25 -080086 qRegisterMetaType<ndn::Interest>("ndn.Interest");
87 qRegisterMetaType<size_t>("size_t");
88
89 m_scene = new DigestTreeScene(this);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -070090 m_trustScene = new TrustTreeScene(this);
Yingdi Yu348f5ea2014-03-01 14:47:25 -080091 m_rosterModel = new QStringListModel(this);
92 m_timer = new QTimer(this);
93
94 ui->setupUi(this);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -070095 ui->syncTreeViewer->setScene(m_scene);
Yingdi Yu348f5ea2014-03-01 14:47:25 -080096 m_scene->setSceneRect(m_scene->itemsBoundingRect());
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -070097 ui->syncTreeViewer->hide();
98 ui->trustTreeViewer->setScene(m_trustScene);
99 m_trustScene->setSceneRect(m_trustScene->itemsBoundingRect());
100 ui->trustTreeViewer->hide();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800101 ui->listView->setModel(m_rosterModel);
102
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700103 m_identity =
104 IdentityCertificate::certificateNameToPublicKeyName(m_myCertificate.getName()).getPrefix(-1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800105 updatePrefix();
106 updateLabels();
107
108 m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
109 m_scene->plot("Empty");
110
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700111 connect(ui->lineEdit, SIGNAL(returnPressed()),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800112 this, SLOT(onReturnPressed()));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700113 connect(ui->syncTreeButton, SIGNAL(pressed()),
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700114 this, SLOT(onSyncTreeButtonPressed()));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700115 connect(ui->trustTreeButton, SIGNAL(pressed()),
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700116 this, SLOT(onTrustTreeButtonPressed()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800117 connect(m_scene, SIGNAL(replot()),
118 this, SLOT(onReplot()));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700119 connect(m_scene, SIGNAL(rosterChanged(QStringList)),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800120 this, SLOT(onRosterChanged(QStringList)));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700121 connect(m_timer, SIGNAL(timeout()),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800122 this, SLOT(onReplot()));
123
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700124 connect(this, SIGNAL(processData(const ndn::shared_ptr<const ndn::Data>&, bool, bool)),
Yingdi Yu233a9722014-03-07 15:47:09 -0800125 this, SLOT(onProcessData(const ndn::shared_ptr<const ndn::Data>&, bool, bool)));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700126 connect(this, SIGNAL(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800127 this, SLOT(onProcessTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700128 connect(this, SIGNAL(reply(const ndn::Interest&,
129 const ndn::shared_ptr<const ndn::Data>&,
130 size_t, bool)),
131 this, SLOT(onReply(const ndn::Interest&,
132 const ndn::shared_ptr<const ndn::Data>&,
133 size_t, bool)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800134 connect(this, SIGNAL(replyTimeout(const ndn::Interest&, size_t)),
135 this, SLOT(onReplyTimeout(const ndn::Interest&, size_t)));
Yingdi Yu233a9722014-03-07 15:47:09 -0800136 connect(this, SIGNAL(introCert(const ndn::Interest&, const ndn::shared_ptr<const ndn::Data>&)),
137 this, SLOT(onIntroCert(const ndn::Interest&, const ndn::shared_ptr<const ndn::Data>&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800138 connect(this, SIGNAL(introCertTimeout(const ndn::Interest&, int, const QString&)),
139 this, SLOT(onIntroCertTimeout(const ndn::Interest&, int, const QString&)));
140
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700141 if (withSecurity) {
142 m_invitationValidator = make_shared<chronos::ValidatorInvitation>();
143 m_dataRule = make_shared<SecRuleRelative>("([^<CHRONOCHAT-DATA>]*)<CHRONOCHAT-DATA><>",
144 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
145 "==", "\\1", "\\1", true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800146
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700147 ui->inviteButton->setEnabled(true);
148 ui->trustTreeButton->setEnabled(true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800149
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700150 connect(ui->inviteButton, SIGNAL(clicked()),
151 this, SLOT(onInviteListDialogRequested()));
152 connect(m_inviteListDialog, SIGNAL(sendInvitation(const QString&)),
153 this, SLOT(onSendInvitation(const QString&)));
154 connect(this, SIGNAL(waitForContactList()),
155 m_contactManager, SLOT(onWaitForContactList()));
156 connect(m_contactManager, SIGNAL(contactAliasListReady(const QStringList&)),
157 m_inviteListDialog, SLOT(onContactAliasListReady(const QStringList&)));
158 connect(m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
159 m_inviteListDialog, SLOT(onContactIdListReady(const QStringList&)));
Mengjin Yanaec70742014-08-25 10:37:45 -0700160
161 m_trustModel = ChatroomInfo::TRUST_MODEL_WEBOFTRUST;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700162 }
Mengjin Yanaec70742014-08-25 10:37:45 -0700163 else
164 m_trustModel = ChatroomInfo::TRUST_MODEL_NONE;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800165
166 initializeSync();
167}
168
169
170ChatDialog::~ChatDialog()
171{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700172 if (m_certListPrefixId)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800173 m_face->unsetInterestFilter(m_certListPrefixId);
174
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700175 if (m_certSinglePrefixId)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800176 m_face->unsetInterestFilter(m_certSinglePrefixId);
177
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700178 if (m_sock != NULL) {
179 sendLeave();
180 delete m_sock;
181 m_sock = NULL;
182 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800183}
184
185// public methods:
186void
187ChatDialog::addSyncAnchor(const Invitation& invitation)
188{
Mengjin Yanaec70742014-08-25 10:37:45 -0700189 // _LOG_DEBUG("Add sync anchor from invitation");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800190 // Add inviter certificate as trust anchor.
191 m_sock->addParticipant(invitation.getInviterCertificate());
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700192 plotTrustTree();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800193
194 // Ask inviter for IntroCertificate
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700195 Name inviterNameSpace =
196 IdentityCertificate::certificateNameToPublicKeyName(
197 invitation.getInviterCertificate().getName()).getPrefix(-1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800198 fetchIntroCert(inviterNameSpace, invitation.getInviterRoutingPrefix());
199}
200
201void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700202ChatDialog::processTreeUpdateWrapper(const vector<Sync::MissingDataInfo>& v,
203 Sync::SyncSocket *sock)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800204{
205 emit processTreeUpdate(v);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700206 // _LOG_DEBUG("<<< Tree update signal emitted");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800207}
208
209void
210ChatDialog::processDataWrapper(const shared_ptr<const Data>& data)
211{
Yingdi Yu233a9722014-03-07 15:47:09 -0800212 emit processData(data, true, false);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700213 // _LOG_DEBUG("<<< " << data->getName() << " fetched");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800214}
215
216void
217ChatDialog::processDataNoShowWrapper(const shared_ptr<const Data>& data)
218{
Yingdi Yu233a9722014-03-07 15:47:09 -0800219 emit processData(data, false, false);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800220}
221
222void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700223ChatDialog::processRemoveWrapper(const string& prefix)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800224{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700225 // _LOG_DEBUG("Sync REMOVE signal received for prefix: " << prefix);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800226}
227
228// protected methods:
229void
230ChatDialog::closeEvent(QCloseEvent *e)
231{
232 QMessageBox::information(this, tr("ChronoChat"),
233 tr("The chatroom will keep running in the "
234 "system tray. To close the chatroom, "
235 "choose <b>Close chatroom</b> in the "
236 "context memu of the system tray entry."));
Mengjin Yanaec70742014-08-25 10:37:45 -0700237 hide();//ymj
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800238 e->ignore();
239}
240
241void
Yingdi Yu233a9722014-03-07 15:47:09 -0800242ChatDialog::changeEvent(QEvent *e)
243{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700244 switch(e->type()) {
Yingdi Yu233a9722014-03-07 15:47:09 -0800245 case QEvent::ActivationChange:
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700246 if (isActiveWindow()) {
Yingdi Yu233a9722014-03-07 15:47:09 -0800247 emit resetIcon();
248 }
249 break;
250 default:
251 break;
252 }
253}
254
255void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800256ChatDialog::resizeEvent(QResizeEvent *e)
257{
258 fitView();
259}
260
261void
262ChatDialog::showEvent(QShowEvent *e)
263{
264 fitView();
265}
266
267// private methods:
268void
269ChatDialog::updatePrefix()
270{
271 m_certListPrefix.clear();
272 m_certSinglePrefix.clear();
273 m_localChatPrefix.clear();
274 m_chatPrefix.clear();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700275 m_chatPrefix.append(m_identity)
276 .append("CHRONOCHAT-DATA")
277 .append(m_chatroomName)
278 .append(getRandomString());
279 if (!m_localPrefix.isPrefixOf(m_identity)) {
280 m_useRoutablePrefix = true;
281 m_certListPrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
282 m_certSinglePrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
283 m_localChatPrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
284 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800285 m_certListPrefix.append(m_identity).append("CHRONOCHAT-CERT-LIST").append(m_chatroomName);
286 m_certSinglePrefix.append(m_identity).append("CHRONOCHAT-CERT-SINGLE").append(m_chatroomName);
287 m_localChatPrefix.append(m_chatPrefix);
288
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700289 if (m_certListPrefixId)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800290 m_face->unsetInterestFilter(m_certListPrefixId);
Mengjin Yanaec70742014-08-25 10:37:45 -0700291
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700292 m_certListPrefixId = m_face->setInterestFilter(m_certListPrefix,
293 bind(&ChatDialog::onCertListInterest,
294 this, _1, _2),
295 bind(&ChatDialog::onCertListRegisterFailed,
296 this, _1, _2));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800297
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700298 if (m_certSinglePrefixId)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800299 m_face->unsetInterestFilter(m_certSinglePrefixId);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700300 m_certSinglePrefixId = m_face->setInterestFilter(m_certSinglePrefix,
301 bind(&ChatDialog::onCertSingleInterest,
302 this, _1, _2),
303 bind(&ChatDialog::onCertSingleRegisterFailed,
304 this, _1, _2));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800305}
306
307void
308ChatDialog::updateLabels()
309{
310 QString settingDisp = QString("Chatroom: %1").arg(QString::fromStdString(m_chatroomName));
311 ui->infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
312 ui->infoLabel->setText(settingDisp);
313 QString prefixDisp;
314 Name privatePrefix("/private/local");
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700315 if (privatePrefix.isPrefixOf(m_localChatPrefix)) {
316 prefixDisp =
317 QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n"
318 "<Prefix = %1>")
319 .arg(QString::fromStdString(m_localChatPrefix.toUri()));
320 ui->prefixLabel->setStyleSheet(
321 "QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
322 }
323 else {
324 prefixDisp = QString("<Prefix = %1>")
325 .arg(QString::fromStdString(m_localChatPrefix.toUri()));
326 ui->prefixLabel->setStyleSheet(
327 "QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
328 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800329 ui->prefixLabel->setText(prefixDisp);
330}
331
332void
333ChatDialog::initializeSync()
334{
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700335
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800336 m_sock = new Sync::SyncSocket(m_chatroomPrefix,
337 m_chatPrefix,
338 m_session,
339 m_useRoutablePrefix,
340 m_localPrefix,
341 m_face,
342 m_myCertificate,
343 m_dataRule,
344 bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
345 bind(&ChatDialog::processRemoveWrapper, this, _1));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700346
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800347 usleep(100000);
348
349 QTimer::singleShot(600, this, SLOT(sendJoin()));
350 m_timer->start(FRESHNESS * 1000);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700351 disableSyncTreeDisplay();
352 QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800353}
354
355void
356ChatDialog::sendInvitation(shared_ptr<Contact> contact, bool isIntroducer)
357{
358 // Add invitee as a trust anchor.
359 m_invitationValidator->addTrustAnchor(contact->getPublicKeyName(),
360 contact->getPublicKey());
361
362 // Prepared an invitation interest without routable prefix.
363 Invitation invitation(contact->getNameSpace(),
364 m_chatroomName,
365 m_localPrefix,
366 m_myCertificate);
367 Interest tmpInterest(invitation.getUnsignedInterestName());
368 m_keyChain.sign(tmpInterest, m_myCertificate.getName());
369
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700370 // Get invitee's routable prefix
371 // (ideally it will do some DNS lookup, but we assume everyone use /ndn/broadcast
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800372 Name routablePrefix = getInviteeRoutablePrefix(contact->getNameSpace());
373
374 // Check if we need to prepend the routable prefix to the interest name.
375 bool requireRoutablePrefix = false;
376 Name interestName;
377 size_t routablePrefixOffset = 0;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700378 if (!routablePrefix.isPrefixOf(tmpInterest.getName())) {
379 interestName.append(routablePrefix).append(CHRONOS_RP_SEPARATOR, 2);
380 requireRoutablePrefix = true;
381 routablePrefixOffset = routablePrefix.size() + 1;
382 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800383 interestName.append(tmpInterest.getName());
384
385 // Send the invitation out
386 Interest interest(interestName);
387 interest.setMustBeFresh(true);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700388 // _LOG_DEBUG("sendInvitation: " << interest.getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800389 m_face->expressInterest(interest,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700390 bind(&ChatDialog::replyWrapper,
391 this, _1, _2, routablePrefixOffset, isIntroducer),
392 bind(&ChatDialog::replyTimeoutWrapper,
393 this, _1, routablePrefixOffset));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800394}
395
396void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700397ChatDialog::replyWrapper(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800398 Data& data,
399 size_t routablePrefixOffset,
400 bool isIntroducer)
401{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700402 // _LOG_DEBUG("ChatDialog::replyWrapper");
Yingdi Yu233a9722014-03-07 15:47:09 -0800403 emit reply(interest, data.shared_from_this(), routablePrefixOffset, isIntroducer);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700404 // _LOG_DEBUG("OK?");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800405}
406
407void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700408ChatDialog::replyTimeoutWrapper(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800409 size_t routablePrefixOffset)
410{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700411 // _LOG_DEBUG("ChatDialog::replyTimeoutWrapper");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800412 emit replyTimeout(interest, routablePrefixOffset);
413}
414
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700415void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800416ChatDialog::onReplyValidated(const shared_ptr<const Data>& data,
417 size_t inviteeRoutablePrefixOffset,
418 bool isIntroducer)
419{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700420 if (data->getName().size() <= inviteeRoutablePrefixOffset) {
421 Invitation invitation(data->getName());
422 invitationRejected(invitation.getInviteeNameSpace());
423 }
424 else {
425 Name inviteePrefix;
426 inviteePrefix.wireDecode(data->getName().get(inviteeRoutablePrefixOffset).blockFromValue());
427 IdentityCertificate inviteeCert;
428 inviteeCert.wireDecode(data->getContent().blockFromValue());
429 invitationAccepted(inviteeCert, inviteePrefix, isIntroducer);
430 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800431}
432
433void
434ChatDialog::onReplyValidationFailed(const shared_ptr<const Data>& data,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700435 const string& failureInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800436{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700437 // _LOG_DEBUG("Invitation reply cannot be validated: " + failureInfo + " ==> " +
438 // data->getName().toUri());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800439}
440
441void
442ChatDialog::invitationRejected(const Name& identity)
443{
444 QString msg = QString::fromStdString(identity.toUri()) + " rejected your invitation!";
445 emit inivationRejection(msg);
446}
447
448void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700449ChatDialog::invitationAccepted(const IdentityCertificate& inviteeCert,
450 const Name& inviteePrefix,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800451 bool isIntroducer)
452{
453 // Add invitee certificate as trust anchor.
454 m_sock->addParticipant(inviteeCert);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700455 plotTrustTree();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800456
457 // Ask invitee for IntroCertificate.
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700458 Name inviteeNameSpace =
459 IdentityCertificate::certificateNameToPublicKeyName(inviteeCert.getName()).getPrefix(-1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800460 fetchIntroCert(inviteeNameSpace, inviteePrefix);
461}
462
463void
464ChatDialog::fetchIntroCert(const Name& identity, const Name& prefix)
465{
466 Name interestName;
467
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700468 if (!prefix.isPrefixOf(identity))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800469 interestName.append(prefix).append(CHRONOS_RP_SEPARATOR, 2);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700470
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800471 interestName.append(identity)
472 .append("CHRONOCHAT-CERT-LIST")
473 .append(m_chatroomName)
474 .appendVersion();
475
476 Interest interest(interestName);
477 interest.setMustBeFresh(true);
478
479 m_face->expressInterest(interest,
480 bind(&ChatDialog::onIntroCertList, this, _1, _2),
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700481 bind(&ChatDialog::onIntroCertListTimeout, this, _1, 1,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800482 "IntroCertList: " + interestName.toUri()));
483}
484
485void
486ChatDialog::onIntroCertList(const Interest& interest, const Data& data)
487{
488 Chronos::IntroCertListMsg introCertList;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700489 if (!introCertList.ParseFromArray(data.getContent().value(), data.getContent().value_size()))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800490 return;
491
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700492 for (int i = 0; i < introCertList.certname_size(); i++) {
493 Name certName(introCertList.certname(i));
494 Interest interest(certName);
495 interest.setMustBeFresh(true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800496
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700497 // _LOG_DEBUG("onIntroCertList: to fetch " << certName);
Yingdi Yu233a9722014-03-07 15:47:09 -0800498
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700499 m_face->expressInterest(interest,
500 bind(&ChatDialog::introCertWrapper, this, _1, _2),
501 bind(&ChatDialog::introCertTimeoutWrapper, this, _1, 0,
502 QString("IntroCert: %1").arg(introCertList.certname(i).c_str())));
503 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800504}
505
506void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700507ChatDialog::onIntroCertListTimeout(const Interest& interest, int retry, const string& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800508{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700509 if (retry > 0) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800510 m_face->expressInterest(interest,
511 bind(&ChatDialog::onIntroCertList, this, _1, _2),
512 bind(&ChatDialog::onIntroCertListTimeout, this, _1, retry - 1, msg));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700513 }
514 else {
515 // _LOG_DEBUG(msg << " TIMEOUT!");
516 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800517}
518
519void
520ChatDialog::introCertWrapper(const Interest& interest, Data& data)
521{
Yingdi Yu233a9722014-03-07 15:47:09 -0800522 emit introCert(interest, data.shared_from_this());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800523}
524
525void
526ChatDialog::introCertTimeoutWrapper(const Interest& interest, int retry, const QString& msg)
527{
528 emit introCertTimeout(interest, retry, msg);
529}
530
531void
Mengjin Yanaec70742014-08-25 10:37:45 -0700532ChatDialog::onCertListInterest(const ndn::Name& prefix, const ndn::Interest& interest)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800533{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700534 vector<Name> certNameList;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800535 m_sock->getIntroCertNames(certNameList);
536
537 Chronos::IntroCertListMsg msg;
538
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700539 for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
540 Name certName;
541 certName.append(m_certSinglePrefix).append(*it);
542 msg.add_certname(certName.toUri());
543 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800544 OBufferStream os;
545 msg.SerializeToOstream(&os);
546
547 Data data(interest.getName());
548 data.setContent(os.buf());
549 m_keyChain.sign(data, m_myCertificate.getName());
550
551 m_face->put(data);
552}
553
554void
Mengjin Yanaec70742014-08-25 10:37:45 -0700555ChatDialog::onCertListRegisterFailed(const ndn::Name& prefix, const std::string& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800556{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700557 // _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800558}
559
560void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700561ChatDialog::onCertSingleInterest(const Name& prefix, const Interest& interest)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800562{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700563 try {
564 Name certName = interest.getName().getSubName(prefix.size());
565 const Sync::IntroCertificate& introCert = m_sock->getIntroCertificate(certName);
566 Data data(interest.getName());
567 data.setContent(introCert.wireEncode());
568 m_keyChain.sign(data, m_myCertificate.getName());
569 m_face->put(data);
570 }
571 catch(Sync::SyncSocket::Error& e) {
572 return;
573 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800574}
575
576void
Mengjin Yanaec70742014-08-25 10:37:45 -0700577ChatDialog::onCertSingleRegisterFailed(const Name& prefix, const std::string& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800578{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700579 // _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800580}
581
582void
583ChatDialog::sendMsg(SyncDemo::ChatMessage &msg)
584{
585 // send msg
586 OBufferStream os;
587 msg.SerializeToOstream(&os);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700588
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700589 if (!msg.IsInitialized()) {
590 // _LOG_DEBUG("Errrrr.. msg was not probally initialized " << __FILE__ <<
591 // ":" << __LINE__ << ". what is happening?");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800592 abort();
593 }
Yingdi Yu233a9722014-03-07 15:47:09 -0800594 uint64_t nextSequence = m_sock->getNextSeq();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800595 m_sock->publishData(os.buf()->buf(), os.buf()->size(), FRESHNESS);
596
Yingdi Yua7876722014-03-25 14:46:55 -0700597 m_lastMsgTime = time::toUnixTimestamp(time::system_clock::now()).count();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800598
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700599 Sync::MissingDataInfo mdi = {m_localChatPrefix.toUri(),
600 Sync::SeqNo(0),
601 Sync::SeqNo(nextSequence)};
602 vector<Sync::MissingDataInfo> v;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800603 v.push_back(mdi);
604 {
605 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
606 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
607 m_scene->msgReceived(QString::fromStdString(m_localChatPrefix.toUri()),
608 QString::fromStdString(m_nick));
609 }
610}
611
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700612void ChatDialog::disableSyncTreeDisplay()
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800613{
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700614 ui->syncTreeButton->setEnabled(false);
615 ui->syncTreeViewer->hide();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800616 fitView();
617}
618
619void
620ChatDialog::appendMessage(const SyncDemo::ChatMessage msg, bool isHistory)
621{
622 boost::recursive_mutex::scoped_lock lock(m_msgMutex);
623
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700624 if (msg.type() == SyncDemo::ChatMessage::CHAT) {
625 if (!msg.has_data()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800626 return;
627 }
628
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700629 if (msg.from().empty() || msg.data().empty()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800630 return;
631 }
632
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700633 if (!msg.has_timestamp()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800634 return;
635 }
636
637 // if (m_history.size() == MAX_HISTORY_ENTRY)
638 // {
639 // m_history.dequeue();
640 // }
641
642 // m_history.enqueue(msg);
643
644 QTextCharFormat nickFormat;
645 nickFormat.setForeground(Qt::darkGreen);
646 nickFormat.setFontWeight(QFont::Bold);
647 nickFormat.setFontUnderline(true);
648 nickFormat.setUnderlineColor(Qt::gray);
649
650 QTextCursor cursor(ui->textEdit->textCursor());
651 cursor.movePosition(QTextCursor::End);
652 QTextTableFormat tableFormat;
653 tableFormat.setBorder(0);
654 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
655 QString from = QString("%1 ").arg(msg.from().c_str());
656 QTextTableCell fromCell = table->cellAt(0, 0);
657 fromCell.setFormat(nickFormat);
658 fromCell.firstCursorPosition().insertText(from);
659
660 time_t timestamp = msg.timestamp();
661 printTimeInCell(table, timestamp);
662
663 QTextCursor nextCursor(ui->textEdit->textCursor());
664 nextCursor.movePosition(QTextCursor::End);
665 table = nextCursor.insertTable(1, 1, tableFormat);
666 table->cellAt(0, 0).firstCursorPosition().insertText(QString::fromUtf8(msg.data().c_str()));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700667 if (!isHistory) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800668 showMessage(from, QString::fromUtf8(msg.data().c_str()));
669 }
670 }
671
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700672 if (msg.type() == SyncDemo::ChatMessage::JOIN || msg.type() == SyncDemo::ChatMessage::LEAVE) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800673 QTextCharFormat nickFormat;
674 nickFormat.setForeground(Qt::gray);
675 nickFormat.setFontWeight(QFont::Bold);
676 nickFormat.setFontUnderline(true);
677 nickFormat.setUnderlineColor(Qt::gray);
678
679 QTextCursor cursor(ui->textEdit->textCursor());
680 cursor.movePosition(QTextCursor::End);
681 QTextTableFormat tableFormat;
682 tableFormat.setBorder(0);
683 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
684 QString action;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700685 if (msg.type() == SyncDemo::ChatMessage::JOIN) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800686 action = "enters room";
687 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700688 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800689 action = "leaves room";
690 }
691
692 QString from = QString("%1 %2 ").arg(msg.from().c_str()).arg(action);
693 QTextTableCell fromCell = table->cellAt(0, 0);
694 fromCell.setFormat(nickFormat);
695 fromCell.firstCursorPosition().insertText(from);
696
697 time_t timestamp = msg.timestamp();
698 printTimeInCell(table, timestamp);
699 }
700
701 QScrollBar *bar = ui->textEdit->verticalScrollBar();
702 bar->setValue(bar->maximum());
703}
704
705void
706ChatDialog::processRemove(QString prefix)
707{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700708 // _LOG_DEBUG("<<< remove node for prefix" << prefix.toStdString());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800709
710 bool removed = m_scene->removeNode(prefix);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700711 if (removed) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800712 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
713 m_scene->plot(m_sock->getRootDigest().c_str());
714 }
715}
716
717Name
718ChatDialog::getInviteeRoutablePrefix(const Name& invitee)
719{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700720 return Name("/ndn/broadcast");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800721}
722
723void
724ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
725 msg.set_from(m_nick);
726 msg.set_to(m_chatroomName);
727 msg.set_data(text.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700728 int32_t seconds =
Mengjin Yanaec70742014-08-25 10:37:45 -0700729 static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800730 msg.set_timestamp(seconds);
731 msg.set_type(SyncDemo::ChatMessage::CHAT);
732}
733
734void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700735ChatDialog::formControlMessage(SyncDemo::ChatMessage &msg,
736 SyncDemo::ChatMessage::ChatMessageType type)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800737{
738 msg.set_from(m_nick);
739 msg.set_to(m_chatroomName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700740 int32_t seconds =
Mengjin Yanaec70742014-08-25 10:37:45 -0700741 static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800742 msg.set_timestamp(seconds);
743 msg.set_type(type);
744}
745
746QString
747ChatDialog::formatTime(time_t timestamp)
748{
749 struct tm *tm_time = localtime(&timestamp);
750 int hour = tm_time->tm_hour;
751 QString amOrPM;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700752 if (hour > 12) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800753 hour -= 12;
754 amOrPM = "PM";
755 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700756 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800757 amOrPM = "AM";
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700758 if (hour == 0) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800759 hour = 12;
760 }
761 }
762
763 char textTime[12];
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700764 sprintf(textTime, "%d:%02d:%02d %s",
765 hour, tm_time->tm_min, tm_time->tm_sec, amOrPM.toStdString().c_str());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800766 return QString(textTime);
767}
768
769void
770ChatDialog::printTimeInCell(QTextTable *table, time_t timestamp)
771{
772 QTextCharFormat timeFormat;
773 timeFormat.setForeground(Qt::gray);
774 timeFormat.setFontUnderline(true);
775 timeFormat.setUnderlineColor(Qt::gray);
776 QTextTableCell timeCell = table->cellAt(0, 1);
777 timeCell.setFormat(timeFormat);
778 timeCell.firstCursorPosition().insertText(formatTime(timestamp));
779}
780
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700781string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800782ChatDialog::getRandomString()
783{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700784 uint32_t r = ndn::random::generateWord32();
Yingdi Yu17032f82014-03-25 15:48:23 -0700785 std::stringstream ss;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800786 {
787 using namespace CryptoPP;
788 StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
789 new HexEncoder(new FileSink(ss), false));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700790
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800791 }
792
793 return ss.str();
794}
795
796void
797ChatDialog::showMessage(const QString& from, const QString& data)
798{
799 if (!isActiveWindow())
800 emit showChatMessage(QString::fromStdString(m_chatroomName),
801 from, data);
802}
803
804void
805ChatDialog::fitView()
806{
807 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
808 QRectF rect = m_scene->itemsBoundingRect();
809 m_scene->setSceneRect(rect);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700810 ui->syncTreeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
811
812 QRectF trustRect = m_trustScene->itemsBoundingRect();
813 m_trustScene->setSceneRect(trustRect);
814 ui->trustTreeViewer->fitInView(m_trustScene->itemsBoundingRect(), Qt::KeepAspectRatio);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800815}
816
817void
818ChatDialog::summonReaper()
819{
820 Sync::SyncLogic &logic = m_sock->getLogic ();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700821 map<string, bool> branches = logic.getBranchPrefixes();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800822 QMap<QString, DisplayUserPtr> roster = m_scene->getRosterFull();
823
824 m_zombieList.clear();
825
826 QMapIterator<QString, DisplayUserPtr> it(roster);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700827 map<string, bool>::iterator mapIt;
828 while (it.hasNext()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800829 it.next();
830 DisplayUserPtr p = it.value();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700831 if (p != DisplayUserNullPtr) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800832 mapIt = branches.find(p->getPrefix().toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700833 if (mapIt != branches.end()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800834 mapIt->second = true;
835 }
836 }
837 }
838
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700839 for (mapIt = branches.begin(); mapIt != branches.end(); ++mapIt) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800840 // this is zombie. all active users should have been marked true
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700841 if (! mapIt->second) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800842 m_zombieList.append(mapIt->first.c_str());
843 }
844 }
845
846 m_zombieIndex = 0;
847
848 // start reaping
849 reap();
850}
851
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700852void
853ChatDialog::getTree(TrustTreeNodeList& nodeList)
854{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700855 typedef map<Name, shared_ptr<TrustTreeNode> > NodeMap;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700856
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700857 vector<Name> certNameList;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700858 NodeMap nodeMap;
859
860 m_sock->getIntroCertNames(certNameList);
861
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700862 for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
863 Name introducerCertName;
864 Name introduceeCertName;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700865
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700866 introducerCertName.wireDecode(it->get(-2).blockFromValue());
867 introduceeCertName.wireDecode(it->get(-3).blockFromValue());
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700868
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700869 Name introducerName =
870 IdentityCertificate::certificateNameToPublicKeyName(introducerCertName).getPrefix(-1);
871 Name introduceeName =
872 IdentityCertificate::certificateNameToPublicKeyName(introduceeCertName).getPrefix(-1);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700873
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700874 NodeMap::iterator introducerIt = nodeMap.find(introducerName);
875 if (introducerIt == nodeMap.end()) {
876 shared_ptr<TrustTreeNode> introducerNode(new TrustTreeNode(introducerName));
877 nodeMap[introducerName] = introducerNode;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700878 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700879 shared_ptr<TrustTreeNode> erNode = nodeMap[introducerName];
880
881 NodeMap::iterator introduceeIt = nodeMap.find(introduceeName);
882 if (introduceeIt == nodeMap.end()) {
883 shared_ptr<TrustTreeNode> introduceeNode(new TrustTreeNode(introduceeName));
884 nodeMap[introduceeName] = introduceeNode;
885 }
886 shared_ptr<TrustTreeNode> eeNode = nodeMap[introduceeName];
887
888 erNode->addIntroducee(eeNode);
889 eeNode->addIntroducer(erNode);
890 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700891
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700892 nodeList.clear();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700893 queue<shared_ptr<TrustTreeNode> > nodeQueue;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700894
895 NodeMap::iterator nodeIt = nodeMap.find(m_identity);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700896 if (nodeIt == nodeMap.end())
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700897 return;
898
899 nodeQueue.push(nodeIt->second);
900 nodeIt->second->setLevel(0);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700901 while (!nodeQueue.empty()) {
902 shared_ptr<TrustTreeNode>& node = nodeQueue.front();
903 node->setVisited();
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700904
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700905 TrustTreeNodeList& introducees = node->getIntroducees();
906 for (TrustTreeNodeList::iterator eeIt = introducees.begin();
907 eeIt != introducees.end(); eeIt++) {
908 // _LOG_DEBUG("introducee: " << (*eeIt)->name() <<
909 // " visited: " << std::boolalpha << (*eeIt)->visited());
910 if (!(*eeIt)->visited()) {
911 nodeQueue.push(*eeIt);
912 (*eeIt)->setLevel(node->level()+1);
913 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700914 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700915
916 nodeList.push_back(node);
917 nodeQueue.pop();
918 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700919}
920
921void
922ChatDialog::plotTrustTree()
923{
924 TrustTreeNodeList nodeList;
925
926 getTree(nodeList);
927 {
928 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
929 m_trustScene->plotTrustTree(nodeList);
930 fitView();
931 }
932}
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800933
Mengjin Yanaec70742014-08-25 10:37:45 -0700934shared_ptr<ChatroomInfo>
935ChatDialog::getChatroomInfo() const
936{
937 shared_ptr<ChatroomInfo> chatroom = make_shared<ChatroomInfo>();
938 chatroom->setName(Name::Component(m_chatroomName));
939
940 Roster roster = m_scene->getRosterFull();
941 Roster_iterator it = roster.begin();
942
943 for(it = roster.begin(); it != roster.end(); ++it )
944 {
945 Name participant = Name(it.key().toStdString()).getPrefix(-3);
946 chatroom->addParticipant(participant);
947 }
948
949 chatroom->setTrustModel(m_trustModel);
950 return chatroom;
951}
952
953
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800954// public slots:
955void
956ChatDialog::onLocalPrefixUpdated(const QString& localPrefix)
957{
958 Name newLocalPrefix(localPrefix.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700959 if (!newLocalPrefix.empty() && newLocalPrefix != m_localPrefix) {
960 // Update localPrefix
961 m_localPrefix = newLocalPrefix;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800962
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700963 updatePrefix();
964 updateLabels();
965 m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800966
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700967 if (m_sock != NULL) {
968 {
969 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
970 m_scene->clearAll();
971 m_scene->plot("Empty");
972 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800973
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700974 ui->textEdit->clear();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700975
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700976 if (m_joined) {
977 sendLeave();
978 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800979
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700980 delete m_sock;
981 m_sock = NULL;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700982
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700983 usleep(100000);
984 m_sock = new Sync::SyncSocket(m_chatroomPrefix,
985 m_chatPrefix,
986 m_session,
987 m_useRoutablePrefix,
988 m_localPrefix,
989 m_face,
990 m_myCertificate,
991 m_dataRule,
992 bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
993 bind(&ChatDialog::processRemoveWrapper, this, _1));
994 usleep(100000);
995 QTimer::singleShot(600, this, SLOT(sendJoin()));
996 m_timer->start(FRESHNESS * 1000);
997 disableSyncTreeDisplay();
998 QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800999 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001000 else
1001 initializeSync();
1002 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001003 else
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001004 if (m_sock == NULL)
1005 initializeSync();
1006
1007 fitView();
1008}
1009
1010void
1011ChatDialog::onClose()
1012{
1013 hide();
1014 emit closeChatDialog(QString::fromStdString(m_chatroomName));
1015}
1016
1017
1018// private slots:
1019void
1020ChatDialog::onReturnPressed()
1021{
1022 QString text = ui->lineEdit->text();
1023 if (text.isEmpty())
1024 return;
1025
1026 ui->lineEdit->clear();
1027
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001028 if (text.startsWith("boruoboluomi")) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001029 summonReaper ();
1030 // reapButton->show();
1031 fitView();
1032 return;
1033 }
1034
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001035 if (text.startsWith("minimanihong")) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001036 // reapButton->hide();
1037 fitView();
1038 return;
1039 }
1040
1041 SyncDemo::ChatMessage msg;
1042 formChatMessage(text, msg);
1043
1044 appendMessage(msg);
1045
1046 sendMsg(msg);
1047
1048 fitView();
1049}
1050
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001051void
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001052ChatDialog::onSyncTreeButtonPressed()
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001053{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001054 if (ui->syncTreeViewer->isVisible()) {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001055 ui->syncTreeViewer->hide();
1056 ui->syncTreeButton->setText("Show ChronoSync Tree");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001057 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001058 else {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001059 ui->syncTreeViewer->show();
1060 ui->syncTreeButton->setText("Hide ChronoSync Tree");
1061 }
1062
1063 fitView();
1064}
1065
1066void
1067ChatDialog::onTrustTreeButtonPressed()
1068{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001069 if (ui->trustTreeViewer->isVisible()) {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001070 ui->trustTreeViewer->hide();
1071 ui->trustTreeButton->setText("Show Trust Tree");
1072 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001073 else {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001074 ui->trustTreeViewer->show();
1075 ui->trustTreeButton->setText("Hide Trust Tree");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001076 }
1077
1078 fitView();
1079}
1080
1081void
Mengjin Yanaec70742014-08-25 10:37:45 -07001082ChatDialog::onProcessData(const ndn::shared_ptr<const ndn::Data>& data, bool show, bool isHistory)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001083{
1084 SyncDemo::ChatMessage msg;
1085 bool corrupted = false;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001086 if (!msg.ParseFromArray(data->getContent().value(), data->getContent().value_size())) {
1087 // _LOG_DEBUG("Errrrr.. Can not parse msg with name: " <<
1088 // data->getName() << ". what is happening?");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001089 // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
1090 msg.set_from("inconnu");
1091 msg.set_type(SyncDemo::ChatMessage::OTHER);
1092 corrupted = true;
1093 }
1094
Mengjin Yanaec70742014-08-25 10:37:45 -07001095 //std::cout << "onProcessData: " << show << std::endl;
1096 //std::cout << "onProcessData: " << corrupted << std::endl;
1097
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001098 // display msg received from network
1099 // we have to do so; this function is called by ccnd thread
1100 // so if we call appendMsg directly
1101 // Qt crash as "QObject: Cannot create children for a parent that is in a different thread"
1102 // the "cannonical" way to is use signal-slot
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001103 if (show && !corrupted) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001104 appendMessage(msg, isHistory);
1105 }
1106
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001107 if (!isHistory) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001108 // update the tree view
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001109 string prefix = data->getName().getPrefix(-2).toUri();
1110 // _LOG_DEBUG("<<< updating scene for" << prefix << ": " << msg.from());
1111 if (msg.type() == SyncDemo::ChatMessage::LEAVE) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001112 processRemove(prefix.c_str());
1113 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001114 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001115 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1116 m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
1117 }
1118 }
1119 fitView();
1120}
1121
1122void
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001123ChatDialog::onProcessTreeUpdate(const vector<Sync::MissingDataInfo>& v)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001124{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001125 // _LOG_DEBUG("<<< processing Tree Update");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001126
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001127 if (v.empty()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001128 return;
1129 }
1130
1131 // reflect the changes on digest tree
1132 {
1133 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1134 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
1135 }
1136
1137 int n = v.size();
1138 int totalMissingPackets = 0;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001139 for (int i = 0; i < n; i++) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001140 totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
1141 }
1142
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001143 for (int i = 0; i < n; i++) {
1144 if (totalMissingPackets < 4) {
1145 for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001146 m_sock->fetchData(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1), 2);
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001147 // _LOG_DEBUG("<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001148 }
1149 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001150 else {
1151 m_sock->fetchData(v[i].prefix, v[i].high,
1152 bind(&ChatDialog::processDataNoShowWrapper, this, _1), 2);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001153 }
1154 }
1155 // adjust the view
1156 fitView();
1157}
1158
1159void
1160ChatDialog::onReplot()
1161{
1162 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1163 m_scene->plot(m_sock->getRootDigest().c_str());
1164 fitView();
1165}
1166
1167void
1168ChatDialog::onRosterChanged(QStringList staleUserList)
1169{
1170 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1171 QStringList rosterList = m_scene->getRosterList();
1172 m_rosterModel->setStringList(rosterList);
1173 QString user;
1174 QStringListIterator it(staleUserList);
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001175 while (it.hasNext()) {
1176 string nick = it.next().toStdString();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001177 if (nick.empty())
1178 continue;
1179
1180 SyncDemo::ChatMessage msg;
1181 formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
1182 msg.set_from(nick);
1183 appendMessage(msg);
1184 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001185 plotTrustTree();
Mengjin Yanaec70742014-08-25 10:37:45 -07001186
1187 emit rosterChanged(*getChatroomInfo());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001188}
1189
1190void
1191ChatDialog::onInviteListDialogRequested()
1192{
Yingdi Yu233a9722014-03-07 15:47:09 -08001193 emit waitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001194 m_inviteListDialog->setInviteLabel(m_chatroomPrefix.toUri());
1195 m_inviteListDialog->show();
1196}
1197
1198void
1199ChatDialog::sendJoin()
1200{
1201 m_joined = true;
1202 SyncDemo::ChatMessage msg;
1203 formControlMessage(msg, SyncDemo::ChatMessage::JOIN);
1204 sendMsg(msg);
1205 boost::random::random_device rng;
1206 boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
1207 m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
1208 QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
1209}
1210
1211void
1212ChatDialog::sendHello()
1213{
Yingdi Yua7876722014-03-25 14:46:55 -07001214 int64_t now = time::toUnixTimestamp(time::system_clock::now()).count();
Mengjin Yanaec70742014-08-25 10:37:45 -07001215 int elapsed = (now - m_lastMsgTime) / 1000;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001216 if (elapsed >= m_randomizedInterval / 1000) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001217 SyncDemo::ChatMessage msg;
1218 formControlMessage(msg, SyncDemo::ChatMessage::HELLO);
1219 sendMsg(msg);
1220 boost::random::random_device rng;
1221 boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
1222 m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
1223 QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
1224 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001225 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001226 QTimer::singleShot((m_randomizedInterval - elapsed * 1000), this, SLOT(sendHello()));
1227 }
1228}
1229
1230void
1231ChatDialog::sendLeave()
1232{
1233 SyncDemo::ChatMessage msg;
1234 formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
1235 sendMsg(msg);
1236 usleep(500000);
1237 m_sock->leave();
1238 usleep(5000);
1239 m_joined = false;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001240 // _LOG_DEBUG("Sync REMOVE signal sent");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001241}
1242
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001243void ChatDialog::enableSyncTreeDisplay()
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001244{
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001245 ui->syncTreeButton->setEnabled(true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001246 // treeViewer->show();
1247 // fitView();
1248}
1249
1250void
1251ChatDialog::reap()
1252{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001253 if (m_zombieIndex < m_zombieList.size()) {
1254 string prefix = m_zombieList.at(m_zombieIndex).toStdString();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001255 m_sock->remove(prefix);
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001256 // _LOG_DEBUG("Reaped: prefix = " << prefix);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001257 m_zombieIndex++;
1258 // reap again in 10 seconds
1259 QTimer::singleShot(10000, this, SLOT(reap()));
1260 }
1261}
1262
1263void
1264ChatDialog::onSendInvitation(QString invitee)
1265{
1266 Name inviteeNamespace(invitee.toStdString());
1267 shared_ptr<Contact> inviteeItem = m_contactManager->getContact(inviteeNamespace);
1268 sendInvitation(inviteeItem, true);
1269}
1270
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001271void
1272ChatDialog::onReply(const Interest& interest,
Yingdi Yu233a9722014-03-07 15:47:09 -08001273 const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001274 size_t routablePrefixOffset,
1275 bool isIntroducer)
1276{
1277 OnDataValidated onValidated = bind(&ChatDialog::onReplyValidated,
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001278 this, _1,
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001279 //RoutablePrefix will be removed before passing to validator
1280 interest.getName().size()-routablePrefixOffset,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001281 isIntroducer);
1282
1283 OnDataValidationFailed onFailed = bind(&ChatDialog::onReplyValidationFailed,
1284 this, _1, _2);
1285
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001286 if (routablePrefixOffset > 0) {
1287 // It is an encapsulated packet, we only validate the inner packet.
1288 shared_ptr<Data> innerData = make_shared<Data>();
1289 innerData->wireDecode(data->getContent().blockFromValue());
1290 m_invitationValidator->validate(*innerData, onValidated, onFailed);
1291 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001292 else
Yingdi Yu233a9722014-03-07 15:47:09 -08001293 m_invitationValidator->validate(*data, onValidated, onFailed);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001294}
1295
1296void
Mengjin Yanaec70742014-08-25 10:37:45 -07001297ChatDialog::onReplyTimeout(const ndn::Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001298 size_t routablePrefixOffset)
1299{
1300 Name interestName;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001301 if (routablePrefixOffset > 0)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001302 interestName = interest.getName().getSubName(routablePrefixOffset);
1303 else
1304 interestName = interest.getName();
1305
1306 Invitation invitation(interestName);
1307
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001308 QString msg = QString::fromUtf8("Your invitation to ") +
1309 QString::fromStdString(invitation.getInviteeNameSpace().toUri()) + " times out!";
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001310 emit inivationRejection(msg);
1311}
1312
1313void
Mengjin Yanaec70742014-08-25 10:37:45 -07001314ChatDialog::onIntroCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001315{
1316 Data innerData;
Yingdi Yu233a9722014-03-07 15:47:09 -08001317 innerData.wireDecode(data->getContent().blockFromValue());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001318 Sync::IntroCertificate introCert(innerData);
1319 m_sock->addParticipant(introCert);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001320 plotTrustTree();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001321}
1322
1323void
Mengjin Yanaec70742014-08-25 10:37:45 -07001324ChatDialog::onIntroCertTimeout(const ndn::Interest& interest, int retry, const QString& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001325{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001326 // _LOG_DEBUG("onIntroCertTimeout: " << msg.toStdString());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001327}
1328
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001329} // namespace chronos
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001330
Mengjin Yanaec70742014-08-25 10:37:45 -07001331
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001332#if WAF
1333#include "chat-dialog.moc"
Yingdi Yu42125862014-08-07 17:04:28 -07001334// #include "chat-dialog.cpp.moc"
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001335#endif