commit b880617514f9e64e991cb8d6fcff74ce3f292e36
parent e366e189791025f7fad5572bc786f4883152812e
Author: TheJackiMonster <thejackimonster@gmail.com>
Date: Sun, 11 Jul 2021 02:33:00 +0200
Code reorganized and refactored, most features implemented
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat:
22 files changed, 1508 insertions(+), 1338 deletions(-)
diff --git a/Makefile b/Makefile
@@ -4,14 +4,17 @@ INCLUDE_DIR = include/
INSTALL_DIR = /usr/local/
LIBRARY = libgnunetchat.so
-SOURCES = gnunet_chat_handle.c\
- gnunet_chat_contact.c\
+SOURCES = gnunet_chat_lib.c\
+ gnunet_chat_config.c\
+ gnunet_chat_contact.c\
+ gnunet_chat_context.c\
gnunet_chat_file.c\
- gnunet_chat_invitation.c\
gnunet_chat_group.c\
- gnunet_chat_context.c\
+ gnunet_chat_handle.c\
+ gnunet_chat_invitation.c\
gnunet_chat_message.c\
- gnunet_chat_config.c
+ gnunet_chat_util.c
+
HEADERS = gnunet_chat_lib.h
LIBRARIES = gnunetarm\
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h
@@ -29,9 +29,8 @@
#ifndef GNUNET_CHAT_LIB_H_
#define GNUNET_CHAT_LIB_H_
-#define GNUNET_UNUSED __attribute__ ((unused))
-
#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_util_lib.h>
/**
@@ -442,29 +441,13 @@ GNUNET_CHAT_context_share_file (struct GNUNET_CHAT_Context *context,
* @param delay
*/
void
-GNUNET_CHAT_context_delete_message (struct GNUNET_CHAT_Context *context,
- const struct GNUNET_HashCode *hash,
+GNUNET_CHAT_context_delete_message (const struct GNUNET_CHAT_Message *message,
struct GNUNET_TIME_Relative delay);
/**
* TODO
*
* @param context
- * @param hash
- * @param callback
- * @param cls
- * @return
- */
-int
-GNUNET_CHAT_context_get_message (struct GNUNET_CHAT_Context *context,
- const struct GNUNET_HashCode *hash,
- GNUNET_CHAT_ContextMessageCallback callback,
- void *cls);
-
-/**
- * TODO
- *
- * @param context
* @param callback
* @param cls
* @return
@@ -615,12 +598,4 @@ GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file);
void
GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation);
-/**
- * TODO
- *
- * @param invitation
- */
-void
-GNUNET_CHAT_invitation_decline (struct GNUNET_CHAT_Invitation *invitation);
-
#endif /* GNUNET_CHAT_LIB_H_ */
diff --git a/src/gnunet_chat_contact.c b/src/gnunet_chat_contact.c
@@ -22,169 +22,26 @@
* @file gnunet_chat_contact.c
*/
-#include "gnunet_chat_lib.h"
#include "gnunet_chat_contact.h"
-#include "gnunet_chat_handle.h"
struct GNUNET_CHAT_Contact*
-contact_create (struct GNUNET_CHAT_Handle *handle,
- const struct GNUNET_MESSENGER_Contact *msg_contact)
+contact_create_from_member (struct GNUNET_CHAT_Handle *handle,
+ const struct GNUNET_MESSENGER_Contact *member)
{
struct GNUNET_CHAT_Contact* contact = GNUNET_new(struct GNUNET_CHAT_Contact);
contact->handle = handle;
- contact->context = context_create(
- handle,
- GNUNET_CHAT_CONTEXT_TYPE_CONTACT,
- NULL
- ); // TODO: check for existing context?
+ contact->context = NULL;
- contact->contact = msg_contact;
+ // TODO: search for private context? create private context?
- if (!contact->context)
- {
- contact_destroy (contact);
- return NULL;
- }
-
- const struct GNUNET_HashCode *key = context_get_key(contact->context);
-
- const int result = GNUNET_CONTAINER_multihashmap_put(
- handle->contacts,
- key,
- contact,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
- );
-
- if (GNUNET_OK != result) {
- contact_destroy (contact);
- return NULL;
- }
+ contact->member = member;
return contact;
}
void
-contact_destroy (struct GNUNET_CHAT_Contact *contact)
+contact_destroy (struct GNUNET_CHAT_Contact* contact)
{
- if (!contact->context)
- goto skip_context;
-
- struct GNUNET_CHAT_Handle *handle = contact->handle;
- const struct GNUNET_HashCode *key = context_get_key(contact->context);
-
- GNUNET_CONTAINER_multihashmap_remove(
- handle->contacts,
- key,
- contact
- );
-
- context_destroy(contact->context);
-
-skip_context:
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
-GNUNET_CHAT_contact_delete (struct GNUNET_CHAT_Contact *contact)
-{
- if (!contact)
- return GNUNET_SYSERR;
-
- if (GNUNET_YES != handle_update_chat_contact(contact->handle,
- contact, GNUNET_YES))
- return GNUNET_SYSERR;
-
- if (contact->context)
- GNUNET_MESSENGER_close_room(contact->context->room);
-
- contact_destroy(contact);
- return GNUNET_OK;
-}
-
-void
-GNUNET_CHAT_contact_set_name (struct GNUNET_CHAT_Contact *contact,
- const char *name)
-{
- if (!contact)
- return;
-
- if (contact->context)
- context_set_nick(contact->context, name);
-}
-
-const char*
-GNUNET_CHAT_contact_get_name (const struct GNUNET_CHAT_Contact *contact)
-{
- if (!contact)
- return NULL;
-
- 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);
-}
-
-struct GNUNET_CHAT_Context*
-GNUNET_CHAT_contact_get_context (struct GNUNET_CHAT_Contact *contact)
-{
- if (!contact)
- return NULL;
-
- return contact->context;
-}
diff --git a/src/gnunet_chat_contact.h b/src/gnunet_chat_contact.h
@@ -25,27 +25,27 @@
#ifndef GNUNET_CHAT_CONTACT_H_
#define GNUNET_CHAT_CONTACT_H_
-#include "gnunet_chat_context.h"
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_messenger_service.h>
+#include <gnunet/gnunet_util_lib.h>
+
+struct GNUNET_CHAT_Handle;
+struct GNUNET_CHAT_Context;
struct GNUNET_CHAT_Contact
{
struct GNUNET_CHAT_Handle *handle;
struct GNUNET_CHAT_Context *context;
- const struct GNUNET_MESSENGER_Contact *contact;
+ const struct GNUNET_MESSENGER_Contact *member;
};
struct GNUNET_CHAT_Contact*
-contact_create (struct GNUNET_CHAT_Handle *handle,
- const struct GNUNET_MESSENGER_Contact *msg_contact);
+contact_create_from_member (struct GNUNET_CHAT_Handle *handle,
+ const struct GNUNET_MESSENGER_Contact *member);
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);
+contact_destroy (struct GNUNET_CHAT_Contact* contact);
#endif /* GNUNET_CHAT_CONTACT_H_ */
diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c
@@ -22,171 +22,37 @@
* @file gnunet_chat_context.c
*/
-#include "gnunet_chat_lib.h"
#include "gnunet_chat_context.h"
-#include "gnunet_chat_handle.h"
struct GNUNET_CHAT_Context*
-context_create (struct GNUNET_CHAT_Handle *handle,
- enum GNUNET_CHAT_ContextType type,
- const struct GNUNET_HashCode *key)
+context_create_from_room (struct GNUNET_CHAT_Handle *handle,
+ struct GNUNET_MESSENGER_Room *room)
{
- struct GNUNET_MESSENGER_Handle *messenger = handle->handles.messenger;
-
- struct GNUNET_HashCode _room_key;
- const struct GNUNET_HashCode *room_key;
-
- if (key)
- room_key = key;
- else
- {
- GNUNET_CRYPTO_random_block(
- GNUNET_CRYPTO_QUALITY_WEAK,
- &_room_key,
- sizeof(_room_key)
- );
-
- room_key = &_room_key;
- }
-
- struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_open_room(
- messenger, room_key
- );
-
- if (!room)
- return NULL;
-
struct GNUNET_CHAT_Context* context = GNUNET_new(struct GNUNET_CHAT_Context);
context->handle = handle;
- context->room = room;
- context->type = type;
- GNUNET_memcpy(&(context->key), room_key, sizeof(_room_key));
+ context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN;
context->nick = NULL;
+ context->messages = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
+ context->invites = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
+ context->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
+
+ context->room = room;
+
return context;
}
void
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;
-}
+ GNUNET_CONTAINER_multihashmap_destroy(context->messages);
+ GNUNET_CONTAINER_multihashmap_destroy(context->invites);
+ GNUNET_CONTAINER_multihashmap_destroy(context->files);
-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)
-{
- if (!context)
- return;
-
- struct GNUNET_MESSENGER_Message message;
- message.header.kind = GNUNET_MESSENGER_KIND_TEXT;
- message.body.text.text = text;
-
- GNUNET_MESSENGER_send_message(context->room, &message, NULL);
-}
-
-void
-GNUNET_CHAT_context_send_file (struct GNUNET_CHAT_Context *context,
- const char *path)
-{
- //TODO: generate key, hash file, encrypt file, upload file, share uri & info
-}
-
-void
-GNUNET_CHAT_context_send_uri (struct GNUNET_CHAT_Context *context,
- const char *uri)
-{
- if (!context)
- return;
-
- struct GNUNET_MESSENGER_Message message;
- message.header.kind = GNUNET_MESSENGER_KIND_FILE;
-
- memset(&(message.body.file.key), 0, sizeof(message.body.file.key));
-
- message.body.file.hash; // TODO: download & hash
- GNUNET_memcpy(message.body.file.name, "", 1); // TODO: cut from uri or get from download?
- message.body.file.uri = uri;
-
- GNUNET_MESSENGER_send_message(context->room, &message, NULL);
-}
-
-void
-GNUNET_CHAT_context_share_file (struct GNUNET_CHAT_Context *context,
- const struct GNUNET_CHAT_File *file)
-{
- //TODO: send copied message basically
-}
-
-void
-GNUNET_CHAT_context_delete_message (struct GNUNET_CHAT_Context *context,
- const struct GNUNET_HashCode *hash,
- struct GNUNET_TIME_Relative delay)
-{
- if (!context)
- return;
-
- struct GNUNET_MESSENGER_Message message;
- message.header.kind = GNUNET_MESSENGER_KIND_TEXT;
- GNUNET_memcpy(&(message.body.delete.hash), hash, sizeof(*hash));
- message.body.delete.delay = GNUNET_TIME_relative_hton(delay);
-
- GNUNET_MESSENGER_send_message(context->room, &message, NULL);
-}
-
-int
-GNUNET_CHAT_context_get_message (struct GNUNET_CHAT_Context *context,
- const struct GNUNET_HashCode *hash,
- GNUNET_CHAT_ContextMessageCallback callback,
- void *cls)
-{
- if (!context)
- return GNUNET_SYSERR;
-
- struct GNUNET_MESSENGER_Message *message = GNUNET_MESSENGER_get_message(
- context->room, hash
- );
-
- //TODO: convert messenger-message to chat-message
-
- return GNUNET_OK;
-}
-
-int
-GNUNET_CHAT_context_iterate_messages (struct GNUNET_CHAT_Context *context,
- GNUNET_CHAT_ContextMessageCallback callback,
- void *cls)
-{
- return GNUNET_SYSERR;
+ GNUNET_free(context);
}
diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h
@@ -26,6 +26,8 @@
#define GNUNET_CHAT_CONTEXT_H_
#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_container_lib.h>
#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_util_lib.h>
@@ -41,32 +43,22 @@ struct GNUNET_CHAT_Handle;
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_CONTAINER_MultiHashMap *messages;
+ struct GNUNET_CONTAINER_MultiHashMap *invites;
+ struct GNUNET_CONTAINER_MultiHashMap *files;
+
+ struct GNUNET_MESSENGER_Room *room;
};
struct GNUNET_CHAT_Context*
-context_create (struct GNUNET_CHAT_Handle *handle,
- enum GNUNET_CHAT_ContextType type,
- const struct GNUNET_HashCode *key);
+context_create_from_room (struct GNUNET_CHAT_Handle *handle,
+ struct GNUNET_MESSENGER_Room *room);
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
@@ -22,81 +22,39 @@
* @file gnunet_chat_file.c
*/
-#include "gnunet_chat_lib.h"
#include "gnunet_chat_file.h"
-const struct GNUNET_HashCode*
-GNUNET_CHAT_file_get_hash (const struct GNUNET_CHAT_File *file)
-{
- return &(file->hash);
-}
+#include <limits.h>
-uint64_t
-GNUNET_CHAT_file_get_size (const struct GNUNET_CHAT_File *file)
+struct GNUNET_CHAT_File*
+file_create_from_message (struct GNUNET_CHAT_Handle *handle,
+ const struct GNUNET_MESSENGER_MessageFile* message)
{
- return 0;
-}
+ struct GNUNET_CHAT_File* file = GNUNET_new(struct GNUNET_CHAT_File);
-int
-GNUNET_CHAT_file_is_local (const struct GNUNET_CHAT_File *file)
-{
- return GNUNET_NO;
-}
+ file->handle = handle;
-int
-GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file,
- GNUNET_CHAT_MessageFileDownloadCallback callback,
- void *cls)
-{
- if (!file)
- return GNUNET_SYSERR;
+ file->name = GNUNET_strndup(message->name, NAME_MAX);
- struct GNUNET_FS_Handle *handle;
- const char *path = ""; // TODO: path = download_directory + filename
+ GNUNET_memcpy(&(file->key), &(message->key), sizeof(file->key));
+ GNUNET_memcpy(&(file->hash), &(message->hash), sizeof(file->hash));
- GNUNET_FS_download_start(
- handle,
- file->uri,
- NULL,
- path,
- NULL,
- 0,
- 0,
- 0,
- GNUNET_FS_DOWNLOAD_OPTION_NONE,
- NULL,
- NULL
- );
+ file->uri = GNUNET_FS_uri_parse(message->uri, NULL);
+ file->download = NULL;
+ file->publish = NULL;
+ file->unindex = NULL;
- return GNUNET_OK;
+ return file;
}
-int
-GNUNET_CHAT_file_pause_download (struct GNUNET_CHAT_File *file)
+void
+file_destroy (struct GNUNET_CHAT_File* file)
{
- if (!file)
- return GNUNET_SYSERR;
+ if (file->uri)
+ GNUNET_FS_uri_destroy(file->uri);
- GNUNET_FS_download_suspend(file->context);
- return GNUNET_OK;
-}
-
-int
-GNUNET_CHAT_file_resume_download (struct GNUNET_CHAT_File *file)
-{
- if (!file)
- return GNUNET_SYSERR;
-
- GNUNET_FS_download_resume(file->context);
- return GNUNET_OK;
-}
-
-int
-GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file)
-{
- if (!file)
- return GNUNET_SYSERR;
+ if (file->name)
+ GNUNET_free(file->name);
- GNUNET_FS_download_stop(file->context, GNUNET_YES);
- return GNUNET_OK;
+ GNUNET_free(file);
}
diff --git a/src/gnunet_chat_file.h b/src/gnunet_chat_file.h
@@ -26,15 +26,34 @@
#define GNUNET_CHAT_FILE_H_
#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_crypto_lib.h>
#include <gnunet/gnunet_fs_service.h>
#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_util_lib.h>
+struct GNUNET_CHAT_Handle;
+
struct GNUNET_CHAT_File
{
+ struct GNUNET_CHAT_Handle *handle;
+
+ char *name;
+
struct GNUNET_HashCode hash;
+ struct GNUNET_CRYPTO_SymmetricSessionKey key;
+
struct GNUNET_FS_Uri* uri;
- struct GNUNET_FS_DownloadContext* context;
+ struct GNUNET_FS_DownloadContext* download;
+ struct GNUNET_FS_PublishContext* publish;
+ struct GNUNET_FS_UnindexContext* unindex;
};
+struct GNUNET_CHAT_File*
+file_create_from_message (struct GNUNET_CHAT_Handle *handle,
+ const struct GNUNET_MESSENGER_MessageFile* message);
+
+void
+file_destroy (struct GNUNET_CHAT_File* file);
+
#endif /* GNUNET_CHAT_FILE_H_ */
diff --git a/src/gnunet_chat_group.c b/src/gnunet_chat_group.c
@@ -22,208 +22,53 @@
* @file gnunet_chat_group.c
*/
-#include "gnunet_chat_lib.h"
#include "gnunet_chat_group.h"
-#include "gnunet_chat_handle.h"
-#include "gnunet_chat_contact.h"
+
+#include "gnunet_chat_group_intern.c"
struct GNUNET_CHAT_Group*
-group_create(struct GNUNET_CHAT_Handle *handle,
- const char *topic)
+group_create_from_context (struct GNUNET_CHAT_Handle *handle,
+ struct GNUNET_CHAT_Context *context)
{
- 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);
+ struct GNUNET_CHAT_Group* group = GNUNET_new(struct GNUNET_CHAT_Group);
group->handle = handle;
- group->context = context_create(
- handle,
- GNUNET_CHAT_CONTEXT_TYPE_GROUP,
- topic? &topic_key : NULL
- );
+ group->context = context;
+
+ group->topic = NULL;
- group->is_public = topic? GNUNET_YES : GNUNET_NO;
group->announcement = NULL;
group->search = NULL;
- if (!group->context)
- {
- group_destroy (group);
- return NULL;
- }
-
- const struct GNUNET_HashCode *key = context_get_key(group->context);
-
- const int result = GNUNET_CONTAINER_multihashmap_put(
- handle->groups,
- key,
- group,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
- );
-
- if (GNUNET_OK != result) {
- group_destroy(group);
- return NULL;
- }
-
return group;
}
void
-group_destroy(struct GNUNET_CHAT_Group* group)
+group_destroy (struct GNUNET_CHAT_Group* group)
{
- if (!group->context)
- goto skip_context;
+ if (group->search)
+ GNUNET_REGEX_search_cancel(group->search);
- struct GNUNET_CHAT_Handle *handle = group->handle;
- const struct GNUNET_HashCode *key = context_get_key(group->context);
+ if (group->announcement)
+ GNUNET_REGEX_announce_cancel(group->announcement);
- GNUNET_CONTAINER_multihashmap_remove(
- handle->groups,
- key,
- group
- );
+ if (group->topic)
+ GNUNET_free(group->topic);
- context_destroy(group->context);
-
-skip_context:
GNUNET_free(group);
}
-int
-GNUNET_CHAT_group_leave (struct GNUNET_CHAT_Group *group)
-{
- if (!group)
- return GNUNET_SYSERR;
-
- if (GNUNET_YES != handle_update_chat_group(group->handle, group, GNUNET_YES))
- return GNUNET_SYSERR;
-
- if (group->context)
- GNUNET_MESSENGER_close_room(group->context->room);
-
- group_destroy(group);
- return GNUNET_OK;
-}
-
-void
-GNUNET_CHAT_group_set_name (struct GNUNET_CHAT_Group *group,
- const char *name)
-{
- if (!group)
- return;
-
- if (group->context)
- context_set_nick(group->context, name);
-}
-
-const char*
-GNUNET_CHAT_group_get_name (const struct GNUNET_CHAT_Group *group)
-{
- if (!group)
- return NULL;
-
- if (!group->context)
- return NULL;
-
- return context_get_nick(group->context);
-}
-
void
-GNUNET_CHAT_group_invite_contact (struct GNUNET_CHAT_Group *group,
- struct GNUNET_CHAT_Contact *contact)
+group_publish (struct GNUNET_CHAT_Group* group)
{
- if ((!group) || (!contact))
- return;
-
- struct GNUNET_CHAT_Context *context = GNUNET_CHAT_contact_get_context(contact);
-
- if (!context)
- return;
-
- struct GNUNET_MESSENGER_Handle *messenger = group->handle->handles.messenger;
- GNUNET_MESSENGER_open_room(messenger, context_get_key(group->context));
-
- struct GNUNET_MESSENGER_Message message;
- message.header.kind = GNUNET_MESSENGER_KIND_INVITE;
-
- int result = GNUNET_CRYPTO_get_peer_identity(
- group->handle->cfg,
- &(message.body.invite.door)
- );
-
- if (GNUNET_OK != result)
- return;
-
- GNUNET_memcpy(
- &(message.body.invite.key),
- context_get_key(group->context),
- sizeof(message.body.invite.key)
- );
-
- GNUNET_MESSENGER_send_message(context->room, &message, NULL);
-}
-
-struct GNUNET_CHAT_GroupIterateContacts
-{
- struct GNUNET_CHAT_Group *group;
- GNUNET_CHAT_GroupContactCallback callback;
- void *cls;
-};
-
-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 contact_call(
- iterate->group->handle,
- contact,
- group_call_member,
- iterate
+ group->announcement = GNUNET_REGEX_announce(
+ group->handle->cfg, group->topic, // TODO: raw topic?
+ GNUNET_TIME_relative_get_minute_(), // TODO: configure delay?
+ 1 // TODO: no compression?
);
-}
-
-int
-GNUNET_CHAT_group_iterate_contacts (struct GNUNET_CHAT_Group *group,
- GNUNET_CHAT_GroupContactCallback callback,
- void *cls)
-{
- if (!group)
- return GNUNET_SYSERR;
-
- if (!callback)
- return GNUNET_MESSENGER_iterate_members(group->context->room, NULL, cls);
- struct GNUNET_CHAT_GroupIterateContacts iterate;
- iterate.group = group;
- iterate.callback = callback;
- iterate.cls = cls;
-
- return GNUNET_MESSENGER_iterate_members(
- group->context->room, group_iterate_members, &iterate
+ group->search = GNUNET_REGEX_search(
+ group->handle->cfg, group->topic, // TODO: raw topic?
+ search_group_by_topic, group
);
}
-
-struct GNUNET_CHAT_Context*
-GNUNET_CHAT_group_get_context (struct GNUNET_CHAT_Group *group)
-{
- if (!group)
- return NULL;
-
- return group->context;
-}
diff --git a/src/gnunet_chat_group.h b/src/gnunet_chat_group.h
@@ -25,26 +25,33 @@
#ifndef GNUNET_CHAT_GROUP_H_
#define GNUNET_CHAT_GROUP_H_
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_regex_service.h>
+#include <gnunet/gnunet_util_lib.h>
-#include "gnunet_chat_context.h"
+struct GNUNET_CHAT_Handle;
+struct GNUNET_CHAT_Context;
struct GNUNET_CHAT_Group
{
struct GNUNET_CHAT_Handle *handle;
struct GNUNET_CHAT_Context *context;
- int is_public;
+ char *topic;
struct GNUNET_REGEX_Announcement *announcement;
struct GNUNET_REGEX_Search *search;
};
struct GNUNET_CHAT_Group*
-group_create(struct GNUNET_CHAT_Handle *handle,
- const char *topic);
+group_create_from_context (struct GNUNET_CHAT_Handle *handle,
+ struct GNUNET_CHAT_Context *context);
void
-group_destroy(struct GNUNET_CHAT_Group* group);
+group_destroy (struct GNUNET_CHAT_Group* group);
+
+void
+group_publish (struct GNUNET_CHAT_Group* group);
#endif /* GNUNET_CHAT_GROUP_H_ */
diff --git a/src/gnunet_chat_group_intern.c b/src/gnunet_chat_group_intern.c
@@ -0,0 +1,51 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file gnunet_chat_group_intern.c
+ */
+
+#include "gnunet_chat_context.h"
+#include "gnunet_chat_handle.h"
+
+#define GNUNET_UNUSED __attribute__ ((unused))
+
+void
+search_group_by_topic(void *cls,
+ const struct GNUNET_PeerIdentity *door,
+ GNUNET_UNUSED const struct GNUNET_PeerIdentity *get_path,
+ GNUNET_UNUSED unsigned int get_path_length,
+ GNUNET_UNUSED const struct GNUNET_PeerIdentity *put_path,
+ GNUNET_UNUSED unsigned int put_path_length)
+{
+ struct GNUNET_CHAT_Group *group = cls;
+
+ struct GNUNET_PeerIdentity peer;
+ GNUNET_CRYPTO_get_peer_identity(group->handle->cfg, &peer);
+
+ if (0 == GNUNET_memcmp(&peer, door))
+ return;
+
+ const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(
+ group->context->room
+ );
+
+ GNUNET_MESSENGER_enter_room(group->handle->messenger, door, key);
+}
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c
@@ -22,642 +22,73 @@
* @file gnunet_chat_handle.c
*/
-#include "gnunet_chat_lib.h"
#include "gnunet_chat_handle.h"
-#include "gnunet_chat_group.h"
-#include "gnunet_chat_contact.h"
-#include "gnunet_chat_message.h"
-#include "gnunet_chat_file.h"
-static void*
-handle_fs_progress(void* cls, const struct GNUNET_FS_ProgressInfo* info)
-{
- struct GNUNET_CHAT_Handle *chat = cls;
-
- if (!chat)
- return NULL;
-
- switch (info->status) {
- case GNUNET_FS_STATUS_PUBLISH_START: {
- /*publication_t* publication = (publication_t*) info->value.publish.cctx;
- publication->progress = 0.0f;
-
- GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication);
-
- return publication;*/
- } case GNUNET_FS_STATUS_PUBLISH_PROGRESS: {
- /*publication_t* publication = (publication_t*) info->value.publish.cctx;
- publication->progress = 1.0f * info->value.publish.completed / info->value.publish.size;
-
- GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication);
-
- return publication;*/
- } case GNUNET_FS_STATUS_PUBLISH_COMPLETED: {
- /*publication_t* publication = (publication_t*) info->value.publish.cctx;
- publication->uri = GNUNET_FS_uri_dup(info->value.publish.specifics.completed.chk_uri);
- publication->progress = 1.0f;
-
- GNUNET_SCHEDULER_add_now(&CGTK_publication_finish, publication);*/
- break;
- } case GNUNET_FS_STATUS_PUBLISH_ERROR: {
- /*publication_t* publication = (publication_t*) info->value.publish.cctx;
-
- GNUNET_SCHEDULER_add_now(&CGTK_publication_error, publication);*/
- break;
- } case GNUNET_FS_STATUS_DOWNLOAD_START: {
- /*request_t* request = (request_t*) info->value.download.cctx;
- request->progress = 0.0f;
-
- return request;*/
- } case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: {
- return info->value.download.cctx;
- } case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: {
- return info->value.download.cctx;
- } case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: {
- /*request_t* request = (request_t*) info->value.download.cctx;
- request->progress = 1.0f * info->value.download.completed / info->value.download.size;
-
- GNUNET_SCHEDULER_add_now(&CGTK_request_progress, request);
-
- return request;*/
- } case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: {
- /*request_t* request = (request_t*) info->value.download.cctx;
- request->progress = 1.0f;
-
- GNUNET_SCHEDULER_add_now(&CGTK_request_finish, request);*/
- break;
- } case GNUNET_FS_STATUS_DOWNLOAD_ERROR: {
- /*request_t *request = (request_t *) info->value.download.cctx;
-
- GNUNET_SCHEDULER_add_now(&CGTK_request_error, request);*/
- break;
- } case GNUNET_FS_STATUS_UNINDEX_START: {
- /*publication_t* publication = (publication_t*) info->value.unindex.cctx;
- publication->progress = 0.0f;
-
- return publication;*/
- } case GNUNET_FS_STATUS_UNINDEX_PROGRESS: {
- /*publication_t* publication = (publication_t*) info->value.unindex.cctx;
- publication->progress = 1.0f * info->value.unindex.completed / info->value.unindex.size;
-
- return publication;*/
- } case GNUNET_FS_STATUS_UNINDEX_COMPLETED: {
- /*publication_t* publication = (publication_t*) info->value.unindex.cctx;
- publication->progress = 1.0f;
-
- GNUNET_SCHEDULER_add_now(&CGTK_publication_unindex_finish, publication);*/
- break;
- } default: {
- break;
- }
- }
-
- return NULL;
-}
-
-static void
-handle_on_message (void *cls,
- GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room,
- GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *sender,
- const struct GNUNET_MESSENGER_Message *message,
- const struct GNUNET_HashCode *hash,
- GNUNET_UNUSED enum GNUNET_MESSENGER_MessageFlags flags)
-{
- struct GNUNET_CHAT_Handle *chat = cls;
-
- //TODO
-
- struct GNUNET_CHAT_Message msg;
- GNUNET_memcpy(&(msg.hash), hash, sizeof(msg.hash));
- msg.message = message;
-
- if ((GNUNET_CHAT_KIND_UNKNOWN == GNUNET_CHAT_message_get_kind(&msg)) ||
- (!chat->msg_cb))
- return;
-
- chat->msg_cb(chat->msg_cls, NULL /* TODO */, &msg);
-}
-
-struct GNUNET_CHAT_CheckRoomMembers
-{
- const struct GNUNET_IDENTITY_PublicKey *ignore_key;
- const struct GNUNET_MESSENGER_Contact *contact;
-};
-
-static int
-handle_check_room_members (void* cls,
- GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room,
- const struct GNUNET_MESSENGER_Contact *contact)
-{
- struct GNUNET_CHAT_CheckRoomMembers *check = cls;
- const struct GNUNET_IDENTITY_PublicKey *contact_key = (
- GNUNET_MESSENGER_contact_get_key(contact)
- );
-
- if (0 == GNUNET_memcmp(contact_key, check->ignore_key))
- return GNUNET_YES;
-
- if (check->contact)
- return GNUNET_NO;
-
- check->contact = contact;
- return GNUNET_YES;
-}
-
-static int
-handle_initialize_context (void *cls, struct GNUNET_MESSENGER_Room *room,
- GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *contact)
-{
- struct GNUNET_CHAT_Handle *chat = cls;
-
- struct GNUNET_CHAT_CheckRoomMembers check;
- check.ignore_key = GNUNET_CHAT_get_key(chat);
- check.contact = NULL;
-
- const int amount = GNUNET_MESSENGER_iterate_members(
- room, handle_check_room_members, &check
- );
-
- if (amount <= 1)
- return GNUNET_YES;
-
- const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room);
- struct GNUNET_CHAT_Context *context = handle_get_chat_context(chat, key);
- enum GNUNET_CHAT_ContextType type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN;
-
- if (check.contact)
- type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
- else
- type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
-
- if (!context)
- context = context_create(chat, type, key);
- else
- context->type = type;
-
- if (GNUNET_YES != handle_update_chat_context(chat, context, GNUNET_NO))
- context_destroy(context);
-
- return GNUNET_YES;
-}
-
-static void
-handle_on_identity(void *cls, struct GNUNET_MESSENGER_Handle *handle)
-{
- struct GNUNET_CHAT_Handle *chat = cls;
-
- //TODO
-
- GNUNET_MESSENGER_find_rooms(
- chat->handles.messenger, NULL, handle_initialize_context, handle
- );
-}
-
-static void
-handle_arm_connection(void *cls, int connected)
-{
- struct GNUNET_CHAT_Handle *chat = cls;
-
- if (GNUNET_YES == connected) {
- GNUNET_ARM_request_service_start(chat->handles.arm, "messenger",
- GNUNET_OS_INHERIT_STD_NONE, NULL, NULL);
- GNUNET_ARM_request_service_start(chat->handles.arm, "fs",
- GNUNET_OS_INHERIT_STD_NONE, NULL, NULL);
- } else {
- GNUNET_ARM_request_service_start(chat->handles.arm, "arm",
- GNUNET_OS_INHERIT_STD_NONE, NULL, NULL);
- }
-}
+#include "gnunet_chat_handle_intern.c"
struct GNUNET_CHAT_Handle*
-GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle* cfg,
- const char *name,
- GNUNET_CHAT_WarningCallback warn_cb,
- void *warn_cls,
- GNUNET_CHAT_ContextMessageCallback msg_cb,
- void *msg_cls)
+handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
+ const char* name,
+ GNUNET_CHAT_ContextMessageCallback msg_cb,
+ void *msg_cls,
+ GNUNET_CHAT_WarningCallback warn_cb,
+ void *warn_cls)
{
- if (!cfg)
- return NULL;
+ struct GNUNET_CHAT_Handle* handle = GNUNET_new(struct GNUNET_CHAT_Handle);
- struct GNUNET_CHAT_Handle *chat = GNUNET_new(struct GNUNET_CHAT_Handle);
- memset(chat, 0, sizeof(*chat));
- chat->cfg = cfg;
+ handle->cfg = cfg;
- chat->warn_cb = warn_cb;
- chat->warn_cls = warn_cls;
+ handle->msg_cb = msg_cb;
+ handle->msg_cls = msg_cls;
- chat->handles.arm = GNUNET_ARM_connect(cfg, &handle_arm_connection, chat);
+ handle->warn_cb = warn_cb;
+ handle->warn_cls = warn_cls;
- if (chat->handles.arm)
- handle_arm_connection(chat, GNUNET_NO);
+ handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
+ handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
+ handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO);
+ handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
- chat->handles.messenger = GNUNET_MESSENGER_connect(
- cfg, name,
- handle_on_identity, chat,
- handle_on_message, chat
+ handle->arm = GNUNET_ARM_connect(
+ handle->cfg,
+ on_handle_arm_connection, handle
);
- if (!chat->handles.messenger)
- {
- GNUNET_CHAT_stop(chat);
- return NULL;
- }
+ if (handle->arm)
+ on_handle_arm_connection(handle, GNUNET_NO);
- chat->handles.fs = GNUNET_FS_start(
- cfg,
- name,
- handle_fs_progress,
- chat,
+ handle->fs = GNUNET_FS_start(
+ handle->cfg, name, // TODO: raw name?
+ notify_handle_fs_progress, handle,
GNUNET_FS_FLAGS_NONE,
GNUNET_FS_OPTIONS_END
);
- chat->contacts.short_map = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO);
- chat->contacts.hash_map = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
-
- chat->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
- chat->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
- chat->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
-
- chat->msg_cb = msg_cb;
- chat->msg_cls = msg_cls;
-
- return chat;
-}
-
-static int
-handle_iterate_destroy_contacts (GNUNET_UNUSED void *cls,
- GNUNET_UNUSED const struct GNUNET_HashCode *key,
- void *value)
-{
- struct GNUNET_CHAT_Contact *contact = value;
- contact_destroy(contact);
- return GNUNET_YES;
-}
+ handle->messenger = GNUNET_MESSENGER_connect(
+ handle->cfg, name,
+ on_handle_identity, handle,
+ on_handle_message, handle
+ );
-static int
-handle_iterate_destroy_groups (GNUNET_UNUSED void *cls,
- GNUNET_UNUSED const struct GNUNET_HashCode *key,
- void *value)
-{
- struct GNUNET_CHAT_Group *group = value;
- group_destroy(group);
- return GNUNET_YES;
+ return handle;
}
void
-GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle)
+handle_destroy (struct GNUNET_CHAT_Handle* handle)
{
- if (!handle)
- return;
-
- if (handle->handles.fs)
- {
- // TODO: stop each action
-
- GNUNET_FS_stop(handle->handles.fs);
- handle->handles.fs = NULL;
- }
-
- if (handle->handles.messenger)
- {
- // TODO: stop everything related
-
- GNUNET_MESSENGER_disconnect(handle->handles.messenger);
- handle->handles.messenger = NULL;
- }
+ if (handle->messenger)
+ GNUNET_MESSENGER_disconnect(handle->messenger);
- if (handle->groups)
- {
- GNUNET_CONTAINER_multihashmap_iterate(
- handle->groups, handle_iterate_destroy_groups, NULL
- );
+ if (handle->files)
+ GNUNET_FS_stop(handle->fs);
- GNUNET_CONTAINER_multihashmap_destroy(handle->groups);
- handle->groups = NULL;
- }
+ if (handle->arm)
+ GNUNET_ARM_disconnect(handle->arm);
- if (handle->contacts.hash_map)
- {
- GNUNET_CONTAINER_multihashmap_iterate(
- handle->contacts.hash_map, handle_iterate_destroy_contacts, NULL
- );
-
- GNUNET_CONTAINER_multihashmap_destroy(handle->contacts.hash_map);
- handle->contacts.hash_map = NULL;
- }
-
- if (handle->contacts.short_map)
- {
- GNUNET_CONTAINER_multishortmap_destroy(handle->contacts.short_map);
- handle->contacts.short_map = NULL;
- }
-
- if (handle->handles.arm)
- {
- //TODO: stop started services?
-
- GNUNET_ARM_disconnect(handle->handles.arm);
- handle->handles.arm = NULL;
- }
+ GNUNET_CONTAINER_multihashmap_destroy(handle->groups);
+ GNUNET_CONTAINER_multishortmap_destroy(handle->contacts);
+ GNUNET_CONTAINER_multihashmap_destroy(handle->contexts);
+ GNUNET_CONTAINER_multihashmap_destroy(handle->files);
GNUNET_free(handle);
}
-
-int
-GNUNET_CHAT_update (struct GNUNET_CHAT_Handle *handle)
-{
- if (!handle)
- return GNUNET_SYSERR;
-
- return GNUNET_MESSENGER_update(handle->handles.messenger);
-}
-
-int
-GNUNET_CHAT_set_name (struct GNUNET_CHAT_Handle *handle,
- const char *name)
-{
- if (!handle)
- return GNUNET_SYSERR;
-
- return GNUNET_MESSENGER_set_name(handle->handles.messenger, name);
-}
-
-const char*
-GNUNET_CHAT_get_name (const struct GNUNET_CHAT_Handle *handle)
-{
- if (!handle)
- return NULL;
-
- return GNUNET_MESSENGER_get_name(handle->handles.messenger);
-}
-
-const struct GNUNET_IDENTITY_PublicKey*
-GNUNET_CHAT_get_key (const struct GNUNET_CHAT_Handle *handle)
-{
- if (!handle)
- 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,
- GNUNET_UNUSED 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)
-{
- 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.hash_map,
- handle_iterate_contacts,
- &iterate);
-}
-
-struct GNUNET_CHAT_Group*
-GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle,
- const char *topic)
-{
- if (!handle)
- return NULL;
-
- struct GNUNET_CHAT_Group *group = group_create(handle, topic);
-
- if (!group)
- return NULL;
-
- if (GNUNET_YES != handle_update_chat_group(handle, group, GNUNET_NO))
- {
- group_destroy(group);
- return NULL;
- }
-
- return group;
-}
-
-struct GNUNET_CHAT_IterateGroups
-{
- struct GNUNET_CHAT_Handle *handle;
- GNUNET_CHAT_GroupCallback callback;
- void *cls;
-};
-
-static int
-handle_iterate_groups(void *cls,
- GNUNET_UNUSED 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
-GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle,
- GNUNET_CHAT_GroupCallback callback,
- void *cls)
-{
- 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_groups,
- &iterate);
-}
-
-int
-handle_update_chat_contact (struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_Contact *chatContact,
- int removeContact)
-{
- const struct GNUNET_HashCode *key = context_get_key(chatContact->context);
-
- if (GNUNET_YES == removeContact)
- {
- const int result = GNUNET_CONTAINER_multihashmap_remove(
- handle->contacts.hash_map, key, chatContact
- );
-
- if (GNUNET_YES == result)
- return handle_update_chat_context(handle, chatContact->context,
- GNUNET_YES);
- else
- return GNUNET_NO;
- }
- else
- {
- const int result = GNUNET_CONTAINER_multihashmap_put(
- handle->contacts.hash_map, key, chatContact,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
- );
-
- if (GNUNET_OK != result)
- return GNUNET_NO;
- else
- return handle_update_chat_context(handle, chatContact->context,
- GNUNET_NO);
- }
-}
-
-int
-handle_update_chat_group (struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_Group *chatGroup,
- int removeGroup)
-{
- const struct GNUNET_HashCode *key = context_get_key(chatGroup->context);
-
- if (GNUNET_YES == removeGroup)
- {
- const int result = GNUNET_CONTAINER_multihashmap_remove(
- handle->groups, key, chatGroup
- );
-
- if (GNUNET_YES == result)
- return handle_update_chat_context(handle, chatGroup->context,
- GNUNET_YES);
- else
- return GNUNET_NO;
- }
- else
- {
- const int result = GNUNET_CONTAINER_multihashmap_put(
- handle->groups, key, chatGroup,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
- );
-
- if (GNUNET_OK != result)
- return GNUNET_NO;
- else
- return handle_update_chat_context(handle, chatGroup->context,
- GNUNET_NO);
- }
-}
-
-int
-handle_update_chat_context (struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_Context *context,
- int removeContext)
-{
- const struct GNUNET_HashCode *key = context_get_key(context);
-
- if (GNUNET_YES == removeContext)
- return GNUNET_CONTAINER_multihashmap_remove(
- handle->contexts, key, context
- );
- else
- {
- const int result = GNUNET_CONTAINER_multihashmap_put(
- handle->contexts, key, context,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
- );
-
- if (GNUNET_OK != result)
- return GNUNET_NO;
- else
- return GNUNET_YES;
- }
-}
-
-int
-handle_update_chat_file (struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_File *file,
- int removeFile)
-{
- const struct GNUNET_HashCode *hash = GNUNET_CHAT_file_get_hash(file);
-
- if (GNUNET_YES == removeFile)
- return GNUNET_CONTAINER_multihashmap_remove(
- handle->files, hash, file
- );
- else
- {
- const int result = GNUNET_CONTAINER_multihashmap_put(
- handle->files, hash, file,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
- );
-
- if (GNUNET_OK != result)
- return GNUNET_NO;
- else
- return GNUNET_YES;
- }
-}
-
-static void
-handle_get_short_of_contact(struct GNUNET_ShortHashCode *shortHash,
- const struct GNUNET_MESSENGER_Contact *contact)
-{
- memset(shortHash, 0, sizeof(*shortHash));
- GNUNET_memcpy(shortHash, &contact, sizeof(contact));
-}
-
-struct GNUNET_CHAT_Contact*
-handle_get_chat_contact (struct GNUNET_CHAT_Handle *handle,
- const struct GNUNET_MESSENGER_Contact *contact)
-{
- struct GNUNET_ShortHashCode shortHash;
- handle_get_short_of_contact (&shortHash, contact);
-
- struct GNUNET_CHAT_Contact* chatContact = GNUNET_CONTAINER_multishortmap_get(
- handle->contacts.short_map, &shortHash
- );
-
- return chatContact;
-}
-
-void
-handle_set_chat_contact (struct GNUNET_CHAT_Handle *handle,
- const struct GNUNET_MESSENGER_Contact *contact,
- struct GNUNET_CHAT_Contact *chatContact)
-{
- struct GNUNET_ShortHashCode shortHash;
- handle_get_short_of_contact (&shortHash, contact);
-
- if (chatContact)
- {
- GNUNET_CONTAINER_multishortmap_remove_all(handle->contacts.short_map,
- &shortHash);
- return;
- }
-
- GNUNET_CONTAINER_multishortmap_put(
- handle->contacts.short_map, &shortHash, chatContact,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
- );
-}
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h
@@ -26,86 +26,45 @@
#define GNUNET_CHAT_HANDLE_H_
#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_config.h>
#include <gnunet/gnunet_container_lib.h>
#include <gnunet/gnunet_arm_service.h>
#include <gnunet/gnunet_fs_service.h>
#include <gnunet/gnunet_messenger_service.h>
-#include <gnunet/gnunet_regex_service.h>
#include <gnunet/gnunet_util_lib.h>
+#include "gnunet_chat_lib.h"
+
struct GNUNET_CHAT_Handle
{
const struct GNUNET_CONFIGURATION_Handle* cfg;
- struct {
- /*
- * feature: (automatically start required services)
- */
- struct GNUNET_ARM_Handle *arm;
-
- /*
- * required: (files can be uploaded/downloaded)
- */
- struct GNUNET_FS_Handle *fs;
-
- /*
- * required!
- */
- struct GNUNET_MESSENGER_Handle *messenger;
- } handles;
-
- struct {
- struct GNUNET_CONTAINER_MultiShortmap *short_map;
- struct GNUNET_CONTAINER_MultiHashMap *hash_map;
- } contacts;
-
- struct GNUNET_CONTAINER_MultiHashMap *groups;
- struct GNUNET_CONTAINER_MultiHashMap *contexts;
- struct GNUNET_CONTAINER_MultiHashMap *files;
-
GNUNET_CHAT_ContextMessageCallback msg_cb;
void *msg_cls;
GNUNET_CHAT_WarningCallback warn_cb;
void *warn_cls;
-};
-
-int
-handle_update_chat_contact (struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_Contact *chatContact,
- int removeContact);
-
-int
-handle_update_chat_group (struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_Group *chatGroup,
- int removeGroup);
-int
-handle_update_chat_context (struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_Context *context,
- int removeContext);
+ struct GNUNET_CONTAINER_MultiHashMap *files;
+ struct GNUNET_CONTAINER_MultiHashMap *contexts;
+ struct GNUNET_CONTAINER_MultiShortmap *contacts;
+ struct GNUNET_CONTAINER_MultiHashMap *groups;
-int
-handle_update_chat_file (struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_File *file,
- int removeFile);
+ struct GNUNET_ARM_Handle *arm;
+ struct GNUNET_FS_Handle *fs;
+ struct GNUNET_MESSENGER_Handle *messenger;
+};
-struct GNUNET_CHAT_Contact*
-handle_get_chat_contact (struct GNUNET_CHAT_Handle *handle,
- const struct GNUNET_MESSENGER_Contact *contact);
+struct GNUNET_CHAT_Handle*
+handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg,
+ const char* name,
+ GNUNET_CHAT_ContextMessageCallback msg_cb,
+ void *msg_cls,
+ GNUNET_CHAT_WarningCallback warn_cb,
+ void *warn_cls);
void
-handle_set_chat_contact (struct GNUNET_CHAT_Handle *handle,
- const struct GNUNET_MESSENGER_Contact *contact,
- struct GNUNET_CHAT_Contact *chatContact);
-
-struct GNUNET_CHAT_Context*
-handle_get_chat_context (struct GNUNET_CHAT_Handle *handle,
- const struct GNUNET_HashCode *key);
-
-struct GNUNET_CHAT_File*
-handle_get_chat_file (struct GNUNET_CHAT_Handle *handle,
- const struct GNUNET_HashCode *hash);
+handle_destroy (struct GNUNET_CHAT_Handle* handle);
#endif /* GNUNET_CHAT_HANDLE_H_ */
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c
@@ -0,0 +1,308 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file gnunet_chat_handle_intern.c
+ */
+
+#include "gnunet_chat_contact.h"
+#include "gnunet_chat_context.h"
+#include "gnunet_chat_group.h"
+#include "gnunet_chat_handle.h"
+#include "gnunet_chat_message.h"
+#include "gnunet_chat_util.h"
+
+#define GNUNET_UNUSED __attribute__ ((unused))
+
+void
+on_handle_arm_connection(void *cls, int connected)
+{
+ struct GNUNET_CHAT_Handle *chat = cls;
+
+ if (GNUNET_YES == connected) {
+ GNUNET_ARM_request_service_start(
+ chat->arm, "messenger",
+ GNUNET_OS_INHERIT_STD_NONE,
+ NULL, NULL
+ );
+
+ GNUNET_ARM_request_service_start(
+ chat->arm, "fs",
+ GNUNET_OS_INHERIT_STD_NONE,
+ NULL, NULL
+ );
+ } else {
+ GNUNET_ARM_request_service_start(
+ chat->arm, "arm",
+ GNUNET_OS_INHERIT_STD_NONE,
+ NULL, NULL
+ );
+ }
+}
+
+void*
+notify_handle_fs_progress(void* cls, const struct GNUNET_FS_ProgressInfo* info)
+{
+ struct GNUNET_CHAT_Handle *chat = cls;
+
+ if (!chat)
+ return NULL;
+
+ switch (info->status) {
+ case GNUNET_FS_STATUS_PUBLISH_START: {
+ /*publication_t* publication = (publication_t*) info->value.publish.cctx;
+ publication->progress = 0.0f;
+
+ GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication);
+
+ return publication;*/
+ break;
+ } case GNUNET_FS_STATUS_PUBLISH_PROGRESS: {
+ /*publication_t* publication = (publication_t*) info->value.publish.cctx;
+ publication->progress = 1.0f * info->value.publish.completed / info->value.publish.size;
+
+ GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication);
+
+ return publication;*/
+ break;
+ } case GNUNET_FS_STATUS_PUBLISH_COMPLETED: {
+ /*publication_t* publication = (publication_t*) info->value.publish.cctx;
+ publication->uri = GNUNET_FS_uri_dup(info->value.publish.specifics.completed.chk_uri);
+ publication->progress = 1.0f;
+
+ GNUNET_SCHEDULER_add_now(&CGTK_publication_finish, publication);*/
+ break;
+ } case GNUNET_FS_STATUS_PUBLISH_ERROR: {
+ /*publication_t* publication = (publication_t*) info->value.publish.cctx;
+
+ GNUNET_SCHEDULER_add_now(&CGTK_publication_error, publication);*/
+ break;
+ } case GNUNET_FS_STATUS_DOWNLOAD_START: {
+ /*request_t* request = (request_t*) info->value.download.cctx;
+ request->progress = 0.0f;
+
+ return request;*/
+ break;
+ } case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: {
+ return info->value.download.cctx;
+ } case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: {
+ return info->value.download.cctx;
+ } case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: {
+ /*request_t* request = (request_t*) info->value.download.cctx;
+ request->progress = 1.0f * info->value.download.completed / info->value.download.size;
+
+ GNUNET_SCHEDULER_add_now(&CGTK_request_progress, request);
+
+ return request;*/
+ break;
+ } case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: {
+ /*request_t* request = (request_t*) info->value.download.cctx;
+ request->progress = 1.0f;
+
+ GNUNET_SCHEDULER_add_now(&CGTK_request_finish, request);*/
+ break;
+ } case GNUNET_FS_STATUS_DOWNLOAD_ERROR: {
+ /*request_t *request = (request_t *) info->value.download.cctx;
+
+ GNUNET_SCHEDULER_add_now(&CGTK_request_error, request);*/
+ break;
+ } case GNUNET_FS_STATUS_UNINDEX_START: {
+ /*publication_t* publication = (publication_t*) info->value.unindex.cctx;
+ publication->progress = 0.0f;
+
+ return publication;*/
+ break;
+ } case GNUNET_FS_STATUS_UNINDEX_PROGRESS: {
+ /*publication_t* publication = (publication_t*) info->value.unindex.cctx;
+ publication->progress = 1.0f * info->value.unindex.completed / info->value.unindex.size;
+
+ return publication;*/
+ break;
+ } case GNUNET_FS_STATUS_UNINDEX_COMPLETED: {
+ /*publication_t* publication = (publication_t*) info->value.unindex.cctx;
+ publication->progress = 1.0f;
+
+ GNUNET_SCHEDULER_add_now(&CGTK_publication_unindex_finish, publication);*/
+ break;
+ } default: {
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+struct GNUNET_CHAT_CheckHandleRoomMembers
+{
+ const struct GNUNET_IDENTITY_PublicKey *ignore_key;
+ const struct GNUNET_MESSENGER_Contact *contact;
+};
+
+int
+check_handle_room_members (void* cls,
+ GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room,
+ const struct GNUNET_MESSENGER_Contact *contact)
+{
+ struct GNUNET_CHAT_CheckHandleRoomMembers *check = cls;
+
+ const struct GNUNET_IDENTITY_PublicKey *contact_key = (
+ GNUNET_MESSENGER_contact_get_key(contact)
+ );
+
+ if (0 == GNUNET_memcmp(contact_key, check->ignore_key))
+ return GNUNET_YES;
+
+ if (check->contact)
+ return GNUNET_NO;
+
+ check->contact = contact;
+ return GNUNET_YES;
+}
+
+struct GNUNET_CHAT_Context*
+request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle,
+ struct GNUNET_MESSENGER_Room *room)
+{
+ const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room);
+
+ struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get(
+ handle->contexts, key
+ );
+
+ if (context)
+ return context;
+
+ context = context_create_from_room(handle, room);
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
+ handle->contexts, key, context,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ {
+ context_destroy(context);
+ return NULL;
+ }
+
+ struct GNUNET_CHAT_CheckHandleRoomMembers check;
+ check.ignore_key = GNUNET_MESSENGER_get_key(handle->messenger);
+ check.contact = NULL;
+
+ GNUNET_MESSENGER_iterate_members(room, check_handle_room_members, &check);
+
+ if (check.contact)
+ {
+ context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT;
+
+ struct GNUNET_CHAT_Contact *contact = contact_create_from_member(
+ handle, check.contact
+ );
+
+ struct GNUNET_ShortHashCode shorthash;
+ util_shorthash_from_member(check.contact, &shorthash);
+
+ if (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put(
+ handle->contacts, &shorthash, contact,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ return context;
+
+ contact_destroy(contact);
+ }
+ else
+ {
+ context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
+
+ struct GNUNET_CHAT_Group *group = group_create_from_context(
+ handle, context
+ );
+
+ if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(
+ handle->groups, key, group,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ return context;
+
+ group_destroy(group);
+ }
+
+ GNUNET_CONTAINER_multihashmap_remove(handle->contexts, key, context);
+ context_destroy(context);
+ return NULL;
+}
+
+int
+find_handle_rooms (void *cls, struct GNUNET_MESSENGER_Room *room,
+ GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *member)
+{
+ struct GNUNET_CHAT_Handle *handle = cls;
+
+ request_handle_context_by_room(
+ handle, room
+ );
+
+ return GNUNET_YES;
+}
+
+void
+on_handle_identity(void *cls,
+ GNUNET_UNUSED struct GNUNET_MESSENGER_Handle *messenger)
+{
+ struct GNUNET_CHAT_Handle *handle = cls;
+
+ GNUNET_MESSENGER_find_rooms(
+ handle->messenger, NULL, find_handle_rooms, handle
+ );
+}
+
+void
+on_handle_message (void *cls,
+ struct GNUNET_MESSENGER_Room *room,
+ GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *sender,
+ const struct GNUNET_MESSENGER_Message *msg,
+ const struct GNUNET_HashCode *hash,
+ GNUNET_UNUSED enum GNUNET_MESSENGER_MessageFlags flags)
+{
+ struct GNUNET_CHAT_Handle *handle = cls;
+
+ struct GNUNET_CHAT_Context *context = request_handle_context_by_room(
+ handle, room
+ );
+
+ if (!context)
+ return;
+
+ struct GNUNET_CHAT_Message *message = GNUNET_CONTAINER_multihashmap_get(
+ context->messages, hash
+ );
+
+ if (message)
+ goto process_callback;
+
+ message = message_create_from_msg(context, hash, msg);
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
+ context->messages, hash, message,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ {
+ message_destroy(message);
+ return;
+ }
+
+process_callback:
+ if (handle->msg_cb)
+ handle->msg_cb(handle->msg_cls, context, message);
+}
diff --git a/src/gnunet_chat_invitation.c b/src/gnunet_chat_invitation.c
@@ -24,14 +24,24 @@
#include "gnunet_chat_invitation.h"
-void
-GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation)
+struct GNUNET_CHAT_Invitation*
+invitation_create_from_message (struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_MESSENGER_MessageInvite *message)
{
- //TODO
+ struct GNUNET_CHAT_Invitation *invitation = GNUNET_new(struct GNUNET_CHAT_Invitation);
+
+ invitation->context = context;
+
+ GNUNET_memcpy(&(invitation->key), &(message->key), sizeof(invitation->key));
+ invitation->door = GNUNET_PEER_intern(&(message->door));
+
+ return invitation;
}
void
-GNUNET_CHAT_invitation_decline (struct GNUNET_CHAT_Invitation *invitation)
+invitation_destroy (struct GNUNET_CHAT_Invitation *invitation)
{
- //TODO
+ GNUNET_PEER_decrement_rcs(&(invitation->door), 1);
+
+ GNUNET_free(invitation);
}
diff --git a/src/gnunet_chat_invitation.h b/src/gnunet_chat_invitation.h
@@ -25,11 +25,28 @@
#ifndef GNUNET_CHAT_INVITATION_H_
#define GNUNET_CHAT_INVITATION_H_
-#include "gnunet_chat_lib.h"
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_crypto_lib.h>
+#include <gnunet/gnunet_messenger_service.h>
+#include <gnunet/gnunet_peer_lib.h>
+#include <gnunet/gnunet_util_lib.h>
+
+struct GNUNET_CHAT_Context;
struct GNUNET_CHAT_Invitation
{
+ struct GNUNET_CHAT_Context *context;
+ struct GNUNET_HashCode key;
+ GNUNET_PEER_Id door;
};
+struct GNUNET_CHAT_Invitation*
+invitation_create_from_message (struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_MESSENGER_MessageInvite *message);
+
+void
+invitation_destroy (struct GNUNET_CHAT_Invitation *invitation);
+
#endif /* GNUNET_CHAT_INVITATION_H_ */
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c
@@ -0,0 +1,693 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file gnunet_chat_lib.c
+ */
+
+#include "gnunet_chat_lib.h"
+
+#include <limits.h>
+
+#include "gnunet_chat_config.h"
+#include "gnunet_chat_contact.h"
+#include "gnunet_chat_context.h"
+#include "gnunet_chat_file.h"
+#include "gnunet_chat_group.h"
+#include "gnunet_chat_handle.h"
+#include "gnunet_chat_invitation.h"
+#include "gnunet_chat_message.h"
+#include "gnunet_chat_util.h"
+
+#include "gnunet_chat_lib_intern.c"
+
+struct GNUNET_CHAT_Handle*
+GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *name,
+ GNUNET_CHAT_WarningCallback warn_cb, void *warn_cls,
+ GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls)
+{
+ if (!cfg)
+ return NULL;
+
+ if (!name)
+ return NULL;
+
+ return handle_create_from_config(
+ cfg, name, msg_cb, msg_cls, warn_cb, warn_cls
+ );
+}
+
+void
+GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle)
+{
+ if (!handle)
+ return;
+
+ handle_destroy(handle);
+}
+
+int
+GNUNET_CHAT_update (struct GNUNET_CHAT_Handle *handle)
+{
+ if (!handle)
+ return GNUNET_SYSERR;
+
+ return GNUNET_MESSENGER_update(handle->messenger);
+}
+
+int
+GNUNET_CHAT_set_name (struct GNUNET_CHAT_Handle *handle,
+ const char *name)
+{
+ if (!handle)
+ return GNUNET_SYSERR;
+
+ if (!name)
+ return GNUNET_NO;
+
+ return GNUNET_MESSENGER_set_name(handle->messenger, name);
+}
+
+const char*
+GNUNET_CHAT_get_name (const struct GNUNET_CHAT_Handle *handle)
+{
+ if (!handle)
+ return NULL;
+
+ return GNUNET_MESSENGER_get_name(handle->messenger);
+}
+
+const struct GNUNET_IDENTITY_PublicKey*
+GNUNET_CHAT_get_key (const struct GNUNET_CHAT_Handle *handle)
+{
+ if (!handle)
+ return NULL;
+
+ return GNUNET_MESSENGER_get_key(handle->messenger);
+}
+
+int
+GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle,
+ GNUNET_CHAT_ContactCallback callback,
+ void *cls)
+{
+ if (!handle)
+ return GNUNET_SYSERR;
+
+ struct GNUNET_CHAT_HandleIterateContacts it;
+ it.handle = handle;
+ it.cb = callback;
+ it.cls = cls;
+
+ return GNUNET_CONTAINER_multishortmap_iterate(
+ handle->contacts, it_handle_iterate_contacts, &it
+ );
+}
+
+struct GNUNET_CHAT_Group *
+GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle,
+ const char* topic)
+{
+ if (!handle)
+ return NULL;
+
+ struct GNUNET_HashCode key;
+
+ if (topic)
+ GNUNET_CRYPTO_hash(topic, strlen(topic), &key);
+ else
+ GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, &key, sizeof(key));
+
+ if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(
+ handle->contexts, &key))
+ return NULL;
+
+ struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_open_room(
+ handle->messenger, &key
+ );
+
+ struct GNUNET_CHAT_Context *context = context_create_from_room(handle, room);
+
+ context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP;
+
+ if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(
+ handle->contexts, &key, context,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ goto destroy_context;
+
+ struct GNUNET_CHAT_Group *group = group_create_from_context(handle, context);
+
+ util_set_name_field(topic, &(group->topic));
+
+ if (group->topic)
+ group_publish(group);
+
+ if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(
+ handle->groups, &key, group,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ return group;
+
+ group_destroy(group);
+
+ GNUNET_CONTAINER_multihashmap_remove(handle->contexts, &key, context);
+
+destroy_context:
+ context_destroy(context);
+ return NULL;
+}
+
+int
+GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle,
+ GNUNET_CHAT_GroupCallback callback,
+ void *cls)
+{
+ if (!handle)
+ return GNUNET_SYSERR;
+
+ struct GNUNET_CHAT_HandleIterateGroups it;
+ it.handle = handle;
+ it.cb = callback;
+ it.cls = cls;
+
+ return GNUNET_CONTAINER_multihashmap_iterate(
+ handle->groups, it_handle_iterate_groups, &it
+ );
+}
+
+int
+GNUNET_CHAT_contact_delete (struct GNUNET_CHAT_Contact *contact)
+{
+ if (!contact)
+ return GNUNET_SYSERR;
+
+ struct GNUNET_ShortHashCode shorthash;
+ util_shorthash_from_member(contact->member, &shorthash);
+
+ GNUNET_CONTAINER_multishortmap_remove(
+ contact->handle->contacts, &shorthash, contact
+ );
+
+ const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(
+ contact->context->room
+ );
+
+ GNUNET_CONTAINER_multihashmap_remove(
+ contact->handle->contexts, key, contact->context
+ );
+
+ GNUNET_MESSENGER_close_room(contact->context->room);
+
+ context_destroy(contact->context);
+ contact_destroy(contact);
+ return GNUNET_OK;
+}
+
+void
+GNUNET_CHAT_contact_set_name (struct GNUNET_CHAT_Contact *contact,
+ const char *name)
+{
+ if (!contact)
+ return;
+
+ util_set_name_field(name, &(contact->context->nick));
+}
+
+
+const char*
+GNUNET_CHAT_contact_get_name (const struct GNUNET_CHAT_Contact *contact)
+{
+ if (!contact)
+ return NULL;
+
+ if (contact->context->nick)
+ return contact->context->nick;
+
+ return GNUNET_MESSENGER_contact_get_name(contact->member);
+}
+
+
+const struct GNUNET_IDENTITY_PublicKey*
+GNUNET_CHAT_contact_get_key (const struct GNUNET_CHAT_Contact *contact)
+{
+ if (!contact)
+ return NULL;
+
+ return GNUNET_MESSENGER_contact_get_key(contact->member);
+}
+
+
+struct GNUNET_CHAT_Context*
+GNUNET_CHAT_contact_get_context (struct GNUNET_CHAT_Contact *contact)
+{
+ if (!contact)
+ return NULL;
+
+ return contact->context;
+}
+
+
+int
+GNUNET_CHAT_group_leave (struct GNUNET_CHAT_Group *group)
+{
+ if (!group)
+ return GNUNET_SYSERR;
+
+ const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(
+ group->context->room
+ );
+
+ GNUNET_CONTAINER_multihashmap_remove(
+ group->handle->groups, key, group
+ );
+
+ GNUNET_CONTAINER_multihashmap_remove(
+ group->handle->contexts, key, group->context
+ );
+
+ GNUNET_MESSENGER_close_room(group->context->room);
+
+ context_destroy(group->context);
+ group_destroy(group);
+ return GNUNET_OK;
+}
+
+
+void
+GNUNET_CHAT_group_set_name (struct GNUNET_CHAT_Group *group,
+ const char *name)
+{
+ if (!group)
+ return;
+
+ util_set_name_field(name, &(group->context->nick));
+}
+
+
+const char*
+GNUNET_CHAT_group_get_name (const struct GNUNET_CHAT_Group *group)
+{
+ if (!group)
+ return NULL;
+
+ return group->context->nick;
+}
+
+
+void
+GNUNET_CHAT_group_invite_contact (struct GNUNET_CHAT_Group *group,
+ struct GNUNET_CHAT_Contact *contact)
+{
+ if ((!group) || (!contact))
+ return;
+
+ const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(
+ group->context->room
+ );
+
+ GNUNET_MESSENGER_open_room(group->handle->messenger, key);
+
+ struct GNUNET_MESSENGER_Message msg;
+ msg.header.kind = GNUNET_MESSENGER_KIND_INVITE;
+ GNUNET_CRYPTO_get_peer_identity(group->handle->cfg, &(msg.body.invite.door));
+ GNUNET_memcpy(&(msg.body.invite.key), key, sizeof(msg.body.invite.key));
+
+ GNUNET_MESSENGER_send_message(contact->context->room, &msg, contact->member);
+}
+
+int
+GNUNET_CHAT_group_iterate_contacts (struct GNUNET_CHAT_Group *group,
+ GNUNET_CHAT_GroupContactCallback callback,
+ void *cls)
+{
+ if (!group)
+ return GNUNET_SYSERR;
+
+ struct GNUNET_CHAT_GroupIterateContacts it;
+ it.group = group;
+ it.cb = callback;
+ it.cls = cls;
+
+ return GNUNET_MESSENGER_iterate_members(
+ group->context->room, it_group_iterate_contacts, &it
+ );
+}
+
+
+struct GNUNET_CHAT_Context*
+GNUNET_CHAT_group_get_context (struct GNUNET_CHAT_Group *group)
+{
+ if (!group)
+ return NULL;
+
+ return group->context;
+}
+
+void
+GNUNET_CHAT_context_send_text (struct GNUNET_CHAT_Context *context,
+ const char *text)
+{
+ if ((!context) || (!text))
+ return;
+
+ struct GNUNET_MESSENGER_Message msg;
+ msg.header.kind = GNUNET_MESSENGER_KIND_TEXT;
+ msg.body.text.text = GNUNET_strdup(text);
+
+ GNUNET_MESSENGER_send_message(context->room, &msg, NULL);
+
+ GNUNET_free(msg.body.text.text);
+}
+
+
+void
+GNUNET_CHAT_context_send_file (struct GNUNET_CHAT_Context *context,
+ const char *path)
+{
+ if ((!context) || (!path))
+ return;
+
+ // TODO: encrypt file, publish file, share file
+}
+
+
+void
+GNUNET_CHAT_context_send_uri (struct GNUNET_CHAT_Context *context,
+ const char *uri)
+{
+ if ((!context) || (!uri))
+ return;
+
+ struct GNUNET_FS_Uri *furi = GNUNET_FS_uri_parse(uri, NULL);
+
+ if (!furi)
+ return;
+
+ // TODO: download file, hash file, share file
+}
+
+
+void
+GNUNET_CHAT_context_share_file (struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_CHAT_File *file)
+{
+ if ((!context) || (!file) || (strlen(file->name) > NAME_MAX))
+ return;
+
+ struct GNUNET_MESSENGER_Message msg;
+ msg.header.kind = GNUNET_MESSENGER_KIND_FILE;
+ GNUNET_memcpy(&(msg.body.file.key), &(file->key), sizeof(file->key));
+ GNUNET_memcpy(&(msg.body.file.hash), &(file->hash), sizeof(file->hash));
+ GNUNET_strlcpy(msg.body.file.name, file->name, NAME_MAX);
+ msg.body.file.uri = GNUNET_FS_uri_to_string(file->uri);
+
+ GNUNET_MESSENGER_send_message(context->room, &msg, NULL);
+
+ GNUNET_free(msg.body.file.uri);
+}
+
+
+void
+GNUNET_CHAT_context_delete_message (const struct GNUNET_CHAT_Message *message,
+ struct GNUNET_TIME_Relative delay)
+{
+ if (!message)
+ return;
+
+ struct GNUNET_MESSENGER_Message msg;
+ msg.header.kind = GNUNET_MESSENGER_KIND_DELETE;
+ GNUNET_memcpy(&(msg.body.delete.hash), &(message->hash), sizeof(message->hash));
+ msg.body.delete.delay = GNUNET_TIME_relative_hton(delay);
+
+ GNUNET_MESSENGER_send_message(message->context->room, &msg, NULL);
+}
+
+
+
+int
+GNUNET_CHAT_context_iterate_messages (struct GNUNET_CHAT_Context *context,
+ GNUNET_CHAT_ContextMessageCallback callback,
+ void *cls)
+{
+ if (!context)
+ return GNUNET_SYSERR;
+
+ struct GNUNET_CHAT_ContextIterateMessages it;
+ it.context = context;
+ it.cb = callback;
+ it.cls = cls;
+
+ return GNUNET_CONTAINER_multihashmap_iterate(
+ context->messages, it_context_iterate_messages, &it
+ );
+}
+
+
+enum GNUNET_CHAT_MessageKind
+GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message)
+{
+ if (!message)
+ return GNUNET_CHAT_KIND_UNKNOWN;
+
+ switch (message->msg->header.kind)
+ {
+ case GNUNET_MESSENGER_KIND_INVITE:
+ return GNUNET_CHAT_KIND_INVITATION;
+ case GNUNET_MESSENGER_KIND_TEXT:
+ return GNUNET_CHAT_KIND_TEXT;
+ case GNUNET_MESSENGER_KIND_FILE:
+ return GNUNET_CHAT_KIND_FILE;
+ default:
+ return GNUNET_CHAT_KIND_UNKNOWN;
+ }
+}
+
+
+struct GNUNET_TIME_Absolute
+GNUNET_CHAT_message_get_timestamp (const struct GNUNET_CHAT_Message *message)
+{
+ if (!message)
+ return GNUNET_TIME_absolute_get_zero_();
+
+ return GNUNET_TIME_absolute_ntoh(message->msg->header.timestamp);
+}
+
+
+const struct GNUNET_CHAT_Contact*
+GNUNET_CHAT_message_get_sender (const struct GNUNET_CHAT_Message *message)
+{
+ if (!message)
+ return NULL;
+
+ const struct GNUNET_MESSENGER_Contact *sender = GNUNET_MESSENGER_get_sender(
+ message->context->room, &(message->hash)
+ );
+
+ if (!sender)
+ return NULL;
+
+ struct GNUNET_ShortHashCode shorthash;
+ util_shorthash_from_member(sender, &shorthash);
+
+ return GNUNET_CONTAINER_multishortmap_get(
+ message->context->handle->contacts, &shorthash
+ );
+}
+
+
+int
+GNUNET_CHAT_message_get_read_receipt (const struct GNUNET_CHAT_Message *message,
+ GNUNET_CHAT_MessageReadReceiptCallback callback,
+ void *cls)
+{
+ if (!message)
+ return GNUNET_SYSERR;
+
+ // TODO: request read receipt? / check if newer message was received of sender?
+
+ return GNUNET_SYSERR;
+}
+
+
+const char*
+GNUNET_CHAT_message_get_text (const struct GNUNET_CHAT_Message *message)
+{
+ if (!message)
+ return NULL;
+
+ if (GNUNET_MESSENGER_KIND_TEXT != message->msg->header.kind)
+ return NULL;
+
+ return message->msg->body.text.text;
+}
+
+
+struct GNUNET_CHAT_File*
+GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message)
+{
+ if (!message)
+ return NULL;
+
+ if (GNUNET_MESSENGER_KIND_FILE != message->msg->header.kind)
+ return NULL;
+
+ return GNUNET_CONTAINER_multihashmap_get(
+ message->context->handle->files,
+ &(message->msg->body.file.hash)
+ );
+}
+
+
+struct GNUNET_CHAT_Invitation*
+GNUNET_CHAT_message_get_invitation (const struct GNUNET_CHAT_Message *message)
+{
+ if (!message)
+ return NULL;
+
+ if (GNUNET_MESSENGER_KIND_INVITE != message->msg->header.kind)
+ return NULL;
+
+ return GNUNET_CONTAINER_multihashmap_get(
+ message->context->invites,
+ &(message->hash)
+ );
+}
+
+
+const struct GNUNET_HashCode*
+GNUNET_CHAT_file_get_hash (const struct GNUNET_CHAT_File *file)
+{
+ if (!file)
+ return NULL;
+
+ return &(file->hash);
+}
+
+
+uint64_t
+GNUNET_CHAT_file_get_size (const struct GNUNET_CHAT_File *file)
+{
+ if (!file)
+ return 0;
+
+ if (file->uri)
+ return GNUNET_FS_uri_chk_get_file_size(file->uri);
+
+ const char *path = ""; // TODO: path = download_directory + file->name
+
+ // TODO: check size through info or check locally?
+
+ return 0;
+}
+
+
+int
+GNUNET_CHAT_file_is_local (const struct GNUNET_CHAT_File *file)
+{
+ if (!file)
+ return GNUNET_SYSERR;
+
+ const char *path = ""; // TODO: path = download_directory + file->name
+
+ // TODO: check locally?
+
+ return GNUNET_SYSERR;
+}
+
+
+int
+GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file,
+ GNUNET_CHAT_MessageFileDownloadCallback callback,
+ void *cls)
+{
+ if (!file)
+ return GNUNET_SYSERR;
+
+ // TODO: check if downloading?
+
+ const char *path = ""; // TODO: path = download_directory + file->name
+
+ file->download = GNUNET_FS_download_start(
+ file->handle->fs,
+ file->uri,
+ NULL,
+ path,
+ NULL,
+ 0,
+ 0,
+ 0,
+ GNUNET_FS_DOWNLOAD_OPTION_NONE,
+ NULL,
+ NULL
+ );
+
+ return GNUNET_OK;
+}
+
+
+int
+GNUNET_CHAT_file_pause_download (struct GNUNET_CHAT_File *file)
+{
+ if (!file)
+ return GNUNET_SYSERR;
+
+ GNUNET_FS_download_suspend(file->download);
+ return GNUNET_OK;
+}
+
+
+int
+GNUNET_CHAT_file_resume_download (struct GNUNET_CHAT_File *file)
+{
+ if (!file)
+ return GNUNET_SYSERR;
+
+ GNUNET_FS_download_resume(file->download);
+ return GNUNET_OK;
+}
+
+
+int
+GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file)
+{
+ if (!file)
+ return GNUNET_SYSERR;
+
+ GNUNET_FS_download_stop(file->download, GNUNET_YES);
+ file->download = NULL;
+ return GNUNET_OK;
+}
+
+
+void
+GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation)
+{
+ if (!invitation)
+ return;
+
+ struct GNUNET_PeerIdentity door;
+ GNUNET_PEER_resolve(invitation->door, &door);
+
+ GNUNET_MESSENGER_enter_room(
+ invitation->context->handle->messenger,
+ &door, &(invitation->key)
+ );
+}
+
diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c
@@ -0,0 +1,124 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file gnunet_chat_lib_intern.c
+ */
+
+#define GNUNET_UNUSED __attribute__ ((unused))
+
+struct GNUNET_CHAT_HandleIterateContacts
+{
+ struct GNUNET_CHAT_Handle *handle;
+ GNUNET_CHAT_ContactCallback cb;
+ void *cls;
+};
+
+int
+it_handle_iterate_contacts (void *cls,
+ GNUNET_UNUSED const struct GNUNET_ShortHashCode *key,
+ void *value)
+{
+ struct GNUNET_CHAT_HandleIterateContacts *it = cls;
+
+ if (!(it->cb))
+ return GNUNET_YES;
+
+ struct GNUNET_CHAT_Contact *contact = value;
+
+ return it->cb(it->cls, it->handle, contact);
+}
+
+struct GNUNET_CHAT_HandleIterateGroups
+{
+ struct GNUNET_CHAT_Handle *handle;
+ GNUNET_CHAT_GroupCallback cb;
+ void *cls;
+};
+
+int
+it_handle_iterate_groups (void *cls,
+ GNUNET_UNUSED const struct GNUNET_HashCode *key,
+ void *value)
+{
+ struct GNUNET_CHAT_HandleIterateGroups *it = cls;
+
+ if (!(it->cb))
+ return GNUNET_YES;
+
+ struct GNUNET_CHAT_Group *group = value;
+
+ return it->cb(it->cls, it->handle, group);
+}
+
+struct GNUNET_CHAT_GroupIterateContacts
+{
+ struct GNUNET_CHAT_Group *group;
+ GNUNET_CHAT_GroupContactCallback cb;
+ void *cls;
+};
+
+int
+it_group_iterate_contacts (void* cls,
+ GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room,
+ const struct GNUNET_MESSENGER_Contact *member)
+{
+ struct GNUNET_CHAT_GroupIterateContacts *it = cls;
+
+ if (!(it->cb))
+ return GNUNET_YES;
+
+ struct GNUNET_ShortHashCode shorthash;
+ util_shorthash_from_member(member, &shorthash);
+
+ struct GNUNET_CHAT_Contact *contact = GNUNET_CONTAINER_multishortmap_get(
+ it->group->handle->contacts, &shorthash
+ );
+
+ return it->cb(it->cls, it->group, contact);
+}
+
+struct GNUNET_CHAT_ContextIterateMessages
+{
+ struct GNUNET_CHAT_Context *context;
+ GNUNET_CHAT_ContextMessageCallback cb;
+ void *cls;
+};
+
+int
+it_context_iterate_messages (void *cls,
+ GNUNET_UNUSED const struct GNUNET_HashCode *key,
+ void *value)
+{
+ struct GNUNET_CHAT_ContextIterateMessages *it = cls;
+
+ if (!(it->cb))
+ return GNUNET_YES;
+
+ struct GNUNET_CHAT_Message *message = value;
+
+ return it->cb(it->cls, it->context, message);
+}
+
+
+
+
+
+
diff --git a/src/gnunet_chat_message.c b/src/gnunet_chat_message.c
@@ -22,70 +22,26 @@
* @file gnunet_chat_message.c
*/
-#include "gnunet_chat_lib.h"
#include "gnunet_chat_message.h"
-enum GNUNET_CHAT_MessageKind
-GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message)
+struct GNUNET_CHAT_Message*
+message_create_from_msg (struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_HashCode *hash,
+ const struct GNUNET_MESSENGER_Message *msg)
{
- if (!message)
- return GNUNET_CHAT_KIND_UNKNOWN;
+ struct GNUNET_CHAT_Message *message = GNUNET_new(struct GNUNET_CHAT_Message);
- switch (message->message->header.kind) {
- case GNUNET_MESSENGER_KIND_INVITE:
- return GNUNET_CHAT_KIND_INVITATION;
- case GNUNET_MESSENGER_KIND_TEXT:
- return GNUNET_CHAT_KIND_TEXT;
- case GNUNET_MESSENGER_KIND_FILE:
- return GNUNET_CHAT_KIND_FILE;
- default:
- return GNUNET_CHAT_KIND_UNKNOWN;
- }
-}
-
-struct GNUNET_TIME_Absolute
-GNUNET_CHAT_message_get_timestamp (const struct GNUNET_CHAT_Message *message)
-{
- if (!message)
- return GNUNET_TIME_absolute_get_zero_();
-
- return GNUNET_TIME_absolute_ntoh(message->message->header.timestamp);
-}
-
-const struct GNUNET_CHAT_Contact*
-GNUNET_CHAT_message_get_sender (const struct GNUNET_CHAT_Message *message)
-{
- return NULL;
-}
+ message->context = context;
-int
-GNUNET_CHAT_message_get_read_receipt (const struct GNUNET_CHAT_Message *message,
- GNUNET_CHAT_MessageReadReceiptCallback callback,
- void *cls)
-{
- return GNUNET_SYSERR;
-}
-
-struct GNUNET_CHAT_Invitation*
-GNUNET_CHAT_message_get_invitation (const struct GNUNET_CHAT_Message *message)
-{
- return NULL; //TODO
-}
-
-const char*
-GNUNET_CHAT_message_get_text (const struct GNUNET_CHAT_Message *message)
-{
- if (!message)
- return NULL;
+ GNUNET_memcpy(&(message->hash), hash, sizeof(message->hash));
- if (GNUNET_MESSENGER_KIND_TEXT != message->message->header.kind)
- return NULL;
+ message->msg = msg;
- return message->message->body.text.text;
+ return message;
}
-struct GNUNET_CHAT_File*
-GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message)
+void
+message_destroy (struct GNUNET_CHAT_Message* message)
{
- return NULL;
+ GNUNET_free(message);
}
diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h
@@ -26,13 +26,27 @@
#define GNUNET_CHAT_MESSAGE_H_
#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_util_lib.h>
+struct GNUNET_CHAT_Context;
+
struct GNUNET_CHAT_Message
{
+ struct GNUNET_CHAT_Context *context;
+
struct GNUNET_HashCode hash;
- const struct GNUNET_MESSENGER_Message *message;
+
+ const struct GNUNET_MESSENGER_Message *msg;
};
+struct GNUNET_CHAT_Message*
+message_create_from_msg (struct GNUNET_CHAT_Context *context,
+ const struct GNUNET_HashCode *hash,
+ const struct GNUNET_MESSENGER_Message *msg);
+
+void
+message_destroy (struct GNUNET_CHAT_Message* message);
+
#endif /* GNUNET_CHAT_MESSAGE_H_ */
diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c
@@ -0,0 +1,45 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file gnunet_chat_util.c
+ */
+
+#include "gnunet_chat_util.h"
+
+void
+util_shorthash_from_member (const struct GNUNET_MESSENGER_Contact *member,
+ struct GNUNET_ShortHashCode* shorthash)
+{
+ memset(shorthash, 0, sizeof(*shorthash));
+ GNUNET_memcpy(shorthash, &member, sizeof(member));
+}
+
+void
+util_set_name_field (const char *name, char** field)
+{
+ if (*field)
+ GNUNET_free(*field);
+
+ if (name)
+ *field = GNUNET_strdup(name);
+ else
+ *field = NULL;
+}
diff --git a/src/gnunet_chat_util.h b/src/gnunet_chat_util.h
@@ -0,0 +1,40 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2021 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file gnunet_chat_util.h
+ */
+
+#ifndef GNUNET_CHAT_UTIL_H_
+#define GNUNET_CHAT_UTIL_H_
+
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_messenger_service.h>
+#include <gnunet/gnunet_util_lib.h>
+
+void
+util_shorthash_from_member (const struct GNUNET_MESSENGER_Contact *member,
+ struct GNUNET_ShortHashCode* shorthash);
+
+void
+util_set_name_field (const char *name, char** field);
+
+#endif /* GNUNET_CHAT_UTIL_H_ */