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

Last change on this file since 67 was 30, checked in by Sanahuja Guillaume, 5 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.