Changeset 234 in flair-src for trunk/tools
- Timestamp:
- Apr 10, 2018, 5:05:27 PM (7 years ago)
- Location:
- trunk/tools
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/Dbt2csv/CMakeLists.txt
r107 r234 4 4 5 5 if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i686" OR "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i586" OR "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64") 6 warn("${PROJECT_NAME} is broken since changes in FlairGCS/src/file_ui.cpp") 7 return() 6 8 7 9 SET(PROJECT_SOURCE_FILES -
trunk/tools/FlairGCS/src/ConnectionLayout.cpp
r222 r234 8 8 #include <qendian.h> 9 9 #include "communication.h" 10 #include <zlib.h>11 #include <assert.h>12 13 #define COMPRESS_CHUNK 102414 #define RX_TIME 500015 10 16 11 ConnectionLayout::ConnectionLayout(UdtSocket *socket, QString name) 17 12 : Layout(NULL, name, "root") { 18 isRemoteNameDefined = false;19 13 this->socket = socket; 20 21 total_received=0; 22 receive_timer = new QTimer(this); 23 connect(receive_timer, SIGNAL(timeout()), this, SLOT(computeRxRate())); 24 receive_timer->start(RX_TIME); 14 this->name = name; 25 15 } 26 16 27 17 ConnectionLayout::~ConnectionLayout() { 28 receive_timer->stop();29 18 } 30 19 31 void ConnectionLayout::computeRxRate(void) { 32 float receive_rate=((float)total_received/(RX_TIME/1000))/1000;//in Ko/s 33 total_received=0; 34 computedRxRate(receive_rate); 20 QString ConnectionLayout::getUDTStats() { 21 return socket->getUDTStats(); 35 22 } 36 23 37 24 void ConnectionLayout::receive(char *buf, int size) { 38 total_received+=size-1;39 25 // printf("trame %x\n",buf[0]); 40 26 // for(int i=0; i<size;i++) printf("%x ",buf[i]); 41 27 // printf("\n"); 42 switch (buf[0]) {43 case ZLIB_HEADER: {44 ssize_t out_size;45 char *uncompressbuf;46 uncompressBuffer(buf, size, &uncompressbuf, &out_size);47 handleUncompressedFrame(uncompressbuf, out_size);48 free(uncompressbuf);49 break;50 }51 default:52 handleUncompressedFrame(buf, size);53 }54 free(buf);55 }56 57 void ConnectionLayout::XmlToSend(QDomDocument doc) {58 // printf("xml to send\n%s\n",doc.toString().toLocal8Bit().constData());59 // xml to send a mettre dans le manager60 QMetaObject::invokeMethod(61 socket, "write", Qt::BlockingQueuedConnection,62 Q_ARG(const char *, doc.toString().toLocal8Bit().constData()),63 Q_ARG(qint64, doc.toString().toLocal8Bit().length()));64 }65 66 void ConnectionLayout::LoadXml(QDomDocument to_parse) {67 if (!isRemoteNameDefined) {68 printf("load xml: name not defined!\n");69 return;70 }71 72 QDomElement tmp = to_parse.firstChildElement("root");73 while (tmp.attribute("name") != remoteName && !tmp.isNull())74 tmp = to_parse.nextSiblingElement("root");75 76 if (!tmp.isNull()) {77 XmlWidget::LoadXml(tmp);78 } else {79 printf("%s not found in xml file \n", remoteName.toLocal8Bit().constData());80 }81 }82 83 void ConnectionLayout::handleUncompressedFrame(char *buf, ssize_t size) {84 28 switch ((unsigned char)buf[0]) { 85 29 case XML_HEADER: { … … 92 36 if (!doc.setContent(xml)) { 93 37 printf("prob setContent fichier\n"); 94 }95 96 if (!isRemoteNameDefined) {97 isRemoteNameDefined = true;98 remoteName = doc.firstChildElement("root").attribute("name");99 setRemoteName(remoteName);100 SetAttribute("name", remoteName);101 38 } 102 39 … … 127 64 } 128 65 66 void ConnectionLayout::XmlToSend(QDomDocument doc) { 67 // printf("xml to send\n%s\n",doc.toString().toLocal8Bit().constData()); 68 69 // xml to send a mettre dans le manager 70 socket->write(doc.toString().toLocal8Bit().constData(),doc.toString().toLocal8Bit().length());/* 71 QMetaObject::invokeMethod( 72 socket, "write", Qt::BlockingQueuedConnection, 73 Q_ARG(const char *, doc.toString().toLocal8Bit().constData()), 74 Q_ARG(qint64, doc.toString().toLocal8Bit().length()));*/ 75 } 76 77 void ConnectionLayout::LoadXml(QDomDocument to_parse) { 78 QDomElement tmp = to_parse.firstChildElement("root"); 79 while (tmp.attribute("name") != name && !tmp.isNull()) 80 tmp = to_parse.nextSiblingElement("root"); 81 82 if (!tmp.isNull()) { 83 XmlWidget::LoadXml(tmp); 84 } else { 85 printf("%s not found in xml file \n", name.toLocal8Bit().constData()); 86 } 87 } 88 129 89 void ConnectionLayout::removeDataRemote(DataRemote *data) { 130 90 dataremotes.removeOne(data); … … 135 95 } 136 96 137 QString ConnectionLayout::get RemoteName() { return remoteName; }97 QString ConnectionLayout::getName() { return name; } 138 98 139 99 void ConnectionLayout::drawDatas(char *buf, int buf_size, uint16_t period, … … 144 104 } 145 105 146 int ConnectionLayout::uncompressBuffer(char *in, ssize_t in_size, char **out, 147 ssize_t *out_size) {148 int ret;149 unsigned have;150 z_stream strm;106 QString ConnectionLayout::getDocRootName(char* buf, int size) { 107 QString xml; 108 QDomDocument doc; 109 xml = QString((char *)buf); 110 xml.resize(size); 151 111 152 // allocate inflate state 153 strm.zalloc = Z_NULL; 154 strm.zfree = Z_NULL; 155 strm.opaque = Z_NULL; 156 strm.avail_in = 0; 157 strm.next_in = Z_NULL; 158 ret = inflateInit(&strm); 159 if (ret != Z_OK) 160 return ret; 161 162 *out = (char *)malloc(COMPRESS_CHUNK); 163 if (!(*out)) 164 return Z_BUF_ERROR; 165 166 strm.avail_in = in_size; 167 strm.next_in = (unsigned char *)in; 168 strm.avail_out = COMPRESS_CHUNK; 169 strm.next_out = (unsigned char *)*out; 170 171 ret = inflate(&strm, Z_NO_FLUSH); 172 assert(ret != Z_STREAM_ERROR); // state not clobbered 173 switch (ret) { 174 case Z_NEED_DICT: 175 ret = Z_DATA_ERROR; // and fall through 176 case Z_DATA_ERROR: 177 case Z_MEM_ERROR: 178 (void)inflateEnd(&strm); 179 return ret; 112 if (!doc.setContent(xml)) { 113 printf("prob setContent fichier\n"); 180 114 } 181 have = COMPRESS_CHUNK - strm.avail_out; 182 *out_size = have; 183 184 // printf("%i -> %i\n",in_size,have); 185 // printf("%s\n",*out); 186 // clean up and return 187 (void)inflateEnd(&strm); 188 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; 115 116 return doc.firstChildElement("root").attribute("name"); 189 117 } -
trunk/tools/FlairGCS/src/ConnectionLayout.h
r30 r234 6 6 #define CONNECTIONLAYOUT_H 7 7 8 #include <QTimer>9 8 #include "Layout.h" 10 9 … … 22 21 void removeDataRemote(DataRemote *data); 23 22 void LoadXml(QDomDocument to_parse); 24 QString getRemoteName(); 23 QString getName(); 24 QString getUDTStats(); 25 static QString getDocRootName(char* buf, int size); 25 26 26 27 private: 27 static int uncompressBuffer(char *in, ssize_t in_size, char **out,28 ssize_t *out_size);29 void handleUncompressedFrame(char *buf, ssize_t size);30 28 void drawDatas(char *buf, int buf_size, uint16_t period, 31 29 bool big_endian = false); 32 bool isRemoteNameDefined; 33 QString remoteName; 30 QString name; 34 31 UdtSocket *socket; 35 32 QList<DataRemote *> dataremotes; 36 unsigned int total_received; 37 QTimer *receive_timer; 38 33 39 34 private slots: 40 35 void receive(char *buf, int size); 41 void computeRxRate(void);42 36 43 37 signals: 44 void setRemoteName(QString name); 45 void computedRxRate(float rxRate); 38 void UDTStats(QString stats); 46 39 }; 47 40 -
trunk/tools/FlairGCS/src/DataRemote.cpp
r222 r234 57 57 if (action == setRefreshRate) { 58 58 bool ok; 59 // uint16_t time = QInputDialog::getInt(this, QString("Set refresh rate 60 // (%1)").arg(title().text()),tr("Value (ms):"), 61 // (uint16_t)(qRound(refresh_rate*1000)), 1, 65535, 10, &ok); 59 62 60 uint16_t time = QInputDialog::getInt( 63 61 parent, "Set refresh rate ", "Value (ms):", … … 83 81 SetAttribute("period", period); 84 82 SetAttribute("enabled", auto_refresh); 85 86 83 connectionLayout()->XmlToSend(XmlDoc()); 87 88 84 RemoveAttribute("period"); 89 85 RemoveAttribute("enabled"); -
trunk/tools/FlairGCS/src/Manager.cpp
r30 r234 7 7 #include "ConnectionLayout.h" 8 8 #include "communication.h" 9 #include "file_ui.h" 9 10 #include <QDate> 10 11 #include <QFileDialog> … … 17 18 #include <QVBoxLayout> 18 19 #include <QModelIndex> 19 //#include <qmetatype.h>20 #include <QStatusBar> 20 21 #include <qendian.h> 21 22 #include <iostream> … … 36 37 qRegisterMetaType<QModelIndex>("QModelIndex"); // pour le file ui?? 37 38 this->name = name; 38 39 //fprintf(stderr,"Manager %x\n",thread()); 39 40 setWindowTitle(name); 40 //statusBar()->showMessage(tr("Ready to serve")); 41 41 42 // manager layout 42 43 managerLayout = new QVBoxLayout; … … 79 80 bool blocking = false; 80 81 UDT::setsockopt(serv, 0, UDT_RCVSYN, &blocking, sizeof(bool)); 81 82 //UDT::setsockopt(serv, 0, UDT_CC, new CCCFactory<CUDPBlast>, sizeof(CCCFactory<CUDPBlast>)); 82 83 sockaddr_in my_addr; 83 84 my_addr.sin_family = AF_INET; … … 96 97 QTimer *timer = new QTimer(this); 97 98 connect(timer, SIGNAL(timeout()), this, SLOT(acceptConnections())); 98 timer->start( 20);99 timer->start(500); 99 100 } 100 101 101 102 Manager::~Manager() { 102 emit killUdtSockets(); 103 printf("%i\n",udtSockets.count()); 104 for (int i = 0; i < udtSockets.count(); i++) { 105 udtSockets.at(i)->kill(); 106 udtSockets.at(i)->thread()->wait(); 107 } 103 108 104 109 // delete main_layout; 105 110 UDT::cleanup(); 111 printf("ok\n"); 106 112 } 107 113 108 114 void Manager::acceptConnections(void) { 109 static UDTSOCKET first_socket = 0;110 115 UDTSOCKET socket; 111 116 … … 113 118 int namelen = sizeof(their_addr); 114 119 115 if (UDT::INVALID_SOCK == 116 (socket = UDT::accept(serv, (sockaddr *)&their_addr, &namelen))) { 120 if (UDT::INVALID_SOCK ==(socket = UDT::accept(serv, (sockaddr *)&their_addr, &namelen))) { 117 121 if (UDT::getlasterror().getErrorCode() != 6002) 118 printf("accept: %s, code %i\n", UDT::getlasterror().getErrorMessage(), 119 UDT::getlasterror().getErrorCode()); 122 printf("accept error: %s, code %i\n", UDT::getlasterror().getErrorMessage(),UDT::getlasterror().getErrorCode()); 120 123 return; 121 124 } 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; 128 } else { 129 QThread *thread = new QThread(this); 130 UdtSocket *new_udt = new UdtSocket(first_socket, socket, name); 131 new_udt->moveToThread(thread); 132 133 newConnection(new_udt); 134 135 connect(this, SIGNAL(killUdtSockets()), thread, SLOT(quit())); 136 connect(this, SIGNAL(killUdtSockets()), new_udt, SLOT(kill()), 137 Qt::BlockingQueuedConnection); 138 139 connect(thread, SIGNAL(started()), new_udt, SLOT(handleConnections())); 140 141 thread->start(); 142 first_socket = 0; 143 } 144 } 145 } 146 147 void Manager::newConnection(UdtSocket *socket) { 148 149 // no tabs to 2 tabs 150 if (connectionsLayout.count() == 1) { 151 tabBar->addTab(hiddenTabName); 152 currentTab = 0; 153 connectionsWidget.at(0)->show(); 154 } 155 156 // layout utilisateur 157 ConnectionLayout *newLayout = new ConnectionLayout(socket, "interface"); 125 QString name=QString("%1:%2").arg(inet_ntoa(their_addr.sin_addr)).arg(their_addr.sin_port); 126 printf("connected to %s\n",name.toLocal8Bit().constData()); 127 128 QThread *thread = new QThread(this); 129 UdtSocket *udtSocket = new UdtSocket(socket,name); 130 udtSocket->moveToThread(thread); 131 udtSockets.append(udtSocket); 132 133 connect(udtSocket, SIGNAL(newFileUI(UDTSOCKET)), this, SLOT(newFileUI(UDTSOCKET))); 134 connect(udtSocket, SIGNAL(newConnectionLayout(QString)), this, SLOT(newConnectionLayout(QString)),Qt::BlockingQueuedConnection); 135 connect(thread, SIGNAL(started()), udtSocket, SLOT(receiveData())); 136 137 thread->start(); 138 } 139 } 140 141 void Manager::newConnectionLayout(QString name) { 142 UdtSocket* udtSocket=(UdtSocket *)sender(); 143 144 ConnectionLayout *newLayout = new ConnectionLayout(udtSocket, name); 158 145 connectionsLayout.append(newLayout); 159 connect(newLayout, SIGNAL(setRemoteName(QString)), this, 160 SLOT(tabName(QString))); 161 connect(newLayout, SIGNAL(computedRxRate(float)), this, 162 SLOT(printRxRates(float))); 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())); 168 169 // widget 146 connect(udtSocket, SIGNAL(UDTStats(QString)), newLayout, SIGNAL(UDTStats(QString)));//connection in 2 steps to get udtsocket as sender 147 connect(newLayout, SIGNAL(UDTStats(QString)), this, SLOT(printUDTStats(QString))); 148 connect(udtSocket, SIGNAL(dataReady(char *, int)), newLayout,SLOT(receive(char *, int)),Qt::BlockingQueuedConnection); 149 connect(newLayout, SIGNAL(destroyed(QObject *)), this, SLOT(layoutDestroyed(QObject *))); 150 connect(udtSocket, SIGNAL(destroyed()), newLayout, SLOT(deleteLater())); 151 152 // widget 170 153 QWidget *newWidget = new QWidget(); 171 154 connectionsWidget.append(newWidget); … … 173 156 managerLayout->insertWidget(1, newWidget); 174 157 newWidget->hide(); 175 158 159 //tab: avoid having only 1 tab (0, 2 or more) 176 160 if (connectionsLayout.count() == 1) { // first connection 177 newWidget->show(); 178 } else { // add a tab for the new connection 179 tabBar->addTab("unknown"); 180 } 181 } 182 183 void Manager::printRxRates(float rxRate) { 161 connectionsWidget.at(0)->show(); 162 hiddenTabName = name; 163 } 164 if (connectionsLayout.count() == 2) { 165 tabBar->addTab(hiddenTabName); 166 currentTab = 0; 167 } 168 if (connectionsLayout.count() > 1) { 169 tabBar->addTab(name); 170 } 171 } 172 173 void Manager::layoutDestroyed(QObject *obj) { 174 int index = connectionsLayout.indexOf((ConnectionLayout *)obj); 175 176 //tab: avoid having only 1 tab (0, 2 or more) 177 if (tabBar->count() > 1) { 178 tabBar->removeTab(index); 179 } 180 181 delete connectionsWidget.at(index); 182 connectionsWidget.removeAt(index); 183 connectionsLayout.removeOne((ConnectionLayout *)obj); 184 185 if (connectionsLayout.count() == 1) { 186 hiddenTabName = tabBar->tabText(0); 187 tabBar->removeTab(0); 188 } 189 190 if (connectionsLayout.count() == 0) { 191 status->showMessage(""); 192 } 193 } 194 195 void Manager::newFileUI(UDTSOCKET socket) { 196 //remove udtsocket as it will be automatically destroyed 197 udtSockets.removeOne((UdtSocket *)sender()); 198 199 QThread *thread = new QThread(this); 200 file_ui* fileUi = new file_ui(socket,name); 201 fileUi->moveToThread(thread); 202 connect(thread, SIGNAL(started()), fileUi, SLOT(receive())); 203 connect(fileUi, SIGNAL(finished()), this, SLOT(deleteFileUI())); 204 thread->start(); 205 } 206 207 void Manager::deleteFileUI(void) { 208 sender()->thread()->quit(); 209 delete sender(); 210 } 211 212 void Manager::printUDTStats(QString stats) { 184 213 int index = connectionsLayout.indexOf((ConnectionLayout *)sender()); 185 214 if(index==-1) return; 215 186 216 if (tabBar->count() == 0) { 187 status->showMessage( tr("rx rate %1 kB/s").arg(rxRate,0,'f',3));217 status->showMessage(stats); 188 218 } else if (index==tabBar->currentIndex()) { 189 status->showMessage( tr("%1 rx rate %2 kB/s").arg(tabBar->tabText(index)).arg(rxRate,0,'f',3));219 status->showMessage(QString("%1: %2").arg(tabBar->tabText(index)).arg(stats)); 190 220 } 191 221 } … … 200 230 connectionsWidget.at(0)->show(); 201 231 } 202 } 203 204 void Manager::tabName(QString name) { 205 int index = connectionsLayout.indexOf((ConnectionLayout *)sender()); 232 206 233 if (tabBar->count() == 0) { 207 hiddenTabName = name;234 status->showMessage(connectionsLayout.at(0)->getUDTStats()); 208 235 } else { 209 tabBar->setTabText(index, name); 210 } 211 } 212 213 void Manager::layoutDestroyed(QObject *obj) { 214 int index = connectionsLayout.indexOf((ConnectionLayout *)obj); 215 216 if (tabBar->count() > 1) { 217 tabBar->removeTab(index); 218 } 219 220 delete connectionsWidget.at(index); 221 connectionsWidget.removeAt(index); 222 connectionsLayout.removeOne((ConnectionLayout *)obj); 223 224 if (connectionsLayout.count() == 1) { 225 hiddenTabName = tabBar->tabText(0); 226 tabBar->removeTab(0); 227 } 228 229 if (connectionsLayout.count() == 0) { 230 status->showMessage(""); 236 status->showMessage(QString("%1: %2").arg(tabBar->tabText(index)).arg(connectionsLayout.at(index)->getUDTStats())); 231 237 } 232 238 } … … 240 246 QFile *file; 241 247 file = new QFile(dir_name + "/" + 242 connectionsLayout.at(i)->get RemoteName() + ".xml");248 connectionsLayout.at(i)->getName() + ".xml"); 243 249 if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) { 244 250 QMessageBox::warning(this, "Warning", 245 251 "Enable to load " + 246 connectionsLayout.at(i)->get RemoteName() +252 connectionsLayout.at(i)->getName() + 247 253 ".xml"); 248 254 continue; … … 256 262 QMessageBox::critical( 257 263 this, "Error", 258 "unable to read " + connectionsLayout.at(i)->get RemoteName() +264 "unable to read " + connectionsLayout.at(i)->getName() + 259 265 ".xml" + " (" + errorMsg + " at " + QString::number(errorLine) + 260 266 "," + QString::number(errorColumn) + ")"); … … 312 318 connectionsLayout.at(i)->GetFullXml((QDomElement *)xml); 313 319 314 QFile fichier(dir_name + "/" + connectionsLayout.at(i)->get RemoteName() +320 QFile fichier(dir_name + "/" + connectionsLayout.at(i)->getName() + 315 321 ".xml"); 316 322 QString write_doc = (xml->ownerDocument()).toString(); … … 322 328 } 323 329 QTextStream stream(&fichier); 324 stream << write_doc; // On utilise l'opérateur << pour écrire write_doc dans 325 // le document XML. 330 stream << write_doc; 326 331 fichier.close(); 327 332 -
trunk/tools/FlairGCS/src/Manager.h
r30 r234 9 9 #include <udt.h> 10 10 #include <qdom.h> 11 #include <QStatusBar>12 11 13 12 class UdtSocket; … … 17 16 class QPushButton; 18 17 class QGridLayout; 18 class QStatusBar; 19 19 20 20 class Manager : public QWidget { … … 30 30 QList<ConnectionLayout *> connectionsLayout; 31 31 QList<QWidget *> connectionsWidget; 32 QList<UdtSocket *> udtSockets; 32 33 QTabBar *tabBar; 33 34 QString name, hiddenTabName; … … 41 42 QStatusBar *status; 42 43 43 void newConnection(UdtSocket *socket);44 45 44 private slots: 46 45 void acceptConnections(void); … … 49 48 void save(void); 50 49 void reset(void); 50 void tabBarCurrentChanged(int index); 51 void printUDTStats(QString stats); 52 void newFileUI(UDTSOCKET socket); 53 void deleteFileUI(void); 54 void newConnectionLayout(QString name); 51 55 void layoutDestroyed(QObject *obj); 52 void tabBarCurrentChanged(int index);53 void tabName(QString name);54 void printRxRates(float rxRate);55 56 signals:57 void killUdtSockets(void);58 56 59 57 protected: -
trunk/tools/FlairGCS/src/UdtSocket.cpp
r30 r234 4 4 // %flair:license} 5 5 #include "UdtSocket.h" 6 #include "ConnectionLayout.h" 6 7 #include <stdio.h> 7 8 #include <stdlib.h> … … 10 11 #include <QDir> 11 12 #include <QDate> 12 #include "file_ui.h"13 13 #include "communication.h" 14 #include <zlib.h> 15 #include <assert.h> 16 #include <QThread> 17 #define COMPRESS_CHUNK 1024*100 14 18 15 19 #ifndef WIN32 … … 20 24 #endif 21 25 26 #define COMPUTE_UDT_STATS_TIMER 2000 27 #define HEARTBEAT_TIMER 200 28 22 29 using namespace std; 23 30 24 UdtSocket::UdtSocket(UDTSOCKET file_socket, UDTSOCKET com_socket, QString name) 25 : QObject() { 26 this->file_socket = file_socket; 27 this->com_socket = com_socket; 28 this->name = name; 31 UdtSocket::UdtSocket(UDTSOCKET socket,QString name): QObject() { 32 this->socket = socket; 33 this->name=name; 29 34 stop = false; 30 file_dialog = new file_ui(); 31 32 bool blocking = true; 33 UDT::setsockopt(file_socket, 0, UDT_RCVSYN, &blocking, sizeof(bool)); 34 35 destroySocket=true; 36 socketType=unknown; 37 total_received=0; 38 39 bool blocking = false; 40 if (UDT::setsockopt(socket, 0, UDT_RCVSYN, &blocking, sizeof(bool)) != 0) 41 printf("UDT::setsockopt error (UDT_RCVSYN)\n"); 42 35 43 heartbeat_timer = new QTimer(this); 36 44 connect(heartbeat_timer, SIGNAL(timeout()), this, SLOT(heartbeat())); 37 heartbeat_timer->start(200); 45 heartbeat_timer->start(HEARTBEAT_TIMER); 46 47 udtstats_timer = new QTimer(this); 48 connect(udtstats_timer, SIGNAL(timeout()), this, SLOT(getUTDStats())); 49 udtstats_timer->start(COMPUTE_UDT_STATS_TIMER); 38 50 } 39 51 40 52 UdtSocket::~UdtSocket() { 41 53 heartbeat_timer->stop(); 42 43 UDT::close(file_socket); 44 UDT::close(com_socket); 45 46 file_dialog->deleteLater(); 54 udtstats_timer->stop(); 55 if(destroySocket) UDT::close(socket); 56 } 57 58 void UdtSocket::setName(QString name) { 59 printf(" %s is %s\n",this->name.toLocal8Bit().constData(),name.toLocal8Bit().constData()); 60 this->name=name; 47 61 } 48 62 … … 52 66 void UdtSocket::heartbeat(void) { 53 67 char data = WATCHDOG_HEADER; 54 write(&data, 1); 68 quint64 sent=write(&data, 1,HEARTBEAT_TIMER,false); 69 if (sent != 1 && UDT::getlasterror().getErrorCode() == 2001) { 70 heartbeat_timer->stop(); 71 } 72 73 } 74 75 void UdtSocket::getUTDStats(void) { 76 float rxRate=((float)total_received/(COMPUTE_UDT_STATS_TIMER/1000))/1000;//in Ko/s 77 total_received=0; 78 79 UDT::TRACEINFO perf; 80 if (UDT::ERROR == UDT::perfmon(socket, &perf)) { 81 printf("perfmon: %s\n",UDT::getlasterror().getErrorMessage()); 82 }/* else { 83 printf("%s socket stats:\n",name.toLocal8Bit().constData()); 84 printf("total number of sent packets, including retransmissions: %i\n",perf.pktSentTotal); 85 printf("total number of received packets: %i\n",perf.pktRecvTotal); 86 printf("total number of lost packets, measured in the sending side: %i\n",perf.pktSndLossTotal); 87 printf("total number of lost packets, measured in the receiving side: %i\n",perf.pktRcvLossTotal); 88 printf("total number of retransmitted packets, measured in the sending side: %i\n",perf.pktRetransTotal); 89 printf("total number of sent ACK packets: %i\n",perf.pktSentACKTotal); 90 printf("total number of received ACK packets: %i\n",perf.pktRecvACKTotal); 91 printf("total number of sent NAK packets: %i\n",perf.pktSentNAKTotal); 92 printf("total number of received NAK packets: %i\n",perf.pktRecvNAKTotal); 93 printf("round trip time: %fms\n",perf.msRTT); 94 95 }*/ 96 stats=QString("rx rate %1kB/s, round trip %2ms, lost packets %3").arg(rxRate,0,'f',3).arg(perf.msRTT,0,'f',3).arg(perf.pktSndLossTotal); 97 UDTStats(stats); 98 99 } 100 101 QString UdtSocket::getUDTStats() { 102 return stats; 55 103 } 56 104 57 105 void UdtSocket::kill(void) { 58 printf("disconnected\n");59 106 stop = true; 60 107 deleteLater(); 61 108 } 62 109 63 void UdtSocket::handleConnections(void) { 110 void UdtSocket::receiveData(void) { 111 int buf_size; 112 int opt_size; 113 UDT::getsockopt(socket, 0, UDT_RCVBUF, &buf_size, &opt_size); 114 char *buf = (char *)malloc(buf_size); 115 if (!buf) { 116 printf("error malloc UdtSocket::receiveData buffer\n"); 117 return; 118 } 119 char *uncompressbuf=(char *)malloc(COMPRESS_CHUNK); 120 if (!uncompressbuf) { 121 printf("error malloc UdtSocket::receiveData uncompress buffer\n"); 122 free(buf); 123 return; 124 } 125 //fprintf(stderr,"receiveData %x\n",thread()); 126 64 127 while (!stop) { 128 QCoreApplication::processEvents(); 129 130 //we need to use epoll? 131 //tests are showing that UDT::recvmsg is waiting for the entire timeout before returning 132 //note that in flair::core the behaviour of UDT::recvmsg timeout is as expected 133 //is it a difference between client and server?? 134 //tests also show that we need to recreate the eid every time, otherwise wait returns immediately 65 135 int eid = UDT::epoll_create(); 66 136 if (eid < 0) { 67 printf(" epoll_create error: %s\n",UDT::getlasterror().getErrorMessage());68 } 69 70 if (UDT::epoll_add_usock(eid, file_socket) < 0) {137 printf("%s: epoll_create error (%s)\n",name.toLocal8Bit().constData(),UDT::getlasterror().getErrorMessage()); 138 } 139 140 if (UDT::epoll_add_usock(eid, socket) < 0) { 71 141 if (UDT::getlasterror().getErrorCode() == 5004) { 72 printf("epoll_add_usock error\n"); 73 break; 142 printf("disconnected from %s\n",name.toLocal8Bit().constData()); 143 heartbeat_timer->stop(); 144 deleteLater(); 145 stop=true;; 74 146 } else { 75 printf("epoll_add_usock error: %s\n", 76 UDT::getlasterror().getErrorMessage()); 147 printf("%s: epoll_add_usock error (%s)\n",name.toLocal8Bit().constData(),UDT::getlasterror().getErrorMessage()); 77 148 } 78 149 } 79 if (UDT::epoll_add_usock(eid, com_socket) < 0) { 80 if (UDT::getlasterror().getErrorCode() == 5004) { 81 printf("epoll_add_usock error\n"); 82 break; 83 } else { 84 printf("epoll_add_usock error: %s\n", 85 UDT::getlasterror().getErrorMessage()); 86 } 87 } 88 89 set<UDTSOCKET> readfds; 90 91 int rv = UDT::epoll_wait(eid, &readfds, NULL, 10); 92 150 151 int num = 1; 152 UDTSOCKET readfds; 153 int rv = UDT::epoll_wait2(eid, &readfds, &num,NULL, NULL,100); 154 93 155 if (rv == -1) { 94 156 if (UDT::getlasterror().getErrorCode() != 6003) 95 157 printf("prob %i\n", UDT::getlasterror().getErrorCode()); 96 // printf("wait\n"); 97 } else if (rv == 0) { 98 printf("timeout\n"); // a timeout occured 158 } else if(readfds==socket && num==1 && rv==1) { 159 160 int size=UDT::recvmsg(socket, buf, buf_size); 161 if (size > 0) { 162 total_received+=size; 163 164 switch ((unsigned char)buf[0]) { 165 case ZLIB_HEADER: { 166 ssize_t out_size; 167 uncompressBuffer(buf, size, uncompressbuf, &out_size); 168 if((unsigned char)uncompressbuf[0]==XML_HEADER && socketType==unknown) { 169 socketType=gui; 170 QString remoteName=ConnectionLayout::getDocRootName(uncompressbuf, out_size); 171 setName(remoteName); 172 emit newConnectionLayout(remoteName);//connection is Qt::BlockingQueuedConnection 173 } 174 emit dataReady(uncompressbuf, out_size);//connection is Qt::BlockingQueuedConnection, as we have only one buffer 175 break; 176 } 177 case START_SENDING_FILES: { 178 if((unsigned char)uncompressbuf[0]==XML_HEADER && socketType==unknown) { 179 socketType=log; 180 } 181 setName("log files"); 182 heartbeat_timer->stop(); 183 emit newFileUI(socket); 184 deleteLater(); 185 stop=true; 186 destroySocket=false; 187 break; 188 } 189 case XML_HEADER: 190 if(socketType==unknown) { 191 socketType=gui; 192 QString remoteName=ConnectionLayout::getDocRootName(buf, size ); 193 setName(remoteName); 194 emit newConnectionLayout(remoteName); 195 } 196 case DATAS_BIG_ENDIAN: 197 case DATAS_LITTLE_ENDIAN: 198 emit dataReady(buf, size ); 199 break; 200 } 201 } else { 202 //if(UDT::getlasterror().getErrorCode()!=6002) 203 printf("udt socket:%s\n",UDT::getlasterror().getErrorMessage()); 204 //UDT::close(socket);//si deconnecté 205 //free(buf); 206 //break; 207 } 99 208 } else { 100 /* 101 if(UDT::getlasterror().getErrorCode()==2001) { 102 UDT::epoll_release(eid); 103 }*/ 104 for (set<UDTSOCKET>::iterator i = readfds.begin(); i != readfds.end(); 105 i++) { 106 // printf("a\n"); 107 if (*i == file_socket) 108 receiveFile(); 109 if (*i == com_socket) 110 receiveData(); 111 } 112 } 113 114 UDT::epoll_remove_usock(eid, file_socket); 115 UDT::epoll_remove_usock(eid, com_socket); 209 printf("udt socket:%s\n",UDT::getlasterror().getErrorMessage()); 210 } 211 UDT::epoll_remove_usock(eid, socket); 116 212 UDT::epoll_release(eid); 117 118 QCoreApplication::processEvents(); 119 } 120 kill(); 121 } 122 123 void UdtSocket::receiveFile(void) { 124 char *recv_buf; 125 int bytesRead; 126 static bool flag_new_seq = true; 127 static QString folder_name; 128 129 // receive file info 130 recv_buf = (char *)malloc(1024); 131 bytesRead = UDT::recvmsg(file_socket, recv_buf, 1024); 132 133 if (bytesRead <= 0) { 134 free(recv_buf); 135 return; 136 } 137 138 int size; 139 memcpy(&size, &recv_buf[1], sizeof(int)); 140 if (recv_buf[0] == FILE_INFO_BIG_ENDIAN) 141 size = qFromBigEndian(size); 142 143 // printf("file_ui recu %i %x\n",bytesRead,recv_buf[0]); 144 if ((recv_buf[0] == FILE_INFO_LITTLE_ENDIAN || 145 recv_buf[0] == FILE_INFO_BIG_ENDIAN) && 146 size > 0) { 147 if (flag_new_seq == true) { 148 // create directory for storage 149 QDateTime dateTime = QDateTime::currentDateTime(); 150 folder_name = dateTime.toString("yyyyMMdd_hhmm") + "_" + name; 151 if (QDir().exists(folder_name) == true) { 152 folder_name = dateTime.toString("yyyyMMdd_hhmm_ss") + "_" + name; 153 } 154 QDir().mkdir(folder_name); 155 156 flag_new_seq = false; 157 file_dialog->log("Creating directory " + folder_name); 158 } 159 160 QString file_name = 161 QString::fromAscii((const char *)&recv_buf[5], bytesRead - 5); 162 QString file_path = folder_name + "/" + file_name; 163 file_dialog->log( 164 QString("receiving %1 (%2 bytes)").arg(file_name).arg(size)); 165 QFile fichier(file_path); 166 167 if (!fichier.open(QIODevice::WriteOnly)) { 168 file_dialog->log(" could not write to file!"); 169 } else { 170 // receive file 171 recv_buf = (char *)realloc((void *)recv_buf, size); 172 bytesRead = UDT::recvmsg(file_socket, recv_buf, size); 173 if (bytesRead != size) { 174 file_dialog->log(QString(" error receiving file! (%1/%2)") 175 .arg(bytesRead) 176 .arg(size)); 177 free(recv_buf); 178 return; 179 } else { 180 file_dialog->log(" ok"); 181 } 182 183 QDataStream stream(&fichier); 184 stream.writeRawData(recv_buf, size); 185 fichier.close(); 186 187 file_dialog->addFile(file_path); 188 } 189 190 free(recv_buf); 191 } else if (recv_buf[0] == END) { 192 file_dialog->endOfFiles(); 193 flag_new_seq = true; 194 //end ack 195 UDT::sendmsg(file_socket,&recv_buf[0],1); 196 } 197 } 198 199 void UdtSocket::receiveData(void) { 200 while (1) { 201 int buf_size; 202 int opt_size; 203 UDT::getsockopt(com_socket, 0, UDT_RCVBUF, &buf_size, &opt_size); 204 205 char *buf = (char *)malloc(buf_size); 206 int size; 207 size = UDT::recvmsg(com_socket, buf, buf_size); 208 buf = (char *)realloc(buf, size + 1); 209 210 if (size > 0) { 211 buf[size] = 0; 212 emit dataReady(buf, size + 1); 213 } else { 214 // if(UDT::getlasterror().getErrorCode()!=6002) printf("udt socket: 215 // %s\n",UDT::getlasterror().getErrorMessage()); 216 free(buf); 217 break; 218 } 219 } 220 } 221 222 void UdtSocket::write(const char *buf, qint64 size) { 223 // printf("write\n%s\n",buf); 224 qint64 sent = UDT::sendmsg(com_socket, buf, size, -1, true); 213 } 214 free(uncompressbuf); 215 free(buf); 216 thread()->quit(); 217 } 218 219 qint64 UdtSocket::write(const char *buf, qint64 size,int ttl,bool inOrder) { 220 qint64 sent = UDT::sendmsg(socket, buf, size, ttl, inOrder); 225 221 if (sent != size) { 226 printf(" erreur envoi: %s\n", UDT::getlasterror().getErrorMessage());222 printf("%s, error writting to udt (%s)\n",name.toLocal8Bit().constData(), UDT::getlasterror().getErrorMessage()); 227 223 if (UDT::getlasterror().getErrorCode() == 2001) { 228 224 stop = true; 229 } 230 } 231 } 225 heartbeat_timer->stop(); 226 deleteLater(); 227 } 228 } 229 return sent; 230 } 231 232 int UdtSocket::uncompressBuffer(char *in, ssize_t in_size, char *out, 233 ssize_t *out_size) { 234 int ret; 235 unsigned have; 236 z_stream strm; 237 238 // allocate inflate state 239 strm.zalloc = Z_NULL; 240 strm.zfree = Z_NULL; 241 strm.opaque = Z_NULL; 242 strm.avail_in = 0; 243 strm.next_in = Z_NULL; 244 ret = inflateInit(&strm); 245 if (ret != Z_OK) 246 return ret; 247 248 strm.avail_in = in_size; 249 strm.next_in = (unsigned char *)in; 250 strm.avail_out = COMPRESS_CHUNK; 251 strm.next_out = (unsigned char *)out; 252 253 ret = inflate(&strm, Z_NO_FLUSH); 254 assert(ret != Z_STREAM_ERROR); // state not clobbered 255 switch (ret) { 256 case Z_NEED_DICT: 257 ret = Z_DATA_ERROR; // and fall through 258 case Z_DATA_ERROR: 259 case Z_MEM_ERROR: 260 (void)inflateEnd(&strm); 261 return ret; 262 } 263 have = COMPRESS_CHUNK - strm.avail_out; 264 *out_size = have; 265 266 // clean up and return 267 (void)inflateEnd(&strm); 268 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; 269 } -
trunk/tools/FlairGCS/src/UdtSocket.h
r15 r234 16 16 17 17 public: 18 UdtSocket(UDTSOCKET file_socket, UDTSOCKET com_socket,QString name);18 UdtSocket(UDTSOCKET socket,QString name); 19 19 ~UdtSocket(); 20 void setName(QString name); 21 QString getUDTStats(); 20 22 21 23 private: 22 UDTSOCKET file_socket, com_socket;23 file_ui *file_dialog;24 bool stop;24 UDTSOCKET socket; 25 bool stop,destroySocket; 26 QTimer *heartbeat_timer,*udtstats_timer; 25 27 QString name; 26 QTimer *heartbeat_timer; 27 void receiveData(void); 28 void receiveFile(void); 28 static int uncompressBuffer(char *in, ssize_t in_size, char *out,ssize_t *out_size); 29 enum SocketType { unknown, gui, log }; 30 SocketType socketType; 31 unsigned int total_received; 32 QString stats; 29 33 30 34 signals: 31 35 void dataReady(char *, int size); 36 void newFileUI(UDTSOCKET socket); 37 void newConnectionLayout(QString name); 38 void UDTStats(QString stats); 32 39 33 40 public slots: 34 void handleConnections(void);41 void receiveData(void); 35 42 void kill(void); 36 void write(const char *buf, qint64 size); 43 qint64 write(const char *buf, qint64 size,int ttl=-1,bool inOrder=true); 44 37 45 private slots: 38 46 void heartbeat(void); 47 void getUTDStats(void); 39 48 }; 40 49 -
trunk/tools/FlairGCS/src/file_ui.cpp
r214 r234 4 4 // %flair:license} 5 5 #include "file_ui.h" 6 #include "communication.h" 7 6 8 #include <stdio.h> 7 8 9 #include <cstring> 9 10 #include <cstdlib> … … 22 23 #include <QStringList> 23 24 #include <QFormLayout> 24 25 #ifndef WIN32 26 #include <arpa/inet.h> 27 #else 28 #include <winsock2.h> 29 #include <ws2tcpip.h> 30 #endif 31 25 #include <QThread> 26 27 #include <unistd.h> 32 28 using namespace std; 33 29 34 file_ui::file_ui() { 30 file_ui::file_ui(UDTSOCKET socket,QString name): QObject() { 31 this->socket=socket; 32 this->name=name; 33 34 bool blocking = true; 35 if (UDT::setsockopt(socket, 0, UDT_SNDSYN, &blocking, sizeof(bool))!= 0) { 36 printf("UDT::setsockopt error (UDT_SNDSYN) %s\n",UDT::getlasterror().getErrorMessage()); 37 } 38 39 linger _linger; 40 _linger.l_onoff=1; 41 _linger.l_linger=180; 42 43 if (UDT::setsockopt(socket, 0, UDT_LINGER, &_linger, sizeof(struct linger)) != 0) 44 printf("UDT::setsockopt error (UDT_LINGER) %s\n",UDT::getlasterror().getErrorMessage()); 45 35 46 dialog = new QDialog(); 47 //fprintf(stderr,"creator file ui %x\n",thread()); 36 48 dialog->setWindowTitle("log files"); 37 49 QGridLayout *main_layout = new QGridLayout(dialog); … … 42 54 input_text->setText("add your log comment here"); 43 55 input_cleared = false; 44 45 56 ok_button->setEnabled(false); 46 57 … … 56 67 main_layout->addWidget(ok_button, 3, 0); 57 68 58 connect(ok_button, SIGNAL(clicked()), this, SLOT(save()), 59 Qt::QueuedConnection); 60 connect(this, SIGNAL(showDialog()), dialog, SLOT(show()), 61 Qt::QueuedConnection); 62 connect(this, SIGNAL(appendToLog(QString)), log_text, SLOT(append(QString)), 63 Qt::QueuedConnection); 64 connect(input_text, SIGNAL(cursorPositionChanged()), this, 65 SLOT(clearInputText()), Qt::QueuedConnection); 69 //connect for multithreaded stuffs 70 connect(ok_button, SIGNAL(clicked()), this, SLOT(save()),Qt::QueuedConnection); 71 connect(input_text, SIGNAL(cursorPositionChanged()), this,SLOT(clearInputText()),Qt::DirectConnection); 72 connect(this, SIGNAL(appendToLog(QString)), log_text, SLOT(append(QString))); 66 73 67 74 file_names = new QStringList(); 68 } 69 70 file_ui::~file_ui() { delete dialog; } 71 72 void file_ui::log(QString text) { appendToLog(text); } 75 76 dialog->show(); 77 } 78 79 file_ui::~file_ui() { 80 delete dialog; 81 } 82 83 void file_ui::receive(void) { 84 char *recv_buf; 85 int bytesRead; 86 bool flag_new_seq = true; 87 QString folder_name; 88 //fprintf(stderr,"file_ui thread %x\n",thread()); 89 while(1) { 90 // receive file info 91 recv_buf = (char *)malloc(1024); 92 bytesRead = UDT::recvmsg(socket, recv_buf, 1024); 93 if (bytesRead <= 0) { 94 free(recv_buf); 95 break; 96 } 97 98 int size; 99 memcpy(&size, &recv_buf[1], sizeof(int)); 100 if (recv_buf[0] == FILE_INFO_BIG_ENDIAN) 101 size = qFromBigEndian(size); 102 103 // printf("file_ui recu %i %x\n",bytesRead,recv_buf[0]); 104 if ((recv_buf[0]==FILE_INFO_LITTLE_ENDIAN || recv_buf[0]==FILE_INFO_BIG_ENDIAN) && size>0) { 105 if (flag_new_seq == true) { 106 // create directory for storage 107 QDateTime dateTime = QDateTime::currentDateTime(); 108 folder_name = dateTime.toString("yyyyMMdd_hhmm") + "_" + name; 109 if (QDir().exists(folder_name) == true) { 110 folder_name = dateTime.toString("yyyyMMdd_hhmm_ss") + "_" + name; 111 } 112 QDir().mkdir(folder_name); 113 114 flag_new_seq = false; 115 appendToLog("Creating directory " + folder_name); 116 } 117 118 QString file_name=QString::fromAscii((const char *)&recv_buf[5], bytesRead - 5); 119 QString file_path=folder_name+"/"+file_name; 120 appendToLog(QString("receiving %1 (%2 bytes)").arg(file_name).arg(size)); 121 QFile fichier(file_path); 122 123 if (!fichier.open(QIODevice::WriteOnly)) { 124 appendToLog(" could not write to file!"); 125 } else { 126 // receive file 127 recv_buf = (char *)realloc((void *)recv_buf, size); 128 bytesRead = UDT::recvmsg(socket, recv_buf, size); 129 if (bytesRead != size) { 130 appendToLog(QString(" error receiving file! (%1/%2)").arg(bytesRead).arg(size)); 131 free(recv_buf); 132 break; 133 } else { 134 appendToLog(" ok"); 135 } 136 137 QDataStream stream(&fichier); 138 stream.writeRawData(recv_buf, size); 139 fichier.close(); 140 141 addFile(file_path); 142 } 143 144 free(recv_buf); 145 } else if (recv_buf[0] == END_SENDING_FILES) { 146 //end ack 147 UDT::sendmsg(socket,&recv_buf[0],1); 148 endOfFiles(); 149 UDT::close(socket); 150 printf("disconnected from log files\n"); 151 break; 152 } 153 } 154 } 73 155 74 156 void file_ui::addFile(QString file_path) { … … 86 168 dbt2csv(file_path.replace(QString(".txt"), QString(".dbt"))); 87 169 } 88 89 if (file_names->size() == 1) {90 input_cleared = false;91 showDialog();92 }93 170 } 94 171 … … 101 178 if (info.size() > max_file_size) { 102 179 max_file_size = info.size(); 103 csv_combo->setCurrentIndex(i + 104 1); // first item of combobox is already taken 180 csv_combo->setCurrentIndex(i+1); // first item of combobox is already taken 105 181 } 106 182 } … … 112 188 QStringList data_type; 113 189 114 QString filename = 115 file_path.section('/', -1); // remove path for displaying on logs 190 QString filename =file_path.section('/', -1); // remove path for displaying on logs 116 191 appendToLog(QString("converting %1 to csv").arg(filename)); 117 192 … … 145 220 break; 146 221 QString txt_line = txt_in.readLine(); 147 data_type.append(txt_line.section( 148 "(", 149 -1)); // on part de la fin pour trouver la premiere parenthese ouvrante 222 data_type.append(txt_line.section("(",-1)); // on part de la fin pour trouver la premiere parenthese ouvrante 150 223 // printf("type %s\n",txt_line.section("(",-1).toLocal8Bit().constData()); 151 224 } … … 241 314 } 242 315 243 log_text->clear();244 input_cleared = true; // avoid clearing it with setText245 input_text->setText("add your log comment here");246 file_names->clear();247 csv_combo->clear();248 csv_combo->addItem(QString("(no base time)"));249 250 dialog->setVisible(false);251 ok_button->setEnabled(false);252 316 emit finished(); 253 317 } -
trunk/tools/FlairGCS/src/file_ui.h
r15 r234 7 7 8 8 #include <QObject> 9 #include <udt.h> 9 10 10 11 class QStringList; … … 19 20 20 21 public: 21 file_ui( );22 file_ui(UDTSOCKET socket,QString name); 22 23 ~file_ui(); 23 24 void log(QString text); … … 36 37 void dbt2csv(QString file_path); 37 38 bool is_greater(qint64 ref_us, qint64 csv_us, int ref_ns, int csv_ns); 38 void closeEvent(QCloseEvent *e);39 39 bool input_cleared; 40 UDTSOCKET socket; 41 QString name; 40 42 43 public slots: 44 void receive(void); 45 41 46 private slots: 42 47 void save(void); … … 44 49 45 50 signals: 46 void showDialog(void);51 void finished(void); 47 52 void appendToLog(QString); 48 void finished();49 53 }; 50 54 -
trunk/tools/FlairGCS/src/main.cpp
r222 r234 6 6 #include <QCleanlooksStyle> 7 7 #include <QLocale> 8 #include <QTextCursor> 8 9 #include <qmetatype.h> 9 10 #include <tclap/CmdLine.h> … … 74 75 75 76 qRegisterMetaType<const char *>("const char*"); 77 qRegisterMetaType<UDTSOCKET>("UDTSOCKET"); 78 qRegisterMetaType<QTextCursor>("QTextCursor"); 76 79 QLocale::setDefault(QLocale::C); 77 80 QApplication app(argc, argv); -
trunk/tools/VrpnBridge/src/main.cpp
r233 r234 58 58 59 59 while (1) { 60 usleep( 10000);60 usleep(5000); 61 61 server_connection->mainloop(); 62 62 client_connection->mainloop();
Note:
See TracChangeset
for help on using the changeset viewer.