summaryrefslogtreecommitdiff
path: root/toxcore/Messenger.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-10-01 16:48:32 -0400
committerirungentoo <irungentoo@gmail.com>2013-10-01 16:48:32 -0400
commit6dbc8a54969421c5baeb0ec7bb50779c62ae2e44 (patch)
tree86c0b3981f8bbb6642fd203a32d12aab13e286c5 /toxcore/Messenger.c
parent766cff692f9dc93ef284a214ad4bc6389d6afa76 (diff)
Core now takes better care of file transfers.
Diffstat (limited to 'toxcore/Messenger.c')
-rw-r--r--toxcore/Messenger.c129
1 files changed, 124 insertions, 5 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index b21da28b..39bcd704 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -606,7 +606,7 @@ void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, in
606 m->friend_connectionstatuschange = function; 606 m->friend_connectionstatuschange = function;
607 m->friend_connectionstatuschange_userdata = userdata; 607 m->friend_connectionstatuschange_userdata = userdata;
608} 608}
609 609static void break_files(Messenger *m, int friendnumber);
610static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_t status) 610static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_t status)
611{ 611{
612 if (!m->friend_connectionstatuschange) 612 if (!m->friend_connectionstatuschange)
@@ -618,8 +618,12 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
618 const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE; 618 const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE;
619 const uint8_t is_online = status == FRIEND_ONLINE; 619 const uint8_t is_online = status == FRIEND_ONLINE;
620 620
621 if (is_online != was_online) 621 if (is_online != was_online) {
622 if (was_online)
623 break_files(m, friendnumber);
624
622 m->friend_connectionstatuschange(m, friendnumber, is_online, m->friend_connectionstatuschange_userdata); 625 m->friend_connectionstatuschange(m, friendnumber, is_online, m->friend_connectionstatuschange_userdata);
626 }
623} 627}
624 628
625void set_friend_status(Messenger *m, int friendnumber, uint8_t status) 629void set_friend_status(Messenger *m, int friendnumber, uint8_t status)
@@ -938,7 +942,6 @@ static void do_allgroupchats(Messenger *m)
938void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int, uint8_t, uint64_t, uint8_t *, uint16_t, 942void callback_file_sendrequest(Messenger *m, void (*function)(Messenger *m, int, uint8_t, uint64_t, uint8_t *, uint16_t,
939 void *), void *userdata) 943 void *), void *userdata)
940{ 944{
941
942 m->file_sendrequest = function; 945 m->file_sendrequest = function;
943 m->file_sendrequest_userdata = userdata; 946 m->file_sendrequest_userdata = userdata;
944} 947}
@@ -977,6 +980,9 @@ void callback_file_data(Messenger *m, void (*function)(Messenger *m, int, uint8_
977int file_sendrequest(Messenger *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, 980int file_sendrequest(Messenger *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename,
978 uint16_t filename_length) 981 uint16_t filename_length)
979{ 982{
983 if (friend_not_valid(m, friendnumber))
984 return 0;
985
980 if (filename_length > MAX_FILENAME_LENGTH) 986 if (filename_length > MAX_FILENAME_LENGTH)
981 return 0; 987 return 0;
982 988
@@ -990,6 +996,35 @@ int file_sendrequest(Messenger *m, int friendnumber, uint8_t filenumber, uint64_
990 1 + sizeof(filesize) + filename_length); 996 1 + sizeof(filesize) + filename_length);
991} 997}
992 998
999/* Send a file send request.
1000 * Maximum filename length is 256 bytes.
1001 * return file number on success
1002 * return -1 on failure
1003 */
1004int new_filesender(Messenger *m, int friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length)
1005{
1006 if (friend_not_valid(m, friendnumber))
1007 return 0;
1008
1009 uint32_t i;
1010
1011 for (i = 0; i < MAX_CONCURRENT_FILE_PIPES; ++i) {
1012 if (m->friendlist[friendnumber].file_sending[i].status == 0)
1013 break;
1014 }
1015
1016 if (i == MAX_CONCURRENT_FILE_PIPES)
1017 return -1;
1018
1019 if (file_sendrequest(m, friendnumber, i, filesize, filename, filename_length) == 0)
1020 return -1;
1021
1022 m->friendlist[friendnumber].file_sending[i].status = 1;
1023 m->friendlist[friendnumber].file_sending[i].size = filesize;
1024 m->friendlist[friendnumber].file_sending[i].transferred = 0;
1025 return i;
1026}
1027
993/* Send a file control request. 1028/* Send a file control request.
994 * 1029 *
995 * return 1 on success 1030 * return 1 on success
@@ -1000,11 +1035,37 @@ int file_control(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t mes
1000 if (length > MAX_DATA_SIZE - 2) 1035 if (length > MAX_DATA_SIZE - 2)
1001 return 0; 1036 return 0;
1002 1037
1038 if (friend_not_valid(m, friendnumber))
1039 return 0;
1040
1041 if (m->friendlist[friendnumber].file_sending[filenumber].status == 0)
1042 return 0;
1043
1003 uint8_t packet[MAX_DATA_SIZE]; 1044 uint8_t packet[MAX_DATA_SIZE];
1004 packet[0] = filenumber; 1045 packet[0] = filenumber;
1005 packet[1] = message_id; 1046 packet[1] = message_id;
1006 memcpy(packet + 2, data, length); 1047 memcpy(packet + 2, data, length);
1007 return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_CONTROL, packet, length + 2); 1048
1049 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_CONTROL, packet, length + 2)) {
1050 switch (message_id) {
1051 case FILECONTROL_ACCEPT:
1052 m->friendlist[friendnumber].file_receiving[filenumber].status = 3;
1053 break;
1054
1055 case FILECONTROL_PAUSE:
1056 m->friendlist[friendnumber].file_receiving[filenumber].status = 2;
1057 break;
1058
1059 case FILECONTROL_KILL:
1060 case FILECONTROL_FINISHED:
1061 m->friendlist[friendnumber].file_receiving[filenumber].status = 0;
1062 break;
1063 }
1064
1065 return 1;
1066 } else {
1067 return 0;
1068 }
1008} 1069}
1009 1070
1010 1071
@@ -1018,10 +1079,62 @@ int file_data(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t *data,
1018 if (length > MAX_DATA_SIZE - 1) 1079 if (length > MAX_DATA_SIZE - 1)
1019 return 0; 1080 return 0;
1020 1081
1082 if (friend_not_valid(m, friendnumber))
1083 return 0;
1084
1085 if (m->friendlist[friendnumber].file_sending[filenumber].status != 3)
1086 return 0;
1087
1021 uint8_t packet[MAX_DATA_SIZE]; 1088 uint8_t packet[MAX_DATA_SIZE];
1022 packet[0] = filenumber; 1089 packet[0] = filenumber;
1023 memcpy(packet + 1, data, length); 1090 memcpy(packet + 1, data, length);
1024 return write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_DATA, packet, length + 1); 1091
1092 if (write_cryptpacket_id(m, friendnumber, PACKET_ID_FILE_DATA, packet, length + 1)) {
1093 m->friendlist[friendnumber].file_sending[filenumber].transferred += length;
1094 return 1;
1095 }
1096
1097 return 0;
1098
1099}
1100/* Run this when the friend disconnects.
1101 * Sets all current file transfers to broken.
1102 */
1103static void break_files(Messenger *m, int friendnumber)
1104{
1105 uint32_t i;
1106
1107 for (i = 0; i < MAX_CONCURRENT_FILE_PIPES; ++i) {
1108 if (m->friendlist[friendnumber].file_sending[i].status != 0)
1109 m->friendlist[friendnumber].file_sending[i].status = 4;
1110
1111 if (m->friendlist[friendnumber].file_receiving[i].status != 0)
1112 m->friendlist[friendnumber].file_receiving[i].status = 4;
1113 }
1114}
1115
1116static int handle_filecontrol(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t message_id, uint8_t *data,
1117 uint16_t length)
1118{
1119 if (m->friendlist[friendnumber].file_sending[filenumber].status == 0)
1120 return -1;
1121
1122 switch (message_id) {
1123 case FILECONTROL_ACCEPT:
1124 m->friendlist[friendnumber].file_sending[filenumber].status = 3;
1125 return 0;
1126
1127 case FILECONTROL_PAUSE:
1128 m->friendlist[friendnumber].file_sending[filenumber].status = 2;
1129 return 0;
1130
1131 case FILECONTROL_KILL:
1132 case FILECONTROL_FINISHED:
1133 m->friendlist[friendnumber].file_sending[filenumber].status = 0;
1134 return 0;
1135 }
1136
1137 return -1;
1025} 1138}
1026 1139
1027/**************************************/ 1140/**************************************/
@@ -1331,6 +1444,9 @@ void doFriends(Messenger *m)
1331 uint8_t filenumber = data[0]; 1444 uint8_t filenumber = data[0];
1332 uint8_t control_type = data[1]; 1445 uint8_t control_type = data[1];
1333 1446
1447 if (handle_filecontrol(m, i, filenumber, control_type, data + 2, data_length - 2) == -1)
1448 break;
1449
1334 if (m->file_filecontrol) 1450 if (m->file_filecontrol)
1335 (*m->file_filecontrol)(m, i, filenumber, control_type, data + 2, data_length - 2, m->file_filecontrol_userdata); 1451 (*m->file_filecontrol)(m, i, filenumber, control_type, data + 2, data_length - 2, m->file_filecontrol_userdata);
1336 1452
@@ -1343,6 +1459,9 @@ void doFriends(Messenger *m)
1343 1459
1344 uint8_t filenumber = data[0]; 1460 uint8_t filenumber = data[0];
1345 1461
1462 if (m->friendlist[i].file_receiving[filenumber].status == 0)
1463 break;
1464
1346 if (m->file_filedata) 1465 if (m->file_filedata)
1347 (*m->file_filedata)(m, i, filenumber, data + 1, data_length - 1, m->file_filedata_userdata); 1466 (*m->file_filedata)(m, i, filenumber, data + 1, data_length - 1, m->file_filedata_userdata);
1348 1467