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

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

gcs

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