aboutsummaryrefslogtreecommitdiff
path: root/src/conversation
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-04 18:44:53 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-04 18:44:53 +0000
commit1b2a11ec4e63a62d7d4ea519bac63929f04bb054 (patch)
treebe95486054fad7d1fd8d014fda2ca7d5142b641f /src/conversation
parent4a57008695b2840dbb18fb48031719d29d7a910c (diff)
downloadgnunet-1b2a11ec4e63a62d7d4ea519bac63929f04bb054.tar.gz
gnunet-1b2a11ec4e63a62d7d4ea519bac63929f04bb054.zip
-cloning gnunet-conversation.c
Diffstat (limited to 'src/conversation')
-rw-r--r--src/conversation/Makefile.am17
-rw-r--r--src/conversation/gnunet-conversation-new.c473
2 files changed, 487 insertions, 3 deletions
diff --git a/src/conversation/Makefile.am b/src/conversation/Makefile.am
index 30e149bf5..a348c1df8 100644
--- a/src/conversation/Makefile.am
+++ b/src/conversation/Makefile.am
@@ -58,7 +58,8 @@ libgnunetconversation_la_LDFLAGS = \
58 58
59bin_PROGRAMS = \ 59bin_PROGRAMS = \
60 gnunet-conversation-test \ 60 gnunet-conversation-test \
61 gnunet-conversation 61 gnunet-conversation \
62 gnunet-conversation-new
62 63
63libexec_PROGRAMS = \ 64libexec_PROGRAMS = \
64 gnunet-service-conversation \ 65 gnunet-service-conversation \
@@ -117,11 +118,21 @@ gnunet_service_conversation_new_LDFLAGS = \
117gnunet_conversation_SOURCES = \ 118gnunet_conversation_SOURCES = \
118 gnunet-conversation.c 119 gnunet-conversation.c
119gnunet_conversation_LDADD = \ 120gnunet_conversation_LDADD = \
120 -lgnunetutil -lgnunetconversation \ 121 libgnunetconversation.la \
122 -lgnunetutil \
121 $(INTLLIBS) 123 $(INTLLIBS)
122gnunet_conversation_LDFLAGS = \ 124gnunet_conversation_LDFLAGS = \
123 $(GNUNET_LDFLAGS) $(WINFLAGS) 125 $(GNUNET_LDFLAGS) $(WINFLAGS)
124 126
127gnunet_conversation_new_SOURCES = \
128 gnunet-conversation-new.c
129gnunet_conversation_new_LDADD = \
130 libgnunetconversation.la \
131 -lgnunetutil \
132 $(INTLLIBS)
133gnunet_conversation_new_LDFLAGS = \
134 $(GNUNET_LDFLAGS) $(WINFLAGS)
135
125gnunet_conversation_test_SOURCES = \ 136gnunet_conversation_test_SOURCES = \
126 gnunet-conversation-test.c 137 gnunet-conversation-test.c
127gnunet_conversation_test_LDADD = \ 138gnunet_conversation_test_LDADD = \
@@ -136,7 +147,7 @@ gnunet_conversation_test_LDFLAGS = \
136test_conversation_api_SOURCES = \ 147test_conversation_api_SOURCES = \
137 test_conversation_api.c 148 test_conversation_api.c
138test_conversation_api_LDADD = \ 149test_conversation_api_LDADD = \
139 $(top_builddir)/src/conversation/libgnunetconversation.la \ 150 libgnunetconversation.la \
140 -lgnunetutil 151 -lgnunetutil
141test_conversation_api_LDFLAGS = \ 152test_conversation_api_LDFLAGS = \
142 $(GNUNET_LDFLAGS) $(WINFLAGS) -export-dynamic 153 $(GNUNET_LDFLAGS) $(WINFLAGS) -export-dynamic
diff --git a/src/conversation/gnunet-conversation-new.c b/src/conversation/gnunet-conversation-new.c
new file mode 100644
index 000000000..a4088984b
--- /dev/null
+++ b/src/conversation/gnunet-conversation-new.c
@@ -0,0 +1,473 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, InGNUNET_SERVERc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file conversation/gnunet-conversation.c
22 * @brief conversation implementation
23 * @author Simon Dieterle
24 * @author Andreas Fuchs
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h"
29#include "gnunet_conversation_service.h"
30#include <fcntl.h>
31
32#define MAX_MESSAGE_LENGTH (32 * 1024)
33
34/**
35 * CONVERSATION handle
36 */
37static struct GNUNET_CONVERSATION_Handle *conversation;
38
39/**
40 * Task which handles the commands
41 */
42static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task;
43
44/**
45 * Function declareation for executing a action
46 */
47typedef int (*ActionFunction) (const char *argumetns,
48 const void *xtra);
49
50/**
51* Structure which defines a command
52*/
53struct VoipCommand
54{
55 const char *command;
56 ActionFunction Action;
57 const char *helptext;
58};
59
60
61static int
62do_help (const char *args,
63 const void *xtra);
64
65
66/**
67 * Method called whenever a call is incoming
68 *
69 * @param cls closure
70 * @param handle to the conversation session
71 * @param caller peer that calls you
72 */
73static void
74call_handler (void *cls,
75 struct GNUNET_CONVERSATION_Handle *handle,
76 const struct GNUNET_PeerIdentity *caller)
77{
78 FPRINTF (stdout,
79 _("Incoming call from peer: %s\n"),
80 GNUNET_i2s_full (caller));
81}
82
83
84/**
85 * Method called whenever a call is rejected
86 *
87 * @param cls closure
88 * @param handle to the conversation session
89 * @param reason given reason why the call was rejected
90 * @param peer peer that rejected your call
91 */
92static void
93reject_handler (void *cls,
94 struct GNUNET_CONVERSATION_Handle *handle,
95 enum GNUNET_CONVERSATION_RejectReason reason,
96 const struct GNUNET_PeerIdentity *peer)
97{
98 FPRINTF (stdout,
99 _("Peer %s rejected your call. Reason: %d\n"),
100 GNUNET_i2s_full (peer), reason);
101}
102
103
104/**
105 * Method called whenever a notification is there
106 *
107 * @param cls closure
108 * @param handle to the conversation session
109 * @param type the type of the notification
110 * @param peer peer that the notification is about
111 */
112static void
113notification_handler (void *cls,
114 struct GNUNET_CONVERSATION_Handle *handle,
115 enum GNUNET_CONVERSATION_NotificationType type,
116 const struct GNUNET_PeerIdentity *peer)
117{
118 switch (type)
119 {
120 case GNUNET_CONVERSATION_NT_SERVICE_BLOCKED:
121 FPRINTF (stdout,
122 _("The service is already in use. Try again later."));
123 break;
124 case GNUNET_CONVERSATION_NT_NO_PEER:
125 FPRINTF (stdout,
126 _("The Peer you were calling is no correct peer.\n"));
127 break;
128 case GNUNET_CONVERSATION_NT_NO_ANSWER:
129 FPRINTF (stdout,
130 _("Peer %s did not answer your call.\n"),
131 GNUNET_i2s_full (peer));
132 break;
133 case GNUNET_CONVERSATION_NT_AVAILABLE_AGAIN:
134 FPRINTF (stdout,
135 _("Peer %s is now available.\n"),
136 GNUNET_i2s_full (peer));
137 break;
138 case GNUNET_CONVERSATION_NT_CALL_ACCEPTED:
139 FPRINTF (stdout,
140 _("Peer %s has accepted your call.\n"),
141 GNUNET_i2s_full (peer));
142 break;
143 case GNUNET_CONVERSATION_NT_CALL_TERMINATED:
144 FPRINTF (stdout,
145 _("Peer %s has terminated the call.\n"),
146 GNUNET_i2s_full (peer));
147 break;
148 default:
149 GNUNET_break (0);
150 }
151}
152
153
154/**
155 * Method called whenever a notification for missed calls is there
156 *
157 * @param cls closure
158 * @param handle to the conversation session
159 * @param missed_calls a list of missed calls
160 */
161static void
162missed_call_handler (void *cls,
163 struct GNUNET_CONVERSATION_Handle *handle,
164 struct GNUNET_CONVERSATION_MissedCallNotification *missed_calls)
165{
166 FPRINTF (stdout,
167 _("You have missed calls.\n"));
168}
169
170
171/**
172 * Terminating the client
173 */
174static int
175do_quit (const char *args,
176 const void *xtra)
177{
178 return GNUNET_SYSERR;
179}
180
181
182/**
183 *
184 */
185static int
186do_unknown (const char *msg,
187 const void *xtra)
188{
189 FPRINTF (stderr,
190 _("Unknown command `%s'\n"),
191 msg);
192 return GNUNET_OK;
193}
194
195
196/**
197 * Initiating a new call
198 */
199static int
200do_call (const char *arg,
201 const void *xtra)
202{
203 FPRINTF (stdout,
204 _("Initiating call to: %s\n"),
205 arg);
206 GNUNET_CONVERSATION_call (conversation,
207 arg,
208 GNUNET_YES);
209 return GNUNET_OK;
210}
211
212
213/**
214 * Initiating a new call
215 */
216static int
217do_call_peer (const char *arg,
218 const void *xtra)
219{
220 FPRINTF (stdout,
221 _("Initiating call to: %s\n"),
222 arg);
223 GNUNET_CONVERSATION_call (conversation,
224 arg,
225 GNUNET_NO);
226 return GNUNET_OK;
227}
228
229
230/**
231 * Accepting an incoming call
232 */
233static int
234do_accept (const char *args,
235 const void *xtra)
236{
237 FPRINTF (stdout,
238 _("Accepting the call\n"));
239 GNUNET_CONVERSATION_accept (conversation);
240
241 return GNUNET_OK;
242}
243
244
245/**
246 * Rejecting a call
247 */
248static int
249do_reject (const char *args,
250 const void *xtra)
251{
252 FPRINTF (stdout,
253 _("Rejecting the call\n"));
254 GNUNET_CONVERSATION_reject (conversation);
255 return GNUNET_OK;
256}
257
258
259/**
260 * Terminating a call
261 */
262static int
263do_hang_up (const char *args,
264 const void *xtra)
265{
266 FPRINTF (stdout,
267 _("Terminating the call\n"));
268 GNUNET_CONVERSATION_hangup (conversation);
269 return GNUNET_OK;
270}
271
272
273/**
274 * List of supported commands.
275 */
276static struct VoipCommand commands[] = {
277 {"/call ", &do_call, gettext_noop ("Use `/call gns_name'")},
278 {"/callpeer ", &do_call_peer,
279 gettext_noop ("Use `/call private_key' to call a person")},
280 {"/accept", &do_accept,
281 gettext_noop ("Use `/accept' to accept an incoming call")},
282 {"/terminate", &do_hang_up,
283 gettext_noop ("Use `/terminate' to end a call")},
284 {"/reject", &do_reject,
285 gettext_noop ("Use `/rejet' to reject an incoming call")},
286 {"/quit", &do_quit, gettext_noop ("Use `/quit' to terminate gnunet-conversation")},
287 {"/help", &do_help,
288 gettext_noop ("Use `/help command' to get help for a specific command")},
289 {"/", &do_unknown, NULL},
290 {"", &do_unknown, NULL},
291 {NULL, NULL, NULL},
292};
293
294
295/**
296 *
297 */
298static int
299do_help (const char *args,
300 const void *xtra)
301{
302 int i;
303
304 i = 0;
305 while ((NULL != args) && (0 != strlen (args)) &&
306 (commands[i].Action != &do_help))
307 {
308 if (0 ==
309 strncasecmp (&args[1], &commands[i].command[1], strlen (args) - 1))
310 {
311 FPRINTF (stdout,
312 "%s\n",
313 gettext (commands[i].helptext));
314 return GNUNET_OK;
315 }
316 i++;
317 }
318 i = 0;
319 FPRINTF (stdout,
320 "%s",
321 "Available commands:");
322 while (commands[i].Action != &do_help)
323 {
324 FPRINTF (stdout,
325 " %s",
326 gettext (commands[i].command));
327 i++;
328 }
329 FPRINTF (stdout,
330 "%s",
331 "\n");
332 FPRINTF (stdout,
333 "%s\n",
334 gettext (commands[i].helptext));
335 return GNUNET_OK;
336}
337
338
339/**
340 *
341 */
342static void
343do_stop_task (void *cls,
344 const struct GNUNET_SCHEDULER_TaskContext *tc)
345{
346 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
347 "Running shutdown task\n");
348 GNUNET_CONVERSATION_disconnect (conversation);
349
350 if (handle_cmd_task != GNUNET_SCHEDULER_NO_TASK)
351 {
352 GNUNET_SCHEDULER_cancel (handle_cmd_task);
353 handle_cmd_task = GNUNET_SCHEDULER_NO_TASK;
354 }
355 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
356 "Running shutdown task finished\n");
357}
358
359
360/**
361 *
362 */
363static void
364handle_command (void *cls,
365 const struct GNUNET_SCHEDULER_TaskContext *tc)
366{
367 char message[MAX_MESSAGE_LENGTH + 1];
368 int i;
369
370 /* read message from command line and handle it */
371 memset (message, 0, MAX_MESSAGE_LENGTH + 1);
372 if (NULL == fgets (message, MAX_MESSAGE_LENGTH, stdin))
373 goto next;
374 if (strlen (message) == 0)
375 goto next;
376 if (message[strlen (message) - 1] == '\n')
377 message[strlen (message) - 1] = '\0';
378 if (strlen (message) == 0)
379 goto next;
380 i = 0;
381 while ((NULL != commands[i].command) &&
382 (0 !=
383 strncasecmp (commands[i].command, message,
384 strlen (commands[i].command))))
385 i++;
386 if (GNUNET_OK !=
387 commands[i].Action (&message[strlen (commands[i].command)], NULL))
388 goto out;
389
390next:
391 handle_cmd_task =
392 GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_multiply
393 (GNUNET_TIME_UNIT_MILLISECONDS,
394 100),
395 GNUNET_SCHEDULER_PRIORITY_UI,
396 &handle_command, NULL);
397 return;
398
399out:
400 handle_cmd_task = GNUNET_SCHEDULER_NO_TASK;
401 GNUNET_SCHEDULER_shutdown ();
402}
403
404
405/**
406 * Main function that will be run by the scheduler.
407 *
408 * @param cls closure
409 * @param args remaining command-line arguments
410 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
411 * @param c configuration
412 */
413static void
414run (void *cls,
415 char *const *args,
416 const char *cfgfile,
417 const struct GNUNET_CONFIGURATION_Handle *c)
418{
419 if (NULL ==
420 (conversation =
421 GNUNET_CONVERSATION_connect (c, NULL,
422 &call_handler,
423 &reject_handler,
424 &notification_handler,
425 &missed_call_handler)))
426 {
427 FPRINTF (stderr,
428 "%s",
429 _("Could not access CONVERSATION service. Exiting.\n"));
430 return;
431 }
432
433 handle_cmd_task =
434 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI,
435 &handle_command, NULL);
436 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task,
437 NULL);
438}
439
440
441/**
442 * The main function to conversation.
443 *
444 * @param argc number of arguments from the command line
445 * @param argv command line arguments
446 * @return 0 ok, 1 on error
447 */
448int
449main (int argc, char *const *argv)
450{
451 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
452 GNUNET_GETOPT_OPTION_END
453 };
454
455 int flags;
456 int ret;
457
458 flags = fcntl (0, F_GETFL, 0);
459 flags |= O_NONBLOCK;
460 fcntl (0, F_SETFL, flags);
461
462 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
463 return 2;
464
465 ret = GNUNET_PROGRAM_run (argc, argv, "gnunet-conversation",
466 gettext_noop ("Print information about conversation."),
467 options, &run, NULL);
468 GNUNET_free ((void *) argv);
469
470 return ret;
471}
472
473/* end of gnunet-conversation.c */