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