source: flair-src/trunk/tools/FlairGCS/src/ConnectionLayout.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: 5.0 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
4// %flair:license}
5#include "ConnectionLayout.h"
6#include "UdtSocket.h"
7#include "DataRemote.h"
8#include <qendian.h>
9#include "communication.h"
10#include <zlib.h>
11#include <assert.h>
12
13#define COMPRESS_CHUNK 1024
14#define RX_TIME 5000
15
16ConnectionLayout::ConnectionLayout(UdtSocket *socket, QString name)
17 : Layout(NULL, name, "root") {
18 isRemoteNameDefined = false;
19 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);
25}
26
27ConnectionLayout::~ConnectionLayout() {
28 receive_timer->stop();
29}
30
31void 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);
35}
36
37void ConnectionLayout::receive(char *buf, int size) {
38 total_received+=size-1;
39 // printf("trame %x\n",buf[0]);
40 // for(int i=0; i<size;i++) printf("%x ",buf[i]);
41 // 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
57void ConnectionLayout::XmlToSend(QDomDocument doc) {
58 // printf("xml to send\n%s\n",doc.toString().toLocal8Bit().constData());
59 // xml to send a mettre dans le manager
60 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
66void 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
83void ConnectionLayout::handleUncompressedFrame(char *buf, ssize_t size) {
84 switch ((unsigned char)buf[0]) {
85 case XML_HEADER: {
86 QString xml;
87 QDomDocument doc;
88 xml = QString((char *)buf);
89 xml.resize(size);
90
91 // printf("recu %i\n%s\n",size,xml.toLocal8Bit().constData());
92 if (!doc.setContent(xml)) {
93 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 }
102
103 ParseXml(doc.firstChildElement("root").firstChildElement());
104 break;
105 }
106 case DATAS_BIG_ENDIAN: {
107 // for(int i=0;i<size;i++) printf("%x ",buf[i]);
108 // printf("\n");
109 uint16_t period;
110 memcpy(&period, &buf[1], sizeof(uint16_t));
111 period = qFromBigEndian(period);
112 drawDatas(&buf[3], size - 3, period, true);
113 break;
114 }
115 case DATAS_LITTLE_ENDIAN: {
116 // for(int i=0;i<size;i++) printf("%x ",buf[i]);
117 // printf("\n");
118 uint16_t period;
119 memcpy(&period, &buf[1], sizeof(uint16_t));
120 // printf("recu %i period %i\n",size,period);
121 drawDatas(&buf[3], size - 3, period);
122 break;
123 }
124 default:
125 printf("trame non supportée %x\n", buf[0]);
126 }
127}
128
129void ConnectionLayout::removeDataRemote(DataRemote *data) {
130 dataremotes.removeOne(data);
131}
132
133void ConnectionLayout::addDataRemote(DataRemote *data) {
134 dataremotes.append(data);
135}
136
137QString ConnectionLayout::getRemoteName() { return remoteName; }
138void ConnectionLayout::drawDatas(char *buf, int buf_size, uint16_t period,
139 bool big_endian) {
140 for (int i = 0; i < dataremotes.count(); i++) {
141 dataremotes.at(i)->BufEvent(&buf, &buf_size, period, big_endian);
142 }
143}
144
145int ConnectionLayout::uncompressBuffer(char *in, ssize_t in_size, char **out,
146 ssize_t *out_size) {
147 int ret;
148 unsigned have;
149 z_stream strm;
150
151 // allocate inflate state
152 strm.zalloc = Z_NULL;
153 strm.zfree = Z_NULL;
154 strm.opaque = Z_NULL;
155 strm.avail_in = 0;
156 strm.next_in = Z_NULL;
157 ret = inflateInit(&strm);
158 if (ret != Z_OK)
159 return ret;
160
161 *out = (char *)malloc(COMPRESS_CHUNK);
162 if (!(*out))
163 return Z_BUF_ERROR;
164
165 strm.avail_in = in_size;
166 strm.next_in = (unsigned char *)in;
167 strm.avail_out = COMPRESS_CHUNK;
168 strm.next_out = (unsigned char *)*out;
169
170 ret = inflate(&strm, Z_NO_FLUSH);
171 assert(ret != Z_STREAM_ERROR); // state not clobbered
172 switch (ret) {
173 case Z_NEED_DICT:
174 ret = Z_DATA_ERROR; // and fall through
175 case Z_DATA_ERROR:
176 case Z_MEM_ERROR:
177 (void)inflateEnd(&strm);
178 return ret;
179 }
180 have = COMPRESS_CHUNK - strm.avail_out;
181 *out_size = have;
182
183 // printf("%i -> %i\n",in_size,have);
184 // printf("%s\n",*out);
185 // clean up and return
186 (void)inflateEnd(&strm);
187 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
188}
Note: See TracBrowser for help on using the repository browser.