00001 #include <QByteArray>
00002 #include <string.h>
00003
00004 #include "exeptions.h"
00005 #include "communication.h"
00006 #include <MD5Hash.h>
00007 #include <QFileInfo>
00008 #include <stdlib.h>
00009
00010
00011
00012
00013 #define PACKET_TIME 10000
00014 #define PACKET_RETRY 3
00015 #define PING_TIME 60000
00016 #define CONNECT_TIMEOUT 5000
00017 #define FILE_PORT 2330
00018
00019 #define MAX_PING_TIME 5000
00020 #define MAX_FILE_TIME 120000
00021
00022
00023 uint qHash (const QHostAddress &ip)
00024 {
00025 return ip.toIPv4Address ();
00026 }
00027
00028 LanPacket::LanPacket ()
00029 {
00030 clearData ();
00031 }
00032
00033 LanPacket::LanPacket (const QByteArray &data)
00034 {
00035 clearData ();
00036 if (data.size () < 3 || data.at(0) <= Invalid || data.at(0) > FileRefuse)
00037 {
00038 qDebug ("LanPacket::LanPacket(QByteArray) :: nieprawidlowy pakiet\n");
00039 return;
00040 }
00041
00042 packet_type = (PacketType) data.at(0);
00043 data_size = (quint8)data.at(1) | (quint8)data.at(2) << 8;
00044 if (data.size() < data_size+3)
00045 {
00046 qDebug ("LanPacket::LanPacket(QByteArray) :: nieprawidlowy pakiet - za krotki\n");
00047 return;
00048 }
00049
00050 switch (packet_type)
00051 {
00052 case Welcome:
00053 file_size = (quint8)data.at(3) | (quint8)data.at(4) << 8 | (quint8)data.at(5) << 16 | (quint8)data.at(6) << 24;
00054 str_data = QString::fromUtf8(data.mid(7, data_size-4).data(), data_size-4);
00055 if (str_data.size () < 1)
00056 {
00057 qDebug ("LanPacket::LanPacket(QByteArray) :: pakiet welcome nie zawiera nicka\n");
00058 return;
00059 }
00060 is_valid = true;
00061 break;
00062
00063 case Hi:
00064 str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00065 if (str_data.size () < 1)
00066 {
00067 qDebug ("LanPacket::LanPacket(QByteArray) :: pakiet hi nie zawiera nicka\n");
00068 return;
00069 }
00070 is_valid = true;
00071 break;
00072
00073 case Bye:
00074 case Ping:
00075 case Pong:
00076 case SysPing:
00077 case SysPong:
00078 is_valid = true;
00079 break;
00080
00081 case Bmsg:
00082 str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00083 if (str_data.size () < 1)
00084 {
00085 qDebug ("LanPacket::LanPacket(QByteArray) :: akiet broadcast msg nie zawiera tresci\n");
00086 return;
00087 }
00088 is_valid = true;
00089 break;
00090 qDebug ("LanPacket::LanPacket(QByteArray) :: \n");
00091
00092 case BmsgOk:
00093 str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00094 if (str_data.size () < 1)
00095 {
00096 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet broadcast msg ok nie zawiera md5\n");
00097 return;
00098 }
00099 is_valid = true;
00100 break;
00101
00102 case Pmsg:
00103 str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00104 if (str_data.size () < 1)
00105 {
00106 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet private msg nie zawiera tresci\n");
00107 return;
00108 }
00109 is_valid = true;
00110 break;
00111
00112 case PmsgOk:
00113 str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00114 if (str_data.size () < 1)
00115 {
00116 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet private msg ok nie zawiera md5\n");
00117 return;
00118 }
00119 is_valid = true;
00120 break;
00121
00122 case FileReq:
00123 if (data_size < 5)
00124 {
00125 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet file request jest za krótki\n");
00126 return;
00127 }
00128
00129 file_size = (quint8)data.at(3) | (quint8)data.at(4) << 8 | (quint8)data.at(5) << 16 | (quint8)data.at(6) << 24;
00130 str_data = QString::fromUtf8(data.mid(7, data_size-4).data(), data_size-4);
00131 is_valid = true;
00132 break;
00133
00134 case FileOk:
00135 if (data_size < 3)
00136 {
00137 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet file ok jest za krótki\n");
00138 return;
00139 }
00140
00141 port = (quint8)data.at(3) | (quint8)data.at(4) << 8;
00142 str_data = QString::fromUtf8(data.mid(5, data_size-2).data(), data_size-2);
00143 is_valid = true;
00144 break;
00145
00146 case FileRefuse:
00147 str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00148 if (str_data.size () < 1)
00149 {
00150 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet file refuse nie zawiera md5\n");
00151 return;
00152 }
00153 is_valid = true;
00154 break;
00155
00156 default:
00157 is_valid = false;
00158 break;
00159 }
00160 }
00161
00162 LanPacket::LanPacket (const enum PacketType packet_type)
00163 {
00164 clearData ();
00165 this->packet_type = packet_type;
00166 is_valid = validate ();
00167 }
00168
00169 LanPacket::LanPacket (const enum PacketType packet_type, const QString& str_data, quint32 file_size, quint16 port)
00170 {
00171 clearData ();
00172 this->packet_type = packet_type;
00173 this->str_data = QString (str_data);
00174 if (file_size) this->file_size = file_size;
00175 if (port) this->port = port;
00176 is_valid = validate ();
00177 }
00178
00179 bool LanPacket::isValid () const
00180 {
00181 return is_valid;
00182 }
00183
00184 QByteArray LanPacket::constData ()
00185 {
00186 if (!is_valid) return QByteArray();
00187 if (!packet_data.isEmpty ())
00188 return QByteArray (packet_data);
00189
00190 char tmp_char = packet_type;
00191 packet_data.append (tmp_char);
00192 QByteArray utf_str;
00193
00194 switch (packet_type)
00195 {
00196 case Hi:
00197 case Bmsg:
00198 case BmsgOk:
00199 case Pmsg:
00200 case PmsgOk:
00201 case FileRefuse:
00202 utf_str = str_data.toUtf8 ();
00203 data_size = utf_str.size ();
00204 packet_data.append (packInt(data_size, false));
00205 packet_data.append (utf_str);
00206 break;
00207
00208 case Welcome:
00209 case FileReq:
00210 utf_str = str_data.toUtf8 ();
00211 data_size = utf_str.size ()+4;
00212 packet_data.append (packInt(data_size, false));
00213 packet_data.append (packInt(file_size, true));
00214 packet_data.append (utf_str);
00215 break;
00216
00217 case FileOk:
00218 utf_str = str_data.toUtf8 ();
00219 data_size = utf_str.size ()+2;
00220 packet_data.append (packInt(data_size, false));
00221 packet_data.append (packInt(port, false));
00222 packet_data.append (utf_str);
00223 break;
00224
00225 default:
00226 data_size = 0;
00227 packet_data.append (packInt(data_size, false));
00228 break;
00229 }
00230 return QByteArray (packet_data);
00231 }
00232
00233 LanPacket::PacketType LanPacket::getType () const
00234 {
00235 return packet_type;
00236 }
00237
00238 quint16 LanPacket::getSize () const
00239 {
00240 return data_size;
00241 }
00242
00243 QString LanPacket::getString () const
00244 {
00245 return QString (str_data);
00246 }
00247
00248 quint32 LanPacket::getFileSize () const
00249 {
00250 return file_size;
00251 }
00252
00253 quint16 LanPacket::getPort () const
00254 {
00255 return port;
00256 }
00257
00258 QByteArray LanPacket::packInt (quint32 num, bool bit32)
00259 {
00260 char tmp[4];
00261 tmp[0] = num & 0xff;
00262 tmp[1] = (num >> 8) & 0xff;
00263 if (bit32)
00264 {
00265 tmp[2] = (num >> 16) & 0xff;
00266 tmp[3] = (num >> 24) & 0xff;
00267 }
00268 return QByteArray (tmp, bit32 ? 4 : 2);
00269 }
00270
00271 void LanPacket::clearData ()
00272 {
00273 packet_type = Invalid;
00274 is_valid = false;
00275 packet_data.clear ();
00276 str_data.clear ();
00277 data_size = file_size = port = 0;
00278 }
00279
00280 bool LanPacket::validate ()
00281 {
00282 if (packet_type == Invalid) return false;
00283
00284 switch (packet_type)
00285 {
00286 case Welcome:
00287 case Hi:
00288 case Bmsg:
00289 case BmsgOk:
00290 case Pmsg:
00291 case PmsgOk:
00292 case FileRefuse:
00293 if (str_data.isEmpty()) return false;
00294 break;
00295
00296 case FileReq:
00297 if (str_data.isEmpty()) return false;
00298 if (!file_size) return false;
00299 break;
00300
00301 case FileOk:
00302 if (str_data.isEmpty()) return false;
00303 if (!port) return false;
00304 break;
00305
00306 default:
00307 return true;
00308 break;
00309 }
00310 return true;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 Communication::Communication () : QObject ()
00323 {
00324 QTime time = QTime::currentTime ();
00325
00326 srand (time.msec ());
00327 rand_num = rand ();
00328 is_connect = connecting = false;
00329 ip_list.clear ();
00330 ping_list.clear ();
00331 packet_queue.clear ();
00332 incoming_file.clear ();
00333 is_transfer = false;
00334 file_transfer = NULL;
00335
00336 packet_timer = new QTimer (this);
00337 ping_timer = new QTimer (this);
00338 connect_timer = NULL;
00339 connect (packet_timer, SIGNAL(timeout()), this, SLOT(packetTimer()));
00340 connect (ping_timer, SIGNAL(timeout()), this, SLOT(sysPingTimer()));
00341 connect (&read_socket, SIGNAL(readyRead()), this, SLOT(readData()));
00342
00343 srand (rand_num);
00344 rand_num = rand ();
00345 }
00346
00347 Communication::~Communication ()
00348 {
00349 delete packet_timer;
00350 delete ping_timer;
00351 delete file_transfer;
00352 if (is_connect) bye ();
00353 }
00354
00355 void Communication::welcome (const QString& nick, QHostAddress broadcast, quint16 port)
00356 {
00357 if (nick.isEmpty ())
00358 throw Exeptions (1, QObject::tr("Niedozwolony pusty nick"), QObject::tr("Communication::welcome (QString,QHostAddress,quint16)"), QObject::tr("Próba połączenia z pustym nickiem"));
00359 if (is_connect)
00360 throw Exeptions (1, QObject::tr("Program jest połączony"), QObject::tr("Communication::welcome (QString,QHostAddress,quint16)"), QObject::tr("Próba ponownego połączenia, gdy program jest już połączony"));
00361 if (connecting)
00362 throw Exeptions (1, QObject::tr("Program łączy się"), QObject::tr("Communication::welcome (QString,QHostAddress,quint16)"), QObject::tr("Próba połączenia, podczas gdy program jest w trakcie łączenia"));
00363
00364 this->main_port = port;
00365 this->broadcast = broadcast;
00366 user_nick = nick;
00367 my_ip.clear ();
00368 srand (rand_num);
00369 rand_num = rand ();
00370
00371 ip_list.clear ();
00372 packet_queue.clear ();
00373 incoming_file.clear ();
00374 connecting = true;
00375 if (!read_socket.bind (main_port))
00376 {
00377 qDebug ("Nie mozna wywolac bind na porcie %d", main_port);
00378 read_socket.close ();
00379 connecting = false;
00380 throw Exeptions (1, QObject::tr("Nie można nasłuchiwać"), QObject::tr("Communication::welcome (QString,QHostAddress,quint16)"), QObject::tr("Nie można nasłuchiwać na porcie ")+QString::number (main_port)+tr(" Prawdopodobnie port jest zajęty lub nie mamy do niego dostępu"));
00381 }
00382
00383 connect_timer = new QTimer (this);
00384 connect_timer->setSingleShot (true);
00385 connect_timer->setInterval (CONNECT_TIMEOUT);
00386 connect_timer->start (CONNECT_TIMEOUT);
00387 connect (connect_timer, SIGNAL(timeout()), this, SLOT(connectTimeOut ()));
00388
00389 ping_list.clear ();
00390 send_file_list.clear ();
00391 is_transfer = false;
00392 delete file_transfer;
00393 file_transfer = NULL;
00394 this->sendPacket (broadcast, LanPacket(LanPacket::Welcome, nick, rand_num));
00395 }
00396
00397 void Communication::bye ()
00398 {
00399 if (!is_connect && !connecting)
00400 throw Exeptions (1, QObject::tr("Program rozłączony"), QObject::tr("Communication::bye ()"), QObject::tr("Próba rozłączenia podczas gdy program jest rozłączony"));
00401
00402 this->sendPacket (broadcast, LanPacket(LanPacket::Bye));
00403 packet_timer->stop ();
00404 ping_timer->stop ();
00405
00406 user_nick.clear ();
00407 packet_queue.clear ();
00408 ip_list.clear ();
00409 send_file_list.clear ();
00410 incoming_file.clear ();
00411 is_connect = connecting = false;
00412 read_socket.close ();
00413 my_ip.clear ();
00414 if (connect_timer)
00415 {
00416 disconnect (connect_timer, SIGNAL(timeout()), this, SLOT(connectTimeOut ()));
00417 delete connect_timer;
00418 connect_timer = NULL;
00419 }
00420 if (is_transfer)
00421 {
00422 emit transferEnd (file_transfer->getIp(), false);
00423 is_transfer = false;
00424 delete file_transfer;
00425 file_transfer = NULL;
00426 }
00427 }
00428
00429 void Communication::sendPMsg (const QHostAddress &user_ip, const QString& msg)
00430 {
00431 checkConnection ("Communication::sendPMsg (const QHostAddress, const QString)");
00432 this->sendPacket (user_ip, LanPacket(LanPacket::Pmsg, msg), true);
00433 }
00434
00435 void Communication::sendBMsg (const QString& msg)
00436 {
00437 checkConnection ("Communication::sendBMsg (const QString)");
00438 this->sendPacket (broadcast, LanPacket(LanPacket::Bmsg, msg), true);
00439 }
00440
00441 void Communication::sendFile (QHostAddress user_ip, QString file_name)
00442 {
00443 checkConnection ("Communication::sendFile (QHostAddress, QString, quint32)");
00444 if (is_transfer)
00445 throw Exeptions (1, tr("Można wysłać tylko jeden plik"), tr("Communication::sendFile (QHostAddress, QString, quint32)"), tr("Próba wysłania pliku podczas gdy plik jest przesyłany"));
00446
00447 QFileInfo file_info (file_name);
00448 quint32 file_size = file_info.size ();
00449 SendFileTime sft;
00450 sft.name = file_name;
00451 sft.time = QTime::currentTime ();
00452 sft.time.start ();
00453 send_file_list.insert (user_ip, sft);
00454 this->sendPacket (user_ip, LanPacket(LanPacket::FileReq, file_info.fileName(), file_size));
00455 }
00456
00457 void Communication::checkPing (QHostAddress user_ip)
00458 {
00459 checkConnection ("Communication::checkPing (QHostAddress)");
00460
00461 if (ping_list.contains (user_ip))
00462 return;
00463 this->sendPacket (user_ip, LanPacket(LanPacket::Ping));
00464 ping_list.insert (user_ip, QTime::currentTime());
00465 ping_list[user_ip].start();
00466 }
00467
00468 void Communication::acceptFileRequest (QHostAddress user_ip, const QString &path)
00469 {
00470 checkConnection ("Communication::acceptFileRequest (QHostAddress, quint16)");
00471
00472 if (!incoming_file.contains (user_ip))
00473 throw Exeptions(1, QObject::tr("Brak żądania wysłania pliku"), QObject::tr("Communication::refuseFileRequest (QHostAddress)"), QObject::tr("Próba przyjęcia pliku od użytkownika który nie wysyłał żądania"));
00474
00475 is_transfer = true;
00476 file_transfer = new FileTransfer ();
00477 connect (file_transfer, SIGNAL(transferEnd(bool)), this, SLOT(fileTransferEnd(bool)));
00478 connect (file_transfer, SIGNAL(posOfProgresBarChanged(int)), this, SLOT(fileTransferProgres(int)));
00479
00480 try
00481 {
00482 file_transfer->receiveFile (user_ip, FILE_PORT, path, incoming_file.value(user_ip).size);
00483 }
00484 catch (Exeptions & wyjatek)
00485 {
00486 this->sendPacket (user_ip, LanPacket(LanPacket::FileRefuse, MD5Hash::hashData(incoming_file.value(user_ip).name.toUtf8())));
00487 throw wyjatek;
00488 }
00489
00490 this->sendPacket (user_ip, LanPacket(LanPacket::FileOk, MD5Hash::hashData(incoming_file.value(user_ip).name.toUtf8()), (quint32) 0, (quint16) FILE_PORT));
00491
00492 incoming_file.remove (user_ip);
00493 }
00494
00495 void Communication::refuseFileRequest (QHostAddress user_ip)
00496 {
00497 checkConnection ("Communication::refuseFileRequest (QHostAddress)");
00498
00499 if (!incoming_file.contains (user_ip))
00500 throw Exeptions(1, QObject::tr("Brak żądania wysłania pliku"), QObject::tr("Communication::refuseFileRequest (QHostAddress)"), QObject::tr("Próba odmówienia przyjęcia pliku od użytkownika który nie wysyłał żądania"));
00501
00502 this->sendPacket (user_ip, LanPacket(LanPacket::FileRefuse, MD5Hash::hashData(incoming_file.value(user_ip).name.toUtf8())));
00503 incoming_file.remove (user_ip);
00504 }
00505
00506 void Communication::cancelTranfer ()
00507 {
00508 if (!is_transfer)
00509 return;
00510 is_transfer = false;
00511 file_transfer->cancelTransfer ();
00512 file_transfer->deleteLater ();
00513
00514 file_transfer = NULL;
00515 }
00516
00517
00518
00519
00520
00521
00522
00523 void Communication::connectOk (const QHostAddress &ip)
00524 {
00525 if (connect_timer)
00526 {
00527 disconnect (connect_timer, SIGNAL(timeout()), this, SLOT(connectTimeOut ()));
00528 delete connect_timer;
00529 connect_timer = NULL;
00530 }
00531 my_ip = ip;
00532 packet_timer->start (PACKET_TIME);
00533 ping_timer->start (PING_TIME);
00534 connecting = false;
00535 is_connect = true;
00536 emit connected ();
00537 qDebug ("polaczony\n");
00538 }
00539
00540 void Communication::connectFail ()
00541 {
00542 this->bye ();
00543 emit unableConnect ();
00544 qDebug ("nie mozna polaczyc\n");
00545
00546 }
00547
00548 void Communication::checkConnection (const QString &place)
00549 {
00550 if (!is_connect)
00551 throw Exeptions(1, tr("Niepołączony"), place, tr("Próba wysłania pakietu gdy program jest niepołączony"));
00552 }
00553
00554 void Communication::sendPacket (QHostAddress ip, LanPacket packet, bool control)
00555 {
00556 QUdpSocket socket (this);
00557 if (!packet.isValid ())
00558 {
00559 qDebug ("Próba wysłania nieprawidłowego pakietu\n");
00560 return;
00561 }
00562 if (!is_connect && packet.getType () != LanPacket::Welcome)
00563 return;
00564
00565 socket.writeDatagram (packet.constData(), ip, main_port);
00566 socket.flush ();
00567 qDebug ("wyslalem: %d\n", packet.constData().size());
00568
00569 if (control)
00570 {
00571 QueueItem qi;
00572 qi.packet = packet;
00573 qi.last_send = QTime::currentTime ();
00574 if (packet.getType() == LanPacket::Pmsg || packet.getType() == LanPacket::Bmsg)
00575 qi.md5 = MD5Hash::hashData (packet.getString().toUtf8());
00576
00577 if (ip == broadcast)
00578 {
00579 for (int i=0; i < ip_list.size(); i++)
00580 qi.num_err.insert (ip_list.at(i), 0);
00581 }
00582 else
00583 qi.num_err.insert (ip, 0);
00584
00585 packet_queue.append (qi);
00586 }
00587
00588 qDebug ("Wysylam pakiet %d do %s\n", packet.getType(), ip.toString().toAscii().data());
00589 }
00590
00591 void Communication::servicePacket (LanPacket &packet, QHostAddress ip)
00592 {
00593 QString tmp_str;
00594 LanPacket res_pack;
00595
00596 qDebug ("Obsluguje pakiet %d od %s\n", packet.getType(), ip.toString().toAscii().data());
00597
00598 switch (packet.getType ())
00599 {
00600 case LanPacket::Welcome:
00601 if (connecting && packet.getFileSize () == rand_num && packet.getString() == user_nick)
00602 connectOk (ip);
00603 else if (!ip_list.contains (ip))
00604 {
00605 ip_list.append (ip);
00606 emit newUser (ip, packet.getString());
00607 }
00608 sendPacket (ip, LanPacket(LanPacket::Hi, user_nick));
00609 break;
00610
00611 case LanPacket::Hi:
00612 if (!ip_list.contains (ip))
00613 {
00614 ip_list.append (ip);
00615 if (user_nick == packet.getString ())
00616 {
00617 this->bye ();
00618 qDebug ("Nick jest zajęty, rozlaczam sie");
00619 emit invalidNick ();
00620 }
00621 emit newUser (ip, packet.getString());
00622 }
00623 break;
00624
00625 case LanPacket::Bye:
00626 if (ip_list.contains (ip))
00627 emit leaveUser (ip);
00628 removeUser (ip);
00629 break;
00630
00631 case LanPacket::Ping:
00632 sendPacket (ip, LanPacket(LanPacket::Pong));
00633 break;
00634
00635 case LanPacket::Pong:
00636 if (ip_list.contains (ip) && ping_list.contains (ip))
00637 {
00638 emit pong (ip, ping_list.value(ip).elapsed());
00639 ping_list.remove (ip);
00640 }
00641 break;
00642
00643 case LanPacket::SysPing:
00644 sendPacket (ip, LanPacket(LanPacket::SysPong));
00645 break;
00646
00647 case LanPacket::SysPong:
00648 removeQueue (ip, LanPacket::SysPing, QString());
00649 break;
00650
00651 case LanPacket::Bmsg:
00652 if (ip_list.contains (ip))
00653 {
00654 emit recvBMsg (ip, packet.getString());
00655 tmp_str = MD5Hash::hashData (packet.getString().toUtf8());
00656 sendPacket (ip, LanPacket(LanPacket::BmsgOk, tmp_str));
00657 }
00658 break;
00659
00660 case LanPacket::BmsgOk:
00661 removeQueue (ip, LanPacket::Bmsg, packet.getString ());
00662 break;
00663
00664 case LanPacket::Pmsg:
00665 if (ip_list.contains (ip))
00666 {
00667 emit recvPMsg (ip, packet.getString());
00668 tmp_str = MD5Hash::hashData (packet.getString().toUtf8());
00669 sendPacket (ip, LanPacket(LanPacket::PmsgOk, tmp_str));
00670 }
00671 break;
00672
00673 case LanPacket::PmsgOk:
00674 removeQueue (ip, LanPacket::Pmsg, packet.getString ());
00675 break;
00676
00677 case LanPacket::FileReq:
00678 if (ip_list.contains (ip))
00679 {
00680 if (is_transfer)
00681 {
00682 this->sendPacket (ip, LanPacket(LanPacket::FileRefuse, MD5Hash::hashData(packet.getString().toUtf8())));
00683 }
00684 else
00685 {
00686 RecvFileSize rfs;
00687 rfs.name = packet.getString();
00688 rfs.size = packet.getFileSize ();
00689 incoming_file.insert (ip, rfs);
00690 emit fileRequest (ip, packet.getString(), packet.getFileSize());
00691 }
00692 }
00693 break;
00694
00695 case LanPacket::FileOk:
00696 if (ip_list.contains(ip) && send_file_list.contains(ip))
00697 {
00698 emit acceptSendFile (ip, send_file_list.value(ip).name);
00699 is_transfer = true;
00700
00701 file_transfer = new FileTransfer ();
00702 connect (file_transfer, SIGNAL(transferEnd(bool)), this, SLOT(fileTransferEnd(bool)));
00703 connect (file_transfer, SIGNAL(posOfProgresBarChanged(int)), this, SLOT(fileTransferProgres(int)));
00704
00705 file_transfer->sendFile (ip, packet.getPort (), send_file_list.value(ip).name);
00706
00707 send_file_list.remove (ip);
00708 }
00709 break;
00710
00711 case LanPacket::FileRefuse:
00712 if (ip_list.contains(ip) && send_file_list.contains(ip))
00713 {
00714 emit refuseSendFile (ip, send_file_list.value(ip).name);
00715 send_file_list.remove (ip);
00716 }
00717 break;
00718
00719 default:
00720 qDebug ("Nieznany pakiet: %d\n", packet.getType());
00721 break;
00722 }
00723 }
00724
00725 void Communication::removeUser (QHostAddress user_ip)
00726 {
00727 ip_list.removeAll (user_ip);
00728 if (send_file_list.contains(user_ip))
00729 {
00730 emit refuseSendFile (user_ip, send_file_list.value(user_ip).name);
00731 send_file_list.remove (user_ip);
00732 }
00733 if (ping_list.contains(user_ip))
00734 {
00735 emit pong (user_ip, -1);
00736 ping_list.remove (user_ip);
00737 }
00738
00739 for (int i=0; i < packet_queue.size (); i++)
00740 {
00741 packet_queue[i].num_err.remove (user_ip);
00742 if (packet_queue.at(i).num_err.isEmpty ())
00743 packet_queue.removeAt (i);
00744 }
00745 incoming_file.remove (user_ip);
00746 }
00747
00748 void Communication::removeQueue (QHostAddress user_ip, LanPacket::PacketType pack_type, QString md5)
00749 {
00750 for (int i=0; i < packet_queue.size(); i++)
00751 {
00752 if (packet_queue[i].packet.getType () != pack_type)
00753 continue;
00754 if (!packet_queue.at(i).num_err.contains (user_ip))
00755 continue;
00756 if (!md5.isEmpty () && packet_queue.at(i).md5 != md5)
00757 continue;
00758
00759 packet_queue[i].num_err.remove (user_ip);
00760 if (packet_queue.at(i).num_err.isEmpty())
00761 packet_queue.removeAt (i);
00762 }
00763 }
00764
00765
00766
00767 void Communication::readData ()
00768 {
00769 if (!is_connect && !connecting)
00770 {
00771 read_socket.readDatagram (NULL, 0);
00772 return;
00773 }
00774
00775 while (read_socket.hasPendingDatagrams ())
00776 {
00777 QByteArray datagram;
00778 QHostAddress user_ip;
00779
00780 datagram.resize(read_socket.pendingDatagramSize());
00781 read_socket.readDatagram(datagram.data(), datagram.size(), &user_ip);
00782
00783 qDebug ("Przylazl pakiet od %s, %d\n", user_ip.toString().toAscii().data(), datagram.size ());
00784 if (!my_ip.isNull () && user_ip == my_ip)
00785 continue;
00786
00787 while (datagram.size () >= 3)
00788 {
00789 LanPacket packet (datagram);
00790
00791 if (packet.isValid ())
00792 servicePacket (packet, user_ip);
00793 else
00794 qDebug ("Nieprawidłowy pakiet !!!!!\n");
00795
00796 datagram.remove (0, packet.getSize()+3);
00797 }
00798 }
00799 }
00800
00801 void Communication::packetTimer ()
00802 {
00803 QTime time = QTime::currentTime ();
00804 QList<QHostAddress> del_list;
00805
00806 QHashIterator<QHostAddress, QTime> it_p(ping_list);
00807 while (it_p.hasNext ())
00808 {
00809 it_p.next ();
00810 if (it_p.value ().elapsed() > MAX_PING_TIME)
00811 {
00812 emit pong (it_p.key(), -1);
00813 ping_list.remove (it_p.key ());
00814 }
00815 }
00816
00817 QHashIterator<QHostAddress, SendFileTime> it_f(send_file_list);
00818 while (it_f.hasNext ())
00819 {
00820 it_f.next ();
00821 if (it_f.value().time.elapsed() > MAX_FILE_TIME)
00822 {
00823 emit refuseSendFile (it_f.key(), it_f.value().name);
00824 send_file_list.remove (it_f.key());
00825 }
00826 }
00827
00828 for (int i=0; i < packet_queue.size(); i++)
00829 {
00830 if (packet_queue.at(i).last_send.msecsTo(time) <= PACKET_TIME)
00831 continue;
00832
00833 QHashIterator<QHostAddress, int> it_q(packet_queue.at(i).num_err);
00834 while (it_q.hasNext ())
00835 {
00836 it_q.next ();
00837 if (it_q.value() > PACKET_RETRY)
00838 {
00839 del_list.append (it_q.key ());
00840 }
00841 else
00842 {
00843 packet_queue[i].num_err[it_q.key()]++;
00844 sendPacket (it_q.key(), packet_queue.at(i).packet);
00845 }
00846 }
00847 }
00848 for (int i=0; i < del_list.size(); i++)
00849 {
00850 emit leaveUser (del_list.at(i));
00851 removeUser (del_list.at(i));
00852 }
00853 }
00854
00855 void Communication::sysPingTimer ()
00856 {
00857 this->sendPacket (broadcast, LanPacket(LanPacket::SysPing), true);
00858 }
00859
00860 void Communication::connectTimeOut ()
00861 {
00862 if (!is_connect)
00863 connectFail ();
00864 }
00865
00866 void Communication::fileTransferEnd (bool ok)
00867 {
00868 is_transfer = false;
00869 emit transferEnd (file_transfer->getIp (), ok);
00870 delete file_transfer;
00871 file_transfer = NULL;
00872 }
00873
00874 void Communication::fileTransferProgres (int perc)
00875 {
00876 emit fileProgress (perc);
00877 }
00878