blob: 0079f4f9d00ec38a7c4ffdaaaaab04781aa8f4da [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"
Yingdi Yud85e29f2014-09-09 17:20:04 -070029
30#define SECURITY_ENABLED false
Yingdi Yu348f5ea2014-03-01 14:47:25 -080031#endif
32
Yingdi Yu348f5ea2014-03-01 14:47:25 -080033
Yingdi Yu0b0a7362014-08-05 16:31:30 -070034// INIT_LOGGER("ChatDialog");
Yingdi Yu348f5ea2014-03-01 14:47:25 -080035
36Q_DECLARE_METATYPE(std::vector<Sync::MissingDataInfo> )
Yingdi Yu233a9722014-03-07 15:47:09 -080037Q_DECLARE_METATYPE(ndn::shared_ptr<const ndn::Data>)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080038Q_DECLARE_METATYPE(ndn::Interest)
39Q_DECLARE_METATYPE(size_t)
40
Yingdi Yu0b0a7362014-08-05 16:31:30 -070041
42namespace chronos {
43
44using std::vector;
45using std::string;
46using std::map;
47using std::queue;
48
49using ndn::IdentityCertificate;
50using ndn::SecRuleRelative;
51using ndn::Face;
52using ndn::OBufferStream;
53using ndn::OnDataValidated;
54using ndn::OnDataValidationFailed;
55
56
57static const int HELLO_INTERVAL = FRESHNESS * 3 / 4;
58static const uint8_t CHRONOS_RP_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
59
Yingdi Yu348f5ea2014-03-01 14:47:25 -080060ChatDialog::ChatDialog(ContactManager* contactManager,
61 shared_ptr<Face> face,
62 const IdentityCertificate& myCertificate,
63 const Name& chatroomPrefix,
Yingdi Yufa0b6a02014-04-30 14:26:42 -070064 const Name& localPrefix,
Yingdi Yu17032f82014-03-25 15:48:23 -070065 const std::string& nick,
Yingdi Yu348f5ea2014-03-01 14:47:25 -080066 bool withSecurity,
Yingdi Yufa0b6a02014-04-30 14:26:42 -070067 QWidget* parent)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080068 : QDialog(parent)
69 , ui(new Ui::ChatDialog)
70 , m_contactManager(contactManager)
71 , m_face(face)
72 , m_myCertificate(myCertificate)
Yingdi Yu0b0a7362014-08-05 16:31:30 -070073 , m_chatroomName(chatroomPrefix.get(-1).toUri())
Yingdi Yu348f5ea2014-03-01 14:47:25 -080074 , m_chatroomPrefix(chatroomPrefix)
75 , m_localPrefix(localPrefix)
76 , m_useRoutablePrefix(false)
77 , m_nick(nick)
Yingdi Yua7876722014-03-25 14:46:55 -070078 , m_lastMsgTime(time::toUnixTimestamp(time::system_clock::now()).count())
Yingdi Yu348f5ea2014-03-01 14:47:25 -080079 , m_joined(false)
80 , m_sock(NULL)
Yingdi Yua7876722014-03-25 14:46:55 -070081 , m_session(static_cast<uint64_t>(time::toUnixTimestamp(time::system_clock::now()).count()))
Yingdi Yu348f5ea2014-03-01 14:47:25 -080082 , m_inviteListDialog(new InviteListDialog)
Mengjin Yanaec70742014-08-25 10:37:45 -070083 //ymj
84 //, m_trustModel(withSecurity)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080085{
86 qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
Yingdi Yu233a9722014-03-07 15:47:09 -080087 qRegisterMetaType<ndn::shared_ptr<const ndn::Data> >("ndn.DataPtr");
Yingdi Yu348f5ea2014-03-01 14:47:25 -080088 qRegisterMetaType<ndn::Interest>("ndn.Interest");
89 qRegisterMetaType<size_t>("size_t");
90
91 m_scene = new DigestTreeScene(this);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -070092 m_trustScene = new TrustTreeScene(this);
Yingdi Yu348f5ea2014-03-01 14:47:25 -080093 m_rosterModel = new QStringListModel(this);
94 m_timer = new QTimer(this);
95
96 ui->setupUi(this);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -070097 ui->syncTreeViewer->setScene(m_scene);
Yingdi Yu348f5ea2014-03-01 14:47:25 -080098 m_scene->setSceneRect(m_scene->itemsBoundingRect());
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -070099 ui->syncTreeViewer->hide();
100 ui->trustTreeViewer->setScene(m_trustScene);
101 m_trustScene->setSceneRect(m_trustScene->itemsBoundingRect());
102 ui->trustTreeViewer->hide();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800103 ui->listView->setModel(m_rosterModel);
104
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700105 m_identity =
106 IdentityCertificate::certificateNameToPublicKeyName(m_myCertificate.getName()).getPrefix(-1);
Yingdi Yud85e29f2014-09-09 17:20:04 -0700107
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800108 updatePrefix();
Yingdi Yud85e29f2014-09-09 17:20:04 -0700109
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800110 updateLabels();
111
112 m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
113 m_scene->plot("Empty");
114
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700115 connect(ui->lineEdit, SIGNAL(returnPressed()),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800116 this, SLOT(onReturnPressed()));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700117 connect(ui->syncTreeButton, SIGNAL(pressed()),
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700118 this, SLOT(onSyncTreeButtonPressed()));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700119 connect(ui->trustTreeButton, SIGNAL(pressed()),
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700120 this, SLOT(onTrustTreeButtonPressed()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800121 connect(m_scene, SIGNAL(replot()),
122 this, SLOT(onReplot()));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700123 connect(m_scene, SIGNAL(rosterChanged(QStringList)),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800124 this, SLOT(onRosterChanged(QStringList)));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700125 connect(m_timer, SIGNAL(timeout()),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800126 this, SLOT(onReplot()));
127
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700128 connect(this, SIGNAL(processData(const ndn::shared_ptr<const ndn::Data>&, bool, bool)),
Yingdi Yu233a9722014-03-07 15:47:09 -0800129 this, SLOT(onProcessData(const ndn::shared_ptr<const ndn::Data>&, bool, bool)));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700130 connect(this, SIGNAL(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800131 this, SLOT(onProcessTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700132 connect(this, SIGNAL(reply(const ndn::Interest&,
133 const ndn::shared_ptr<const ndn::Data>&,
134 size_t, bool)),
135 this, SLOT(onReply(const ndn::Interest&,
136 const ndn::shared_ptr<const ndn::Data>&,
137 size_t, bool)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800138 connect(this, SIGNAL(replyTimeout(const ndn::Interest&, size_t)),
139 this, SLOT(onReplyTimeout(const ndn::Interest&, size_t)));
Yingdi Yu233a9722014-03-07 15:47:09 -0800140 connect(this, SIGNAL(introCert(const ndn::Interest&, const ndn::shared_ptr<const ndn::Data>&)),
141 this, SLOT(onIntroCert(const ndn::Interest&, const ndn::shared_ptr<const ndn::Data>&)));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800142 connect(this, SIGNAL(introCertTimeout(const ndn::Interest&, int, const QString&)),
143 this, SLOT(onIntroCertTimeout(const ndn::Interest&, int, const QString&)));
144
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700145 if (withSecurity) {
146 m_invitationValidator = make_shared<chronos::ValidatorInvitation>();
147 m_dataRule = make_shared<SecRuleRelative>("([^<CHRONOCHAT-DATA>]*)<CHRONOCHAT-DATA><>",
148 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
149 "==", "\\1", "\\1", true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800150
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700151 ui->inviteButton->setEnabled(true);
152 ui->trustTreeButton->setEnabled(true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800153
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700154 connect(ui->inviteButton, SIGNAL(clicked()),
155 this, SLOT(onInviteListDialogRequested()));
156 connect(m_inviteListDialog, SIGNAL(sendInvitation(const QString&)),
157 this, SLOT(onSendInvitation(const QString&)));
158 connect(this, SIGNAL(waitForContactList()),
159 m_contactManager, SLOT(onWaitForContactList()));
160 connect(m_contactManager, SIGNAL(contactAliasListReady(const QStringList&)),
161 m_inviteListDialog, SLOT(onContactAliasListReady(const QStringList&)));
162 connect(m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
163 m_inviteListDialog, SLOT(onContactIdListReady(const QStringList&)));
Mengjin Yanaec70742014-08-25 10:37:45 -0700164
165 m_trustModel = ChatroomInfo::TRUST_MODEL_WEBOFTRUST;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700166 }
Mengjin Yanaec70742014-08-25 10:37:45 -0700167 else
168 m_trustModel = ChatroomInfo::TRUST_MODEL_NONE;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800169
170 initializeSync();
171}
172
173
174ChatDialog::~ChatDialog()
175{
Yingdi Yud85e29f2014-09-09 17:20:04 -0700176 if (SECURITY_ENABLED) {
177 if (m_certListPrefixId)
178 m_face->unsetInterestFilter(m_certListPrefixId);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800179
Yingdi Yud85e29f2014-09-09 17:20:04 -0700180 if (m_certSinglePrefixId)
181 m_face->unsetInterestFilter(m_certSinglePrefixId);
182 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800183
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700184 if (m_sock != NULL) {
185 sendLeave();
186 delete m_sock;
187 m_sock = NULL;
188 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800189}
190
191// public methods:
192void
193ChatDialog::addSyncAnchor(const Invitation& invitation)
194{
Mengjin Yanaec70742014-08-25 10:37:45 -0700195 // _LOG_DEBUG("Add sync anchor from invitation");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800196 // Add inviter certificate as trust anchor.
197 m_sock->addParticipant(invitation.getInviterCertificate());
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700198 plotTrustTree();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800199
200 // Ask inviter for IntroCertificate
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700201 Name inviterNameSpace =
202 IdentityCertificate::certificateNameToPublicKeyName(
203 invitation.getInviterCertificate().getName()).getPrefix(-1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800204 fetchIntroCert(inviterNameSpace, invitation.getInviterRoutingPrefix());
205}
206
207void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700208ChatDialog::processTreeUpdateWrapper(const vector<Sync::MissingDataInfo>& v,
209 Sync::SyncSocket *sock)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800210{
211 emit processTreeUpdate(v);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700212 // _LOG_DEBUG("<<< Tree update signal emitted");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800213}
214
215void
216ChatDialog::processDataWrapper(const shared_ptr<const Data>& data)
217{
Yingdi Yu233a9722014-03-07 15:47:09 -0800218 emit processData(data, true, false);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700219 // _LOG_DEBUG("<<< " << data->getName() << " fetched");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800220}
221
222void
223ChatDialog::processDataNoShowWrapper(const shared_ptr<const Data>& data)
224{
Yingdi Yu233a9722014-03-07 15:47:09 -0800225 emit processData(data, false, false);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800226}
227
228void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700229ChatDialog::processRemoveWrapper(const string& prefix)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800230{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700231 // _LOG_DEBUG("Sync REMOVE signal received for prefix: " << prefix);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800232}
233
234// protected methods:
235void
236ChatDialog::closeEvent(QCloseEvent *e)
237{
238 QMessageBox::information(this, tr("ChronoChat"),
239 tr("The chatroom will keep running in the "
240 "system tray. To close the chatroom, "
241 "choose <b>Close chatroom</b> in the "
242 "context memu of the system tray entry."));
Yingdi Yue8323b62014-09-02 17:24:15 -0700243 hide();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800244 e->ignore();
245}
246
247void
Yingdi Yu233a9722014-03-07 15:47:09 -0800248ChatDialog::changeEvent(QEvent *e)
249{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700250 switch(e->type()) {
Yingdi Yu233a9722014-03-07 15:47:09 -0800251 case QEvent::ActivationChange:
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700252 if (isActiveWindow()) {
Yingdi Yu233a9722014-03-07 15:47:09 -0800253 emit resetIcon();
254 }
255 break;
256 default:
257 break;
258 }
259}
260
261void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800262ChatDialog::resizeEvent(QResizeEvent *e)
263{
264 fitView();
265}
266
267void
268ChatDialog::showEvent(QShowEvent *e)
269{
270 fitView();
271}
272
273// private methods:
274void
275ChatDialog::updatePrefix()
276{
277 m_certListPrefix.clear();
278 m_certSinglePrefix.clear();
279 m_localChatPrefix.clear();
280 m_chatPrefix.clear();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700281 m_chatPrefix.append(m_identity)
282 .append("CHRONOCHAT-DATA")
283 .append(m_chatroomName)
284 .append(getRandomString());
285 if (!m_localPrefix.isPrefixOf(m_identity)) {
286 m_useRoutablePrefix = true;
287 m_certListPrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
288 m_certSinglePrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
289 m_localChatPrefix.append(m_localPrefix).append(CHRONOS_RP_SEPARATOR, 2);
290 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800291 m_certListPrefix.append(m_identity).append("CHRONOCHAT-CERT-LIST").append(m_chatroomName);
292 m_certSinglePrefix.append(m_identity).append("CHRONOCHAT-CERT-SINGLE").append(m_chatroomName);
293 m_localChatPrefix.append(m_chatPrefix);
294
Yingdi Yud85e29f2014-09-09 17:20:04 -0700295 if (SECURITY_ENABLED) {
296 if (static_cast<bool>(m_certListPrefixId))
297 m_face->unsetInterestFilter(m_certListPrefixId);
Mengjin Yanaec70742014-08-25 10:37:45 -0700298
Yingdi Yud85e29f2014-09-09 17:20:04 -0700299 m_certListPrefixId = m_face->setInterestFilter(m_certListPrefix,
300 bind(&ChatDialog::onCertListInterest,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700301 this, _1, _2),
Yingdi Yud85e29f2014-09-09 17:20:04 -0700302 bind(&ChatDialog::onCertListRegisterFailed,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700303 this, _1, _2));
Yingdi Yud85e29f2014-09-09 17:20:04 -0700304
305 if (static_cast<bool>(m_certSinglePrefixId))
306 m_face->unsetInterestFilter(m_certSinglePrefixId);
307
308 m_certSinglePrefixId = m_face->setInterestFilter(m_certSinglePrefix,
309 bind(&ChatDialog::onCertSingleInterest,
310 this, _1, _2),
311 bind(&ChatDialog::onCertSingleRegisterFailed,
312 this, _1, _2));
313 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800314}
315
316void
317ChatDialog::updateLabels()
318{
319 QString settingDisp = QString("Chatroom: %1").arg(QString::fromStdString(m_chatroomName));
320 ui->infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
321 ui->infoLabel->setText(settingDisp);
322 QString prefixDisp;
323 Name privatePrefix("/private/local");
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700324 if (privatePrefix.isPrefixOf(m_localChatPrefix)) {
325 prefixDisp =
326 QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n"
327 "<Prefix = %1>")
328 .arg(QString::fromStdString(m_localChatPrefix.toUri()));
329 ui->prefixLabel->setStyleSheet(
330 "QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
331 }
332 else {
333 prefixDisp = QString("<Prefix = %1>")
334 .arg(QString::fromStdString(m_localChatPrefix.toUri()));
335 ui->prefixLabel->setStyleSheet(
336 "QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
337 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800338 ui->prefixLabel->setText(prefixDisp);
339}
340
341void
342ChatDialog::initializeSync()
343{
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700344
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800345 m_sock = new Sync::SyncSocket(m_chatroomPrefix,
346 m_chatPrefix,
347 m_session,
348 m_useRoutablePrefix,
349 m_localPrefix,
350 m_face,
351 m_myCertificate,
352 m_dataRule,
353 bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
354 bind(&ChatDialog::processRemoveWrapper, this, _1));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700355
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800356 usleep(100000);
357
358 QTimer::singleShot(600, this, SLOT(sendJoin()));
359 m_timer->start(FRESHNESS * 1000);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700360 disableSyncTreeDisplay();
361 QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800362}
363
364void
365ChatDialog::sendInvitation(shared_ptr<Contact> contact, bool isIntroducer)
366{
367 // Add invitee as a trust anchor.
368 m_invitationValidator->addTrustAnchor(contact->getPublicKeyName(),
369 contact->getPublicKey());
370
371 // Prepared an invitation interest without routable prefix.
372 Invitation invitation(contact->getNameSpace(),
373 m_chatroomName,
374 m_localPrefix,
375 m_myCertificate);
376 Interest tmpInterest(invitation.getUnsignedInterestName());
377 m_keyChain.sign(tmpInterest, m_myCertificate.getName());
378
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700379 // Get invitee's routable prefix
380 // (ideally it will do some DNS lookup, but we assume everyone use /ndn/broadcast
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800381 Name routablePrefix = getInviteeRoutablePrefix(contact->getNameSpace());
382
383 // Check if we need to prepend the routable prefix to the interest name.
384 bool requireRoutablePrefix = false;
385 Name interestName;
386 size_t routablePrefixOffset = 0;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700387 if (!routablePrefix.isPrefixOf(tmpInterest.getName())) {
388 interestName.append(routablePrefix).append(CHRONOS_RP_SEPARATOR, 2);
389 requireRoutablePrefix = true;
390 routablePrefixOffset = routablePrefix.size() + 1;
391 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800392 interestName.append(tmpInterest.getName());
393
394 // Send the invitation out
395 Interest interest(interestName);
396 interest.setMustBeFresh(true);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700397 // _LOG_DEBUG("sendInvitation: " << interest.getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800398 m_face->expressInterest(interest,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700399 bind(&ChatDialog::replyWrapper,
400 this, _1, _2, routablePrefixOffset, isIntroducer),
401 bind(&ChatDialog::replyTimeoutWrapper,
402 this, _1, routablePrefixOffset));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800403}
404
405void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700406ChatDialog::replyWrapper(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800407 Data& data,
408 size_t routablePrefixOffset,
409 bool isIntroducer)
410{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700411 // _LOG_DEBUG("ChatDialog::replyWrapper");
Yingdi Yu233a9722014-03-07 15:47:09 -0800412 emit reply(interest, data.shared_from_this(), routablePrefixOffset, isIntroducer);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700413 // _LOG_DEBUG("OK?");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800414}
415
416void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700417ChatDialog::replyTimeoutWrapper(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800418 size_t routablePrefixOffset)
419{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700420 // _LOG_DEBUG("ChatDialog::replyTimeoutWrapper");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800421 emit replyTimeout(interest, routablePrefixOffset);
422}
423
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700424void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800425ChatDialog::onReplyValidated(const shared_ptr<const Data>& data,
426 size_t inviteeRoutablePrefixOffset,
427 bool isIntroducer)
428{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700429 if (data->getName().size() <= inviteeRoutablePrefixOffset) {
430 Invitation invitation(data->getName());
431 invitationRejected(invitation.getInviteeNameSpace());
432 }
433 else {
434 Name inviteePrefix;
435 inviteePrefix.wireDecode(data->getName().get(inviteeRoutablePrefixOffset).blockFromValue());
436 IdentityCertificate inviteeCert;
437 inviteeCert.wireDecode(data->getContent().blockFromValue());
438 invitationAccepted(inviteeCert, inviteePrefix, isIntroducer);
439 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800440}
441
442void
443ChatDialog::onReplyValidationFailed(const shared_ptr<const Data>& data,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700444 const string& failureInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800445{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700446 // _LOG_DEBUG("Invitation reply cannot be validated: " + failureInfo + " ==> " +
447 // data->getName().toUri());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800448}
449
450void
451ChatDialog::invitationRejected(const Name& identity)
452{
453 QString msg = QString::fromStdString(identity.toUri()) + " rejected your invitation!";
454 emit inivationRejection(msg);
455}
456
457void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700458ChatDialog::invitationAccepted(const IdentityCertificate& inviteeCert,
459 const Name& inviteePrefix,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800460 bool isIntroducer)
461{
462 // Add invitee certificate as trust anchor.
463 m_sock->addParticipant(inviteeCert);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700464 plotTrustTree();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800465
466 // Ask invitee for IntroCertificate.
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700467 Name inviteeNameSpace =
468 IdentityCertificate::certificateNameToPublicKeyName(inviteeCert.getName()).getPrefix(-1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800469 fetchIntroCert(inviteeNameSpace, inviteePrefix);
470}
471
472void
473ChatDialog::fetchIntroCert(const Name& identity, const Name& prefix)
474{
475 Name interestName;
476
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700477 if (!prefix.isPrefixOf(identity))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800478 interestName.append(prefix).append(CHRONOS_RP_SEPARATOR, 2);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700479
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800480 interestName.append(identity)
481 .append("CHRONOCHAT-CERT-LIST")
482 .append(m_chatroomName)
483 .appendVersion();
484
485 Interest interest(interestName);
486 interest.setMustBeFresh(true);
487
488 m_face->expressInterest(interest,
489 bind(&ChatDialog::onIntroCertList, this, _1, _2),
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700490 bind(&ChatDialog::onIntroCertListTimeout, this, _1, 1,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800491 "IntroCertList: " + interestName.toUri()));
492}
493
494void
495ChatDialog::onIntroCertList(const Interest& interest, const Data& data)
496{
497 Chronos::IntroCertListMsg introCertList;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700498 if (!introCertList.ParseFromArray(data.getContent().value(), data.getContent().value_size()))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800499 return;
500
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700501 for (int i = 0; i < introCertList.certname_size(); i++) {
502 Name certName(introCertList.certname(i));
503 Interest interest(certName);
504 interest.setMustBeFresh(true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800505
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700506 // _LOG_DEBUG("onIntroCertList: to fetch " << certName);
Yingdi Yu233a9722014-03-07 15:47:09 -0800507
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700508 m_face->expressInterest(interest,
509 bind(&ChatDialog::introCertWrapper, this, _1, _2),
510 bind(&ChatDialog::introCertTimeoutWrapper, this, _1, 0,
511 QString("IntroCert: %1").arg(introCertList.certname(i).c_str())));
512 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800513}
514
515void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700516ChatDialog::onIntroCertListTimeout(const Interest& interest, int retry, const string& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800517{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700518 if (retry > 0) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800519 m_face->expressInterest(interest,
520 bind(&ChatDialog::onIntroCertList, this, _1, _2),
521 bind(&ChatDialog::onIntroCertListTimeout, this, _1, retry - 1, msg));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700522 }
523 else {
524 // _LOG_DEBUG(msg << " TIMEOUT!");
525 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800526}
527
528void
529ChatDialog::introCertWrapper(const Interest& interest, Data& data)
530{
Yingdi Yu233a9722014-03-07 15:47:09 -0800531 emit introCert(interest, data.shared_from_this());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800532}
533
534void
535ChatDialog::introCertTimeoutWrapper(const Interest& interest, int retry, const QString& msg)
536{
537 emit introCertTimeout(interest, retry, msg);
538}
539
540void
Mengjin Yanaec70742014-08-25 10:37:45 -0700541ChatDialog::onCertListInterest(const ndn::Name& prefix, const ndn::Interest& interest)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800542{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700543 vector<Name> certNameList;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800544 m_sock->getIntroCertNames(certNameList);
545
546 Chronos::IntroCertListMsg msg;
547
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700548 for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
549 Name certName;
550 certName.append(m_certSinglePrefix).append(*it);
551 msg.add_certname(certName.toUri());
552 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800553 OBufferStream os;
554 msg.SerializeToOstream(&os);
555
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700556 shared_ptr<Data> data = make_shared<Data>(interest.getName());
557 data->setContent(os.buf());
558 m_keyChain.sign(*data, m_myCertificate.getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800559
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700560 m_face->put(*data);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800561}
562
563void
Mengjin Yanaec70742014-08-25 10:37:45 -0700564ChatDialog::onCertListRegisterFailed(const ndn::Name& prefix, const std::string& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800565{
Yingdi Yud85e29f2014-09-09 17:20:04 -0700566 _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800567}
568
569void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700570ChatDialog::onCertSingleInterest(const Name& prefix, const Interest& interest)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800571{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700572 try {
573 Name certName = interest.getName().getSubName(prefix.size());
574 const Sync::IntroCertificate& introCert = m_sock->getIntroCertificate(certName);
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700575
576 shared_ptr<Data> data = make_shared<Data>(interest.getName());
577 data->setContent(introCert.wireEncode());
578 m_keyChain.sign(*data, m_myCertificate.getName());
579 m_face->put(*data);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700580 }
581 catch(Sync::SyncSocket::Error& e) {
582 return;
583 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800584}
585
586void
Mengjin Yanaec70742014-08-25 10:37:45 -0700587ChatDialog::onCertSingleRegisterFailed(const Name& prefix, const std::string& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800588{
Yingdi Yud85e29f2014-09-09 17:20:04 -0700589 _LOG_DEBUG("ChatDialog::onCertListRegisterFailed failed: " + msg);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800590}
591
592void
593ChatDialog::sendMsg(SyncDemo::ChatMessage &msg)
594{
595 // send msg
596 OBufferStream os;
597 msg.SerializeToOstream(&os);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700598
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700599 if (!msg.IsInitialized()) {
600 // _LOG_DEBUG("Errrrr.. msg was not probally initialized " << __FILE__ <<
601 // ":" << __LINE__ << ". what is happening?");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800602 abort();
603 }
Yingdi Yu233a9722014-03-07 15:47:09 -0800604 uint64_t nextSequence = m_sock->getNextSeq();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800605 m_sock->publishData(os.buf()->buf(), os.buf()->size(), FRESHNESS);
606
Yingdi Yua7876722014-03-25 14:46:55 -0700607 m_lastMsgTime = time::toUnixTimestamp(time::system_clock::now()).count();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800608
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700609 Sync::MissingDataInfo mdi = {m_localChatPrefix.toUri(),
610 Sync::SeqNo(0),
611 Sync::SeqNo(nextSequence)};
612 vector<Sync::MissingDataInfo> v;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800613 v.push_back(mdi);
614 {
615 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
616 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
617 m_scene->msgReceived(QString::fromStdString(m_localChatPrefix.toUri()),
618 QString::fromStdString(m_nick));
619 }
620}
621
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700622void ChatDialog::disableSyncTreeDisplay()
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800623{
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700624 ui->syncTreeButton->setEnabled(false);
625 ui->syncTreeViewer->hide();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800626 fitView();
627}
628
629void
630ChatDialog::appendMessage(const SyncDemo::ChatMessage msg, bool isHistory)
631{
632 boost::recursive_mutex::scoped_lock lock(m_msgMutex);
633
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700634 if (msg.type() == SyncDemo::ChatMessage::CHAT) {
635 if (!msg.has_data()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800636 return;
637 }
638
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700639 if (msg.from().empty() || msg.data().empty()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800640 return;
641 }
642
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700643 if (!msg.has_timestamp()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800644 return;
645 }
646
647 // if (m_history.size() == MAX_HISTORY_ENTRY)
648 // {
649 // m_history.dequeue();
650 // }
651
652 // m_history.enqueue(msg);
653
654 QTextCharFormat nickFormat;
655 nickFormat.setForeground(Qt::darkGreen);
656 nickFormat.setFontWeight(QFont::Bold);
657 nickFormat.setFontUnderline(true);
658 nickFormat.setUnderlineColor(Qt::gray);
659
660 QTextCursor cursor(ui->textEdit->textCursor());
661 cursor.movePosition(QTextCursor::End);
662 QTextTableFormat tableFormat;
663 tableFormat.setBorder(0);
664 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
665 QString from = QString("%1 ").arg(msg.from().c_str());
666 QTextTableCell fromCell = table->cellAt(0, 0);
667 fromCell.setFormat(nickFormat);
668 fromCell.firstCursorPosition().insertText(from);
669
670 time_t timestamp = msg.timestamp();
671 printTimeInCell(table, timestamp);
672
673 QTextCursor nextCursor(ui->textEdit->textCursor());
674 nextCursor.movePosition(QTextCursor::End);
675 table = nextCursor.insertTable(1, 1, tableFormat);
676 table->cellAt(0, 0).firstCursorPosition().insertText(QString::fromUtf8(msg.data().c_str()));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700677 if (!isHistory) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800678 showMessage(from, QString::fromUtf8(msg.data().c_str()));
679 }
680 }
681
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700682 if (msg.type() == SyncDemo::ChatMessage::JOIN || msg.type() == SyncDemo::ChatMessage::LEAVE) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800683 QTextCharFormat nickFormat;
684 nickFormat.setForeground(Qt::gray);
685 nickFormat.setFontWeight(QFont::Bold);
686 nickFormat.setFontUnderline(true);
687 nickFormat.setUnderlineColor(Qt::gray);
688
689 QTextCursor cursor(ui->textEdit->textCursor());
690 cursor.movePosition(QTextCursor::End);
691 QTextTableFormat tableFormat;
692 tableFormat.setBorder(0);
693 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
694 QString action;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700695 if (msg.type() == SyncDemo::ChatMessage::JOIN) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800696 action = "enters room";
697 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700698 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800699 action = "leaves room";
700 }
701
702 QString from = QString("%1 %2 ").arg(msg.from().c_str()).arg(action);
703 QTextTableCell fromCell = table->cellAt(0, 0);
704 fromCell.setFormat(nickFormat);
705 fromCell.firstCursorPosition().insertText(from);
706
707 time_t timestamp = msg.timestamp();
708 printTimeInCell(table, timestamp);
709 }
710
711 QScrollBar *bar = ui->textEdit->verticalScrollBar();
712 bar->setValue(bar->maximum());
713}
714
715void
716ChatDialog::processRemove(QString prefix)
717{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700718 // _LOG_DEBUG("<<< remove node for prefix" << prefix.toStdString());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800719
720 bool removed = m_scene->removeNode(prefix);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700721 if (removed) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800722 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
723 m_scene->plot(m_sock->getRootDigest().c_str());
724 }
725}
726
727Name
728ChatDialog::getInviteeRoutablePrefix(const Name& invitee)
729{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700730 return Name("/ndn/broadcast");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800731}
732
733void
734ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
735 msg.set_from(m_nick);
736 msg.set_to(m_chatroomName);
737 msg.set_data(text.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700738 int32_t seconds =
Mengjin Yanaec70742014-08-25 10:37:45 -0700739 static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800740 msg.set_timestamp(seconds);
741 msg.set_type(SyncDemo::ChatMessage::CHAT);
742}
743
744void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700745ChatDialog::formControlMessage(SyncDemo::ChatMessage &msg,
746 SyncDemo::ChatMessage::ChatMessageType type)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800747{
748 msg.set_from(m_nick);
749 msg.set_to(m_chatroomName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700750 int32_t seconds =
Mengjin Yanaec70742014-08-25 10:37:45 -0700751 static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count()/1000);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800752 msg.set_timestamp(seconds);
753 msg.set_type(type);
754}
755
756QString
757ChatDialog::formatTime(time_t timestamp)
758{
759 struct tm *tm_time = localtime(&timestamp);
760 int hour = tm_time->tm_hour;
761 QString amOrPM;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700762 if (hour > 12) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800763 hour -= 12;
764 amOrPM = "PM";
765 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700766 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800767 amOrPM = "AM";
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700768 if (hour == 0) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800769 hour = 12;
770 }
771 }
772
773 char textTime[12];
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700774 sprintf(textTime, "%d:%02d:%02d %s",
775 hour, tm_time->tm_min, tm_time->tm_sec, amOrPM.toStdString().c_str());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800776 return QString(textTime);
777}
778
779void
780ChatDialog::printTimeInCell(QTextTable *table, time_t timestamp)
781{
782 QTextCharFormat timeFormat;
783 timeFormat.setForeground(Qt::gray);
784 timeFormat.setFontUnderline(true);
785 timeFormat.setUnderlineColor(Qt::gray);
786 QTextTableCell timeCell = table->cellAt(0, 1);
787 timeCell.setFormat(timeFormat);
788 timeCell.firstCursorPosition().insertText(formatTime(timestamp));
789}
790
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700791string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800792ChatDialog::getRandomString()
793{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700794 uint32_t r = ndn::random::generateWord32();
Yingdi Yu17032f82014-03-25 15:48:23 -0700795 std::stringstream ss;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800796 {
797 using namespace CryptoPP;
798 StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
799 new HexEncoder(new FileSink(ss), false));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700800
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800801 }
802
803 return ss.str();
804}
805
806void
807ChatDialog::showMessage(const QString& from, const QString& data)
808{
809 if (!isActiveWindow())
810 emit showChatMessage(QString::fromStdString(m_chatroomName),
811 from, data);
812}
813
814void
815ChatDialog::fitView()
816{
817 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
818 QRectF rect = m_scene->itemsBoundingRect();
819 m_scene->setSceneRect(rect);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700820 ui->syncTreeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
821
822 QRectF trustRect = m_trustScene->itemsBoundingRect();
823 m_trustScene->setSceneRect(trustRect);
824 ui->trustTreeViewer->fitInView(m_trustScene->itemsBoundingRect(), Qt::KeepAspectRatio);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800825}
826
827void
828ChatDialog::summonReaper()
829{
830 Sync::SyncLogic &logic = m_sock->getLogic ();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700831 map<string, bool> branches = logic.getBranchPrefixes();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800832 QMap<QString, DisplayUserPtr> roster = m_scene->getRosterFull();
833
834 m_zombieList.clear();
835
836 QMapIterator<QString, DisplayUserPtr> it(roster);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700837 map<string, bool>::iterator mapIt;
838 while (it.hasNext()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800839 it.next();
840 DisplayUserPtr p = it.value();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700841 if (p != DisplayUserNullPtr) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800842 mapIt = branches.find(p->getPrefix().toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700843 if (mapIt != branches.end()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800844 mapIt->second = true;
845 }
846 }
847 }
848
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700849 for (mapIt = branches.begin(); mapIt != branches.end(); ++mapIt) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800850 // this is zombie. all active users should have been marked true
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700851 if (! mapIt->second) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800852 m_zombieList.append(mapIt->first.c_str());
853 }
854 }
855
856 m_zombieIndex = 0;
857
858 // start reaping
859 reap();
860}
861
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700862void
863ChatDialog::getTree(TrustTreeNodeList& nodeList)
864{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700865 typedef map<Name, shared_ptr<TrustTreeNode> > NodeMap;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700866
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700867 vector<Name> certNameList;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700868 NodeMap nodeMap;
869
870 m_sock->getIntroCertNames(certNameList);
871
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700872 for (vector<Name>::const_iterator it = certNameList.begin(); it != certNameList.end(); it++) {
873 Name introducerCertName;
874 Name introduceeCertName;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700875
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700876 introducerCertName.wireDecode(it->get(-2).blockFromValue());
877 introduceeCertName.wireDecode(it->get(-3).blockFromValue());
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700878
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700879 Name introducerName =
880 IdentityCertificate::certificateNameToPublicKeyName(introducerCertName).getPrefix(-1);
881 Name introduceeName =
882 IdentityCertificate::certificateNameToPublicKeyName(introduceeCertName).getPrefix(-1);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700883
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700884 NodeMap::iterator introducerIt = nodeMap.find(introducerName);
885 if (introducerIt == nodeMap.end()) {
886 shared_ptr<TrustTreeNode> introducerNode(new TrustTreeNode(introducerName));
887 nodeMap[introducerName] = introducerNode;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700888 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700889 shared_ptr<TrustTreeNode> erNode = nodeMap[introducerName];
890
891 NodeMap::iterator introduceeIt = nodeMap.find(introduceeName);
892 if (introduceeIt == nodeMap.end()) {
893 shared_ptr<TrustTreeNode> introduceeNode(new TrustTreeNode(introduceeName));
894 nodeMap[introduceeName] = introduceeNode;
895 }
896 shared_ptr<TrustTreeNode> eeNode = nodeMap[introduceeName];
897
898 erNode->addIntroducee(eeNode);
899 eeNode->addIntroducer(erNode);
900 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700901
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700902 nodeList.clear();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700903 queue<shared_ptr<TrustTreeNode> > nodeQueue;
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700904
905 NodeMap::iterator nodeIt = nodeMap.find(m_identity);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700906 if (nodeIt == nodeMap.end())
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700907 return;
908
909 nodeQueue.push(nodeIt->second);
910 nodeIt->second->setLevel(0);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700911 while (!nodeQueue.empty()) {
912 shared_ptr<TrustTreeNode>& node = nodeQueue.front();
913 node->setVisited();
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700914
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700915 TrustTreeNodeList& introducees = node->getIntroducees();
916 for (TrustTreeNodeList::iterator eeIt = introducees.begin();
917 eeIt != introducees.end(); eeIt++) {
918 // _LOG_DEBUG("introducee: " << (*eeIt)->name() <<
919 // " visited: " << std::boolalpha << (*eeIt)->visited());
920 if (!(*eeIt)->visited()) {
921 nodeQueue.push(*eeIt);
922 (*eeIt)->setLevel(node->level()+1);
923 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700924 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700925
926 nodeList.push_back(node);
927 nodeQueue.pop();
928 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -0700929}
930
931void
932ChatDialog::plotTrustTree()
933{
934 TrustTreeNodeList nodeList;
935
936 getTree(nodeList);
937 {
938 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
939 m_trustScene->plotTrustTree(nodeList);
940 fitView();
941 }
942}
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800943
Mengjin Yanaec70742014-08-25 10:37:45 -0700944shared_ptr<ChatroomInfo>
945ChatDialog::getChatroomInfo() const
946{
947 shared_ptr<ChatroomInfo> chatroom = make_shared<ChatroomInfo>();
948 chatroom->setName(Name::Component(m_chatroomName));
949
950 Roster roster = m_scene->getRosterFull();
951 Roster_iterator it = roster.begin();
952
953 for(it = roster.begin(); it != roster.end(); ++it )
954 {
955 Name participant = Name(it.key().toStdString()).getPrefix(-3);
956 chatroom->addParticipant(participant);
957 }
958
959 chatroom->setTrustModel(m_trustModel);
960 return chatroom;
961}
962
963
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800964// public slots:
965void
966ChatDialog::onLocalPrefixUpdated(const QString& localPrefix)
967{
968 Name newLocalPrefix(localPrefix.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700969 if (!newLocalPrefix.empty() && newLocalPrefix != m_localPrefix) {
970 // Update localPrefix
971 m_localPrefix = newLocalPrefix;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800972
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700973 updatePrefix();
974 updateLabels();
975 m_scene->setCurrentPrefix(QString(m_localChatPrefix.toUri().c_str()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800976
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700977 if (m_sock != NULL) {
978 {
979 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
980 m_scene->clearAll();
981 m_scene->plot("Empty");
982 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800983
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700984 ui->textEdit->clear();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700985
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700986 if (m_joined) {
987 sendLeave();
988 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800989
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700990 delete m_sock;
991 m_sock = NULL;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700992
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700993 usleep(100000);
994 m_sock = new Sync::SyncSocket(m_chatroomPrefix,
995 m_chatPrefix,
996 m_session,
997 m_useRoutablePrefix,
998 m_localPrefix,
999 m_face,
1000 m_myCertificate,
1001 m_dataRule,
1002 bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2),
1003 bind(&ChatDialog::processRemoveWrapper, this, _1));
1004 usleep(100000);
1005 QTimer::singleShot(600, this, SLOT(sendJoin()));
1006 m_timer->start(FRESHNESS * 1000);
1007 disableSyncTreeDisplay();
1008 QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001009 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001010 else
1011 initializeSync();
1012 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001013 else
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001014 if (m_sock == NULL)
1015 initializeSync();
1016
1017 fitView();
1018}
1019
1020void
Yingdi Yue8323b62014-09-02 17:24:15 -07001021ChatDialog::onShow()
1022{
1023 this->show();
1024 this->raise();
1025 this->activateWindow();
1026}
1027
1028void
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001029ChatDialog::onClose()
1030{
1031 hide();
1032 emit closeChatDialog(QString::fromStdString(m_chatroomName));
1033}
1034
1035
1036// private slots:
1037void
1038ChatDialog::onReturnPressed()
1039{
1040 QString text = ui->lineEdit->text();
1041 if (text.isEmpty())
1042 return;
1043
1044 ui->lineEdit->clear();
1045
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001046 if (text.startsWith("boruoboluomi")) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001047 summonReaper ();
1048 // reapButton->show();
1049 fitView();
1050 return;
1051 }
1052
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001053 if (text.startsWith("minimanihong")) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001054 // reapButton->hide();
1055 fitView();
1056 return;
1057 }
1058
1059 SyncDemo::ChatMessage msg;
1060 formChatMessage(text, msg);
1061
1062 appendMessage(msg);
1063
1064 sendMsg(msg);
1065
1066 fitView();
1067}
1068
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001069void
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001070ChatDialog::onSyncTreeButtonPressed()
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001071{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001072 if (ui->syncTreeViewer->isVisible()) {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001073 ui->syncTreeViewer->hide();
1074 ui->syncTreeButton->setText("Show ChronoSync Tree");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001075 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001076 else {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001077 ui->syncTreeViewer->show();
1078 ui->syncTreeButton->setText("Hide ChronoSync Tree");
1079 }
1080
1081 fitView();
1082}
1083
1084void
1085ChatDialog::onTrustTreeButtonPressed()
1086{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001087 if (ui->trustTreeViewer->isVisible()) {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001088 ui->trustTreeViewer->hide();
1089 ui->trustTreeButton->setText("Show Trust Tree");
1090 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001091 else {
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001092 ui->trustTreeViewer->show();
1093 ui->trustTreeButton->setText("Hide Trust Tree");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001094 }
1095
1096 fitView();
1097}
1098
1099void
Mengjin Yanaec70742014-08-25 10:37:45 -07001100ChatDialog::onProcessData(const ndn::shared_ptr<const ndn::Data>& data, bool show, bool isHistory)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001101{
1102 SyncDemo::ChatMessage msg;
1103 bool corrupted = false;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001104 if (!msg.ParseFromArray(data->getContent().value(), data->getContent().value_size())) {
1105 // _LOG_DEBUG("Errrrr.. Can not parse msg with name: " <<
1106 // data->getName() << ". what is happening?");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001107 // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
1108 msg.set_from("inconnu");
1109 msg.set_type(SyncDemo::ChatMessage::OTHER);
1110 corrupted = true;
1111 }
1112
Mengjin Yanaec70742014-08-25 10:37:45 -07001113 //std::cout << "onProcessData: " << show << std::endl;
1114 //std::cout << "onProcessData: " << corrupted << std::endl;
1115
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001116 // display msg received from network
1117 // we have to do so; this function is called by ccnd thread
1118 // so if we call appendMsg directly
1119 // Qt crash as "QObject: Cannot create children for a parent that is in a different thread"
1120 // the "cannonical" way to is use signal-slot
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001121 if (show && !corrupted) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001122 appendMessage(msg, isHistory);
1123 }
1124
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001125 if (!isHistory) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001126 // update the tree view
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001127 string prefix = data->getName().getPrefix(-2).toUri();
1128 // _LOG_DEBUG("<<< updating scene for" << prefix << ": " << msg.from());
1129 if (msg.type() == SyncDemo::ChatMessage::LEAVE) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001130 processRemove(prefix.c_str());
1131 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001132 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001133 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1134 m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
1135 }
1136 }
1137 fitView();
1138}
1139
1140void
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001141ChatDialog::onProcessTreeUpdate(const vector<Sync::MissingDataInfo>& v)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001142{
Yingdi Yud85e29f2014-09-09 17:20:04 -07001143 _LOG_DEBUG("<<< processing Tree Update");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001144
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001145 if (v.empty()) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001146 return;
1147 }
1148
1149 // reflect the changes on digest tree
1150 {
1151 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1152 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
1153 }
1154
1155 int n = v.size();
1156 int totalMissingPackets = 0;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001157 for (int i = 0; i < n; i++) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001158 totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
1159 }
1160
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001161 for (int i = 0; i < n; i++) {
1162 if (totalMissingPackets < 4) {
1163 for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001164 m_sock->fetchData(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1), 2);
Yingdi Yud85e29f2014-09-09 17:20:04 -07001165 _LOG_DEBUG("<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001166 }
1167 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001168 else {
1169 m_sock->fetchData(v[i].prefix, v[i].high,
1170 bind(&ChatDialog::processDataNoShowWrapper, this, _1), 2);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001171 }
1172 }
1173 // adjust the view
1174 fitView();
1175}
1176
1177void
1178ChatDialog::onReplot()
1179{
1180 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1181 m_scene->plot(m_sock->getRootDigest().c_str());
1182 fitView();
1183}
1184
1185void
1186ChatDialog::onRosterChanged(QStringList staleUserList)
1187{
1188 boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
1189 QStringList rosterList = m_scene->getRosterList();
1190 m_rosterModel->setStringList(rosterList);
1191 QString user;
1192 QStringListIterator it(staleUserList);
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001193 while (it.hasNext()) {
1194 string nick = it.next().toStdString();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001195 if (nick.empty())
1196 continue;
1197
1198 SyncDemo::ChatMessage msg;
1199 formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
1200 msg.set_from(nick);
1201 appendMessage(msg);
1202 }
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001203 plotTrustTree();
Mengjin Yanaec70742014-08-25 10:37:45 -07001204
1205 emit rosterChanged(*getChatroomInfo());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001206}
1207
1208void
1209ChatDialog::onInviteListDialogRequested()
1210{
Yingdi Yu233a9722014-03-07 15:47:09 -08001211 emit waitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001212 m_inviteListDialog->setInviteLabel(m_chatroomPrefix.toUri());
1213 m_inviteListDialog->show();
1214}
1215
1216void
1217ChatDialog::sendJoin()
1218{
1219 m_joined = true;
1220 SyncDemo::ChatMessage msg;
1221 formControlMessage(msg, SyncDemo::ChatMessage::JOIN);
1222 sendMsg(msg);
1223 boost::random::random_device rng;
1224 boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
1225 m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
1226 QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
1227}
1228
1229void
1230ChatDialog::sendHello()
1231{
Yingdi Yua7876722014-03-25 14:46:55 -07001232 int64_t now = time::toUnixTimestamp(time::system_clock::now()).count();
Mengjin Yanaec70742014-08-25 10:37:45 -07001233 int elapsed = (now - m_lastMsgTime) / 1000;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001234 if (elapsed >= m_randomizedInterval / 1000) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001235 SyncDemo::ChatMessage msg;
1236 formControlMessage(msg, SyncDemo::ChatMessage::HELLO);
1237 sendMsg(msg);
1238 boost::random::random_device rng;
1239 boost::random::uniform_int_distribution<> uniform(1, FRESHNESS / 5 * 1000);
1240 m_randomizedInterval = HELLO_INTERVAL * 1000 + uniform(rng);
1241 QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
1242 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001243 else {
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001244 QTimer::singleShot((m_randomizedInterval - elapsed * 1000), this, SLOT(sendHello()));
1245 }
1246}
1247
1248void
1249ChatDialog::sendLeave()
1250{
1251 SyncDemo::ChatMessage msg;
1252 formControlMessage(msg, SyncDemo::ChatMessage::LEAVE);
1253 sendMsg(msg);
1254 usleep(500000);
1255 m_sock->leave();
1256 usleep(5000);
1257 m_joined = false;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001258 // _LOG_DEBUG("Sync REMOVE signal sent");
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001259}
1260
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001261void ChatDialog::enableSyncTreeDisplay()
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001262{
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001263 ui->syncTreeButton->setEnabled(true);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001264 // treeViewer->show();
1265 // fitView();
1266}
1267
1268void
1269ChatDialog::reap()
1270{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001271 if (m_zombieIndex < m_zombieList.size()) {
1272 string prefix = m_zombieList.at(m_zombieIndex).toStdString();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001273 m_sock->remove(prefix);
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001274 // _LOG_DEBUG("Reaped: prefix = " << prefix);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001275 m_zombieIndex++;
1276 // reap again in 10 seconds
1277 QTimer::singleShot(10000, this, SLOT(reap()));
1278 }
1279}
1280
1281void
1282ChatDialog::onSendInvitation(QString invitee)
1283{
1284 Name inviteeNamespace(invitee.toStdString());
1285 shared_ptr<Contact> inviteeItem = m_contactManager->getContact(inviteeNamespace);
1286 sendInvitation(inviteeItem, true);
1287}
1288
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001289void
1290ChatDialog::onReply(const Interest& interest,
Yingdi Yu233a9722014-03-07 15:47:09 -08001291 const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001292 size_t routablePrefixOffset,
1293 bool isIntroducer)
1294{
1295 OnDataValidated onValidated = bind(&ChatDialog::onReplyValidated,
Yingdi Yufa0b6a02014-04-30 14:26:42 -07001296 this, _1,
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001297 //RoutablePrefix will be removed before passing to validator
1298 interest.getName().size()-routablePrefixOffset,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001299 isIntroducer);
1300
1301 OnDataValidationFailed onFailed = bind(&ChatDialog::onReplyValidationFailed,
1302 this, _1, _2);
1303
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001304 if (routablePrefixOffset > 0) {
1305 // It is an encapsulated packet, we only validate the inner packet.
1306 shared_ptr<Data> innerData = make_shared<Data>();
1307 innerData->wireDecode(data->getContent().blockFromValue());
1308 m_invitationValidator->validate(*innerData, onValidated, onFailed);
1309 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001310 else
Yingdi Yu233a9722014-03-07 15:47:09 -08001311 m_invitationValidator->validate(*data, onValidated, onFailed);
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001312}
1313
1314void
Mengjin Yanaec70742014-08-25 10:37:45 -07001315ChatDialog::onReplyTimeout(const ndn::Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001316 size_t routablePrefixOffset)
1317{
1318 Name interestName;
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001319 if (routablePrefixOffset > 0)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001320 interestName = interest.getName().getSubName(routablePrefixOffset);
1321 else
1322 interestName = interest.getName();
1323
1324 Invitation invitation(interestName);
1325
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001326 QString msg = QString::fromUtf8("Your invitation to ") +
1327 QString::fromStdString(invitation.getInviteeNameSpace().toUri()) + " times out!";
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001328 emit inivationRejection(msg);
1329}
1330
1331void
Mengjin Yanaec70742014-08-25 10:37:45 -07001332ChatDialog::onIntroCert(const ndn::Interest& interest, const ndn::shared_ptr<const ndn::Data>& data)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001333{
1334 Data innerData;
Yingdi Yu233a9722014-03-07 15:47:09 -08001335 innerData.wireDecode(data->getContent().blockFromValue());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001336 Sync::IntroCertificate introCert(innerData);
1337 m_sock->addParticipant(introCert);
Yingdi Yuf4aaa8b2014-03-10 11:24:31 -07001338 plotTrustTree();
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001339}
1340
1341void
Mengjin Yanaec70742014-08-25 10:37:45 -07001342ChatDialog::onIntroCertTimeout(const ndn::Interest& interest, int retry, const QString& msg)
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001343{
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001344 // _LOG_DEBUG("onIntroCertTimeout: " << msg.toStdString());
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001345}
1346
Yingdi Yu0b0a7362014-08-05 16:31:30 -07001347} // namespace chronos
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001348
Mengjin Yanaec70742014-08-25 10:37:45 -07001349
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001350#if WAF
1351#include "chat-dialog.moc"
Yingdi Yu42125862014-08-07 17:04:28 -07001352// #include "chat-dialog.cpp.moc"
Yingdi Yu348f5ea2014-03-01 14:47:25 -08001353#endif