source: flair-src/trunk/tools/FlairGCS/src/Manager.cpp@ 176

Last change on this file since 176 was 30, checked in by Sanahuja Guillaume, 8 years ago

show rx rate in GCS

File size: 9.8 KB
RevLine 
[10]1// %flair:license{
[15]2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
[10]4// %flair:license}
[9]5#include "Manager.h"
6#include "UdtSocket.h"
7#include "ConnectionLayout.h"
8#include "communication.h"
9#include <QDate>
10#include <QFileDialog>
11#include <QMessageBox>
12#include <QPushButton>
13#include <QTabBar>
14#include <QTimer>
15#include <QThread>
16#include <QTextStream>
17#include <QVBoxLayout>
18#include <QModelIndex>
19//#include <qmetatype.h>
20#include <qendian.h>
21#include <iostream>
22#include <string>
23#include <fstream>
24#include <stdio.h>
25
26#ifndef WIN32
[15]27#include <arpa/inet.h>
[9]28#else
[15]29#include <winsock2.h>
30#include <ws2tcpip.h>
[9]31#endif
32
33using namespace std;
34
[15]35Manager::Manager(QString name, int port) : QWidget() {
36 qRegisterMetaType<QModelIndex>("QModelIndex"); // pour le file ui??
37 this->name = name;
[9]38
[15]39 setWindowTitle(name);
[30]40//statusBar()->showMessage(tr("Ready to serve"));
[15]41 // manager layout
42 managerLayout = new QVBoxLayout;
43 setLayout(managerLayout);
[9]44
[15]45 // tab bar for multiple connections
46 tabBar = new QTabBar();
47 managerLayout->addWidget(tabBar);
48 connect(tabBar, SIGNAL(currentChanged(int)), this,
49 SLOT(tabBarCurrentChanged(int)));
50 currentTab = 0;
[9]51
[15]52 // layout boutons
53 button_layout = new QGridLayout();
54 managerLayout->addLayout(button_layout);
[9]55
[15]56 // boutons du button_Layout
57 send_button = new QPushButton("apply all");
58 reset_button = new QPushButton("reset all");
59 load_button = new QPushButton("load all locally");
60 save_button = new QPushButton("save all locally");
61 button_layout->addWidget(send_button, 0, 0);
62 button_layout->addWidget(reset_button, 0, 1);
63 button_layout->addWidget(load_button, 0, 2);
64 button_layout->addWidget(save_button, 0, 3);
[9]65
[15]66 connect(send_button, SIGNAL(clicked(bool)), this, SLOT(send()));
67 connect(reset_button, SIGNAL(clicked(bool)), this, SLOT(reset()));
68 connect(load_button, SIGNAL(clicked(bool)), this, SLOT(load()));
69 connect(save_button, SIGNAL(clicked(bool)), this, SLOT(save()));
[9]70
[30]71 status=new QStatusBar();
72 status->setSizeGripEnabled(false);
73 button_layout->addWidget(status, 1,0);
74
[15]75 UDT::startup();
76 serv = UDT::socket(AF_INET, SOCK_DGRAM, 0);
[9]77
[15]78 // for non blocking accept
79 bool blocking = false;
80 UDT::setsockopt(serv, 0, UDT_RCVSYN, &blocking, sizeof(bool));
[9]81
[15]82 sockaddr_in my_addr;
83 my_addr.sin_family = AF_INET;
84 my_addr.sin_port = htons(port);
85 my_addr.sin_addr.s_addr = INADDR_ANY;
86 memset(&(my_addr.sin_zero), '\0', 8);
[9]87
[15]88 if (UDT::ERROR == UDT::bind(serv, (sockaddr *)&my_addr, sizeof(my_addr))) {
89 printf("bind error, %s\n", UDT::getlasterror().getErrorMessage());
90 }
[9]91
[15]92 if (UDT::ERROR == UDT::listen(serv, 1)) {
93 printf("listen error, %s\n", UDT::getlasterror().getErrorMessage());
94 }
[9]95
[15]96 QTimer *timer = new QTimer(this);
97 connect(timer, SIGNAL(timeout()), this, SLOT(acceptConnections()));
98 timer->start(20);
[9]99}
100
101Manager::~Manager() {
[15]102 emit killUdtSockets();
[9]103
[15]104 // delete main_layout;
105 UDT::cleanup();
[9]106}
107
108void Manager::acceptConnections(void) {
[15]109 static UDTSOCKET first_socket = 0;
110 UDTSOCKET socket;
[9]111
[15]112 sockaddr_in their_addr;
113 int namelen = sizeof(their_addr);
[9]114
[15]115 if (UDT::INVALID_SOCK ==
116 (socket = UDT::accept(serv, (sockaddr *)&their_addr, &namelen))) {
117 if (UDT::getlasterror().getErrorCode() != 6002)
118 printf("accept: %s, code %i\n", UDT::getlasterror().getErrorMessage(),
119 UDT::getlasterror().getErrorCode());
120 return;
121 } else {
122 printf("connected to %s:%i\n", inet_ntoa(their_addr.sin_addr),
123 their_addr.sin_port);
124
125 if (!first_socket) {
126 first_socket = socket;
127 return;
[9]128 } else {
[15]129 QThread *thread = new QThread(this);
130 UdtSocket *new_udt = new UdtSocket(first_socket, socket, name);
131 new_udt->moveToThread(thread);
[9]132
[15]133 newConnection(new_udt);
[9]134
[15]135 connect(this, SIGNAL(killUdtSockets()), thread, SLOT(quit()));
136 connect(this, SIGNAL(killUdtSockets()), new_udt, SLOT(kill()),
137 Qt::BlockingQueuedConnection);
[9]138
[15]139 connect(thread, SIGNAL(started()), new_udt, SLOT(handleConnections()));
[9]140
[15]141 thread->start();
142 first_socket = 0;
[9]143 }
[15]144 }
[9]145}
146
[15]147void Manager::newConnection(UdtSocket *socket) {
[9]148
[15]149 // no tabs to 2 tabs
150 if (connectionsLayout.count() == 1) {
151 tabBar->addTab(hiddenTabName);
152 currentTab = 0;
153 connectionsWidget.at(0)->show();
154 }
[9]155
[15]156 // layout utilisateur
157 ConnectionLayout *newLayout = new ConnectionLayout(socket, "interface");
158 connectionsLayout.append(newLayout);
159 connect(newLayout, SIGNAL(setRemoteName(QString)), this,
160 SLOT(tabName(QString)));
[30]161 connect(newLayout, SIGNAL(computedRxRate(float)), this,
162 SLOT(printRxRates(float)));
[15]163 connect(socket, SIGNAL(dataReady(char *, int)), newLayout,
164 SLOT(receive(char *, int)));
165 connect(newLayout, SIGNAL(destroyed(QObject *)), this,
166 SLOT(layoutDestroyed(QObject *)));
167 connect(socket, SIGNAL(destroyed()), newLayout, SLOT(deleteLater()));
[9]168
[15]169 // widget
170 QWidget *newWidget = new QWidget();
171 connectionsWidget.append(newWidget);
172 newWidget->setLayout(newLayout->getQGridLayout());
173 managerLayout->insertWidget(1, newWidget);
174 newWidget->hide();
[9]175
[15]176 if (connectionsLayout.count() == 1) { // first connection
177 newWidget->show();
178 } else { // add a tab for the new connection
179 tabBar->addTab("unknown");
180 }
[9]181}
182
[30]183void Manager::printRxRates(float rxRate) {
184 int index = connectionsLayout.indexOf((ConnectionLayout *)sender());
185
186 if (tabBar->count() == 0) {
187 status->showMessage(tr("rx rate %1 kB/s").arg(rxRate,0,'f',3));
188 } else if (index==tabBar->currentIndex()) {
189 status->showMessage(tr("%1 rx rate %2 kB/s").arg(tabBar->tabText(index)).arg(rxRate,0,'f',3));
190 }
191}
192
[9]193void Manager::tabBarCurrentChanged(int index) {
[15]194 if (index >= 0) {
195 connectionsWidget.at(currentTab)->hide();
196 connectionsWidget.at(index)->show();
197 currentTab = index;
198 } else {
199 currentTab = 0;
200 connectionsWidget.at(0)->show();
201 }
[9]202}
203
204void Manager::tabName(QString name) {
[15]205 int index = connectionsLayout.indexOf((ConnectionLayout *)sender());
206 if (tabBar->count() == 0) {
207 hiddenTabName = name;
208 } else {
209 tabBar->setTabText(index, name);
210 }
[9]211}
212
[15]213void Manager::layoutDestroyed(QObject *obj) {
214 int index = connectionsLayout.indexOf((ConnectionLayout *)obj);
[9]215
[15]216 if (tabBar->count() > 1) {
217 tabBar->removeTab(index);
218 }
[9]219
[15]220 delete connectionsWidget.at(index);
221 connectionsWidget.removeAt(index);
222 connectionsLayout.removeOne((ConnectionLayout *)obj);
[9]223
[15]224 if (connectionsLayout.count() == 1) {
225 hiddenTabName = tabBar->tabText(0);
226 tabBar->removeTab(0);
227 }
[30]228
229 if (connectionsLayout.count() == 0) {
230 status->showMessage("");
231 }
[9]232}
233
234void Manager::load(void) {
[15]235 QString dir_name =
236 QFileDialog::getExistingDirectory(this, "Select a directory", 0, 0);
[9]237
[15]238 if (dir_name != "") {
239 for (int i = 0; i < connectionsLayout.count(); i++) {
240 QFile *file;
241 file = new QFile(dir_name + "/" +
242 connectionsLayout.at(i)->getRemoteName() + ".xml");
243 if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) {
244 QMessageBox::warning(this, "Warning",
245 "Enable to load " +
246 connectionsLayout.at(i)->getRemoteName() +
247 ".xml");
248 continue;
249 }
[9]250
[15]251 QDomDocument doc;
252 QString errorMsg;
253 int errorLine;
254 int errorColumn;
255 if (!doc.setContent(file, &errorMsg, &errorLine, &errorColumn)) {
256 QMessageBox::critical(
257 this, "Error",
258 "unable to read " + connectionsLayout.at(i)->getRemoteName() +
259 ".xml" + " (" + errorMsg + " at " + QString::number(errorLine) +
260 "," + QString::number(errorColumn) + ")");
261 } else {
262 connectionsLayout.at(i)->LoadXml(doc);
263 }
264 delete file;
[9]265 }
[15]266 }
[9]267}
268
269void Manager::save(void) {
[15]270 bool isUptodate = true;
[9]271
[15]272 for (int i = 0; i < connectionsLayout.count(); i++) {
273 if (!connectionsLayout.at(i)->IsUptodate()) {
274 isUptodate = false;
275 break;
[9]276 }
[15]277 }
[9]278
[15]279 if (!isUptodate) {
280 QMessageBox msgBox;
281 msgBox.setText("There are pending modifications");
282 msgBox.setInformativeText("Apply and save?");
283 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
284 msgBox.setDefaultButton(QMessageBox::Yes);
285 int ret = msgBox.exec();
[9]286
[15]287 switch (ret) {
288 case QMessageBox::Yes:
289 send();
290 break;
291 case QMessageBox::Cancel:
292 return;
293 break;
294 default:
295 // should never be reached
296 break;
[9]297 }
[15]298 }
[9]299
[15]300 // create dirctory for storage
301 QDateTime dateTime = QDateTime::currentDateTime();
302 QString dir_name =
303 "configs_" + dateTime.toString("yyyyMMdd_hhmm") + "_" + name;
304 if (QDir().exists(dir_name) == true) {
305 dir_name = "configs_" + dateTime.toString("yyyyMMdd_hhmm_ss") + "_" + name;
306 }
307 QDir().mkdir(dir_name);
[9]308
[15]309 for (int i = 0; i < connectionsLayout.count(); i++) {
310 QDomDocument *xml = new QDomDocument("remote_ui_xml");
[9]311
[15]312 connectionsLayout.at(i)->GetFullXml((QDomElement *)xml);
[9]313
[15]314 QFile fichier(dir_name + "/" + connectionsLayout.at(i)->getRemoteName() +
315 ".xml");
316 QString write_doc = (xml->ownerDocument()).toString();
[9]317
[15]318 if (!fichier.open(QIODevice::WriteOnly)) {
319 fichier.close();
320 QMessageBox::critical(this, "Error", "Enable to write XML");
321 continue;
[9]322 }
[15]323 QTextStream stream(&fichier);
324 stream << write_doc; // On utilise l'opérateur << pour écrire write_doc dans
325 // le document XML.
326 fichier.close();
[9]327
[15]328 delete xml;
329 }
330
331 QMessageBox::information(this, "save all", "saved to ./" + dir_name);
[9]332}
333
334void Manager::send(void) {
[15]335 for (int i = 0; i < connectionsLayout.count(); i++) {
336 QDomDocument doc("remote_ui_xml");
337 connectionsLayout.at(i)->GetUpdateXml((QDomElement *)&doc);
338 // printf("merge\n%s\n",doc.toString().toLocal8Bit().constData());
[9]339
[15]340 connectionsLayout.at(i)->XmlToSend(doc);
341 }
[9]342}
343
344void Manager::reset() {
[15]345 for (int i = 0; i < connectionsLayout.count(); i++)
346 connectionsLayout.at(i)->ResetAllChilds();
[9]347}
Note: See TracBrowser for help on using the repository browser.