2 This file is part of GNUnet.
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.
22 * @file conversation/gnunet-conversation.c
23 * @brief conversation implementation
24 * @author Simon Dieterle
25 * @author Andreas Fuchs
27 #include <gnunet/platform.h>
28 #include <gnunet/gnunet_constants.h>
29 #include <gnunet/gnunet_util_lib.h>
30 #include "gnunet_conversation_service.h"
33 #define MAX_MESSAGE_LENGTH (32 * 1024)
38 struct GNUNET_CONVERSATION_Handle *conversation = NULL;
41 * Task which handles the commands
43 static GNUNET_SCHEDULER_TaskIdentifier handle_cmd_task;
46 * Function declareation for executing a action
48 typedef int (*ActionFunction) (const char *argumetns, const void *xtra);
51 * Structure which defines a command
56 ActionFunction Action;
60 /******************************************************************************/
61 /*********************** DECLARATIONS *************************/
62 /******************************************************************************/
64 static int do_help (const char *args, const void *xtra);
66 /******************************************************************************/
67 /*********************** Functions *************************/
68 /******************************************************************************/
72 * Method called whenever a call is incoming
75 * @param handle to the conversation session
76 * @param caller peer that calls you
79 call_handler (void *cls, struct GNUNET_CONVERSATION_Handle *handle,
80 const struct GNUNET_PeerIdentity *caller)
82 FPRINTF (stdout, _("Incoming call from peer: %s\n"),
83 GNUNET_i2s_full (caller));
87 * Method called whenever a call is rejected
90 * @param handle to the conversation session
91 * @param peer peer that rejected your call
94 reject_handler (void *cls, struct GNUNET_CONVERSATION_Handle *handle, int reason,
95 const struct GNUNET_PeerIdentity *peer)
97 FPRINTF (stdout, _("Peer %s rejected your call. Reason: %d\n"),
98 GNUNET_i2s_full (peer), reason);
102 * Method called whenever a notification is there
105 * @param handle to the conversation session
106 * @param type the type of the notification
107 * @param peer peer that the notification is about
110 notification_handler (void *cls, struct GNUNET_CONVERSATION_Handle *handle, int type,
111 const struct GNUNET_PeerIdentity *peer)
115 case GNUNET_CONVERSATION_NT_SERVICE_BLOCKED:
116 FPRINTF (stdout, _("The service is already in use. Try again later."));
120 case GNUNET_CONVERSATION_NT_NO_PEER:
121 FPRINTF (stdout, _("The Peer you were calling is no correct peer.\n"));
125 case GNUNET_CONVERSATION_NT_NO_ANSWER:
126 FPRINTF (stdout, _("Peer %s did not answer your call.\n"),
127 GNUNET_i2s_full (peer));
131 case GNUNET_CONVERSATION_NT_AVAILABLE_AGAIN:
132 FPRINTF (stdout, _("Peer %s is now available.\n"),
133 GNUNET_i2s_full (peer));
137 case GNUNET_CONVERSATION_NT_CALL_ACCEPTED:
138 FPRINTF (stdout, _("Peer %s has accepted your call.\n"),
139 GNUNET_i2s_full (peer));
143 case GNUNET_CONVERSATION_NT_CALL_TERMINATED:
144 FPRINTF (stdout, _("Peer %s has terminated the call.\n"),
145 GNUNET_i2s_full (peer));
152 * Method called whenever a notification for missed calls is there
155 * @param handle to the conversation session
156 * @param missed_calls a list of missed calls
159 missed_call_handler (void *cls, struct GNUNET_CONVERSATION_Handle *handle,
160 struct GNUNET_CONVERSATION_MissedCallNotification *missed_calls)
162 FPRINTF (stdout, _("You have missed calls.\n"));
166 * Terminating the client
169 do_quit (const char *args, const void *xtra)
171 return GNUNET_SYSERR;
178 do_unknown (const char *msg, const void *xtra)
180 FPRINTF (stderr, _("Unknown command `%s'\n"), msg);
185 * Initiating a new call
188 do_call (const char *arg, const void *xtra)
190 char *callee = GNUNET_strdup (arg);
191 FPRINTF (stdout, _("Initiating call to: %s\n"), callee);
192 GNUNET_CONVERSATION_call (conversation, callee, GNUNET_YES);
198 * Initiating a new call
201 do_call_peer (const char *arg, const void *xtra)
203 char *callee = GNUNET_strdup (arg);
204 FPRINTF (stdout, _("Initiating call to: %s\n"), callee);
205 GNUNET_CONVERSATION_call (conversation, callee, GNUNET_NO);
211 * Accepting an incoming call
214 do_accept (const char *args, const void *xtra)
216 FPRINTF (stdout, _("Accepting the call\n"));
217 GNUNET_CONVERSATION_accept (conversation);
226 do_reject (const char *args, const void *xtra)
228 FPRINTF (stdout, _("Rejecting the call\n"));
229 GNUNET_CONVERSATION_reject (conversation);
238 do_hang_up (const char *args, const void *xtra)
240 FPRINTF (stdout, _("Terminating the call\n"));
241 GNUNET_CONVERSATION_hangup (conversation);
247 * List of supported commands.
249 static struct VoipCommand commands[] = {
250 {"/call ", &do_call, gettext_noop ("Use `/call gads_record'")},
251 {"/callpeer ", &do_call_peer,
252 gettext_noop ("Use `/call private_key' to call a person")},
253 {"/accept", &do_accept,
254 gettext_noop ("Use `/accept' to accept an incoming call")},
255 {"/terminate", &do_hang_up,
256 gettext_noop ("Use `/terminate' to end a call")},
257 {"/reject", &do_reject,
258 gettext_noop ("Use `/rejet' to reject an incoming call")},
259 {"/quit", &do_quit, gettext_noop ("Use `/quit' to terminate gnunet-conversation")},
261 gettext_noop ("Use `/help command' to get help for a specific command")},
262 {"/", &do_unknown, NULL},
263 {"", &do_unknown, NULL},
271 do_help (const char *args, const void *xtra)
276 while ((NULL != args) && (0 != strlen (args)) &&
277 (commands[i].Action != &do_help))
280 strncasecmp (&args[1], &commands[i].command[1], strlen (args) - 1))
282 FPRINTF (stdout, "%s\n", gettext (commands[i].helptext));
288 FPRINTF (stdout, "%s", "Available commands:");
289 while (commands[i].Action != &do_help)
291 FPRINTF (stdout, " %s", gettext (commands[i].command));
294 FPRINTF (stdout, "%s", "\n");
295 FPRINTF (stdout, "%s\n", gettext (commands[i].helptext));
303 do_stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
305 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running shutdown task\n");
306 GNUNET_CONVERSATION_disconnect (conversation);
308 if (handle_cmd_task != GNUNET_SCHEDULER_NO_TASK)
310 GNUNET_SCHEDULER_cancel (handle_cmd_task);
311 handle_cmd_task = GNUNET_SCHEDULER_NO_TASK;
314 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running shutdown task finished\n");
321 handle_command (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
323 char message[MAX_MESSAGE_LENGTH + 1];
326 /* read message from command line and handle it */
327 memset (message, 0, MAX_MESSAGE_LENGTH + 1);
328 if (NULL == fgets (message, MAX_MESSAGE_LENGTH, stdin))
330 if (strlen (message) == 0)
332 if (message[strlen (message) - 1] == '\n')
333 message[strlen (message) - 1] = '\0';
334 if (strlen (message) == 0)
337 while ((NULL != commands[i].command) &&
339 strncasecmp (commands[i].command, message,
340 strlen (commands[i].command))))
343 commands[i].Action (&message[strlen (commands[i].command)], NULL))
348 GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_multiply
349 (GNUNET_TIME_UNIT_MILLISECONDS,
351 GNUNET_SCHEDULER_PRIORITY_UI,
352 &handle_command, NULL);
356 handle_cmd_task = GNUNET_SCHEDULER_NO_TASK;
357 GNUNET_SCHEDULER_shutdown ();
361 * Main function that will be run by the scheduler.
364 * @param args remaining command-line arguments
365 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
366 * @param c configuration
369 run (void *cls, char *const *args, const char *cfgfile,
370 const struct GNUNET_CONFIGURATION_Handle *c)
374 GNUNET_CONVERSATION_connect (c, NULL, &call_handler, &reject_handler,
375 ¬ification_handler, &missed_call_handler)))
377 FPRINTF (stderr, "%s", _("Could not access CONVERSATION service. Exiting.\n"));
382 GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI,
383 &handle_command, NULL);
384 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task,
388 /** * The main function to conversation.
390 * @param argc number of arguments from the command line
391 * @param argv command line arguments
392 * @return 0 ok, 1 on error
395 main (int argc, char *const *argv)
397 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
398 GNUNET_GETOPT_OPTION_END
404 flags = fcntl (0, F_GETFL, 0);
406 fcntl (0, F_SETFL, flags);
408 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
411 ret = GNUNET_PROGRAM_run (argc, argv, "gnunet-conversation",
412 gettext_noop ("Print information about conversation."),
413 options, &run, NULL);
414 GNUNET_free ((void *) argv);
419 /* end of gnunet-conversation.c */