blob: 0dbbfd20eed40abb8f5d27e89e9267482310f18a [file] [log] [blame]
taylorchuc27dd482014-05-17 20:06:49 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014, Regents of the University of California,
4 *
5 * This file is part of NFD Control Center. See AUTHORS.md for complete list of NFD
6 * authors and contributors.
7 *
8 * NFD Control Center is free software: you can redistribute it and/or modify it under the
9 * terms of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * NFD Control Center is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with NFD
17 * Control Center, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <QtQml/QQmlApplicationEngine>
21#include <QtWidgets/QApplication>
Alexander Afanasyev4086d512014-07-11 15:56:33 -070022#include <QtWidgets/QPushButton>
taylorchuc27dd482014-05-17 20:06:49 -070023#include <QtQml/QQmlContext>
24
25#include "forwarder-status.hpp"
26#include "fib-status.hpp"
27#include "tray-menu.hpp"
28
29#include <ndn-cxx/face.hpp>
Alexander Afanasyev4086d512014-07-11 15:56:33 -070030#include <ndn-cxx/util/scheduler.hpp>
taylorchuc27dd482014-05-17 20:06:49 -070031#include <boost/thread.hpp>
32
33namespace ndn {
34
35class Ncc
36{
37public:
38 Ncc()
39 : m_isActive(true)
Alexander Afanasyev4086d512014-07-11 15:56:33 -070040 , m_scheduler(m_face.getIoService())
taylorchuc27dd482014-05-17 20:06:49 -070041 , m_fibModel(m_face)
Alexander Afanasyev4086d512014-07-11 15:56:33 -070042 , m_tray(m_engine.rootContext())
taylorchuc27dd482014-05-17 20:06:49 -070043 {
44 QQmlContext* context = m_engine.rootContext();
45
Alexander Afanasyev4086d512014-07-11 15:56:33 -070046 context->setContextProperty("forwarderModel", &m_forwarderStatusModel);
taylorchuc27dd482014-05-17 20:06:49 -070047 context->setContextProperty("fibModel", &m_fibModel);
48 context->setContextProperty("trayModel", &m_tray);
49
50 m_engine.load((QUrl("qrc:/main.qml")));
51
52 m_nfdThread = boost::thread(&Ncc::nfdConnectionLoop, this);
53 }
54
55 void
56 nfdConnectionLoop()
57 {
58 try {
59#ifdef BOOST_THREAD_USES_CHRONO
60 time::seconds retryTimeout = time::seconds(5);
61#else
62 boost::posix_time::time_duration retryTimeout = boost::posix_time::seconds(1);
63#endif
64
65 while (m_isActive) {
66 try {
67 while (m_isActive) {
68 m_face.expressInterest(Interest("/localhost/nfd/status"),
Alexander Afanasyev4086d512014-07-11 15:56:33 -070069 bind(&Ncc::onStatusRetrieved, this, _2),
taylorchuc27dd482014-05-17 20:06:49 -070070 bind(&Ncc::onStatusTimeout, this));
71 m_face.processEvents(time::milliseconds::zero(), true);
72 }
73 }
Alexander Afanasyev4086d512014-07-11 15:56:33 -070074 catch (const std::exception&e) {
taylorchuc27dd482014-05-17 20:06:49 -070075 emit m_tray.nfdActivityUpdate(false);
Alexander Afanasyev8e986f82016-03-21 14:19:15 -070076 m_face.shutdown();
taylorchuc27dd482014-05-17 20:06:49 -070077#ifdef BOOST_THREAD_USES_CHRONO
78 boost::this_thread::sleep_for(retryTimeout);
79#else
80 boost::this_thread::sleep(retryTimeout);
81#endif
82 }
83 }
84 }
85 catch (const boost::thread_interrupted&) {
86 // done
87 }
88 }
89
90 void
Alexander Afanasyev4086d512014-07-11 15:56:33 -070091 onStatusRetrieved(const Data& data)
taylorchuc27dd482014-05-17 20:06:49 -070092 {
93 emit m_tray.nfdActivityUpdate(true);
Alexander Afanasyev4086d512014-07-11 15:56:33 -070094 emit m_forwarderStatusModel.onDataReceived(data.shared_from_this());
95
96 m_scheduler.scheduleEvent(time::seconds(6), bind(&Ncc::requestNfdStatus, this));
taylorchuc27dd482014-05-17 20:06:49 -070097 }
98
99 void
100 onStatusTimeout()
101 {
102 emit m_tray.nfdActivityUpdate(false);
103
104 std::cerr << "Should not really happen, most likely a serious problem" << std::endl;
Alexander Afanasyev4086d512014-07-11 15:56:33 -0700105 m_scheduler.scheduleEvent(time::seconds(6), bind(&Ncc::requestNfdStatus, this));
taylorchuc27dd482014-05-17 20:06:49 -0700106 }
107
108 void
109 stop()
110 {
111 m_isActive = false;
112 m_face.shutdown();
Alexander Afanasyev4086d512014-07-11 15:56:33 -0700113 m_scheduler.cancelAllEvents();
taylorchuc27dd482014-05-17 20:06:49 -0700114 m_nfdThread.interrupt();
115 m_nfdThread.join();
116 }
117
118private:
Alexander Afanasyev4086d512014-07-11 15:56:33 -0700119 void
120 requestNfdStatus()
121 {
122 Interest interest("/localhost/nfd/status");
123 interest.setMustBeFresh(true);
124 m_face.expressInterest(interest,
125 bind(&Ncc::onStatusRetrieved, this, _2),
126 bind(&Ncc::onStatusTimeout, this));
127 }
128
129private:
taylorchuc27dd482014-05-17 20:06:49 -0700130 volatile bool m_isActive;
131 boost::thread m_nfdThread;
132
133 Face m_face;
Alexander Afanasyev4086d512014-07-11 15:56:33 -0700134 Scheduler m_scheduler;
taylorchuc27dd482014-05-17 20:06:49 -0700135
136 QQmlApplicationEngine m_engine;
137
Alexander Afanasyev4086d512014-07-11 15:56:33 -0700138 ForwarderStatusModel m_forwarderStatusModel;
taylorchuc27dd482014-05-17 20:06:49 -0700139 FibStatusModel m_fibModel;
140 TrayMenu m_tray;
141};
142
143} // namespace ndn
144
145Q_DECLARE_METATYPE(ndn::shared_ptr<const ndn::Data>)
146
147int
148main(int argc, char *argv[])
149{
150 qRegisterMetaType<ndn::shared_ptr<const ndn::Data> >();
151
Alexander Afanasyev4c37bfb2016-03-20 12:06:30 -0700152 QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
taylorchuc27dd482014-05-17 20:06:49 -0700153 QApplication app(argc, argv);
154
155 ndn::Ncc controlCenterGui;
156
157 QApplication::setQuitOnLastWindowClosed(false);
158 int retval = app.exec();
159
160 controlCenterGui.stop();
161
162 return retval;
163}