tox_file_send_chunk() must now send data the same length as requested

in the requested chunk callback.

For zero size transfers if the data sent is not the same length, the
file is assumed to be done.
This commit is contained in:
irungentoo 2015-03-13 12:40:21 -04:00
parent eec1042695
commit 669975c226
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
4 changed files with 44 additions and 27 deletions

View File

@ -1196,6 +1196,28 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber,
return 0;
}
/* return packet number on success.
* return -1 on failure.
*/
static int64_t send_file_data_packet(const Messenger *m, int32_t friendnumber, uint8_t filenumber, const uint8_t *data,
uint16_t length)
{
if (friend_not_valid(m, friendnumber))
return -1;
uint8_t packet[2 + length];
packet[0] = PACKET_ID_FILE_DATA;
packet[1] = filenumber;
if (length) {
memcpy(packet + 2, data, length);
}
return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c,
m->friendlist[friendnumber].friendcon_id), packet, sizeof(packet), 1);
}
#define MAX_FILE_DATA_SIZE (MAX_CRYPTO_DATA_SIZE - 2)
#define MIN_SLOTS_FREE (CRYPTO_MIN_QUEUE_LENGTH / 4)
/* Send file data.
*
@ -1204,7 +1226,7 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber,
* return -2 if friend not online.
* return -3 if filenumber invalid.
* return -4 if file transfer not transferring.
* return -5 if trying to send too much data.
* return -5 if bad data size.
* return -6 if packet queue full.
* return -7 if wrong position.
*/
@ -1228,13 +1250,17 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
if (ft->paused != FILE_PAUSE_NOT)
return -4;
if (length > MAX_CRYPTO_DATA_SIZE - 2)
if (length > MAX_FILE_DATA_SIZE)
return -5;
if (ft->size) {
if (ft->size - ft->transferred < length) {
return -5;
}
if (length != MAX_FILE_DATA_SIZE && (ft->transferred + length) != ft->size) {
return -5;
}
}
if (position != ft->transferred) {
@ -1246,13 +1272,7 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
m->friendlist[friendnumber].friendcon_id)) < MIN_SLOTS_FREE)
return -6;
uint8_t packet[2 + length];
packet[0] = PACKET_ID_FILE_DATA;
packet[1] = filenumber;
memcpy(packet + 2, data, length);
int64_t ret = write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c,
m->friendlist[friendnumber].friendcon_id), packet, sizeof(packet), 1);
int64_t ret = send_file_data_packet(m, friendnumber, filenumber, data, length);
if (ret != -1) {
//TODO record packet ids to check if other received complete file.
@ -1262,7 +1282,7 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
--ft->slots_allocated;
}
if (length == 0 || ft->size == ft->transferred) {
if (length != MAX_FILE_DATA_SIZE || ft->size == ft->transferred) {
ft->status = FILESTATUS_FINISHED;
ft->last_packet_number = ret;
}
@ -1346,7 +1366,7 @@ static void do_reqchunk_filecb(Messenger *m, int32_t friendnumber)
if (free_slots == 0)
break;
uint16_t length = MAX_CRYPTO_DATA_SIZE - 2;
uint16_t length = MAX_FILE_DATA_SIZE;
if (ft->size) {
if (ft->size == ft->requested) {
@ -1980,7 +2000,7 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
ft->transferred += file_data_length;
if (ft->size && ft->transferred >= ft->size) {
if ((ft->size && ft->transferred >= ft->size) || file_data_length != MAX_FILE_DATA_SIZE) {
file_data_length = 0;
file_data = NULL;
position = ft->transferred;

View File

@ -637,7 +637,7 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber,
* return -2 if friend not online.
* return -3 if filenumber invalid.
* return -4 if file transfer not transferring.
* return -5 if trying to send too much data.
* return -5 if bad data size.
* return -6 if packet queue full.
* return -7 if wrong position.
*/

View File

@ -960,7 +960,7 @@ bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number,
return 0;
case -5:
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_TOO_LARGE);
SET_ERROR_PARAMETER(error, TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH);
return 0;
case -6:

View File

@ -1645,11 +1645,11 @@ typedef enum TOX_ERR_FILE_SEND_CHUNK {
*/
TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING,
/**
* Attempted to send more data than requested. The requested data size is
* Attempted to send more or less data than requested. The requested data size is
* adjusted according to maximum transmission unit and the expected end of
* the file. Trying to send more will result in no data being sent.
* the file. Trying to send less or more than requested will return this error.
*/
TOX_ERR_FILE_SEND_CHUNK_TOO_LARGE,
TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH,
/**
* Packet queue is full.
*/
@ -1664,12 +1664,12 @@ typedef enum TOX_ERR_FILE_SEND_CHUNK {
* Send a chunk of file data to a friend.
*
* This function is called in response to the `file_request_chunk` callback. The
* length parameter should be equal to or less than the one received though the
* callback. If it is zero, the transfer is assumed complete. For files with
* known size, Core will know that the transfer is complete after the last byte
* has been received, so it is not necessary (though not harmful) to send a
* zero-length chunk to terminate. For streams, it is necessary for the last
* chunk sent to be zero-length.
* length parameter should be equal to the one received though the callback.
* If it is zero, the transfer is assumed complete. For files with known size,
* Core will know that the transfer is complete after the last byte has been
* received, so it is not necessary (though not harmful) to send a zero-length
* chunk to terminate. For streams, core will know that the transfer is finished
* if a chunk with length less than the length requested in the callback is sent.
*
* @return true on success.
*/
@ -1694,10 +1694,7 @@ bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number,
* In response to receiving this callback, the client should call the function
* `tox_file_send_chunk` with the requested chunk. If the number of bytes sent
* through that function is zero, the file transfer is assumed complete. A
* client may choose to send less than requested, if it is reading from a
* stream that doesn't have more data, yet, and it still wants to send some
* data to the other side. However, this will generally be less efficient than
* waiting for a full chunk size of data to be ready.
* client must send the full length of data requested with this callback.
*
* @param friend_number The friend number of the receiving friend for this file.
* @param file_number The file transfer identifier returned by tox_file_send.