mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Added resume support if the connection breaks during file sending.
This commit is contained in:
parent
8abad7bc82
commit
0aa6ba8e28
|
@ -31,6 +31,28 @@
|
|||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
|
||||
void host_to_net(uint8_t *num, uint16_t numbytes)
|
||||
{
|
||||
union {
|
||||
uint32_t i;
|
||||
uint8_t c[4];
|
||||
} a;
|
||||
a.i = 1;
|
||||
|
||||
if (a.c[0] == 1) {
|
||||
uint32_t i;
|
||||
uint8_t buff[numbytes];
|
||||
|
||||
for (i = 0; i < numbytes; ++i) {
|
||||
buff[i] = num[numbytes - i - 1];
|
||||
}
|
||||
|
||||
memcpy(num, buff, numbytes);
|
||||
}
|
||||
}
|
||||
#define net_to_host(x, y) host_to_net(x, y)
|
||||
|
||||
static void set_friend_status(Messenger *m, int friendnumber, uint8_t status);
|
||||
static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length);
|
||||
|
||||
|
@ -1017,8 +1039,7 @@ int file_sendrequest(Messenger *m, int friendnumber, uint8_t filenumber, uint64_
|
|||
|
||||
uint8_t packet[MAX_FILENAME_LENGTH + 1 + sizeof(filesize)];
|
||||
packet[0] = filenumber;
|
||||
//TODO:
|
||||
//filesize = htonll(filesize);
|
||||
host_to_net((uint8_t *)&filesize, sizeof(filesize));
|
||||
memcpy(packet + 1, &filesize, sizeof(filesize));
|
||||
memcpy(packet + 1 + sizeof(filesize), filename, filename_length);
|
||||
return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_SENDREQUEST, packet,
|
||||
|
@ -1084,7 +1105,20 @@ int file_control(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t f
|
|||
packet[0] = send_receive;
|
||||
packet[1] = filenumber;
|
||||
packet[2] = message_id;
|
||||
memcpy(packet + 3, data, length);
|
||||
uint64_t transferred = 0;
|
||||
|
||||
if (message_id == FILECONTROL_RESUME_BROKEN) {
|
||||
if (length != sizeof(uint64_t))
|
||||
return 0;
|
||||
|
||||
uint8_t remaining[sizeof(uint64_t)];
|
||||
memcpy(remaining, data, sizeof(uint64_t));
|
||||
host_to_net(remaining, sizeof(uint64_t));
|
||||
memcpy(packet + 3, remaining, sizeof(uint64_t));
|
||||
memcpy(&transferred, data, sizeof(uint64_t));
|
||||
} else {
|
||||
memcpy(packet + 3, data, length);
|
||||
}
|
||||
|
||||
if (write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_CONTROL, packet, length + 3)) {
|
||||
if (send_receive == 1)
|
||||
|
@ -1101,6 +1135,11 @@ int file_control(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t f
|
|||
case FILECONTROL_FINISHED:
|
||||
m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_NONE;
|
||||
break;
|
||||
|
||||
case FILECONTROL_RESUME_BROKEN:
|
||||
m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_PAUSED_BY_OTHER;
|
||||
m->friendlist[friendnumber].file_receiving[filenumber].transferred = transferred;
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (message_id) {
|
||||
|
@ -1201,17 +1240,23 @@ static void break_files(Messenger *m, int friendnumber)
|
|||
}
|
||||
}
|
||||
|
||||
static int handle_filecontrol(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t filenumber,
|
||||
static int handle_filecontrol(Messenger *m, int friendnumber, uint8_t receive_send, uint8_t filenumber,
|
||||
uint8_t message_id, uint8_t *data,
|
||||
uint16_t length)
|
||||
{
|
||||
if (send_receive > 1)
|
||||
if (receive_send > 1)
|
||||
return -1;
|
||||
|
||||
if (send_receive == 0) {
|
||||
if (m->friendlist[friendnumber].file_receiving[filenumber].status == FILESTATUS_NONE)
|
||||
if (receive_send == 0) {
|
||||
if (m->friendlist[friendnumber].file_receiving[filenumber].status == FILESTATUS_NONE) {
|
||||
/* Tell the other to kill the file sending if we don't know this one. */
|
||||
m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_TEMPORARY;
|
||||
file_control(m, friendnumber, !receive_send, filenumber, FILECONTROL_KILL, NULL, 0);
|
||||
m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_NONE;
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
switch (message_id) {
|
||||
case FILECONTROL_ACCEPT:
|
||||
if (m->friendlist[friendnumber].file_receiving[filenumber].status != FILESTATUS_PAUSED_BY_US) {
|
||||
|
@ -1235,8 +1280,13 @@ static int handle_filecontrol(Messenger *m, int friendnumber, uint8_t send_recei
|
|||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (m->friendlist[friendnumber].file_sending[filenumber].status == FILESTATUS_NONE)
|
||||
if (m->friendlist[friendnumber].file_sending[filenumber].status == FILESTATUS_NONE) {
|
||||
/* Tell the other to kill the file sending if we don't know this one. */
|
||||
m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_TEMPORARY;
|
||||
file_control(m, friendnumber, !receive_send, filenumber, FILECONTROL_KILL, NULL, 0);
|
||||
m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_NONE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (message_id) {
|
||||
case FILECONTROL_ACCEPT:
|
||||
|
@ -1258,6 +1308,16 @@ static int handle_filecontrol(Messenger *m, int friendnumber, uint8_t send_recei
|
|||
case FILECONTROL_FINISHED:
|
||||
m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_NONE;
|
||||
return 0;
|
||||
|
||||
case FILECONTROL_RESUME_BROKEN: {
|
||||
if (m->friendlist[friendnumber].file_sending[filenumber].status == FILESTATUS_BROKEN && length == sizeof(uint64_t)) {
|
||||
m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_PAUSED_BY_US;
|
||||
net_to_host(data, sizeof(uint64_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1584,9 +1644,8 @@ void doFriends(Messenger *m)
|
|||
|
||||
uint8_t filenumber = data[0];
|
||||
uint64_t filesize;
|
||||
net_to_host(data + 1, sizeof(filesize));
|
||||
memcpy(&filesize, data + 1, sizeof(filesize));
|
||||
//TODO:
|
||||
//filesize = ntohll(filesize);
|
||||
m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED;
|
||||
m->friendlist[i].file_receiving[filenumber].size = filesize;
|
||||
m->friendlist[i].file_receiving[filenumber].transferred = 0;
|
||||
|
|
|
@ -111,7 +111,8 @@ enum {
|
|||
FILESTATUS_PAUSED_BY_OTHER,
|
||||
FILESTATUS_TRANSFERRING,
|
||||
FILESTATUS_BROKEN,
|
||||
FILESTATUS_PAUSED_BY_US
|
||||
FILESTATUS_PAUSED_BY_US,
|
||||
FILESTATUS_TEMPORARY
|
||||
};
|
||||
/* This cannot be bigger than 256 */
|
||||
#define MAX_CONCURRENT_FILE_PIPES 256
|
||||
|
@ -120,7 +121,8 @@ enum {
|
|||
FILECONTROL_ACCEPT,
|
||||
FILECONTROL_PAUSE,
|
||||
FILECONTROL_KILL,
|
||||
FILECONTROL_FINISHED
|
||||
FILECONTROL_FINISHED,
|
||||
FILECONTROL_RESUME_BROKEN
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
Loading…
Reference in New Issue
Block a user