commit e366e189791025f7fad5572bc786f4883152812e
parent 5200796f0fe43ba498eaa7ea5c81e46cdc2d8116
Author: TheJackiMonster <thejackimonster@gmail.com>
Date: Sun, 4 Jul 2021 23:21:39 +0200
Additions to restructure generalized the messenger API for the purpose of chatting
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat:
16 files changed, 810 insertions(+), 88 deletions(-)
diff --git a/Makefile b/Makefile
@@ -7,9 +7,11 @@ LIBRARY = libgnunetchat.so
SOURCES = gnunet_chat_handle.c\
gnunet_chat_contact.c\
gnunet_chat_file.c\
+ gnunet_chat_invitation.c\
gnunet_chat_group.c\
gnunet_chat_context.c\
- gnunet_chat_message.c
+ gnunet_chat_message.c\
+ gnunet_chat_config.c
HEADERS = gnunet_chat_lib.h
LIBRARIES = gnunetarm\
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h
@@ -29,6 +29,8 @@
#ifndef GNUNET_CHAT_LIB_H_
#define GNUNET_CHAT_LIB_H_
+#define GNUNET_UNUSED __attribute__ ((unused))
+
#include <gnunet/platform.h>
#include <gnunet/gnunet_util_lib.h>
@@ -40,17 +42,22 @@ enum GNUNET_CHAT_MessageKind
/**
* TODO
*/
- GNUNET_CHAT_KIND_TEXT = 1, /**< GNUNET_CHAT_KIND_TEXT */
+ GNUNET_CHAT_KIND_TEXT = 1, /**< GNUNET_CHAT_KIND_TEXT */
+
+ /**
+ * TODO
+ */
+ GNUNET_CHAT_KIND_FILE = 2, /**< GNUNET_CHAT_KIND_FILE */
/**
* TODO
*/
- GNUNET_CHAT_KIND_FILE = 2, /**< GNUNET_CHAT_KIND_FILE */
+ GNUNET_CHAT_KIND_INVITATION = 3, /**< GNUNET_CHAT_KIND_INVITATION */
/**
* TODO
*/
- GNUNET_CHAT_KIND_UNKNOWN = 0/**< GNUNET_CHAT_KIND_UNKNOWN */
+ GNUNET_CHAT_KIND_UNKNOWN = 0 /**< GNUNET_CHAT_KIND_UNKNOWN */
};
/**
@@ -85,6 +92,11 @@ struct GNUNET_CHAT_File;
/**
* TODO
+ */
+struct GNUNET_CHAT_Invitation;
+
+/**
+ * TODO
*
* @param cls
* @param handle
@@ -157,8 +169,27 @@ typedef int
struct GNUNET_CHAT_Contact *contact,
int read_receipt);
-typedef void
-(*GNUNET_CHAT_MessageFileDownloadCallback) (void *cls, struct GNUNET_CHAT_File *file);
+/**
+ * TODO
+ *
+ * @param cls
+ * @param file
+ * @param completed
+ */
+typedef int
+(*GNUNET_CHAT_MessageFileUploadCallback) (void *cls, const struct GNUNET_CHAT_File *file,
+ uint64_t completed);
+
+/**
+ * TODO
+ *
+ * @param cls
+ * @param file
+ * @param completed
+ */
+typedef int
+(*GNUNET_CHAT_MessageFileDownloadCallback) (void *cls, struct GNUNET_CHAT_File *file,
+ uint64_t completed);
/**
* TODO
@@ -172,7 +203,8 @@ typedef void
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_WarningCallback warn_cb, void *warn_cls,
+ GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls);
/**
* TODO
@@ -306,8 +338,9 @@ GNUNET_CHAT_contact_get_context (struct GNUNET_CHAT_Contact *contact);
* TODO
*
* @param group
+ * @return
*/
-void
+int
GNUNET_CHAT_group_leave (struct GNUNET_CHAT_Group *group);
/**
@@ -418,11 +451,15 @@ GNUNET_CHAT_context_delete_message (struct GNUNET_CHAT_Context *context,
*
* @param context
* @param hash
+ * @param callback
+ * @param cls
* @return
*/
-const struct GNUNET_CHAT_Message*
+int
GNUNET_CHAT_context_get_message (struct GNUNET_CHAT_Context *context,
- const struct GNUNET_HashCode *hash);
+ const struct GNUNET_HashCode *hash,
+ GNUNET_CHAT_ContextMessageCallback callback,
+ void *cls);
/**
* TODO
@@ -499,33 +536,91 @@ GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message);
/**
* TODO
*
+ * @param message
+ * @return
+ */
+struct GNUNET_CHAT_Invitation*
+GNUNET_CHAT_message_get_invitation (const struct GNUNET_CHAT_Message *message);
+
+/**
+ * TODO
+ *
* @param file
+ * @return
*/
-void
-GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file);
+const struct GNUNET_HashCode*
+GNUNET_CHAT_file_get_hash (const struct GNUNET_CHAT_File *file);
/**
* TODO
*
* @param file
+ * @return
*/
-void
+uint64_t
+GNUNET_CHAT_file_get_size (const struct GNUNET_CHAT_File *file);
+
+/**
+ * TODO
+ *
+ * @param file
+ * @return
+ */
+int
+GNUNET_CHAT_file_is_local (const struct GNUNET_CHAT_File *file);
+
+/**
+ * TODO
+ *
+ * @param file
+ * @return
+ */
+int
+GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file,
+ GNUNET_CHAT_MessageFileDownloadCallback callback,
+ void *cls);
+
+/**
+ * TODO
+ *
+ * @param file
+ * @return
+ */
+int
GNUNET_CHAT_file_pause_download (struct GNUNET_CHAT_File *file);
/**
* TODO
*
* @param file
+ * @return
*/
-void
+int
GNUNET_CHAT_file_resume_download (struct GNUNET_CHAT_File *file);
/**
* TODO
*
* @param file
+ * @return
*/
-void
+int
GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file);
+/**
+ * TODO
+ *
+ * @param invitation
+ */
+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_config.c b/src/gnunet_chat_config.c
@@ -0,0 +1,27 @@
+/*
+ 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_config.c
+ */
+
+#include "gnunet_chat_config.h"
+
+
diff --git a/src/gnunet_chat_config.h b/src/gnunet_chat_config.h
@@ -0,0 +1,30 @@
+/*
+ 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_config.h
+ */
+
+#ifndef GNUNET_CHAT_CONFIG_H_
+#define GNUNET_CHAT_CONFIG_H_
+
+
+
+#endif /* GNUNET_CHAT_CONFIG_H_ */
diff --git a/src/gnunet_chat_contact.c b/src/gnunet_chat_contact.c
@@ -140,6 +140,10 @@ 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);
diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c
@@ -165,12 +165,14 @@ GNUNET_CHAT_context_delete_message (struct GNUNET_CHAT_Context *context,
GNUNET_MESSENGER_send_message(context->room, &message, NULL);
}
-const struct GNUNET_CHAT_Message*
+int
GNUNET_CHAT_context_get_message (struct GNUNET_CHAT_Context *context,
- const struct GNUNET_HashCode *hash)
+ const struct GNUNET_HashCode *hash,
+ GNUNET_CHAT_ContextMessageCallback callback,
+ void *cls)
{
if (!context)
- return NULL;
+ return GNUNET_SYSERR;
struct GNUNET_MESSENGER_Message *message = GNUNET_MESSENGER_get_message(
context->room, hash
@@ -178,7 +180,7 @@ GNUNET_CHAT_context_get_message (struct GNUNET_CHAT_Context *context,
//TODO: convert messenger-message to chat-message
- return NULL;
+ return GNUNET_OK;
}
int
diff --git a/src/gnunet_chat_file.c b/src/gnunet_chat_file.c
@@ -25,11 +25,31 @@
#include "gnunet_chat_lib.h"
#include "gnunet_chat_file.h"
-void
-GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file)
+const struct GNUNET_HashCode*
+GNUNET_CHAT_file_get_hash (const struct GNUNET_CHAT_File *file)
+{
+ return &(file->hash);
+}
+
+uint64_t
+GNUNET_CHAT_file_get_size (const struct GNUNET_CHAT_File *file)
+{
+ return 0;
+}
+
+int
+GNUNET_CHAT_file_is_local (const struct GNUNET_CHAT_File *file)
+{
+ return GNUNET_NO;
+}
+
+int
+GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file,
+ GNUNET_CHAT_MessageFileDownloadCallback callback,
+ void *cls)
{
if (!file)
- return;
+ return GNUNET_SYSERR;
struct GNUNET_FS_Handle *handle;
const char *path = ""; // TODO: path = download_directory + filename
@@ -47,31 +67,36 @@ GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file)
NULL,
NULL
);
+
+ return GNUNET_OK;
}
-void
+int
GNUNET_CHAT_file_pause_download (struct GNUNET_CHAT_File *file)
{
if (!file)
- return;
+ return GNUNET_SYSERR;
GNUNET_FS_download_suspend(file->context);
+ return GNUNET_OK;
}
-void
+int
GNUNET_CHAT_file_resume_download (struct GNUNET_CHAT_File *file)
{
if (!file)
- return;
+ return GNUNET_SYSERR;
GNUNET_FS_download_resume(file->context);
+ return GNUNET_OK;
}
-void
+int
GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file)
{
if (!file)
- return;
+ return GNUNET_SYSERR;
GNUNET_FS_download_stop(file->context, GNUNET_YES);
+ return GNUNET_OK;
}
diff --git a/src/gnunet_chat_file.h b/src/gnunet_chat_file.h
@@ -27,10 +27,12 @@
#include <gnunet/platform.h>
#include <gnunet/gnunet_fs_service.h>
+#include <gnunet/gnunet_messenger_service.h>
#include <gnunet/gnunet_util_lib.h>
struct GNUNET_CHAT_File
{
+ struct GNUNET_HashCode hash;
struct GNUNET_FS_Uri* uri;
struct GNUNET_FS_DownloadContext* context;
};
diff --git a/src/gnunet_chat_group.c b/src/gnunet_chat_group.c
@@ -46,6 +46,10 @@ group_create(struct GNUNET_CHAT_Handle *handle,
topic? &topic_key : NULL
);
+ group->is_public = topic? GNUNET_YES : GNUNET_NO;
+ group->announcement = NULL;
+ group->search = NULL;
+
if (!group->context)
{
group_destroy (group);
@@ -90,16 +94,20 @@ skip_context:
GNUNET_free(group);
}
-void
+int
GNUNET_CHAT_group_leave (struct GNUNET_CHAT_Group *group)
{
if (!group)
- return;
+ 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
diff --git a/src/gnunet_chat_group.h b/src/gnunet_chat_group.h
@@ -25,12 +25,19 @@
#ifndef GNUNET_CHAT_GROUP_H_
#define GNUNET_CHAT_GROUP_H_
+#include <gnunet/gnunet_regex_service.h>
+
#include "gnunet_chat_context.h"
struct GNUNET_CHAT_Group
{
struct GNUNET_CHAT_Handle *handle;
struct GNUNET_CHAT_Context *context;
+
+ int is_public;
+
+ struct GNUNET_REGEX_Announcement *announcement;
+ struct GNUNET_REGEX_Search *search;
};
struct GNUNET_CHAT_Group*
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c
@@ -25,57 +25,285 @@
#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_arm_connection(void* cls, int connected) {
- struct GNUNET_CHAT_Handle *handle = cls;
+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(handle->handles.arm, "messenger", GNUNET_OS_INHERIT_STD_NONE, NULL, NULL);
- GNUNET_ARM_request_service_start(handle->handles.arm, "fs", GNUNET_OS_INHERIT_STD_NONE, NULL, NULL);
+ 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(handle->handles.arm, "arm", GNUNET_OS_INHERIT_STD_NONE, NULL, NULL);
+ GNUNET_ARM_request_service_start(chat->handles.arm, "arm",
+ GNUNET_OS_INHERIT_STD_NONE, NULL, NULL);
}
}
struct GNUNET_CHAT_Handle*
GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle* cfg,
- const char *name,
- GNUNET_CHAT_WarningCallback warn_cb,
- void *warn_cls) {
+ const char *name,
+ GNUNET_CHAT_WarningCallback warn_cb,
+ void *warn_cls,
+ GNUNET_CHAT_ContextMessageCallback msg_cb,
+ void *msg_cls)
+{
if (!cfg)
return NULL;
- struct GNUNET_CHAT_Handle *handle = GNUNET_new(struct GNUNET_CHAT_Handle);
- memset(handle, 0, sizeof(*handle));
- handle->cfg = cfg;
+ struct GNUNET_CHAT_Handle *chat = GNUNET_new(struct GNUNET_CHAT_Handle);
+ memset(chat, 0, sizeof(*chat));
+ chat->cfg = cfg;
- handle->handles.arm = GNUNET_ARM_connect(cfg, &handle_arm_connection, handle);
+ chat->warn_cb = warn_cb;
+ chat->warn_cls = warn_cls;
- if (handle->handles.arm)
- handle_arm_connection(handle, GNUNET_NO);
+ chat->handles.arm = GNUNET_ARM_connect(cfg, &handle_arm_connection, chat);
+
+ if (chat->handles.arm)
+ handle_arm_connection(chat, GNUNET_NO);
- handle->handles.messenger = GNUNET_MESSENGER_connect(
- cfg, name, NULL, NULL, NULL, NULL //TODO
+ chat->handles.messenger = GNUNET_MESSENGER_connect(
+ cfg, name,
+ handle_on_identity, chat,
+ handle_on_message, chat
);
- if (!handle->handles.messenger)
+ if (!chat->handles.messenger)
{
- GNUNET_CHAT_stop(handle);
+ GNUNET_CHAT_stop(chat);
return NULL;
}
- handle->handles.fs = GNUNET_FS_start(
+ chat->handles.fs = GNUNET_FS_start(
cfg,
- NULL, //TODO
- NULL,
+ name,
+ handle_fs_progress,
+ chat,
GNUNET_FS_FLAGS_NONE,
GNUNET_FS_OPTIONS_END
);
- handle->contacts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
- handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO);
+ 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;
+}
- return 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;
}
void
@@ -102,18 +330,28 @@ GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle)
if (handle->groups)
{
- // TODO: destroy each
+ GNUNET_CONTAINER_multihashmap_iterate(
+ handle->groups, handle_iterate_destroy_groups, NULL
+ );
GNUNET_CONTAINER_multihashmap_destroy(handle->groups);
handle->groups = NULL;
}
- if (handle->contacts)
+ if (handle->contacts.hash_map)
{
- // TODO: destroy each
+ GNUNET_CONTAINER_multihashmap_iterate(
+ handle->contacts.hash_map, handle_iterate_destroy_contacts, NULL
+ );
- GNUNET_CONTAINER_multihashmap_destroy(handle->contacts);
- handle->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)
@@ -172,7 +410,8 @@ struct GNUNET_CHAT_IterateContacts
};
static int
-handle_iterate_contacts(void *cls, const struct GNUNET_HashCode *key,
+handle_iterate_contacts(void *cls,
+ GNUNET_UNUSED const struct GNUNET_HashCode *key,
void *value)
{
struct GNUNET_CHAT_IterateContacts *iterate = cls;
@@ -197,7 +436,7 @@ GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle,
iterate.callback = callback;
iterate.cls = cls;
- return GNUNET_CONTAINER_multihashmap_iterate(handle->contacts,
+ return GNUNET_CONTAINER_multihashmap_iterate(handle->contacts.hash_map,
handle_iterate_contacts,
&iterate);
}
@@ -209,7 +448,18 @@ GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle,
if (!handle)
return NULL;
- return group_create(handle, topic);
+ 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
@@ -220,8 +470,9 @@ struct GNUNET_CHAT_IterateGroups
};
static int
-handle_iterate_groups(void *cls, const struct GNUNET_HashCode *key,
- void *value)
+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;
@@ -246,6 +497,167 @@ GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle,
iterate.cls = cls;
return GNUNET_CONTAINER_multihashmap_iterate(handle->groups,
- handle_iterate_contacts,
+ 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
@@ -30,10 +30,7 @@
#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>
@@ -53,31 +50,62 @@ struct GNUNET_CHAT_Handle
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;
+ 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);
+
+int
+handle_update_chat_file (struct GNUNET_CHAT_Handle *handle,
+ struct GNUNET_CHAT_File *file,
+ int removeFile);
+
+struct GNUNET_CHAT_Contact*
+handle_get_chat_contact (struct GNUNET_CHAT_Handle *handle,
+ const struct GNUNET_MESSENGER_Contact *contact);
+
+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);
+
#endif /* GNUNET_CHAT_HANDLE_H_ */
diff --git a/src/gnunet_chat_invitation.c b/src/gnunet_chat_invitation.c
@@ -0,0 +1,37 @@
+/*
+ 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_invitation.c
+ */
+
+#include "gnunet_chat_invitation.h"
+
+void
+GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation)
+{
+ //TODO
+}
+
+void
+GNUNET_CHAT_invitation_decline (struct GNUNET_CHAT_Invitation *invitation)
+{
+ //TODO
+}
diff --git a/src/gnunet_chat_invitation.h b/src/gnunet_chat_invitation.h
@@ -0,0 +1,35 @@
+/*
+ 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_invitation.h
+ */
+
+#ifndef GNUNET_CHAT_INVITATION_H_
+#define GNUNET_CHAT_INVITATION_H_
+
+#include "gnunet_chat_lib.h"
+
+struct GNUNET_CHAT_Invitation
+{
+
+};
+
+#endif /* GNUNET_CHAT_INVITATION_H_ */
diff --git a/src/gnunet_chat_message.c b/src/gnunet_chat_message.c
@@ -32,6 +32,8 @@ GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message)
return GNUNET_CHAT_KIND_UNKNOWN;
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:
@@ -64,6 +66,12 @@ GNUNET_CHAT_message_get_read_receipt (const struct GNUNET_CHAT_Message *message,
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)
{
diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h
@@ -32,7 +32,7 @@
struct GNUNET_CHAT_Message
{
struct GNUNET_HashCode hash;
- struct GNUNET_MESSENGER_Message *message;
+ const struct GNUNET_MESSENGER_Message *message;
};
#endif /* GNUNET_CHAT_MESSAGE_H_ */