diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 108159a3..1c710522 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -304,6 +304,10 @@ int32_t m_addfriend_norequest(Messenger *m, const uint8_t *client_id) m->friendlist[i].statusmessage = calloc(1, 1); m->friendlist[i].statusmessage_length = 1; m->friendlist[i].userstatus = USERSTATUS_NONE; + m->friendlist[i].avatar_info_sent = 0; + m->friendlist[i].avatar_recv_data = NULL; + m->friendlist[i].avatar_send_data.bytes_sent = 0; + m->friendlist[i].avatar_send_data.last_reset = 0; m->friendlist[i].is_typing = 0; m->friendlist[i].message_id = 0; m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ @@ -643,7 +647,7 @@ int m_request_avatar_info(const Messenger *m, const int32_t friendnumber) if (friend_not_valid(m, friendnumber)) return -1; - if (write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_INFO_REQ, 0, 0, 0) >= 0) + if (write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_INFO_REQ, 0, 0, 0)) return 0; else return -1; @@ -658,9 +662,7 @@ int m_send_avatar_info(const Messenger *m, const int32_t friendnumber) data[0] = m->avatar_format; memcpy(data + 1, m->avatar_hash, AVATAR_HASH_LENGTH); - int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_INFO, data, sizeof(data), 0); - - if (ret >= 0) + if (write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_INFO, data, sizeof(data), 0)) return 0; else return -1; @@ -674,12 +676,11 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber) AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; if (avrd == NULL) { - avrd = malloc(sizeof(AVATARRECEIVEDATA)); + avrd = calloc(sizeof(AVATARRECEIVEDATA), 1); if (avrd == NULL) return -1; - memset(avrd, 0, sizeof(AVATARRECEIVEDATA)); avrd->started = 0; m->friendlist[friendnumber].avatar_recv_data = avrd; } @@ -2081,8 +2082,8 @@ void kill_messenger(Messenger *m) kill_networking(m->net); for (i = 0; i < m->numfriends; ++i) { - if (m->friendlist[i].statusmessage) - free(m->friendlist[i].statusmessage); + free(m->friendlist[i].statusmessage); + free(m->friendlist[friendnumber].avatar_recv_data); } free(m->avatar_data); @@ -2147,7 +2148,7 @@ static int send_avatar_data_control(const Messenger *m, const uint32_t friendnum &op, sizeof(op), 0); LOGGER_DEBUG("friendnumber = %u, op = %u, ret = %d", friendnumber, op, ret); - return (ret >= 0) ? 0 : -1; + return ret ? 0 : -1; } @@ -2207,7 +2208,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber, int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_DATA_START, start_data, sizeof(start_data), 0); - if (ret < 0) { + if (!ret) { /* Something went wrong, try to signal the error so the friend * can clear up the state. */ send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); @@ -2236,7 +2237,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber, PACKET_ID_AVATAR_DATA_PUSH, chunk, chunk_len, 0); - if (ret < 0) { + if (!ret) { LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, " "friendnumber = %u, offset = %u", ret, friendnumber, offset); diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 01632126..a107d80f 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -122,7 +122,7 @@ enum { /* Per-friend data limit for avatar data requests */ #define AVATAR_DATA_TRANSFER_LIMIT (10*MAX_AVATAR_DATA_LENGTH) -#define AVATAR_DATA_TRANSFER_TIMEOUT (20*60) +#define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */ /* USERSTATUS - diff --git a/toxcore/tox.c b/toxcore/tox.c index c5bea846..b44f0ee6 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -275,42 +275,6 @@ uint8_t tox_get_self_user_status(const Tox *tox) return m_get_self_userstatus(m); } -int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length) -{ - Messenger *m = tox; - return m_set_avatar(m, format, data, length); -} - -int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash) -{ - const Messenger *m = tox; - return m_get_self_avatar(m, format, buf, length, maxlen, hash); -} - -int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen) -{ - return m_avatar_hash(hash, data, datalen); -} - -int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber) -{ - const Messenger *m = tox; - return m_request_avatar_info(m, friendnumber); -} - -int tox_send_avatar_info(Tox *tox, const int32_t friendnumber) -{ - const Messenger *m = tox; - return m_send_avatar_info(m, friendnumber); -} - -int tox_request_avatar_data(const Tox *tox, const int32_t friendnumber) -{ - const Messenger *m = tox; - return m_request_avatar_data(m, friendnumber); -} - - /* returns timestamp of last time friendnumber was seen online, or 0 if never seen. * returns -1 on error. */ @@ -475,24 +439,6 @@ void tox_callback_connection_status(Tox *tox, void (*function)(Messenger *tox, i m_callback_connectionstatus(m, function, userdata); } -void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t *, void *), void *userdata) -{ - Messenger *m = tox; - m_callback_avatar_info(m, function, userdata); -} - - -void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t *, uint8_t *, uint32_t, - void *), void *userdata) -{ - Messenger *m = tox; - m_callback_avatar_data(m, function, userdata); -} - - - - - /**********ADVANCED FUNCTIONS (If you don't know what they do you can safely ignore them.) ************/ /* Functions to get/set the nospam part of the id. @@ -852,6 +798,57 @@ uint64_t tox_file_data_remaining(const Tox *tox, int32_t friendnumber, uint8_t f return file_dataremaining(m, friendnumber, filenumber, send_receive); } + +/****************AVATAR FUNCTIONS*****************/ + +void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t *, void *), void *userdata) +{ + Messenger *m = tox; + m_callback_avatar_info(m, function, userdata); +} + +void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t *, uint8_t *, uint32_t, + void *), void *userdata) +{ + Messenger *m = tox; + m_callback_avatar_data(m, function, userdata); +} + +int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length) +{ + Messenger *m = tox; + return m_set_avatar(m, format, data, length); +} + +int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, uint8_t *hash) +{ + const Messenger *m = tox; + return m_get_self_avatar(m, format, buf, length, maxlen, hash); +} + +int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen) +{ + return m_avatar_hash(hash, data, datalen); +} + +int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber) +{ + const Messenger *m = tox; + return m_request_avatar_info(m, friendnumber); +} + +int tox_send_avatar_info(Tox *tox, const int32_t friendnumber) +{ + const Messenger *m = tox; + return m_send_avatar_info(m, friendnumber); +} + +int tox_request_avatar_data(const Tox *tox, const int32_t friendnumber) +{ + const Messenger *m = tox; + return m_request_avatar_data(m, friendnumber); +} + /***************END OF FILE SENDING FUNCTIONS******************/ /* Like tox_bootstrap_from_address but for TCP relays only. diff --git a/toxcore/tox.h b/toxcore/tox.h index 8f54697f..a5efee34 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -254,98 +254,6 @@ int tox_get_self_status_message(const Tox *tox, uint8_t *buf, uint32_t maxlen); uint8_t tox_get_user_status(const Tox *tox, int32_t friendnumber); uint8_t tox_get_self_user_status(const Tox *tox); - -/* Set the user avatar image data. - * This should be made before connecting, so we will not announce that the user have no avatar - * before setting and announcing a new one, forcing the peers to re-download it. - * - * Notice that the library treats the image as raw data and does not interpret it by any way. - * - * Arguments: - * format - Avatar image format or NONE for user with no avatar (see TOX_AVATARFORMAT); - * data - pointer to the avatar data (may be NULL it the format is NONE); - * length - length of image data. Must be <= TOX_MAX_AVATAR_DATA_LENGTH. - * - * returns 0 on success - * returns -1 on failure. - */ -int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length); - - -/* Get avatar data from the current user. - * Copies the current user avatar data to the destination buffer and sets the image format - * accordingly. - * - * If the avatar format is NONE, the buffer 'buf' isleft uninitialized, 'hash' is zeroed, and - * 'length' is set to zero. - * - * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored. - * - * Arguments: - * format - destination pointer to the avatar image format (see TOX_AVATARFORMAT); - * buf - destination buffer to the image data. Must have at least 'maxlen' bytes; - * length - destination pointer to the image data length; - * maxlen - length of the destination buffer 'buf'; - * hash - destination pointer to the avatar hash (it must be exactly TOX_AVATAR_HASH_LENGTH bytes long). - * - * returns 0 on success; - * returns -1 on failure. - * - */ -int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, - uint8_t *hash); - - -/* Generates a cryptographic hash of the given avatar data. - * This function is a wrapper to internal message-digest functions and specifically provided - * to generate hashes from user avatars that may be memcmp()ed with the values returned by the - * other avatar functions. It is specially important to validate cached avatars. - * - * Arguments: - * hash - destination buffer for the hash data, it must be exactly TOX_AVATAR_HASH_LENGTH bytes long. - * data - avatar image data; - * datalen - length of the avatar image data; it must be <= TOX_MAX_AVATAR_DATA_LENGTH. - * - * returns 0 on success - * returns -1 on failure. - */ -int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen); - - -/* Request avatar information from a friend. - * Asks a friend to provide their avatar information (image format and hash). The friend may - * or may not answer this request and, if answered, the information will be provided through - * the callback 'avatar_info'. - * - * returns 0 on success - * returns -1 on failure. - */ -int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber); - - -/* Send an unrequested avatar information to a friend. - * Sends our avatar format and hash to a friend; he/she can use this information to validate - * an avatar from the cache and may (or not) reply with an avatar data request. - * - * Notice: it is NOT necessary to send these notification after changing the avatar or - * connecting. The library already does this. - * - * returns 0 on success - * returns -1 on failure. - */ -int tox_send_avatar_info(Tox *tox, const int32_t friendnumber); - - -/* Request the avatar data from a friend. - * Ask a friend to send their avatar data. The friend may or may not answer this request and, - * if answered, the information will be provided in callback 'avatar_data'. - * - * returns 0 on sucess - * returns -1 on failure. - */ -int tox_request_avatar_data(const Tox *tox, const int32_t friendnumber); - - /* returns timestamp of last time friendnumber was seen online, or 0 if never seen. * returns -1 on error. */ @@ -447,48 +355,6 @@ void tox_callback_read_receipt(Tox *tox, void (*function)(Tox *tox, int32_t, uin */ void tox_callback_connection_status(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, void *), void *userdata); -/* Set the callback function for avatar information. - * This callback will be called when avatar information are received from friends. These events - * can arrive at anytime, but are usually received uppon connection and in reply of avatar - * information requests. - * - * Function format is: - * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata) - * - * where 'format' is the avatar image format (see TOX_AVATARFORMAT) and 'hash' is the hash of - * the avatar data for caching purposes and it is exactly TOX_AVATAR_HASH_LENGTH long. If the - * image format is NONE, the hash is zeroed. - * - */ -void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t *, void *), - void *userdata); - - -/* Set the callback function for avatar data. - * This callback will be called when the complete avatar data was correctly received from a - * friend. This only happens in reply of a avatar data request (see tox_request_avatar_data); - * - * Function format is: - * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata) - * - * where 'format' is the avatar image format (see TOX_AVATARFORMAT); 'hash' is the - * locally-calculated cryptographic hash of the avatar data and it is exactly - * TOX_AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length - * of such data. - * - * If format is NONE, 'data' is NULL, 'datalen' is zero, and the hash is zeroed. The hash is - * always validated locally with the function tox_avatar_hash and ensured to match the image - * data, so this value can be safely used to compare with cached avatars. - * - * WARNING: users MUST treat all avatar image data received from another peer as untrusted and - * potentially malicious. The library only ensures that the data which arrived is the same the - * other user sent, and does not interpret or validate any image data. - */ -void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t *, uint8_t *, uint32_t, - void *), void *userdata); - - - /**********ADVANCED FUNCTIONS (If you don't know what they do you can safely ignore them.) ************/ @@ -662,6 +528,137 @@ uint32_t tox_count_chatlist(const Tox *tox); * of out_list will be truncated to list_size. */ uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size); +/****************AVATAR FUNCTIONS*****************/ + +/* Set the callback function for avatar information. + * This callback will be called when avatar information are received from friends. These events + * can arrive at anytime, but are usually received uppon connection and in reply of avatar + * information requests. + * + * Function format is: + * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata) + * + * where 'format' is the avatar image format (see TOX_AVATARFORMAT) and 'hash' is the hash of + * the avatar data for caching purposes and it is exactly TOX_AVATAR_HASH_LENGTH long. If the + * image format is NONE, the hash is zeroed. + * + */ +void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t *, void *), + void *userdata); + + +/* Set the callback function for avatar data. + * This callback will be called when the complete avatar data was correctly received from a + * friend. This only happens in reply of a avatar data request (see tox_request_avatar_data); + * + * Function format is: + * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata) + * + * where 'format' is the avatar image format (see TOX_AVATARFORMAT); 'hash' is the + * locally-calculated cryptographic hash of the avatar data and it is exactly + * TOX_AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length + * of such data. + * + * If format is NONE, 'data' is NULL, 'datalen' is zero, and the hash is zeroed. The hash is + * always validated locally with the function tox_avatar_hash and ensured to match the image + * data, so this value can be safely used to compare with cached avatars. + * + * WARNING: users MUST treat all avatar image data received from another peer as untrusted and + * potentially malicious. The library only ensures that the data which arrived is the same the + * other user sent, and does not interpret or validate any image data. + */ +void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, uint8_t *, uint8_t *, uint32_t, + void *), void *userdata); + +/* Set the user avatar image data. + * This should be made before connecting, so we will not announce that the user have no avatar + * before setting and announcing a new one, forcing the peers to re-download it. + * + * Notice that the library treats the image as raw data and does not interpret it by any way. + * + * Arguments: + * format - Avatar image format or NONE for user with no avatar (see TOX_AVATARFORMAT); + * data - pointer to the avatar data (may be NULL it the format is NONE); + * length - length of image data. Must be <= TOX_MAX_AVATAR_DATA_LENGTH. + * + * returns 0 on success + * returns -1 on failure. + */ +int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t length); + + +/* Get avatar data from the current user. + * Copies the current user avatar data to the destination buffer and sets the image format + * accordingly. + * + * If the avatar format is NONE, the buffer 'buf' isleft uninitialized, 'hash' is zeroed, and + * 'length' is set to zero. + * + * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored. + * + * Arguments: + * format - destination pointer to the avatar image format (see TOX_AVATARFORMAT); + * buf - destination buffer to the image data. Must have at least 'maxlen' bytes; + * length - destination pointer to the image data length; + * maxlen - length of the destination buffer 'buf'; + * hash - destination pointer to the avatar hash (it must be exactly TOX_AVATAR_HASH_LENGTH bytes long). + * + * returns 0 on success; + * returns -1 on failure. + * + */ +int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, + uint8_t *hash); + + +/* Generates a cryptographic hash of the given avatar data. + * This function is a wrapper to internal message-digest functions and specifically provided + * to generate hashes from user avatars that may be memcmp()ed with the values returned by the + * other avatar functions. It is specially important to validate cached avatars. + * + * Arguments: + * hash - destination buffer for the hash data, it must be exactly TOX_AVATAR_HASH_LENGTH bytes long. + * data - avatar image data; + * datalen - length of the avatar image data; it must be <= TOX_MAX_AVATAR_DATA_LENGTH. + * + * returns 0 on success + * returns -1 on failure. + */ +int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen); + + +/* Request avatar information from a friend. + * Asks a friend to provide their avatar information (image format and hash). The friend may + * or may not answer this request and, if answered, the information will be provided through + * the callback 'avatar_info'. + * + * returns 0 on success + * returns -1 on failure. + */ +int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber); + + +/* Send an unrequested avatar information to a friend. + * Sends our avatar format and hash to a friend; he/she can use this information to validate + * an avatar from the cache and may (or not) reply with an avatar data request. + * + * Notice: it is NOT necessary to send these notification after changing the avatar or + * connecting. The library already does this. + * + * returns 0 on success + * returns -1 on failure. + */ +int tox_send_avatar_info(Tox *tox, const int32_t friendnumber); + + +/* Request the avatar data from a friend. + * Ask a friend to send their avatar data. The friend may or may not answer this request and, + * if answered, the information will be provided in callback 'avatar_data'. + * + * returns 0 on sucess + * returns -1 on failure. + */ +int tox_request_avatar_data(const Tox *tox, const int32_t friendnumber); /****************FILE SENDING FUNCTIONS*****************/ /* NOTE: This how to will be updated.