2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
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.
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.
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.
21 * @file conversation/gnunet-conversation.c
22 * @brief conversation implementation
23 * @author Simon Dieterle
24 * @author Andreas Fuchs
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_conversation_service.h"
32 #define MAX_MESSAGE_LENGTH (32 * 1024)
37 static struct GNUNET_CONVERSATION_Handle *conversation;
40 * Task which handles the commands
42 static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task;
45 * Function declareation for executing a action
47 typedef int (*ActionFunction) (const char *argumetns,
51 * Structure which defines a command
56 ActionFunction Action;
62 do_help (const char *args,
67 * Method called whenever a call is incoming
70 * @param handle to the conversation session
71 * @param caller peer that calls you
74 call_handler (void *cls,
75 struct GNUNET_CONVERSATION_Handle *handle,
76 const struct GNUNET_PeerIdentity *caller)
79 _("Incoming call from peer: %s\n"),
80 GNUNET_i2s_full (caller));
85 * Method called whenever a call is rejected
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
93 reject_handler (void *cls,
94 struct GNUNET_CONVERSATION_Handle *handle,
95 enum GNUNET_CONVERSATION_RejectReason reason,
96 const struct GNUNET_PeerIdentity *peer)
99 _("Peer %s rejected your call. Reason: %d\n"),
100 GNUNET_i2s_full (peer), reason);
105 * Method called whenever a notification is there
108 * @param handle to the conversation session
109 * @param type the type of the notification
110 * @param peer peer that the notification is about
113 notification_handler (void *cls,
114 struct GNUNET_CONVERSATION_Handle *handle,
115 enum GNUNET_CONVERSATION_NotificationType type,
116 const struct GNUNET_PeerIdentity *peer)
120 case GNUNET_CONVERSATION_NT_SERVICE_BLOCKED:
122 _("The service is already in use. Try again later."));
124 case GNUNET_CONVERSATION_NT_NO_PEER:
126 _("The Peer you were calling is no correct peer.\n"));
128 case GNUNET_CONVERSATION_NT_NO_ANSWER:
130 _("Peer %s did not answer your call.\n"),
131 GNUNET_i2s_full (peer));
133 case GNUNET_CONVERSATION_NT_AVAILABLE_AGAIN:
135 _("Peer %s is now available.\n"),
136 GNUNET_i2s_full (peer));
138 case GNUNET_CONVERSATION_NT_CALL_ACCEPTED:
140 _("Peer %s has accepted your call.\n"),
141 GNUNET_i2s_full (peer));
143 case GNUNET_CONVERSATION_NT_CALL_TERMINATED:
145 _("Peer %s has terminated the call.\n"),
146 GNUNET_i2s_full (peer));
155 * Method called whenever a notification for missed calls is there
158 * @param handle to the conversation session
159 * @param missed_calls a list of missed calls
162 missed_call_handler (void *cls,
163 struct GNUNET_CONVERSATION_Handle *handle,
164 struct GNUNET_CONVERSATION_MissedCallNotification *missed_calls)
167 _("You have missed calls.\n"));
172 * Terminating the client
175 do_quit (const char *args,
178 return GNUNET_SYSERR;
186 do_unknown (const char *msg,
190 _("Unknown command `%s'\n"),
197 * Initiating a new call
200 do_call (const char *arg,
204 _("Initiating call to: %s\n"),
206 GNUNET_CONVERSATION_call (conversation,
214 * Initiating a new call
217 do_call_peer (const char *arg,
221 _("Initiating call to: %s\n"),
223 GNUNET_CONVERSATION_call (conversation,
231 * Accepting an incoming call
234 do_accept (const char *args,
238 _("Accepting the call\n"));
239 GNUNET_CONVERSATION_accept (conversation);
249 do_reject (const char *args,
253 _("Rejecting the call\n"));
254 GNUNET_CONVERSATION_reject (conversation);
263 do_hang_up (const char *args,
267 _("Terminating the call\n"));
268 GNUNET_CONVERSATION_hangup (conversation);
274 * List of supported commands.
276 static 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")},
288 gettext_noop ("Use `/help command' to get help for a specific command")},
289 {"/", &do_unknown, NULL},
290 {"", &do_unknown, NULL},
299 do_help (const char *args,
305 while ((NULL != args) && (0 != strlen (args)) &&
306 (commands[i].Action != &do_help))
309 strncasecmp (&args[1], &commands[i].command[1], strlen (args) - 1))
313 gettext (commands[i].helptext));
321 "Available commands:");
322 while (commands[i].Action != &do_help)
326 gettext (commands[i].command));
334 gettext (commands[i].helptext));
343 do_stop_task (void *cls,
344 const struct GNUNET_SCHEDULER_TaskContext *tc)
346 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
347 "Running shutdown task\n");
348 GNUNET_CONVERSATION_disconnect (conversation);
350 if (handle_cmd_task != GNUNET_SCHEDULER_NO_TASK)
352 GNUNET_SCHEDULER_cancel (handle_cmd_task);
353 handle_cmd_task = GNUNET_SCHEDULER_NO_TASK;
355 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
356 "Running shutdown task finished\n");
364 handle_command (void *cls,
365 const struct GNUNET_SCHEDULER_TaskContext *tc)
367 char message[MAX_MESSAGE_LENGTH + 1];
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))
374 if (strlen (message) == 0)
376 if (message[strlen (message) - 1] == '\n')
377 message[strlen (message) - 1] = '\0';
378 if (strlen (message) == 0)
381 while ((NULL != commands[i].command) &&
383 strncasecmp (commands[i].command, message,
384 strlen (commands[i].command))))
387 commands[i].Action (&message[strlen (commands[i].command)], NULL))
392 GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_multiply
393 (GNUNET_TIME_UNIT_MILLISECONDS,
395 GNUNET_SCHEDULER_PRIORITY_UI,
396 &handle_command, NULL);
400 handle_cmd_task = GNUNET_SCHEDULER_NO_TASK;
401 GNUNET_SCHEDULER_shutdown ();
406 * Main function that will be run by the scheduler.
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
417 const struct GNUNET_CONFIGURATION_Handle *c)
421 GNUNET_CONVERSATION_connect (c, NULL,
424 ¬ification_handler,
425 &missed_call_handler)))
429 _("Could not access CONVERSATION service. Exiting.\n"));
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,
442 * The main function to conversation.
444 * @param argc number of arguments from the command line
445 * @param argv command line arguments
446 * @return 0 ok, 1 on error
449 main (int argc, char *const *argv)
451 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
452 GNUNET_GETOPT_OPTION_END
458 flags = fcntl (0, F_GETFL, 0);
460 fcntl (0, F_SETFL, flags);
462 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
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);
473 /* end of gnunet-conversation.c */