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

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