summaryrefslogtreecommitdiff
path: root/toxcore/Messenger.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-10-15 17:23:00 -0400
committerirungentoo <irungentoo@gmail.com>2013-10-15 17:23:00 -0400
commit0aa6ba8e2811fdc0a67e402dedc044b3ca22d610 (patch)
treeaa7bd3e526dff72b098b4729c61818f4a219d6ae /toxcore/Messenger.c
parent8abad7bc822a548d4f6e73203e8d4f640c1217ae (diff)
Added resume support if the connection breaks during file sending.
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r--toxcore/Messenger.c79
1 files changed, 69 insertions, 10 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 44570742..76f2a5fd 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -31,6 +31,28 @@
31 31
32#define MIN(a,b) (((a)<(b))?(a):(b)) 32#define MIN(a,b) (((a)<(b))?(a):(b))
33 33
34
35void host_to_net(uint8_t *num, uint16_t numbytes)
36{
37 union {
38 uint32_t i;
39 uint8_t c[4];
40 } a;
41 a.i = 1;
42
43 if (a.c[0] == 1) {
44 uint32_t i;
45 uint8_t buff[numbytes];
46
47 for (i = 0; i < numbytes; ++i) {
48 buff[i] = num[numbytes - i - 1];
49 }
50
51 memcpy(num, buff, numbytes);
52 }
53}
54#define net_to_host(x, y) host_to_net(x, y)
55
34static void set_friend_status(Messenger *m, int friendnumber, uint8_t status); 56static void set_friend_status(Messenger *m, int friendnumber, uint8_t status);
35static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); 57static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length);
36 58
@@ -1017,8 +1039,7 @@ int file_sendrequest(Messenger *m, int friendnumber, uint8_t filenumber, uint64_
1017 1039
1018 uint8_t packet[MAX_FILENAME_LENGTH + 1 + sizeof(filesize)]; 1040 uint8_t packet[MAX_FILENAME_LENGTH + 1 + sizeof(filesize)];
1019 packet[0] = filenumber; 1041 packet[0] = filenumber;
1020 //TODO: 1042 host_to_net((uint8_t *)&filesize, sizeof(filesize));
1021 //filesize = htonll(filesize);
1022 memcpy(packet + 1, &filesize, sizeof(filesize)); 1043 memcpy(packet + 1, &filesize, sizeof(filesize));
1023 memcpy(packet + 1 + sizeof(filesize), filename, filename_length); 1044 memcpy(packet + 1 + sizeof(filesize), filename, filename_length);
1024 return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_SENDREQUEST, packet, 1045 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
1084 packet[0] = send_receive; 1105 packet[0] = send_receive;
1085 packet[1] = filenumber; 1106 packet[1] = filenumber;
1086 packet[2] = message_id; 1107 packet[2] = message_id;
1087 memcpy(packet + 3, data, length); 1108 uint64_t transferred = 0;
1109
1110 if (message_id == FILECONTROL_RESUME_BROKEN) {
1111 if (length != sizeof(uint64_t))
1112 return 0;
1113
1114 uint8_t remaining[sizeof(uint64_t)];
1115 memcpy(remaining, data, sizeof(uint64_t));
1116 host_to_net(remaining, sizeof(uint64_t));
1117 memcpy(packet + 3, remaining, sizeof(uint64_t));
1118 memcpy(&transferred, data, sizeof(uint64_t));
1119 } else {
1120 memcpy(packet + 3, data, length);
1121 }
1088 1122
1089 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_CONTROL, packet, length + 3)) { 1123 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_CONTROL, packet, length + 3)) {
1090 if (send_receive == 1) 1124 if (send_receive == 1)
@@ -1101,6 +1135,11 @@ int file_control(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t f
1101 case FILECONTROL_FINISHED: 1135 case FILECONTROL_FINISHED:
1102 m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_NONE; 1136 m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_NONE;
1103 break; 1137 break;
1138
1139 case FILECONTROL_RESUME_BROKEN:
1140 m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_PAUSED_BY_OTHER;
1141 m->friendlist[friendnumber].file_receiving[filenumber].transferred = transferred;
1142 break;
1104 } 1143 }
1105 else 1144 else
1106 switch (message_id) { 1145 switch (message_id) {
@@ -1201,17 +1240,23 @@ static void break_files(Messenger *m, int friendnumber)
1201 } 1240 }
1202} 1241}
1203 1242
1204static int handle_filecontrol(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t filenumber, 1243static int handle_filecontrol(Messenger *m, int friendnumber, uint8_t receive_send, uint8_t filenumber,
1205 uint8_t message_id, uint8_t *data, 1244 uint8_t message_id, uint8_t *data,
1206 uint16_t length) 1245 uint16_t length)
1207{ 1246{
1208 if (send_receive > 1) 1247 if (receive_send > 1)
1209 return -1; 1248 return -1;
1210 1249
1211 if (send_receive == 0) { 1250 if (receive_send == 0) {
1212 if (m->friendlist[friendnumber].file_receiving[filenumber].status == FILESTATUS_NONE) 1251 if (m->friendlist[friendnumber].file_receiving[filenumber].status == FILESTATUS_NONE) {
1252 /* Tell the other to kill the file sending if we don't know this one. */
1253 m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_TEMPORARY;
1254 file_control(m, friendnumber, !receive_send, filenumber, FILECONTROL_KILL, NULL, 0);
1255 m->friendlist[friendnumber].file_receiving[filenumber].status = FILESTATUS_NONE;
1213 return -1; 1256 return -1;
1214 1257
1258 }
1259
1215 switch (message_id) { 1260 switch (message_id) {
1216 case FILECONTROL_ACCEPT: 1261 case FILECONTROL_ACCEPT:
1217 if (m->friendlist[friendnumber].file_receiving[filenumber].status != FILESTATUS_PAUSED_BY_US) { 1262 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
1235 return 0; 1280 return 0;
1236 } 1281 }
1237 } else { 1282 } else {
1238 if (m->friendlist[friendnumber].file_sending[filenumber].status == FILESTATUS_NONE) 1283 if (m->friendlist[friendnumber].file_sending[filenumber].status == FILESTATUS_NONE) {
1284 /* Tell the other to kill the file sending if we don't know this one. */
1285 m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_TEMPORARY;
1286 file_control(m, friendnumber, !receive_send, filenumber, FILECONTROL_KILL, NULL, 0);
1287 m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_NONE;
1239 return -1; 1288 return -1;
1289 }
1240 1290
1241 switch (message_id) { 1291 switch (message_id) {
1242 case FILECONTROL_ACCEPT: 1292 case FILECONTROL_ACCEPT:
@@ -1258,6 +1308,16 @@ static int handle_filecontrol(Messenger *m, int friendnumber, uint8_t send_recei
1258 case FILECONTROL_FINISHED: 1308 case FILECONTROL_FINISHED:
1259 m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_NONE; 1309 m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_NONE;
1260 return 0; 1310 return 0;
1311
1312 case FILECONTROL_RESUME_BROKEN: {
1313 if (m->friendlist[friendnumber].file_sending[filenumber].status == FILESTATUS_BROKEN && length == sizeof(uint64_t)) {
1314 m->friendlist[friendnumber].file_sending[filenumber].status = FILESTATUS_PAUSED_BY_US;
1315 net_to_host(data, sizeof(uint64_t));
1316 return 0;
1317 }
1318
1319 return -1;
1320 }
1261 } 1321 }
1262 } 1322 }
1263 1323
@@ -1584,9 +1644,8 @@ void doFriends(Messenger *m)
1584 1644
1585 uint8_t filenumber = data[0]; 1645 uint8_t filenumber = data[0];
1586 uint64_t filesize; 1646 uint64_t filesize;
1647 net_to_host(data + 1, sizeof(filesize));
1587 memcpy(&filesize, data + 1, sizeof(filesize)); 1648 memcpy(&filesize, data + 1, sizeof(filesize));
1588 //TODO:
1589 //filesize = ntohll(filesize);
1590 m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED; 1649 m->friendlist[i].file_receiving[filenumber].status = FILESTATUS_NOT_ACCEPTED;
1591 m->friendlist[i].file_receiving[filenumber].size = filesize; 1650 m->friendlist[i].file_receiving[filenumber].size = filesize;
1592 m->friendlist[i].file_receiving[filenumber].transferred = 0; 1651 m->friendlist[i].file_receiving[filenumber].transferred = 0;