summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xPICA_client.c100
-rwxr-xr-xPICA_client.h3
-rw-r--r--pica-client/dialogs/filetransferdialog.cpp19
-rw-r--r--pica-client/dialogs/filetransferdialog.h3
-rw-r--r--pica-client/filetransfercontroller.cpp62
-rw-r--r--pica-client/filetransfercontroller.h11
-rw-r--r--pica-client/skynet.cpp123
-rw-r--r--pica-client/skynet.h19
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);