summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/Avatars.md44
-rw-r--r--testing/test_avatars.c50
-rw-r--r--toxcore/Messenger.c49
-rw-r--r--toxcore/Messenger.h61
-rw-r--r--toxcore/tox.c4
-rw-r--r--toxcore/tox.h40
6 files changed, 133 insertions, 115 deletions
diff --git a/docs/Avatars.md b/docs/Avatars.md
index 97b65c10..fee401c0 100644
--- a/docs/Avatars.md
+++ b/docs/Avatars.md
@@ -127,16 +127,16 @@ complete API documentation is available in `tox.h`.
127 127
128 128
129``` 129```
130#define TOX_MAX_AVATAR_DATA_LENGTH 16384 130#define TOX_AVATAR_MAX_DATA_LENGTH 16384
131#define TOX_AVATAR_HASH_LENGTH 32 131#define TOX_AVATAR_HASH_LENGTH 32
132 132
133 133
134/* Data formats for user avatar images */ 134/* Data formats for user avatar images */
135typedef enum { 135typedef enum {
136 TOX_AVATARFORMAT_NONE, 136 TOX_AVATAR_FORMAT_NONE,
137 TOX_AVATARFORMAT_PNG 137 TOX_AVATAR_FORMAT_PNG
138} 138}
139TOX_AVATARFORMAT; 139TOX_AVATAR_FORMAT;
140 140
141 141
142 142
@@ -287,11 +287,11 @@ functions. For a complete, working, example, see `testing/test_avatars.c`.
287In this example `load_data_file` is just an hypothetical function that loads 287In this example `load_data_file` is just an hypothetical function that loads
288data from a file into the buffer and sets the length accordingly. 288data from a file into the buffer and sets the length accordingly.
289 289
290 uint8_t buf[TOX_MAX_AVATAR_DATA_LENGTH]; 290 uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH];
291 uint32_t len; 291 uint32_t len;
292 292
293 if (load_data_file("avatar.png", buf, &len) == 0) 293 if (load_data_file("avatar.png", buf, &len) == 0)
294 if (tox_set_avatar(tox, TOX_AVATARFORMAT_PNG, buf, len) != 0) 294 if (tox_set_avatar(tox, TOX_AVATAR_FORMAT_PNG, buf, len) != 0)
295 fprintf(stderr, "Failed to set avatar.\n"); 295 fprintf(stderr, "Failed to set avatar.\n");
296 296
297If the user is connected, this function will also notify all connected 297If the user is connected, this function will also notify all connected
@@ -306,9 +306,9 @@ notifications and unnecessary data transfers.
306 306
307#### Removing the avatar from the current user 307#### Removing the avatar from the current user
308 308
309To remove an avatar, an application must set it to `TOX_AVATARFORMAT_NONE`. 309To remove an avatar, an application must set it to `TOX_AVATAR_FORMAT_NONE`.
310 310
311 tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0); 311 tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
312 312
313If the user is connected, this function will also notify all connected 313If the user is connected, this function will also notify all connected
314friends about the avatar change. 314friends about the avatar change.
@@ -362,7 +362,7 @@ checks the local avatar cache and emits an avatar data request if necessary:
362 { 362 {
363 printf("Receiving avatar information from friend %d. Format = %d\n", 363 printf("Receiving avatar information from friend %d. Format = %d\n",
364 friendnumber, format); 364 friendnumber, format);
365 if (format = TOX_AVATARFORMAT_NONE) { 365 if (format = TOX_AVATAR_FORMAT_NONE) {
366 /* User have no avatar or removed the avatar */ 366 /* User have no avatar or removed the avatar */
367 delete_avatar_from_cache(tox, friendnumber); 367 delete_avatar_from_cache(tox, friendnumber);
368 } else { 368 } else {
@@ -382,7 +382,7 @@ cache:
382 static void avatar_data_cb(Tox *tox, int32_t friendnumber, uint8_t format, 382 static void avatar_data_cb(Tox *tox, int32_t friendnumber, uint8_t format,
383 uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata) 383 uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
384 { 384 {
385 if (format = TOX_AVATARFORMAT_NONE) { 385 if (format = TOX_AVATAR_FORMAT_NONE) {
386 /* User have no avatar or removed the avatar */ 386 /* User have no avatar or removed the avatar */
387 delete_avatar_from_cache(tox, friendnumber); 387 delete_avatar_from_cache(tox, friendnumber);
388 } else { 388 } else {
@@ -453,8 +453,8 @@ the following structure:
453 453
454Where 'format' is the image data format, one of the following: 454Where 'format' is the image data format, one of the following:
455 455
456 0 = AVATARFORMAT_NONE (no avatar set) 456 0 = AVATAR_FORMAT_NONE (no avatar set)
457 1 = AVATARFORMAT_PNG 457 1 = AVATAR_FORMAT_PNG
458 458
459and 'hash' is the SHA-256 message digest of the avatar data. 459and 'hash' is the SHA-256 message digest of the avatar data.
460 460
@@ -481,8 +481,8 @@ types.
481 return, which semantics are explained bellow. The following values are 481 return, which semantics are explained bellow. The following values are
482 defined: 482 defined:
483 483
484 0 = AVATARDATACONTROL_REQ 484 0 = AVATAR_DATACONTROL_REQ
485 1 = AVATARDATACONTROL_ERROR 485 1 = AVATAR_DATACONTROL_ERROR
486 486
487 487
488 - Packet `PACKET_ID_AVATAR_DATA_START` have the following format: 488 - Packet `PACKET_ID_AVATAR_DATA_START` have the following format:
@@ -511,17 +511,17 @@ from a client "B":
511 - "A" must initialize its control structures and mark its data transfer 511 - "A" must initialize its control structures and mark its data transfer
512 as not yet started. Then it requests avatar data from "B" by sending a 512 as not yet started. Then it requests avatar data from "B" by sending a
513 packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to 513 packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to
514 `AVATARDATACONTROL_REQ`. 514 `AVATAR_DATACONTROL_REQ`.
515 515
516 - If "B" accepts this transfer, it answers by sending an 516 - If "B" accepts this transfer, it answers by sending an
517 `PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and 517 `PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and
518 'data_length' set to the respective values from the current avatar. 518 'data_length' set to the respective values from the current avatar.
519 If "B" have no avatar set, 'format' must be `AVATARFORMAT_NONE`, 'hash' 519 If "B" have no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash'
520 must be zeroed and 'data_length' must be zero. 520 must be zeroed and 'data_length' must be zero.
521 521
522 If "B" does not accept sending the avatar, it may send a packet 522 If "B" does not accept sending the avatar, it may send a packet
523 `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to 523 `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
524 `AVATARDATACONTROL_ERROR` or simply ignore this request. "A" must cope 524 `AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope
525 with this. 525 with this.
526 526
527 If "B" have an avatar, it sends a variable number of 527 If "B" have an avatar, it sends a variable number of
@@ -531,7 +531,7 @@ from a client "B":
531 - Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it 531 - Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it
532 has sent a data request to "B". If not, just ignores the packet. 532 has sent a data request to "B". If not, just ignores the packet.
533 533
534 If "A" really requested avatar data and the format is `AVATARFORMAT_NONE`, 534 If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`,
535 it triggers the avatar data callback, and clears all the temporary data, 535 it triggers the avatar data callback, and clears all the temporary data,
536 finishing the process. For other formats, "A" just waits for packets 536 finishing the process. For other formats, "A" just waits for packets
537 of type `PACKET_ID_AVATAR_DATA_PUSH`. 537 of type `PACKET_ID_AVATAR_DATA_PUSH`.
@@ -541,9 +541,9 @@ from a client "B":
541 already received. If this conditions are valid, it checks if the total 541 already received. If this conditions are valid, it checks if the total
542 length of the data already stored in the receiving buffer plus the data 542 length of the data already stored in the receiving buffer plus the data
543 present in the push packet is still less or equal than 543 present in the push packet is still less or equal than
544 `TOX_MAX_AVATAR_DATA_LENGTH`. If invalid, it replies with a 544 `TOX_AVATAR_MAX_DATA_LENGTH`. If invalid, it replies with a
545 `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to 545 `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
546 `AVATARDATACONTROL_ERROR`. 546 `AVATAR_DATACONTROL_ERROR`.
547 547
548 If valid, "A" updates the 'bytes_received' counter and concatenates the 548 If valid, "A" updates the 'bytes_received' counter and concatenates the
549 newly arrived data to the buffer. 549 newly arrived data to the buffer.
@@ -566,7 +566,7 @@ from a client "B":
566 some transfer limit for the data it sends. 566 some transfer limit for the data it sends.
567 567
568 - Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' 568 - Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op'
569 set to `AVATARDATACONTROL_ERROR` clears any existing control state and 569 set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and
570 finishes sending or receiving data. 570 finishes sending or receiving data.
571 571
572 572
@@ -596,7 +596,7 @@ The present proposal mitigates this situation by:
596 same offset of the avatar again and again, the implementation limits 596 same offset of the avatar again and again, the implementation limits
597 the amount of data a single user can request for some time. For now, 597 the amount of data a single user can request for some time. For now,
598 the library will not allow an user to request more than 598 the library will not allow an user to request more than
599 `10*TOX_MAX_AVATAR_DATA_LENGTH` in less than 20 minutes; 599 `10*TOX_AVATAR_MAX_DATA_LENGTH` in less than 20 minutes;
600 600
601 - Making the requester responsible for storing partial data and state 601 - Making the requester responsible for storing partial data and state
602 information; 602 information;
diff --git a/testing/test_avatars.c b/testing/test_avatars.c
index 9e2a411b..7e7cdd49 100644
--- a/testing/test_avatars.c
+++ b/testing/test_avatars.c
@@ -86,8 +86,8 @@ typedef struct {
86 86
87static const def_avatar_name_t def_avatar_names[] = { 87static const def_avatar_name_t def_avatar_names[] = {
88 /* In order of preference */ 88 /* In order of preference */
89 { TOX_AVATARFORMAT_PNG, "png", "avatar.png" }, 89 { TOX_AVATAR_FORMAT_PNG, "png", "avatar.png" },
90 { TOX_AVATARFORMAT_NONE, NULL, NULL }, /* Must be the last one */ 90 { TOX_AVATAR_FORMAT_NONE, NULL, NULL }, /* Must be the last one */
91}; 91};
92 92
93 93
@@ -99,7 +99,7 @@ static char *get_avatar_suffix_from_format(uint8_t format)
99{ 99{
100 int i; 100 int i;
101 101
102 for (i = 0; def_avatar_names[i].format != TOX_AVATARFORMAT_NONE; i++) 102 for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++)
103 if (def_avatar_names[i].format == format) 103 if (def_avatar_names[i].format == format)
104 return def_avatar_names[i].suffix; 104 return def_avatar_names[i].suffix;
105 105
@@ -118,7 +118,7 @@ static int load_avatar_data(char *fname, uint8_t *buf)
118 if (fp == NULL) 118 if (fp == NULL)
119 return -1; /* Error */ 119 return -1; /* Error */
120 120
121 size_t n = fread(buf, 1, TOX_MAX_AVATAR_DATA_LENGTH, fp); 121 size_t n = fread(buf, 1, TOX_AVATAR_MAX_DATA_LENGTH, fp);
122 int ret; 122 int ret;
123 123
124 if (ferror(fp) != 0 || n == 0) 124 if (ferror(fp) != 0 || n == 0)
@@ -222,7 +222,7 @@ static int load_user_avatar(Tox *tox, char *base_dir, int friendnum,
222 } 222 }
223 223
224 *datalen = ret; 224 *datalen = ret;
225 tox_avatar_hash(tox, hash, data, *datalen); 225 tox_hash(tox, hash, data, *datalen);
226 226
227 return 0; 227 return 0;
228} 228}
@@ -267,7 +267,7 @@ static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum)
267 /* This iteration is dumb and inefficient */ 267 /* This iteration is dumb and inefficient */
268 int i; 268 int i;
269 269
270 for (i = 0; def_avatar_names[i].format != TOX_AVATARFORMAT_NONE; i++) { 270 for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) {
271 int ret = make_avatar_file_name(path, sizeof(path), base_dir, 271 int ret = make_avatar_file_name(path, sizeof(path), base_dir,
272 def_avatar_names[i].format, addr); 272 def_avatar_names[i].format, addr);
273 273
@@ -305,7 +305,7 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *
305 char *base_dir = (char *) ud; 305 char *base_dir = (char *) ud;
306 uint8_t addr[TOX_CLIENT_ID_SIZE]; 306 uint8_t addr[TOX_CLIENT_ID_SIZE];
307 char addr_str[2 * TOX_CLIENT_ID_SIZE + 1]; 307 char addr_str[2 * TOX_CLIENT_ID_SIZE + 1];
308 char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1]; 308 char hash_str[2 * TOX_HASH_LENGTH + 1];
309 309
310 if (tox_get_client_id(tox, n, addr) == 0) { 310 if (tox_get_client_id(tox, n, addr) == 0) {
311 byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str); 311 byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str);
@@ -315,10 +315,10 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *
315 printf("Receiving avatar information from friend number %u.\n", n); 315 printf("Receiving avatar information from friend number %u.\n", n);
316 } 316 }
317 317
318 byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str); 318 byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
319 DEBUG("format=%u, hash=%s", format, hash_str); 319 DEBUG("format=%u, hash=%s", format, hash_str);
320 320
321 if (format == TOX_AVATARFORMAT_NONE) { 321 if (format == TOX_AVATAR_FORMAT_NONE) {
322 printf(" -> User do not have an avatar.\n"); 322 printf(" -> User do not have an avatar.\n");
323 /* User have no avatar anymore, delete it from our cache */ 323 /* User have no avatar anymore, delete it from our cache */
324 delete_user_avatar(tox, base_dir, n); 324 delete_user_avatar(tox, base_dir, n);
@@ -332,14 +332,14 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *
332 * these events. 332 * these events.
333 */ 333 */
334 uint32_t cur_av_len; 334 uint32_t cur_av_len;
335 uint8_t cur_av_data[TOX_MAX_AVATAR_DATA_LENGTH]; 335 uint8_t cur_av_data[TOX_AVATAR_MAX_DATA_LENGTH];
336 uint8_t cur_av_hash[TOX_AVATAR_HASH_LENGTH]; 336 uint8_t cur_av_hash[TOX_HASH_LENGTH];
337 int ret; 337 int ret;
338 338
339 ret = load_user_avatar(tox, base_dir, n, format, cur_av_hash, cur_av_data, &cur_av_len); 339 ret = load_user_avatar(tox, base_dir, n, format, cur_av_hash, cur_av_data, &cur_av_len);
340 340
341 if (ret != 0 341 if (ret != 0
342 && memcpy(cur_av_hash, hash, TOX_AVATAR_HASH_LENGTH) != 0) { 342 && memcpy(cur_av_hash, hash, TOX_HASH_LENGTH) != 0) {
343 printf(" -> Cached avatar is outdated. Requesting avatar data.\n"); 343 printf(" -> Cached avatar is outdated. Requesting avatar data.\n");
344 tox_request_avatar_data(tox, n); 344 tox_request_avatar_data(tox, n);
345 } else { 345 } else {
@@ -355,7 +355,7 @@ static void friend_avatar_data_cb(Tox *tox, int32_t n, uint8_t format,
355 char *base_dir = (char *) ud; 355 char *base_dir = (char *) ud;
356 uint8_t addr[TOX_CLIENT_ID_SIZE]; 356 uint8_t addr[TOX_CLIENT_ID_SIZE];
357 char addr_str[2 * TOX_CLIENT_ID_SIZE + 1]; 357 char addr_str[2 * TOX_CLIENT_ID_SIZE + 1];
358 char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1]; 358 char hash_str[2 * TOX_HASH_LENGTH + 1];
359 359
360 if (tox_get_client_id(tox, n, addr) == 0) { 360 if (tox_get_client_id(tox, n, addr) == 0) {
361 byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str); 361 byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str);
@@ -365,12 +365,12 @@ static void friend_avatar_data_cb(Tox *tox, int32_t n, uint8_t format,
365 printf("Receiving avatar data from friend number %u.\n", n); 365 printf("Receiving avatar data from friend number %u.\n", n);
366 } 366 }
367 367
368 byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str); 368 byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
369 DEBUG("format=%u, datalen=%d, hash=%s\n", format, datalen, hash_str); 369 DEBUG("format=%u, datalen=%d, hash=%s\n", format, datalen, hash_str);
370 370
371 delete_user_avatar(tox, base_dir, n); 371 delete_user_avatar(tox, base_dir, n);
372 372
373 if (format != TOX_AVATARFORMAT_NONE) { 373 if (format != TOX_AVATAR_FORMAT_NONE) {
374 int ret = save_user_avatar(tox, base_dir, n, format, data, datalen); 374 int ret = save_user_avatar(tox, base_dir, n, format, data, datalen);
375 375
376 if (ret == 0) 376 if (ret == 0)
@@ -406,7 +406,7 @@ static void friend_msg_cb(Tox *tox, int n, const uint8_t *msg, uint16_t len, voi
406 set_avatar(tox, base_dir); 406 set_avatar(tox, base_dir);
407 reply_ptr = "Setting image avatar"; 407 reply_ptr = "Setting image avatar";
408 } else if (strstr(msg_str, "!remove-avatar") != NULL) { 408 } else if (strstr(msg_str, "!remove-avatar") != NULL) {
409 int r = tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0); 409 int r = tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
410 DEBUG("tox_set_avatar returned %d", r); 410 DEBUG("tox_set_avatar returned %d", r);
411 reply_ptr = "Removing avatar"; 411 reply_ptr = "Removing avatar";
412 } 412 }
@@ -453,10 +453,10 @@ static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name
453 FILE *fp = fopen(path, "rb"); 453 FILE *fp = fopen(path, "rb");
454 454
455 if (fp != NULL) { 455 if (fp != NULL) {
456 uint8_t buf[2 * TOX_MAX_AVATAR_DATA_LENGTH]; 456 uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
457 int len = fread(buf, 1, sizeof(buf), fp); 457 int len = fread(buf, 1, sizeof(buf), fp);
458 458
459 if (len >= 0 && len <= TOX_MAX_AVATAR_DATA_LENGTH) { 459 if (len >= 0 && len <= TOX_AVATAR_MAX_DATA_LENGTH) {
460 int r = tox_set_avatar(tox, an->format, buf, len); 460 int r = tox_set_avatar(tox, an->format, buf, len);
461 DEBUG("%d bytes, tox_set_avatar returned=%d", len, r); 461 DEBUG("%d bytes, tox_set_avatar returned=%d", len, r);
462 462
@@ -468,7 +468,7 @@ static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name
468 DEBUG("read error %d", len); 468 DEBUG("read error %d", len);
469 } else { 469 } else {
470 printf("Avatar file %s if too big (more than %d bytes)", 470 printf("Avatar file %s if too big (more than %d bytes)",
471 path, TOX_MAX_AVATAR_DATA_LENGTH); 471 path, TOX_AVATAR_MAX_DATA_LENGTH);
472 } 472 }
473 473
474 fclose(fp); 474 fclose(fp);
@@ -486,8 +486,8 @@ static void set_avatar(Tox *tox, const char *base_dir)
486 int i; 486 int i;
487 487
488 for (i = 0; i < 4; i++) { 488 for (i = 0; i < 4; i++) {
489 if (def_avatar_names[i].format == TOX_AVATARFORMAT_NONE) { 489 if (def_avatar_names[i].format == TOX_AVATAR_FORMAT_NONE) {
490 tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0); 490 tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
491 printf("No avatar file found, setting to NONE.\n"); 491 printf("No avatar file found, setting to NONE.\n");
492 return; 492 return;
493 } else { 493 } else {
@@ -504,15 +504,15 @@ static void set_avatar(Tox *tox, const char *base_dir)
504static void print_avatar_info(Tox *tox) 504static void print_avatar_info(Tox *tox)
505{ 505{
506 uint8_t format; 506 uint8_t format;
507 uint8_t data[TOX_MAX_AVATAR_DATA_LENGTH]; 507 uint8_t data[TOX_AVATAR_MAX_DATA_LENGTH];
508 uint8_t hash[TOX_AVATAR_HASH_LENGTH]; 508 uint8_t hash[TOX_HASH_LENGTH];
509 uint32_t data_length; 509 uint32_t data_length;
510 char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1]; 510 char hash_str[2 * TOX_HASH_LENGTH + 1];
511 511
512 int ret = tox_get_self_avatar(tox, &format, data, &data_length, sizeof(data), hash); 512 int ret = tox_get_self_avatar(tox, &format, data, &data_length, sizeof(data), hash);
513 DEBUG("tox_get_self_avatar returned %d", ret); 513 DEBUG("tox_get_self_avatar returned %d", ret);
514 DEBUG("format: %d, data_length: %d", format, data_length); 514 DEBUG("format: %d, data_length: %d", format, data_length);
515 byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str); 515 byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
516 DEBUG("hash: %s", hash_str); 516 DEBUG("hash: %s", hash_str);
517} 517}
518 518
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 3d96f6ca..99b95f67 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -576,10 +576,10 @@ int m_set_userstatus(Messenger *m, uint8_t status)
576 576
577int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length) 577int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length)
578{ 578{
579 if (length > MAX_AVATAR_DATA_LENGTH) 579 if (length > AVATAR_MAX_DATA_LENGTH)
580 return -1; 580 return -1;
581 581
582 if (format == AVATARFORMAT_NONE) { 582 if (format == AVATAR_FORMAT_NONE) {
583 free(m->avatar_data); 583 free(m->avatar_data);
584 m->avatar_data = NULL; 584 m->avatar_data = NULL;
585 m->avatar_data_length = 0; 585 m->avatar_data_length = 0;
@@ -632,15 +632,18 @@ int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_
632 return 0; 632 return 0;
633} 633}
634 634
635int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen) 635int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
636{ 636{
637 if (hash == NULL) 637 if (hash == NULL)
638 return -1; 638 return -1;
639 639
640 crypto_hash_sha256(hash, data, datalen); 640 return crypto_hash_sha256(hash, data, datalen);
641 return 0;
642} 641}
643 642
643int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
644{
645 return m_hash(hash, data, datalen);
646}
644 647
645int m_request_avatar_info(const Messenger *m, const int32_t friendnumber) 648int m_request_avatar_info(const Messenger *m, const int32_t friendnumber)
646{ 649{
@@ -673,10 +676,10 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
673 if (friend_not_valid(m, friendnumber)) 676 if (friend_not_valid(m, friendnumber))
674 return -1; 677 return -1;
675 678
676 AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; 679 AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
677 680
678 if (avrd == NULL) { 681 if (avrd == NULL) {
679 avrd = calloc(sizeof(AVATARRECEIVEDATA), 1); 682 avrd = calloc(sizeof(AVATAR_RECEIVEDATA), 1);
680 683
681 if (avrd == NULL) 684 if (avrd == NULL)
682 return -1; 685 return -1;
@@ -693,9 +696,9 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
693 avrd->started = 0; 696 avrd->started = 0;
694 avrd->bytes_received = 0; 697 avrd->bytes_received = 0;
695 avrd->total_length = 0; 698 avrd->total_length = 0;
696 avrd->format = AVATARFORMAT_NONE; 699 avrd->format = AVATAR_FORMAT_NONE;
697 700
698 return send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_REQ); 701 return send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_REQ);
699} 702}
700 703
701 704
@@ -2006,7 +2009,7 @@ Messenger *new_messenger(Messenger_Options *options)
2006 m->net = new_networking(ip, TOX_PORT_DEFAULT); 2009 m->net = new_networking(ip, TOX_PORT_DEFAULT);
2007 } 2010 }
2008 2011
2009 m->avatar_format = AVATARFORMAT_NONE; 2012 m->avatar_format = AVATAR_FORMAT_NONE;
2010 m->avatar_data = NULL; 2013 m->avatar_data = NULL;
2011 2014
2012 if (m->net == NULL) { 2015 if (m->net == NULL) {
@@ -2159,17 +2162,17 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
2159 LOGGER_DEBUG("Error: PACKET_ID_AVATAR_DATA_CONTROL with bad " 2162 LOGGER_DEBUG("Error: PACKET_ID_AVATAR_DATA_CONTROL with bad "
2160 "data_length = %u, friendnumber = %u", 2163 "data_length = %u, friendnumber = %u",
2161 data_length, friendnumber); 2164 data_length, friendnumber);
2162 send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); 2165 send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
2163 return -1; /* Error */ 2166 return -1; /* Error */
2164 } 2167 }
2165 2168
2166 LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]); 2169 LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]);
2167 2170
2168 switch (data[0]) { 2171 switch (data[0]) {
2169 case AVATARDATACONTROL_REQ: { 2172 case AVATAR_DATACONTROL_REQ: {
2170 2173
2171 /* Check data transfer limits for this friend */ 2174 /* Check data transfer limits for this friend */
2172 AVATARSENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data); 2175 AVATAR_SENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data);
2173 2176
2174 if (avsd->bytes_sent >= AVATAR_DATA_TRANSFER_LIMIT) { 2177 if (avsd->bytes_sent >= AVATAR_DATA_TRANSFER_LIMIT) {
2175 /* User reached data limit. Check timeout */ 2178 /* User reached data limit. Check timeout */
@@ -2183,7 +2186,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
2183 /* Friend still rate-limitted. Send an error and stops. */ 2186 /* Friend still rate-limitted. Send an error and stops. */
2184 LOGGER_DEBUG("Avatar data transfer limit reached. " 2187 LOGGER_DEBUG("Avatar data transfer limit reached. "
2185 "friendnumber = %u", friendnumber); 2188 "friendnumber = %u", friendnumber);
2186 send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); 2189 send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
2187 return 0; 2190 return 0;
2188 } 2191 }
2189 } 2192 }
@@ -2211,12 +2214,12 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
2211 if (!ret) { 2214 if (!ret) {
2212 /* Something went wrong, try to signal the error so the friend 2215 /* Something went wrong, try to signal the error so the friend
2213 * can clear up the state. */ 2216 * can clear up the state. */
2214 send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); 2217 send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
2215 return 0; 2218 return 0;
2216 } 2219 }
2217 2220
2218 /* User have no avatar data, nothing more to do. */ 2221 /* User have no avatar data, nothing more to do. */
2219 if (m->avatar_format == AVATARFORMAT_NONE) 2222 if (m->avatar_format == AVATAR_FORMAT_NONE)
2220 return 0; 2223 return 0;
2221 2224
2222 /* Send the actual avatar data. */ 2225 /* Send the actual avatar data. */
@@ -2241,7 +2244,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
2241 LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, " 2244 LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, "
2242 "friendnumber = %u, offset = %u", 2245 "friendnumber = %u, offset = %u",
2243 ret, friendnumber, offset); 2246 ret, friendnumber, offset);
2244 send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR); 2247 send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
2245 return -1; 2248 return -1;
2246 } 2249 }
2247 } 2250 }
@@ -2249,7 +2252,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
2249 return 0; 2252 return 0;
2250 } 2253 }
2251 2254
2252 case AVATARDATACONTROL_ERROR: { 2255 case AVATAR_DATACONTROL_ERROR: {
2253 if (m->friendlist[friendnumber].avatar_recv_data) { 2256 if (m->friendlist[friendnumber].avatar_recv_data) {
2254 /* We were receiving the data, sender detected an error 2257 /* We were receiving the data, sender detected an error
2255 (eg. changing avatar) and asked us to stop. */ 2258 (eg. changing avatar) and asked us to stop. */
@@ -2276,7 +2279,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
2276 return -1; 2279 return -1;
2277 } 2280 }
2278 2281
2279 AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; 2282 AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
2280 2283
2281 if (avrd == NULL) { 2284 if (avrd == NULL) {
2282 LOGGER_DEBUG("Received an unrequested DATA_START, friendnumber = %u", 2285 LOGGER_DEBUG("Received an unrequested DATA_START, friendnumber = %u",
@@ -2307,7 +2310,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
2307 friendnumber, avrd->format, avrd->total_length, 2310 friendnumber, avrd->format, avrd->total_length,
2308 avrd->bytes_received); 2311 avrd->bytes_received);
2309 2312
2310 if (avrd->total_length > MAX_AVATAR_DATA_LENGTH) { 2313 if (avrd->total_length > AVATAR_MAX_DATA_LENGTH) {
2311 /* Invalid data length. Stops. */ 2314 /* Invalid data length. Stops. */
2312 LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, " 2315 LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, "
2313 "friendnumber = %u", friendnumber); 2316 "friendnumber = %u", friendnumber);
@@ -2317,7 +2320,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
2317 return 0; 2320 return 0;
2318 } 2321 }
2319 2322
2320 if (avrd->format == AVATARFORMAT_NONE || avrd->total_length == 0) { 2323 if (avrd->format == AVATAR_FORMAT_NONE || avrd->total_length == 0) {
2321 /* No real data to receive. Run callback function and finish. */ 2324 /* No real data to receive. Run callback function and finish. */
2322 LOGGER_DEBUG("format == NONE, friendnumber = %u", friendnumber); 2325 LOGGER_DEBUG("format == NONE, friendnumber = %u", friendnumber);
2323 2326
@@ -2343,7 +2346,7 @@ static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber,
2343{ 2346{
2344 LOGGER_DEBUG("friendnumber = %u, data_length = %u", friendnumber, data_length); 2347 LOGGER_DEBUG("friendnumber = %u, data_length = %u", friendnumber, data_length);
2345 2348
2346 AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; 2349 AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
2347 2350
2348 if (avrd == NULL) { 2351 if (avrd == NULL) {
2349 /* No active transfer. It must be an error or a malicious request, 2352 /* No active transfer. It must be an error or a malicious request,
@@ -2363,7 +2366,7 @@ static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber,
2363 uint32_t new_length = avrd->bytes_received + data_length; 2366 uint32_t new_length = avrd->bytes_received + data_length;
2364 2367
2365 if (new_length > avrd->total_length 2368 if (new_length > avrd->total_length
2366 || new_length >= MAX_AVATAR_DATA_LENGTH) { 2369 || new_length >= AVATAR_MAX_DATA_LENGTH) {
2367 /* Invalid data length due to error or malice. Stops. */ 2370 /* Invalid data length due to error or malice. Stops. */
2368 LOGGER_DEBUG("Invalid data length. friendnumber = %u, " 2371 LOGGER_DEBUG("Invalid data length. friendnumber = %u, "
2369 "new_length = %u, avrd->total_length = %u", 2372 "new_length = %u, avrd->total_length = %u",
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index a107d80f..e6877002 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -36,8 +36,8 @@
36#define MAX_NAME_LENGTH 128 36#define MAX_NAME_LENGTH 128
37/* TODO: this must depend on other variable. */ 37/* TODO: this must depend on other variable. */
38#define MAX_STATUSMESSAGE_LENGTH 1007 38#define MAX_STATUSMESSAGE_LENGTH 1007
39#define MAX_AVATAR_DATA_LENGTH 16384 39#define AVATAR_MAX_DATA_LENGTH 16384
40#define AVATAR_HASH_LENGTH 32 40#define AVATAR_HASH_LENGTH crypto_hash_sha256_BYTES
41 41
42 42
43#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t)) 43#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
@@ -121,7 +121,7 @@ enum {
121#define AVATAR_DATA_MAX_CHUNK_SIZE (MAX_CRYPTO_DATA_SIZE-1) 121#define AVATAR_DATA_MAX_CHUNK_SIZE (MAX_CRYPTO_DATA_SIZE-1)
122 122
123/* Per-friend data limit for avatar data requests */ 123/* Per-friend data limit for avatar data requests */
124#define AVATAR_DATA_TRANSFER_LIMIT (10*MAX_AVATAR_DATA_LENGTH) 124#define AVATAR_DATA_TRANSFER_LIMIT (10*AVATAR_MAX_DATA_LENGTH)
125#define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */ 125#define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */
126 126
127 127
@@ -137,40 +137,40 @@ typedef enum {
137} 137}
138USERSTATUS; 138USERSTATUS;
139 139
140/* AVATARFORMAT - 140/* AVATAR_FORMAT -
141 * Data formats for user avatar images 141 * Data formats for user avatar images
142 */ 142 */
143typedef enum { 143typedef enum {
144 AVATARFORMAT_NONE, 144 AVATAR_FORMAT_NONE = 0,
145 AVATARFORMAT_PNG 145 AVATAR_FORMAT_PNG
146} 146}
147AVATARFORMAT; 147AVATAR_FORMAT;
148 148
149/* AVATARDATACONTROL 149/* AVATAR_DATACONTROL
150 * To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL) 150 * To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL)
151 */ 151 */
152typedef enum { 152typedef enum {
153 AVATARDATACONTROL_REQ, 153 AVATAR_DATACONTROL_REQ,
154 AVATARDATACONTROL_ERROR 154 AVATAR_DATACONTROL_ERROR
155} 155}
156AVATARDATACONTROL; 156AVATAR_DATACONTROL;
157 157
158typedef struct { 158typedef struct {
159 uint8_t started; 159 uint8_t started;
160 AVATARFORMAT format; 160 AVATAR_FORMAT format;
161 uint8_t hash[AVATAR_HASH_LENGTH]; 161 uint8_t hash[AVATAR_HASH_LENGTH];
162 uint32_t total_length; 162 uint32_t total_length;
163 uint32_t bytes_received; 163 uint32_t bytes_received;
164 uint8_t data[MAX_AVATAR_DATA_LENGTH]; 164 uint8_t data[AVATAR_MAX_DATA_LENGTH];
165} 165}
166AVATARRECEIVEDATA; 166AVATAR_RECEIVEDATA;
167 167
168typedef struct { 168typedef struct {
169 /* Fields only used to limit the network usage from a given friend */ 169 /* Fields only used to limit the network usage from a given friend */
170 uint32_t bytes_sent; /* Total bytes send to this user */ 170 uint32_t bytes_sent; /* Total bytes send to this user */
171 uint64_t last_reset; /* Time the data counter was last reset */ 171 uint64_t last_reset; /* Time the data counter was last reset */
172} 172}
173AVATARSENDDATA; 173AVATAR_SENDDATA;
174 174
175 175
176struct File_Transfers { 176struct File_Transfers {
@@ -230,8 +230,8 @@ typedef struct {
230 int invited_groups[MAX_INVITED_GROUPS]; 230 int invited_groups[MAX_INVITED_GROUPS];
231 uint16_t invited_groups_num; 231 uint16_t invited_groups_num;
232 232
233 AVATARSENDDATA avatar_send_data; 233 AVATAR_SENDDATA avatar_send_data;
234 AVATARRECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend. 234 AVATAR_RECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend.
235 235
236 struct { 236 struct {
237 int (*function)(void *object, const uint8_t *data, uint32_t len); 237 int (*function)(void *object, const uint8_t *data, uint32_t len);
@@ -264,7 +264,7 @@ typedef struct Messenger {
264 264
265 USERSTATUS userstatus; 265 USERSTATUS userstatus;
266 266
267 AVATARFORMAT avatar_format; 267 AVATAR_FORMAT avatar_format;
268 uint8_t *avatar_data; 268 uint8_t *avatar_data;
269 uint32_t avatar_data_length; 269 uint32_t avatar_data_length;
270 uint8_t avatar_hash[AVATAR_HASH_LENGTH]; 270 uint8_t avatar_hash[AVATAR_HASH_LENGTH];
@@ -509,7 +509,7 @@ uint8_t m_get_self_userstatus(const Messenger *m);
509 * Notice that the library treats the image as raw data and does not interpret it by any way. 509 * Notice that the library treats the image as raw data and does not interpret it by any way.
510 * 510 *
511 * Arguments: 511 * Arguments:
512 * format - Avatar image format or NONE for user with no avatar (see AVATARFORMAT); 512 * format - Avatar image format or NONE for user with no avatar (see AVATAR_FORMAT);
513 * data - pointer to the avatar data (may be NULL it the format is NONE); 513 * data - pointer to the avatar data (may be NULL it the format is NONE);
514 * length - length of image data. Must be <= MAX_AVATAR_DATA_LENGTH. 514 * length - length of image data. Must be <= MAX_AVATAR_DATA_LENGTH.
515 * 515 *
@@ -528,7 +528,7 @@ int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t len
528 * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored. 528 * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
529 * 529 *
530 * Arguments: 530 * Arguments:
531 * format - destination pointer to the avatar image format (see AVATARFORMAT); 531 * format - destination pointer to the avatar image format (see AVATAR_FORMAT);
532 * buf - destination buffer to the image data. Must have at least 'maxlen' bytes; 532 * buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
533 * length - destination pointer to the image data length; 533 * length - destination pointer to the image data length;
534 * maxlen - length of the destination buffer 'buf'; 534 * maxlen - length of the destination buffer 'buf';
@@ -541,8 +541,23 @@ int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t len
541int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, 541int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen,
542 uint8_t *hash); 542 uint8_t *hash);
543 543
544/* Generates a cryptographic hash of the given data.
545 * This function may be used by clients for any purpose, but is provided primarily for
546 * validating cached avatars.
547 * This function is a wrapper to internal message-digest functions.
548 *
549 * Arguments:
550 * hash - destination buffer for the hash data, it must be exactly crypto_hash_sha256_BYTES bytes long.
551 * data - data to be hashed;
552 * datalen - length of the data;
553 *
554 * returns 0 on success
555 * returns -1 on failure.
556 */
557int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen);
558
544/* Generates a cryptographic hash of the given avatar data. 559/* Generates a cryptographic hash of the given avatar data.
545 * This function is a wrapper to internal message-digest functions and specifically provided 560 * This function is a wrapper to m_hash and specifically provided
546 * to generate hashes from user avatars that may be memcmp()ed with the values returned by the 561 * to generate hashes from user avatars that may be memcmp()ed with the values returned by the
547 * other avatar functions. It is specially important to validate cached avatars. 562 * other avatar functions. It is specially important to validate cached avatars.
548 * 563 *
@@ -694,7 +709,7 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess
694 * Function format is: 709 * Function format is:
695 * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata) 710 * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata)
696 * 711 *
697 * where 'format' is the avatar image format (see AVATARFORMAT) and 'hash' is the hash of 712 * where 'format' is the avatar image format (see AVATAR_FORMAT) and 'hash' is the hash of
698 * the avatar data for caching purposes and it is exactly AVATAR_HASH_LENGTH long. If the 713 * the avatar data for caching purposes and it is exactly AVATAR_HASH_LENGTH long. If the
699 * image format is NONE, the hash is zeroed. 714 * image format is NONE, the hash is zeroed.
700 * 715 *
@@ -710,7 +725,7 @@ void m_callback_avatar_info(Messenger *m, void (*function)(Messenger *m, int32_t
710 * Function format is: 725 * Function format is:
711 * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata) 726 * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
712 * 727 *
713 * where 'format' is the avatar image format (see AVATARFORMAT); 'hash' is the 728 * where 'format' is the avatar image format (see AVATAR_FORMAT); 'hash' is the
714 * locally-calculated cryptographic hash of the avatar data and it is exactly 729 * locally-calculated cryptographic hash of the avatar data and it is exactly
715 * AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length 730 * AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
716 * of such data. 731 * of such data.
diff --git a/toxcore/tox.c b/toxcore/tox.c
index b44f0ee6..21854de4 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -826,9 +826,9 @@ int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t
826 return m_get_self_avatar(m, format, buf, length, maxlen, hash); 826 return m_get_self_avatar(m, format, buf, length, maxlen, hash);
827} 827}
828 828
829int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen) 829int tox_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen)
830{ 830{
831 return m_avatar_hash(hash, data, datalen); 831 return m_hash(hash, data, datalen);
832} 832}
833 833
834int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber) 834int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber)
diff --git a/toxcore/tox.h b/toxcore/tox.h
index a5efee34..d285e3fc 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -37,8 +37,8 @@ extern "C" {
37#define TOX_MAX_MESSAGE_LENGTH 1368 37#define TOX_MAX_MESSAGE_LENGTH 1368
38#define TOX_MAX_STATUSMESSAGE_LENGTH 1007 38#define TOX_MAX_STATUSMESSAGE_LENGTH 1007
39#define TOX_CLIENT_ID_SIZE 32 39#define TOX_CLIENT_ID_SIZE 32
40#define TOX_MAX_AVATAR_DATA_LENGTH 16384 40#define TOX_AVATAR_MAX_DATA_LENGTH 16384
41#define TOX_AVATAR_HASH_LENGTH 32 41#define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32
42 42
43#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) 43#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
44 44
@@ -73,14 +73,14 @@ typedef enum {
73TOX_USERSTATUS; 73TOX_USERSTATUS;
74 74
75 75
76/* AVATARFORMAT - 76/* AVATAR_FORMAT -
77 * Data formats for user avatar images 77 * Data formats for user avatar images
78 */ 78 */
79typedef enum { 79typedef enum {
80 TOX_AVATARFORMAT_NONE, 80 TOX_AVATAR_FORMAT_NONE = 0,
81 TOX_AVATARFORMAT_PNG 81 TOX_AVATAR_FORMAT_PNG
82} 82}
83TOX_AVATARFORMAT; 83TOX_AVATAR_FORMAT;
84 84
85#ifndef __TOX_DEFINED__ 85#ifndef __TOX_DEFINED__
86#define __TOX_DEFINED__ 86#define __TOX_DEFINED__
@@ -538,7 +538,7 @@ uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size);
538 * Function format is: 538 * Function format is:
539 * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata) 539 * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata)
540 * 540 *
541 * where 'format' is the avatar image format (see TOX_AVATARFORMAT) and 'hash' is the hash of 541 * where 'format' is the avatar image format (see TOX_AVATAR_FORMAT) and 'hash' is the hash of
542 * the avatar data for caching purposes and it is exactly TOX_AVATAR_HASH_LENGTH long. If the 542 * the avatar data for caching purposes and it is exactly TOX_AVATAR_HASH_LENGTH long. If the
543 * image format is NONE, the hash is zeroed. 543 * image format is NONE, the hash is zeroed.
544 * 544 *
@@ -554,7 +554,7 @@ void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint
554 * Function format is: 554 * Function format is:
555 * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata) 555 * function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
556 * 556 *
557 * where 'format' is the avatar image format (see TOX_AVATARFORMAT); 'hash' is the 557 * where 'format' is the avatar image format (see TOX_AVATAR_FORMAT); 'hash' is the
558 * locally-calculated cryptographic hash of the avatar data and it is exactly 558 * locally-calculated cryptographic hash of the avatar data and it is exactly
559 * TOX_AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length 559 * TOX_AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
560 * of such data. 560 * of such data.
@@ -577,9 +577,9 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint
577 * Notice that the library treats the image as raw data and does not interpret it by any way. 577 * Notice that the library treats the image as raw data and does not interpret it by any way.
578 * 578 *
579 * Arguments: 579 * Arguments:
580 * format - Avatar image format or NONE for user with no avatar (see TOX_AVATARFORMAT); 580 * format - Avatar image format or NONE for user with no avatar (see TOX_AVATAR_FORMAT);
581 * data - pointer to the avatar data (may be NULL it the format is NONE); 581 * data - pointer to the avatar data (may be NULL it the format is NONE);
582 * length - length of image data. Must be <= TOX_MAX_AVATAR_DATA_LENGTH. 582 * length - length of image data. Must be <= TOX_AVATAR_MAX_DATA_LENGTH.
583 * 583 *
584 * returns 0 on success 584 * returns 0 on success
585 * returns -1 on failure. 585 * returns -1 on failure.
@@ -597,7 +597,7 @@ int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t lengt
597 * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored. 597 * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
598 * 598 *
599 * Arguments: 599 * Arguments:
600 * format - destination pointer to the avatar image format (see TOX_AVATARFORMAT); 600 * format - destination pointer to the avatar image format (see TOX_AVATAR_FORMAT);
601 * buf - destination buffer to the image data. Must have at least 'maxlen' bytes; 601 * buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
602 * length - destination pointer to the image data length; 602 * length - destination pointer to the image data length;
603 * maxlen - length of the destination buffer 'buf'; 603 * maxlen - length of the destination buffer 'buf';
@@ -611,21 +611,21 @@ int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t
611 uint8_t *hash); 611 uint8_t *hash);
612 612
613 613
614/* Generates a cryptographic hash of the given avatar data. 614/* Generates a cryptographic hash of the given data.
615 * This function is a wrapper to internal message-digest functions and specifically provided 615 * This function may be used by clients for any purpose, but is provided primarily for
616 * to generate hashes from user avatars that may be memcmp()ed with the values returned by the 616 * validating cached avatars. This use is highly recommended to avoid unnecessary avatar
617 * other avatar functions. It is specially important to validate cached avatars. 617 * updates.
618 * This function is a wrapper to internal message-digest functions.
618 * 619 *
619 * Arguments: 620 * Arguments:
620 * hash - destination buffer for the hash data, it must be exactly TOX_AVATAR_HASH_LENGTH bytes long. 621 * hash - destination buffer for the hash data, it must be exactly TOX_HASH_LENGTH bytes long.
621 * data - avatar image data; 622 * data - data to be hashed;
622 * datalen - length of the avatar image data; it must be <= TOX_MAX_AVATAR_DATA_LENGTH. 623 * datalen - length of the data; for avatars, should be TOX_AVATAR_MAX_DATA_LENGTH
623 * 624 *
624 * returns 0 on success 625 * returns 0 on success
625 * returns -1 on failure. 626 * returns -1 on failure.
626 */ 627 */
627int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen); 628int tox_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen);
628
629 629
630/* Request avatar information from a friend. 630/* Request avatar information from a friend.
631 * Asks a friend to provide their avatar information (image format and hash). The friend may 631 * Asks a friend to provide their avatar information (image format and hash). The friend may