source: flair-src/trunk/tools/FlairGCS/src/ConnectionLayout.cpp@ 187

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

show rx rate in GCS

File size: 5.0 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 "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
[30]14#define RX_TIME 5000
[9]15
[15]16ConnectionLayout::ConnectionLayout(UdtSocket *socket, QString name)
17 : Layout(NULL, name, "root") {
18 isRemoteNameDefined = false;
19 this->socket = socket;
[30]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);
[9]25}
26
[30]27ConnectionLayout::~ConnectionLayout() {
28 receive_timer->stop();
29}
[9]30
[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
[15]37void ConnectionLayout::receive(char *buf, int size) {
[30]38 total_received+=size-1;
[15]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);
[9]55}
56
57void ConnectionLayout::XmlToSend(QDomDocument doc) {
[15]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()));
[9]64}
65
66void ConnectionLayout::LoadXml(QDomDocument to_parse) {
[15]67 if (!isRemoteNameDefined) {
68 printf("load xml: name not defined!\n");
69 return;
70 }
[9]71
[15]72 QDomElement tmp = to_parse.firstChildElement("root");
73 while (tmp.attribute("name") != remoteName && !tmp.isNull())
74 tmp = to_parse.nextSiblingElement("root");
[9]75
[15]76 if (!tmp.isNull()) {
77 XmlWidget::LoadXml(tmp);
78 } else {
79 printf("%s not found in xml file \n", remoteName.toLocal8Bit().constData());
80 }
[9]81}
82
[15]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);
[9]90
[15]91 // printf("recu %i\n%s\n",size,xml.toLocal8Bit().constData());
92 if (!doc.setContent(xml)) {
93 printf("prob setContent fichier\n");
94 }
[9]95
[15]96 if (!isRemoteNameDefined) {
97 isRemoteNameDefined = true;
98 remoteName = doc.firstChildElement("root").attribute("name");
99 setRemoteName(remoteName);
100 SetAttribute("name", remoteName);
101 }
[9]102
[15]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 }
[9]127}
128
[15]129void ConnectionLayout::removeDataRemote(DataRemote *data) {
130 dataremotes.removeOne(data);
[9]131}
132
[15]133void ConnectionLayout::addDataRemote(DataRemote *data) {
134 dataremotes.append(data);
[9]135}
136
[15]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 }
[9]143}
144
[15]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;
[9]150
[15]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;
[9]160
[15]161 *out = (char *)malloc(COMPRESS_CHUNK);
162 if (!(*out))
163 return Z_BUF_ERROR;
[9]164
[15]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;
[9]169
[15]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;
[9]182
[15]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;
[9]188}
Note: See TracBrowser for help on using the repository browser.