diff --git a/testing/nTox.c b/testing/nTox.c index cbf8d028..92827554 100644 --- a/testing/nTox.c +++ b/testing/nTox.c @@ -103,17 +103,26 @@ void send_filesenders(Tox *m) } int add_filesender(Tox *m, uint16_t friendnum, char *filename) { - file_senders[numfilesenders].file = fopen(filename, "r"); + FILE *tempfile = fopen(filename, "r"); - if (file_senders[numfilesenders].file == 0) + if (tempfile == 0) return -1; + fseek(tempfile, 0, SEEK_END); + uint64_t filesize = ftell(tempfile); + fseek(tempfile, 0, SEEK_SET); + int filenum = new_filesender(m, friendnum, filesize, filename, strlen(filename) + 1); + + if (filenum == -1) + return -1; + + file_senders[numfilesenders].file = tempfile; file_senders[numfilesenders].piecelength = fread(file_senders[numfilesenders].nextpiece, 1, 1000, file_senders[numfilesenders].file); file_senders[numfilesenders].friendnum = friendnum; - file_senders[numfilesenders].filenumber = numfilesenders; + file_senders[numfilesenders].filenumber = filenum; ++numfilesenders; - return (numfilesenders - 1); + return filenum; } /* @@ -421,7 +430,7 @@ void line_eval(Tox *m, char *line) int friendnum = strtoul(line + prompt_offset, posi, 0); if (**posi != 0) { - sprintf(msg, "[t] Sending file %s to friendnum %u returned %i (-1 means failure)", *posi + 1, friendnum, + sprintf(msg, "[t] Sending file %s to friendnum %u filenumber is %i (-1 means failure)", *posi + 1, friendnum, add_filesender(m, friendnum, *posi + 1)); new_lines(msg); } @@ -645,11 +654,48 @@ void print_groupmessage(Tox *m, int groupnumber, int peernumber, uint8_t *messag new_lines(msg); } -void write_file(Tox *tox, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) +void file_request_accept(Tox *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, + uint16_t filename_length, void *userdata) +{ + char msg[512]; + sprintf(msg, "[t] %u is sending us: %s of size %llu", friendnumber, filename, filesize); + new_lines(msg); + + if (file_control(m, friendnumber, filenumber, 0, 0, 0)) { + sprintf(msg, "Accepted file transfer. (saving file as: %u.%u.bin)", friendnumber, filenumber); + new_lines(msg); + } else + new_lines("Could not accept file transfer."); +} + +void file_print_control(Tox *m, int friendnumber, uint8_t filenumber, uint8_t control_type, uint8_t *data, + uint16_t length, void *userdata) +{ + char msg[512] = {0}; + + if (control_type == 0) + sprintf(msg, "[t] %u accepted file transfer: %u", friendnumber, filenumber, friendnumber, filenumber); + else if (control_type == 3) + sprintf(msg, "[t] %u file transfer: %u completed", friendnumber, filenumber); + else + sprintf(msg, "[t] control %u received", control_type); + + new_lines(msg); +} + +void write_file(Tox *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) { char filename[256]; sprintf(filename, "%u.%u.bin", friendnumber, filenumber); FILE *pFile = fopen(filename, "a"); + + if (file_dataremaining(m, friendnumber, filenumber, 1) == 0) { + file_control(m, friendnumber, filenumber, 3, 0, 0); + char msg[512]; + sprintf(msg, "[t] %u file transfer: %u completed", friendnumber, filenumber); + new_lines(msg); + } + fwrite(data, length, 1, pFile); fclose(pFile); } @@ -702,6 +748,8 @@ int main(int argc, char *argv[]) tox_callback_group_invite(m, print_invite, NULL); tox_callback_group_message(m, print_groupmessage, NULL); callback_file_data(m, write_file, NULL); + callback_file_control(m, file_print_control, NULL); + callback_file_sendrequest(m, file_request_accept, NULL); initscr(); noecho(); diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 39bcd704..49be4a0a 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1038,7 +1038,7 @@ int file_control(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t mes if (friend_not_valid(m, friendnumber)) return 0; - if (m->friendlist[friendnumber].file_sending[filenumber].status == 0) + if (m->friendlist[friendnumber].file_receiving[filenumber].status == 0) return 0; uint8_t packet[MAX_DATA_SIZE]; @@ -1097,6 +1097,34 @@ int file_data(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t *data, return 0; } + +/* Give the number of bytes left to be sent/received. + * + * send_receive is 0 if we want the sending files, 1 if we want the receiving. + * + * return number of bytes remaining to be sent/received on success + * return 0 on failure + */ +uint64_t file_dataremaining(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t send_receive) +{ + if (friend_not_valid(m, friendnumber)) + return 0; + + if (send_receive == 0) { + if (m->friendlist[friendnumber].file_sending[filenumber].status == 0) + return 0; + + return m->friendlist[friendnumber].file_sending[filenumber].size - + m->friendlist[friendnumber].file_sending[filenumber].transferred; + } else { + if (m->friendlist[friendnumber].file_receiving[filenumber].status == 0) + return 0; + + return m->friendlist[friendnumber].file_receiving[filenumber].size - + m->friendlist[friendnumber].file_receiving[filenumber].transferred; + } +} + /* Run this when the friend disconnects. * Sets all current file transfers to broken. */ @@ -1427,9 +1455,11 @@ void doFriends(Messenger *m) uint8_t filenumber = data[0]; uint64_t filesize; memcpy(&filesize, data + 1, sizeof(filesize)); - //TODO: //filesize = ntohll(filesize); + m->friendlist[i].file_receiving[filenumber].status = 1; + m->friendlist[i].file_receiving[filenumber].size = filesize; + if (m->file_sendrequest) (*m->file_sendrequest)(m, i, filenumber, filesize, data + 1 + sizeof(uint64_t), data_length - 1 - sizeof(uint64_t), m->file_sendrequest_userdata); @@ -1462,6 +1492,8 @@ void doFriends(Messenger *m) if (m->friendlist[i].file_receiving[filenumber].status == 0) break; + m->friendlist[i].file_receiving[filenumber].transferred += (data_length - 1); + if (m->file_filedata) (*m->file_filedata)(m, i, filenumber, data + 1, data_length - 1, m->file_filedata_userdata); diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index fbf4d767..ca99fa18 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -502,6 +502,13 @@ void callback_file_data(Messenger *m, void (*function)(Messenger *m, int, uint8_ int file_sendrequest(Messenger *m, int friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length); +/* Send a file send request. + * Maximum filename length is 256 bytes. + * return file number on success + * return -1 on failure + */ +int new_filesender(Messenger *m, int friendnumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length); + /* Send a file control request. * * return 1 on success @@ -517,6 +524,15 @@ int file_control(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t mes */ int file_data(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length); +/* Give the number of bytes left to be sent/received. + * + * send_receive is 0 if we want the sending files, 1 if we want the receiving. + * + * return number of bytes remaining to be sent/received on success + * return 0 on failure + */ +uint64_t file_dataremaining(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t send_receive); + /*********************************/ /* Run this at startup.