diff options
Diffstat (limited to 'src/gnunet_chat_handle_intern.c')
-rw-r--r-- | src/gnunet_chat_handle_intern.c | 308 |
1 files changed, 308 insertions, 0 deletions
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 | } | ||