diff options
| -rwxr-xr-x | PICA_client.c | 100 | ||||
| -rwxr-xr-x | PICA_client.h | 3 | ||||
| -rw-r--r-- | pica-client/dialogs/filetransferdialog.cpp | 19 | ||||
| -rw-r--r-- | pica-client/dialogs/filetransferdialog.h | 3 | ||||
| -rw-r--r-- | pica-client/filetransfercontroller.cpp | 62 | ||||
| -rw-r--r-- | pica-client/filetransfercontroller.h | 11 | ||||
| -rw-r--r-- | pica-client/skynet.cpp | 123 | ||||
| -rw-r--r-- | pica-client/skynet.h | 19 |
8 files changed, 320 insertions, 20 deletions
diff --git a/PICA_client.c b/PICA_client.c index bc0939d..3116c3a 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -28,9 +28,10 @@ static pthread_mutex_t *mt_locks; #endif -int PICA_send_file_fragment(struct PICA_chaninfo *chn); -int PICA_sendfile_open_read(struct PICA_chaninfo *chn, const char *filename_utf8, uint64_t *file_size); -int PICA_recvfile_open_write(struct PICA_chaninfo *chn, const char *filename_utf8, unsigned int filenamesize); +static int PICA_send_file_fragment(struct PICA_chaninfo *chn); +static int PICA_sendfile_open_read(struct PICA_chaninfo *chn, const char *filename_utf8, uint64_t *file_size); +static int PICA_recvfile_open_write(struct PICA_chaninfo *chn, const char *filename_utf8, unsigned int filenamesize); +static int PICA_send_filecontrol(struct PICA_chaninfo *chan, int senderctl, int receiverctl); static unsigned int procmsg_INITRESP(unsigned char*,unsigned int,void*); static unsigned int procmsg_CONNREQINC(unsigned char*,unsigned int,void*); @@ -788,14 +789,7 @@ if (fwrite(buf + 4, nb - 4, 1, chan->recvfile_stream) != 1) chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; - mp = c2c_writebuf_push( chan, PICA_PROTO_FILECONTROL, PICA_PROTO_FILECONTROL_SIZE); - - if (mp) - { - mp->tail[0] = PICA_PROTO_FILECONTROL_VOID; //sender's command - mp->tail[1] = PICA_PROTO_FILECONTROL_IOERROR; //receiver's command - } - else + if (PICA_OK != PICA_send_filecontrol(chan, PICA_PROTO_FILECONTROL_VOID, PICA_PROTO_FILECONTROL_IOERROR)) return 0; } @@ -824,6 +818,8 @@ unsigned int sender_cmd, receiver_cmd; sender_cmd = buf[2]; receiver_cmd = buf[3]; +fprintf(stderr, "procmsg_FILECONTROL sender_cmd = %i receiver_cmd = %i\n", sender_cmd, receiver_cmd); + if ((chan->sendfilestate == PICA_CHANSENDFILESTATE_IDLE || chan->sendfilestate == PICA_CHANSENDFILESTATE_SENTREQ) && receiver_cmd != PICA_PROTO_FILECONTROL_VOID) return 0; @@ -831,6 +827,8 @@ if ((chan->sendfilestate == PICA_CHANSENDFILESTATE_IDLE || chan->sendfilestate = if (chan->recvfilestate == PICA_CHANRECVFILESTATE_IDLE && sender_cmd != PICA_PROTO_FILECONTROL_VOID) return 0; +fprintf(stderr, "procmsg_FILECONTROL switch(sender_cmd)\n"); + switch(sender_cmd) { case PICA_PROTO_FILECONTROL_PAUSE: @@ -861,6 +859,7 @@ switch(sender_cmd) return 0; } +fprintf(stderr, "procmsg_FILECONTROL switch(receiver_cmd)\n"); switch(receiver_cmd) { case PICA_PROTO_FILECONTROL_PAUSE: @@ -884,10 +883,14 @@ switch(receiver_cmd) chan->sendfile_stream = NULL; break; + case PICA_PROTO_FILECONTROL_VOID: + break; + default: return 0; } +fprintf(stderr, "procmsg_FILECONTROL calling callback\n"); callbacks.file_control(chan->peer_id, sender_cmd, receiver_cmd); return 1; @@ -1759,6 +1762,75 @@ chn->sendfile_pos = 0; return PICA_OK; } +int PICA_pause_file(struct PICA_chaninfo *chan, int sending) +{ +int senderctl = PICA_PROTO_FILECONTROL_VOID; +int receiverctl = PICA_PROTO_FILECONTROL_VOID; + +if (sending) + { + if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENDING) + return PICA_ERRINVARG; + + chan->sendfilestate = PICA_CHANSENDFILESTATE_PAUSED; + + senderctl = PICA_PROTO_FILECONTROL_PAUSE; + } + else + { + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING) + return PICA_ERRINVARG; + + chan->recvfilestate = PICA_CHANRECVFILESTATE_PAUSED; + + receiverctl = PICA_PROTO_FILECONTROL_PAUSE; + } + +return PICA_send_filecontrol(chan, senderctl, receiverctl); +} + +int PICA_resume_file(struct PICA_chaninfo *chan, int sending) +{ +int senderctl = PICA_PROTO_FILECONTROL_VOID; +int receiverctl = PICA_PROTO_FILECONTROL_VOID; + +if (sending) + { + if (chan->sendfilestate != PICA_CHANSENDFILESTATE_PAUSED) + return PICA_ERRINVARG; + + chan->sendfilestate = PICA_CHANSENDFILESTATE_SENDING; + + senderctl = PICA_PROTO_FILECONTROL_RESUME; + } + else + { + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) + return PICA_ERRINVARG; + + chan->recvfilestate = PICA_CHANRECVFILESTATE_RECEIVING; + + receiverctl = PICA_PROTO_FILECONTROL_RESUME; + } + +return PICA_send_filecontrol(chan, senderctl, receiverctl); +} + +int PICA_send_filecontrol(struct PICA_chaninfo *chan, int senderctl, int receiverctl) +{ +struct PICA_proto_msg *mp; + +if ((mp = c2c_writebuf_push(chan, PICA_PROTO_FILECONTROL, PICA_PROTO_FILECONTROL_SIZE))) + { + mp->tail[0] = senderctl; //sender's command + mp->tail[1] = receiverctl; //receiver's command + } +else + return PICA_ERRNOMEM; + +return PICA_OK; +} + int PICA_send_file_fragment(struct PICA_chaninfo *chn) { struct PICA_proto_msg *mp; @@ -1776,11 +1848,7 @@ if (fragment_size == 0) chn->sendfile_stream = NULL; chn->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; - if ((mp = c2c_writebuf_push(chn, PICA_PROTO_FILECONTROL, PICA_PROTO_FILECONTROL_SIZE))) - { - mp->tail[0] = PICA_PROTO_FILECONTROL_IOERROR; //sender's command - mp->tail[1] = PICA_PROTO_FILECONTROL_VOID; //receiver's command - } + PICA_send_filecontrol(chn, PICA_PROTO_FILECONTROL_IOERROR, PICA_PROTO_FILECONTROL_VOID); return PICA_ERRFILEIO; } diff --git a/PICA_client.h b/PICA_client.h index 7d1ae3e..fd3762d 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -244,6 +244,9 @@ int PICA_read_msg(struct PICA_chaninfo *chn,char *buf,unsigned int *n); int PICA_send_file(struct PICA_chaninfo *chn, const char *filepath); int PICA_accept_file(struct PICA_chaninfo *chan, char *filename, unsigned int filenamesize); int PICA_deny_file(struct PICA_chaninfo *chan); +// if sending != 0 then pause sending file, else pause receiving of file +int PICA_pause_file(struct PICA_chaninfo *chan, int sending); +int PICA_resume_file(struct PICA_chaninfo *chan, int sending); void PICA_close_channel(struct PICA_chaninfo *chn); void PICA_close_connection(struct PICA_conninfo *cid); diff --git a/pica-client/dialogs/filetransferdialog.cpp b/pica-client/dialogs/filetransferdialog.cpp index 4e09b31..c87ed89 100644 --- a/pica-client/dialogs/filetransferdialog.cpp +++ b/pica-client/dialogs/filetransferdialog.cpp @@ -137,6 +137,23 @@ void FileTransferDialog::setTransferStatus(TransferStatus st) } } +void FileTransferDialog::pausedByPeer() +{ + leftbutton->setEnabled(false); + setTransferStatus(PAUSED); +} + +void FileTransferDialog::resumedByPeer() +{ + leftbutton->setEnabled(true); + setTransferStatus( dir_ == SENDING ? SENDINGFILE : RECEIVINGFILE); +} + +void FileTransferDialog::cancelledByPeer() +{ + setTransferStatus(CANCELLED); +} + void FileTransferDialog::leftbuttonclick() { if (dir_ == RECEIVING) @@ -154,11 +171,13 @@ void FileTransferDialog::leftbuttonclick() { leftbutton->setText(tr("Resume")); emit pausedFile(peer_id_, this); + setTransferStatus(PAUSED); } else if (leftbutton->text() == tr("Resume")) { leftbutton->setText(tr("Pause")); emit resumedFile(peer_id_, this); + setTransferStatus(dir_ == SENDING ? SENDINGFILE : RECEIVINGFILE); } } diff --git a/pica-client/dialogs/filetransferdialog.h b/pica-client/dialogs/filetransferdialog.h index 10fab6d..2511651 100644 --- a/pica-client/dialogs/filetransferdialog.h +++ b/pica-client/dialogs/filetransferdialog.h @@ -69,6 +69,9 @@ signals: public slots: void update(quint64 progress); void setTransferStatus(enum TransferStatus st); + void pausedByPeer(); + void resumedByPeer(); + void cancelledByPeer(); private slots: void timeout(); diff --git a/pica-client/filetransfercontroller.cpp b/pica-client/filetransfercontroller.cpp index 6bf3658..61534c9 100644 --- a/pica-client/filetransfercontroller.cpp +++ b/pica-client/filetransfercontroller.cpp @@ -55,18 +55,61 @@ void FileTransferController::file_request(QByteArray peer_id, quint64 file_size, void FileTransferController::file_accepted_by_peer(QByteArray peer_id) { + connect(skynet, SIGNAL(OutgoingFilePaused(QByteArray)), this, SLOT(file_paused_outgoing(QByteArray))); + connect(skynet, SIGNAL(OutgoingFileResumed(QByteArray)), this, SLOT(file_resumed_outgoing(QByteArray))); + connect(skynet, SIGNAL(OutgoingFileCancelled(QByteArray)), this, SLOT(file_cancelled_outgoing(QByteArray))); + connect(skynet, SIGNAL(OutgoingFileIoError(QByteArray)), this, SLOT(file_ioerror_outgoing(QByteArray))); + ftdialogs_out[peer_id]->setTransferStatus(FileTransferDialog::SENDINGFILE); } void FileTransferController::file_denied_by_peer(QByteArray peer_id) { + ftdialogs_out[peer_id]->setTransferStatus(FileTransferDialog::DENIED); +} +void FileTransferController::file_paused_incoming(QByteArray peer_id) +{ + ftdialogs_in[peer_id]->pausedByPeer(); } -void FileTransferController::file_accepted_by_me(QByteArray peer_id) +void FileTransferController::file_resumed_incoming(QByteArray peer_id) +{ + ftdialogs_in[peer_id]->resumedByPeer(); +} + +void FileTransferController::file_cancelled_incoming(QByteArray peer_id) { + ftdialogs_in[peer_id]->cancelledByPeer(); +} +void FileTransferController::file_ioerror_incoming(QByteArray peer_id) +{ +} + +void FileTransferController::file_paused_outgoing(QByteArray peer_id) +{ + ftdialogs_out[peer_id]->pausedByPeer(); +} + +void FileTransferController::file_resumed_outgoing(QByteArray peer_id) +{ + ftdialogs_out[peer_id]->resumedByPeer(); +} + +void FileTransferController::file_cancelled_outgoing(QByteArray peer_id) +{ + ftdialogs_out[peer_id]->cancelledByPeer(); +} + +void FileTransferController::file_ioerror_outgoing(QByteArray peer_id) +{ + +} + +void FileTransferController::file_accepted_by_me(QByteArray peer_id) +{ QString filePathToSave = QFileDialog::getSaveFileName(ftdialogs_in[peer_id], tr("Save received file to"), fnames[peer_id], tr("Any file (* *.*)")); @@ -75,6 +118,13 @@ void FileTransferController::file_accepted_by_me(QByteArray peer_id) connect(ftdialogs_in[peer_id], SIGNAL(cancelledFile(QByteArray,FileTransferDialog*)), this, SLOT(file_cancelled_by_me(QByteArray,FileTransferDialog*))); connect(ftdialogs_in[peer_id], SIGNAL(pausedFile(QByteArray,FileTransferDialog*)), this, SLOT(file_paused_by_me(QByteArray,FileTransferDialog*))); connect(ftdialogs_in[peer_id], SIGNAL(resumedFile(QByteArray,FileTransferDialog*)), this, SLOT(file_resumed_by_me(QByteArray,FileTransferDialog*))); + + connect(skynet, SIGNAL(IncomingFilePaused(QByteArray)), this, SLOT(file_paused_incoming(QByteArray))); + connect(skynet, SIGNAL(IncomingFileResumed(QByteArray)), this, SLOT(file_resumed_incoming(QByteArray))); + connect(skynet, SIGNAL(IncomingFileCancelled(QByteArray)), this, SLOT(file_cancelled_incoming(QByteArray))); + connect(skynet, SIGNAL(IncomingFileIoError(QByteArray)), this, SLOT(file_ioerror_incoming(QByteArray))); + + ftdialogs_in[peer_id]->setTransferStatus(FileTransferDialog::RECEIVINGFILE); } void FileTransferController::file_denied_by_me(QByteArray peer_id) @@ -93,12 +143,22 @@ void FileTransferController::file_cancelled_by_me(QByteArray peer_id, FileTransf void FileTransferController::file_paused_by_me(QByteArray peer_id, FileTransferDialog *from) { + bool sending = true; + + if (from->getTransferDirection() == FileTransferDialog::RECEIVING) + sending = false; + skynet->PauseFile(peer_id, sending); } void FileTransferController::file_resumed_by_me(QByteArray peer_id, FileTransferDialog *from) { + bool sending = true; + + if (from->getTransferDirection() == FileTransferDialog::RECEIVING) + sending = false; + skynet->ResumeFile(peer_id, sending); } void FileTransferController::send_file(QByteArray peer_id) diff --git a/pica-client/filetransfercontroller.h b/pica-client/filetransfercontroller.h index 72a989e..f261605 100644 --- a/pica-client/filetransfercontroller.h +++ b/pica-client/filetransfercontroller.h @@ -29,7 +29,16 @@ public slots: void file_request(QByteArray peer_id, quint64 file_size, QString filename); void file_accepted_by_peer(QByteArray peer_id); void file_denied_by_peer(QByteArray peer_id); - //void file_control(QByteArray peer_id, ) + + void file_paused_incoming(QByteArray peer_id); + void file_resumed_incoming(QByteArray peer_id); + void file_cancelled_incoming(QByteArray peer_id); + void file_ioerror_incoming(QByteArray peer_id); + + void file_paused_outgoing(QByteArray peer_id); + void file_resumed_outgoing(QByteArray peer_id); + void file_cancelled_outgoing(QByteArray peer_id); + void file_ioerror_outgoing(QByteArray peer_id); //from me (file transfer dialog shown to user) to remote peer void file_accepted_by_me(QByteArray peer_id); diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index c2f89ff..462ad02 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -317,6 +317,43 @@ if ( (iptr = find_active_chan(from)) ) write_mutex.unlock();//>> } +void SkyNet::PauseFile(QByteArray peer_id, bool pause_sending) +{ +int ret = PICA_OK; +struct PICA_chaninfo *iptr; + +write_mutex.lock();//<< +if ( (iptr = find_active_chan(peer_id)) ) + { + qDebug() << "calling PICA_pause_file(" << iptr << "," << pause_sending << ")\n"; + ret = PICA_pause_file(iptr, (int)pause_sending ); + + if (ret != PICA_OK) + { + qDebug() << "PICA_pause_file() returned " << ret << "\n"; + } + } +write_mutex.unlock();//>> +} + +void SkyNet::ResumeFile(QByteArray peer_id, bool resume_sending) +{ +int ret = PICA_OK; +struct PICA_chaninfo *iptr; + +write_mutex.lock();//<< +if ( (iptr = find_active_chan(peer_id)) ) + { + ret = PICA_resume_file(iptr, (int)resume_sending ); + + if (ret != PICA_OK) + { + //show error somewhere somehow + } + } +write_mutex.unlock();//>> +} + void SkyNet::SendMessage(QByteArray to, QString msg) { int ret = PICA_OK; @@ -488,6 +525,46 @@ void SkyNet::emit_FileProgress(QByteArray peer_id, quint64 bytes_sent, quint64 b emit FileProgress(peer_id, bytes_sent, bytes_received); } +void SkyNet::emit_IncomingFilePaused(QByteArray peer_id) +{ + emit IncomingFilePaused(peer_id); +} + +void SkyNet::emit_IncomingFileCancelled(QByteArray peer_id) +{ + emit IncomingFileCancelled(peer_id); +} + +void SkyNet::emit_IncomingFileIoError(QByteArray peer_id) +{ + emit IncomingFileIoError(peer_id); +} + +void SkyNet::emit_IncomingFileResumed(QByteArray peer_id) +{ + emit IncomingFileResumed(peer_id); +} + +void SkyNet::emit_OutgoingFilePaused(QByteArray peer_id) +{ + emit OutgoingFilePaused(peer_id); +} + +void SkyNet::emit_OutgoingFileCancelled(QByteArray peer_id) +{ + emit OutgoingFileCancelled(peer_id); +} + +void SkyNet::emit_OutgoingFileIoError(QByteArray peer_id) +{ + emit OutgoingFileIoError(peer_id); +} + +void SkyNet::emit_OutgoingFileResumed(QByteArray peer_id) +{ + emit OutgoingFileResumed(peer_id); +} + //callbacks //all callbacks are executed in separate thread, created in Nodethread instance, REMEMBER THAT !!! @@ -589,6 +666,50 @@ void SkyNet::file_progress(const unsigned char *peer_id, uint64_t sent, uint64_t void SkyNet::file_control(const unsigned char *peer_id, unsigned int sender_cmd, unsigned int receiver_cmd) { - //implement me + qDebug() << "file_control callback: sender_cmd=" << sender_cmd << ", receiver_cmd=" << receiver_cmd << "\n"; + + + if (sender_cmd != PICA_PROTO_FILECONTROL_VOID && receiver_cmd == PICA_PROTO_FILECONTROL_VOID) + { + switch(sender_cmd) + { + case PICA_PROTO_FILECONTROL_PAUSE: + skynet->emit_IncomingFilePaused(QByteArray((const char *)peer_id, PICA_ID_SIZE)); + break; + + case PICA_PROTO_FILECONTROL_RESUME: + skynet->emit_IncomingFileResumed(QByteArray((const char *)peer_id, PICA_ID_SIZE)); + break; + + case PICA_PROTO_FILECONTROL_CANCEL: + skynet->emit_IncomingFileCancelled(QByteArray((const char *)peer_id, PICA_ID_SIZE)); + break; + + case PICA_PROTO_FILECONTROL_IOERROR: + skynet->emit_IncomingFileIoError(QByteArray((const char *)peer_id, PICA_ID_SIZE)); + break; + } + } + else if (sender_cmd == PICA_PROTO_FILECONTROL_VOID && receiver_cmd != PICA_PROTO_FILECONTROL_VOID) + { + switch(receiver_cmd) + { + case PICA_PROTO_FILECONTROL_PAUSE: + skynet->emit_OutgoingFilePaused(QByteArray((const char *)peer_id, PICA_ID_SIZE)); + break; + + case PICA_PROTO_FILECONTROL_RESUME: + skynet->emit_OutgoingFileResumed(QByteArray((const char *)peer_id, PICA_ID_SIZE)); + break; + + case PICA_PROTO_FILECONTROL_CANCEL: + skynet->emit_OutgoingFileCancelled(QByteArray((const char *)peer_id, PICA_ID_SIZE)); + break; + + case PICA_PROTO_FILECONTROL_IOERROR: + skynet->emit_OutgoingFileIoError(QByteArray((const char *)peer_id, PICA_ID_SIZE)); + break; + } + } } diff --git a/pica-client/skynet.h b/pica-client/skynet.h index 5ab4db1..a053083 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -4,6 +4,7 @@ #include "nodes.h" #include "nodethread.h" #include "../PICA_client.h" +#include "../PICA_proto.h" #include "accounts.h" #include <QObject> #include <QMap> @@ -23,6 +24,9 @@ public: void SendFile(QByteArray to, QString filepath); void AcceptFile(QByteArray from, QString filepath); void DenyFile(QByteArray from); + void PauseFile(QByteArray peer_id, bool pause_sending); + void ResumeFile(QByteArray peer_id, bool resume_sending); + Accounts::AccountRecord CurrentAccount() {return skynet_account;}; signals: @@ -43,6 +47,10 @@ signals: void IncomingFileCancelled(QByteArray peer_id); void IncomingFileIoError(QByteArray peer_id); void IncomingFileResumed(QByteArray peer_id); + void OutgoingFilePaused(QByteArray peer_id); + void OutgoingFileCancelled(QByteArray peer_id); + void OutgoingFileIoError(QByteArray peer_id); + void OutgoingFileResumed(QByteArray peer_id); private: Nodes nodes; @@ -70,7 +78,16 @@ private: void emit_OutgoingFileRequestAccepted(QByteArray peer_id); void emit_OutgoingFileRequestDenied(QByteArray peer_id); void emit_FileProgress(QByteArray peer_id, quint64 bytes_sent, quint64 bytes_received); - //incoming/outgoing x paused, cancelled, io error + + void emit_IncomingFilePaused(QByteArray peer_id); + void emit_IncomingFileCancelled(QByteArray peer_id); + void emit_IncomingFileIoError(QByteArray peer_id); + void emit_IncomingFileResumed(QByteArray peer_id); + void emit_OutgoingFilePaused(QByteArray peer_id); + void emit_OutgoingFileCancelled(QByteArray peer_id); + void emit_OutgoingFileIoError(QByteArray peer_id); + void emit_OutgoingFileResumed(QByteArray peer_id); + //получение сообщения. static void newmsg_cb(const unsigned char *peer_id,const char* msgbuf,unsigned int nb,int type); |
