aboutsummaryrefslogtreecommitdiff
path: root/src/conversation
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-05 12:52:48 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-05 12:52:48 +0000
commit660c1d610b9ae61814d501b73c4bb745201e023d (patch)
tree97c2f49a82a873f291e0ca1fbd6680944094571f /src/conversation
parent096f081ac0f1ae884e97bad0574b2df5b10adefa (diff)
downloadgnunet-660c1d610b9ae61814d501b73c4bb745201e023d.tar.gz
gnunet-660c1d610b9ae61814d501b73c4bb745201e023d.zip
-cleaning up command-line tool
Diffstat (limited to 'src/conversation')
-rw-r--r--src/conversation/gnunet-conversation-new.c334
1 files changed, 291 insertions, 43 deletions
diff --git a/src/conversation/gnunet-conversation-new.c b/src/conversation/gnunet-conversation-new.c
index 57315ac0d..4be8f11aa 100644
--- a/src/conversation/gnunet-conversation-new.c
+++ b/src/conversation/gnunet-conversation-new.c
@@ -27,9 +27,61 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h" 28#include "gnunet_constants.h"
29#include "gnunet_conversation_service.h" 29#include "gnunet_conversation_service.h"
30#include <fcntl.h>
31 30
32#define MAX_MESSAGE_LENGTH (32 * 1024) 31
32/**
33 * Maximum length allowed for the command line input.
34 */
35#define MAX_MESSAGE_LENGTH 1024
36
37
38/**
39 * Possible states of the program.
40 */
41enum ConversationState
42{
43 /**
44 * We're waiting for our own idenitty.
45 */
46 CS_LOOKUP_EGO,
47
48 /**
49 * We're listening for calls
50 */
51 CS_LISTEN,
52
53 /**
54 * Our phone is ringing.
55 */
56 CS_RING,
57
58 /**
59 * We accepted an incoming phone call.
60 */
61 CS_ACCEPTED,
62
63 /**
64 * We are looking up some other participant.
65 */
66 CS_RESOLVING,
67
68 /**
69 * We are now ringing the other participant.
70 */
71 CS_RINGING,
72
73 /**
74 * The other party accepted our call and we are now connected.
75 */
76 CS_CONNECTED,
77
78 /**
79 * Internal error
80 */
81 CS_ERROR
82
83};
84
33 85
34/** 86/**
35 * Phone handle 87 * Phone handle
@@ -82,10 +134,25 @@ static struct GNUNET_IDENTITY_Handle *id;
82static char *ego_name; 134static char *ego_name;
83 135
84/** 136/**
137 * Name of conversation partner (if any).
138 */
139static char *peer_name;
140
141/**
85 * File handle for stdin. 142 * File handle for stdin.
86 */ 143 */
87static struct GNUNET_DISK_FileHandle *stdin_fh; 144static struct GNUNET_DISK_FileHandle *stdin_fh;
88 145
146/**
147 * Our current state.
148 */
149static enum ConversationState state;
150
151/**
152 * Be verbose.
153 */
154static int verbose;
155
89 156
90/** 157/**
91 * Function called with an event emitted by a phone. 158 * Function called with an event emitted by a phone.
@@ -105,9 +172,13 @@ phone_event_handler (void *cls,
105 switch (code) 172 switch (code)
106 { 173 {
107 case GNUNET_CONVERSATION_EC_RING: 174 case GNUNET_CONVERSATION_EC_RING:
175 GNUNET_break (CS_LISTEN == state);
176 GNUNET_free_non_null (peer_name);
177 peer_name = GNUNET_strdup (va_arg (va, const char *));
108 FPRINTF (stdout, 178 FPRINTF (stdout,
109 _("Incoming call from `%s'. Enter /accept to take it.\n"), 179 _("Incoming call from `%s'.\nPlease /accept or /cancel the call.\n"),
110 va_arg (va, const char *)); 180 peer_name);
181 state = CS_RING;
111 break; 182 break;
112 case GNUNET_CONVERSATION_EC_RINGING: 183 case GNUNET_CONVERSATION_EC_RINGING:
113 GNUNET_break (0); 184 GNUNET_break (0);
@@ -122,9 +193,12 @@ phone_event_handler (void *cls,
122 GNUNET_break (0); 193 GNUNET_break (0);
123 break; 194 break;
124 case GNUNET_CONVERSATION_EC_TERMINATED: 195 case GNUNET_CONVERSATION_EC_TERMINATED:
196 GNUNET_break ( (CS_RING == state) ||
197 (CS_ACCEPTED == state) );
125 FPRINTF (stdout, 198 FPRINTF (stdout,
126 _("Call terminated: %s\n"), 199 _("Call terminated: %s\n"),
127 va_arg (va, const char *)); 200 va_arg (va, const char *));
201 state = CS_LISTEN;
128 break; 202 break;
129 } 203 }
130 va_end (va); 204 va_end (va);
@@ -132,6 +206,42 @@ phone_event_handler (void *cls,
132 206
133 207
134/** 208/**
209 * Start our phone.
210 */
211static void
212start_phone ()
213{
214 if (NULL == caller_id)
215 {
216 FPRINTF (stderr,
217 _("Ego `%s' no longer available, phone is now down.\n"),
218 ego_name);
219 state = CS_LOOKUP_EGO;
220 return;
221 }
222 phone = GNUNET_CONVERSATION_phone_create (cfg,
223 caller_id,
224 &phone_event_handler, NULL);
225 /* FIXME: get record and print full GNS record info later here... */
226 if (NULL == phone)
227 {
228 FPRINTF (stderr,
229 "%s",
230 _("Failed to setup phone (internal error)\n"));
231 state = CS_ERROR;
232 }
233 else
234 {
235 if (verbose)
236 FPRINTF (stdout,
237 _("Phone active on line %u\n"),
238 (unsigned int) line);
239 state = CS_LISTEN;
240 }
241}
242
243
244/**
135 * Function called with an event emitted by a phone. 245 * Function called with an event emitted by a phone.
136 * 246 *
137 * @param cls closure 247 * @param cls closure
@@ -152,41 +262,47 @@ call_event_handler (void *cls,
152 GNUNET_break (0); 262 GNUNET_break (0);
153 break; 263 break;
154 case GNUNET_CONVERSATION_EC_RINGING: 264 case GNUNET_CONVERSATION_EC_RINGING:
155 FPRINTF (stdout, 265 GNUNET_break (CS_RESOLVING == state);
156 "%s", 266 if (verbose)
157 _("Ringing other party\n")); 267 FPRINTF (stdout,
268 "%s",
269 _("Resolved address. Now ringing other party.\n"));
270 state = CS_RINGING;
158 break; 271 break;
159 case GNUNET_CONVERSATION_EC_READY: 272 case GNUNET_CONVERSATION_EC_READY:
273 GNUNET_break (CS_RINGING == state);
160 FPRINTF (stdout, 274 FPRINTF (stdout,
161 _("Connection established: %s\n"), 275 _("Connection established: %s\n"),
162 va_arg (va, const char *)); 276 va_arg (va, const char *));
277 state = CS_CONNECTED;
163 break; 278 break;
164 case GNUNET_CONVERSATION_EC_GNS_FAIL: 279 case GNUNET_CONVERSATION_EC_GNS_FAIL:
280 GNUNET_break (CS_RESOLVING == state);
165 FPRINTF (stdout, 281 FPRINTF (stdout,
166 "%s", 282 "%s",
167 _("Failed to resolve name\n")); 283 _("Failed to resolve name\n"));
284 GNUNET_CONVERSATION_call_stop (call, NULL);
285 call = NULL;
286 start_phone ();
168 break; 287 break;
169 case GNUNET_CONVERSATION_EC_BUSY: 288 case GNUNET_CONVERSATION_EC_BUSY:
289 GNUNET_break (CS_RINGING == state);
170 FPRINTF (stdout, 290 FPRINTF (stdout,
171 "%s", 291 "%s",
172 _("Line busy\n")); 292 _("Line busy\n"));
293 GNUNET_CONVERSATION_call_stop (call, NULL);
294 call = NULL;
295 start_phone ();
173 break; 296 break;
174 case GNUNET_CONVERSATION_EC_TERMINATED: 297 case GNUNET_CONVERSATION_EC_TERMINATED:
298 GNUNET_break ( (CS_RINGING == state) ||
299 (CS_CONNECTED == state) );
175 FPRINTF (stdout, 300 FPRINTF (stdout,
176 _("Call terminated: %s\n"), 301 _("Call terminated: %s\n"),
177 va_arg (va, const char *)); 302 va_arg (va, const char *));
178 GNUNET_CONVERSATION_call_stop (call, NULL); 303 GNUNET_CONVERSATION_call_stop (call, NULL);
179 call = NULL; 304 call = NULL;
180 if (NULL == caller_id) 305 start_phone ();
181 {
182 FPRINTF (stderr,
183 _("Ego `%s' no longer available, phone is now down.\n"),
184 ego_name);
185 return;
186 }
187 phone = GNUNET_CONVERSATION_phone_create (cfg,
188 caller_id,
189 &phone_event_handler, NULL);
190 break; 306 break;
191 } 307 }
192 va_end (va); 308 va_end (va);
@@ -266,8 +382,6 @@ do_unknown (const char *msg)
266static void 382static void
267do_call (const char *arg) 383do_call (const char *arg)
268{ 384{
269 if (NULL != call)
270 return;
271 if (NULL == caller_id) 385 if (NULL == caller_id)
272 { 386 {
273 FPRINTF (stderr, 387 FPRINTF (stderr,
@@ -275,18 +389,62 @@ do_call (const char *arg)
275 ego_name); 389 ego_name);
276 return; 390 return;
277 } 391 }
278 /* FIXME: also check that we do NOT have a running conversation or ring */ 392 switch (state)
393 {
394 case CS_LOOKUP_EGO:
395 FPRINTF (stderr,
396 _("Ego `%s' not available\n"),
397 ego_name);
398 return;
399 case CS_LISTEN:
400 /* ok to call! */
401 break;
402 case CS_RING:
403 FPRINTF (stdout,
404 _("Hanging up on incoming phone call from `%s' to call `%s'.\n"),
405 peer_name,
406 arg);
407 GNUNET_CONVERSATION_phone_hang_up (phone, NULL);
408 break;
409 case CS_ACCEPTED:
410 FPRINTF (stderr,
411 _("You are already in a conversation with `%s', refusing to call `%s'.\n"),
412 peer_name,
413 arg);
414 return;
415 case CS_RESOLVING:
416 case CS_RINGING:
417 FPRINTF (stderr,
418 _("Aborting call to `%s'\n"),
419 peer_name);
420 GNUNET_CONVERSATION_call_stop (call, NULL);
421 call = NULL;
422 break;
423 case CS_CONNECTED:
424 FPRINTF (stderr,
425 _("You are already in a conversation with `%s', refusing to call `%s'.\n"),
426 peer_name,
427 arg);
428 return;
429 case CS_ERROR:
430 /* ok to call */
431 break;
432 }
433 GNUNET_assert (NULL == call);
279 if (NULL != phone) 434 if (NULL != phone)
280 { 435 {
281 GNUNET_CONVERSATION_phone_destroy (phone); 436 GNUNET_CONVERSATION_phone_destroy (phone);
282 phone = NULL; 437 phone = NULL;
283 } 438 }
439 GNUNET_free_non_null (peer_name);
440 peer_name = GNUNET_strdup (arg);
284 call = GNUNET_CONVERSATION_call_start (cfg, 441 call = GNUNET_CONVERSATION_call_start (cfg,
285 caller_id, 442 caller_id,
286 arg, 443 arg,
287 speaker, 444 speaker,
288 mic, 445 mic,
289 &call_event_handler, NULL); 446 &call_event_handler, NULL);
447 state = CS_RESOLVING;
290} 448}
291 449
292 450
@@ -298,13 +456,90 @@ do_call (const char *arg)
298static void 456static void
299do_accept (const char *args) 457do_accept (const char *args)
300{ 458{
301 if (NULL == phone) 459 switch (state)
460 {
461 case CS_LOOKUP_EGO:
462 case CS_LISTEN:
463 case CS_ERROR:
464 FPRINTF (stderr,
465 _("There is no incoming call to be accepted!\n"));
466 return;
467 case CS_RING:
468 /* this is the expected state */
469 break;
470 case CS_ACCEPTED:
471 FPRINTF (stderr,
472 _("You are already in a conversation with `%s'.\n"),
473 peer_name);
474 return;
475 case CS_RESOLVING:
476 case CS_RINGING:
477 FPRINTF (stderr,
478 _("You are trying to call `%s', cannot accept incoming calls right now.\n"),
479 peer_name);
302 return; 480 return;
303 /* FIXME: also check that we don't have a running conversation */ 481 case CS_CONNECTED:
482 FPRINTF (stderr,
483 _("You are already in a conversation with `%s'.\n"),
484 peer_name);
485 return;
486 }
487 GNUNET_assert (NULL != phone);
304 GNUNET_CONVERSATION_phone_pick_up (phone, 488 GNUNET_CONVERSATION_phone_pick_up (phone,
305 args, 489 args,
306 speaker, 490 speaker,
307 mic); 491 mic);
492 state = CS_ACCEPTED;
493}
494
495
496/**
497 * Accepting an incoming call
498 *
499 * @param args arguments given to the command
500 */
501static void
502do_status (const char *args)
503{
504 switch (state)
505 {
506 case CS_LOOKUP_EGO:
507 FPRINTF (stdout,
508 _("We are currently trying to locate the private key for the ego `%s'.\n"),
509 ego_name);
510 break;
511 case CS_LISTEN:
512 FPRINTF (stdout,
513 _("We are listening for incoming calls for ego `%s' on line %u.\n"),
514 ego_name,
515 line);
516 break;
517 case CS_RING:
518 FPRINTF (stdout,
519 _("The phone is rining. `%s' is trying to call us.\n"),
520 peer_name);
521 break;
522 case CS_ACCEPTED:
523 case CS_CONNECTED:
524 FPRINTF (stdout,
525 _("You are having a conversation with `%s'.\n"),
526 peer_name);
527 break;
528 case CS_RESOLVING:
529 FPRINTF (stdout,
530 _("We are trying to find the network address to call `%s'.\n"),
531 peer_name);
532 break;
533 case CS_RINGING:
534 FPRINTF (stdout,
535 _("We are calling `%s', his phone should be ringing.\n"),
536 peer_name);
537 break;
538 case CS_ERROR:
539 FPRINTF (stdout,
540 _("We had an internal error setting up our phone line. You can still make calls.\n"));
541 break;
542 }
308} 543}
309 544
310 545
@@ -316,19 +551,35 @@ do_accept (const char *args)
316static void 551static void
317do_reject (const char *args) 552do_reject (const char *args)
318{ 553{
319 /* FIXME: also check that we do have a running conversation or ring */ 554 switch (state)
555 {
556 case CS_LOOKUP_EGO:
557 case CS_LISTEN:
558 case CS_ERROR:
559 FPRINTF (stderr,
560 "%s",
561 _("There is no call that could be cancelled right now.\n"));
562 return;
563 case CS_RING:
564 case CS_ACCEPTED:
565 case CS_RESOLVING:
566 case CS_RINGING:
567 case CS_CONNECTED:
568 /* expected state, do rejection logic */
569 break;
570 }
320 if (NULL == call) 571 if (NULL == call)
321 { 572 {
573 GNUNET_assert (NULL != phone);
322 GNUNET_CONVERSATION_phone_hang_up (phone, 574 GNUNET_CONVERSATION_phone_hang_up (phone,
323 args); 575 args);
576 state = CS_LISTEN;
324 } 577 }
325 else 578 else
326 { 579 {
327 GNUNET_CONVERSATION_call_stop (call, args); 580 GNUNET_CONVERSATION_call_stop (call, args);
328 call = NULL; 581 call = NULL;
329 phone = GNUNET_CONVERSATION_phone_create (cfg, 582 start_phone ();
330 caller_id,
331 &phone_event_handler, NULL);
332 } 583 }
333} 584}
334 585
@@ -343,6 +594,8 @@ static struct VoipCommand commands[] = {
343 gettext_noop ("Use `/accept MESSAGE' to accept an incoming call")}, 594 gettext_noop ("Use `/accept MESSAGE' to accept an incoming call")},
344 {"/cancel", &do_reject, 595 {"/cancel", &do_reject,
345 gettext_noop ("Use `/cancel MESSAGE' to reject or terminate a call")}, 596 gettext_noop ("Use `/cancel MESSAGE' to reject or terminate a call")},
597 {"/status", &do_status,
598 gettext_noop ("Use `/status to print status information")},
346 {"/quit", &do_quit, 599 {"/quit", &do_quit,
347 gettext_noop ("Use `/quit' to terminate gnunet-conversation")}, 600 gettext_noop ("Use `/quit' to terminate gnunet-conversation")},
348 {"/help", &do_help, 601 {"/help", &do_help,
@@ -436,6 +689,8 @@ do_stop_task (void *cls,
436 ego_name = NULL; 689 ego_name = NULL;
437 GNUNET_CONFIGURATION_destroy (cfg); 690 GNUNET_CONFIGURATION_destroy (cfg);
438 cfg = NULL; 691 cfg = NULL;
692 GNUNET_free_non_null (peer_name);
693 state = CS_ERROR;
439} 694}
440 695
441 696
@@ -451,7 +706,7 @@ handle_command (void *cls,
451{ 706{
452 char message[MAX_MESSAGE_LENGTH + 1]; 707 char message[MAX_MESSAGE_LENGTH + 1];
453 const char *ptr; 708 const char *ptr;
454 int i; 709 size_t i;
455 710
456 handle_cmd_task = 711 handle_cmd_task =
457 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 712 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -497,9 +752,10 @@ identity_cb (void *cls,
497 return; 752 return;
498 if (ego == caller_id) 753 if (ego == caller_id)
499 { 754 {
500 FPRINTF (stdout, 755 if (verbose)
501 _("Name of our ego changed to `%s'\n"), 756 FPRINTF (stdout,
502 name); 757 _("Name of our ego changed to `%s'\n"),
758 name);
503 GNUNET_free (ego_name); 759 GNUNET_free (ego_name);
504 ego_name = GNUNET_strdup (name); 760 ego_name = GNUNET_strdup (name);
505 return; 761 return;
@@ -509,6 +765,10 @@ identity_cb (void *cls,
509 return; 765 return;
510 if (NULL == ego) 766 if (NULL == ego)
511 { 767 {
768 if (verbose)
769 FPRINTF (stdout,
770 _("Our ego `%s' was deleted!\n"),
771 ego_name);
512 caller_id = NULL; 772 caller_id = NULL;
513 return; 773 return;
514 } 774 }
@@ -517,19 +777,7 @@ identity_cb (void *cls,
517 "CONVERSATION", 777 "CONVERSATION",
518 "LINE", 778 "LINE",
519 line); 779 line);
520 phone = GNUNET_CONVERSATION_phone_create (cfg, 780 start_phone ();
521 caller_id,
522 &phone_event_handler, NULL);
523 /* FIXME: get record and print full GNS record info later here... */
524 if (NULL == phone)
525 {
526 fprintf (stderr,
527 _("Failed to setup phone (internal error)\n"));
528 }
529 else
530 fprintf (stdout,
531 _("Phone active on line %u\n"),
532 (unsigned int) line);
533} 781}
534 782
535 783