blob: 334f3457a1ce953bfe44e1f62aa5d0b36e011601 [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
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700547 shared_ptr<Data> data = make_shared<Data>(interest.getName());
548 data->setContent(os.buf());
549 m_keyChain.sign(*data, m_myCertificate.getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800550
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700551 m_face->put(*data);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800552}
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);
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700566
567 shared_ptr<Data> data = make_shared<Data>(interest.getName());
568 data->setContent(introCert.wireEncode());
569 m_keyChain.sign(*data, m_myCertificate.getName());
570 m_face->put(*data);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700571 }
572 catch(Sync::SyncSocket::Error& e) {
573 return;
574 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800575}
576
577void
Mengjin Yanaec70742014-08-25 10:37:45 -0700578ChatDialog::onCertSingleRegisterFailed(const Name& prefix, const std::string& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800579{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700580 // _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800581}
582
583void
584ChatDialog::sendMsg(SyncDemo::ChatMessage &msg)
585{
586 // send msg
587 OBufferStream os;
588 msg.SerializeToOstream(&os);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700589
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700590 if (!msg.IsInitialized()) {
591 // _LOG_DEBUG("Errrrr.. msg was not probally initialized " << __FILE__ <<
592 // ":" << __LINE__ << ". what is happening?");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800593 abort();
594 }
Yingdi Yu233a9722014-03-07 15:47:09 -0800595 uint64_t nextSequence = m_sock->getNextSeq();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800596 m_sock->publishData(os.buf()->buf(), os.buf()->size(), FRESHNESS);
597
Yingdi Yua7876722014-03-25 14:46:55 -0700598 m_lastMsgTime = time::toUnixTimestamp(time::system_clock::now()).count();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800599
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700600 Sync::MissingDataInfo mdi = {m_localChatPrefix.toUri(),
601 Sync::SeqNo(0),
602 Sync::SeqNo(nextSequence)};
603 vector<Sync::MissingDataInfo> v;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800604 v.push_back(mdi);
605 {
606 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
607 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
608 m_scene->msgReceived(QString::fromStdString(m_localChatPrefix.toUri()),
609 QString::fromStdString(m_nick));
610 }
611}
612
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700613void ChatDialog::disableSyncTreeDisplay()
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800614{
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700615 ui->syncTreeButton->setEnabled(false);
616 ui->syncTreeViewer->hide();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800617 fitView();
618}
619
620void
621ChatDialog::appendMessage(const SyncDemo::ChatMessage msg, bool isHistory)
622{
623 boost::recursive_mutex::scoped_lock lock(m_msgMutex);
624
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700625 if (msg.type() == SyncDemo::ChatMessage::CHAT) {
626 if (!msg.has_data()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800627 return;
628 }
629
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700630 if (msg.from().empty() || msg.data().empty()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800631 return;
632 }
633
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700634 if (!msg.has_timestamp()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800635 return;
636 }
637
638 // if (m_history.size() == MAX_HISTORY_ENTRY)
639 // {
640 // m_history.dequeue();
641 // }
642
643 // m_history.enqueue(msg);
644
645 QTextCharFormat nickFormat;
646 nickFormat.setForeground(Qt::darkGreen);
647 nickFormat.setFontWeight(QFont::Bold);
648 nickFormat.setFontUnderline(true);
649 nickFormat.setUnderlineColor(Qt::gray);
650
651 QTextCursor cursor(ui->textEdit->textCursor());
652 cursor.movePosition(QTextCursor::End);
653 QTextTableFormat tableFormat;
654 tableFormat.setBorder(0);
655 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
656 QString from = QString("%1 ").arg(msg.from().c_str());
657 QTextTableCell fromCell = table->cellAt(0, 0);
658 fromCell.setFormat(nickFormat);
659 fromCell.firstCursorPosition().insertText(from);
660
661 time_t timestamp = msg.timestamp();
662 printTimeInCell(table, timestamp);
663
664 QTextCursor nextCursor(ui->textEdit->textCursor());
665 nextCursor.movePosition(QTextCursor::End);
666 table = nextCursor.insertTable(1, 1, tableFormat);
667 table->cellAt(0, 0).firstCursorPosition().insertText(QString::fromUtf8(msg.data().c_str()));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700668 if (!isHistory) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800669 showMessage(from, QString::fromUtf8(msg.data().c_str()));
670 }
671 }
672
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700673 if (msg.type() == SyncDemo::ChatMessage::JOIN || msg.type() == SyncDemo::ChatMessage::LEAVE) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800674 QTextCharFormat nickFormat;
675 nickFormat.setForeground(Qt::gray);
676 nickFormat.setFontWeight(QFont::Bold);
677 nickFormat.setFontUnderline(true);
678 nickFormat.setUnderlineColor(Qt::gray);
679
680 QTextCursor cursor(ui->textEdit->textCursor());
681 cursor.movePosition(QTextCursor::End);
682 QTextTableFormat tableFormat;
683 tableFormat.setBorder(0);
684 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
685 QString action;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700686 if (msg.type() == SyncDemo::ChatMessage::JOIN) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800687 action = "enters room";
688 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700689 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800690 action = "leaves room";
691 }
692
693 QString from = QString("%1 %2 ").arg(msg.from().c_str()).arg(action);
694 QTextTableCell fromCell = table->cellAt(0, 0);
695 fromCell.setFormat(nickFormat);
696 fromCell.firstCursorPosition().insertText(from);
697
698 time_t timestamp = msg.timestamp();
699 printTimeInCell(table, timestamp);
700 }
701
702 QScrollBar *bar = ui->textEdit->verticalScrollBar();
703 bar->setValue(bar->maximum());
704}
705
706void
707ChatDialog::processRemove(QString prefix)
708{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700709 // _LOG_DEBUG("<<< remove node for prefix" << prefix.toStdString());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800710
711 bool removed = m_scene->removeNode(prefix);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700712 if (removed) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800713 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
714 m_scene->plot(m_sock->getRootDigest().c_str());
715 }
716}
717
718Name
719ChatDialog::getInviteeRoutablePrefix(const Name& invitee)
720{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700721 return Name("/ndn/broadcast");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800722}
723
724void
725ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
726 msg.set_from(m_nick);
727 msg.set_to(m_chatroomName);
728 msg.set_data(text.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700729 int32_t seconds =
Mengjin Yanaec70742014-08-25 10:37:45 -0700730 static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800731 msg.set_timestamp(seconds);
732 msg.set_type(SyncDemo::ChatMessage::CHAT);
733}
734
735void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700736ChatDialog::formControlMessage(SyncDemo::ChatMessage &msg,
737 SyncDemo::ChatMessage::ChatMessageType type)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800738{
739 msg.set_from(m_nick);
740 msg.set_to(m_chatroomName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700741 int32_t seconds =
Mengjin Yanaec70742014-08-25 10:37:45 -0700742 static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800743 msg.set_timestamp(seconds);
744 msg.set_type(type);
745}
746
747QString
748ChatDialog::formatTime(time_t timestamp)
749{
750 struct tm *tm_time = localtime(&timestamp);
751 int hour = tm_time->tm_hour;
752 QString amOrPM;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700753 if (hour > 12) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800754 hour -= 12;
755 amOrPM = "PM";
756 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700757 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800758 amOrPM = "AM";
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700759 if (hour == 0) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800760 hour = 12;
761 }
762 }
763
764 char textTime[12];
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700765 sprintf(textTime, "%d:%02d:%02d %s",
766 hour, tm_time->tm_min, tm_time->tm_sec, amOrPM.toStdString().c_str());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800767 return QString(textTime);
768}
769
770void
771ChatDialog::printTimeInCell(QTextTable *table, time_t timestamp)
772{
773 QTextCharFormat timeFormat;
774 timeFormat.setForeground(Qt::gray);
775 timeFormat.setFontUnderline(true);
776 timeFormat.setUnderlineColor(Qt::gray);
777 QTextTableCell timeCell = table->cellAt(0, 1);
778 timeCell.setFormat(timeFormat);
779 timeCell.firstCursorPosition().insertText(formatTime(timestamp));
780}
781
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700782string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800783ChatDialog::getRandomString()
784{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700785 uint32_t r = ndn::random::generateWord32();
Yingdi Yu17032f82014-03-25 15:48:23 -0700786 std::stringstream ss;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800787 {
788 using namespace CryptoPP;
789 StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
790 new HexEncoder(new FileSink(ss), false));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700791
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800792 }
793
794 return ss.str();
795}
796
797void
798ChatDialog::showMessage(const QString& from, const QString& data)
799{
800 if (!isActiveWindow())
801 emit showChatMessage(QString::fromStdString(m_chatroomName),
802 from, data);
803}
804
805void
806ChatDialog::fitView()
807{
808 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
809 QRectF rect = m_scene->itemsBoundingRect();
810 m_scene->setSceneRect(rect);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700811 ui->syncTreeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
812
813 QRectF trustRect = m_trustScene->itemsBoundingRect();
814 m_trustScene->setSceneRect(trustRect);
815 ui->trustTreeViewer->fitInView(m_trustScene->itemsBoundingRect(), Qt::KeepAspectRatio);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800816}
817
818void
819ChatDialog::summonReaper()
820{
821 Sync::SyncLogic &logic = m_sock->getLogic ();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700822 map<string, bool> branches = logic.getBranchPrefixes();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800823 QMap<QString, DisplayUserPtr> roster = m_scene->getRosterFull();
824
825 m_zombieList.clear();
826
827 QMapIterator<QString, DisplayUserPtr> it(roster);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700828 map<string, bool>::iterator mapIt;
829 while (it.hasNext()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800830 it.next();
831 DisplayUserPtr p = it.value();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700832 if (p != DisplayUserNullPtr) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800833 mapIt = branches.find(p->getPrefix().toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700834 if (mapIt != branches.end()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800835 mapIt->second = true;
836 }
837 }
838 }
839
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700840 for (mapIt = branches.begin(); mapIt != branches.end(); ++mapIt) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800841 // this is zombie. all active users should have been marked true
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700842 if (! mapIt->second) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800843 m_zombieList.append(mapIt->first.c_str());
844 }
845 }
846
847 m_zombieIndex = 0;
848
849 // start reaping
850 reap();
851}
852
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700853void
854ChatDialog::getTree(TrustTreeNodeList& nodeList)
855{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700856 typedef map<Name, shared_ptr<TrustTreeNode> > NodeMap;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700857
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700858 vector<Name> certNameList;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700859 NodeMap nodeMap;
860
861 m_sock->getIntroCertNames(certNameList);
862
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700863 for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
864 Name introducerCertName;
865 Name introduceeCertName;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700866
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700867 introducerCertName.wireDecode(it->get(-2).blockFromValue());
868 introduceeCertName.wireDecode(it->get(-3).blockFromValue());
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700869
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700870 Name introducerName =
871 IdentityCertificate::certificateNameToPublicKeyName(introducerCertName).getPrefix(-1);
872 Name introduceeName =
873 IdentityCertificate::certificateNameToPublicKeyName(introduceeCertName).getPrefix(-1);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700874
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700875 NodeMap::iterator introducerIt = nodeMap.find(introducerName);
876 if (introducerIt == nodeMap.end()) {
877 shared_ptr<TrustTreeNode> introducerNode(new TrustTreeNode(introducerName));
878 nodeMap[introducerName] = introducerNode;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700879 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700880 shared_ptr<TrustTreeNode> erNode = nodeMap[introducerName];
881
882 NodeMap::iterator introduceeIt = nodeMap.find(introduceeName);
883 if (introduceeIt == nodeMap.end()) {
884 shared_ptr<TrustTreeNode> introduceeNode(new TrustTreeNode(introduceeName));
885 nodeMap[introduceeName] = introduceeNode;
886 }
887 shared_ptr<TrustTreeNode> eeNode = nodeMap[introduceeName];
888
889 erNode->addIntroducee(eeNode);
890 eeNode->addIntroducer(erNode);
891 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700892
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700893 nodeList.clear();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700894 queue<shared_ptr<TrustTreeNode> > nodeQueue;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700895
896 NodeMap::iterator nodeIt = nodeMap.find(m_identity);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700897 if (nodeIt == nodeMap.end())
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700898 return;
899
900 nodeQueue.push(nodeIt->second);
901 nodeIt->second->setLevel(0);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700902 while (!nodeQueue.empty()) {
903 shared_ptr<TrustTreeNode>& node = nodeQueue.front();
904 node->setVisited();
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700905
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700906 TrustTreeNodeList& introducees = node->getIntroducees();
907 for (TrustTreeNodeList::iterator eeIt = introducees.begin();
908 eeIt != introducees.end(); eeIt++) {
909 // _LOG_DEBUG("introducee: " << (*eeIt)->name() <<
910 // " visited: " << std::boolalpha << (*eeIt)->visited());
911 if (!(*eeIt)->visited()) {
912 nodeQueue.push(*eeIt);
913 (*eeIt)->setLevel(node->level()+1);
914 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700915 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700916
917 nodeList.push_back(node);
918 nodeQueue.pop();
919 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700920}
921
922void
923ChatDialog::plotTrustTree()
924{
925 TrustTreeNodeList nodeList;
926
927 getTree(nodeList);
928 {
929 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
930 m_trustScene->plotTrustTree(nodeList);
931 fitView();
932 }
933}
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800934
Mengjin Yanaec70742014-08-25 10:37:45 -0700935shared_ptr<ChatroomInfo>
936ChatDialog::getChatroomInfo() const
937{
938 shared_ptr<ChatroomInfo> chatroom = make_shared<ChatroomInfo>();
939 chatroom->setName(Name::Component(m_chatroomName));
940
941 Roster roster = m_scene->getRosterFull();
942 Roster_iterator it = roster.begin();
943
944 for(it = roster.begin(); it != roster.end(); ++it )
945 {
946 Name participant = Name(it.key().toStdString()).getPrefix(-3);
947 chatroom->addParticipant(participant);
948 }
949
950 chatroom->setTrustModel(m_trustModel);
951 return chatroom;
952}
953
954
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800955// public slots:
956void
957ChatDialog::onLocalPrefixUpdated(const QString& localPrefix)
958{
959 Name newLocalPrefix(localPrefix.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700960 if (!newLocalPrefix.empty() && newLocalPrefix != m_localPrefix) {
961 // Update localPrefix
962 m_localPrefix = newLocalPrefix;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800963
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700964 updatePrefix();
965 updateLabels();
966 m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800967
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700968 if (m_sock != NULL) {
969 {
970 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
971 m_scene->clearAll();
972 m_scene->plot("Empty");
973 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800974
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700975 ui->textEdit->clear();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700976
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700977 if (m_joined) {
978 sendLeave();
979 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800980
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700981 delete m_sock;
982 m_sock = NULL;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700983
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700984 usleep(100000);
985 m_sock = new Sync::SyncSocket(m_chatroomPrefix,
986 m_chatPrefix,
987 m_session,
988 m_useRoutablePrefix,
989 m_localPrefix,
990 m_face,
991 m_myCertificate,
992 m_dataRule,
993 bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
994 bind(&ChatDialog::processRemoveWrapper, this, _1));
995 usleep(100000);
996 QTimer::singleShot(600, this, SLOT(sendJoin()));
997 m_timer->start(FRESHNESS * 1000);
998 disableSyncTreeDisplay();
999 QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001000 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001001 else
1002 initializeSync();
1003 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001004 else
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001005 if (m_sock == NULL)
1006 initializeSync();
1007
1008 fitView();
1009}
1010
1011void
1012ChatDialog::onClose()
1013{
1014 hide();
1015 emit closeChatDialog(QString::fromStdString(m_chatroomName));
1016}
1017
1018
1019// private slots:
1020void
1021ChatDialog::onReturnPressed()
1022{
1023 QString text = ui->lineEdit->text();
1024 if (text.isEmpty())
1025 return;
1026
1027 ui->lineEdit->clear();
1028
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001029 if (text.startsWith("boruoboluomi")) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001030 summonReaper ();
1031 // reapButton->show();
1032 fitView();
1033 return;
1034 }
1035
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001036 if (text.startsWith("minimanihong")) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001037 // reapButton->hide();
1038 fitView();
1039 return;
1040 }
1041
1042 SyncDemo::ChatMessage msg;
1043 formChatMessage(text, msg);
1044
1045 appendMessage(msg);
1046
1047 sendMsg(msg);
1048
1049 fitView();
1050}
1051
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001052void
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001053ChatDialog::onSyncTreeButtonPressed()
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001054{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001055 if (ui->syncTreeViewer->isVisible()) {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001056 ui->syncTreeViewer->hide();
1057 ui->syncTreeButton->setText("Show ChronoSync Tree");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001058 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001059 else {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001060 ui->syncTreeViewer->show();
1061 ui->syncTreeButton->setText("Hide ChronoSync Tree");
1062 }
1063
1064 fitView();
1065}
1066
1067void
1068ChatDialog::onTrustTreeButtonPressed()
1069{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001070 if (ui->trustTreeViewer->isVisible()) {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001071 ui->trustTreeViewer->hide();
1072 ui->trustTreeButton->setText("Show Trust Tree");
1073 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001074 else {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001075 ui->trustTreeViewer->show();
1076 ui->trustTreeButton->setText("Hide Trust Tree");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001077 }
1078
1079 fitView();
1080}
1081
1082void
Mengjin Yanaec70742014-08-25 10:37:45 -07001083ChatDialog::onProcessData(const ndn::shared_ptr<const ndn::Data>& data, bool show, bool isHistory)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001084{
1085 SyncDemo::ChatMessage msg;
1086 bool corrupted = false;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001087 if (!msg.ParseFromArray(data->getContent().value(), data->getContent().value_size())) {
1088 // _LOG_DEBUG("Errrrr.. Can not parse msg with name: " <<
1089 // data->getName() << ". what is happening?");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001090 // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
1091 msg.set_from("inconnu");
1092 msg.set_type(SyncDemo::ChatMessage::OTHER);
1093 corrupted = true;
1094 }
1095
Mengjin Yanaec70742014-08-25 10:37:45 -07001096 //std::cout << "onProcessData: " << show << std::endl;
1097 //std::cout << "onProcessData: " << corrupted << std::endl;
1098
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001099 // display msg received from network
1100 // we have to do so; this function is called by ccnd thread
1101 // so if we call appendMsg directly
1102 // Qt crash as "QObject: Cannot create children for a parent that is in a different thread"
1103 // the "cannonical" way to is use signal-slot
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001104 if (show && !corrupted) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001105 appendMessage(msg, isHistory);
1106 }
1107
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001108 if (!isHistory) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001109 // update the tree view
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001110 string prefix = data->getName().getPrefix(-2).toUri();
1111 // _LOG_DEBUG("<<< updating scene for" << prefix << ": " << msg.from());
1112 if (msg.type() == SyncDemo::ChatMessage::LEAVE) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001113 processRemove(prefix.c_str());
1114 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001115 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001116 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1117 m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
1118 }
1119 }
1120 fitView();
1121}
1122
1123void
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001124ChatDialog::onProcessTreeUpdate(const vector<Sync::MissingDataInfo>& v)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001125{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001126 // _LOG_DEBUG("<<< processing Tree Update");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001127
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001128 if (v.empty()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001129 return;
1130 }
1131
1132 // reflect the changes on digest tree
1133 {
1134 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1135 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
1136 }
1137
1138 int n = v.size();
1139 int totalMissingPackets = 0;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001140 for (int i = 0; i < n; i++) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001141 totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
1142 }
1143
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001144 for (int i = 0; i < n; i++) {
1145 if (totalMissingPackets < 4) {
1146 for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001147 m_sock->fetchData(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1), 2);
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001148 // _LOG_DEBUG("<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001149 }
1150 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001151 else {
1152 m_sock->fetchData(v[i].prefix, v[i].high,
1153 bind(&ChatDialog::processDataNoShowWrapper, this, _1), 2);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001154 }
1155 }
1156 // adjust the view
1157 fitView();
1158}
1159
1160void
1161ChatDialog::onReplot()
1162{
1163 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1164 m_scene->plot(m_sock->getRootDigest().c_str());
1165 fitView();
1166}
1167
1168void
1169ChatDialog::onRosterChanged(QStringList staleUserList)
1170{
1171 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1172 QStringList rosterList = m_scene->getRosterList();
1173 m_rosterModel->setStringList(rosterList);
1174 QString user;
1175 QStringListIterator it(staleUserList);
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001176 while (it.hasNext()) {
1177 string nick = it.next().toStdString();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001178 if (nick.empty())
1179 continue;
1180
1181 SyncDemo::ChatMessage msg;
1182 formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
1183 msg.set_from(nick);
1184 appendMessage(msg);
1185 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001186 plotTrustTree();
Mengjin Yanaec70742014-08-25 10:37:45 -07001187
1188 emit rosterChanged(*getChatroomInfo());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001189}
1190
1191void
1192ChatDialog::onInviteListDialogRequested()
1193{
Yingdi Yu233a9722014-03-07 15:47:09 -08001194 emit waitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001195 m_inviteListDialog->setInviteLabel(m_chatroomPrefix.toUri());
1196 m_inviteListDialog->show();
1197}
1198
1199void
1200ChatDialog::sendJoin()
1201{
1202 m_joined = true;
1203 SyncDemo::ChatMessage msg;
1204 formControlMessage(msg, SyncDemo::ChatMessage::JOIN);
1205 sendMsg(msg);
1206 boost::random::random_device rng;
1207 boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
1208 m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
1209 QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
1210}
1211
1212void
1213ChatDialog::sendHello()
1214{
Yingdi Yua7876722014-03-25 14:46:55 -07001215 int64_t now = time::toUnixTimestamp(time::system_clock::now()).count();
Mengjin Yanaec70742014-08-25 10:37:45 -07001216 int elapsed = (now - m_lastMsgTime) / 1000;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001217 if (elapsed >= m_randomizedInterval / 1000) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001218 SyncDemo::ChatMessage msg;
1219 formControlMessage(msg, SyncDemo::ChatMessage::HELLO);
1220 sendMsg(msg);
1221 boost::random::random_device rng;
1222 boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
1223 m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
1224 QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
1225 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001226 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001227 QTimer::singleShot((m_randomizedInterval - elapsed * 1000), this, SLOT(sendHello()));
1228 }
1229}
1230
1231void
1232ChatDialog::sendLeave()
1233{
1234 SyncDemo::ChatMessage msg;
1235 formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
1236 sendMsg(msg);
1237 usleep(500000);
1238 m_sock->leave();
1239 usleep(5000);
1240 m_joined = false;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001241 // _LOG_DEBUG("Sync REMOVE signal sent");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001242}
1243
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001244void ChatDialog::enableSyncTreeDisplay()
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001245{
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001246 ui->syncTreeButton->setEnabled(true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001247 // treeViewer->show();
1248 // fitView();
1249}
1250
1251void
1252ChatDialog::reap()
1253{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001254 if (m_zombieIndex < m_zombieList.size()) {
1255 string prefix = m_zombieList.at(m_zombieIndex).toStdString();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001256 m_sock->remove(prefix);
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001257 // _LOG_DEBUG("Reaped: prefix = " << prefix);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001258 m_zombieIndex++;
1259 // reap again in 10 seconds
1260 QTimer::singleShot(10000, this, SLOT(reap()));
1261 }
1262}
1263
1264void
1265ChatDialog::onSendInvitation(QString invitee)
1266{
1267 Name inviteeNamespace(invitee.toStdString());
1268 shared_ptr<Contact> inviteeItem = m_contactManager->getContact(inviteeNamespace);
1269 sendInvitation(inviteeItem, true);
1270}
1271
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001272void
1273ChatDialog::onReply(const Interest& interest,
Yingdi Yu233a9722014-03-07 15:47:09 -08001274 const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001275 size_t routablePrefixOffset,
1276 bool isIntroducer)
1277{
1278 OnDataValidated onValidated = bind(&ChatDialog::onReplyValidated,
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001279 this, _1,
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001280 //RoutablePrefix will be removed before passing to validator
1281 interest.getName().size()-routablePrefixOffset,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001282 isIntroducer);
1283
1284 OnDataValidationFailed onFailed = bind(&ChatDialog::onReplyValidationFailed,
1285 this, _1, _2);
1286
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001287 if (routablePrefixOffset > 0) {
1288 // It is an encapsulated packet, we only validate the inner packet.
1289 shared_ptr<Data> innerData = make_shared<Data>();
1290 innerData->wireDecode(data->getContent().blockFromValue());
1291 m_invitationValidator->validate(*innerData, onValidated, onFailed);
1292 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001293 else
Yingdi Yu233a9722014-03-07 15:47:09 -08001294 m_invitationValidator->validate(*data, onValidated, onFailed);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001295}
1296
1297void
Mengjin Yanaec70742014-08-25 10:37:45 -07001298ChatDialog::onReplyTimeout(const ndn::Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001299 size_t routablePrefixOffset)
1300{
1301 Name interestName;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001302 if (routablePrefixOffset > 0)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001303 interestName = interest.getName().getSubName(routablePrefixOffset);
1304 else
1305 interestName = interest.getName();
1306
1307 Invitation invitation(interestName);
1308
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001309 QString msg = QString::fromUtf8("Your invitation to ") +
1310 QString::fromStdString(invitation.getInviteeNameSpace().toUri()) + " times out!";
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001311 emit inivationRejection(msg);
1312}
1313
1314void
Mengjin Yanaec70742014-08-25 10:37:45 -07001315ChatDialog::onIntroCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001316{
1317 Data innerData;
Yingdi Yu233a9722014-03-07 15:47:09 -08001318 innerData.wireDecode(data->getContent().blockFromValue());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001319 Sync::IntroCertificate introCert(innerData);
1320 m_sock->addParticipant(introCert);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001321 plotTrustTree();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001322}
1323
1324void
Mengjin Yanaec70742014-08-25 10:37:45 -07001325ChatDialog::onIntroCertTimeout(const ndn::Interest& interest, int retry, const QString& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001326{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001327 // _LOG_DEBUG("onIntroCertTimeout: " << msg.toStdString());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001328}
1329
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001330} // namespace chronos
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001331
Mengjin Yanaec70742014-08-25 10:37:45 -07001332
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001333#if WAF
1334#include "chat-dialog.moc"
Yingdi Yu42125862014-08-07 17:04:28 -07001335// #include "chat-dialog.cpp.moc"
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001336#endif