This commit is contained in:
irungentoo 2014-09-25 07:16:49 -04:00
commit 80fdfbad07
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
6 changed files with 133 additions and 115 deletions

View File

@ -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
/* Data formats for user avatar images */
typedef enum {
TOX_AVATARFORMAT_NONE,
TOX_AVATARFORMAT_PNG
TOX_AVATAR_FORMAT_NONE,
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
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;
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");
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
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
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",
friendnumber, format);
if (format = TOX_AVATARFORMAT_NONE) {
if (format = TOX_AVATAR_FORMAT_NONE) {
/* User have no avatar or removed the avatar */
delete_avatar_from_cache(tox, friendnumber);
} else {
@ -382,7 +382,7 @@ cache:
static void avatar_data_cb(Tox *tox, int32_t friendnumber, uint8_t format,
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 */
delete_avatar_from_cache(tox, friendnumber);
} else {
@ -453,8 +453,8 @@ the following structure:
Where 'format' is the image data format, one of the following:
0 = AVATARFORMAT_NONE (no avatar set)
1 = AVATARFORMAT_PNG
0 = AVATAR_FORMAT_NONE (no avatar set)
1 = AVATAR_FORMAT_PNG
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
defined:
0 = AVATARDATACONTROL_REQ
1 = AVATARDATACONTROL_ERROR
0 = AVATAR_DATACONTROL_REQ
1 = AVATAR_DATACONTROL_ERROR
- 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
as not yet started. Then it requests avatar data from "B" by sending a
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
`PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and
'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.
If "B" does not accept sending the avatar, it may send a packet
`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.
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
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,
finishing the process. For other formats, "A" just waits for packets
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
length of the data already stored in the receiving buffer plus the data
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
`AVATARDATACONTROL_ERROR`.
`AVATAR_DATACONTROL_ERROR`.
If valid, "A" updates the 'bytes_received' counter and concatenates the
newly arrived data to the buffer.
@ -566,7 +566,7 @@ from a client "B":
some transfer limit for the data it sends.
- 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.
@ -596,7 +596,7 @@ The present proposal mitigates this situation by:
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 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
information;

View File

@ -86,8 +86,8 @@ typedef struct {
static const def_avatar_name_t def_avatar_names[] = {
/* In order of preference */
{ TOX_AVATARFORMAT_PNG, "png", "avatar.png" },
{ TOX_AVATARFORMAT_NONE, NULL, NULL }, /* Must be the last one */
{ TOX_AVATAR_FORMAT_PNG, "png", "avatar.png" },
{ 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;
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)
return def_avatar_names[i].suffix;
@ -118,7 +118,7 @@ static int load_avatar_data(char *fname, uint8_t *buf)
if (fp == NULL)
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;
if (ferror(fp) != 0 || n == 0)
@ -222,7 +222,7 @@ static int load_user_avatar(Tox *tox, char *base_dir, int friendnum,
}
*datalen = ret;
tox_avatar_hash(tox, hash, data, *datalen);
tox_hash(tox, hash, data, *datalen);
return 0;
}
@ -267,7 +267,7 @@ static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum)
/* This iteration is dumb and inefficient */
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,
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;
uint8_t addr[TOX_CLIENT_ID_SIZE];
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) {
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);
}
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);
if (format == TOX_AVATARFORMAT_NONE) {
if (format == TOX_AVATAR_FORMAT_NONE) {
printf(" -> User do not have an avatar.\n");
/* User have no avatar anymore, delete it from our cache */
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.
*/
uint32_t cur_av_len;
uint8_t cur_av_data[TOX_MAX_AVATAR_DATA_LENGTH];
uint8_t cur_av_hash[TOX_AVATAR_HASH_LENGTH];
uint8_t cur_av_data[TOX_AVATAR_MAX_DATA_LENGTH];
uint8_t cur_av_hash[TOX_HASH_LENGTH];
int ret;
ret = load_user_avatar(tox, base_dir, n, format, cur_av_hash, cur_av_data, &cur_av_len);
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");
tox_request_avatar_data(tox, n);
} else {
@ -355,7 +355,7 @@ static void friend_avatar_data_cb(Tox *tox, int32_t n, uint8_t format,
char *base_dir = (char *) ud;
uint8_t addr[TOX_CLIENT_ID_SIZE];
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) {
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);
}
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);
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);
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);
reply_ptr = "Setting image avatar";
} 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);
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");
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);
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);
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);
} else {
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);
@ -486,8 +486,8 @@ static void set_avatar(Tox *tox, const char *base_dir)
int i;
for (i = 0; i < 4; i++) {
if (def_avatar_names[i].format == TOX_AVATARFORMAT_NONE) {
tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0);
if (def_avatar_names[i].format == TOX_AVATAR_FORMAT_NONE) {
tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
printf("No avatar file found, setting to NONE.\n");
return;
} else {
@ -504,15 +504,15 @@ static void set_avatar(Tox *tox, const char *base_dir)
static void print_avatar_info(Tox *tox)
{
uint8_t format;
uint8_t data[TOX_MAX_AVATAR_DATA_LENGTH];
uint8_t hash[TOX_AVATAR_HASH_LENGTH];
uint8_t data[TOX_AVATAR_MAX_DATA_LENGTH];
uint8_t hash[TOX_HASH_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);
DEBUG("tox_get_self_avatar returned %d", ret);
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);
}

View File

@ -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)
{
if (length > MAX_AVATAR_DATA_LENGTH)
if (length > AVATAR_MAX_DATA_LENGTH)
return -1;
if (format == AVATARFORMAT_NONE) {
if (format == AVATAR_FORMAT_NONE) {
free(m->avatar_data);
m->avatar_data = NULL;
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;
}
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)
return -1;
crypto_hash_sha256(hash, data, datalen);
return 0;
return crypto_hash_sha256(hash, data, datalen);
}
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)
{
@ -673,10 +676,10 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
if (friend_not_valid(m, friendnumber))
return -1;
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
if (avrd == NULL) {
avrd = calloc(sizeof(AVATARRECEIVEDATA), 1);
avrd = calloc(sizeof(AVATAR_RECEIVEDATA), 1);
if (avrd == NULL)
return -1;
@ -693,9 +696,9 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
avrd->started = 0;
avrd->bytes_received = 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->avatar_format = AVATARFORMAT_NONE;
m->avatar_format = AVATAR_FORMAT_NONE;
m->avatar_data = 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 "
"data_length = %u, friendnumber = %u",
data_length, friendnumber);
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
return -1; /* Error */
}
LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]);
switch (data[0]) {
case AVATARDATACONTROL_REQ: {
case AVATAR_DATACONTROL_REQ: {
/* 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) {
/* 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. */
LOGGER_DEBUG("Avatar data transfer limit reached. "
"friendnumber = %u", friendnumber);
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
return 0;
}
}
@ -2211,12 +2214,12 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
if (!ret) {
/* Something went wrong, try to signal the error so the friend
* can clear up the state. */
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
return 0;
}
/* User have no avatar data, nothing more to do. */
if (m->avatar_format == AVATARFORMAT_NONE)
if (m->avatar_format == AVATAR_FORMAT_NONE)
return 0;
/* 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, "
"friendnumber = %u, offset = %u",
ret, friendnumber, offset);
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
return -1;
}
}
@ -2249,7 +2252,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
return 0;
}
case AVATARDATACONTROL_ERROR: {
case AVATAR_DATACONTROL_ERROR: {
if (m->friendlist[friendnumber].avatar_recv_data) {
/* We were receiving the data, sender detected an error
(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;
}
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
if (avrd == NULL) {
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,
avrd->bytes_received);
if (avrd->total_length > MAX_AVATAR_DATA_LENGTH) {
if (avrd->total_length > AVATAR_MAX_DATA_LENGTH) {
/* Invalid data length. Stops. */
LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, "
"friendnumber = %u", friendnumber);
@ -2317,7 +2320,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
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. */
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);
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
if (avrd == NULL) {
/* 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;
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. */
LOGGER_DEBUG("Invalid data length. friendnumber = %u, "
"new_length = %u, avrd->total_length = %u",

View File

@ -36,8 +36,8 @@
#define MAX_NAME_LENGTH 128
/* TODO: this must depend on other variable. */
#define MAX_STATUSMESSAGE_LENGTH 1007
#define MAX_AVATAR_DATA_LENGTH 16384
#define AVATAR_HASH_LENGTH 32
#define AVATAR_MAX_DATA_LENGTH 16384
#define AVATAR_HASH_LENGTH crypto_hash_sha256_BYTES
#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)
/* 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 */
@ -137,40 +137,40 @@ typedef enum {
}
USERSTATUS;
/* AVATARFORMAT -
/* AVATAR_FORMAT -
* Data formats for user avatar images
*/
typedef enum {
AVATARFORMAT_NONE,
AVATARFORMAT_PNG
AVATAR_FORMAT_NONE = 0,
AVATAR_FORMAT_PNG
}
AVATARFORMAT;
AVATAR_FORMAT;
/* AVATARDATACONTROL
/* AVATAR_DATACONTROL
* To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL)
*/
typedef enum {
AVATARDATACONTROL_REQ,
AVATARDATACONTROL_ERROR
AVATAR_DATACONTROL_REQ,
AVATAR_DATACONTROL_ERROR
}
AVATARDATACONTROL;
AVATAR_DATACONTROL;
typedef struct {
uint8_t started;
AVATARFORMAT format;
AVATAR_FORMAT format;
uint8_t hash[AVATAR_HASH_LENGTH];
uint32_t total_length;
uint32_t bytes_received;
uint8_t data[MAX_AVATAR_DATA_LENGTH];
uint8_t data[AVATAR_MAX_DATA_LENGTH];
}
AVATARRECEIVEDATA;
AVATAR_RECEIVEDATA;
typedef struct {
/* Fields only used to limit the network usage from a given friend */
uint32_t bytes_sent; /* Total bytes send to this user */
uint64_t last_reset; /* Time the data counter was last reset */
}
AVATARSENDDATA;
AVATAR_SENDDATA;
struct File_Transfers {
@ -230,8 +230,8 @@ typedef struct {
int invited_groups[MAX_INVITED_GROUPS];
uint16_t invited_groups_num;
AVATARSENDDATA avatar_send_data;
AVATARRECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend.
AVATAR_SENDDATA avatar_send_data;
AVATAR_RECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend.
struct {
int (*function)(void *object, const uint8_t *data, uint32_t len);
@ -264,7 +264,7 @@ typedef struct Messenger {
USERSTATUS userstatus;
AVATARFORMAT avatar_format;
AVATAR_FORMAT avatar_format;
uint8_t *avatar_data;
uint32_t avatar_data_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.
*
* 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);
* 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.
*
* 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;
* length - destination pointer to the image data length;
* 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,
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.
* 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
* 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(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
* 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(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
* AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
* of such data.

View File

@ -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);
}
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)

View File

@ -37,8 +37,8 @@ extern "C" {
#define TOX_MAX_MESSAGE_LENGTH 1368
#define TOX_MAX_STATUSMESSAGE_LENGTH 1007
#define TOX_CLIENT_ID_SIZE 32
#define TOX_MAX_AVATAR_DATA_LENGTH 16384
#define TOX_AVATAR_HASH_LENGTH 32
#define TOX_AVATAR_MAX_DATA_LENGTH 16384
#define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32
#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
@ -73,14 +73,14 @@ typedef enum {
TOX_USERSTATUS;
/* AVATARFORMAT -
/* AVATAR_FORMAT -
* Data formats for user avatar images
*/
typedef enum {
TOX_AVATARFORMAT_NONE,
TOX_AVATARFORMAT_PNG
TOX_AVATAR_FORMAT_NONE = 0,
TOX_AVATAR_FORMAT_PNG
}
TOX_AVATARFORMAT;
TOX_AVATAR_FORMAT;
#ifndef __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(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
* 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(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
* TOX_AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
* 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.
*
* 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);
* 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 -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.
*
* 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;
* length - destination pointer to the image data length;
* 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);
/* Generates a cryptographic hash of the given avatar data.
* This function is a wrapper to internal message-digest functions and specifically provided
* to generate hashes from user avatars that may be memcmp()ed with the values returned by the
* other avatar functions. It is specially important to validate cached avatars.
/* 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 use is highly recommended to avoid unnecessary avatar
* updates.
* This function is a wrapper to internal message-digest functions.
*
* Arguments:
* hash - destination buffer for the hash data, it must be exactly TOX_AVATAR_HASH_LENGTH bytes long.
* data - avatar image data;
* datalen - length of the avatar image data; it must be <= TOX_MAX_AVATAR_DATA_LENGTH.
* hash - destination buffer for the hash data, it must be exactly TOX_HASH_LENGTH bytes long.
* data - data to be hashed;
* datalen - length of the data; for avatars, should be TOX_AVATAR_MAX_DATA_LENGTH
*
* returns 0 on success
* returns -1 on failure.
*/
int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen);
int tox_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen);
/* Request avatar information from a friend.
* Asks a friend to provide their avatar information (image format and hash). The friend may