mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'master' of https://github.com/dubslow/toxcore
This commit is contained in:
commit
80fdfbad07
|
@ -127,16 +127,16 @@ complete API documentation is available in `tox.h`.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
#define TOX_MAX_AVATAR_DATA_LENGTH 16384
|
#define TOX_AVATAR_MAX_DATA_LENGTH 16384
|
||||||
#define TOX_AVATAR_HASH_LENGTH 32
|
#define TOX_AVATAR_HASH_LENGTH 32
|
||||||
|
|
||||||
|
|
||||||
/* Data formats for user avatar images */
|
/* Data formats for user avatar images */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TOX_AVATARFORMAT_NONE,
|
TOX_AVATAR_FORMAT_NONE,
|
||||||
TOX_AVATARFORMAT_PNG
|
TOX_AVATAR_FORMAT_PNG
|
||||||
}
|
}
|
||||||
TOX_AVATARFORMAT;
|
TOX_AVATAR_FORMAT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -287,11 +287,11 @@ functions. For a complete, working, example, see `testing/test_avatars.c`.
|
||||||
In this example `load_data_file` is just an hypothetical function that loads
|
In this example `load_data_file` is just an hypothetical function that loads
|
||||||
data from a file into the buffer and sets the length accordingly.
|
data from a file into the buffer and sets the length accordingly.
|
||||||
|
|
||||||
uint8_t buf[TOX_MAX_AVATAR_DATA_LENGTH];
|
uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH];
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
|
|
||||||
if (load_data_file("avatar.png", buf, &len) == 0)
|
if (load_data_file("avatar.png", buf, &len) == 0)
|
||||||
if (tox_set_avatar(tox, TOX_AVATARFORMAT_PNG, buf, len) != 0)
|
if (tox_set_avatar(tox, TOX_AVATAR_FORMAT_PNG, buf, len) != 0)
|
||||||
fprintf(stderr, "Failed to set avatar.\n");
|
fprintf(stderr, "Failed to set avatar.\n");
|
||||||
|
|
||||||
If the user is connected, this function will also notify all connected
|
If the user is connected, this function will also notify all connected
|
||||||
|
@ -306,9 +306,9 @@ notifications and unnecessary data transfers.
|
||||||
|
|
||||||
#### Removing the avatar from the current user
|
#### Removing the avatar from the current user
|
||||||
|
|
||||||
To remove an avatar, an application must set it to `TOX_AVATARFORMAT_NONE`.
|
To remove an avatar, an application must set it to `TOX_AVATAR_FORMAT_NONE`.
|
||||||
|
|
||||||
tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0);
|
tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
|
||||||
|
|
||||||
If the user is connected, this function will also notify all connected
|
If the user is connected, this function will also notify all connected
|
||||||
friends about the avatar change.
|
friends about the avatar change.
|
||||||
|
@ -362,7 +362,7 @@ checks the local avatar cache and emits an avatar data request if necessary:
|
||||||
{
|
{
|
||||||
printf("Receiving avatar information from friend %d. Format = %d\n",
|
printf("Receiving avatar information from friend %d. Format = %d\n",
|
||||||
friendnumber, format);
|
friendnumber, format);
|
||||||
if (format = TOX_AVATARFORMAT_NONE) {
|
if (format = TOX_AVATAR_FORMAT_NONE) {
|
||||||
/* User have no avatar or removed the avatar */
|
/* User have no avatar or removed the avatar */
|
||||||
delete_avatar_from_cache(tox, friendnumber);
|
delete_avatar_from_cache(tox, friendnumber);
|
||||||
} else {
|
} else {
|
||||||
|
@ -382,7 +382,7 @@ cache:
|
||||||
static void avatar_data_cb(Tox *tox, int32_t friendnumber, uint8_t format,
|
static void avatar_data_cb(Tox *tox, int32_t friendnumber, uint8_t format,
|
||||||
uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
|
uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
|
||||||
{
|
{
|
||||||
if (format = TOX_AVATARFORMAT_NONE) {
|
if (format = TOX_AVATAR_FORMAT_NONE) {
|
||||||
/* User have no avatar or removed the avatar */
|
/* User have no avatar or removed the avatar */
|
||||||
delete_avatar_from_cache(tox, friendnumber);
|
delete_avatar_from_cache(tox, friendnumber);
|
||||||
} else {
|
} else {
|
||||||
|
@ -453,8 +453,8 @@ the following structure:
|
||||||
|
|
||||||
Where 'format' is the image data format, one of the following:
|
Where 'format' is the image data format, one of the following:
|
||||||
|
|
||||||
0 = AVATARFORMAT_NONE (no avatar set)
|
0 = AVATAR_FORMAT_NONE (no avatar set)
|
||||||
1 = AVATARFORMAT_PNG
|
1 = AVATAR_FORMAT_PNG
|
||||||
|
|
||||||
and 'hash' is the SHA-256 message digest of the avatar data.
|
and 'hash' is the SHA-256 message digest of the avatar data.
|
||||||
|
|
||||||
|
@ -481,8 +481,8 @@ types.
|
||||||
return, which semantics are explained bellow. The following values are
|
return, which semantics are explained bellow. The following values are
|
||||||
defined:
|
defined:
|
||||||
|
|
||||||
0 = AVATARDATACONTROL_REQ
|
0 = AVATAR_DATACONTROL_REQ
|
||||||
1 = AVATARDATACONTROL_ERROR
|
1 = AVATAR_DATACONTROL_ERROR
|
||||||
|
|
||||||
|
|
||||||
- Packet `PACKET_ID_AVATAR_DATA_START` have the following format:
|
- Packet `PACKET_ID_AVATAR_DATA_START` have the following format:
|
||||||
|
@ -511,17 +511,17 @@ from a client "B":
|
||||||
- "A" must initialize its control structures and mark its data transfer
|
- "A" must initialize its control structures and mark its data transfer
|
||||||
as not yet started. Then it requests avatar data from "B" by sending a
|
as not yet started. Then it requests avatar data from "B" by sending a
|
||||||
packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to
|
packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to
|
||||||
`AVATARDATACONTROL_REQ`.
|
`AVATAR_DATACONTROL_REQ`.
|
||||||
|
|
||||||
- If "B" accepts this transfer, it answers by sending an
|
- If "B" accepts this transfer, it answers by sending an
|
||||||
`PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and
|
`PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and
|
||||||
'data_length' set to the respective values from the current avatar.
|
'data_length' set to the respective values from the current avatar.
|
||||||
If "B" have no avatar set, 'format' must be `AVATARFORMAT_NONE`, 'hash'
|
If "B" have no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash'
|
||||||
must be zeroed and 'data_length' must be zero.
|
must be zeroed and 'data_length' must be zero.
|
||||||
|
|
||||||
If "B" does not accept sending the avatar, it may send a packet
|
If "B" does not accept sending the avatar, it may send a packet
|
||||||
`PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
|
`PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
|
||||||
`AVATARDATACONTROL_ERROR` or simply ignore this request. "A" must cope
|
`AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope
|
||||||
with this.
|
with this.
|
||||||
|
|
||||||
If "B" have an avatar, it sends a variable number of
|
If "B" have an avatar, it sends a variable number of
|
||||||
|
@ -531,7 +531,7 @@ from a client "B":
|
||||||
- Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it
|
- Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it
|
||||||
has sent a data request to "B". If not, just ignores the packet.
|
has sent a data request to "B". If not, just ignores the packet.
|
||||||
|
|
||||||
If "A" really requested avatar data and the format is `AVATARFORMAT_NONE`,
|
If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`,
|
||||||
it triggers the avatar data callback, and clears all the temporary data,
|
it triggers the avatar data callback, and clears all the temporary data,
|
||||||
finishing the process. For other formats, "A" just waits for packets
|
finishing the process. For other formats, "A" just waits for packets
|
||||||
of type `PACKET_ID_AVATAR_DATA_PUSH`.
|
of type `PACKET_ID_AVATAR_DATA_PUSH`.
|
||||||
|
@ -541,9 +541,9 @@ from a client "B":
|
||||||
already received. If this conditions are valid, it checks if the total
|
already received. If this conditions are valid, it checks if the total
|
||||||
length of the data already stored in the receiving buffer plus the data
|
length of the data already stored in the receiving buffer plus the data
|
||||||
present in the push packet is still less or equal than
|
present in the push packet is still less or equal than
|
||||||
`TOX_MAX_AVATAR_DATA_LENGTH`. If invalid, it replies with a
|
`TOX_AVATAR_MAX_DATA_LENGTH`. If invalid, it replies with a
|
||||||
`PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
|
`PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
|
||||||
`AVATARDATACONTROL_ERROR`.
|
`AVATAR_DATACONTROL_ERROR`.
|
||||||
|
|
||||||
If valid, "A" updates the 'bytes_received' counter and concatenates the
|
If valid, "A" updates the 'bytes_received' counter and concatenates the
|
||||||
newly arrived data to the buffer.
|
newly arrived data to the buffer.
|
||||||
|
@ -566,7 +566,7 @@ from a client "B":
|
||||||
some transfer limit for the data it sends.
|
some transfer limit for the data it sends.
|
||||||
|
|
||||||
- Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op'
|
- Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op'
|
||||||
set to `AVATARDATACONTROL_ERROR` clears any existing control state and
|
set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and
|
||||||
finishes sending or receiving data.
|
finishes sending or receiving data.
|
||||||
|
|
||||||
|
|
||||||
|
@ -596,7 +596,7 @@ The present proposal mitigates this situation by:
|
||||||
same offset of the avatar again and again, the implementation limits
|
same offset of the avatar again and again, the implementation limits
|
||||||
the amount of data a single user can request for some time. For now,
|
the amount of data a single user can request for some time. For now,
|
||||||
the library will not allow an user to request more than
|
the library will not allow an user to request more than
|
||||||
`10*TOX_MAX_AVATAR_DATA_LENGTH` in less than 20 minutes;
|
`10*TOX_AVATAR_MAX_DATA_LENGTH` in less than 20 minutes;
|
||||||
|
|
||||||
- Making the requester responsible for storing partial data and state
|
- Making the requester responsible for storing partial data and state
|
||||||
information;
|
information;
|
||||||
|
|
|
@ -86,8 +86,8 @@ typedef struct {
|
||||||
|
|
||||||
static const def_avatar_name_t def_avatar_names[] = {
|
static const def_avatar_name_t def_avatar_names[] = {
|
||||||
/* In order of preference */
|
/* In order of preference */
|
||||||
{ TOX_AVATARFORMAT_PNG, "png", "avatar.png" },
|
{ TOX_AVATAR_FORMAT_PNG, "png", "avatar.png" },
|
||||||
{ TOX_AVATARFORMAT_NONE, NULL, NULL }, /* Must be the last one */
|
{ TOX_AVATAR_FORMAT_NONE, NULL, NULL }, /* Must be the last one */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ static char *get_avatar_suffix_from_format(uint8_t format)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; def_avatar_names[i].format != TOX_AVATARFORMAT_NONE; i++)
|
for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++)
|
||||||
if (def_avatar_names[i].format == format)
|
if (def_avatar_names[i].format == format)
|
||||||
return def_avatar_names[i].suffix;
|
return def_avatar_names[i].suffix;
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ static int load_avatar_data(char *fname, uint8_t *buf)
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
return -1; /* Error */
|
return -1; /* Error */
|
||||||
|
|
||||||
size_t n = fread(buf, 1, TOX_MAX_AVATAR_DATA_LENGTH, fp);
|
size_t n = fread(buf, 1, TOX_AVATAR_MAX_DATA_LENGTH, fp);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (ferror(fp) != 0 || n == 0)
|
if (ferror(fp) != 0 || n == 0)
|
||||||
|
@ -222,7 +222,7 @@ static int load_user_avatar(Tox *tox, char *base_dir, int friendnum,
|
||||||
}
|
}
|
||||||
|
|
||||||
*datalen = ret;
|
*datalen = ret;
|
||||||
tox_avatar_hash(tox, hash, data, *datalen);
|
tox_hash(tox, hash, data, *datalen);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum)
|
||||||
/* This iteration is dumb and inefficient */
|
/* This iteration is dumb and inefficient */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; def_avatar_names[i].format != TOX_AVATARFORMAT_NONE; i++) {
|
for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) {
|
||||||
int ret = make_avatar_file_name(path, sizeof(path), base_dir,
|
int ret = make_avatar_file_name(path, sizeof(path), base_dir,
|
||||||
def_avatar_names[i].format, addr);
|
def_avatar_names[i].format, addr);
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *
|
||||||
char *base_dir = (char *) ud;
|
char *base_dir = (char *) ud;
|
||||||
uint8_t addr[TOX_CLIENT_ID_SIZE];
|
uint8_t addr[TOX_CLIENT_ID_SIZE];
|
||||||
char addr_str[2 * TOX_CLIENT_ID_SIZE + 1];
|
char addr_str[2 * TOX_CLIENT_ID_SIZE + 1];
|
||||||
char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1];
|
char hash_str[2 * TOX_HASH_LENGTH + 1];
|
||||||
|
|
||||||
if (tox_get_client_id(tox, n, addr) == 0) {
|
if (tox_get_client_id(tox, n, addr) == 0) {
|
||||||
byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str);
|
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 *
|
||||||
printf("Receiving avatar information from friend number %u.\n", n);
|
printf("Receiving avatar information from friend number %u.\n", n);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str);
|
byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
|
||||||
DEBUG("format=%u, hash=%s", format, hash_str);
|
DEBUG("format=%u, hash=%s", format, hash_str);
|
||||||
|
|
||||||
if (format == TOX_AVATARFORMAT_NONE) {
|
if (format == TOX_AVATAR_FORMAT_NONE) {
|
||||||
printf(" -> User do not have an avatar.\n");
|
printf(" -> User do not have an avatar.\n");
|
||||||
/* User have no avatar anymore, delete it from our cache */
|
/* User have no avatar anymore, delete it from our cache */
|
||||||
delete_user_avatar(tox, base_dir, n);
|
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 *
|
||||||
* these events.
|
* these events.
|
||||||
*/
|
*/
|
||||||
uint32_t cur_av_len;
|
uint32_t cur_av_len;
|
||||||
uint8_t cur_av_data[TOX_MAX_AVATAR_DATA_LENGTH];
|
uint8_t cur_av_data[TOX_AVATAR_MAX_DATA_LENGTH];
|
||||||
uint8_t cur_av_hash[TOX_AVATAR_HASH_LENGTH];
|
uint8_t cur_av_hash[TOX_HASH_LENGTH];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = load_user_avatar(tox, base_dir, n, format, cur_av_hash, cur_av_data, &cur_av_len);
|
ret = load_user_avatar(tox, base_dir, n, format, cur_av_hash, cur_av_data, &cur_av_len);
|
||||||
|
|
||||||
if (ret != 0
|
if (ret != 0
|
||||||
&& memcpy(cur_av_hash, hash, TOX_AVATAR_HASH_LENGTH) != 0) {
|
&& memcpy(cur_av_hash, hash, TOX_HASH_LENGTH) != 0) {
|
||||||
printf(" -> Cached avatar is outdated. Requesting avatar data.\n");
|
printf(" -> Cached avatar is outdated. Requesting avatar data.\n");
|
||||||
tox_request_avatar_data(tox, n);
|
tox_request_avatar_data(tox, n);
|
||||||
} else {
|
} else {
|
||||||
|
@ -355,7 +355,7 @@ static void friend_avatar_data_cb(Tox *tox, int32_t n, uint8_t format,
|
||||||
char *base_dir = (char *) ud;
|
char *base_dir = (char *) ud;
|
||||||
uint8_t addr[TOX_CLIENT_ID_SIZE];
|
uint8_t addr[TOX_CLIENT_ID_SIZE];
|
||||||
char addr_str[2 * TOX_CLIENT_ID_SIZE + 1];
|
char addr_str[2 * TOX_CLIENT_ID_SIZE + 1];
|
||||||
char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1];
|
char hash_str[2 * TOX_HASH_LENGTH + 1];
|
||||||
|
|
||||||
if (tox_get_client_id(tox, n, addr) == 0) {
|
if (tox_get_client_id(tox, n, addr) == 0) {
|
||||||
byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str);
|
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,
|
||||||
printf("Receiving avatar data from friend number %u.\n", n);
|
printf("Receiving avatar data from friend number %u.\n", n);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str);
|
byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
|
||||||
DEBUG("format=%u, datalen=%d, hash=%s\n", format, datalen, hash_str);
|
DEBUG("format=%u, datalen=%d, hash=%s\n", format, datalen, hash_str);
|
||||||
|
|
||||||
delete_user_avatar(tox, base_dir, n);
|
delete_user_avatar(tox, base_dir, n);
|
||||||
|
|
||||||
if (format != TOX_AVATARFORMAT_NONE) {
|
if (format != TOX_AVATAR_FORMAT_NONE) {
|
||||||
int ret = save_user_avatar(tox, base_dir, n, format, data, datalen);
|
int ret = save_user_avatar(tox, base_dir, n, format, data, datalen);
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
@ -406,7 +406,7 @@ static void friend_msg_cb(Tox *tox, int n, const uint8_t *msg, uint16_t len, voi
|
||||||
set_avatar(tox, base_dir);
|
set_avatar(tox, base_dir);
|
||||||
reply_ptr = "Setting image avatar";
|
reply_ptr = "Setting image avatar";
|
||||||
} else if (strstr(msg_str, "!remove-avatar") != NULL) {
|
} else if (strstr(msg_str, "!remove-avatar") != NULL) {
|
||||||
int r = tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0);
|
int r = tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
|
||||||
DEBUG("tox_set_avatar returned %d", r);
|
DEBUG("tox_set_avatar returned %d", r);
|
||||||
reply_ptr = "Removing avatar";
|
reply_ptr = "Removing avatar";
|
||||||
}
|
}
|
||||||
|
@ -453,10 +453,10 @@ static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name
|
||||||
FILE *fp = fopen(path, "rb");
|
FILE *fp = fopen(path, "rb");
|
||||||
|
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
uint8_t buf[2 * TOX_MAX_AVATAR_DATA_LENGTH];
|
uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
|
||||||
int len = fread(buf, 1, sizeof(buf), fp);
|
int len = fread(buf, 1, sizeof(buf), fp);
|
||||||
|
|
||||||
if (len >= 0 && len <= TOX_MAX_AVATAR_DATA_LENGTH) {
|
if (len >= 0 && len <= TOX_AVATAR_MAX_DATA_LENGTH) {
|
||||||
int r = tox_set_avatar(tox, an->format, buf, len);
|
int r = tox_set_avatar(tox, an->format, buf, len);
|
||||||
DEBUG("%d bytes, tox_set_avatar returned=%d", len, r);
|
DEBUG("%d bytes, tox_set_avatar returned=%d", len, r);
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name
|
||||||
DEBUG("read error %d", len);
|
DEBUG("read error %d", len);
|
||||||
} else {
|
} else {
|
||||||
printf("Avatar file %s if too big (more than %d bytes)",
|
printf("Avatar file %s if too big (more than %d bytes)",
|
||||||
path, TOX_MAX_AVATAR_DATA_LENGTH);
|
path, TOX_AVATAR_MAX_DATA_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -486,8 +486,8 @@ static void set_avatar(Tox *tox, const char *base_dir)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (def_avatar_names[i].format == TOX_AVATARFORMAT_NONE) {
|
if (def_avatar_names[i].format == TOX_AVATAR_FORMAT_NONE) {
|
||||||
tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0);
|
tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
|
||||||
printf("No avatar file found, setting to NONE.\n");
|
printf("No avatar file found, setting to NONE.\n");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -504,15 +504,15 @@ static void set_avatar(Tox *tox, const char *base_dir)
|
||||||
static void print_avatar_info(Tox *tox)
|
static void print_avatar_info(Tox *tox)
|
||||||
{
|
{
|
||||||
uint8_t format;
|
uint8_t format;
|
||||||
uint8_t data[TOX_MAX_AVATAR_DATA_LENGTH];
|
uint8_t data[TOX_AVATAR_MAX_DATA_LENGTH];
|
||||||
uint8_t hash[TOX_AVATAR_HASH_LENGTH];
|
uint8_t hash[TOX_HASH_LENGTH];
|
||||||
uint32_t data_length;
|
uint32_t data_length;
|
||||||
char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1];
|
char hash_str[2 * TOX_HASH_LENGTH + 1];
|
||||||
|
|
||||||
int ret = tox_get_self_avatar(tox, &format, data, &data_length, sizeof(data), hash);
|
int ret = tox_get_self_avatar(tox, &format, data, &data_length, sizeof(data), hash);
|
||||||
DEBUG("tox_get_self_avatar returned %d", ret);
|
DEBUG("tox_get_self_avatar returned %d", ret);
|
||||||
DEBUG("format: %d, data_length: %d", format, data_length);
|
DEBUG("format: %d, data_length: %d", format, data_length);
|
||||||
byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str);
|
byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
|
||||||
DEBUG("hash: %s", hash_str);
|
DEBUG("hash: %s", hash_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -576,10 +576,10 @@ int m_set_userstatus(Messenger *m, uint8_t status)
|
||||||
|
|
||||||
int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length)
|
int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length)
|
||||||
{
|
{
|
||||||
if (length > MAX_AVATAR_DATA_LENGTH)
|
if (length > AVATAR_MAX_DATA_LENGTH)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (format == AVATARFORMAT_NONE) {
|
if (format == AVATAR_FORMAT_NONE) {
|
||||||
free(m->avatar_data);
|
free(m->avatar_data);
|
||||||
m->avatar_data = NULL;
|
m->avatar_data = NULL;
|
||||||
m->avatar_data_length = 0;
|
m->avatar_data_length = 0;
|
||||||
|
@ -632,15 +632,18 @@ int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
||||||
{
|
{
|
||||||
if (hash == NULL)
|
if (hash == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
crypto_hash_sha256(hash, data, datalen);
|
return crypto_hash_sha256(hash, data, datalen);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
||||||
|
{
|
||||||
|
return m_hash(hash, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
int m_request_avatar_info(const Messenger *m, const int32_t friendnumber)
|
int m_request_avatar_info(const Messenger *m, const int32_t friendnumber)
|
||||||
{
|
{
|
||||||
|
@ -673,10 +676,10 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
|
||||||
if (friend_not_valid(m, friendnumber))
|
if (friend_not_valid(m, friendnumber))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||||
|
|
||||||
if (avrd == NULL) {
|
if (avrd == NULL) {
|
||||||
avrd = calloc(sizeof(AVATARRECEIVEDATA), 1);
|
avrd = calloc(sizeof(AVATAR_RECEIVEDATA), 1);
|
||||||
|
|
||||||
if (avrd == NULL)
|
if (avrd == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -693,9 +696,9 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
|
||||||
avrd->started = 0;
|
avrd->started = 0;
|
||||||
avrd->bytes_received = 0;
|
avrd->bytes_received = 0;
|
||||||
avrd->total_length = 0;
|
avrd->total_length = 0;
|
||||||
avrd->format = AVATARFORMAT_NONE;
|
avrd->format = AVATAR_FORMAT_NONE;
|
||||||
|
|
||||||
return send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_REQ);
|
return send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_REQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2006,7 +2009,7 @@ Messenger *new_messenger(Messenger_Options *options)
|
||||||
m->net = new_networking(ip, TOX_PORT_DEFAULT);
|
m->net = new_networking(ip, TOX_PORT_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
m->avatar_format = AVATARFORMAT_NONE;
|
m->avatar_format = AVATAR_FORMAT_NONE;
|
||||||
m->avatar_data = NULL;
|
m->avatar_data = NULL;
|
||||||
|
|
||||||
if (m->net == NULL) {
|
if (m->net == NULL) {
|
||||||
|
@ -2159,17 +2162,17 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
||||||
LOGGER_DEBUG("Error: PACKET_ID_AVATAR_DATA_CONTROL with bad "
|
LOGGER_DEBUG("Error: PACKET_ID_AVATAR_DATA_CONTROL with bad "
|
||||||
"data_length = %u, friendnumber = %u",
|
"data_length = %u, friendnumber = %u",
|
||||||
data_length, friendnumber);
|
data_length, friendnumber);
|
||||||
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
|
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
|
||||||
return -1; /* Error */
|
return -1; /* Error */
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]);
|
LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]);
|
||||||
|
|
||||||
switch (data[0]) {
|
switch (data[0]) {
|
||||||
case AVATARDATACONTROL_REQ: {
|
case AVATAR_DATACONTROL_REQ: {
|
||||||
|
|
||||||
/* Check data transfer limits for this friend */
|
/* Check data transfer limits for this friend */
|
||||||
AVATARSENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data);
|
AVATAR_SENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data);
|
||||||
|
|
||||||
if (avsd->bytes_sent >= AVATAR_DATA_TRANSFER_LIMIT) {
|
if (avsd->bytes_sent >= AVATAR_DATA_TRANSFER_LIMIT) {
|
||||||
/* User reached data limit. Check timeout */
|
/* User reached data limit. Check timeout */
|
||||||
|
@ -2183,7 +2186,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
||||||
/* Friend still rate-limitted. Send an error and stops. */
|
/* Friend still rate-limitted. Send an error and stops. */
|
||||||
LOGGER_DEBUG("Avatar data transfer limit reached. "
|
LOGGER_DEBUG("Avatar data transfer limit reached. "
|
||||||
"friendnumber = %u", friendnumber);
|
"friendnumber = %u", friendnumber);
|
||||||
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
|
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2211,12 +2214,12 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
/* Something went wrong, try to signal the error so the friend
|
/* Something went wrong, try to signal the error so the friend
|
||||||
* can clear up the state. */
|
* can clear up the state. */
|
||||||
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
|
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User have no avatar data, nothing more to do. */
|
/* User have no avatar data, nothing more to do. */
|
||||||
if (m->avatar_format == AVATARFORMAT_NONE)
|
if (m->avatar_format == AVATAR_FORMAT_NONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Send the actual avatar data. */
|
/* Send the actual avatar data. */
|
||||||
|
@ -2241,7 +2244,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
||||||
LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, "
|
LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, "
|
||||||
"friendnumber = %u, offset = %u",
|
"friendnumber = %u, offset = %u",
|
||||||
ret, friendnumber, offset);
|
ret, friendnumber, offset);
|
||||||
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
|
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2249,7 +2252,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AVATARDATACONTROL_ERROR: {
|
case AVATAR_DATACONTROL_ERROR: {
|
||||||
if (m->friendlist[friendnumber].avatar_recv_data) {
|
if (m->friendlist[friendnumber].avatar_recv_data) {
|
||||||
/* We were receiving the data, sender detected an error
|
/* We were receiving the data, sender detected an error
|
||||||
(eg. changing avatar) and asked us to stop. */
|
(eg. changing avatar) and asked us to stop. */
|
||||||
|
@ -2276,7 +2279,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||||
|
|
||||||
if (avrd == NULL) {
|
if (avrd == NULL) {
|
||||||
LOGGER_DEBUG("Received an unrequested DATA_START, friendnumber = %u",
|
LOGGER_DEBUG("Received an unrequested DATA_START, friendnumber = %u",
|
||||||
|
@ -2307,7 +2310,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
|
||||||
friendnumber, avrd->format, avrd->total_length,
|
friendnumber, avrd->format, avrd->total_length,
|
||||||
avrd->bytes_received);
|
avrd->bytes_received);
|
||||||
|
|
||||||
if (avrd->total_length > MAX_AVATAR_DATA_LENGTH) {
|
if (avrd->total_length > AVATAR_MAX_DATA_LENGTH) {
|
||||||
/* Invalid data length. Stops. */
|
/* Invalid data length. Stops. */
|
||||||
LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, "
|
LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, "
|
||||||
"friendnumber = %u", friendnumber);
|
"friendnumber = %u", friendnumber);
|
||||||
|
@ -2317,7 +2320,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avrd->format == AVATARFORMAT_NONE || avrd->total_length == 0) {
|
if (avrd->format == AVATAR_FORMAT_NONE || avrd->total_length == 0) {
|
||||||
/* No real data to receive. Run callback function and finish. */
|
/* No real data to receive. Run callback function and finish. */
|
||||||
LOGGER_DEBUG("format == NONE, friendnumber = %u", friendnumber);
|
LOGGER_DEBUG("format == NONE, friendnumber = %u", friendnumber);
|
||||||
|
|
||||||
|
@ -2343,7 +2346,7 @@ static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber,
|
||||||
{
|
{
|
||||||
LOGGER_DEBUG("friendnumber = %u, data_length = %u", friendnumber, data_length);
|
LOGGER_DEBUG("friendnumber = %u, data_length = %u", friendnumber, data_length);
|
||||||
|
|
||||||
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||||
|
|
||||||
if (avrd == NULL) {
|
if (avrd == NULL) {
|
||||||
/* No active transfer. It must be an error or a malicious request,
|
/* 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,
|
||||||
uint32_t new_length = avrd->bytes_received + data_length;
|
uint32_t new_length = avrd->bytes_received + data_length;
|
||||||
|
|
||||||
if (new_length > avrd->total_length
|
if (new_length > avrd->total_length
|
||||||
|| new_length >= MAX_AVATAR_DATA_LENGTH) {
|
|| new_length >= AVATAR_MAX_DATA_LENGTH) {
|
||||||
/* Invalid data length due to error or malice. Stops. */
|
/* Invalid data length due to error or malice. Stops. */
|
||||||
LOGGER_DEBUG("Invalid data length. friendnumber = %u, "
|
LOGGER_DEBUG("Invalid data length. friendnumber = %u, "
|
||||||
"new_length = %u, avrd->total_length = %u",
|
"new_length = %u, avrd->total_length = %u",
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
#define MAX_NAME_LENGTH 128
|
#define MAX_NAME_LENGTH 128
|
||||||
/* TODO: this must depend on other variable. */
|
/* TODO: this must depend on other variable. */
|
||||||
#define MAX_STATUSMESSAGE_LENGTH 1007
|
#define MAX_STATUSMESSAGE_LENGTH 1007
|
||||||
#define MAX_AVATAR_DATA_LENGTH 16384
|
#define AVATAR_MAX_DATA_LENGTH 16384
|
||||||
#define AVATAR_HASH_LENGTH 32
|
#define AVATAR_HASH_LENGTH crypto_hash_sha256_BYTES
|
||||||
|
|
||||||
|
|
||||||
#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
|
#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
|
||||||
|
@ -121,7 +121,7 @@ enum {
|
||||||
#define AVATAR_DATA_MAX_CHUNK_SIZE (MAX_CRYPTO_DATA_SIZE-1)
|
#define AVATAR_DATA_MAX_CHUNK_SIZE (MAX_CRYPTO_DATA_SIZE-1)
|
||||||
|
|
||||||
/* Per-friend data limit for avatar data requests */
|
/* Per-friend data limit for avatar data requests */
|
||||||
#define AVATAR_DATA_TRANSFER_LIMIT (10*MAX_AVATAR_DATA_LENGTH)
|
#define AVATAR_DATA_TRANSFER_LIMIT (10*AVATAR_MAX_DATA_LENGTH)
|
||||||
#define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */
|
#define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,40 +137,40 @@ typedef enum {
|
||||||
}
|
}
|
||||||
USERSTATUS;
|
USERSTATUS;
|
||||||
|
|
||||||
/* AVATARFORMAT -
|
/* AVATAR_FORMAT -
|
||||||
* Data formats for user avatar images
|
* Data formats for user avatar images
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
AVATARFORMAT_NONE,
|
AVATAR_FORMAT_NONE = 0,
|
||||||
AVATARFORMAT_PNG
|
AVATAR_FORMAT_PNG
|
||||||
}
|
}
|
||||||
AVATARFORMAT;
|
AVATAR_FORMAT;
|
||||||
|
|
||||||
/* AVATARDATACONTROL
|
/* AVATAR_DATACONTROL
|
||||||
* To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL)
|
* To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL)
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
AVATARDATACONTROL_REQ,
|
AVATAR_DATACONTROL_REQ,
|
||||||
AVATARDATACONTROL_ERROR
|
AVATAR_DATACONTROL_ERROR
|
||||||
}
|
}
|
||||||
AVATARDATACONTROL;
|
AVATAR_DATACONTROL;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t started;
|
uint8_t started;
|
||||||
AVATARFORMAT format;
|
AVATAR_FORMAT format;
|
||||||
uint8_t hash[AVATAR_HASH_LENGTH];
|
uint8_t hash[AVATAR_HASH_LENGTH];
|
||||||
uint32_t total_length;
|
uint32_t total_length;
|
||||||
uint32_t bytes_received;
|
uint32_t bytes_received;
|
||||||
uint8_t data[MAX_AVATAR_DATA_LENGTH];
|
uint8_t data[AVATAR_MAX_DATA_LENGTH];
|
||||||
}
|
}
|
||||||
AVATARRECEIVEDATA;
|
AVATAR_RECEIVEDATA;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Fields only used to limit the network usage from a given friend */
|
/* Fields only used to limit the network usage from a given friend */
|
||||||
uint32_t bytes_sent; /* Total bytes send to this user */
|
uint32_t bytes_sent; /* Total bytes send to this user */
|
||||||
uint64_t last_reset; /* Time the data counter was last reset */
|
uint64_t last_reset; /* Time the data counter was last reset */
|
||||||
}
|
}
|
||||||
AVATARSENDDATA;
|
AVATAR_SENDDATA;
|
||||||
|
|
||||||
|
|
||||||
struct File_Transfers {
|
struct File_Transfers {
|
||||||
|
@ -230,8 +230,8 @@ typedef struct {
|
||||||
int invited_groups[MAX_INVITED_GROUPS];
|
int invited_groups[MAX_INVITED_GROUPS];
|
||||||
uint16_t invited_groups_num;
|
uint16_t invited_groups_num;
|
||||||
|
|
||||||
AVATARSENDDATA avatar_send_data;
|
AVATAR_SENDDATA avatar_send_data;
|
||||||
AVATARRECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend.
|
AVATAR_RECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend.
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int (*function)(void *object, const uint8_t *data, uint32_t len);
|
int (*function)(void *object, const uint8_t *data, uint32_t len);
|
||||||
|
@ -264,7 +264,7 @@ typedef struct Messenger {
|
||||||
|
|
||||||
USERSTATUS userstatus;
|
USERSTATUS userstatus;
|
||||||
|
|
||||||
AVATARFORMAT avatar_format;
|
AVATAR_FORMAT avatar_format;
|
||||||
uint8_t *avatar_data;
|
uint8_t *avatar_data;
|
||||||
uint32_t avatar_data_length;
|
uint32_t avatar_data_length;
|
||||||
uint8_t avatar_hash[AVATAR_HASH_LENGTH];
|
uint8_t avatar_hash[AVATAR_HASH_LENGTH];
|
||||||
|
@ -509,7 +509,7 @@ uint8_t m_get_self_userstatus(const Messenger *m);
|
||||||
* Notice that the library treats the image as raw data and does not interpret it by any way.
|
* Notice that the library treats the image as raw data and does not interpret it by any way.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* format - Avatar image format or NONE for user with no avatar (see AVATARFORMAT);
|
* format - Avatar image format or NONE for user with no avatar (see AVATAR_FORMAT);
|
||||||
* data - pointer to the avatar data (may be NULL it the format is NONE);
|
* data - pointer to the avatar data (may be NULL it the format is NONE);
|
||||||
* length - length of image data. Must be <= MAX_AVATAR_DATA_LENGTH.
|
* length - length of image data. Must be <= MAX_AVATAR_DATA_LENGTH.
|
||||||
*
|
*
|
||||||
|
@ -528,7 +528,7 @@ int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t len
|
||||||
* If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
|
* If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* format - destination pointer to the avatar image format (see AVATARFORMAT);
|
* format - destination pointer to the avatar image format (see AVATAR_FORMAT);
|
||||||
* buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
|
* buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
|
||||||
* length - destination pointer to the image data length;
|
* length - destination pointer to the image data length;
|
||||||
* maxlen - length of the destination buffer 'buf';
|
* 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
|
||||||
int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen,
|
int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen,
|
||||||
uint8_t *hash);
|
uint8_t *hash);
|
||||||
|
|
||||||
|
/* Generates a cryptographic hash of the given data.
|
||||||
|
* This function may be used by clients for any purpose, but is provided primarily for
|
||||||
|
* validating cached avatars.
|
||||||
|
* This function is a wrapper to internal message-digest functions.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* hash - destination buffer for the hash data, it must be exactly crypto_hash_sha256_BYTES bytes long.
|
||||||
|
* data - data to be hashed;
|
||||||
|
* datalen - length of the data;
|
||||||
|
*
|
||||||
|
* returns 0 on success
|
||||||
|
* returns -1 on failure.
|
||||||
|
*/
|
||||||
|
int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen);
|
||||||
|
|
||||||
/* Generates a cryptographic hash of the given avatar data.
|
/* Generates a cryptographic hash of the given avatar data.
|
||||||
* This function is a wrapper to internal message-digest functions and specifically provided
|
* This function is a wrapper to m_hash and specifically provided
|
||||||
* to generate hashes from user avatars that may be memcmp()ed with the values returned by the
|
* 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.
|
* other avatar functions. It is specially important to validate cached avatars.
|
||||||
*
|
*
|
||||||
|
@ -694,7 +709,7 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess
|
||||||
* Function format is:
|
* Function format is:
|
||||||
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata)
|
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata)
|
||||||
*
|
*
|
||||||
* where 'format' is the avatar image format (see AVATARFORMAT) and 'hash' is the hash of
|
* where 'format' is the avatar image format (see AVATAR_FORMAT) and 'hash' is the hash of
|
||||||
* the avatar data for caching purposes and it is exactly AVATAR_HASH_LENGTH long. If the
|
* the avatar data for caching purposes and it is exactly AVATAR_HASH_LENGTH long. If the
|
||||||
* image format is NONE, the hash is zeroed.
|
* image format is NONE, the hash is zeroed.
|
||||||
*
|
*
|
||||||
|
@ -710,7 +725,7 @@ void m_callback_avatar_info(Messenger *m, void (*function)(Messenger *m, int32_t
|
||||||
* Function format is:
|
* Function format is:
|
||||||
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
|
* 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 AVATARFORMAT); 'hash' is the
|
* where 'format' is the avatar image format (see AVATAR_FORMAT); 'hash' is the
|
||||||
* locally-calculated cryptographic hash of the avatar data and it is exactly
|
* locally-calculated cryptographic hash of the avatar data and it is exactly
|
||||||
* AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
|
* AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
|
||||||
* of such data.
|
* of such data.
|
||||||
|
|
|
@ -826,9 +826,9 @@ int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t
|
||||||
return m_get_self_avatar(m, format, buf, length, maxlen, hash);
|
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)
|
int tox_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
||||||
{
|
{
|
||||||
return m_avatar_hash(hash, data, datalen);
|
return m_hash(hash, data, datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber)
|
int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber)
|
||||||
|
|
|
@ -37,8 +37,8 @@ extern "C" {
|
||||||
#define TOX_MAX_MESSAGE_LENGTH 1368
|
#define TOX_MAX_MESSAGE_LENGTH 1368
|
||||||
#define TOX_MAX_STATUSMESSAGE_LENGTH 1007
|
#define TOX_MAX_STATUSMESSAGE_LENGTH 1007
|
||||||
#define TOX_CLIENT_ID_SIZE 32
|
#define TOX_CLIENT_ID_SIZE 32
|
||||||
#define TOX_MAX_AVATAR_DATA_LENGTH 16384
|
#define TOX_AVATAR_MAX_DATA_LENGTH 16384
|
||||||
#define TOX_AVATAR_HASH_LENGTH 32
|
#define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32
|
||||||
|
|
||||||
#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
|
#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
|
||||||
|
|
||||||
|
@ -73,14 +73,14 @@ typedef enum {
|
||||||
TOX_USERSTATUS;
|
TOX_USERSTATUS;
|
||||||
|
|
||||||
|
|
||||||
/* AVATARFORMAT -
|
/* AVATAR_FORMAT -
|
||||||
* Data formats for user avatar images
|
* Data formats for user avatar images
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TOX_AVATARFORMAT_NONE,
|
TOX_AVATAR_FORMAT_NONE = 0,
|
||||||
TOX_AVATARFORMAT_PNG
|
TOX_AVATAR_FORMAT_PNG
|
||||||
}
|
}
|
||||||
TOX_AVATARFORMAT;
|
TOX_AVATAR_FORMAT;
|
||||||
|
|
||||||
#ifndef __TOX_DEFINED__
|
#ifndef __TOX_DEFINED__
|
||||||
#define __TOX_DEFINED__
|
#define __TOX_DEFINED__
|
||||||
|
@ -538,7 +538,7 @@ uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size);
|
||||||
* Function format is:
|
* Function format is:
|
||||||
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata)
|
* 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
|
* where 'format' is the avatar image format (see TOX_AVATAR_FORMAT) and 'hash' is the hash of
|
||||||
* the avatar data for caching purposes and it is exactly TOX_AVATAR_HASH_LENGTH long. If the
|
* 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.
|
* image format is NONE, the hash is zeroed.
|
||||||
*
|
*
|
||||||
|
@ -554,7 +554,7 @@ void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint
|
||||||
* Function format is:
|
* Function format is:
|
||||||
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
|
* 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
|
* where 'format' is the avatar image format (see TOX_AVATAR_FORMAT); 'hash' is the
|
||||||
* locally-calculated cryptographic hash of the avatar data and it is exactly
|
* 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
|
* TOX_AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
|
||||||
* of such data.
|
* of such data.
|
||||||
|
@ -577,9 +577,9 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint
|
||||||
* Notice that the library treats the image as raw data and does not interpret it by any way.
|
* Notice that the library treats the image as raw data and does not interpret it by any way.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* format - Avatar image format or NONE for user with no avatar (see TOX_AVATARFORMAT);
|
* format - Avatar image format or NONE for user with no avatar (see TOX_AVATAR_FORMAT);
|
||||||
* data - pointer to the avatar data (may be NULL it the format is NONE);
|
* 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.
|
* length - length of image data. Must be <= TOX_AVATAR_MAX_DATA_LENGTH.
|
||||||
*
|
*
|
||||||
* returns 0 on success
|
* returns 0 on success
|
||||||
* returns -1 on failure.
|
* returns -1 on failure.
|
||||||
|
@ -597,7 +597,7 @@ int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t lengt
|
||||||
* If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
|
* If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* format - destination pointer to the avatar image format (see TOX_AVATARFORMAT);
|
* format - destination pointer to the avatar image format (see TOX_AVATAR_FORMAT);
|
||||||
* buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
|
* buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
|
||||||
* length - destination pointer to the image data length;
|
* length - destination pointer to the image data length;
|
||||||
* maxlen - length of the destination buffer 'buf';
|
* 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
|
||||||
uint8_t *hash);
|
uint8_t *hash);
|
||||||
|
|
||||||
|
|
||||||
/* Generates a cryptographic hash of the given avatar data.
|
/* Generates a cryptographic hash of the given data.
|
||||||
* This function is a wrapper to internal message-digest functions and specifically provided
|
* This function may be used by clients for any purpose, but is provided primarily for
|
||||||
* to generate hashes from user avatars that may be memcmp()ed with the values returned by the
|
* validating cached avatars. This use is highly recommended to avoid unnecessary avatar
|
||||||
* other avatar functions. It is specially important to validate cached avatars.
|
* updates.
|
||||||
|
* This function is a wrapper to internal message-digest functions.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* hash - destination buffer for the hash data, it must be exactly TOX_AVATAR_HASH_LENGTH bytes long.
|
* hash - destination buffer for the hash data, it must be exactly TOX_HASH_LENGTH bytes long.
|
||||||
* data - avatar image data;
|
* data - data to be hashed;
|
||||||
* datalen - length of the avatar image data; it must be <= TOX_MAX_AVATAR_DATA_LENGTH.
|
* datalen - length of the data; for avatars, should be TOX_AVATAR_MAX_DATA_LENGTH
|
||||||
*
|
*
|
||||||
* returns 0 on success
|
* returns 0 on success
|
||||||
* returns -1 on failure.
|
* returns -1 on failure.
|
||||||
*/
|
*/
|
||||||
int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen);
|
int tox_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen);
|
||||||
|
|
||||||
|
|
||||||
/* Request avatar information from a friend.
|
/* Request avatar information from a friend.
|
||||||
* Asks a friend to provide their avatar information (image format and hash). The friend may
|
* Asks a friend to provide their avatar information (image format and hash). The friend may
|
||||||
|
|
Loading…
Reference in New Issue
Block a user