From 90a63e8188aabde41beb60152b04d2cd4576c2ac Mon Sep 17 00:00:00 2001 From: iphydf Date: Fri, 13 Jul 2018 19:10:22 +0000 Subject: [PATCH] Add conference_by_uid and conference_get_uid functions. These are useful once we have persistent group chats, so clients can store data associated with this permanent group identifier. --- toxcore/group.c | 37 ++++++++++++++++++++++-- toxcore/group.h | 13 +++++++-- toxcore/tox.api.h | 57 +++++++++++++++++++++++++++++------- toxcore/tox.c | 25 ++++++++++++++++ toxcore/tox.h | 73 ++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 178 insertions(+), 27 deletions(-) diff --git a/toxcore/group.c b/toxcore/group.c index 3e0c1fd3c..2ee81de82 100644 --- a/toxcore/group.c +++ b/toxcore/group.c @@ -183,6 +183,17 @@ static int32_t get_group_num(const Group_Chats *g_c, const uint8_t *identifier) return -1; } +int32_t conference_by_uid(const Group_Chats *g_c, const uint8_t *uid) +{ + for (uint16_t i = 0; i < g_c->num_chats; ++i) { + if (crypto_memcmp(g_c->chats[i].identifier + 1, uid, GROUP_IDENTIFIER_LENGTH - 1) == 0) { + return i; + } + } + + return -1; +} + /* * check if peer with peer_number is in peer array. * @@ -942,7 +953,7 @@ int group_peernumber_is_ours(const Group_Chats *g_c, uint32_t groupnumber, int p */ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber) { - Group_c *g = get_group_c(g_c, groupnumber); + const Group_c *g = get_group_c(g_c, groupnumber); if (!g) { return -1; @@ -951,6 +962,26 @@ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber) return g->identifier[0]; } +/* Copies the unique id of group_chat[groupnumber] into uid. +* +* return false on failure. +* return true on success. +*/ +bool conference_get_uid(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *uid) +{ + const Group_c *g = get_group_c(g_c, groupnumber); + + if (!g) { + return false; + } + + if (uid != nullptr) { + memcpy(uid, g->identifier + 1, sizeof(g->identifier) - 1); + } + + return true; +} + /* Send a group packet to friendcon_id. * * return 1 on success @@ -2504,7 +2535,7 @@ void kill_groupchats(Group_Chats *g_c) * You should use this to determine how much memory to allocate * for copy_chatlist. */ -uint32_t count_chatlist(Group_Chats *g_c) +uint32_t count_chatlist(const Group_Chats *g_c) { uint32_t ret = 0; @@ -2522,7 +2553,7 @@ uint32_t count_chatlist(Group_Chats *g_c) * Otherwise, returns the number of elements copied. * If the array was too small, the contents * of out_list will be truncated to list_size. */ -uint32_t copy_chatlist(Group_Chats *g_c, uint32_t *out_list, uint32_t list_size) +uint32_t copy_chatlist(const Group_Chats *g_c, uint32_t *out_list, uint32_t list_size) { if (!out_list) { return 0; diff --git a/toxcore/group.h b/toxcore/group.h index b2a297f92..9b4541c47 100644 --- a/toxcore/group.h +++ b/toxcore/group.h @@ -331,14 +331,14 @@ int send_group_lossy_packet(const Group_Chats *g_c, uint32_t groupnumber, const * You should use this to determine how much memory to allocate * for copy_chatlist. */ -uint32_t count_chatlist(Group_Chats *g_c); +uint32_t count_chatlist(const Group_Chats *g_c); /* Copy a list of valid chat IDs into the array out_list. * If out_list is NULL, returns 0. * Otherwise, returns the number of elements copied. * If the array was too small, the contents * of out_list will be truncated to list_size. */ -uint32_t copy_chatlist(Group_Chats *g_c, uint32_t *out_list, uint32_t list_size); +uint32_t copy_chatlist(const Group_Chats *g_c, uint32_t *out_list, uint32_t list_size); /* return the type of groupchat (GROUPCHAT_TYPE_) that groupnumber is. * @@ -347,6 +347,15 @@ uint32_t copy_chatlist(Group_Chats *g_c, uint32_t *out_list, uint32_t list_size) */ int group_get_type(const Group_Chats *g_c, uint32_t groupnumber); +/* Copies the unique id of group_chat[groupnumber] into uid. +* +* return false on failure. +* return true on success. +*/ +bool conference_get_uid(const Group_Chats *g_c, uint32_t groupnumber, uint8_t *uid); + +int32_t conference_by_uid(const Group_Chats *g_c, const uint8_t *uid); + /* Send current name (set in messenger) to all online groups. */ void send_name_all_groups(Group_Chats *g_c); diff --git a/toxcore/tox.api.h b/toxcore/tox.api.h index f3286bc58..632d79c53 100644 --- a/toxcore/tox.api.h +++ b/toxcore/tox.api.h @@ -42,7 +42,8 @@ extern "C" { *****************************************************************************/ -/** \page core Public core API for Tox clients. +/** + * @page core Public core API for Tox clients. * * Every function that can fail takes a function-specific error code pointer * that can be used to diagnose problems with the Tox state or the function @@ -81,7 +82,8 @@ extern "C" { * part of the ABI. */ -/** \subsection events Events and callbacks +/** + * @subsection events Events and callbacks * * Events are handled by callbacks. One callback can be registered per event. * All events have a callback function type named `tox_{event}_cb` and a @@ -104,7 +106,8 @@ extern "C" { * their own user data pointer of their own type. */ -/** \subsection threading Threading implications +/** + * @subsection threading Threading implications * * It is possible to run multiple concurrent threads with a Tox instance for * each thread. It is also possible to run all Tox instances in the same thread. @@ -126,12 +129,12 @@ extern "C" { * * E.g. to get the current nickname, one would write * - * \code + * @code * size_t length = ${tox.self.name.size}(tox); * uint8_t *name = malloc(length); * if (!name) abort(); * ${tox.self.name.get}(tox, name); - * \endcode + * @endcode * * If any other thread calls ${tox.self.name.set} while this thread is allocating * memory, the length may have become invalid, and the call to @@ -240,6 +243,11 @@ const PUBLIC_KEY_SIZE = 32; */ const SECRET_KEY_SIZE = 32; +/** + * The size of a Tox Conference unique id in bytes. + */ +const CONFERENCE_UID_SIZE = 32; + /** * The size of the nospam in bytes when written in a Tox address. */ @@ -1078,7 +1086,7 @@ namespace friend { * @param message The message that will be sent along with the friend request. * @param length The length of the data byte array. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. */ uint32_t add( const uint8_t[ADDRESS_SIZE] address, @@ -1134,7 +1142,7 @@ namespace friend { * @param public_key A byte array of length $PUBLIC_KEY_SIZE containing the * Public Key (not the Address) of the friend to add. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. * @see $add for a more detailed description of friend numbers. */ uint32_t add_norequest(const uint8_t[PUBLIC_KEY_SIZE] public_key) @@ -1173,7 +1181,7 @@ namespace friend { /** * Return the friend number associated with that Public Key. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. * @param public_key A byte array containing the Public Key. */ const uint32_t by_public_key(const uint8_t[PUBLIC_KEY_SIZE] public_key) { @@ -1901,7 +1909,7 @@ namespace file { * * @return A file number used as an identifier in subsequent callbacks. This * number is per friend. File numbers are reused after a transfer terminates. - * On failure, this function returns UINT32_MAX. Any pattern in file numbers + * On failure, this function returns an unspecified value. Any pattern in file numbers * should not be relied on. */ uint32_t send(uint32_t friend_number, uint32_t kind, uint64_t file_size, @@ -2186,7 +2194,7 @@ namespace conference { * * This function creates a new text conference. * - * @return conference number on success, or UINT32_MAX on failure. + * @return conference number on success, or an unspecified value on failure. */ uint32_t new() { /** @@ -2301,7 +2309,7 @@ namespace conference { * @param cookie Received via the `${event invite}` event. * @param length The size of cookie. * - * @return conference number on success, UINT32_MAX on failure. + * @return conference number on success, an unspecified value on failure. */ uint32_t join(uint32_t friend_number, const uint8_t[length] cookie) { /** @@ -2453,6 +2461,32 @@ namespace conference { } } + /** + * Get the conference unique ID. + * + * If uid is NULL, this function has no effect. + * + * @param uid A memory region large enough to store $CONFERENCE_UID_SIZE bytes. + * + * @return true on success. + */ + const bool get_uid(uint32_t conference_number, uint8_t[CONFERENCE_UID_SIZE] uid); + + /** + * Return the conference number associated with the specified uid. + * + * @param uid A byte array containing the conference id ($CONFERENCE_UID_SIZE). + * + * @return the conference number on success, an unspecified value on failure. + */ + const uint32_t by_uid(const uint8_t[CONFERENCE_UID_SIZE] uid) { + NULL, + /** + * No conference with the given uid exists on the conference list. + */ + NOT_FOUND, + } + } @@ -2644,6 +2678,7 @@ typedef TOX_ERR_FILE_SEND_CHUNK Tox_Err_File_Send_Chunk; typedef TOX_ERR_CONFERENCE_NEW Tox_Err_Conference_New; typedef TOX_ERR_CONFERENCE_DELETE Tox_Err_Conference_Delete; typedef TOX_ERR_CONFERENCE_PEER_QUERY Tox_Err_Conference_Peer_Query; +typedef TOX_ERR_CONFERENCE_BY_UID Tox_Err_Conference_By_Uid; typedef TOX_ERR_CONFERENCE_INVITE Tox_Err_Conference_Invite; typedef TOX_ERR_CONFERENCE_JOIN Tox_Err_Conference_Join; typedef TOX_ERR_CONFERENCE_SEND_MESSAGE Tox_Err_Conference_Send_Message; diff --git a/toxcore/tox.c b/toxcore/tox.c index 4c764aeb7..cae2dcb36 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -1453,6 +1453,31 @@ Tox_Conference_Type tox_conference_get_type(const Tox *tox, uint32_t conference_ return (Tox_Conference_Type)ret; } +bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid /* TOX_CONFERENCE_ID_SIZE bytes */) +{ + const Messenger *m = tox; + return conference_get_uid((Group_Chats *)m->conferences_object, conference_number, uid); +} + +uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, Tox_Err_Conference_By_Uid *error) +{ + if (!uid) { + SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_NULL); + return UINT32_MAX; + } + + const Messenger *m = tox; + int32_t ret = conference_by_uid((Group_Chats *)m->conferences_object, uid); + + if (ret == -1) { + SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND); + return UINT32_MAX; + } + + SET_ERROR_PARAMETER(error, TOX_ERR_CONFERENCE_BY_UID_OK); + return ret; +} + static void set_custom_packet_error(int ret, Tox_Err_Friend_Custom_Packet *error) { switch (ret) { diff --git a/toxcore/tox.h b/toxcore/tox.h index a5e79d63f..6a4df16dc 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -41,7 +41,8 @@ extern "C" { -/** \page core Public core API for Tox clients. +/** + * @page core Public core API for Tox clients. * * Every function that can fail takes a function-specific error code pointer * that can be used to diagnose problems with the Tox state or the function @@ -79,7 +80,8 @@ extern "C" { * Integer constants and the memory layout of publicly exposed structs are not * part of the ABI. */ -/** \subsection events Events and callbacks +/** + * @subsection events Events and callbacks * * Events are handled by callbacks. One callback can be registered per event. * All events have a callback function type named `tox_{event}_cb` and a @@ -101,7 +103,8 @@ extern "C" { * receive that pointer as argument when they are called. They can each have * their own user data pointer of their own type. */ -/** \subsection threading Threading implications +/** + * @subsection threading Threading implications * * It is possible to run multiple concurrent threads with a Tox instance for * each thread. It is also possible to run all Tox instances in the same thread. @@ -123,12 +126,12 @@ extern "C" { * * E.g. to get the current nickname, one would write * - * \code + * @code * size_t length = tox_self_get_name_size(tox); * uint8_t *name = malloc(length); * if (!name) abort(); * tox_self_get_name(tox, name); - * \endcode + * @endcode * * If any other thread calls tox_self_set_name while this thread is allocating * memory, the length may have become invalid, and the call to @@ -245,6 +248,13 @@ uint32_t tox_public_key_size(void); uint32_t tox_secret_key_size(void); +/** + * The size of a Tox Conference unique id in bytes. + */ +#define TOX_CONFERENCE_UID_SIZE 32 + +uint32_t tox_conference_uid_size(void); + /** * The size of the nospam in bytes when written in a Tox address. */ @@ -1269,7 +1279,7 @@ typedef enum TOX_ERR_FRIEND_ADD { * @param message The message that will be sent along with the friend request. * @param length The length of the data byte array. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. */ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length, TOX_ERR_FRIEND_ADD *error); @@ -1289,7 +1299,7 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message * @param public_key A byte array of length TOX_PUBLIC_KEY_SIZE containing the * Public Key (not the Address) of the friend to add. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. * @see tox_friend_add for a more detailed description of friend numbers. */ uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error); @@ -1354,7 +1364,7 @@ typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY { /** * Return the friend number associated with that Public Key. * - * @return the friend number on success, UINT32_MAX on failure. + * @return the friend number on success, an unspecified value on failure. * @param public_key A byte array containing the Public Key. */ uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error); @@ -2172,7 +2182,7 @@ typedef enum TOX_ERR_FILE_SEND { * * @return A file number used as an identifier in subsequent callbacks. This * number is per friend. File numbers are reused after a transfer terminates. - * On failure, this function returns UINT32_MAX. Any pattern in file numbers + * On failure, this function returns an unspecified value. Any pattern in file numbers * should not be relied on. */ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id, @@ -2486,7 +2496,7 @@ typedef enum TOX_ERR_CONFERENCE_NEW { * * This function creates a new text conference. * - * @return conference number on success, or UINT32_MAX on failure. + * @return conference number on success, or an unspecified value on failure. */ uint32_t tox_conference_new(Tox *tox, TOX_ERR_CONFERENCE_NEW *error); @@ -2655,7 +2665,7 @@ typedef enum TOX_ERR_CONFERENCE_JOIN { * @param cookie Received via the `conference_invite` event. * @param length The size of cookie. * - * @return conference number on success, UINT32_MAX on failure. + * @return conference number on success, an unspecified value on failure. */ uint32_t tox_conference_join(Tox *tox, uint32_t friend_number, const uint8_t *cookie, size_t length, TOX_ERR_CONFERENCE_JOIN *error); @@ -2804,6 +2814,46 @@ typedef enum TOX_ERR_CONFERENCE_GET_TYPE { TOX_CONFERENCE_TYPE tox_conference_get_type(const Tox *tox, uint32_t conference_number, TOX_ERR_CONFERENCE_GET_TYPE *error); +/** + * Get the conference unique ID. + * + * If uid is NULL, this function has no effect. + * + * @param uid A memory region large enough to store TOX_CONFERENCE_UID_SIZE bytes. + * + * @return true on success. + */ +bool tox_conference_get_uid(const Tox *tox, uint32_t conference_number, uint8_t *uid); + +typedef enum TOX_ERR_CONFERENCE_BY_UID { + + /** + * The function returned successfully. + */ + TOX_ERR_CONFERENCE_BY_UID_OK, + + /** + * One of the arguments to the function was NULL when it was not expected. + */ + TOX_ERR_CONFERENCE_BY_UID_NULL, + + /** + * No conference with the given uid exists on the conference list. + */ + TOX_ERR_CONFERENCE_BY_UID_NOT_FOUND, + +} TOX_ERR_CONFERENCE_BY_UID; + + +/** + * Return the conference number associated with the specified uid. + * + * @param uid A byte array containing the conference id (TOX_CONFERENCE_UID_SIZE). + * + * @return the conference number on success, an unspecified value on failure. + */ +uint32_t tox_conference_by_uid(const Tox *tox, const uint8_t *uid, TOX_ERR_CONFERENCE_BY_UID *error); + /******************************************************************************* * @@ -3004,6 +3054,7 @@ typedef TOX_ERR_FILE_SEND_CHUNK Tox_Err_File_Send_Chunk; typedef TOX_ERR_CONFERENCE_NEW Tox_Err_Conference_New; typedef TOX_ERR_CONFERENCE_DELETE Tox_Err_Conference_Delete; typedef TOX_ERR_CONFERENCE_PEER_QUERY Tox_Err_Conference_Peer_Query; +typedef TOX_ERR_CONFERENCE_BY_UID Tox_Err_Conference_By_Uid; typedef TOX_ERR_CONFERENCE_INVITE Tox_Err_Conference_Invite; typedef TOX_ERR_CONFERENCE_JOIN Tox_Err_Conference_Join; typedef TOX_ERR_CONFERENCE_SEND_MESSAGE Tox_Err_Conference_Send_Message;