blob: 53bfdb34db5c5f06ae212b3388d9fe6a3b54cf1a [file] [log] [blame]
Yingdi Yud45777b2014-10-16 23:54:11 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
Varun Patila24bd3e2020-11-24 10:08:33 +05303 * Copyright (c) 2013-2020, Regents of the University of California
Junxiao Shid5798f22016-08-22 02:33:26 +00004 * Yingdi Yu
Yingdi Yud45777b2014-10-16 23:54:11 -07005 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
Yingdi Yuf3401182015-02-02 20:21:07 -08009 * Qiuhan Ding <qiuhanding@cs.ucla.edu>
Yingdi Yud45777b2014-10-16 23:54:11 -070010 */
11
12#include "chat-dialog-backend.hpp"
13
Yingdi Yu45da92a2015-02-02 13:17:03 -080014#include <QFile>
15
Yingdi Yud45777b2014-10-16 23:54:11 -070016#ifndef Q_MOC_RUN
Junxiao Shid5798f22016-08-22 02:33:26 +000017#include <boost/iostreams/stream.hpp>
Yingdi Yud45777b2014-10-16 23:54:11 -070018#include <ndn-cxx/util/io.hpp>
Varun Patil3d850902020-11-23 12:19:14 +053019#include "cryptopp.hpp"
Yingdi Yud45777b2014-10-16 23:54:11 -070020#endif
21
Varun Patil3d850902020-11-23 12:19:14 +053022using namespace CryptoPP;
Yingdi Yud45777b2014-10-16 23:54:11 -070023
Yingdi Yueb692ac2015-02-10 18:46:18 -080024namespace chronochat {
Yingdi Yud45777b2014-10-16 23:54:11 -070025
26static const time::milliseconds FRESHNESS_PERIOD(60000);
27static const time::seconds HELLO_INTERVAL(60);
Qiuhan Dingba3e57a2015-01-08 19:07:39 -080028static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
29 ndn::name::Component::fromEscapedString("%F0%2E");
Qiuhan Ding43c8e162015-02-02 15:16:48 -080030static const int IDENTITY_OFFSET = -3;
Yingdi Yuf3401182015-02-02 20:21:07 -080031static const int CONNECTION_RETRY_TIMER = 3;
Yingdi Yud45777b2014-10-16 23:54:11 -070032
33ChatDialogBackend::ChatDialogBackend(const Name& chatroomPrefix,
34 const Name& userChatPrefix,
35 const Name& routingPrefix,
36 const std::string& chatroomName,
37 const std::string& nick,
Yingdi Yu45da92a2015-02-02 13:17:03 -080038 const Name& signingId,
Yingdi Yud45777b2014-10-16 23:54:11 -070039 QObject* parent)
40 : QThread(parent)
Yingdi Yuf3401182015-02-02 20:21:07 -080041 , m_shouldResume(false)
Yingdi Yud45777b2014-10-16 23:54:11 -070042 , m_localRoutingPrefix(routingPrefix)
43 , m_chatroomPrefix(chatroomPrefix)
44 , m_userChatPrefix(userChatPrefix)
45 , m_chatroomName(chatroomName)
46 , m_nick(nick)
Yingdi Yu45da92a2015-02-02 13:17:03 -080047 , m_signingId(signingId)
Yingdi Yud45777b2014-10-16 23:54:11 -070048{
49 updatePrefixes();
50}
51
52
53ChatDialogBackend::~ChatDialogBackend()
54{
55}
56
57// protected methods:
58void
59ChatDialogBackend::run()
60{
Yingdi Yu4647f022015-02-01 00:26:38 -080061 bool shouldResume = false;
62 do {
63 initializeSync();
Yingdi Yud45777b2014-10-16 23:54:11 -070064
Yingdi Yu4647f022015-02-01 00:26:38 -080065 if (m_face == nullptr)
66 break;
67
Yingdi Yuf3401182015-02-02 20:21:07 -080068 try {
69 m_face->getIoService().run();
70 }
Varun Patila24bd3e2020-11-24 10:08:33 +053071 catch (const std::runtime_error& e) {
Yingdi Yuf3401182015-02-02 20:21:07 -080072 {
73 std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
74 m_isNfdConnected = false;
75 }
76 emit nfdError();
77 {
78 std::lock_guard<std::mutex>lock(m_resumeMutex);
79 m_shouldResume = true;
80 }
81#ifdef BOOST_THREAD_USES_CHRONO
82 time::seconds reconnectTimer = time::seconds(CONNECTION_RETRY_TIMER);
83#else
84 boost::posix_time::time_duration reconnectTimer;
85 reconnectTimer = boost::posix_time::seconds(CONNECTION_RETRY_TIMER);
86#endif
87 while (!m_isNfdConnected) {
88#ifdef BOOST_THREAD_USES_CHRONO
89 boost::this_thread::sleep_for(reconnectTimer);
90#else
91 boost::this_thread::sleep(reconnectTimer);
92#endif
93 }
94 emit refreshChatDialog(m_routableUserChatPrefix);
95 }
Qiuhan Dingf22c41b2015-03-11 13:19:01 -070096 {
Yingdi Yuf3401182015-02-02 20:21:07 -080097 std::lock_guard<std::mutex>lock(m_resumeMutex);
Qiuhan Dingf22c41b2015-03-11 13:19:01 -070098 shouldResume = m_shouldResume;
99 m_shouldResume = false;
100 }
Yingdi Yuf3401182015-02-02 20:21:07 -0800101 close();
Yingdi Yu4647f022015-02-01 00:26:38 -0800102
103 } while (shouldResume);
Yingdi Yud45777b2014-10-16 23:54:11 -0700104
105 std::cerr << "Bye!" << std::endl;
106}
107
108// private methods:
109void
110ChatDialogBackend::initializeSync()
111{
Yingdi Yu4647f022015-02-01 00:26:38 -0800112 BOOST_ASSERT(m_sock == nullptr);
Yingdi Yud45777b2014-10-16 23:54:11 -0700113
Yingdi Yu45da92a2015-02-02 13:17:03 -0800114 m_face = make_shared<ndn::Face>();
Yingdi Yu4647f022015-02-01 00:26:38 -0800115 m_scheduler = unique_ptr<ndn::Scheduler>(new ndn::Scheduler(m_face->getIoService()));
Yingdi Yud45777b2014-10-16 23:54:11 -0700116
Yingdi Yu45da92a2015-02-02 13:17:03 -0800117 // initialize validator
Varun Patil3d850902020-11-23 12:19:14 +0530118 m_validator = make_shared<ndn::security::ValidatorConfig>(*m_face);
119 m_validator->load("security/validation-chat.conf");
Yingdi Yu45da92a2015-02-02 13:17:03 -0800120
Yingdi Yud45777b2014-10-16 23:54:11 -0700121 // create a new SyncSocket
122 m_sock = make_shared<chronosync::Socket>(m_chatroomPrefix,
123 m_routableUserChatPrefix,
Yingdi Yu4647f022015-02-01 00:26:38 -0800124 ref(*m_face),
Yingdi Yu45da92a2015-02-02 13:17:03 -0800125 bind(&ChatDialogBackend::processSyncUpdate, this, _1),
126 m_signingId,
127 m_validator);
Yingdi Yud45777b2014-10-16 23:54:11 -0700128
129 // schedule a new join event
Varun Patil3d850902020-11-23 12:19:14 +0530130 m_scheduler->schedule(time::milliseconds(600),
131 bind(&ChatDialogBackend::sendJoin, this));
Yingdi Yud45777b2014-10-16 23:54:11 -0700132
133 // cancel existing hello event if it exists
Varun Patila24bd3e2020-11-24 10:08:33 +0530134 if (m_helloEventId)
Varun Patil3d850902020-11-23 12:19:14 +0530135 m_helloEventId.cancel();
Yingdi Yud45777b2014-10-16 23:54:11 -0700136}
137
Yingdi Yu45da92a2015-02-02 13:17:03 -0800138class IoDeviceSource
139{
140public:
141 typedef char char_type;
142 typedef boost::iostreams::source_tag category;
143
144 explicit
145 IoDeviceSource(QIODevice& source)
146 : m_source(source)
147 {
148 }
149
150 std::streamsize
151 read(char* buffer, std::streamsize n)
152 {
153 return m_source.read(buffer, n);
154 }
155private:
156 QIODevice& m_source;
157};
158
Yingdi Yud45777b2014-10-16 23:54:11 -0700159void
Yingdi Yuf3401182015-02-02 20:21:07 -0800160ChatDialogBackend::exitChatroom() {
Yingdi Yu4647f022015-02-01 00:26:38 -0800161 if (m_joined)
162 sendLeave();
163
164 usleep(100000);
Yingdi Yuf3401182015-02-02 20:21:07 -0800165}
Yingdi Yu4647f022015-02-01 00:26:38 -0800166
Yingdi Yuf3401182015-02-02 20:21:07 -0800167void
168ChatDialogBackend::close()
169{
Yingdi Yu4647f022015-02-01 00:26:38 -0800170 m_scheduler->cancelAllEvents();
171 m_helloEventId.reset();
172 m_roster.clear();
Yingdi Yu45da92a2015-02-02 13:17:03 -0800173 m_validator.reset();
Yingdi Yu4647f022015-02-01 00:26:38 -0800174 m_sock.reset();
175}
176
177void
Yingdi Yud45777b2014-10-16 23:54:11 -0700178ChatDialogBackend::processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates)
179{
Yingdi Yud45777b2014-10-16 23:54:11 -0700180 if (updates.empty()) {
181 return;
182 }
183
184 std::vector<NodeInfo> nodeInfos;
185
186
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800187 for (size_t i = 0; i < updates.size(); i++) {
Yingdi Yud45777b2014-10-16 23:54:11 -0700188 // update roster
189 if (m_roster.find(updates[i].session) == m_roster.end()) {
190 m_roster[updates[i].session].sessionPrefix = updates[i].session;
191 m_roster[updates[i].session].hasNick = false;
192 }
193
194 // fetch missing chat data
195 if (updates[i].high - updates[i].low < 3) {
196 for (chronosync::SeqNo seq = updates[i].low; seq <= updates[i].high; ++seq) {
197 m_sock->fetchData(updates[i].session, seq,
Varun Patil3d850902020-11-23 12:19:14 +0530198 bind(&ChatDialogBackend::processChatData, this, _1, true, true),
199 bind(&ChatDialogBackend::processChatData, this, _1, true, false),
200 [] (const ndn::Interest& interest) {},
Yingdi Yud45777b2014-10-16 23:54:11 -0700201 2);
Yingdi Yud45777b2014-10-16 23:54:11 -0700202 }
203 }
204 else {
205 // There are too many msgs to fetch, let's just fetch the latest one
206 m_sock->fetchData(updates[i].session, updates[i].high,
Varun Patil3d850902020-11-23 12:19:14 +0530207 bind(&ChatDialogBackend::processChatData, this, _1, true, true),
208 bind(&ChatDialogBackend::processChatData, this, _1, true, false),
209 [] (const ndn::Interest& interest) {},
Yingdi Yud45777b2014-10-16 23:54:11 -0700210 2);
211 }
212
Yingdi Yud45777b2014-10-16 23:54:11 -0700213 }
214
215 // reflect the changes on GUI
216 emit syncTreeUpdated(nodeInfos,
217 QString::fromStdString(getHexEncodedDigest(m_sock->getRootDigest())));
218}
219
220void
Varun Patil3d850902020-11-23 12:19:14 +0530221ChatDialogBackend::processChatData(const ndn::Data& data,
Yingdi Yu45da92a2015-02-02 13:17:03 -0800222 bool needDisplay,
223 bool isValidated)
Yingdi Yud45777b2014-10-16 23:54:11 -0700224{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800225 ChatMessage msg;
Yingdi Yud45777b2014-10-16 23:54:11 -0700226
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800227 try {
Varun Patil3d850902020-11-23 12:19:14 +0530228 msg.wireDecode(data.getContent().blockFromValue());
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800229 }
Varun Patila24bd3e2020-11-24 10:08:33 +0530230 catch (const tlv::Error&) {
Yingdi Yud45777b2014-10-16 23:54:11 -0700231 // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800232 msg.setNick("inconnu");
233 msg.setMsgType(ChatMessage::OTHER);
Yingdi Yud45777b2014-10-16 23:54:11 -0700234 return;
235 }
236
Varun Patil3d850902020-11-23 12:19:14 +0530237 Name remoteSessionPrefix = data.getName().getPrefix(-1);
Yingdi Yud45777b2014-10-16 23:54:11 -0700238
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800239 if (msg.getMsgType() == ChatMessage::LEAVE) {
Yingdi Yud45777b2014-10-16 23:54:11 -0700240 BackendRoster::iterator it = m_roster.find(remoteSessionPrefix);
241
242 if (it != m_roster.end()) {
243 // cancel timeout event
Varun Patila24bd3e2020-11-24 10:08:33 +0530244 if (it->second.timeoutEventId)
Varun Patil3d850902020-11-23 12:19:14 +0530245 it->second.timeoutEventId.cancel();
Yingdi Yud45777b2014-10-16 23:54:11 -0700246
247 // notify frontend to remove the remote session (node)
248 emit sessionRemoved(QString::fromStdString(remoteSessionPrefix.toUri()),
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800249 QString::fromStdString(msg.getNick()),
250 msg.getTimestamp());
Yingdi Yud45777b2014-10-16 23:54:11 -0700251
252 // remove roster entry
253 m_roster.erase(remoteSessionPrefix);
Qiuhan Ding43c8e162015-02-02 15:16:48 -0800254
255 emit eraseInRoster(remoteSessionPrefix.getPrefix(IDENTITY_OFFSET),
256 Name::Component(m_chatroomName));
Yingdi Yud45777b2014-10-16 23:54:11 -0700257 }
258 }
259 else {
260 BackendRoster::iterator it = m_roster.find(remoteSessionPrefix);
261
262 if (it == m_roster.end()) {
263 // Should not happen
264 BOOST_ASSERT(false);
265 }
266
Varun Patil3d850902020-11-23 12:19:14 +0530267 uint64_t seqNo = data.getName().get(-1).toNumber();
Yingdi Yud45777b2014-10-16 23:54:11 -0700268
Yingdi Yud45777b2014-10-16 23:54:11 -0700269 // (Re)schedule another timeout event after 3 HELLO_INTERVAL;
270 it->second.timeoutEventId =
Varun Patil3d850902020-11-23 12:19:14 +0530271 m_scheduler->schedule(HELLO_INTERVAL * 3,
272 bind(&ChatDialogBackend::remoteSessionTimeout,
273 this, remoteSessionPrefix));
Yingdi Yud45777b2014-10-16 23:54:11 -0700274
275 // If chat message, notify the frontend
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800276 if (msg.getMsgType() == ChatMessage::CHAT) {
Yingdi Yu45da92a2015-02-02 13:17:03 -0800277 if (isValidated)
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800278 emit chatMessageReceived(QString::fromStdString(msg.getNick()),
279 QString::fromStdString(msg.getData()),
280 msg.getTimestamp());
Yingdi Yu45da92a2015-02-02 13:17:03 -0800281 else
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800282 emit chatMessageReceived(QString::fromStdString(msg.getNick() + " (Unverified)"),
283 QString::fromStdString(msg.getData()),
284 msg.getTimestamp());
Yingdi Yu45da92a2015-02-02 13:17:03 -0800285 }
Yingdi Yud45777b2014-10-16 23:54:11 -0700286
287 // Notify frontend to plot notification on DigestTree.
Qiuhan Ding7a4e7ef2015-02-03 20:25:50 -0800288
289 // If we haven't got any message from this session yet.
290 if (m_roster[remoteSessionPrefix].hasNick == false) {
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800291 m_roster[remoteSessionPrefix].userNick = msg.getNick();
Qiuhan Ding7a4e7ef2015-02-03 20:25:50 -0800292 m_roster[remoteSessionPrefix].hasNick = true;
293
294 emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()),
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800295 QString::fromStdString(msg.getNick()),
Qiuhan Ding7a4e7ef2015-02-03 20:25:50 -0800296 seqNo,
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800297 msg.getTimestamp(),
Qiuhan Ding7a4e7ef2015-02-03 20:25:50 -0800298 true);
299
300 emit addInRoster(remoteSessionPrefix.getPrefix(IDENTITY_OFFSET),
301 Name::Component(m_chatroomName));
302 }
303 else
304 emit messageReceived(QString::fromStdString(remoteSessionPrefix.toUri()),
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800305 QString::fromStdString(msg.getNick()),
Qiuhan Ding7a4e7ef2015-02-03 20:25:50 -0800306 seqNo,
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800307 msg.getTimestamp(),
Qiuhan Ding7a4e7ef2015-02-03 20:25:50 -0800308 false);
Yingdi Yud45777b2014-10-16 23:54:11 -0700309 }
310}
311
312void
313ChatDialogBackend::remoteSessionTimeout(const Name& sessionPrefix)
314{
315 time_t timestamp =
316 static_cast<time_t>(time::toUnixTimestamp(time::system_clock::now()).count() / 1000);
317
318 // notify frontend
319 emit sessionRemoved(QString::fromStdString(sessionPrefix.toUri()),
320 QString::fromStdString(m_roster[sessionPrefix].userNick),
321 timestamp);
322
323 // remove roster entry
324 m_roster.erase(sessionPrefix);
Qiuhan Ding43c8e162015-02-02 15:16:48 -0800325
326 emit eraseInRoster(sessionPrefix.getPrefix(IDENTITY_OFFSET),
327 Name::Component(m_chatroomName));
Yingdi Yud45777b2014-10-16 23:54:11 -0700328}
329
330void
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800331ChatDialogBackend::sendMsg(ChatMessage& msg)
Yingdi Yud45777b2014-10-16 23:54:11 -0700332{
333 // send msg
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800334 ndn::Block buf = msg.wireEncode();
Yingdi Yud45777b2014-10-16 23:54:11 -0700335
336 uint64_t nextSequence = m_sock->getLogic().getSeqNo() + 1;
337
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800338 m_sock->publishData(buf.wire(), buf.size(), FRESHNESS_PERIOD);
Yingdi Yud45777b2014-10-16 23:54:11 -0700339
340 std::vector<NodeInfo> nodeInfos;
Qiuhan Ding43c8e162015-02-02 15:16:48 -0800341 Name sessionName = m_sock->getLogic().getSessionName();
342 NodeInfo nodeInfo = {QString::fromStdString(sessionName.toUri()),
Yingdi Yud45777b2014-10-16 23:54:11 -0700343 nextSequence};
344 nodeInfos.push_back(nodeInfo);
345
346 emit syncTreeUpdated(nodeInfos,
347 QString::fromStdString(getHexEncodedDigest(m_sock->getRootDigest())));
Qiuhan Ding7a4e7ef2015-02-03 20:25:50 -0800348
349 emit messageReceived(QString::fromStdString(sessionName.toUri()),
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800350 QString::fromStdString(msg.getNick()),
Qiuhan Ding7a4e7ef2015-02-03 20:25:50 -0800351 nextSequence,
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800352 msg.getTimestamp(),
353 msg.getMsgType() == ChatMessage::JOIN);
Yingdi Yud45777b2014-10-16 23:54:11 -0700354}
355
356void
357ChatDialogBackend::sendJoin()
358{
359 m_joined = true;
360
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800361 ChatMessage msg;
362 prepareControlMessage(msg, ChatMessage::JOIN);
Yingdi Yud45777b2014-10-16 23:54:11 -0700363 sendMsg(msg);
364
Varun Patil3d850902020-11-23 12:19:14 +0530365 m_helloEventId = m_scheduler->schedule(HELLO_INTERVAL,
366 bind(&ChatDialogBackend::sendHello, this));
Yingdi Yuf3401182015-02-02 20:21:07 -0800367 emit newChatroomForDiscovery(Name::Component(m_chatroomName));
Yingdi Yud45777b2014-10-16 23:54:11 -0700368}
369
370void
371ChatDialogBackend::sendHello()
372{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800373 ChatMessage msg;
374 prepareControlMessage(msg, ChatMessage::HELLO);
Yingdi Yud45777b2014-10-16 23:54:11 -0700375 sendMsg(msg);
376
Varun Patil3d850902020-11-23 12:19:14 +0530377 m_helloEventId = m_scheduler->schedule(HELLO_INTERVAL,
378 bind(&ChatDialogBackend::sendHello, this));
Yingdi Yud45777b2014-10-16 23:54:11 -0700379}
380
381void
382ChatDialogBackend::sendLeave()
383{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800384 ChatMessage msg;
385 prepareControlMessage(msg, ChatMessage::LEAVE);
Yingdi Yud45777b2014-10-16 23:54:11 -0700386 sendMsg(msg);
387
Qiuhan Ding43c8e162015-02-02 15:16:48 -0800388 // get my own identity with routable prefix by getPrefix(-2)
389 emit eraseInRoster(m_routableUserChatPrefix.getPrefix(-2),
390 Name::Component(m_chatroomName));
391
Yingdi Yud45777b2014-10-16 23:54:11 -0700392 usleep(5000);
393 m_joined = false;
394}
395
396void
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800397ChatDialogBackend::prepareControlMessage(ChatMessage& msg,
398 ChatMessage::ChatMessageType type)
Yingdi Yud45777b2014-10-16 23:54:11 -0700399{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800400 msg.setNick(m_nick);
401 msg.setChatroomName(m_chatroomName);
Yingdi Yud45777b2014-10-16 23:54:11 -0700402 int32_t seconds =
403 static_cast<int32_t>(time::toUnixTimestamp(time::system_clock::now()).count() / 1000);
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800404 msg.setTimestamp(seconds);
405 msg.setMsgType(type);
Yingdi Yud45777b2014-10-16 23:54:11 -0700406}
407
408void
409ChatDialogBackend::prepareChatMessage(const QString& text,
410 time_t timestamp,
Varun Patila24bd3e2020-11-24 10:08:33 +0530411 ChatMessage& msg)
Yingdi Yud45777b2014-10-16 23:54:11 -0700412{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800413 msg.setNick(m_nick);
414 msg.setChatroomName(m_chatroomName);
415 msg.setData(text.toStdString());
416 msg.setTimestamp(timestamp);
417 msg.setMsgType(ChatMessage::CHAT);
Yingdi Yud45777b2014-10-16 23:54:11 -0700418}
419
420void
421ChatDialogBackend::updatePrefixes()
422{
423 m_routableUserChatPrefix.clear();
424
425 if (m_localRoutingPrefix.isPrefixOf(m_userChatPrefix))
426 m_routableUserChatPrefix = m_userChatPrefix;
427 else
428 m_routableUserChatPrefix.append(m_localRoutingPrefix)
Qiuhan Dingba3e57a2015-01-08 19:07:39 -0800429 .append(ROUTING_HINT_SEPARATOR)
Yingdi Yud45777b2014-10-16 23:54:11 -0700430 .append(m_userChatPrefix);
431
432 emit chatPrefixChanged(m_routableUserChatPrefix);
433}
434
435std::string
436ChatDialogBackend::getHexEncodedDigest(ndn::ConstBufferPtr digest)
437{
438 std::stringstream os;
439
Varun Patil3d850902020-11-23 12:19:14 +0530440 CryptoPP::StringSource(digest->data(), digest->size(), true,
Yingdi Yud45777b2014-10-16 23:54:11 -0700441 new CryptoPP::HexEncoder(new CryptoPP::FileSink(os), false));
442 return os.str();
443}
444
445
446// public slots:
447void
448ChatDialogBackend::sendChatMessage(QString text, time_t timestamp)
449{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800450 ChatMessage msg;
Yingdi Yud45777b2014-10-16 23:54:11 -0700451 prepareChatMessage(text, timestamp, msg);
452 sendMsg(msg);
453
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800454 emit chatMessageReceived(QString::fromStdString(msg.getNick()),
455 QString::fromStdString(msg.getData()),
456 msg.getTimestamp());
Yingdi Yud45777b2014-10-16 23:54:11 -0700457}
458
459void
460ChatDialogBackend::updateRoutingPrefix(const QString& localRoutingPrefix)
461{
462 Name newLocalRoutingPrefix(localRoutingPrefix.toStdString());
463
464 if (!newLocalRoutingPrefix.empty() && newLocalRoutingPrefix != m_localRoutingPrefix) {
465 // Update localPrefix
466 m_localRoutingPrefix = newLocalRoutingPrefix;
467
Qiuhan Dingf22c41b2015-03-11 13:19:01 -0700468 {
Yingdi Yuf3401182015-02-02 20:21:07 -0800469 std::lock_guard<std::mutex>lock(m_resumeMutex);
Qiuhan Dingf22c41b2015-03-11 13:19:01 -0700470 m_shouldResume = true;
471 }
Yingdi Yu4647f022015-02-01 00:26:38 -0800472
Yingdi Yuf3401182015-02-02 20:21:07 -0800473 exitChatroom();
Yingdi Yu4647f022015-02-01 00:26:38 -0800474
Qiuhan Ding112ee482015-03-11 11:54:11 -0700475 updatePrefixes();
476
Yingdi Yu4647f022015-02-01 00:26:38 -0800477 m_face->getIoService().stop();
Yingdi Yud45777b2014-10-16 23:54:11 -0700478 }
479}
480
481void
482ChatDialogBackend::shutdown()
483{
Qiuhan Dingf22c41b2015-03-11 13:19:01 -0700484 {
Yingdi Yuf3401182015-02-02 20:21:07 -0800485 std::lock_guard<std::mutex>lock(m_resumeMutex);
Qiuhan Dingf22c41b2015-03-11 13:19:01 -0700486 m_shouldResume = false;
487 }
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700488
Yingdi Yuf3401182015-02-02 20:21:07 -0800489 {
490 // In this case, we just stop checking the nfd connection and exit
491 std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
492 m_isNfdConnected = true;
493 }
494
495 exitChatroom();
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700496
Yingdi Yu4647f022015-02-01 00:26:38 -0800497 m_face->getIoService().stop();
Yingdi Yud45777b2014-10-16 23:54:11 -0700498}
499
Yingdi Yuf3401182015-02-02 20:21:07 -0800500void
501ChatDialogBackend::onNfdReconnect()
502{
503 std::lock_guard<std::mutex>lock(m_nfdConnectionMutex);
504 m_isNfdConnected = true;
505}
506
Yingdi Yueb692ac2015-02-10 18:46:18 -0800507} // namespace chronochat
Yingdi Yud45777b2014-10-16 23:54:11 -0700508
509#if WAF
510#include "chat-dialog-backend.moc"
Yingdi Yud45777b2014-10-16 23:54:11 -0700511#endif