source: flair-src/trunk/tools/FlairGCS/src/UdtSocket.cpp@ 14

Last change on this file since 14 was 10, checked in by Sanahuja Guillaume, 9 years ago

lic

File size: 6.3 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 "UdtSocket.h"
6#include <stdio.h>
7#include <stdlib.h>
8#include <QApplication>
9#include <QtEndian>
10#include <QDir>
11#include <QDate>
12#include "file_ui.h"
13#include "communication.h"
14
15#ifndef WIN32
16 #include <arpa/inet.h>
17#else
18 #include <winsock2.h>
19 #include <ws2tcpip.h>
20#endif
21
22using namespace std;
23
24UdtSocket::UdtSocket(UDTSOCKET file_socket,UDTSOCKET com_socket,QString name): QObject() {
25 this->file_socket=file_socket;
26 this->com_socket=com_socket;
27 this->name=name;
28 stop=false;
29 file_dialog=new file_ui();
30
31 bool blocking = true;
32 UDT::setsockopt(file_socket, 0, UDT_RCVSYN, &blocking, sizeof(bool));
33
34 heartbeat_timer = new QTimer(this);
35 connect(heartbeat_timer, SIGNAL(timeout()), this, SLOT(heartbeat()));
36 heartbeat_timer->start(200);
37}
38
39UdtSocket::~UdtSocket() {
40 heartbeat_timer->stop();
41
42 UDT::close(file_socket);
43 UDT::close(com_socket);
44
45 file_dialog->deleteLater();
46}
47
48//send signal to uav, to check connectivity through a watchdog
49//this is necessary because we use udt (udp based), and we cannot check disconnection of ground station
50void UdtSocket::heartbeat(void) {
51 char data=WATCHDOG_HEADER;
52 write(&data,1);
53}
54
55void UdtSocket::kill(void) {
56 printf("disconnected\n");
57 stop=true;
58 deleteLater();
59}
60
61void UdtSocket::handleConnections(void) {
62 while(!stop) {
63 int eid = UDT::epoll_create();
64 if(eid<0) {
65 printf("epoll_create error: %s\n",UDT::getlasterror().getErrorMessage());
66 }
67
68 if(UDT::epoll_add_usock(eid,file_socket)<0) {
69 if(UDT::getlasterror().getErrorCode()==5004) {
70 printf("epoll_add_usock\n");
71 break;
72 } else {
73 printf("epoll_add_usock error: %s\n",UDT::getlasterror().getErrorMessage());
74 }
75 }
76 if(UDT::epoll_add_usock(eid,com_socket)<0) {
77 if(UDT::getlasterror().getErrorCode()==5004) {
78 printf("epoll_add_usock\n");
79 break;
80 } else {
81 printf("epoll_add_usock error: %s\n",UDT::getlasterror().getErrorMessage());
82 }
83 }
84
85 set<UDTSOCKET> readfds;
86
87 int rv=UDT::epoll_wait(eid, &readfds,NULL, 10) ;
88
89 if(rv == -1) {
90 if(UDT::getlasterror().getErrorCode()!=6003) printf("prob %i\n",UDT::getlasterror().getErrorCode());
91 //printf("wait\n");
92 } else if(rv == 0) {
93 printf("timeout\n"); // a timeout occured
94 } else {
95 /*
96 if(UDT::getlasterror().getErrorCode()==2001) {
97 UDT::epoll_release(eid);
98 }*/
99 for (set<UDTSOCKET>::iterator i = readfds.begin(); i != readfds.end(); i++) {
100 //printf("a\n");
101 if(*i==file_socket) receiveFile();
102 if(*i==com_socket) receiveData();
103 }
104 }
105
106 UDT::epoll_remove_usock(eid,file_socket);
107 UDT::epoll_remove_usock(eid,com_socket);
108 UDT::epoll_release(eid);
109
110 QCoreApplication::processEvents();
111 }
112 kill();
113}
114
115void UdtSocket::receiveFile(void) {
116 char* recv_buf;
117 int bytesRead;
118 static bool flag_new_seq=true;
119 static QString folder_name;
120
121 //receive file info
122 recv_buf= (char*)malloc(1024);
123 bytesRead = UDT::recvmsg(file_socket,recv_buf,1024);
124
125 if(bytesRead<=0) {
126 free(recv_buf);
127 return;
128 }
129
130 int size;
131 memcpy(&size,&recv_buf[1],sizeof(int));
132 if(recv_buf[0]==FILE_INFO_BIG_ENDIAN) size=qFromBigEndian(size);
133
134 //printf("file_ui recu %i %x\n",bytesRead,recv_buf[0]);
135 if((recv_buf[0]==FILE_INFO_LITTLE_ENDIAN || recv_buf[0]==FILE_INFO_BIG_ENDIAN) && size>0) {
136 if(flag_new_seq==true) {
137 //create directory for storage
138 QDateTime dateTime = QDateTime::currentDateTime();
139 folder_name = dateTime.toString("yyyyMMdd_hhmm")+ "_" + name;
140 if(QDir().exists(folder_name)==true) {
141 folder_name = dateTime.toString("yyyyMMdd_hhmm_ss")+ "_" + name;
142 }
143 QDir().mkdir(folder_name);
144
145 flag_new_seq=false;
146 file_dialog->log("Creating directory " +folder_name);
147 }
148
149 QString file_name= QString::fromAscii((const char*)&recv_buf[5],bytesRead-5);
150 QString file_path=folder_name + "/" + file_name;
151 file_dialog->log(QString("receiving %1 (%2 bytes)").arg(file_name).arg(size));
152 QFile fichier(file_path);
153
154 if(!fichier.open(QIODevice::WriteOnly)) {
155 file_dialog->log(" could not write to file!");
156 } else {
157 //receive file
158 recv_buf= (char*)realloc((void*)recv_buf,size);
159 bytesRead = UDT::recvmsg(file_socket,recv_buf,size);
160 if(bytesRead!=size) {
161 file_dialog->log(QString(" error receiving file! (%1/%2)").arg(bytesRead).arg(size));
162 free(recv_buf);
163 return;
164 } else {
165 file_dialog->log(" ok");
166 }
167
168 QDataStream stream(&fichier);
169 stream.writeRawData(recv_buf,size);
170 fichier.close();
171
172 file_dialog->addFile(file_path);
173 }
174
175 free(recv_buf);
176 } else if(recv_buf[0]==END) {
177 file_dialog->endOfFiles();
178 flag_new_seq=true;
179 }
180}
181
182void UdtSocket::receiveData(void) {
183 while(1) {
184 int buf_size;
185 int opt_size;
186 UDT::getsockopt(com_socket,0,UDT_RCVBUF,&buf_size,&opt_size);
187
188 char* buf=(char*)malloc(buf_size);
189 int size;
190 size = UDT::recvmsg(com_socket,buf, buf_size);
191 buf=(char*)realloc(buf,size+1);
192
193 if(size>0) {
194 buf[size]=0;
195 emit dataReady(buf,size+1);
196 } else {
197 //if(UDT::getlasterror().getErrorCode()!=6002) printf("udt socket: %s\n",UDT::getlasterror().getErrorMessage());
198 free(buf);
199 break;
200 }
201 }
202}
203
204void UdtSocket::write(const char* buf, qint64 size) {
205 //printf("write\n%s\n",buf);
206 qint64 sent=UDT::sendmsg(com_socket,buf,size, -1, true);
207 if(sent!=size) {
208 printf("erreur envoi: %s\n",UDT::getlasterror().getErrorMessage());
209 if(UDT::getlasterror().getErrorCode()==2001) {
210 stop=true;
211 }
212 }
213}
Note: See TracBrowser for help on using the repository browser.