diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2021-07-11 02:33:00 +0200 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2021-07-11 02:33:00 +0200 |
commit | b880617514f9e64e991cb8d6fcff74ce3f292e36 (patch) | |
tree | 6f65a73f7ce40bdd3f5b3e9bc40f6477447cd8b3 | |
parent | e366e189791025f7fad5572bc786f4883152812e (diff) | |
download | libgnunetchat-b880617514f9e64e991cb8d6fcff74ce3f292e36.tar.gz libgnunetchat-b880617514f9e64e991cb8d6fcff74ce3f292e36.zip |
Code reorganized and refactored, most features implemented
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | include/gnunet_chat_lib.h | 29 | ||||
-rw-r--r-- | src/gnunet_chat_contact.c | 155 | ||||
-rw-r--r-- | src/gnunet_chat_contact.h | 22 | ||||
-rw-r--r-- | src/gnunet_chat_context.c | 160 | ||||
-rw-r--r-- | src/gnunet_chat_context.h | 28 | ||||
-rw-r--r-- | src/gnunet_chat_file.c | 84 | ||||
-rw-r--r-- | src/gnunet_chat_file.h | 21 | ||||
-rw-r--r-- | src/gnunet_chat_group.c | 201 | ||||
-rw-r--r-- | src/gnunet_chat_group.h | 17 | ||||
-rw-r--r-- | src/gnunet_chat_group_intern.c | 51 | ||||
-rw-r--r-- | src/gnunet_chat_handle.c | 653 | ||||
-rw-r--r-- | src/gnunet_chat_handle.h | 79 | ||||
-rw-r--r-- | src/gnunet_chat_handle_intern.c | 308 | ||||
-rw-r--r-- | src/gnunet_chat_invitation.c | 20 | ||||
-rw-r--r-- | src/gnunet_chat_invitation.h | 19 | ||||
-rw-r--r-- | src/gnunet_chat_lib.c | 693 | ||||
-rw-r--r-- | src/gnunet_chat_lib_intern.c | 124 | ||||
-rw-r--r-- | src/gnunet_chat_message.c | 68 | ||||
-rw-r--r-- | src/gnunet_chat_message.h | 16 | ||||
-rw-r--r-- | src/gnunet_chat_util.c | 45 | ||||
-rw-r--r-- | src/gnunet_chat_util.h | 40 |
22 files changed, 1508 insertions, 1338 deletions
@@ -4,14 +4,17 @@ INCLUDE_DIR = include/ | |||
4 | INSTALL_DIR = /usr/local/ | 4 | INSTALL_DIR = /usr/local/ |
5 | 5 | ||
6 | LIBRARY = libgnunetchat.so | 6 | LIBRARY = libgnunetchat.so |
7 | SOURCES = gnunet_chat_handle.c\ | 7 | SOURCES = gnunet_chat_lib.c\ |
8 | gnunet_chat_contact.c\ | 8 | gnunet_chat_config.c\ |
9 | gnunet_chat_contact.c\ | ||
10 | gnunet_chat_context.c\ | ||
9 | gnunet_chat_file.c\ | 11 | gnunet_chat_file.c\ |
10 | gnunet_chat_invitation.c\ | ||
11 | gnunet_chat_group.c\ | 12 | gnunet_chat_group.c\ |
12 | gnunet_chat_context.c\ | 13 | gnunet_chat_handle.c\ |
14 | gnunet_chat_invitation.c\ | ||
13 | gnunet_chat_message.c\ | 15 | gnunet_chat_message.c\ |
14 | gnunet_chat_config.c | 16 | gnunet_chat_util.c |
17 | |||
15 | HEADERS = gnunet_chat_lib.h | 18 | HEADERS = gnunet_chat_lib.h |
16 | 19 | ||
17 | LIBRARIES = gnunetarm\ | 20 | LIBRARIES = gnunetarm\ |
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h index f2605b9..4c15df5 100644 --- a/include/gnunet_chat_lib.h +++ b/include/gnunet_chat_lib.h | |||
@@ -29,9 +29,8 @@ | |||
29 | #ifndef GNUNET_CHAT_LIB_H_ | 29 | #ifndef GNUNET_CHAT_LIB_H_ |
30 | #define GNUNET_CHAT_LIB_H_ | 30 | #define GNUNET_CHAT_LIB_H_ |
31 | 31 | ||
32 | #define GNUNET_UNUSED __attribute__ ((unused)) | ||
33 | |||
34 | #include <gnunet/platform.h> | 32 | #include <gnunet/platform.h> |
33 | #include <gnunet/gnunet_common.h> | ||
35 | #include <gnunet/gnunet_util_lib.h> | 34 | #include <gnunet/gnunet_util_lib.h> |
36 | 35 | ||
37 | /** | 36 | /** |
@@ -442,29 +441,13 @@ GNUNET_CHAT_context_share_file (struct GNUNET_CHAT_Context *context, | |||
442 | * @param delay | 441 | * @param delay |
443 | */ | 442 | */ |
444 | void | 443 | void |
445 | GNUNET_CHAT_context_delete_message (struct GNUNET_CHAT_Context *context, | 444 | GNUNET_CHAT_context_delete_message (const struct GNUNET_CHAT_Message *message, |
446 | const struct GNUNET_HashCode *hash, | ||
447 | struct GNUNET_TIME_Relative delay); | 445 | struct GNUNET_TIME_Relative delay); |
448 | 446 | ||
449 | /** | 447 | /** |
450 | * TODO | 448 | * TODO |
451 | * | 449 | * |
452 | * @param context | 450 | * @param context |
453 | * @param hash | ||
454 | * @param callback | ||
455 | * @param cls | ||
456 | * @return | ||
457 | */ | ||
458 | int | ||
459 | GNUNET_CHAT_context_get_message (struct GNUNET_CHAT_Context *context, | ||
460 | const struct GNUNET_HashCode *hash, | ||
461 | GNUNET_CHAT_ContextMessageCallback callback, | ||
462 | void *cls); | ||
463 | |||
464 | /** | ||
465 | * TODO | ||
466 | * | ||
467 | * @param context | ||
468 | * @param callback | 451 | * @param callback |
469 | * @param cls | 452 | * @param cls |
470 | * @return | 453 | * @return |
@@ -615,12 +598,4 @@ GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file); | |||
615 | void | 598 | void |
616 | GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation); | 599 | GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation); |
617 | 600 | ||
618 | /** | ||
619 | * TODO | ||
620 | * | ||
621 | * @param invitation | ||
622 | */ | ||
623 | void | ||
624 | GNUNET_CHAT_invitation_decline (struct GNUNET_CHAT_Invitation *invitation); | ||
625 | |||
626 | #endif /* GNUNET_CHAT_LIB_H_ */ | 601 | #endif /* GNUNET_CHAT_LIB_H_ */ |
diff --git a/src/gnunet_chat_contact.c b/src/gnunet_chat_contact.c index d1d92ff..a172c8e 100644 --- a/src/gnunet_chat_contact.c +++ b/src/gnunet_chat_contact.c | |||
@@ -22,169 +22,26 @@ | |||
22 | * @file gnunet_chat_contact.c | 22 | * @file gnunet_chat_contact.c |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "gnunet_chat_lib.h" | ||
26 | #include "gnunet_chat_contact.h" | 25 | #include "gnunet_chat_contact.h" |
27 | #include "gnunet_chat_handle.h" | ||
28 | 26 | ||
29 | struct GNUNET_CHAT_Contact* | 27 | struct GNUNET_CHAT_Contact* |
30 | contact_create (struct GNUNET_CHAT_Handle *handle, | 28 | contact_create_from_member (struct GNUNET_CHAT_Handle *handle, |
31 | const struct GNUNET_MESSENGER_Contact *msg_contact) | 29 | const struct GNUNET_MESSENGER_Contact *member) |
32 | { | 30 | { |
33 | struct GNUNET_CHAT_Contact* contact = GNUNET_new(struct GNUNET_CHAT_Contact); | 31 | struct GNUNET_CHAT_Contact* contact = GNUNET_new(struct GNUNET_CHAT_Contact); |
34 | 32 | ||
35 | contact->handle = handle; | 33 | contact->handle = handle; |
36 | contact->context = context_create( | 34 | contact->context = NULL; |
37 | handle, | ||
38 | GNUNET_CHAT_CONTEXT_TYPE_CONTACT, | ||
39 | NULL | ||
40 | ); // TODO: check for existing context? | ||
41 | 35 | ||
42 | contact->contact = msg_contact; | 36 | // TODO: search for private context? create private context? |
43 | 37 | ||
44 | if (!contact->context) | 38 | contact->member = member; |
45 | { | ||
46 | contact_destroy (contact); | ||
47 | return NULL; | ||
48 | } | ||
49 | |||
50 | const struct GNUNET_HashCode *key = context_get_key(contact->context); | ||
51 | |||
52 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
53 | handle->contacts, | ||
54 | key, | ||
55 | contact, | ||
56 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST | ||
57 | ); | ||
58 | |||
59 | if (GNUNET_OK != result) { | ||
60 | contact_destroy (contact); | ||
61 | return NULL; | ||
62 | } | ||
63 | 39 | ||
64 | return contact; | 40 | return contact; |
65 | } | 41 | } |
66 | 42 | ||
67 | void | 43 | void |
68 | contact_destroy (struct GNUNET_CHAT_Contact *contact) | 44 | contact_destroy (struct GNUNET_CHAT_Contact* contact) |
69 | { | 45 | { |
70 | if (!contact->context) | ||
71 | goto skip_context; | ||
72 | |||
73 | struct GNUNET_CHAT_Handle *handle = contact->handle; | ||
74 | const struct GNUNET_HashCode *key = context_get_key(contact->context); | ||
75 | |||
76 | GNUNET_CONTAINER_multihashmap_remove( | ||
77 | handle->contacts, | ||
78 | key, | ||
79 | contact | ||
80 | ); | ||
81 | |||
82 | context_destroy(contact->context); | ||
83 | |||
84 | skip_context: | ||
85 | GNUNET_free(contact); | 46 | GNUNET_free(contact); |
86 | } | 47 | } |
87 | |||
88 | struct GNUNET_CHAT_SearchContact | ||
89 | { | ||
90 | struct GNUNET_MESSENGER_Contact *contact; | ||
91 | const struct GNUNET_MESSENGER_Contact *msg_contact; | ||
92 | }; | ||
93 | |||
94 | static int | ||
95 | contact_search (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
96 | { | ||
97 | struct GNUNET_CHAT_Contact *contact = value; | ||
98 | struct GNUNET_CHAT_SearchContact *search = cls; | ||
99 | |||
100 | if (contact->contact == search->msg_contact) | ||
101 | { | ||
102 | search->contact = contact; | ||
103 | return GNUNET_NO; | ||
104 | } | ||
105 | |||
106 | return GNUNET_YES; | ||
107 | } | ||
108 | |||
109 | int | ||
110 | contact_call (struct GNUNET_CHAT_Handle *handle, | ||
111 | const struct GNUNET_MESSENGER_Contact *msg_contact, | ||
112 | GNUNET_CHAT_ContactCallback callback, | ||
113 | void *cls) | ||
114 | { | ||
115 | struct GNUNET_CHAT_SearchContact search; | ||
116 | search.contact = NULL; | ||
117 | search.msg_contact = msg_contact; | ||
118 | |||
119 | GNUNET_CONTAINER_multihashmap_iterate( | ||
120 | handle->contacts, | ||
121 | contact_search, | ||
122 | &search | ||
123 | ); | ||
124 | |||
125 | if (search.contact) | ||
126 | return callback(cls, handle, search.contact); | ||
127 | |||
128 | search.contact = contact_create(handle, msg_contact); | ||
129 | int result = callback(cls, handle, search.contact); | ||
130 | |||
131 | // TODO: check if contact has private chat | ||
132 | |||
133 | contact_destroy(search.contact); | ||
134 | return result; | ||
135 | } | ||
136 | |||
137 | int | ||
138 | GNUNET_CHAT_contact_delete (struct GNUNET_CHAT_Contact *contact) | ||
139 | { | ||
140 | if (!contact) | ||
141 | return GNUNET_SYSERR; | ||
142 | |||
143 | if (GNUNET_YES != handle_update_chat_contact(contact->handle, | ||
144 | contact, GNUNET_YES)) | ||
145 | return GNUNET_SYSERR; | ||
146 | |||
147 | if (contact->context) | ||
148 | GNUNET_MESSENGER_close_room(contact->context->room); | ||
149 | |||
150 | contact_destroy(contact); | ||
151 | return GNUNET_OK; | ||
152 | } | ||
153 | |||
154 | void | ||
155 | GNUNET_CHAT_contact_set_name (struct GNUNET_CHAT_Contact *contact, | ||
156 | const char *name) | ||
157 | { | ||
158 | if (!contact) | ||
159 | return; | ||
160 | |||
161 | if (contact->context) | ||
162 | context_set_nick(contact->context, name); | ||
163 | } | ||
164 | |||
165 | const char* | ||
166 | GNUNET_CHAT_contact_get_name (const struct GNUNET_CHAT_Contact *contact) | ||
167 | { | ||
168 | if (!contact) | ||
169 | return NULL; | ||
170 | |||
171 | if (!contact->context) | ||
172 | goto skip_context; | ||
173 | |||
174 | const char *nick = context_get_nick(contact->context); | ||
175 | |||
176 | if (nick) | ||
177 | return nick; | ||
178 | |||
179 | skip_context: | ||
180 | return GNUNET_MESSENGER_contact_get_name(contact->contact); | ||
181 | } | ||
182 | |||
183 | struct GNUNET_CHAT_Context* | ||
184 | GNUNET_CHAT_contact_get_context (struct GNUNET_CHAT_Contact *contact) | ||
185 | { | ||
186 | if (!contact) | ||
187 | return NULL; | ||
188 | |||
189 | return contact->context; | ||
190 | } | ||
diff --git a/src/gnunet_chat_contact.h b/src/gnunet_chat_contact.h index e215c5f..1cf5618 100644 --- a/src/gnunet_chat_contact.h +++ b/src/gnunet_chat_contact.h | |||
@@ -25,27 +25,27 @@ | |||
25 | #ifndef GNUNET_CHAT_CONTACT_H_ | 25 | #ifndef GNUNET_CHAT_CONTACT_H_ |
26 | #define GNUNET_CHAT_CONTACT_H_ | 26 | #define GNUNET_CHAT_CONTACT_H_ |
27 | 27 | ||
28 | #include "gnunet_chat_context.h" | 28 | #include <gnunet/platform.h> |
29 | #include <gnunet/gnunet_common.h> | ||
30 | #include <gnunet/gnunet_messenger_service.h> | ||
31 | #include <gnunet/gnunet_util_lib.h> | ||
32 | |||
33 | struct GNUNET_CHAT_Handle; | ||
34 | struct GNUNET_CHAT_Context; | ||
29 | 35 | ||
30 | struct GNUNET_CHAT_Contact | 36 | struct GNUNET_CHAT_Contact |
31 | { | 37 | { |
32 | struct GNUNET_CHAT_Handle *handle; | 38 | struct GNUNET_CHAT_Handle *handle; |
33 | struct GNUNET_CHAT_Context *context; | 39 | struct GNUNET_CHAT_Context *context; |
34 | 40 | ||
35 | const struct GNUNET_MESSENGER_Contact *contact; | 41 | const struct GNUNET_MESSENGER_Contact *member; |
36 | }; | 42 | }; |
37 | 43 | ||
38 | struct GNUNET_CHAT_Contact* | 44 | struct GNUNET_CHAT_Contact* |
39 | contact_create (struct GNUNET_CHAT_Handle *handle, | 45 | contact_create_from_member (struct GNUNET_CHAT_Handle *handle, |
40 | const struct GNUNET_MESSENGER_Contact *msg_contact); | 46 | const struct GNUNET_MESSENGER_Contact *member); |
41 | 47 | ||
42 | void | 48 | void |
43 | contact_destroy (struct GNUNET_CHAT_Contact *contact); | 49 | contact_destroy (struct GNUNET_CHAT_Contact* contact); |
44 | |||
45 | int | ||
46 | contact_call (struct GNUNET_CHAT_Handle *handle, | ||
47 | const struct GNUNET_MESSENGER_Contact *msg_contact, | ||
48 | GNUNET_CHAT_ContactCallback callback, | ||
49 | void *cls); | ||
50 | 50 | ||
51 | #endif /* GNUNET_CHAT_CONTACT_H_ */ | 51 | #endif /* GNUNET_CHAT_CONTACT_H_ */ |
diff --git a/src/gnunet_chat_context.c b/src/gnunet_chat_context.c index 27e8f35..54c63f7 100644 --- a/src/gnunet_chat_context.c +++ b/src/gnunet_chat_context.c | |||
@@ -22,171 +22,37 @@ | |||
22 | * @file gnunet_chat_context.c | 22 | * @file gnunet_chat_context.c |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "gnunet_chat_lib.h" | ||
26 | #include "gnunet_chat_context.h" | 25 | #include "gnunet_chat_context.h" |
27 | #include "gnunet_chat_handle.h" | ||
28 | 26 | ||
29 | struct GNUNET_CHAT_Context* | 27 | struct GNUNET_CHAT_Context* |
30 | context_create (struct GNUNET_CHAT_Handle *handle, | 28 | context_create_from_room (struct GNUNET_CHAT_Handle *handle, |
31 | enum GNUNET_CHAT_ContextType type, | 29 | struct GNUNET_MESSENGER_Room *room) |
32 | const struct GNUNET_HashCode *key) | ||
33 | { | 30 | { |
34 | struct GNUNET_MESSENGER_Handle *messenger = handle->handles.messenger; | ||
35 | |||
36 | struct GNUNET_HashCode _room_key; | ||
37 | const struct GNUNET_HashCode *room_key; | ||
38 | |||
39 | if (key) | ||
40 | room_key = key; | ||
41 | else | ||
42 | { | ||
43 | GNUNET_CRYPTO_random_block( | ||
44 | GNUNET_CRYPTO_QUALITY_WEAK, | ||
45 | &_room_key, | ||
46 | sizeof(_room_key) | ||
47 | ); | ||
48 | |||
49 | room_key = &_room_key; | ||
50 | } | ||
51 | |||
52 | struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_open_room( | ||
53 | messenger, room_key | ||
54 | ); | ||
55 | |||
56 | if (!room) | ||
57 | return NULL; | ||
58 | |||
59 | struct GNUNET_CHAT_Context* context = GNUNET_new(struct GNUNET_CHAT_Context); | 31 | struct GNUNET_CHAT_Context* context = GNUNET_new(struct GNUNET_CHAT_Context); |
60 | 32 | ||
61 | context->handle = handle; | 33 | context->handle = handle; |
62 | context->room = room; | ||
63 | 34 | ||
64 | context->type = type; | 35 | context->type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN; |
65 | GNUNET_memcpy(&(context->key), room_key, sizeof(_room_key)); | ||
66 | context->nick = NULL; | 36 | context->nick = NULL; |
67 | 37 | ||
38 | context->messages = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
39 | context->invites = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
40 | context->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
41 | |||
42 | context->room = room; | ||
43 | |||
68 | return context; | 44 | return context; |
69 | } | 45 | } |
70 | 46 | ||
71 | void | 47 | void |
72 | context_destroy (struct GNUNET_CHAT_Context* context) | 48 | context_destroy (struct GNUNET_CHAT_Context* context) |
73 | { | 49 | { |
74 | GNUNET_free(context); | 50 | GNUNET_CONTAINER_multihashmap_destroy(context->messages); |
75 | } | 51 | GNUNET_CONTAINER_multihashmap_destroy(context->invites); |
76 | 52 | GNUNET_CONTAINER_multihashmap_destroy(context->files); | |
77 | enum GNUNET_CHAT_ContextType | ||
78 | context_get_type (struct GNUNET_CHAT_Context* context) | ||
79 | { | ||
80 | return context->type; | ||
81 | } | ||
82 | 53 | ||
83 | const struct GNUNET_HashCode* | ||
84 | context_get_key (struct GNUNET_CHAT_Context* context) | ||
85 | { | ||
86 | return &(context->key); | ||
87 | } | ||
88 | |||
89 | const char* | ||
90 | context_get_nick (struct GNUNET_CHAT_Context* context) | ||
91 | { | ||
92 | return context->nick; | ||
93 | } | ||
94 | |||
95 | void | ||
96 | context_set_nick (struct GNUNET_CHAT_Context* context, | ||
97 | const char *nick) | ||
98 | { | ||
99 | if (context->nick) | 54 | if (context->nick) |
100 | GNUNET_free(context->nick); | 55 | GNUNET_free(context->nick); |
101 | 56 | ||
102 | context->nick = nick? GNUNET_strdup(nick) : NULL; | 57 | GNUNET_free(context); |
103 | } | ||
104 | |||
105 | void | ||
106 | GNUNET_CHAT_context_send_text (struct GNUNET_CHAT_Context *context, | ||
107 | const char *text) | ||
108 | { | ||
109 | if (!context) | ||
110 | return; | ||
111 | |||
112 | struct GNUNET_MESSENGER_Message message; | ||
113 | message.header.kind = GNUNET_MESSENGER_KIND_TEXT; | ||
114 | message.body.text.text = text; | ||
115 | |||
116 | GNUNET_MESSENGER_send_message(context->room, &message, NULL); | ||
117 | } | ||
118 | |||
119 | void | ||
120 | GNUNET_CHAT_context_send_file (struct GNUNET_CHAT_Context *context, | ||
121 | const char *path) | ||
122 | { | ||
123 | //TODO: generate key, hash file, encrypt file, upload file, share uri & info | ||
124 | } | ||
125 | |||
126 | void | ||
127 | GNUNET_CHAT_context_send_uri (struct GNUNET_CHAT_Context *context, | ||
128 | const char *uri) | ||
129 | { | ||
130 | if (!context) | ||
131 | return; | ||
132 | |||
133 | struct GNUNET_MESSENGER_Message message; | ||
134 | message.header.kind = GNUNET_MESSENGER_KIND_FILE; | ||
135 | |||
136 | memset(&(message.body.file.key), 0, sizeof(message.body.file.key)); | ||
137 | |||
138 | message.body.file.hash; // TODO: download & hash | ||
139 | GNUNET_memcpy(message.body.file.name, "", 1); // TODO: cut from uri or get from download? | ||
140 | message.body.file.uri = uri; | ||
141 | |||
142 | GNUNET_MESSENGER_send_message(context->room, &message, NULL); | ||
143 | } | ||
144 | |||
145 | void | ||
146 | GNUNET_CHAT_context_share_file (struct GNUNET_CHAT_Context *context, | ||
147 | const struct GNUNET_CHAT_File *file) | ||
148 | { | ||
149 | //TODO: send copied message basically | ||
150 | } | ||
151 | |||
152 | void | ||
153 | GNUNET_CHAT_context_delete_message (struct GNUNET_CHAT_Context *context, | ||
154 | const struct GNUNET_HashCode *hash, | ||
155 | struct GNUNET_TIME_Relative delay) | ||
156 | { | ||
157 | if (!context) | ||
158 | return; | ||
159 | |||
160 | struct GNUNET_MESSENGER_Message message; | ||
161 | message.header.kind = GNUNET_MESSENGER_KIND_TEXT; | ||
162 | GNUNET_memcpy(&(message.body.delete.hash), hash, sizeof(*hash)); | ||
163 | message.body.delete.delay = GNUNET_TIME_relative_hton(delay); | ||
164 | |||
165 | GNUNET_MESSENGER_send_message(context->room, &message, NULL); | ||
166 | } | ||
167 | |||
168 | int | ||
169 | GNUNET_CHAT_context_get_message (struct GNUNET_CHAT_Context *context, | ||
170 | const struct GNUNET_HashCode *hash, | ||
171 | GNUNET_CHAT_ContextMessageCallback callback, | ||
172 | void *cls) | ||
173 | { | ||
174 | if (!context) | ||
175 | return GNUNET_SYSERR; | ||
176 | |||
177 | struct GNUNET_MESSENGER_Message *message = GNUNET_MESSENGER_get_message( | ||
178 | context->room, hash | ||
179 | ); | ||
180 | |||
181 | //TODO: convert messenger-message to chat-message | ||
182 | |||
183 | return GNUNET_OK; | ||
184 | } | ||
185 | |||
186 | int | ||
187 | GNUNET_CHAT_context_iterate_messages (struct GNUNET_CHAT_Context *context, | ||
188 | GNUNET_CHAT_ContextMessageCallback callback, | ||
189 | void *cls) | ||
190 | { | ||
191 | return GNUNET_SYSERR; | ||
192 | } | 58 | } |
diff --git a/src/gnunet_chat_context.h b/src/gnunet_chat_context.h index 87f7dfd..e975312 100644 --- a/src/gnunet_chat_context.h +++ b/src/gnunet_chat_context.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #define GNUNET_CHAT_CONTEXT_H_ | 26 | #define GNUNET_CHAT_CONTEXT_H_ |
27 | 27 | ||
28 | #include <gnunet/platform.h> | 28 | #include <gnunet/platform.h> |
29 | #include <gnunet/gnunet_common.h> | ||
30 | #include <gnunet/gnunet_container_lib.h> | ||
29 | #include <gnunet/gnunet_messenger_service.h> | 31 | #include <gnunet/gnunet_messenger_service.h> |
30 | #include <gnunet/gnunet_util_lib.h> | 32 | #include <gnunet/gnunet_util_lib.h> |
31 | 33 | ||
@@ -41,32 +43,22 @@ struct GNUNET_CHAT_Handle; | |||
41 | struct GNUNET_CHAT_Context | 43 | struct GNUNET_CHAT_Context |
42 | { | 44 | { |
43 | struct GNUNET_CHAT_Handle *handle; | 45 | struct GNUNET_CHAT_Handle *handle; |
44 | struct GNUNET_MESSENGER_Room *room; | ||
45 | 46 | ||
46 | enum GNUNET_CHAT_ContextType type; | 47 | enum GNUNET_CHAT_ContextType type; |
47 | struct GNUNET_HashCode key; | ||
48 | char *nick; | 48 | char *nick; |
49 | |||
50 | struct GNUNET_CONTAINER_MultiHashMap *messages; | ||
51 | struct GNUNET_CONTAINER_MultiHashMap *invites; | ||
52 | struct GNUNET_CONTAINER_MultiHashMap *files; | ||
53 | |||
54 | struct GNUNET_MESSENGER_Room *room; | ||
49 | }; | 55 | }; |
50 | 56 | ||
51 | struct GNUNET_CHAT_Context* | 57 | struct GNUNET_CHAT_Context* |
52 | context_create (struct GNUNET_CHAT_Handle *handle, | 58 | context_create_from_room (struct GNUNET_CHAT_Handle *handle, |
53 | enum GNUNET_CHAT_ContextType type, | 59 | struct GNUNET_MESSENGER_Room *room); |
54 | const struct GNUNET_HashCode *key); | ||
55 | 60 | ||
56 | void | 61 | void |
57 | context_destroy (struct GNUNET_CHAT_Context* context); | 62 | context_destroy (struct GNUNET_CHAT_Context* context); |
58 | 63 | ||
59 | enum GNUNET_CHAT_ContextType | ||
60 | context_get_type (struct GNUNET_CHAT_Context* context); | ||
61 | |||
62 | const struct GNUNET_HashCode* | ||
63 | context_get_key (struct GNUNET_CHAT_Context* context); | ||
64 | |||
65 | const char* | ||
66 | context_get_nick (struct GNUNET_CHAT_Context* context); | ||
67 | |||
68 | void | ||
69 | context_set_nick (struct GNUNET_CHAT_Context* context, | ||
70 | const char *nick); | ||
71 | |||
72 | #endif /* GNUNET_CHAT_CONTEXT_H_ */ | 64 | #endif /* GNUNET_CHAT_CONTEXT_H_ */ |
diff --git a/src/gnunet_chat_file.c b/src/gnunet_chat_file.c index b5f480c..d472551 100644 --- a/src/gnunet_chat_file.c +++ b/src/gnunet_chat_file.c | |||
@@ -22,81 +22,39 @@ | |||
22 | * @file gnunet_chat_file.c | 22 | * @file gnunet_chat_file.c |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "gnunet_chat_lib.h" | ||
26 | #include "gnunet_chat_file.h" | 25 | #include "gnunet_chat_file.h" |
27 | 26 | ||
28 | const struct GNUNET_HashCode* | 27 | #include <limits.h> |
29 | GNUNET_CHAT_file_get_hash (const struct GNUNET_CHAT_File *file) | ||
30 | { | ||
31 | return &(file->hash); | ||
32 | } | ||
33 | 28 | ||
34 | uint64_t | 29 | struct GNUNET_CHAT_File* |
35 | GNUNET_CHAT_file_get_size (const struct GNUNET_CHAT_File *file) | 30 | file_create_from_message (struct GNUNET_CHAT_Handle *handle, |
31 | const struct GNUNET_MESSENGER_MessageFile* message) | ||
36 | { | 32 | { |
37 | return 0; | 33 | struct GNUNET_CHAT_File* file = GNUNET_new(struct GNUNET_CHAT_File); |
38 | } | ||
39 | 34 | ||
40 | int | 35 | file->handle = handle; |
41 | GNUNET_CHAT_file_is_local (const struct GNUNET_CHAT_File *file) | ||
42 | { | ||
43 | return GNUNET_NO; | ||
44 | } | ||
45 | 36 | ||
46 | int | 37 | file->name = GNUNET_strndup(message->name, NAME_MAX); |
47 | GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file, | ||
48 | GNUNET_CHAT_MessageFileDownloadCallback callback, | ||
49 | void *cls) | ||
50 | { | ||
51 | if (!file) | ||
52 | return GNUNET_SYSERR; | ||
53 | 38 | ||
54 | struct GNUNET_FS_Handle *handle; | 39 | GNUNET_memcpy(&(file->key), &(message->key), sizeof(file->key)); |
55 | const char *path = ""; // TODO: path = download_directory + filename | 40 | GNUNET_memcpy(&(file->hash), &(message->hash), sizeof(file->hash)); |
56 | 41 | ||
57 | GNUNET_FS_download_start( | 42 | file->uri = GNUNET_FS_uri_parse(message->uri, NULL); |
58 | handle, | 43 | file->download = NULL; |
59 | file->uri, | 44 | file->publish = NULL; |
60 | NULL, | 45 | file->unindex = NULL; |
61 | path, | ||
62 | NULL, | ||
63 | 0, | ||
64 | 0, | ||
65 | 0, | ||
66 | GNUNET_FS_DOWNLOAD_OPTION_NONE, | ||
67 | NULL, | ||
68 | NULL | ||
69 | ); | ||
70 | 46 | ||
71 | return GNUNET_OK; | 47 | return file; |
72 | } | 48 | } |
73 | 49 | ||
74 | int | 50 | void |
75 | GNUNET_CHAT_file_pause_download (struct GNUNET_CHAT_File *file) | 51 | file_destroy (struct GNUNET_CHAT_File* file) |
76 | { | 52 | { |
77 | if (!file) | 53 | if (file->uri) |
78 | return GNUNET_SYSERR; | 54 | GNUNET_FS_uri_destroy(file->uri); |
79 | 55 | ||
80 | GNUNET_FS_download_suspend(file->context); | 56 | if (file->name) |
81 | return GNUNET_OK; | 57 | GNUNET_free(file->name); |
82 | } | ||
83 | |||
84 | int | ||
85 | GNUNET_CHAT_file_resume_download (struct GNUNET_CHAT_File *file) | ||
86 | { | ||
87 | if (!file) | ||
88 | return GNUNET_SYSERR; | ||
89 | |||
90 | GNUNET_FS_download_resume(file->context); | ||
91 | return GNUNET_OK; | ||
92 | } | ||
93 | |||
94 | int | ||
95 | GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file) | ||
96 | { | ||
97 | if (!file) | ||
98 | return GNUNET_SYSERR; | ||
99 | 58 | ||
100 | GNUNET_FS_download_stop(file->context, GNUNET_YES); | 59 | GNUNET_free(file); |
101 | return GNUNET_OK; | ||
102 | } | 60 | } |
diff --git a/src/gnunet_chat_file.h b/src/gnunet_chat_file.h index ae45def..9669bf2 100644 --- a/src/gnunet_chat_file.h +++ b/src/gnunet_chat_file.h | |||
@@ -26,15 +26,34 @@ | |||
26 | #define GNUNET_CHAT_FILE_H_ | 26 | #define GNUNET_CHAT_FILE_H_ |
27 | 27 | ||
28 | #include <gnunet/platform.h> | 28 | #include <gnunet/platform.h> |
29 | #include <gnunet/gnunet_common.h> | ||
30 | #include <gnunet/gnunet_crypto_lib.h> | ||
29 | #include <gnunet/gnunet_fs_service.h> | 31 | #include <gnunet/gnunet_fs_service.h> |
30 | #include <gnunet/gnunet_messenger_service.h> | 32 | #include <gnunet/gnunet_messenger_service.h> |
31 | #include <gnunet/gnunet_util_lib.h> | 33 | #include <gnunet/gnunet_util_lib.h> |
32 | 34 | ||
35 | struct GNUNET_CHAT_Handle; | ||
36 | |||
33 | struct GNUNET_CHAT_File | 37 | struct GNUNET_CHAT_File |
34 | { | 38 | { |
39 | struct GNUNET_CHAT_Handle *handle; | ||
40 | |||
41 | char *name; | ||
42 | |||
35 | struct GNUNET_HashCode hash; | 43 | struct GNUNET_HashCode hash; |
44 | struct GNUNET_CRYPTO_SymmetricSessionKey key; | ||
45 | |||
36 | struct GNUNET_FS_Uri* uri; | 46 | struct GNUNET_FS_Uri* uri; |
37 | struct GNUNET_FS_DownloadContext* context; | 47 | struct GNUNET_FS_DownloadContext* download; |
48 | struct GNUNET_FS_PublishContext* publish; | ||
49 | struct GNUNET_FS_UnindexContext* unindex; | ||
38 | }; | 50 | }; |
39 | 51 | ||
52 | struct GNUNET_CHAT_File* | ||
53 | file_create_from_message (struct GNUNET_CHAT_Handle *handle, | ||
54 | const struct GNUNET_MESSENGER_MessageFile* message); | ||
55 | |||
56 | void | ||
57 | file_destroy (struct GNUNET_CHAT_File* file); | ||
58 | |||
40 | #endif /* GNUNET_CHAT_FILE_H_ */ | 59 | #endif /* GNUNET_CHAT_FILE_H_ */ |
diff --git a/src/gnunet_chat_group.c b/src/gnunet_chat_group.c index e027b19..0c998ec 100644 --- a/src/gnunet_chat_group.c +++ b/src/gnunet_chat_group.c | |||
@@ -22,208 +22,53 @@ | |||
22 | * @file gnunet_chat_group.c | 22 | * @file gnunet_chat_group.c |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "gnunet_chat_lib.h" | ||
26 | #include "gnunet_chat_group.h" | 25 | #include "gnunet_chat_group.h" |
27 | #include "gnunet_chat_handle.h" | 26 | |
28 | #include "gnunet_chat_contact.h" | 27 | #include "gnunet_chat_group_intern.c" |
29 | 28 | ||
30 | struct GNUNET_CHAT_Group* | 29 | struct GNUNET_CHAT_Group* |
31 | group_create(struct GNUNET_CHAT_Handle *handle, | 30 | group_create_from_context (struct GNUNET_CHAT_Handle *handle, |
32 | const char *topic) | 31 | struct GNUNET_CHAT_Context *context) |
33 | { | 32 | { |
34 | struct GNUNET_HashCode topic_key; | 33 | struct GNUNET_CHAT_Group* group = GNUNET_new(struct GNUNET_CHAT_Group); |
35 | |||
36 | if (topic) { | ||
37 | GNUNET_CRYPTO_hash(topic, strlen(topic), &topic_key); | ||
38 | } | ||
39 | |||
40 | struct GNUNET_CHAT_Group *group = GNUNET_new(struct GNUNET_CHAT_Group); | ||
41 | 34 | ||
42 | group->handle = handle; | 35 | group->handle = handle; |
43 | group->context = context_create( | 36 | group->context = context; |
44 | handle, | 37 | |
45 | GNUNET_CHAT_CONTEXT_TYPE_GROUP, | 38 | group->topic = NULL; |
46 | topic? &topic_key : NULL | ||
47 | ); | ||
48 | 39 | ||
49 | group->is_public = topic? GNUNET_YES : GNUNET_NO; | ||
50 | group->announcement = NULL; | 40 | group->announcement = NULL; |
51 | group->search = NULL; | 41 | group->search = NULL; |
52 | 42 | ||
53 | if (!group->context) | ||
54 | { | ||
55 | group_destroy (group); | ||
56 | return NULL; | ||
57 | } | ||
58 | |||
59 | const struct GNUNET_HashCode *key = context_get_key(group->context); | ||
60 | |||
61 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
62 | handle->groups, | ||
63 | key, | ||
64 | group, | ||
65 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST | ||
66 | ); | ||
67 | |||
68 | if (GNUNET_OK != result) { | ||
69 | group_destroy(group); | ||
70 | return NULL; | ||
71 | } | ||
72 | |||
73 | return group; | 43 | return group; |
74 | } | 44 | } |
75 | 45 | ||
76 | void | 46 | void |
77 | group_destroy(struct GNUNET_CHAT_Group* group) | 47 | group_destroy (struct GNUNET_CHAT_Group* group) |
78 | { | 48 | { |
79 | if (!group->context) | 49 | if (group->search) |
80 | goto skip_context; | 50 | GNUNET_REGEX_search_cancel(group->search); |
81 | 51 | ||
82 | struct GNUNET_CHAT_Handle *handle = group->handle; | 52 | if (group->announcement) |
83 | const struct GNUNET_HashCode *key = context_get_key(group->context); | 53 | GNUNET_REGEX_announce_cancel(group->announcement); |
84 | 54 | ||
85 | GNUNET_CONTAINER_multihashmap_remove( | 55 | if (group->topic) |
86 | handle->groups, | 56 | GNUNET_free(group->topic); |
87 | key, | ||
88 | group | ||
89 | ); | ||
90 | 57 | ||
91 | context_destroy(group->context); | ||
92 | |||
93 | skip_context: | ||
94 | GNUNET_free(group); | 58 | GNUNET_free(group); |
95 | } | 59 | } |
96 | 60 | ||
97 | int | ||
98 | GNUNET_CHAT_group_leave (struct GNUNET_CHAT_Group *group) | ||
99 | { | ||
100 | if (!group) | ||
101 | return GNUNET_SYSERR; | ||
102 | |||
103 | if (GNUNET_YES != handle_update_chat_group(group->handle, group, GNUNET_YES)) | ||
104 | return GNUNET_SYSERR; | ||
105 | |||
106 | if (group->context) | ||
107 | GNUNET_MESSENGER_close_room(group->context->room); | ||
108 | |||
109 | group_destroy(group); | ||
110 | return GNUNET_OK; | ||
111 | } | ||
112 | |||
113 | void | ||
114 | GNUNET_CHAT_group_set_name (struct GNUNET_CHAT_Group *group, | ||
115 | const char *name) | ||
116 | { | ||
117 | if (!group) | ||
118 | return; | ||
119 | |||
120 | if (group->context) | ||
121 | context_set_nick(group->context, name); | ||
122 | } | ||
123 | |||
124 | const char* | ||
125 | GNUNET_CHAT_group_get_name (const struct GNUNET_CHAT_Group *group) | ||
126 | { | ||
127 | if (!group) | ||
128 | return NULL; | ||
129 | |||
130 | if (!group->context) | ||
131 | return NULL; | ||
132 | |||
133 | return context_get_nick(group->context); | ||
134 | } | ||
135 | |||
136 | void | 61 | void |
137 | GNUNET_CHAT_group_invite_contact (struct GNUNET_CHAT_Group *group, | 62 | group_publish (struct GNUNET_CHAT_Group* group) |
138 | struct GNUNET_CHAT_Contact *contact) | ||
139 | { | 63 | { |
140 | if ((!group) || (!contact)) | 64 | group->announcement = GNUNET_REGEX_announce( |
141 | return; | 65 | group->handle->cfg, group->topic, // TODO: raw topic? |
142 | 66 | GNUNET_TIME_relative_get_minute_(), // TODO: configure delay? | |
143 | struct GNUNET_CHAT_Context *context = GNUNET_CHAT_contact_get_context(contact); | 67 | 1 // TODO: no compression? |
144 | |||
145 | if (!context) | ||
146 | return; | ||
147 | |||
148 | struct GNUNET_MESSENGER_Handle *messenger = group->handle->handles.messenger; | ||
149 | GNUNET_MESSENGER_open_room(messenger, context_get_key(group->context)); | ||
150 | |||
151 | struct GNUNET_MESSENGER_Message message; | ||
152 | message.header.kind = GNUNET_MESSENGER_KIND_INVITE; | ||
153 | |||
154 | int result = GNUNET_CRYPTO_get_peer_identity( | ||
155 | group->handle->cfg, | ||
156 | &(message.body.invite.door) | ||
157 | ); | ||
158 | |||
159 | if (GNUNET_OK != result) | ||
160 | return; | ||
161 | |||
162 | GNUNET_memcpy( | ||
163 | &(message.body.invite.key), | ||
164 | context_get_key(group->context), | ||
165 | sizeof(message.body.invite.key) | ||
166 | ); | ||
167 | |||
168 | GNUNET_MESSENGER_send_message(context->room, &message, NULL); | ||
169 | } | ||
170 | |||
171 | struct GNUNET_CHAT_GroupIterateContacts | ||
172 | { | ||
173 | struct GNUNET_CHAT_Group *group; | ||
174 | GNUNET_CHAT_GroupContactCallback callback; | ||
175 | void *cls; | ||
176 | }; | ||
177 | |||
178 | static int | ||
179 | group_call_member (void* cls, struct GNUNET_CHAT_Handle *handle, | ||
180 | struct GNUNET_CHAT_Contact *contact) | ||
181 | { | ||
182 | struct GNUNET_CHAT_GroupIterateContacts *iterate = cls; | ||
183 | |||
184 | return iterate->callback(iterate->cls, iterate->group, contact); | ||
185 | } | ||
186 | |||
187 | static int | ||
188 | group_iterate_members (void* cls, struct GNUNET_MESSENGER_Room *room, | ||
189 | const struct GNUNET_MESSENGER_Contact *contact) | ||
190 | { | ||
191 | struct GNUNET_CHAT_GroupIterateContacts *iterate = cls; | ||
192 | |||
193 | return contact_call( | ||
194 | iterate->group->handle, | ||
195 | contact, | ||
196 | group_call_member, | ||
197 | iterate | ||
198 | ); | 68 | ); |
199 | } | ||
200 | |||
201 | int | ||
202 | GNUNET_CHAT_group_iterate_contacts (struct GNUNET_CHAT_Group *group, | ||
203 | GNUNET_CHAT_GroupContactCallback callback, | ||
204 | void *cls) | ||
205 | { | ||
206 | if (!group) | ||
207 | return GNUNET_SYSERR; | ||
208 | |||
209 | if (!callback) | ||
210 | return GNUNET_MESSENGER_iterate_members(group->context->room, NULL, cls); | ||
211 | 69 | ||
212 | struct GNUNET_CHAT_GroupIterateContacts iterate; | 70 | group->search = GNUNET_REGEX_search( |
213 | iterate.group = group; | 71 | group->handle->cfg, group->topic, // TODO: raw topic? |
214 | iterate.callback = callback; | 72 | search_group_by_topic, group |
215 | iterate.cls = cls; | ||
216 | |||
217 | return GNUNET_MESSENGER_iterate_members( | ||
218 | group->context->room, group_iterate_members, &iterate | ||
219 | ); | 73 | ); |
220 | } | 74 | } |
221 | |||
222 | struct GNUNET_CHAT_Context* | ||
223 | GNUNET_CHAT_group_get_context (struct GNUNET_CHAT_Group *group) | ||
224 | { | ||
225 | if (!group) | ||
226 | return NULL; | ||
227 | |||
228 | return group->context; | ||
229 | } | ||
diff --git a/src/gnunet_chat_group.h b/src/gnunet_chat_group.h index c0127bc..0130481 100644 --- a/src/gnunet_chat_group.h +++ b/src/gnunet_chat_group.h | |||
@@ -25,26 +25,33 @@ | |||
25 | #ifndef GNUNET_CHAT_GROUP_H_ | 25 | #ifndef GNUNET_CHAT_GROUP_H_ |
26 | #define GNUNET_CHAT_GROUP_H_ | 26 | #define GNUNET_CHAT_GROUP_H_ |
27 | 27 | ||
28 | #include <gnunet/platform.h> | ||
29 | #include <gnunet/gnunet_common.h> | ||
28 | #include <gnunet/gnunet_regex_service.h> | 30 | #include <gnunet/gnunet_regex_service.h> |
31 | #include <gnunet/gnunet_util_lib.h> | ||
29 | 32 | ||
30 | #include "gnunet_chat_context.h" | 33 | struct GNUNET_CHAT_Handle; |
34 | struct GNUNET_CHAT_Context; | ||
31 | 35 | ||
32 | struct GNUNET_CHAT_Group | 36 | struct GNUNET_CHAT_Group |
33 | { | 37 | { |
34 | struct GNUNET_CHAT_Handle *handle; | 38 | struct GNUNET_CHAT_Handle *handle; |
35 | struct GNUNET_CHAT_Context *context; | 39 | struct GNUNET_CHAT_Context *context; |
36 | 40 | ||
37 | int is_public; | 41 | char *topic; |
38 | 42 | ||
39 | struct GNUNET_REGEX_Announcement *announcement; | 43 | struct GNUNET_REGEX_Announcement *announcement; |
40 | struct GNUNET_REGEX_Search *search; | 44 | struct GNUNET_REGEX_Search *search; |
41 | }; | 45 | }; |
42 | 46 | ||
43 | struct GNUNET_CHAT_Group* | 47 | struct GNUNET_CHAT_Group* |
44 | group_create(struct GNUNET_CHAT_Handle *handle, | 48 | group_create_from_context (struct GNUNET_CHAT_Handle *handle, |
45 | const char *topic); | 49 | struct GNUNET_CHAT_Context *context); |
46 | 50 | ||
47 | void | 51 | void |
48 | group_destroy(struct GNUNET_CHAT_Group* group); | 52 | group_destroy (struct GNUNET_CHAT_Group* group); |
53 | |||
54 | void | ||
55 | group_publish (struct GNUNET_CHAT_Group* group); | ||
49 | 56 | ||
50 | #endif /* GNUNET_CHAT_GROUP_H_ */ | 57 | #endif /* GNUNET_CHAT_GROUP_H_ */ |
diff --git a/src/gnunet_chat_group_intern.c b/src/gnunet_chat_group_intern.c new file mode 100644 index 0000000..b70b901 --- /dev/null +++ b/src/gnunet_chat_group_intern.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file gnunet_chat_group_intern.c | ||
23 | */ | ||
24 | |||
25 | #include "gnunet_chat_context.h" | ||
26 | #include "gnunet_chat_handle.h" | ||
27 | |||
28 | #define GNUNET_UNUSED __attribute__ ((unused)) | ||
29 | |||
30 | void | ||
31 | search_group_by_topic(void *cls, | ||
32 | const struct GNUNET_PeerIdentity *door, | ||
33 | GNUNET_UNUSED const struct GNUNET_PeerIdentity *get_path, | ||
34 | GNUNET_UNUSED unsigned int get_path_length, | ||
35 | GNUNET_UNUSED const struct GNUNET_PeerIdentity *put_path, | ||
36 | GNUNET_UNUSED unsigned int put_path_length) | ||
37 | { | ||
38 | struct GNUNET_CHAT_Group *group = cls; | ||
39 | |||
40 | struct GNUNET_PeerIdentity peer; | ||
41 | GNUNET_CRYPTO_get_peer_identity(group->handle->cfg, &peer); | ||
42 | |||
43 | if (0 == GNUNET_memcmp(&peer, door)) | ||
44 | return; | ||
45 | |||
46 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( | ||
47 | group->context->room | ||
48 | ); | ||
49 | |||
50 | GNUNET_MESSENGER_enter_room(group->handle->messenger, door, key); | ||
51 | } | ||
diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c index 84539c5..11b57ac 100644 --- a/src/gnunet_chat_handle.c +++ b/src/gnunet_chat_handle.c | |||
@@ -22,642 +22,73 @@ | |||
22 | * @file gnunet_chat_handle.c | 22 | * @file gnunet_chat_handle.c |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "gnunet_chat_lib.h" | ||
26 | #include "gnunet_chat_handle.h" | 25 | #include "gnunet_chat_handle.h" |
27 | #include "gnunet_chat_group.h" | ||
28 | #include "gnunet_chat_contact.h" | ||
29 | #include "gnunet_chat_message.h" | ||
30 | #include "gnunet_chat_file.h" | ||
31 | 26 | ||
32 | static void* | 27 | #include "gnunet_chat_handle_intern.c" |
33 | handle_fs_progress(void* cls, const struct GNUNET_FS_ProgressInfo* info) | ||
34 | { | ||
35 | struct GNUNET_CHAT_Handle *chat = cls; | ||
36 | |||
37 | if (!chat) | ||
38 | return NULL; | ||
39 | |||
40 | switch (info->status) { | ||
41 | case GNUNET_FS_STATUS_PUBLISH_START: { | ||
42 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
43 | publication->progress = 0.0f; | ||
44 | |||
45 | GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication); | ||
46 | |||
47 | return publication;*/ | ||
48 | } case GNUNET_FS_STATUS_PUBLISH_PROGRESS: { | ||
49 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
50 | publication->progress = 1.0f * info->value.publish.completed / info->value.publish.size; | ||
51 | |||
52 | GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication); | ||
53 | |||
54 | return publication;*/ | ||
55 | } case GNUNET_FS_STATUS_PUBLISH_COMPLETED: { | ||
56 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
57 | publication->uri = GNUNET_FS_uri_dup(info->value.publish.specifics.completed.chk_uri); | ||
58 | publication->progress = 1.0f; | ||
59 | |||
60 | GNUNET_SCHEDULER_add_now(&CGTK_publication_finish, publication);*/ | ||
61 | break; | ||
62 | } case GNUNET_FS_STATUS_PUBLISH_ERROR: { | ||
63 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
64 | |||
65 | GNUNET_SCHEDULER_add_now(&CGTK_publication_error, publication);*/ | ||
66 | break; | ||
67 | } case GNUNET_FS_STATUS_DOWNLOAD_START: { | ||
68 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
69 | request->progress = 0.0f; | ||
70 | |||
71 | return request;*/ | ||
72 | } case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: { | ||
73 | return info->value.download.cctx; | ||
74 | } case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: { | ||
75 | return info->value.download.cctx; | ||
76 | } case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: { | ||
77 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
78 | request->progress = 1.0f * info->value.download.completed / info->value.download.size; | ||
79 | |||
80 | GNUNET_SCHEDULER_add_now(&CGTK_request_progress, request); | ||
81 | |||
82 | return request;*/ | ||
83 | } case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: { | ||
84 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
85 | request->progress = 1.0f; | ||
86 | |||
87 | GNUNET_SCHEDULER_add_now(&CGTK_request_finish, request);*/ | ||
88 | break; | ||
89 | } case GNUNET_FS_STATUS_DOWNLOAD_ERROR: { | ||
90 | /*request_t *request = (request_t *) info->value.download.cctx; | ||
91 | |||
92 | GNUNET_SCHEDULER_add_now(&CGTK_request_error, request);*/ | ||
93 | break; | ||
94 | } case GNUNET_FS_STATUS_UNINDEX_START: { | ||
95 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
96 | publication->progress = 0.0f; | ||
97 | |||
98 | return publication;*/ | ||
99 | } case GNUNET_FS_STATUS_UNINDEX_PROGRESS: { | ||
100 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
101 | publication->progress = 1.0f * info->value.unindex.completed / info->value.unindex.size; | ||
102 | |||
103 | return publication;*/ | ||
104 | } case GNUNET_FS_STATUS_UNINDEX_COMPLETED: { | ||
105 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
106 | publication->progress = 1.0f; | ||
107 | |||
108 | GNUNET_SCHEDULER_add_now(&CGTK_publication_unindex_finish, publication);*/ | ||
109 | break; | ||
110 | } default: { | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | return NULL; | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | handle_on_message (void *cls, | ||
120 | GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room, | ||
121 | GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *sender, | ||
122 | const struct GNUNET_MESSENGER_Message *message, | ||
123 | const struct GNUNET_HashCode *hash, | ||
124 | GNUNET_UNUSED enum GNUNET_MESSENGER_MessageFlags flags) | ||
125 | { | ||
126 | struct GNUNET_CHAT_Handle *chat = cls; | ||
127 | |||
128 | //TODO | ||
129 | |||
130 | struct GNUNET_CHAT_Message msg; | ||
131 | GNUNET_memcpy(&(msg.hash), hash, sizeof(msg.hash)); | ||
132 | msg.message = message; | ||
133 | |||
134 | if ((GNUNET_CHAT_KIND_UNKNOWN == GNUNET_CHAT_message_get_kind(&msg)) || | ||
135 | (!chat->msg_cb)) | ||
136 | return; | ||
137 | |||
138 | chat->msg_cb(chat->msg_cls, NULL /* TODO */, &msg); | ||
139 | } | ||
140 | |||
141 | struct GNUNET_CHAT_CheckRoomMembers | ||
142 | { | ||
143 | const struct GNUNET_IDENTITY_PublicKey *ignore_key; | ||
144 | const struct GNUNET_MESSENGER_Contact *contact; | ||
145 | }; | ||
146 | |||
147 | static int | ||
148 | handle_check_room_members (void* cls, | ||
149 | GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room, | ||
150 | const struct GNUNET_MESSENGER_Contact *contact) | ||
151 | { | ||
152 | struct GNUNET_CHAT_CheckRoomMembers *check = cls; | ||
153 | const struct GNUNET_IDENTITY_PublicKey *contact_key = ( | ||
154 | GNUNET_MESSENGER_contact_get_key(contact) | ||
155 | ); | ||
156 | |||
157 | if (0 == GNUNET_memcmp(contact_key, check->ignore_key)) | ||
158 | return GNUNET_YES; | ||
159 | |||
160 | if (check->contact) | ||
161 | return GNUNET_NO; | ||
162 | |||
163 | check->contact = contact; | ||
164 | return GNUNET_YES; | ||
165 | } | ||
166 | |||
167 | static int | ||
168 | handle_initialize_context (void *cls, struct GNUNET_MESSENGER_Room *room, | ||
169 | GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *contact) | ||
170 | { | ||
171 | struct GNUNET_CHAT_Handle *chat = cls; | ||
172 | |||
173 | struct GNUNET_CHAT_CheckRoomMembers check; | ||
174 | check.ignore_key = GNUNET_CHAT_get_key(chat); | ||
175 | check.contact = NULL; | ||
176 | |||
177 | const int amount = GNUNET_MESSENGER_iterate_members( | ||
178 | room, handle_check_room_members, &check | ||
179 | ); | ||
180 | |||
181 | if (amount <= 1) | ||
182 | return GNUNET_YES; | ||
183 | |||
184 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room); | ||
185 | struct GNUNET_CHAT_Context *context = handle_get_chat_context(chat, key); | ||
186 | enum GNUNET_CHAT_ContextType type = GNUNET_CHAT_CONTEXT_TYPE_UNKNOWN; | ||
187 | |||
188 | if (check.contact) | ||
189 | type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; | ||
190 | else | ||
191 | type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; | ||
192 | |||
193 | if (!context) | ||
194 | context = context_create(chat, type, key); | ||
195 | else | ||
196 | context->type = type; | ||
197 | |||
198 | if (GNUNET_YES != handle_update_chat_context(chat, context, GNUNET_NO)) | ||
199 | context_destroy(context); | ||
200 | |||
201 | return GNUNET_YES; | ||
202 | } | ||
203 | |||
204 | static void | ||
205 | handle_on_identity(void *cls, struct GNUNET_MESSENGER_Handle *handle) | ||
206 | { | ||
207 | struct GNUNET_CHAT_Handle *chat = cls; | ||
208 | |||
209 | //TODO | ||
210 | |||
211 | GNUNET_MESSENGER_find_rooms( | ||
212 | chat->handles.messenger, NULL, handle_initialize_context, handle | ||
213 | ); | ||
214 | } | ||
215 | |||
216 | static void | ||
217 | handle_arm_connection(void *cls, int connected) | ||
218 | { | ||
219 | struct GNUNET_CHAT_Handle *chat = cls; | ||
220 | |||
221 | if (GNUNET_YES == connected) { | ||
222 | GNUNET_ARM_request_service_start(chat->handles.arm, "messenger", | ||
223 | GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | ||
224 | GNUNET_ARM_request_service_start(chat->handles.arm, "fs", | ||
225 | GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | ||
226 | } else { | ||
227 | GNUNET_ARM_request_service_start(chat->handles.arm, "arm", | ||
228 | GNUNET_OS_INHERIT_STD_NONE, NULL, NULL); | ||
229 | } | ||
230 | } | ||
231 | 28 | ||
232 | struct GNUNET_CHAT_Handle* | 29 | struct GNUNET_CHAT_Handle* |
233 | GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle* cfg, | 30 | handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, |
234 | const char *name, | 31 | const char* name, |
235 | GNUNET_CHAT_WarningCallback warn_cb, | 32 | GNUNET_CHAT_ContextMessageCallback msg_cb, |
236 | void *warn_cls, | 33 | void *msg_cls, |
237 | GNUNET_CHAT_ContextMessageCallback msg_cb, | 34 | GNUNET_CHAT_WarningCallback warn_cb, |
238 | void *msg_cls) | 35 | void *warn_cls) |
239 | { | 36 | { |
240 | if (!cfg) | 37 | struct GNUNET_CHAT_Handle* handle = GNUNET_new(struct GNUNET_CHAT_Handle); |
241 | return NULL; | ||
242 | 38 | ||
243 | struct GNUNET_CHAT_Handle *chat = GNUNET_new(struct GNUNET_CHAT_Handle); | 39 | handle->cfg = cfg; |
244 | memset(chat, 0, sizeof(*chat)); | ||
245 | chat->cfg = cfg; | ||
246 | 40 | ||
247 | chat->warn_cb = warn_cb; | 41 | handle->msg_cb = msg_cb; |
248 | chat->warn_cls = warn_cls; | 42 | handle->msg_cls = msg_cls; |
249 | 43 | ||
250 | chat->handles.arm = GNUNET_ARM_connect(cfg, &handle_arm_connection, chat); | 44 | handle->warn_cb = warn_cb; |
45 | handle->warn_cls = warn_cls; | ||
251 | 46 | ||
252 | if (chat->handles.arm) | 47 | handle->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
253 | handle_arm_connection(chat, GNUNET_NO); | 48 | handle->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); |
49 | handle->contacts = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); | ||
50 | handle->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
254 | 51 | ||
255 | chat->handles.messenger = GNUNET_MESSENGER_connect( | 52 | handle->arm = GNUNET_ARM_connect( |
256 | cfg, name, | 53 | handle->cfg, |
257 | handle_on_identity, chat, | 54 | on_handle_arm_connection, handle |
258 | handle_on_message, chat | ||
259 | ); | 55 | ); |
260 | 56 | ||
261 | if (!chat->handles.messenger) | 57 | if (handle->arm) |
262 | { | 58 | on_handle_arm_connection(handle, GNUNET_NO); |
263 | GNUNET_CHAT_stop(chat); | ||
264 | return NULL; | ||
265 | } | ||
266 | 59 | ||
267 | chat->handles.fs = GNUNET_FS_start( | 60 | handle->fs = GNUNET_FS_start( |
268 | cfg, | 61 | handle->cfg, name, // TODO: raw name? |
269 | name, | 62 | notify_handle_fs_progress, handle, |
270 | handle_fs_progress, | ||
271 | chat, | ||
272 | GNUNET_FS_FLAGS_NONE, | 63 | GNUNET_FS_FLAGS_NONE, |
273 | GNUNET_FS_OPTIONS_END | 64 | GNUNET_FS_OPTIONS_END |
274 | ); | 65 | ); |
275 | 66 | ||
276 | chat->contacts.short_map = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); | 67 | handle->messenger = GNUNET_MESSENGER_connect( |
277 | chat->contacts.hash_map = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 68 | handle->cfg, name, |
278 | 69 | on_handle_identity, handle, | |
279 | chat->groups = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 70 | on_handle_message, handle |
280 | chat->contexts = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | 71 | ); |
281 | chat->files = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
282 | |||
283 | chat->msg_cb = msg_cb; | ||
284 | chat->msg_cls = msg_cls; | ||
285 | |||
286 | return chat; | ||
287 | } | ||
288 | |||
289 | static int | ||
290 | handle_iterate_destroy_contacts (GNUNET_UNUSED void *cls, | ||
291 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
292 | void *value) | ||
293 | { | ||
294 | struct GNUNET_CHAT_Contact *contact = value; | ||
295 | contact_destroy(contact); | ||
296 | return GNUNET_YES; | ||
297 | } | ||
298 | 72 | ||
299 | static int | 73 | return handle; |
300 | handle_iterate_destroy_groups (GNUNET_UNUSED void *cls, | ||
301 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
302 | void *value) | ||
303 | { | ||
304 | struct GNUNET_CHAT_Group *group = value; | ||
305 | group_destroy(group); | ||
306 | return GNUNET_YES; | ||
307 | } | 74 | } |
308 | 75 | ||
309 | void | 76 | void |
310 | GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle) | 77 | handle_destroy (struct GNUNET_CHAT_Handle* handle) |
311 | { | 78 | { |
312 | if (!handle) | 79 | if (handle->messenger) |
313 | return; | 80 | GNUNET_MESSENGER_disconnect(handle->messenger); |
314 | |||
315 | if (handle->handles.fs) | ||
316 | { | ||
317 | // TODO: stop each action | ||
318 | |||
319 | GNUNET_FS_stop(handle->handles.fs); | ||
320 | handle->handles.fs = NULL; | ||
321 | } | ||
322 | |||
323 | if (handle->handles.messenger) | ||
324 | { | ||
325 | // TODO: stop everything related | ||
326 | |||
327 | GNUNET_MESSENGER_disconnect(handle->handles.messenger); | ||
328 | handle->handles.messenger = NULL; | ||
329 | } | ||
330 | 81 | ||
331 | if (handle->groups) | 82 | if (handle->files) |
332 | { | 83 | GNUNET_FS_stop(handle->fs); |
333 | GNUNET_CONTAINER_multihashmap_iterate( | ||
334 | handle->groups, handle_iterate_destroy_groups, NULL | ||
335 | ); | ||
336 | 84 | ||
337 | GNUNET_CONTAINER_multihashmap_destroy(handle->groups); | 85 | if (handle->arm) |
338 | handle->groups = NULL; | 86 | GNUNET_ARM_disconnect(handle->arm); |
339 | } | ||
340 | 87 | ||
341 | if (handle->contacts.hash_map) | 88 | GNUNET_CONTAINER_multihashmap_destroy(handle->groups); |
342 | { | 89 | GNUNET_CONTAINER_multishortmap_destroy(handle->contacts); |
343 | GNUNET_CONTAINER_multihashmap_iterate( | 90 | GNUNET_CONTAINER_multihashmap_destroy(handle->contexts); |
344 | handle->contacts.hash_map, handle_iterate_destroy_contacts, NULL | 91 | GNUNET_CONTAINER_multihashmap_destroy(handle->files); |
345 | ); | ||
346 | |||
347 | GNUNET_CONTAINER_multihashmap_destroy(handle->contacts.hash_map); | ||
348 | handle->contacts.hash_map = NULL; | ||
349 | } | ||
350 | |||
351 | if (handle->contacts.short_map) | ||
352 | { | ||
353 | GNUNET_CONTAINER_multishortmap_destroy(handle->contacts.short_map); | ||
354 | handle->contacts.short_map = NULL; | ||
355 | } | ||
356 | |||
357 | if (handle->handles.arm) | ||
358 | { | ||
359 | //TODO: stop started services? | ||
360 | |||
361 | GNUNET_ARM_disconnect(handle->handles.arm); | ||
362 | handle->handles.arm = NULL; | ||
363 | } | ||
364 | 92 | ||
365 | GNUNET_free(handle); | 93 | GNUNET_free(handle); |
366 | } | 94 | } |
367 | |||
368 | int | ||
369 | GNUNET_CHAT_update (struct GNUNET_CHAT_Handle *handle) | ||
370 | { | ||
371 | if (!handle) | ||
372 | return GNUNET_SYSERR; | ||
373 | |||
374 | return GNUNET_MESSENGER_update(handle->handles.messenger); | ||
375 | } | ||
376 | |||
377 | int | ||
378 | GNUNET_CHAT_set_name (struct GNUNET_CHAT_Handle *handle, | ||
379 | const char *name) | ||
380 | { | ||
381 | if (!handle) | ||
382 | return GNUNET_SYSERR; | ||
383 | |||
384 | return GNUNET_MESSENGER_set_name(handle->handles.messenger, name); | ||
385 | } | ||
386 | |||
387 | const char* | ||
388 | GNUNET_CHAT_get_name (const struct GNUNET_CHAT_Handle *handle) | ||
389 | { | ||
390 | if (!handle) | ||
391 | return NULL; | ||
392 | |||
393 | return GNUNET_MESSENGER_get_name(handle->handles.messenger); | ||
394 | } | ||
395 | |||
396 | const struct GNUNET_IDENTITY_PublicKey* | ||
397 | GNUNET_CHAT_get_key (const struct GNUNET_CHAT_Handle *handle) | ||
398 | { | ||
399 | if (!handle) | ||
400 | return NULL; | ||
401 | |||
402 | return GNUNET_MESSENGER_get_key(handle->handles.messenger); | ||
403 | } | ||
404 | |||
405 | struct GNUNET_CHAT_IterateContacts | ||
406 | { | ||
407 | struct GNUNET_CHAT_Handle *handle; | ||
408 | GNUNET_CHAT_ContactCallback callback; | ||
409 | void *cls; | ||
410 | }; | ||
411 | |||
412 | static int | ||
413 | handle_iterate_contacts(void *cls, | ||
414 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
415 | void *value) | ||
416 | { | ||
417 | struct GNUNET_CHAT_IterateContacts *iterate = cls; | ||
418 | struct GNUNET_CHAT_Contact *contact = value; | ||
419 | |||
420 | if (!iterate->callback) | ||
421 | return GNUNET_YES; | ||
422 | |||
423 | return iterate->callback(iterate->cls, iterate->handle, contact); | ||
424 | } | ||
425 | |||
426 | int | ||
427 | GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle, | ||
428 | GNUNET_CHAT_ContactCallback callback, | ||
429 | void *cls) | ||
430 | { | ||
431 | if (!handle) | ||
432 | return GNUNET_SYSERR; | ||
433 | |||
434 | struct GNUNET_CHAT_IterateContacts iterate; | ||
435 | iterate.handle = handle; | ||
436 | iterate.callback = callback; | ||
437 | iterate.cls = cls; | ||
438 | |||
439 | return GNUNET_CONTAINER_multihashmap_iterate(handle->contacts.hash_map, | ||
440 | handle_iterate_contacts, | ||
441 | &iterate); | ||
442 | } | ||
443 | |||
444 | struct GNUNET_CHAT_Group* | ||
445 | GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, | ||
446 | const char *topic) | ||
447 | { | ||
448 | if (!handle) | ||
449 | return NULL; | ||
450 | |||
451 | struct GNUNET_CHAT_Group *group = group_create(handle, topic); | ||
452 | |||
453 | if (!group) | ||
454 | return NULL; | ||
455 | |||
456 | if (GNUNET_YES != handle_update_chat_group(handle, group, GNUNET_NO)) | ||
457 | { | ||
458 | group_destroy(group); | ||
459 | return NULL; | ||
460 | } | ||
461 | |||
462 | return group; | ||
463 | } | ||
464 | |||
465 | struct GNUNET_CHAT_IterateGroups | ||
466 | { | ||
467 | struct GNUNET_CHAT_Handle *handle; | ||
468 | GNUNET_CHAT_GroupCallback callback; | ||
469 | void *cls; | ||
470 | }; | ||
471 | |||
472 | static int | ||
473 | handle_iterate_groups(void *cls, | ||
474 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
475 | void *value) | ||
476 | { | ||
477 | struct GNUNET_CHAT_IterateGroups *iterate = cls; | ||
478 | struct GNUNET_CHAT_Group *group = value; | ||
479 | |||
480 | if (!iterate->callback) | ||
481 | return GNUNET_YES; | ||
482 | |||
483 | return iterate->callback(iterate->cls, iterate->handle, group); | ||
484 | } | ||
485 | |||
486 | int | ||
487 | GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle, | ||
488 | GNUNET_CHAT_GroupCallback callback, | ||
489 | void *cls) | ||
490 | { | ||
491 | if (!handle) | ||
492 | return GNUNET_SYSERR; | ||
493 | |||
494 | struct GNUNET_CHAT_IterateGroups iterate; | ||
495 | iterate.handle = handle; | ||
496 | iterate.callback = callback; | ||
497 | iterate.cls = cls; | ||
498 | |||
499 | return GNUNET_CONTAINER_multihashmap_iterate(handle->groups, | ||
500 | handle_iterate_groups, | ||
501 | &iterate); | ||
502 | } | ||
503 | |||
504 | int | ||
505 | handle_update_chat_contact (struct GNUNET_CHAT_Handle *handle, | ||
506 | struct GNUNET_CHAT_Contact *chatContact, | ||
507 | int removeContact) | ||
508 | { | ||
509 | const struct GNUNET_HashCode *key = context_get_key(chatContact->context); | ||
510 | |||
511 | if (GNUNET_YES == removeContact) | ||
512 | { | ||
513 | const int result = GNUNET_CONTAINER_multihashmap_remove( | ||
514 | handle->contacts.hash_map, key, chatContact | ||
515 | ); | ||
516 | |||
517 | if (GNUNET_YES == result) | ||
518 | return handle_update_chat_context(handle, chatContact->context, | ||
519 | GNUNET_YES); | ||
520 | else | ||
521 | return GNUNET_NO; | ||
522 | } | ||
523 | else | ||
524 | { | ||
525 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
526 | handle->contacts.hash_map, key, chatContact, | ||
527 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY | ||
528 | ); | ||
529 | |||
530 | if (GNUNET_OK != result) | ||
531 | return GNUNET_NO; | ||
532 | else | ||
533 | return handle_update_chat_context(handle, chatContact->context, | ||
534 | GNUNET_NO); | ||
535 | } | ||
536 | } | ||
537 | |||
538 | int | ||
539 | handle_update_chat_group (struct GNUNET_CHAT_Handle *handle, | ||
540 | struct GNUNET_CHAT_Group *chatGroup, | ||
541 | int removeGroup) | ||
542 | { | ||
543 | const struct GNUNET_HashCode *key = context_get_key(chatGroup->context); | ||
544 | |||
545 | if (GNUNET_YES == removeGroup) | ||
546 | { | ||
547 | const int result = GNUNET_CONTAINER_multihashmap_remove( | ||
548 | handle->groups, key, chatGroup | ||
549 | ); | ||
550 | |||
551 | if (GNUNET_YES == result) | ||
552 | return handle_update_chat_context(handle, chatGroup->context, | ||
553 | GNUNET_YES); | ||
554 | else | ||
555 | return GNUNET_NO; | ||
556 | } | ||
557 | else | ||
558 | { | ||
559 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
560 | handle->groups, key, chatGroup, | ||
561 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY | ||
562 | ); | ||
563 | |||
564 | if (GNUNET_OK != result) | ||
565 | return GNUNET_NO; | ||
566 | else | ||
567 | return handle_update_chat_context(handle, chatGroup->context, | ||
568 | GNUNET_NO); | ||
569 | } | ||
570 | } | ||
571 | |||
572 | int | ||
573 | handle_update_chat_context (struct GNUNET_CHAT_Handle *handle, | ||
574 | struct GNUNET_CHAT_Context *context, | ||
575 | int removeContext) | ||
576 | { | ||
577 | const struct GNUNET_HashCode *key = context_get_key(context); | ||
578 | |||
579 | if (GNUNET_YES == removeContext) | ||
580 | return GNUNET_CONTAINER_multihashmap_remove( | ||
581 | handle->contexts, key, context | ||
582 | ); | ||
583 | else | ||
584 | { | ||
585 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
586 | handle->contexts, key, context, | ||
587 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY | ||
588 | ); | ||
589 | |||
590 | if (GNUNET_OK != result) | ||
591 | return GNUNET_NO; | ||
592 | else | ||
593 | return GNUNET_YES; | ||
594 | } | ||
595 | } | ||
596 | |||
597 | int | ||
598 | handle_update_chat_file (struct GNUNET_CHAT_Handle *handle, | ||
599 | struct GNUNET_CHAT_File *file, | ||
600 | int removeFile) | ||
601 | { | ||
602 | const struct GNUNET_HashCode *hash = GNUNET_CHAT_file_get_hash(file); | ||
603 | |||
604 | if (GNUNET_YES == removeFile) | ||
605 | return GNUNET_CONTAINER_multihashmap_remove( | ||
606 | handle->files, hash, file | ||
607 | ); | ||
608 | else | ||
609 | { | ||
610 | const int result = GNUNET_CONTAINER_multihashmap_put( | ||
611 | handle->files, hash, file, | ||
612 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY | ||
613 | ); | ||
614 | |||
615 | if (GNUNET_OK != result) | ||
616 | return GNUNET_NO; | ||
617 | else | ||
618 | return GNUNET_YES; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | static void | ||
623 | handle_get_short_of_contact(struct GNUNET_ShortHashCode *shortHash, | ||
624 | const struct GNUNET_MESSENGER_Contact *contact) | ||
625 | { | ||
626 | memset(shortHash, 0, sizeof(*shortHash)); | ||
627 | GNUNET_memcpy(shortHash, &contact, sizeof(contact)); | ||
628 | } | ||
629 | |||
630 | struct GNUNET_CHAT_Contact* | ||
631 | handle_get_chat_contact (struct GNUNET_CHAT_Handle *handle, | ||
632 | const struct GNUNET_MESSENGER_Contact *contact) | ||
633 | { | ||
634 | struct GNUNET_ShortHashCode shortHash; | ||
635 | handle_get_short_of_contact (&shortHash, contact); | ||
636 | |||
637 | struct GNUNET_CHAT_Contact* chatContact = GNUNET_CONTAINER_multishortmap_get( | ||
638 | handle->contacts.short_map, &shortHash | ||
639 | ); | ||
640 | |||
641 | return chatContact; | ||
642 | } | ||
643 | |||
644 | void | ||
645 | handle_set_chat_contact (struct GNUNET_CHAT_Handle *handle, | ||
646 | const struct GNUNET_MESSENGER_Contact *contact, | ||
647 | struct GNUNET_CHAT_Contact *chatContact) | ||
648 | { | ||
649 | struct GNUNET_ShortHashCode shortHash; | ||
650 | handle_get_short_of_contact (&shortHash, contact); | ||
651 | |||
652 | if (chatContact) | ||
653 | { | ||
654 | GNUNET_CONTAINER_multishortmap_remove_all(handle->contacts.short_map, | ||
655 | &shortHash); | ||
656 | return; | ||
657 | } | ||
658 | |||
659 | GNUNET_CONTAINER_multishortmap_put( | ||
660 | handle->contacts.short_map, &shortHash, chatContact, | ||
661 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE | ||
662 | ); | ||
663 | } | ||
diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h index b287336..a0f44e0 100644 --- a/src/gnunet_chat_handle.h +++ b/src/gnunet_chat_handle.h | |||
@@ -26,86 +26,45 @@ | |||
26 | #define GNUNET_CHAT_HANDLE_H_ | 26 | #define GNUNET_CHAT_HANDLE_H_ |
27 | 27 | ||
28 | #include <gnunet/platform.h> | 28 | #include <gnunet/platform.h> |
29 | #include <gnunet/gnunet_common.h> | ||
29 | #include <gnunet/gnunet_config.h> | 30 | #include <gnunet/gnunet_config.h> |
30 | #include <gnunet/gnunet_container_lib.h> | 31 | #include <gnunet/gnunet_container_lib.h> |
31 | #include <gnunet/gnunet_arm_service.h> | 32 | #include <gnunet/gnunet_arm_service.h> |
32 | #include <gnunet/gnunet_fs_service.h> | 33 | #include <gnunet/gnunet_fs_service.h> |
33 | #include <gnunet/gnunet_messenger_service.h> | 34 | #include <gnunet/gnunet_messenger_service.h> |
34 | #include <gnunet/gnunet_regex_service.h> | ||
35 | #include <gnunet/gnunet_util_lib.h> | 35 | #include <gnunet/gnunet_util_lib.h> |
36 | 36 | ||
37 | #include "gnunet_chat_lib.h" | ||
38 | |||
37 | struct GNUNET_CHAT_Handle | 39 | struct GNUNET_CHAT_Handle |
38 | { | 40 | { |
39 | const struct GNUNET_CONFIGURATION_Handle* cfg; | 41 | const struct GNUNET_CONFIGURATION_Handle* cfg; |
40 | 42 | ||
41 | struct { | ||
42 | /* | ||
43 | * feature: (automatically start required services) | ||
44 | */ | ||
45 | struct GNUNET_ARM_Handle *arm; | ||
46 | |||
47 | /* | ||
48 | * required: (files can be uploaded/downloaded) | ||
49 | */ | ||
50 | struct GNUNET_FS_Handle *fs; | ||
51 | |||
52 | /* | ||
53 | * required! | ||
54 | */ | ||
55 | struct GNUNET_MESSENGER_Handle *messenger; | ||
56 | } handles; | ||
57 | |||
58 | struct { | ||
59 | struct GNUNET_CONTAINER_MultiShortmap *short_map; | ||
60 | struct GNUNET_CONTAINER_MultiHashMap *hash_map; | ||
61 | } contacts; | ||
62 | |||
63 | struct GNUNET_CONTAINER_MultiHashMap *groups; | ||
64 | struct GNUNET_CONTAINER_MultiHashMap *contexts; | ||
65 | struct GNUNET_CONTAINER_MultiHashMap *files; | ||
66 | |||
67 | GNUNET_CHAT_ContextMessageCallback msg_cb; | 43 | GNUNET_CHAT_ContextMessageCallback msg_cb; |
68 | void *msg_cls; | 44 | void *msg_cls; |
69 | 45 | ||
70 | GNUNET_CHAT_WarningCallback warn_cb; | 46 | GNUNET_CHAT_WarningCallback warn_cb; |
71 | void *warn_cls; | 47 | void *warn_cls; |
72 | }; | ||
73 | |||
74 | int | ||
75 | handle_update_chat_contact (struct GNUNET_CHAT_Handle *handle, | ||
76 | struct GNUNET_CHAT_Contact *chatContact, | ||
77 | int removeContact); | ||
78 | |||
79 | int | ||
80 | handle_update_chat_group (struct GNUNET_CHAT_Handle *handle, | ||
81 | struct GNUNET_CHAT_Group *chatGroup, | ||
82 | int removeGroup); | ||
83 | 48 | ||
84 | int | 49 | struct GNUNET_CONTAINER_MultiHashMap *files; |
85 | handle_update_chat_context (struct GNUNET_CHAT_Handle *handle, | 50 | struct GNUNET_CONTAINER_MultiHashMap *contexts; |
86 | struct GNUNET_CHAT_Context *context, | 51 | struct GNUNET_CONTAINER_MultiShortmap *contacts; |
87 | int removeContext); | 52 | struct GNUNET_CONTAINER_MultiHashMap *groups; |
88 | 53 | ||
89 | int | 54 | struct GNUNET_ARM_Handle *arm; |
90 | handle_update_chat_file (struct GNUNET_CHAT_Handle *handle, | 55 | struct GNUNET_FS_Handle *fs; |
91 | struct GNUNET_CHAT_File *file, | 56 | struct GNUNET_MESSENGER_Handle *messenger; |
92 | int removeFile); | 57 | }; |
93 | 58 | ||
94 | struct GNUNET_CHAT_Contact* | 59 | struct GNUNET_CHAT_Handle* |
95 | handle_get_chat_contact (struct GNUNET_CHAT_Handle *handle, | 60 | handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, |
96 | const struct GNUNET_MESSENGER_Contact *contact); | 61 | const char* name, |
62 | GNUNET_CHAT_ContextMessageCallback msg_cb, | ||
63 | void *msg_cls, | ||
64 | GNUNET_CHAT_WarningCallback warn_cb, | ||
65 | void *warn_cls); | ||
97 | 66 | ||
98 | void | 67 | void |
99 | handle_set_chat_contact (struct GNUNET_CHAT_Handle *handle, | 68 | handle_destroy (struct GNUNET_CHAT_Handle* handle); |
100 | const struct GNUNET_MESSENGER_Contact *contact, | ||
101 | struct GNUNET_CHAT_Contact *chatContact); | ||
102 | |||
103 | struct GNUNET_CHAT_Context* | ||
104 | handle_get_chat_context (struct GNUNET_CHAT_Handle *handle, | ||
105 | const struct GNUNET_HashCode *key); | ||
106 | |||
107 | struct GNUNET_CHAT_File* | ||
108 | handle_get_chat_file (struct GNUNET_CHAT_Handle *handle, | ||
109 | const struct GNUNET_HashCode *hash); | ||
110 | 69 | ||
111 | #endif /* GNUNET_CHAT_HANDLE_H_ */ | 70 | #endif /* GNUNET_CHAT_HANDLE_H_ */ |
diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c new file mode 100644 index 0000000..282492c --- /dev/null +++ b/src/gnunet_chat_handle_intern.c | |||
@@ -0,0 +1,308 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file gnunet_chat_handle_intern.c | ||
23 | */ | ||
24 | |||
25 | #include "gnunet_chat_contact.h" | ||
26 | #include "gnunet_chat_context.h" | ||
27 | #include "gnunet_chat_group.h" | ||
28 | #include "gnunet_chat_handle.h" | ||
29 | #include "gnunet_chat_message.h" | ||
30 | #include "gnunet_chat_util.h" | ||
31 | |||
32 | #define GNUNET_UNUSED __attribute__ ((unused)) | ||
33 | |||
34 | void | ||
35 | on_handle_arm_connection(void *cls, int connected) | ||
36 | { | ||
37 | struct GNUNET_CHAT_Handle *chat = cls; | ||
38 | |||
39 | if (GNUNET_YES == connected) { | ||
40 | GNUNET_ARM_request_service_start( | ||
41 | chat->arm, "messenger", | ||
42 | GNUNET_OS_INHERIT_STD_NONE, | ||
43 | NULL, NULL | ||
44 | ); | ||
45 | |||
46 | GNUNET_ARM_request_service_start( | ||
47 | chat->arm, "fs", | ||
48 | GNUNET_OS_INHERIT_STD_NONE, | ||
49 | NULL, NULL | ||
50 | ); | ||
51 | } else { | ||
52 | GNUNET_ARM_request_service_start( | ||
53 | chat->arm, "arm", | ||
54 | GNUNET_OS_INHERIT_STD_NONE, | ||
55 | NULL, NULL | ||
56 | ); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | void* | ||
61 | notify_handle_fs_progress(void* cls, const struct GNUNET_FS_ProgressInfo* info) | ||
62 | { | ||
63 | struct GNUNET_CHAT_Handle *chat = cls; | ||
64 | |||
65 | if (!chat) | ||
66 | return NULL; | ||
67 | |||
68 | switch (info->status) { | ||
69 | case GNUNET_FS_STATUS_PUBLISH_START: { | ||
70 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
71 | publication->progress = 0.0f; | ||
72 | |||
73 | GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication); | ||
74 | |||
75 | return publication;*/ | ||
76 | break; | ||
77 | } case GNUNET_FS_STATUS_PUBLISH_PROGRESS: { | ||
78 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
79 | publication->progress = 1.0f * info->value.publish.completed / info->value.publish.size; | ||
80 | |||
81 | GNUNET_SCHEDULER_add_now(&CGTK_publication_progress, publication); | ||
82 | |||
83 | return publication;*/ | ||
84 | break; | ||
85 | } case GNUNET_FS_STATUS_PUBLISH_COMPLETED: { | ||
86 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
87 | publication->uri = GNUNET_FS_uri_dup(info->value.publish.specifics.completed.chk_uri); | ||
88 | publication->progress = 1.0f; | ||
89 | |||
90 | GNUNET_SCHEDULER_add_now(&CGTK_publication_finish, publication);*/ | ||
91 | break; | ||
92 | } case GNUNET_FS_STATUS_PUBLISH_ERROR: { | ||
93 | /*publication_t* publication = (publication_t*) info->value.publish.cctx; | ||
94 | |||
95 | GNUNET_SCHEDULER_add_now(&CGTK_publication_error, publication);*/ | ||
96 | break; | ||
97 | } case GNUNET_FS_STATUS_DOWNLOAD_START: { | ||
98 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
99 | request->progress = 0.0f; | ||
100 | |||
101 | return request;*/ | ||
102 | break; | ||
103 | } case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: { | ||
104 | return info->value.download.cctx; | ||
105 | } case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: { | ||
106 | return info->value.download.cctx; | ||
107 | } case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: { | ||
108 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
109 | request->progress = 1.0f * info->value.download.completed / info->value.download.size; | ||
110 | |||
111 | GNUNET_SCHEDULER_add_now(&CGTK_request_progress, request); | ||
112 | |||
113 | return request;*/ | ||
114 | break; | ||
115 | } case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: { | ||
116 | /*request_t* request = (request_t*) info->value.download.cctx; | ||
117 | request->progress = 1.0f; | ||
118 | |||
119 | GNUNET_SCHEDULER_add_now(&CGTK_request_finish, request);*/ | ||
120 | break; | ||
121 | } case GNUNET_FS_STATUS_DOWNLOAD_ERROR: { | ||
122 | /*request_t *request = (request_t *) info->value.download.cctx; | ||
123 | |||
124 | GNUNET_SCHEDULER_add_now(&CGTK_request_error, request);*/ | ||
125 | break; | ||
126 | } case GNUNET_FS_STATUS_UNINDEX_START: { | ||
127 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
128 | publication->progress = 0.0f; | ||
129 | |||
130 | return publication;*/ | ||
131 | break; | ||
132 | } case GNUNET_FS_STATUS_UNINDEX_PROGRESS: { | ||
133 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
134 | publication->progress = 1.0f * info->value.unindex.completed / info->value.unindex.size; | ||
135 | |||
136 | return publication;*/ | ||
137 | break; | ||
138 | } case GNUNET_FS_STATUS_UNINDEX_COMPLETED: { | ||
139 | /*publication_t* publication = (publication_t*) info->value.unindex.cctx; | ||
140 | publication->progress = 1.0f; | ||
141 | |||
142 | GNUNET_SCHEDULER_add_now(&CGTK_publication_unindex_finish, publication);*/ | ||
143 | break; | ||
144 | } default: { | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | return NULL; | ||
150 | } | ||
151 | |||
152 | struct GNUNET_CHAT_CheckHandleRoomMembers | ||
153 | { | ||
154 | const struct GNUNET_IDENTITY_PublicKey *ignore_key; | ||
155 | const struct GNUNET_MESSENGER_Contact *contact; | ||
156 | }; | ||
157 | |||
158 | int | ||
159 | check_handle_room_members (void* cls, | ||
160 | GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room, | ||
161 | const struct GNUNET_MESSENGER_Contact *contact) | ||
162 | { | ||
163 | struct GNUNET_CHAT_CheckHandleRoomMembers *check = cls; | ||
164 | |||
165 | const struct GNUNET_IDENTITY_PublicKey *contact_key = ( | ||
166 | GNUNET_MESSENGER_contact_get_key(contact) | ||
167 | ); | ||
168 | |||
169 | if (0 == GNUNET_memcmp(contact_key, check->ignore_key)) | ||
170 | return GNUNET_YES; | ||
171 | |||
172 | if (check->contact) | ||
173 | return GNUNET_NO; | ||
174 | |||
175 | check->contact = contact; | ||
176 | return GNUNET_YES; | ||
177 | } | ||
178 | |||
179 | struct GNUNET_CHAT_Context* | ||
180 | request_handle_context_by_room (struct GNUNET_CHAT_Handle *handle, | ||
181 | struct GNUNET_MESSENGER_Room *room) | ||
182 | { | ||
183 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key(room); | ||
184 | |||
185 | struct GNUNET_CHAT_Context *context = GNUNET_CONTAINER_multihashmap_get( | ||
186 | handle->contexts, key | ||
187 | ); | ||
188 | |||
189 | if (context) | ||
190 | return context; | ||
191 | |||
192 | context = context_create_from_room(handle, room); | ||
193 | |||
194 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | ||
195 | handle->contexts, key, context, | ||
196 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
197 | { | ||
198 | context_destroy(context); | ||
199 | return NULL; | ||
200 | } | ||
201 | |||
202 | struct GNUNET_CHAT_CheckHandleRoomMembers check; | ||
203 | check.ignore_key = GNUNET_MESSENGER_get_key(handle->messenger); | ||
204 | check.contact = NULL; | ||
205 | |||
206 | GNUNET_MESSENGER_iterate_members(room, check_handle_room_members, &check); | ||
207 | |||
208 | if (check.contact) | ||
209 | { | ||
210 | context->type = GNUNET_CHAT_CONTEXT_TYPE_CONTACT; | ||
211 | |||
212 | struct GNUNET_CHAT_Contact *contact = contact_create_from_member( | ||
213 | handle, check.contact | ||
214 | ); | ||
215 | |||
216 | struct GNUNET_ShortHashCode shorthash; | ||
217 | util_shorthash_from_member(check.contact, &shorthash); | ||
218 | |||
219 | if (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put( | ||
220 | handle->contacts, &shorthash, contact, | ||
221 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
222 | return context; | ||
223 | |||
224 | contact_destroy(contact); | ||
225 | } | ||
226 | else | ||
227 | { | ||
228 | context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; | ||
229 | |||
230 | struct GNUNET_CHAT_Group *group = group_create_from_context( | ||
231 | handle, context | ||
232 | ); | ||
233 | |||
234 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( | ||
235 | handle->groups, key, group, | ||
236 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
237 | return context; | ||
238 | |||
239 | group_destroy(group); | ||
240 | } | ||
241 | |||
242 | GNUNET_CONTAINER_multihashmap_remove(handle->contexts, key, context); | ||
243 | context_destroy(context); | ||
244 | return NULL; | ||
245 | } | ||
246 | |||
247 | int | ||
248 | find_handle_rooms (void *cls, struct GNUNET_MESSENGER_Room *room, | ||
249 | GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *member) | ||
250 | { | ||
251 | struct GNUNET_CHAT_Handle *handle = cls; | ||
252 | |||
253 | request_handle_context_by_room( | ||
254 | handle, room | ||
255 | ); | ||
256 | |||
257 | return GNUNET_YES; | ||
258 | } | ||
259 | |||
260 | void | ||
261 | on_handle_identity(void *cls, | ||
262 | GNUNET_UNUSED struct GNUNET_MESSENGER_Handle *messenger) | ||
263 | { | ||
264 | struct GNUNET_CHAT_Handle *handle = cls; | ||
265 | |||
266 | GNUNET_MESSENGER_find_rooms( | ||
267 | handle->messenger, NULL, find_handle_rooms, handle | ||
268 | ); | ||
269 | } | ||
270 | |||
271 | void | ||
272 | on_handle_message (void *cls, | ||
273 | struct GNUNET_MESSENGER_Room *room, | ||
274 | GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *sender, | ||
275 | const struct GNUNET_MESSENGER_Message *msg, | ||
276 | const struct GNUNET_HashCode *hash, | ||
277 | GNUNET_UNUSED enum GNUNET_MESSENGER_MessageFlags flags) | ||
278 | { | ||
279 | struct GNUNET_CHAT_Handle *handle = cls; | ||
280 | |||
281 | struct GNUNET_CHAT_Context *context = request_handle_context_by_room( | ||
282 | handle, room | ||
283 | ); | ||
284 | |||
285 | if (!context) | ||
286 | return; | ||
287 | |||
288 | struct GNUNET_CHAT_Message *message = GNUNET_CONTAINER_multihashmap_get( | ||
289 | context->messages, hash | ||
290 | ); | ||
291 | |||
292 | if (message) | ||
293 | goto process_callback; | ||
294 | |||
295 | message = message_create_from_msg(context, hash, msg); | ||
296 | |||
297 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | ||
298 | context->messages, hash, message, | ||
299 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
300 | { | ||
301 | message_destroy(message); | ||
302 | return; | ||
303 | } | ||
304 | |||
305 | process_callback: | ||
306 | if (handle->msg_cb) | ||
307 | handle->msg_cb(handle->msg_cls, context, message); | ||
308 | } | ||
diff --git a/src/gnunet_chat_invitation.c b/src/gnunet_chat_invitation.c index 44f7787..9562daa 100644 --- a/src/gnunet_chat_invitation.c +++ b/src/gnunet_chat_invitation.c | |||
@@ -24,14 +24,24 @@ | |||
24 | 24 | ||
25 | #include "gnunet_chat_invitation.h" | 25 | #include "gnunet_chat_invitation.h" |
26 | 26 | ||
27 | void | 27 | struct GNUNET_CHAT_Invitation* |
28 | GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation) | 28 | invitation_create_from_message (struct GNUNET_CHAT_Context *context, |
29 | const struct GNUNET_MESSENGER_MessageInvite *message) | ||
29 | { | 30 | { |
30 | //TODO | 31 | struct GNUNET_CHAT_Invitation *invitation = GNUNET_new(struct GNUNET_CHAT_Invitation); |
32 | |||
33 | invitation->context = context; | ||
34 | |||
35 | GNUNET_memcpy(&(invitation->key), &(message->key), sizeof(invitation->key)); | ||
36 | invitation->door = GNUNET_PEER_intern(&(message->door)); | ||
37 | |||
38 | return invitation; | ||
31 | } | 39 | } |
32 | 40 | ||
33 | void | 41 | void |
34 | GNUNET_CHAT_invitation_decline (struct GNUNET_CHAT_Invitation *invitation) | 42 | invitation_destroy (struct GNUNET_CHAT_Invitation *invitation) |
35 | { | 43 | { |
36 | //TODO | 44 | GNUNET_PEER_decrement_rcs(&(invitation->door), 1); |
45 | |||
46 | GNUNET_free(invitation); | ||
37 | } | 47 | } |
diff --git a/src/gnunet_chat_invitation.h b/src/gnunet_chat_invitation.h index dd2b8e8..433131e 100644 --- a/src/gnunet_chat_invitation.h +++ b/src/gnunet_chat_invitation.h | |||
@@ -25,11 +25,28 @@ | |||
25 | #ifndef GNUNET_CHAT_INVITATION_H_ | 25 | #ifndef GNUNET_CHAT_INVITATION_H_ |
26 | #define GNUNET_CHAT_INVITATION_H_ | 26 | #define GNUNET_CHAT_INVITATION_H_ |
27 | 27 | ||
28 | #include "gnunet_chat_lib.h" | 28 | #include <gnunet/platform.h> |
29 | #include <gnunet/gnunet_common.h> | ||
30 | #include <gnunet/gnunet_crypto_lib.h> | ||
31 | #include <gnunet/gnunet_messenger_service.h> | ||
32 | #include <gnunet/gnunet_peer_lib.h> | ||
33 | #include <gnunet/gnunet_util_lib.h> | ||
34 | |||
35 | struct GNUNET_CHAT_Context; | ||
29 | 36 | ||
30 | struct GNUNET_CHAT_Invitation | 37 | struct GNUNET_CHAT_Invitation |
31 | { | 38 | { |
39 | struct GNUNET_CHAT_Context *context; | ||
32 | 40 | ||
41 | struct GNUNET_HashCode key; | ||
42 | GNUNET_PEER_Id door; | ||
33 | }; | 43 | }; |
34 | 44 | ||
45 | struct GNUNET_CHAT_Invitation* | ||
46 | invitation_create_from_message (struct GNUNET_CHAT_Context *context, | ||
47 | const struct GNUNET_MESSENGER_MessageInvite *message); | ||
48 | |||
49 | void | ||
50 | invitation_destroy (struct GNUNET_CHAT_Invitation *invitation); | ||
51 | |||
35 | #endif /* GNUNET_CHAT_INVITATION_H_ */ | 52 | #endif /* GNUNET_CHAT_INVITATION_H_ */ |
diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c new file mode 100644 index 0000000..23c541d --- /dev/null +++ b/src/gnunet_chat_lib.c | |||
@@ -0,0 +1,693 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file gnunet_chat_lib.c | ||
23 | */ | ||
24 | |||
25 | #include "gnunet_chat_lib.h" | ||
26 | |||
27 | #include <limits.h> | ||
28 | |||
29 | #include "gnunet_chat_config.h" | ||
30 | #include "gnunet_chat_contact.h" | ||
31 | #include "gnunet_chat_context.h" | ||
32 | #include "gnunet_chat_file.h" | ||
33 | #include "gnunet_chat_group.h" | ||
34 | #include "gnunet_chat_handle.h" | ||
35 | #include "gnunet_chat_invitation.h" | ||
36 | #include "gnunet_chat_message.h" | ||
37 | #include "gnunet_chat_util.h" | ||
38 | |||
39 | #include "gnunet_chat_lib_intern.c" | ||
40 | |||
41 | struct GNUNET_CHAT_Handle* | ||
42 | GNUNET_CHAT_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
43 | const char *name, | ||
44 | GNUNET_CHAT_WarningCallback warn_cb, void *warn_cls, | ||
45 | GNUNET_CHAT_ContextMessageCallback msg_cb, void *msg_cls) | ||
46 | { | ||
47 | if (!cfg) | ||
48 | return NULL; | ||
49 | |||
50 | if (!name) | ||
51 | return NULL; | ||
52 | |||
53 | return handle_create_from_config( | ||
54 | cfg, name, msg_cb, msg_cls, warn_cb, warn_cls | ||
55 | ); | ||
56 | } | ||
57 | |||
58 | void | ||
59 | GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle) | ||
60 | { | ||
61 | if (!handle) | ||
62 | return; | ||
63 | |||
64 | handle_destroy(handle); | ||
65 | } | ||
66 | |||
67 | int | ||
68 | GNUNET_CHAT_update (struct GNUNET_CHAT_Handle *handle) | ||
69 | { | ||
70 | if (!handle) | ||
71 | return GNUNET_SYSERR; | ||
72 | |||
73 | return GNUNET_MESSENGER_update(handle->messenger); | ||
74 | } | ||
75 | |||
76 | int | ||
77 | GNUNET_CHAT_set_name (struct GNUNET_CHAT_Handle *handle, | ||
78 | const char *name) | ||
79 | { | ||
80 | if (!handle) | ||
81 | return GNUNET_SYSERR; | ||
82 | |||
83 | if (!name) | ||
84 | return GNUNET_NO; | ||
85 | |||
86 | return GNUNET_MESSENGER_set_name(handle->messenger, name); | ||
87 | } | ||
88 | |||
89 | const char* | ||
90 | GNUNET_CHAT_get_name (const struct GNUNET_CHAT_Handle *handle) | ||
91 | { | ||
92 | if (!handle) | ||
93 | return NULL; | ||
94 | |||
95 | return GNUNET_MESSENGER_get_name(handle->messenger); | ||
96 | } | ||
97 | |||
98 | const struct GNUNET_IDENTITY_PublicKey* | ||
99 | GNUNET_CHAT_get_key (const struct GNUNET_CHAT_Handle *handle) | ||
100 | { | ||
101 | if (!handle) | ||
102 | return NULL; | ||
103 | |||
104 | return GNUNET_MESSENGER_get_key(handle->messenger); | ||
105 | } | ||
106 | |||
107 | int | ||
108 | GNUNET_CHAT_iterate_contacts (struct GNUNET_CHAT_Handle *handle, | ||
109 | GNUNET_CHAT_ContactCallback callback, | ||
110 | void *cls) | ||
111 | { | ||
112 | if (!handle) | ||
113 | return GNUNET_SYSERR; | ||
114 | |||
115 | struct GNUNET_CHAT_HandleIterateContacts it; | ||
116 | it.handle = handle; | ||
117 | it.cb = callback; | ||
118 | it.cls = cls; | ||
119 | |||
120 | return GNUNET_CONTAINER_multishortmap_iterate( | ||
121 | handle->contacts, it_handle_iterate_contacts, &it | ||
122 | ); | ||
123 | } | ||
124 | |||
125 | struct GNUNET_CHAT_Group * | ||
126 | GNUNET_CHAT_group_create (struct GNUNET_CHAT_Handle *handle, | ||
127 | const char* topic) | ||
128 | { | ||
129 | if (!handle) | ||
130 | return NULL; | ||
131 | |||
132 | struct GNUNET_HashCode key; | ||
133 | |||
134 | if (topic) | ||
135 | GNUNET_CRYPTO_hash(topic, strlen(topic), &key); | ||
136 | else | ||
137 | GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, &key, sizeof(key)); | ||
138 | |||
139 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains( | ||
140 | handle->contexts, &key)) | ||
141 | return NULL; | ||
142 | |||
143 | struct GNUNET_MESSENGER_Room *room = GNUNET_MESSENGER_open_room( | ||
144 | handle->messenger, &key | ||
145 | ); | ||
146 | |||
147 | struct GNUNET_CHAT_Context *context = context_create_from_room(handle, room); | ||
148 | |||
149 | context->type = GNUNET_CHAT_CONTEXT_TYPE_GROUP; | ||
150 | |||
151 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | ||
152 | handle->contexts, &key, context, | ||
153 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
154 | goto destroy_context; | ||
155 | |||
156 | struct GNUNET_CHAT_Group *group = group_create_from_context(handle, context); | ||
157 | |||
158 | util_set_name_field(topic, &(group->topic)); | ||
159 | |||
160 | if (group->topic) | ||
161 | group_publish(group); | ||
162 | |||
163 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put( | ||
164 | handle->groups, &key, group, | ||
165 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
166 | return group; | ||
167 | |||
168 | group_destroy(group); | ||
169 | |||
170 | GNUNET_CONTAINER_multihashmap_remove(handle->contexts, &key, context); | ||
171 | |||
172 | destroy_context: | ||
173 | context_destroy(context); | ||
174 | return NULL; | ||
175 | } | ||
176 | |||
177 | int | ||
178 | GNUNET_CHAT_iterate_groups (struct GNUNET_CHAT_Handle *handle, | ||
179 | GNUNET_CHAT_GroupCallback callback, | ||
180 | void *cls) | ||
181 | { | ||
182 | if (!handle) | ||
183 | return GNUNET_SYSERR; | ||
184 | |||
185 | struct GNUNET_CHAT_HandleIterateGroups it; | ||
186 | it.handle = handle; | ||
187 | it.cb = callback; | ||
188 | it.cls = cls; | ||
189 | |||
190 | return GNUNET_CONTAINER_multihashmap_iterate( | ||
191 | handle->groups, it_handle_iterate_groups, &it | ||
192 | ); | ||
193 | } | ||
194 | |||
195 | int | ||
196 | GNUNET_CHAT_contact_delete (struct GNUNET_CHAT_Contact *contact) | ||
197 | { | ||
198 | if (!contact) | ||
199 | return GNUNET_SYSERR; | ||
200 | |||
201 | struct GNUNET_ShortHashCode shorthash; | ||
202 | util_shorthash_from_member(contact->member, &shorthash); | ||
203 | |||
204 | GNUNET_CONTAINER_multishortmap_remove( | ||
205 | contact->handle->contacts, &shorthash, contact | ||
206 | ); | ||
207 | |||
208 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( | ||
209 | contact->context->room | ||
210 | ); | ||
211 | |||
212 | GNUNET_CONTAINER_multihashmap_remove( | ||
213 | contact->handle->contexts, key, contact->context | ||
214 | ); | ||
215 | |||
216 | GNUNET_MESSENGER_close_room(contact->context->room); | ||
217 | |||
218 | context_destroy(contact->context); | ||
219 | contact_destroy(contact); | ||
220 | return GNUNET_OK; | ||
221 | } | ||
222 | |||
223 | void | ||
224 | GNUNET_CHAT_contact_set_name (struct GNUNET_CHAT_Contact *contact, | ||
225 | const char *name) | ||
226 | { | ||
227 | if (!contact) | ||
228 | return; | ||
229 | |||
230 | util_set_name_field(name, &(contact->context->nick)); | ||
231 | } | ||
232 | |||
233 | |||
234 | const char* | ||
235 | GNUNET_CHAT_contact_get_name (const struct GNUNET_CHAT_Contact *contact) | ||
236 | { | ||
237 | if (!contact) | ||
238 | return NULL; | ||
239 | |||
240 | if (contact->context->nick) | ||
241 | return contact->context->nick; | ||
242 | |||
243 | return GNUNET_MESSENGER_contact_get_name(contact->member); | ||
244 | } | ||
245 | |||
246 | |||
247 | const struct GNUNET_IDENTITY_PublicKey* | ||
248 | GNUNET_CHAT_contact_get_key (const struct GNUNET_CHAT_Contact *contact) | ||
249 | { | ||
250 | if (!contact) | ||
251 | return NULL; | ||
252 | |||
253 | return GNUNET_MESSENGER_contact_get_key(contact->member); | ||
254 | } | ||
255 | |||
256 | |||
257 | struct GNUNET_CHAT_Context* | ||
258 | GNUNET_CHAT_contact_get_context (struct GNUNET_CHAT_Contact *contact) | ||
259 | { | ||
260 | if (!contact) | ||
261 | return NULL; | ||
262 | |||
263 | return contact->context; | ||
264 | } | ||
265 | |||
266 | |||
267 | int | ||
268 | GNUNET_CHAT_group_leave (struct GNUNET_CHAT_Group *group) | ||
269 | { | ||
270 | if (!group) | ||
271 | return GNUNET_SYSERR; | ||
272 | |||
273 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( | ||
274 | group->context->room | ||
275 | ); | ||
276 | |||
277 | GNUNET_CONTAINER_multihashmap_remove( | ||
278 | group->handle->groups, key, group | ||
279 | ); | ||
280 | |||
281 | GNUNET_CONTAINER_multihashmap_remove( | ||
282 | group->handle->contexts, key, group->context | ||
283 | ); | ||
284 | |||
285 | GNUNET_MESSENGER_close_room(group->context->room); | ||
286 | |||
287 | context_destroy(group->context); | ||
288 | group_destroy(group); | ||
289 | return GNUNET_OK; | ||
290 | } | ||
291 | |||
292 | |||
293 | void | ||
294 | GNUNET_CHAT_group_set_name (struct GNUNET_CHAT_Group *group, | ||
295 | const char *name) | ||
296 | { | ||
297 | if (!group) | ||
298 | return; | ||
299 | |||
300 | util_set_name_field(name, &(group->context->nick)); | ||
301 | } | ||
302 | |||
303 | |||
304 | const char* | ||
305 | GNUNET_CHAT_group_get_name (const struct GNUNET_CHAT_Group *group) | ||
306 | { | ||
307 | if (!group) | ||
308 | return NULL; | ||
309 | |||
310 | return group->context->nick; | ||
311 | } | ||
312 | |||
313 | |||
314 | void | ||
315 | GNUNET_CHAT_group_invite_contact (struct GNUNET_CHAT_Group *group, | ||
316 | struct GNUNET_CHAT_Contact *contact) | ||
317 | { | ||
318 | if ((!group) || (!contact)) | ||
319 | return; | ||
320 | |||
321 | const struct GNUNET_HashCode *key = GNUNET_MESSENGER_room_get_key( | ||
322 | group->context->room | ||
323 | ); | ||
324 | |||
325 | GNUNET_MESSENGER_open_room(group->handle->messenger, key); | ||
326 | |||
327 | struct GNUNET_MESSENGER_Message msg; | ||
328 | msg.header.kind = GNUNET_MESSENGER_KIND_INVITE; | ||
329 | GNUNET_CRYPTO_get_peer_identity(group->handle->cfg, &(msg.body.invite.door)); | ||
330 | GNUNET_memcpy(&(msg.body.invite.key), key, sizeof(msg.body.invite.key)); | ||
331 | |||
332 | GNUNET_MESSENGER_send_message(contact->context->room, &msg, contact->member); | ||
333 | } | ||
334 | |||
335 | int | ||
336 | GNUNET_CHAT_group_iterate_contacts (struct GNUNET_CHAT_Group *group, | ||
337 | GNUNET_CHAT_GroupContactCallback callback, | ||
338 | void *cls) | ||
339 | { | ||
340 | if (!group) | ||
341 | return GNUNET_SYSERR; | ||
342 | |||
343 | struct GNUNET_CHAT_GroupIterateContacts it; | ||
344 | it.group = group; | ||
345 | it.cb = callback; | ||
346 | it.cls = cls; | ||
347 | |||
348 | return GNUNET_MESSENGER_iterate_members( | ||
349 | group->context->room, it_group_iterate_contacts, &it | ||
350 | ); | ||
351 | } | ||
352 | |||
353 | |||
354 | struct GNUNET_CHAT_Context* | ||
355 | GNUNET_CHAT_group_get_context (struct GNUNET_CHAT_Group *group) | ||
356 | { | ||
357 | if (!group) | ||
358 | return NULL; | ||
359 | |||
360 | return group->context; | ||
361 | } | ||
362 | |||
363 | void | ||
364 | GNUNET_CHAT_context_send_text (struct GNUNET_CHAT_Context *context, | ||
365 | const char *text) | ||
366 | { | ||
367 | if ((!context) || (!text)) | ||
368 | return; | ||
369 | |||
370 | struct GNUNET_MESSENGER_Message msg; | ||
371 | msg.header.kind = GNUNET_MESSENGER_KIND_TEXT; | ||
372 | msg.body.text.text = GNUNET_strdup(text); | ||
373 | |||
374 | GNUNET_MESSENGER_send_message(context->room, &msg, NULL); | ||
375 | |||
376 | GNUNET_free(msg.body.text.text); | ||
377 | } | ||
378 | |||
379 | |||
380 | void | ||
381 | GNUNET_CHAT_context_send_file (struct GNUNET_CHAT_Context *context, | ||
382 | const char *path) | ||
383 | { | ||
384 | if ((!context) || (!path)) | ||
385 | return; | ||
386 | |||
387 | // TODO: encrypt file, publish file, share file | ||
388 | } | ||
389 | |||
390 | |||
391 | void | ||
392 | GNUNET_CHAT_context_send_uri (struct GNUNET_CHAT_Context *context, | ||
393 | const char *uri) | ||
394 | { | ||
395 | if ((!context) || (!uri)) | ||
396 | return; | ||
397 | |||
398 | struct GNUNET_FS_Uri *furi = GNUNET_FS_uri_parse(uri, NULL); | ||
399 | |||
400 | if (!furi) | ||
401 | return; | ||
402 | |||
403 | // TODO: download file, hash file, share file | ||
404 | } | ||
405 | |||
406 | |||
407 | void | ||
408 | GNUNET_CHAT_context_share_file (struct GNUNET_CHAT_Context *context, | ||
409 | const struct GNUNET_CHAT_File *file) | ||
410 | { | ||
411 | if ((!context) || (!file) || (strlen(file->name) > NAME_MAX)) | ||
412 | return; | ||
413 | |||
414 | struct GNUNET_MESSENGER_Message msg; | ||
415 | msg.header.kind = GNUNET_MESSENGER_KIND_FILE; | ||
416 | GNUNET_memcpy(&(msg.body.file.key), &(file->key), sizeof(file->key)); | ||
417 | GNUNET_memcpy(&(msg.body.file.hash), &(file->hash), sizeof(file->hash)); | ||
418 | GNUNET_strlcpy(msg.body.file.name, file->name, NAME_MAX); | ||
419 | msg.body.file.uri = GNUNET_FS_uri_to_string(file->uri); | ||
420 | |||
421 | GNUNET_MESSENGER_send_message(context->room, &msg, NULL); | ||
422 | |||
423 | GNUNET_free(msg.body.file.uri); | ||
424 | } | ||
425 | |||
426 | |||
427 | void | ||
428 | GNUNET_CHAT_context_delete_message (const struct GNUNET_CHAT_Message *message, | ||
429 | struct GNUNET_TIME_Relative delay) | ||
430 | { | ||
431 | if (!message) | ||
432 | return; | ||
433 | |||
434 | struct GNUNET_MESSENGER_Message msg; | ||
435 | msg.header.kind = GNUNET_MESSENGER_KIND_DELETE; | ||
436 | GNUNET_memcpy(&(msg.body.delete.hash), &(message->hash), sizeof(message->hash)); | ||
437 | msg.body.delete.delay = GNUNET_TIME_relative_hton(delay); | ||
438 | |||
439 | GNUNET_MESSENGER_send_message(message->context->room, &msg, NULL); | ||
440 | } | ||
441 | |||
442 | |||
443 | |||
444 | int | ||
445 | GNUNET_CHAT_context_iterate_messages (struct GNUNET_CHAT_Context *context, | ||
446 | GNUNET_CHAT_ContextMessageCallback callback, | ||
447 | void *cls) | ||
448 | { | ||
449 | if (!context) | ||
450 | return GNUNET_SYSERR; | ||
451 | |||
452 | struct GNUNET_CHAT_ContextIterateMessages it; | ||
453 | it.context = context; | ||
454 | it.cb = callback; | ||
455 | it.cls = cls; | ||
456 | |||
457 | return GNUNET_CONTAINER_multihashmap_iterate( | ||
458 | context->messages, it_context_iterate_messages, &it | ||
459 | ); | ||
460 | } | ||
461 | |||
462 | |||
463 | enum GNUNET_CHAT_MessageKind | ||
464 | GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) | ||
465 | { | ||
466 | if (!message) | ||
467 | return GNUNET_CHAT_KIND_UNKNOWN; | ||
468 | |||
469 | switch (message->msg->header.kind) | ||
470 | { | ||
471 | case GNUNET_MESSENGER_KIND_INVITE: | ||
472 | return GNUNET_CHAT_KIND_INVITATION; | ||
473 | case GNUNET_MESSENGER_KIND_TEXT: | ||
474 | return GNUNET_CHAT_KIND_TEXT; | ||
475 | case GNUNET_MESSENGER_KIND_FILE: | ||
476 | return GNUNET_CHAT_KIND_FILE; | ||
477 | default: | ||
478 | return GNUNET_CHAT_KIND_UNKNOWN; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | |||
483 | struct GNUNET_TIME_Absolute | ||
484 | GNUNET_CHAT_message_get_timestamp (const struct GNUNET_CHAT_Message *message) | ||
485 | { | ||
486 | if (!message) | ||
487 | return GNUNET_TIME_absolute_get_zero_(); | ||
488 | |||
489 | return GNUNET_TIME_absolute_ntoh(message->msg->header.timestamp); | ||
490 | } | ||
491 | |||
492 | |||
493 | const struct GNUNET_CHAT_Contact* | ||
494 | GNUNET_CHAT_message_get_sender (const struct GNUNET_CHAT_Message *message) | ||
495 | { | ||
496 | if (!message) | ||
497 | return NULL; | ||
498 | |||
499 | const struct GNUNET_MESSENGER_Contact *sender = GNUNET_MESSENGER_get_sender( | ||
500 | message->context->room, &(message->hash) | ||
501 | ); | ||
502 | |||
503 | if (!sender) | ||
504 | return NULL; | ||
505 | |||
506 | struct GNUNET_ShortHashCode shorthash; | ||
507 | util_shorthash_from_member(sender, &shorthash); | ||
508 | |||
509 | return GNUNET_CONTAINER_multishortmap_get( | ||
510 | message->context->handle->contacts, &shorthash | ||
511 | ); | ||
512 | } | ||
513 | |||
514 | |||
515 | int | ||
516 | GNUNET_CHAT_message_get_read_receipt (const struct GNUNET_CHAT_Message *message, | ||
517 | GNUNET_CHAT_MessageReadReceiptCallback callback, | ||
518 | void *cls) | ||
519 | { | ||
520 | if (!message) | ||
521 | return GNUNET_SYSERR; | ||
522 | |||
523 | // TODO: request read receipt? / check if newer message was received of sender? | ||
524 | |||
525 | return GNUNET_SYSERR; | ||
526 | } | ||
527 | |||
528 | |||
529 | const char* | ||
530 | GNUNET_CHAT_message_get_text (const struct GNUNET_CHAT_Message *message) | ||
531 | { | ||
532 | if (!message) | ||
533 | return NULL; | ||
534 | |||
535 | if (GNUNET_MESSENGER_KIND_TEXT != message->msg->header.kind) | ||
536 | return NULL; | ||
537 | |||
538 | return message->msg->body.text.text; | ||
539 | } | ||
540 | |||
541 | |||
542 | struct GNUNET_CHAT_File* | ||
543 | GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message) | ||
544 | { | ||
545 | if (!message) | ||
546 | return NULL; | ||
547 | |||
548 | if (GNUNET_MESSENGER_KIND_FILE != message->msg->header.kind) | ||
549 | return NULL; | ||
550 | |||
551 | return GNUNET_CONTAINER_multihashmap_get( | ||
552 | message->context->handle->files, | ||
553 | &(message->msg->body.file.hash) | ||
554 | ); | ||
555 | } | ||
556 | |||
557 | |||
558 | struct GNUNET_CHAT_Invitation* | ||
559 | GNUNET_CHAT_message_get_invitation (const struct GNUNET_CHAT_Message *message) | ||
560 | { | ||
561 | if (!message) | ||
562 | return NULL; | ||
563 | |||
564 | if (GNUNET_MESSENGER_KIND_INVITE != message->msg->header.kind) | ||
565 | return NULL; | ||
566 | |||
567 | return GNUNET_CONTAINER_multihashmap_get( | ||
568 | message->context->invites, | ||
569 | &(message->hash) | ||
570 | ); | ||
571 | } | ||
572 | |||
573 | |||
574 | const struct GNUNET_HashCode* | ||
575 | GNUNET_CHAT_file_get_hash (const struct GNUNET_CHAT_File *file) | ||
576 | { | ||
577 | if (!file) | ||
578 | return NULL; | ||
579 | |||
580 | return &(file->hash); | ||
581 | } | ||
582 | |||
583 | |||
584 | uint64_t | ||
585 | GNUNET_CHAT_file_get_size (const struct GNUNET_CHAT_File *file) | ||
586 | { | ||
587 | if (!file) | ||
588 | return 0; | ||
589 | |||
590 | if (file->uri) | ||
591 | return GNUNET_FS_uri_chk_get_file_size(file->uri); | ||
592 | |||
593 | const char *path = ""; // TODO: path = download_directory + file->name | ||
594 | |||
595 | // TODO: check size through info or check locally? | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | |||
601 | int | ||
602 | GNUNET_CHAT_file_is_local (const struct GNUNET_CHAT_File *file) | ||
603 | { | ||
604 | if (!file) | ||
605 | return GNUNET_SYSERR; | ||
606 | |||
607 | const char *path = ""; // TODO: path = download_directory + file->name | ||
608 | |||
609 | // TODO: check locally? | ||
610 | |||
611 | return GNUNET_SYSERR; | ||
612 | } | ||
613 | |||
614 | |||
615 | int | ||
616 | GNUNET_CHAT_file_start_download (struct GNUNET_CHAT_File *file, | ||
617 | GNUNET_CHAT_MessageFileDownloadCallback callback, | ||
618 | void *cls) | ||
619 | { | ||
620 | if (!file) | ||
621 | return GNUNET_SYSERR; | ||
622 | |||
623 | // TODO: check if downloading? | ||
624 | |||
625 | const char *path = ""; // TODO: path = download_directory + file->name | ||
626 | |||
627 | file->download = GNUNET_FS_download_start( | ||
628 | file->handle->fs, | ||
629 | file->uri, | ||
630 | NULL, | ||
631 | path, | ||
632 | NULL, | ||
633 | 0, | ||
634 | 0, | ||
635 | 0, | ||
636 | GNUNET_FS_DOWNLOAD_OPTION_NONE, | ||
637 | NULL, | ||
638 | NULL | ||
639 | ); | ||
640 | |||
641 | return GNUNET_OK; | ||
642 | } | ||
643 | |||
644 | |||
645 | int | ||
646 | GNUNET_CHAT_file_pause_download (struct GNUNET_CHAT_File *file) | ||
647 | { | ||
648 | if (!file) | ||
649 | return GNUNET_SYSERR; | ||
650 | |||
651 | GNUNET_FS_download_suspend(file->download); | ||
652 | return GNUNET_OK; | ||
653 | } | ||
654 | |||
655 | |||
656 | int | ||
657 | GNUNET_CHAT_file_resume_download (struct GNUNET_CHAT_File *file) | ||
658 | { | ||
659 | if (!file) | ||
660 | return GNUNET_SYSERR; | ||
661 | |||
662 | GNUNET_FS_download_resume(file->download); | ||
663 | return GNUNET_OK; | ||
664 | } | ||
665 | |||
666 | |||
667 | int | ||
668 | GNUNET_CHAT_file_stop_download (struct GNUNET_CHAT_File *file) | ||
669 | { | ||
670 | if (!file) | ||
671 | return GNUNET_SYSERR; | ||
672 | |||
673 | GNUNET_FS_download_stop(file->download, GNUNET_YES); | ||
674 | file->download = NULL; | ||
675 | return GNUNET_OK; | ||
676 | } | ||
677 | |||
678 | |||
679 | void | ||
680 | GNUNET_CHAT_invitation_accept (struct GNUNET_CHAT_Invitation *invitation) | ||
681 | { | ||
682 | if (!invitation) | ||
683 | return; | ||
684 | |||
685 | struct GNUNET_PeerIdentity door; | ||
686 | GNUNET_PEER_resolve(invitation->door, &door); | ||
687 | |||
688 | GNUNET_MESSENGER_enter_room( | ||
689 | invitation->context->handle->messenger, | ||
690 | &door, &(invitation->key) | ||
691 | ); | ||
692 | } | ||
693 | |||
diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c new file mode 100644 index 0000000..8ccfce5 --- /dev/null +++ b/src/gnunet_chat_lib_intern.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file gnunet_chat_lib_intern.c | ||
23 | */ | ||
24 | |||
25 | #define GNUNET_UNUSED __attribute__ ((unused)) | ||
26 | |||
27 | struct GNUNET_CHAT_HandleIterateContacts | ||
28 | { | ||
29 | struct GNUNET_CHAT_Handle *handle; | ||
30 | GNUNET_CHAT_ContactCallback cb; | ||
31 | void *cls; | ||
32 | }; | ||
33 | |||
34 | int | ||
35 | it_handle_iterate_contacts (void *cls, | ||
36 | GNUNET_UNUSED const struct GNUNET_ShortHashCode *key, | ||
37 | void *value) | ||
38 | { | ||
39 | struct GNUNET_CHAT_HandleIterateContacts *it = cls; | ||
40 | |||
41 | if (!(it->cb)) | ||
42 | return GNUNET_YES; | ||
43 | |||
44 | struct GNUNET_CHAT_Contact *contact = value; | ||
45 | |||
46 | return it->cb(it->cls, it->handle, contact); | ||
47 | } | ||
48 | |||
49 | struct GNUNET_CHAT_HandleIterateGroups | ||
50 | { | ||
51 | struct GNUNET_CHAT_Handle *handle; | ||
52 | GNUNET_CHAT_GroupCallback cb; | ||
53 | void *cls; | ||
54 | }; | ||
55 | |||
56 | int | ||
57 | it_handle_iterate_groups (void *cls, | ||
58 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
59 | void *value) | ||
60 | { | ||
61 | struct GNUNET_CHAT_HandleIterateGroups *it = cls; | ||
62 | |||
63 | if (!(it->cb)) | ||
64 | return GNUNET_YES; | ||
65 | |||
66 | struct GNUNET_CHAT_Group *group = value; | ||
67 | |||
68 | return it->cb(it->cls, it->handle, group); | ||
69 | } | ||
70 | |||
71 | struct GNUNET_CHAT_GroupIterateContacts | ||
72 | { | ||
73 | struct GNUNET_CHAT_Group *group; | ||
74 | GNUNET_CHAT_GroupContactCallback cb; | ||
75 | void *cls; | ||
76 | }; | ||
77 | |||
78 | int | ||
79 | it_group_iterate_contacts (void* cls, | ||
80 | GNUNET_UNUSED struct GNUNET_MESSENGER_Room *room, | ||
81 | const struct GNUNET_MESSENGER_Contact *member) | ||
82 | { | ||
83 | struct GNUNET_CHAT_GroupIterateContacts *it = cls; | ||
84 | |||
85 | if (!(it->cb)) | ||
86 | return GNUNET_YES; | ||
87 | |||
88 | struct GNUNET_ShortHashCode shorthash; | ||
89 | util_shorthash_from_member(member, &shorthash); | ||
90 | |||
91 | struct GNUNET_CHAT_Contact *contact = GNUNET_CONTAINER_multishortmap_get( | ||
92 | it->group->handle->contacts, &shorthash | ||
93 | ); | ||
94 | |||
95 | return it->cb(it->cls, it->group, contact); | ||
96 | } | ||
97 | |||
98 | struct GNUNET_CHAT_ContextIterateMessages | ||
99 | { | ||
100 | struct GNUNET_CHAT_Context *context; | ||
101 | GNUNET_CHAT_ContextMessageCallback cb; | ||
102 | void *cls; | ||
103 | }; | ||
104 | |||
105 | int | ||
106 | it_context_iterate_messages (void *cls, | ||
107 | GNUNET_UNUSED const struct GNUNET_HashCode *key, | ||
108 | void *value) | ||
109 | { | ||
110 | struct GNUNET_CHAT_ContextIterateMessages *it = cls; | ||
111 | |||
112 | if (!(it->cb)) | ||
113 | return GNUNET_YES; | ||
114 | |||
115 | struct GNUNET_CHAT_Message *message = value; | ||
116 | |||
117 | return it->cb(it->cls, it->context, message); | ||
118 | } | ||
119 | |||
120 | |||
121 | |||
122 | |||
123 | |||
124 | |||
diff --git a/src/gnunet_chat_message.c b/src/gnunet_chat_message.c index 805453e..bff8a52 100644 --- a/src/gnunet_chat_message.c +++ b/src/gnunet_chat_message.c | |||
@@ -22,70 +22,26 @@ | |||
22 | * @file gnunet_chat_message.c | 22 | * @file gnunet_chat_message.c |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "gnunet_chat_lib.h" | ||
26 | #include "gnunet_chat_message.h" | 25 | #include "gnunet_chat_message.h" |
27 | 26 | ||
28 | enum GNUNET_CHAT_MessageKind | 27 | struct GNUNET_CHAT_Message* |
29 | GNUNET_CHAT_message_get_kind (const struct GNUNET_CHAT_Message *message) | 28 | message_create_from_msg (struct GNUNET_CHAT_Context *context, |
29 | const struct GNUNET_HashCode *hash, | ||
30 | const struct GNUNET_MESSENGER_Message *msg) | ||
30 | { | 31 | { |
31 | if (!message) | 32 | struct GNUNET_CHAT_Message *message = GNUNET_new(struct GNUNET_CHAT_Message); |
32 | return GNUNET_CHAT_KIND_UNKNOWN; | ||
33 | 33 | ||
34 | switch (message->message->header.kind) { | 34 | message->context = context; |
35 | case GNUNET_MESSENGER_KIND_INVITE: | ||
36 | return GNUNET_CHAT_KIND_INVITATION; | ||
37 | case GNUNET_MESSENGER_KIND_TEXT: | ||
38 | return GNUNET_CHAT_KIND_TEXT; | ||
39 | case GNUNET_MESSENGER_KIND_FILE: | ||
40 | return GNUNET_CHAT_KIND_FILE; | ||
41 | default: | ||
42 | return GNUNET_CHAT_KIND_UNKNOWN; | ||
43 | } | ||
44 | } | ||
45 | |||
46 | struct GNUNET_TIME_Absolute | ||
47 | GNUNET_CHAT_message_get_timestamp (const struct GNUNET_CHAT_Message *message) | ||
48 | { | ||
49 | if (!message) | ||
50 | return GNUNET_TIME_absolute_get_zero_(); | ||
51 | |||
52 | return GNUNET_TIME_absolute_ntoh(message->message->header.timestamp); | ||
53 | } | ||
54 | |||
55 | const struct GNUNET_CHAT_Contact* | ||
56 | GNUNET_CHAT_message_get_sender (const struct GNUNET_CHAT_Message *message) | ||
57 | { | ||
58 | return NULL; | ||
59 | } | ||
60 | 35 | ||
61 | int | 36 | GNUNET_memcpy(&(message->hash), hash, sizeof(message->hash)); |
62 | GNUNET_CHAT_message_get_read_receipt (const struct GNUNET_CHAT_Message *message, | ||
63 | GNUNET_CHAT_MessageReadReceiptCallback callback, | ||
64 | void *cls) | ||
65 | { | ||
66 | return GNUNET_SYSERR; | ||
67 | } | ||
68 | |||
69 | struct GNUNET_CHAT_Invitation* | ||
70 | GNUNET_CHAT_message_get_invitation (const struct GNUNET_CHAT_Message *message) | ||
71 | { | ||
72 | return NULL; //TODO | ||
73 | } | ||
74 | |||
75 | const char* | ||
76 | GNUNET_CHAT_message_get_text (const struct GNUNET_CHAT_Message *message) | ||
77 | { | ||
78 | if (!message) | ||
79 | return NULL; | ||
80 | 37 | ||
81 | if (GNUNET_MESSENGER_KIND_TEXT != message->message->header.kind) | 38 | message->msg = msg; |
82 | return NULL; | ||
83 | 39 | ||
84 | return message->message->body.text.text; | 40 | return message; |
85 | } | 41 | } |
86 | 42 | ||
87 | struct GNUNET_CHAT_File* | 43 | void |
88 | GNUNET_CHAT_message_get_file (const struct GNUNET_CHAT_Message *message) | 44 | message_destroy (struct GNUNET_CHAT_Message* message) |
89 | { | 45 | { |
90 | return NULL; | 46 | GNUNET_free(message); |
91 | } | 47 | } |
diff --git a/src/gnunet_chat_message.h b/src/gnunet_chat_message.h index 6de7fae..7b3051c 100644 --- a/src/gnunet_chat_message.h +++ b/src/gnunet_chat_message.h | |||
@@ -26,13 +26,27 @@ | |||
26 | #define GNUNET_CHAT_MESSAGE_H_ | 26 | #define GNUNET_CHAT_MESSAGE_H_ |
27 | 27 | ||
28 | #include <gnunet/platform.h> | 28 | #include <gnunet/platform.h> |
29 | #include <gnunet/gnunet_common.h> | ||
29 | #include <gnunet/gnunet_messenger_service.h> | 30 | #include <gnunet/gnunet_messenger_service.h> |
30 | #include <gnunet/gnunet_util_lib.h> | 31 | #include <gnunet/gnunet_util_lib.h> |
31 | 32 | ||
33 | struct GNUNET_CHAT_Context; | ||
34 | |||
32 | struct GNUNET_CHAT_Message | 35 | struct GNUNET_CHAT_Message |
33 | { | 36 | { |
37 | struct GNUNET_CHAT_Context *context; | ||
38 | |||
34 | struct GNUNET_HashCode hash; | 39 | struct GNUNET_HashCode hash; |
35 | const struct GNUNET_MESSENGER_Message *message; | 40 | |
41 | const struct GNUNET_MESSENGER_Message *msg; | ||
36 | }; | 42 | }; |
37 | 43 | ||
44 | struct GNUNET_CHAT_Message* | ||
45 | message_create_from_msg (struct GNUNET_CHAT_Context *context, | ||
46 | const struct GNUNET_HashCode *hash, | ||
47 | const struct GNUNET_MESSENGER_Message *msg); | ||
48 | |||
49 | void | ||
50 | message_destroy (struct GNUNET_CHAT_Message* message); | ||
51 | |||
38 | #endif /* GNUNET_CHAT_MESSAGE_H_ */ | 52 | #endif /* GNUNET_CHAT_MESSAGE_H_ */ |
diff --git a/src/gnunet_chat_util.c b/src/gnunet_chat_util.c new file mode 100644 index 0000000..1a75ba9 --- /dev/null +++ b/src/gnunet_chat_util.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file gnunet_chat_util.c | ||
23 | */ | ||
24 | |||
25 | #include "gnunet_chat_util.h" | ||
26 | |||
27 | void | ||
28 | util_shorthash_from_member (const struct GNUNET_MESSENGER_Contact *member, | ||
29 | struct GNUNET_ShortHashCode* shorthash) | ||
30 | { | ||
31 | memset(shorthash, 0, sizeof(*shorthash)); | ||
32 | GNUNET_memcpy(shorthash, &member, sizeof(member)); | ||
33 | } | ||
34 | |||
35 | void | ||
36 | util_set_name_field (const char *name, char** field) | ||
37 | { | ||
38 | if (*field) | ||
39 | GNUNET_free(*field); | ||
40 | |||
41 | if (name) | ||
42 | *field = GNUNET_strdup(name); | ||
43 | else | ||
44 | *field = NULL; | ||
45 | } | ||
diff --git a/src/gnunet_chat_util.h b/src/gnunet_chat_util.h new file mode 100644 index 0000000..d9ff947 --- /dev/null +++ b/src/gnunet_chat_util.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /* | ||
21 | * @author Tobias Frisch | ||
22 | * @file gnunet_chat_util.h | ||
23 | */ | ||
24 | |||
25 | #ifndef GNUNET_CHAT_UTIL_H_ | ||
26 | #define GNUNET_CHAT_UTIL_H_ | ||
27 | |||
28 | #include <gnunet/platform.h> | ||
29 | #include <gnunet/gnunet_common.h> | ||
30 | #include <gnunet/gnunet_messenger_service.h> | ||
31 | #include <gnunet/gnunet_util_lib.h> | ||
32 | |||
33 | void | ||
34 | util_shorthash_from_member (const struct GNUNET_MESSENGER_Contact *member, | ||
35 | struct GNUNET_ShortHashCode* shorthash); | ||
36 | |||
37 | void | ||
38 | util_set_name_field (const char *name, char** field); | ||
39 | |||
40 | #endif /* GNUNET_CHAT_UTIL_H_ */ | ||