diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index c45debed47..92cbb1d36a 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -158,6 +158,15 @@ static int send_online_packet(Messenger *m, int32_t friendnumber) return 0; } + uint8_t buf[TOX_CAPABILITIES_SIZE + 1]; + buf[0] = PACKET_ID_ONLINE; + net_pack_u64(buf + 1, TOX_CAPABILITIES_CURRENT); + + if (write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, + m->friendlist[friendnumber].friendcon_id), buf, TOX_CAPABILITIES_SIZE + 1, 0) == -1) { + return -1; + } + uint8_t packet = PACKET_ID_ONLINE; return write_cryptpacket(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, m->friendlist[friendnumber].friendcon_id), &packet, sizeof(packet), 0) != -1; @@ -202,6 +211,7 @@ static int32_t init_new_friend(Messenger *m, const uint8_t *real_pk, uint8_t sta m->friendlist[i].userstatus = USERSTATUS_NONE; m->friendlist[i].is_typing = 0; m->friendlist[i].message_id = 0; + m->friendlist[i].toxcore_capabilities = TOX_CAPABILITY_BASIC; friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &m_handle_status, &m_handle_packet, &m_handle_lossy_packet, m, i); @@ -2157,6 +2167,19 @@ static int m_handle_status(void *object, int i, uint8_t status, void *userdata) return 0; } +/* get capabilities of friend's toxcore + * return TOX_CAPABILITY_BASIC on any error + */ +uint64_t m_get_friend_toxcore_capabilities(const Messenger *m, int32_t friendnumber) +{ + if (friend_not_valid(m, friendnumber)) { + return TOX_CAPABILITY_BASIC; + } + + // return toxcore_capabilities for friend, not matter if ONLINE or OFFLINE + return m->friendlist[friendnumber].toxcore_capabilities; +} + static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t len, void *userdata) { if (len == 0) { @@ -2169,9 +2192,17 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le uint32_t data_length = len - 1; if (m->friendlist[i].status != FRIEND_ONLINE) { - if (packet_id == PACKET_ID_ONLINE && len == 1) { - set_friend_status(m, i, FRIEND_ONLINE, userdata); - send_online_packet(m, i); + if (packet_id == PACKET_ID_ONLINE) { + if (data_length == TOX_CAPABILITIES_SIZE) { + uint64_t received_caps; + net_unpack_u64(data, &received_caps); + m->friendlist[i].toxcore_capabilities = received_caps; + } else if (data_length == 0) { + set_friend_status(m, i, FRIEND_ONLINE, userdata); + send_online_packet(m, i); + } else { + return -1; + } } else { return -1; } diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index cd872a2d24..8da0238722 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -64,6 +64,31 @@ typedef struct Messenger_Options { void *log_user_data; } Messenger_Options; +/* this means no special capabilities, in other words clients that are older + * and did not implement this feature yet + */ +#define TOX_CAPABILITY_BASIC 0 + +/* ATTENTION: if you are adding new flags in your fork or toxcore, + * or in c-toxcore master, + * please coordinate with us first! + * thank you, the Tox Devs. + */ +#define TOX_CAPABILITY_CAPABILITIES ((uint64_t)1) << 0 +/* add new flags/bits here */ + +/* if the TOX_CAPABILITY_NEXT_IMPLEMENTATION flag is set it means + * we are using a different system for indicating capabilities now, + * and TOX_CAPABILITIES_* should be ignored and just the new (not yet known) + * system should be used + */ +#define TOX_CAPABILITY_NEXT_IMPLEMENTATION ((uint64_t)1) << 63 + +/* hardcoded capabilities of this version/branch of toxcore */ +#define TOX_CAPABILITIES_CURRENT (uint64_t)(TOX_CAPABILITY_CAPABILITIES) +/* size of the FLAGS in bytes */ +#define TOX_CAPABILITIES_SIZE sizeof(uint64_t) + struct Receipts { uint32_t packet_num; @@ -228,6 +253,7 @@ typedef struct Friend { struct Receipts *receipts_start; struct Receipts *receipts_end; + uint64_t toxcore_capabilities; } Friend; struct Messenger { @@ -460,6 +486,11 @@ uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber); uint8_t m_get_self_userstatus(const Messenger *m); +/* get capabilities of friend's toxcore + * return TOX_CAPABILITY_BASIC on any error + */ +uint64_t m_get_friend_toxcore_capabilities(const Messenger *m, int32_t friendnumber); + /* returns timestamp of last time friendnumber was seen online or 0 if never seen. * if friendnumber is invalid this function will return UINT64_MAX. */