libgnunetchat

library for GNUnet Messenger
Log | Files | Refs | README | LICENSE

commit 5200796f0fe43ba498eaa7ea5c81e46cdc2d8116
parent 26be0917d6b987b4a344aa9cbae71a8c89822da2
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Mon, 21 Jun 2021 14:22:07 +0200

First refinements of the overall API

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>

Diffstat:
MMakefile | 1+
Minclude/gnunet_chat_lib.h | 53+++++++++++++++++++++++++----------------------------
Msrc/gnunet_chat_contact.c | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/gnunet_chat_contact.h | 13+++++++++----
Msrc/gnunet_chat_context.c | 25+++++++++++++++++++++++++
Msrc/gnunet_chat_context.h | 20++++++++++++++++++++
Msrc/gnunet_chat_file.c | 2+-
Msrc/gnunet_chat_group.c | 47+++++++++++++++++++++++++++++++++++------------
Msrc/gnunet_chat_group.h | 5++---
Msrc/gnunet_chat_handle.c | 80++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/gnunet_chat_handle.h | 37++++++++++++++++++++++++++++++++++---
Msrc/gnunet_chat_message.h | 1+
12 files changed, 292 insertions(+), 85 deletions(-)

diff --git a/Makefile b/Makefile @@ -6,6 +6,7 @@ INSTALL_DIR = /usr/local/ LIBRARY = libgnunetchat.so SOURCES = gnunet_chat_handle.c\ gnunet_chat_contact.c\ + gnunet_chat_file.c\ gnunet_chat_group.c\ gnunet_chat_context.c\ gnunet_chat_message.c diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h @@ -88,12 +88,24 @@ struct GNUNET_CHAT_File; * * @param cls * @param handle + * @param context + * @param reason + */ +typedef void +(*GNUNET_CHAT_WarningCallback) (void *cls, struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Context *context, int reason); + +/** + * TODO + * + * @param cls + * @param handle * @param contact * @return */ typedef int (*GNUNET_CHAT_ContactCallback) (void *cls, struct GNUNET_CHAT_Handle *handle, - const struct GNUNET_CHAT_Contact *contact); + struct GNUNET_CHAT_Contact *contact); /** * TODO @@ -105,7 +117,7 @@ typedef int */ typedef int (*GNUNET_CHAT_GroupCallback) (void *cls, struct GNUNET_CHAT_Handle *handle, - const struct GNUNET_CHAT_Group *group); + struct GNUNET_CHAT_Group *group); /** * TODO @@ -117,7 +129,7 @@ typedef int */ typedef int (*GNUNET_CHAT_GroupContactCallback) (void *cls, struct GNUNET_CHAT_Group *group, - const struct GNUNET_CHAT_Contact *contact); + struct GNUNET_CHAT_Contact *contact); /** * TODO @@ -129,7 +141,7 @@ typedef int */ typedef int (*GNUNET_CHAT_ContextMessageCallback) (void *cls, struct GNUNET_CHAT_Context *context, - const struct GNUNET_CHAT_Message *message); + struct GNUNET_CHAT_Message *message); /** * TODO @@ -141,24 +153,26 @@ typedef int * @return */ typedef int -(*GNUNET_CHAT_MessageReadReceiptCallback) (void *cls, const struct GNUNET_CHAT_Message *message, - const struct GNUNET_CHAT_Contact *contact, +(*GNUNET_CHAT_MessageReadReceiptCallback) (void *cls, struct GNUNET_CHAT_Message *message, + struct GNUNET_CHAT_Contact *contact, int read_receipt); typedef void -(*GNUNET_CHAT_MessageFileDownloadCallback) (void *cls, const struct GNUNET_CHAT_File *file); - +(*GNUNET_CHAT_MessageFileDownloadCallback) (void *cls, struct GNUNET_CHAT_File *file); /** * TODO * * @param cfg * @param name + * @param warn_cb + * @param warn_cls * @return */ struct GNUNET_CHAT_Handle* GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *name); + const char *name, + GNUNET_CHAT_WarningCallback warn_cb, void *warn_cls); /** * TODO @@ -226,7 +240,8 @@ GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle, * @return */ struct GNUNET_CHAT_Group * -GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle); +GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, + const char* topic); /** * TODO @@ -253,24 +268,6 @@ GNUNET_CHAT_contact_delete (struct GNUNET_CHAT_Contact *contact); /** * TODO * - * @param contact - */ -void -GNUNET_CHAT_contact_set_blocking (struct GNUNET_CHAT_Contact *contact, - int blocking); - -/** - * TODO - * - * @param contact - * @return - */ -int -GNUNET_CHAT_contact_is_blocking (const struct GNUNET_CHAT_Contact *contact); - -/** - * TODO - * * @param contact Contact * @param name Custom nick name */ diff --git a/src/gnunet_chat_contact.c b/src/gnunet_chat_contact.c @@ -27,15 +27,19 @@ #include "gnunet_chat_handle.h" struct GNUNET_CHAT_Contact* -contact_create (struct GNUNET_CHAT_Handle *handle) +contact_create (struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_MESSENGER_Contact *msg_contact) { struct GNUNET_CHAT_Contact* contact = GNUNET_new(struct GNUNET_CHAT_Contact); contact->handle = handle; - contact->context = context_create(handle, NULL); // TODO: check for existing context? + contact->context = context_create( + handle, + GNUNET_CHAT_CONTEXT_TYPE_CONTACT, + NULL + ); // TODO: check for existing context? - contact->contact = NULL; - contact->nick = NULL; + contact->contact = msg_contact; if (!contact->context) { @@ -78,8 +82,56 @@ contact_destroy (struct GNUNET_CHAT_Contact *contact) context_destroy(contact->context); skip_context: - if (contact->nick) - GNUNET_free(contact->nick); + GNUNET_free(contact); +} + +struct GNUNET_CHAT_SearchContact +{ + struct GNUNET_MESSENGER_Contact *contact; + const struct GNUNET_MESSENGER_Contact *msg_contact; +}; + +static int +contact_search (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + struct GNUNET_CHAT_Contact *contact = value; + struct GNUNET_CHAT_SearchContact *search = cls; + + if (contact->contact == search->msg_contact) + { + search->contact = contact; + return GNUNET_NO; + } + + return GNUNET_YES; +} + +int +contact_call (struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_MESSENGER_Contact *msg_contact, + GNUNET_CHAT_ContactCallback callback, + void *cls) +{ + struct GNUNET_CHAT_SearchContact search; + search.contact = NULL; + search.msg_contact = msg_contact; + + GNUNET_CONTAINER_multihashmap_iterate( + handle->contacts, + contact_search, + &search + ); + + if (search.contact) + return callback(cls, handle, search.contact); + + search.contact = contact_create(handle, msg_contact); + int result = callback(cls, handle, search.contact); + + // TODO: check if contact has private chat + + contact_destroy(search.contact); + return result; } int @@ -96,29 +148,14 @@ GNUNET_CHAT_contact_delete (struct GNUNET_CHAT_Contact *contact) } void -GNUNET_CHAT_contact_set_blocking (struct GNUNET_CHAT_Contact *contact, - int blocking) -{ - //TODO -} - -int -GNUNET_CHAT_contact_is_blocking (const struct GNUNET_CHAT_Contact *contact) -{ - return GNUNET_NO; -} - -void GNUNET_CHAT_contact_set_name (struct GNUNET_CHAT_Contact *contact, const char *name) { if (!contact) return; - if (contact->nick) - GNUNET_free(contact->nick); - - contact->nick = name? GNUNET_strdup(name) : NULL; + if (contact->context) + context_set_nick(contact->context, name); } const char* @@ -127,9 +164,15 @@ GNUNET_CHAT_contact_get_name (const struct GNUNET_CHAT_Contact *contact) if (!contact) return NULL; - if (contact->nick) - return contact->nick; + if (!contact->context) + goto skip_context; + + const char *nick = context_get_nick(contact->context); + if (nick) + return nick; + +skip_context: return GNUNET_MESSENGER_contact_get_name(contact->contact); } diff --git a/src/gnunet_chat_contact.h b/src/gnunet_chat_contact.h @@ -32,15 +32,20 @@ struct GNUNET_CHAT_Contact struct GNUNET_CHAT_Handle *handle; struct GNUNET_CHAT_Context *context; - struct GNUNET_MESSENGER_Contact *contact; - - char *nick; + const struct GNUNET_MESSENGER_Contact *contact; }; struct GNUNET_CHAT_Contact* -contact_create (struct GNUNET_CHAT_Handle *handle); +contact_create (struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_MESSENGER_Contact *msg_contact); void contact_destroy (struct GNUNET_CHAT_Contact *contact); +int +contact_call (struct GNUNET_CHAT_Handle *handle, + const struct GNUNET_MESSENGER_Contact *msg_contact, + GNUNET_CHAT_ContactCallback callback, + void *cls); + #endif /* GNUNET_CHAT_CONTACT_H_ */ diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c @@ -28,6 +28,7 @@ struct GNUNET_CHAT_Context* context_create (struct GNUNET_CHAT_Handle *handle, + enum GNUNET_CHAT_ContextType type, const struct GNUNET_HashCode *key) { struct GNUNET_MESSENGER_Handle *messenger = handle->handles.messenger; @@ -60,7 +61,9 @@ context_create (struct GNUNET_CHAT_Handle *handle, context->handle = handle; context->room = room; + context->type = type; GNUNET_memcpy(&(context->key), room_key, sizeof(_room_key)); + context->nick = NULL; return context; } @@ -71,12 +74,34 @@ context_destroy (struct GNUNET_CHAT_Context* context) GNUNET_free(context); } +enum GNUNET_CHAT_ContextType +context_get_type (struct GNUNET_CHAT_Context* context) +{ + return context->type; +} + const struct GNUNET_HashCode* context_get_key (struct GNUNET_CHAT_Context* context) { return &(context->key); } +const char* +context_get_nick (struct GNUNET_CHAT_Context* context) +{ + return context->nick; +} + +void +context_set_nick (struct GNUNET_CHAT_Context* context, + const char *nick) +{ + if (context->nick) + GNUNET_free(context->nick); + + context->nick = nick? GNUNET_strdup(nick) : NULL; +} + void GNUNET_CHAT_context_send_text (struct GNUNET_CHAT_Context *context, const char *text) diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h @@ -29,6 +29,13 @@ #include <gnunet/gnunet_messenger_service.h> #include <gnunet/gnunet_util_lib.h> +enum GNUNET_CHAT_ContextType +{ + GNUNET_CHAT_CONTEXT_TYPE_CONTACT = 1, + GNUNET_CHAT_CONTEXT_TYPE_GROUP = 2, + GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN = 0 +}; + struct GNUNET_CHAT_Handle; struct GNUNET_CHAT_Context @@ -36,17 +43,30 @@ struct GNUNET_CHAT_Context struct GNUNET_CHAT_Handle *handle; struct GNUNET_MESSENGER_Room *room; + enum GNUNET_CHAT_ContextType type; struct GNUNET_HashCode key; + char *nick; }; struct GNUNET_CHAT_Context* context_create (struct GNUNET_CHAT_Handle *handle, + enum GNUNET_CHAT_ContextType type, const struct GNUNET_HashCode *key); void context_destroy (struct GNUNET_CHAT_Context* context); +enum GNUNET_CHAT_ContextType +context_get_type (struct GNUNET_CHAT_Context* context); + const struct GNUNET_HashCode* context_get_key (struct GNUNET_CHAT_Context* context); +const char* +context_get_nick (struct GNUNET_CHAT_Context* context); + +void +context_set_nick (struct GNUNET_CHAT_Context* context, + const char *nick); + #endif /* GNUNET_CHAT_CONTEXT_H_ */ diff --git a/src/gnunet_chat_file.c b/src/gnunet_chat_file.c @@ -73,5 +73,5 @@ GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file) if (!file) return; - GNUNET_FS_download_stop(file, GNUNET_YES); + GNUNET_FS_download_stop(file->context, GNUNET_YES); } diff --git a/src/gnunet_chat_group.c b/src/gnunet_chat_group.c @@ -25,15 +25,26 @@ #include "gnunet_chat_lib.h" #include "gnunet_chat_group.h" #include "gnunet_chat_handle.h" +#include "gnunet_chat_contact.h" struct GNUNET_CHAT_Group* -group_create(struct GNUNET_CHAT_Handle *handle) +group_create(struct GNUNET_CHAT_Handle *handle, + const char *topic) { + struct GNUNET_HashCode topic_key; + + if (topic) { + GNUNET_CRYPTO_hash(topic, strlen(topic), &topic_key); + } + struct GNUNET_CHAT_Group *group = GNUNET_new(struct GNUNET_CHAT_Group); group->handle = handle; - group->context = context_create(handle, NULL); - group->name = NULL; + group->context = context_create( + handle, + GNUNET_CHAT_CONTEXT_TYPE_GROUP, + topic? &topic_key : NULL + ); if (!group->context) { @@ -76,9 +87,6 @@ group_destroy(struct GNUNET_CHAT_Group* group) context_destroy(group->context); skip_context: - if (group->name) - GNUNET_free(group->name); - GNUNET_free(group); } @@ -101,10 +109,8 @@ GNUNET_CHAT_group_set_name (struct GNUNET_CHAT_Group *group, if (!group) return; - if (group->name) - GNUNET_free(group->name); - - group->name = name? GNUNET_strdup(name) : NULL; + if (group->context) + context_set_nick(group->context, name); } const char* @@ -113,7 +119,10 @@ GNUNET_CHAT_group_get_name (const struct GNUNET_CHAT_Group *group) if (!group) return NULL; - return group->name; + if (!group->context) + return NULL; + + return context_get_nick(group->context); } void @@ -159,12 +168,26 @@ struct GNUNET_CHAT_GroupIterateContacts }; static int +group_call_member (void* cls, struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Contact *contact) +{ + struct GNUNET_CHAT_GroupIterateContacts *iterate = cls; + + return iterate->callback(iterate->cls, iterate->group, contact); +} + +static int group_iterate_members (void* cls, struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Contact *contact) { struct GNUNET_CHAT_GroupIterateContacts *iterate = cls; - return iterate->callback(iterate->cls, iterate->group, NULL); // TODO + return contact_call( + iterate->group->handle, + contact, + group_call_member, + iterate + ); } int diff --git a/src/gnunet_chat_group.h b/src/gnunet_chat_group.h @@ -31,12 +31,11 @@ struct GNUNET_CHAT_Group { struct GNUNET_CHAT_Handle *handle; struct GNUNET_CHAT_Context *context; - - char *name; }; struct GNUNET_CHAT_Group* -group_create(struct GNUNET_CHAT_Handle *handle); +group_create(struct GNUNET_CHAT_Handle *handle, + const char *topic); void group_destroy(struct GNUNET_CHAT_Group* group); diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c @@ -37,10 +37,11 @@ static void handle_arm_connection(void* cls, int connected) { } } - struct GNUNET_CHAT_Handle* GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle* cfg, - const char *name) { + const char *name, + GNUNET_CHAT_WarningCallback warn_cb, + void *warn_cls) { if (!cfg) return NULL; @@ -142,14 +143,14 @@ GNUNET_CHAT_set_name (struct GNUNET_CHAT_Handle *handle, if (!handle) return GNUNET_SYSERR; - return GNUNET_MESSENGER_set_name(handle, name); + return GNUNET_MESSENGER_set_name(handle->handles.messenger, name); } const char* GNUNET_CHAT_get_name (const struct GNUNET_CHAT_Handle *handle) { if (!handle) - return GNUNET_SYSERR; + return NULL; return GNUNET_MESSENGER_get_name(handle->handles.messenger); } @@ -158,26 +159,77 @@ const struct GNUNET_IDENTITY_PublicKey* GNUNET_CHAT_get_key (const struct GNUNET_CHAT_Handle *handle) { if (!handle) - return GNUNET_SYSERR; + return NULL; return GNUNET_MESSENGER_get_key(handle->handles.messenger); } +struct GNUNET_CHAT_IterateContacts +{ + struct GNUNET_CHAT_Handle *handle; + GNUNET_CHAT_ContactCallback callback; + void *cls; +}; + +static int +handle_iterate_contacts(void *cls, const struct GNUNET_HashCode *key, + void *value) +{ + struct GNUNET_CHAT_IterateContacts *iterate = cls; + struct GNUNET_CHAT_Contact *contact = value; + + if (!iterate->callback) + return GNUNET_YES; + + return iterate->callback(iterate->cls, iterate->handle, contact); +} + int GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle, GNUNET_CHAT_ContactCallback callback, void *cls) { - return GNUNET_SYSERR; + if (!handle) + return GNUNET_SYSERR; + + struct GNUNET_CHAT_IterateContacts iterate; + iterate.handle = handle; + iterate.callback = callback; + iterate.cls = cls; + + return GNUNET_CONTAINER_multihashmap_iterate(handle->contacts, + handle_iterate_contacts, + &iterate); } struct GNUNET_CHAT_Group* -GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle) +GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, + const char *topic) { if (!handle) return NULL; - return group_create(handle); + return group_create(handle, topic); +} + +struct GNUNET_CHAT_IterateGroups +{ + struct GNUNET_CHAT_Handle *handle; + GNUNET_CHAT_GroupCallback callback; + void *cls; +}; + +static int +handle_iterate_groups(void *cls, const struct GNUNET_HashCode *key, + void *value) +{ + struct GNUNET_CHAT_IterateGroups *iterate = cls; + struct GNUNET_CHAT_Group *group = value; + + if (!iterate->callback) + return GNUNET_YES; + + return iterate->callback(iterate->cls, iterate->handle, group); } int @@ -185,5 +237,15 @@ GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle, GNUNET_CHAT_GroupCallback callback, void *cls) { - return GNUNET_SYSERR; + if (!handle) + return GNUNET_SYSERR; + + struct GNUNET_CHAT_IterateGroups iterate; + iterate.handle = handle; + iterate.callback = callback; + iterate.cls = cls; + + return GNUNET_CONTAINER_multihashmap_iterate(handle->groups, + handle_iterate_contacts, + &iterate); } diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h @@ -30,8 +30,10 @@ #include <gnunet/gnunet_container_lib.h> #include <gnunet/gnunet_arm_service.h> #include <gnunet/gnunet_fs_service.h> +#include <gnunet/gnunet_gns_service.h> #include <gnunet/gnunet_identity_service.h> #include <gnunet/gnunet_messenger_service.h> +#include <gnunet/gnunet_reclaim_service.h> #include <gnunet/gnunet_regex_service.h> #include <gnunet/gnunet_util_lib.h> @@ -40,9 +42,38 @@ struct GNUNET_CHAT_Handle const struct GNUNET_CONFIGURATION_Handle* cfg; struct { - struct GNUNET_ARM_Handle* arm; - struct GNUNET_FS_Handle* fs; - struct GNUNET_MESSENGER_Handle* messenger; + /* + * feature: (automatically start required services) + */ + struct GNUNET_ARM_Handle *arm; + + /* + * required: (files can be uploaded/downloaded) + */ + struct GNUNET_FS_Handle *fs; + + /* + * required: (names can be resolved as well as zones and members) + */ + struct GNUNET_GNS_Handle *gns; + + /* + * optional: (if not anonymous to receive private key) + * (has to be reset as soon as the private key changes) + */ + struct GNUNET_IDENTITY_Handle *identity; + + /* + * required! + */ + struct GNUNET_MESSENGER_Handle *messenger; + + /* + * feature/optional: (maybe add new reclaim message kind?) + * (the message would automatically issue the ticket) + * (send the ticket and consume it) + */ + struct GNUNET_RECLAIM_Handle *reclaim; } handles; struct GNUNET_CONTAINER_MultiHashMap *contacts; diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h @@ -31,6 +31,7 @@ struct GNUNET_CHAT_Message { + struct GNUNET_HashCode hash; struct GNUNET_MESSENGER_Message *message; };