diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-11-15 22:45:59 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-11-15 22:45:59 +0000 |
commit | d87511e863db9e215c0ed8054897c49473c708f8 (patch) | |
tree | 467b840f642973e58c1bac1def03425fab914b77 /src/conversation | |
parent | e38fa2748c5f85427959bc61f112582d72d856de (diff) | |
download | gnunet-d87511e863db9e215c0ed8054897c49473c708f8.tar.gz gnunet-d87511e863db9e215c0ed8054897c49473c708f8.zip |
-updating gnunet-conversation to match current API
Diffstat (limited to 'src/conversation')
-rw-r--r-- | src/conversation/gnunet-conversation.c | 467 |
1 files changed, 335 insertions, 132 deletions
diff --git a/src/conversation/gnunet-conversation.c b/src/conversation/gnunet-conversation.c index 0287114f2..5961046d1 100644 --- a/src/conversation/gnunet-conversation.c +++ b/src/conversation/gnunet-conversation.c | |||
@@ -38,30 +38,37 @@ | |||
38 | 38 | ||
39 | 39 | ||
40 | /** | 40 | /** |
41 | * Possible states of the program. | 41 | * Possible states of the phone. |
42 | */ | 42 | */ |
43 | enum ConversationState | 43 | enum PhoneState |
44 | { | 44 | { |
45 | /** | 45 | /** |
46 | * We're waiting for our own idenitty. | 46 | * We're waiting for our own idenitty. |
47 | */ | 47 | */ |
48 | CS_LOOKUP_EGO, | 48 | PS_LOOKUP_EGO, |
49 | 49 | ||
50 | /** | 50 | /** |
51 | * We're listening for calls | 51 | * We're listening for calls |
52 | */ | 52 | */ |
53 | CS_LISTEN, | 53 | PS_LISTEN, |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * Our phone is ringing. | 56 | * We accepted an incoming phone call. |
57 | */ | 57 | */ |
58 | CS_RING, | 58 | PS_ACCEPTED, |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * We accepted an incoming phone call. | 61 | * Internal error |
62 | */ | 62 | */ |
63 | CS_ACCEPTED, | 63 | PS_ERROR |
64 | }; | ||
65 | |||
64 | 66 | ||
67 | /** | ||
68 | * States for current outgoing call. | ||
69 | */ | ||
70 | enum CallState | ||
71 | { | ||
65 | /** | 72 | /** |
66 | * We are looking up some other participant. | 73 | * We are looking up some other participant. |
67 | */ | 74 | */ |
@@ -78,13 +85,14 @@ enum ConversationState | |||
78 | CS_CONNECTED, | 85 | CS_CONNECTED, |
79 | 86 | ||
80 | /** | 87 | /** |
81 | * Internal error | 88 | * The call is currently suspended (by us). |
82 | */ | 89 | */ |
83 | CS_ERROR | 90 | CS_SUSPENDED |
84 | 91 | ||
85 | }; | 92 | }; |
86 | 93 | ||
87 | 94 | ||
95 | |||
88 | /** | 96 | /** |
89 | * List of incoming calls | 97 | * List of incoming calls |
90 | */ | 98 | */ |
@@ -109,15 +117,17 @@ struct CallList | |||
109 | /** | 117 | /** |
110 | * String identifying the caller. | 118 | * String identifying the caller. |
111 | */ | 119 | */ |
112 | const char *caller_id; | 120 | char *caller_id; |
113 | 121 | ||
114 | /** | 122 | /** |
115 | * Unique number of the call. | 123 | * Unique number of the call. |
116 | */ | 124 | */ |
117 | unsigned int caller_num; | 125 | unsigned int caller_num; |
126 | |||
118 | }; | 127 | }; |
119 | 128 | ||
120 | 129 | ||
130 | |||
121 | /** | 131 | /** |
122 | * Phone handle | 132 | * Phone handle |
123 | */ | 133 | */ |
@@ -194,9 +204,14 @@ static char *peer_name; | |||
194 | static struct GNUNET_DISK_FileHandle *stdin_fh; | 204 | static struct GNUNET_DISK_FileHandle *stdin_fh; |
195 | 205 | ||
196 | /** | 206 | /** |
197 | * Our current state. | 207 | * Our phone's current state. |
208 | */ | ||
209 | static enum PhoneState phone_state; | ||
210 | |||
211 | /** | ||
212 | * Our call's current state. | ||
198 | */ | 213 | */ |
199 | static enum ConversationState state; | 214 | static enum CallState call_state; |
200 | 215 | ||
201 | /** | 216 | /** |
202 | * Counts the number of incoming calls we have had so far. | 217 | * Counts the number of incoming calls we have had so far. |
@@ -228,21 +243,46 @@ phone_event_handler (void *cls, | |||
228 | struct GNUNET_CONVERSATION_Caller *caller, | 243 | struct GNUNET_CONVERSATION_Caller *caller, |
229 | const char *caller_id) | 244 | const char *caller_id) |
230 | { | 245 | { |
246 | struct CallList *cl; | ||
247 | |||
231 | switch (code) | 248 | switch (code) |
232 | { | 249 | { |
233 | case GNUNET_CONVERSATION_EC_PHONE_RING: | 250 | case GNUNET_CONVERSATION_EC_PHONE_RING: |
234 | // FIXME: update state! | ||
235 | FPRINTF (stdout, | 251 | FPRINTF (stdout, |
236 | _("Incoming call from `%s'.\nPlease /accept #%u or /cancel %u the call.\n"), | 252 | _("Incoming call from `%s'.\nPlease /accept #%u or /cancel %u the call.\n"), |
237 | caller_id, | 253 | caller_id, |
238 | caller_num_gen, | 254 | caller_num_gen, |
239 | caller_num_gen); | 255 | caller_num_gen); |
256 | cl = GNUNET_new (struct CallList); | ||
257 | cl->caller = caller; | ||
258 | cl->caller_id = GNUNET_strdup (caller_id); | ||
259 | cl->caller_num = caller_num_gen++; | ||
260 | GNUNET_CONTAINER_DLL_insert (cl_head, | ||
261 | cl_tail, | ||
262 | cl); | ||
240 | break; | 263 | break; |
241 | case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP: | 264 | case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP: |
242 | // FIXME: update state! | 265 | for (cl = cl_head; NULL != cl; cl = cl->next) |
266 | if (caller == cl->caller) | ||
267 | break; | ||
268 | if (NULL == cl) | ||
269 | { | ||
270 | GNUNET_break (0); | ||
271 | return; | ||
272 | } | ||
243 | FPRINTF (stdout, | 273 | FPRINTF (stdout, |
244 | _("Call terminated: %s\n"), | 274 | _("Call from `%s' terminated\n"), |
245 | caller_id); | 275 | cl->caller_id); |
276 | GNUNET_CONTAINER_DLL_remove (cl_head, | ||
277 | cl_tail, | ||
278 | cl); | ||
279 | GNUNET_free (cl->caller_id); | ||
280 | if (cl == cl_active) | ||
281 | { | ||
282 | cl_active = NULL; | ||
283 | phone_state = PS_LISTEN; | ||
284 | } | ||
285 | GNUNET_free (cl); | ||
246 | break; | 286 | break; |
247 | } | 287 | } |
248 | } | 288 | } |
@@ -258,13 +298,19 @@ static void | |||
258 | caller_event_handler (void *cls, | 298 | caller_event_handler (void *cls, |
259 | enum GNUNET_CONVERSATION_CallerEventCode code) | 299 | enum GNUNET_CONVERSATION_CallerEventCode code) |
260 | { | 300 | { |
301 | struct CallList *cl = cls; | ||
302 | |||
261 | switch (code) | 303 | switch (code) |
262 | { | 304 | { |
263 | case GNUNET_CONVERSATION_EC_CALLER_SUSPEND: | 305 | case GNUNET_CONVERSATION_EC_CALLER_SUSPEND: |
264 | // FIXME: notify user! | 306 | FPRINTF (stdout, |
307 | _("Call from `%s' suspended by other user\n"), | ||
308 | cl->caller_id); | ||
265 | break; | 309 | break; |
266 | case GNUNET_CONVERSATION_EC_CALLER_RESUME: | 310 | case GNUNET_CONVERSATION_EC_CALLER_RESUME: |
267 | // FIXME: notify user! | 311 | FPRINTF (stdout, |
312 | _("Call from `%s' resumed by other user\n"), | ||
313 | cl->caller_id); | ||
268 | break; | 314 | break; |
269 | } | 315 | } |
270 | } | 316 | } |
@@ -283,7 +329,7 @@ start_phone () | |||
283 | FPRINTF (stderr, | 329 | FPRINTF (stderr, |
284 | _("Ego `%s' no longer available, phone is now down.\n"), | 330 | _("Ego `%s' no longer available, phone is now down.\n"), |
285 | ego_name); | 331 | ego_name); |
286 | state = CS_LOOKUP_EGO; | 332 | phone_state = PS_LOOKUP_EGO; |
287 | return; | 333 | return; |
288 | } | 334 | } |
289 | phone = GNUNET_CONVERSATION_phone_create (cfg, | 335 | phone = GNUNET_CONVERSATION_phone_create (cfg, |
@@ -295,7 +341,7 @@ start_phone () | |||
295 | FPRINTF (stderr, | 341 | FPRINTF (stderr, |
296 | "%s", | 342 | "%s", |
297 | _("Failed to setup phone (internal error)\n")); | 343 | _("Failed to setup phone (internal error)\n")); |
298 | state = CS_ERROR; | 344 | phone_state = PS_ERROR; |
299 | } | 345 | } |
300 | else | 346 | else |
301 | { | 347 | { |
@@ -309,7 +355,7 @@ start_phone () | |||
309 | FPRINTF (stdout, | 355 | FPRINTF (stdout, |
310 | _("Phone active on line %u\n"), | 356 | _("Phone active on line %u\n"), |
311 | (unsigned int) line); | 357 | (unsigned int) line); |
312 | state = CS_LISTEN; | 358 | phone_state = PS_LISTEN; |
313 | } | 359 | } |
314 | } | 360 | } |
315 | 361 | ||
@@ -317,7 +363,7 @@ start_phone () | |||
317 | /** | 363 | /** |
318 | * Function called with an event emitted by a call. | 364 | * Function called with an event emitted by a call. |
319 | * | 365 | * |
320 | * @param cls closure | 366 | * @param cls closure, NULL |
321 | * @param code type of the event on the call | 367 | * @param code type of the event on the call |
322 | */ | 368 | */ |
323 | static void | 369 | static void |
@@ -327,42 +373,44 @@ call_event_handler (void *cls, | |||
327 | switch (code) | 373 | switch (code) |
328 | { | 374 | { |
329 | case GNUNET_CONVERSATION_EC_CALL_RINGING: | 375 | case GNUNET_CONVERSATION_EC_CALL_RINGING: |
330 | GNUNET_break (CS_RESOLVING == state); | 376 | GNUNET_break (CS_RESOLVING == call_state); |
331 | if (verbose) | 377 | if (verbose) |
332 | FPRINTF (stdout, | 378 | FPRINTF (stdout, |
333 | "%s", | 379 | "%s", |
334 | _("Resolved address. Now ringing other party.\n")); | 380 | _("Resolved address. Now ringing other party.\n")); |
335 | state = CS_RINGING; | 381 | call_state = CS_RINGING; |
336 | break; | 382 | break; |
337 | case GNUNET_CONVERSATION_EC_CALL_PICKED_UP: | 383 | case GNUNET_CONVERSATION_EC_CALL_PICKED_UP: |
338 | GNUNET_break (CS_RINGING == state); | 384 | GNUNET_break (CS_RINGING == call_state); |
339 | FPRINTF (stdout, | 385 | FPRINTF (stdout, |
340 | _("Connection established to `%s'\n"), | 386 | _("Connection established to `%s'\n"), |
341 | peer_name); | 387 | peer_name); |
342 | state = CS_CONNECTED; | 388 | call_state = CS_CONNECTED; |
343 | break; | 389 | break; |
344 | case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL: | 390 | case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL: |
345 | GNUNET_break (CS_RESOLVING == state); | 391 | GNUNET_break (CS_RESOLVING == call_state); |
346 | FPRINTF (stdout, | 392 | FPRINTF (stdout, |
347 | _("Failed to resolve `%s'\n"), | 393 | _("Failed to resolve `%s'\n"), |
348 | ego_name); | 394 | ego_name); |
349 | call = NULL; | 395 | call = NULL; |
350 | state = CS_LISTEN; | ||
351 | break; | 396 | break; |
352 | case GNUNET_CONVERSATION_EC_CALL_HUNG_UP: | 397 | case GNUNET_CONVERSATION_EC_CALL_HUNG_UP: |
353 | FPRINTF (stdout, | 398 | FPRINTF (stdout, |
354 | "%s", | 399 | "%s", |
355 | _("Call terminated\n")); | 400 | _("Call terminated\n")); |
356 | call = NULL; | 401 | call = NULL; |
357 | state = CS_LISTEN; | ||
358 | break; | 402 | break; |
359 | case GNUNET_CONVERSATION_EC_CALL_SUSPENDED: | 403 | case GNUNET_CONVERSATION_EC_CALL_SUSPENDED: |
360 | // FIXME: notify user | 404 | GNUNET_break (CS_CONNECTED == call_state); |
361 | // state = CS_SUSPENDED_CALL; | 405 | FPRINTF (stdout, |
406 | _("Connection to `%s' suspended (by other user)\n"), | ||
407 | peer_name); | ||
362 | break; | 408 | break; |
363 | case GNUNET_CONVERSATION_EC_CALL_RESUMED: | 409 | case GNUNET_CONVERSATION_EC_CALL_RESUMED: |
364 | // FIXME: notify user | 410 | GNUNET_break (CS_CONNECTED == call_state); |
365 | // state = CS_CONNECTED; | 411 | FPRINTF (stdout, |
412 | _("Connection to `%s' resumed (by other user)\n"), | ||
413 | peer_name); | ||
366 | break; | 414 | break; |
367 | } | 415 | } |
368 | } | 416 | } |
@@ -448,63 +496,40 @@ do_call (const char *arg) | |||
448 | ego_name); | 496 | ego_name); |
449 | return; | 497 | return; |
450 | } | 498 | } |
451 | switch (state) | 499 | if (NULL != call) |
500 | { | ||
501 | FPRINTF (stderr, | ||
502 | _("You are calling someone else already, hang up first!\n")); | ||
503 | return; | ||
504 | } | ||
505 | switch (phone_state) | ||
452 | { | 506 | { |
453 | case CS_LOOKUP_EGO: | 507 | case PS_LOOKUP_EGO: |
454 | FPRINTF (stderr, | 508 | FPRINTF (stderr, |
455 | _("Ego `%s' not available\n"), | 509 | _("Ego `%s' not available\n"), |
456 | ego_name); | 510 | ego_name); |
457 | return; | 511 | return; |
458 | case CS_LISTEN: | 512 | case PS_LISTEN: |
459 | /* ok to call! */ | 513 | /* ok to call! */ |
460 | break; | 514 | break; |
461 | case CS_RING: | 515 | case PS_ACCEPTED: |
462 | FPRINTF (stdout, | ||
463 | _("Hanging up on incoming phone call from `%s' to call `%s'.\n"), | ||
464 | peer_name, | ||
465 | arg); | ||
466 | // GNUNET_CONVERSATION_caller_hang_up (caller); | ||
467 | break; | ||
468 | case CS_ACCEPTED: | ||
469 | FPRINTF (stderr, | ||
470 | _("You are already in a conversation with `%s', refusing to call `%s'.\n"), | ||
471 | peer_name, | ||
472 | arg); | ||
473 | return; | ||
474 | case CS_RESOLVING: | ||
475 | case CS_RINGING: | ||
476 | FPRINTF (stderr, | 516 | FPRINTF (stderr, |
477 | _("Aborting call to `%s'\n"), | 517 | _("You are answering call from `%s', hang up or suspend that call first!\n"), |
478 | peer_name); | 518 | peer_name); |
479 | // GNUNET_CONVERSATION_caller_hang_up (caller); | ||
480 | // GNUNET_CONVERSATION_call_stop (call); | ||
481 | call = NULL; | ||
482 | break; | ||
483 | case CS_CONNECTED: | ||
484 | FPRINTF (stderr, | ||
485 | _("You are already in a conversation with `%s', refusing to call `%s'.\n"), | ||
486 | peer_name, | ||
487 | arg); | ||
488 | return; | 519 | return; |
489 | case CS_ERROR: | 520 | case PS_ERROR: |
490 | /* ok to call */ | 521 | /* ok to call */ |
491 | break; | 522 | break; |
492 | } | 523 | } |
493 | GNUNET_assert (NULL == call); | ||
494 | if (NULL != phone) | ||
495 | { | ||
496 | GNUNET_CONVERSATION_phone_destroy (phone); | ||
497 | phone = NULL; | ||
498 | } | ||
499 | GNUNET_free_non_null (peer_name); | 524 | GNUNET_free_non_null (peer_name); |
500 | peer_name = GNUNET_strdup (arg); | 525 | peer_name = GNUNET_strdup (arg); |
526 | call_state = CS_RESOLVING; | ||
501 | call = GNUNET_CONVERSATION_call_start (cfg, | 527 | call = GNUNET_CONVERSATION_call_start (cfg, |
502 | caller_id, | 528 | caller_id, |
503 | arg, | 529 | arg, |
504 | speaker, | 530 | speaker, |
505 | mic, | 531 | mic, |
506 | &call_event_handler, NULL); | 532 | &call_event_handler, NULL); |
507 | state = CS_RESOLVING; | ||
508 | } | 533 | } |
509 | 534 | ||
510 | 535 | ||
@@ -516,41 +541,67 @@ do_call (const char *arg) | |||
516 | static void | 541 | static void |
517 | do_accept (const char *args) | 542 | do_accept (const char *args) |
518 | { | 543 | { |
519 | switch (state) | 544 | struct CallList *cl; |
545 | char buf[32]; | ||
546 | |||
547 | if ( (NULL != call) && | ||
548 | (CS_SUSPENDED != call_state) ) | ||
520 | { | 549 | { |
521 | case CS_LOOKUP_EGO: | ||
522 | case CS_LISTEN: | ||
523 | case CS_ERROR: | ||
524 | FPRINTF (stderr, | 550 | FPRINTF (stderr, |
525 | _("There is no incoming call to be accepted!\n")); | 551 | _("You are calling someone else already, hang up first!\n")); |
526 | return; | 552 | return; |
527 | case CS_RING: | 553 | } |
554 | switch (phone_state) | ||
555 | { | ||
556 | case PS_LOOKUP_EGO: | ||
557 | GNUNET_break (0); | ||
558 | break; | ||
559 | case PS_LISTEN: | ||
528 | /* this is the expected state */ | 560 | /* this is the expected state */ |
529 | break; | 561 | break; |
530 | case CS_ACCEPTED: | 562 | case PS_ACCEPTED: |
531 | FPRINTF (stderr, | 563 | FPRINTF (stderr, |
532 | _("You are already in a conversation with `%s'.\n"), | 564 | _("You are answering call from `%s', hang up or suspend that call first!\n"), |
533 | peer_name); | 565 | peer_name); |
534 | return; | 566 | return; |
535 | case CS_RESOLVING: | 567 | case PS_ERROR: |
536 | case CS_RINGING: | 568 | GNUNET_break (0); |
569 | break; | ||
570 | } | ||
571 | cl = cl_head; | ||
572 | if (NULL == cl) | ||
573 | { | ||
537 | FPRINTF (stderr, | 574 | FPRINTF (stderr, |
538 | _("You are trying to call `%s', cannot accept incoming calls right now.\n"), | 575 | _("There is no incoming call to accept here!\n")); |
539 | peer_name); | ||
540 | return; | 576 | return; |
541 | case CS_CONNECTED: | 577 | } |
578 | if ( (NULL != cl->next) || (NULL != args) ) | ||
579 | { | ||
580 | for (cl = cl_head; NULL != cl; cl = cl->next) | ||
581 | { | ||
582 | GNUNET_snprintf (buf, sizeof (buf), | ||
583 | "%u", | ||
584 | cl->caller_num); | ||
585 | if (0 == strcmp (buf, args)) | ||
586 | break; | ||
587 | } | ||
588 | } | ||
589 | if (NULL == cl) | ||
590 | { | ||
542 | FPRINTF (stderr, | 591 | FPRINTF (stderr, |
543 | _("You are already in a conversation with `%s'.\n"), | 592 | _("There is no incoming call `%s' to accept right now!\n"), |
544 | peer_name); | 593 | args); |
545 | return; | 594 | return; |
546 | } | 595 | } |
547 | GNUNET_assert (NULL != cl_active); | 596 | cl_active = cl; |
548 | GNUNET_CONVERSATION_caller_pick_up (cl_active->caller, | 597 | GNUNET_free_non_null (peer_name); |
598 | peer_name = GNUNET_strdup (cl->caller_id); | ||
599 | phone_state = PS_ACCEPTED; | ||
600 | GNUNET_CONVERSATION_caller_pick_up (cl->caller, | ||
549 | &caller_event_handler, | 601 | &caller_event_handler, |
550 | cl_active, | 602 | cl, |
551 | speaker, | 603 | speaker, |
552 | mic); | 604 | mic); |
553 | state = CS_ACCEPTED; | ||
554 | } | 605 | } |
555 | 606 | ||
556 | 607 | ||
@@ -583,87 +634,235 @@ do_address (const char *args) | |||
583 | static void | 634 | static void |
584 | do_status (const char *args) | 635 | do_status (const char *args) |
585 | { | 636 | { |
586 | switch (state) | 637 | struct CallList *cl; |
638 | |||
639 | switch (phone_state) | ||
587 | { | 640 | { |
588 | case CS_LOOKUP_EGO: | 641 | case PS_LOOKUP_EGO: |
589 | FPRINTF (stdout, | 642 | FPRINTF (stdout, |
590 | _("We are currently trying to locate the private key for the ego `%s'.\n"), | 643 | _("We are currently trying to locate the private key for the ego `%s'.\n"), |
591 | ego_name); | 644 | ego_name); |
592 | break; | 645 | break; |
593 | case CS_LISTEN: | 646 | case PS_LISTEN: |
594 | FPRINTF (stdout, | 647 | FPRINTF (stdout, |
595 | _("We are listening for incoming calls for ego `%s' on line %u.\n"), | 648 | _("We are listening for incoming calls for ego `%s' on line %u.\n"), |
596 | ego_name, | 649 | ego_name, |
597 | line); | 650 | line); |
598 | break; | 651 | break; |
599 | case CS_RING: | 652 | case PS_ACCEPTED: |
600 | FPRINTF (stdout, | ||
601 | _("The phone is rining. `%s' is trying to call us.\n"), | ||
602 | peer_name); | ||
603 | break; | ||
604 | case CS_ACCEPTED: | ||
605 | case CS_CONNECTED: | ||
606 | FPRINTF (stdout, | 653 | FPRINTF (stdout, |
607 | _("You are having a conversation with `%s'.\n"), | 654 | _("You are having a conversation with `%s'.\n"), |
608 | peer_name); | 655 | peer_name); |
609 | break; | 656 | break; |
610 | case CS_RESOLVING: | 657 | case PS_ERROR: |
611 | FPRINTF (stdout, | 658 | FPRINTF (stdout, |
612 | _("We are trying to find the network address to call `%s'.\n"), | 659 | _("We had an internal error setting up our phone line. You can still make calls.\n")); |
613 | peer_name); | ||
614 | break; | 660 | break; |
615 | case CS_RINGING: | 661 | } |
662 | if (NULL != call) | ||
663 | { | ||
664 | switch (call_state) | ||
665 | { | ||
666 | case CS_RESOLVING: | ||
667 | FPRINTF (stdout, | ||
668 | _("We are trying to find the network address to call `%s'.\n"), | ||
669 | peer_name); | ||
670 | break; | ||
671 | case CS_RINGING: | ||
672 | FPRINTF (stdout, | ||
673 | _("We are calling `%s', his phone should be ringing.\n"), | ||
674 | peer_name); | ||
675 | break; | ||
676 | case CS_CONNECTED: | ||
677 | FPRINTF (stdout, | ||
678 | _("You are having a conversation with `%s'.\n"), | ||
679 | peer_name); | ||
680 | break; | ||
681 | case CS_SUSPENDED: | ||
682 | /* ok to accept incoming call right now */ | ||
683 | break; | ||
684 | } | ||
685 | } | ||
686 | if ( (NULL != cl_head) && | ||
687 | ( (cl_head != cl_active) || | ||
688 | (cl_head != cl_tail) ) ) | ||
689 | { | ||
616 | FPRINTF (stdout, | 690 | FPRINTF (stdout, |
617 | _("We are calling `%s', his phone should be ringing.\n"), | 691 | "%s", |
618 | peer_name); | 692 | _("Calls waiting:\n")); |
619 | break; | 693 | for (cl = cl_head; NULL != cl; cl = cl->next) |
620 | case CS_ERROR: | 694 | { |
695 | if (cl == cl_active) | ||
696 | continue; | ||
697 | FPRINTF (stdout, | ||
698 | _("#%u: `%s'\n"), | ||
699 | cl->caller_num, | ||
700 | cl->caller_id); | ||
701 | } | ||
621 | FPRINTF (stdout, | 702 | FPRINTF (stdout, |
622 | _("We had an internal error setting up our phone line. You can still make calls.\n")); | 703 | "%s", |
623 | break; | 704 | "\n"); |
624 | } | 705 | } |
625 | } | 706 | } |
626 | 707 | ||
627 | 708 | ||
628 | /** | 709 | /** |
629 | * Rejecting a call | 710 | * Suspending a call |
630 | * | 711 | * |
631 | * @param args arguments given to the command | 712 | * @param args arguments given to the command |
632 | */ | 713 | */ |
633 | static void | 714 | static void |
634 | do_reject (const char *args) | 715 | do_suspend (const char *args) |
635 | { | 716 | { |
636 | switch (state) | 717 | if (NULL != call) |
718 | { | ||
719 | switch (call_state) | ||
720 | { | ||
721 | case CS_RESOLVING: | ||
722 | case CS_RINGING: | ||
723 | case CS_SUSPENDED: | ||
724 | FPRINTF (stderr, | ||
725 | "%s", | ||
726 | _("There is no call that could be suspended right now.\n")); | ||
727 | return; | ||
728 | case CS_CONNECTED: | ||
729 | call_state = CS_SUSPENDED; | ||
730 | GNUNET_CONVERSATION_call_suspend (call); | ||
731 | return; | ||
732 | } | ||
733 | } | ||
734 | switch (phone_state) | ||
637 | { | 735 | { |
638 | case CS_LOOKUP_EGO: | 736 | case PS_LOOKUP_EGO: |
639 | case CS_LISTEN: | 737 | case PS_LISTEN: |
640 | case CS_ERROR: | 738 | case PS_ERROR: |
641 | FPRINTF (stderr, | 739 | FPRINTF (stderr, |
642 | "%s", | 740 | "%s", |
643 | _("There is no call that could be cancelled right now.\n")); | 741 | _("There is no call that could be suspended right now.\n")); |
644 | return; | 742 | return; |
645 | case CS_RING: | 743 | case PS_ACCEPTED: |
646 | case CS_ACCEPTED: | ||
647 | case CS_RESOLVING: | ||
648 | case CS_RINGING: | ||
649 | case CS_CONNECTED: | ||
650 | /* expected state, do rejection logic */ | 744 | /* expected state, do rejection logic */ |
651 | break; | 745 | break; |
652 | } | 746 | } |
653 | if (NULL == call) | 747 | GNUNET_assert (NULL != cl_active); |
748 | GNUNET_CONVERSATION_caller_suspend (cl_active->caller); | ||
749 | cl_active = NULL; | ||
750 | phone_state = PS_LISTEN; | ||
751 | } | ||
752 | |||
753 | |||
754 | /** | ||
755 | * Resuming a call | ||
756 | * | ||
757 | * @param args arguments given to the command | ||
758 | */ | ||
759 | static void | ||
760 | do_resume (const char *args) | ||
761 | { | ||
762 | struct CallList *cl; | ||
763 | char buf[32]; | ||
764 | |||
765 | if (NULL != call) | ||
654 | { | 766 | { |
655 | #if 0 | 767 | switch (call_state) |
656 | GNUNET_assert (NULL != caller); | 768 | { |
657 | GNUNET_CONVERSATION_caller_hang_up (caller); | 769 | case CS_RESOLVING: |
658 | #endif | 770 | case CS_RINGING: |
659 | state = CS_LISTEN; | 771 | case CS_CONNECTED: |
772 | FPRINTF (stderr, | ||
773 | "%s", | ||
774 | _("There is no call that could be resumed right now.\n")); | ||
775 | return; | ||
776 | case CS_SUSPENDED: | ||
777 | call_state = CS_CONNECTED; | ||
778 | GNUNET_CONVERSATION_call_resume (call, | ||
779 | speaker, | ||
780 | mic); | ||
781 | return; | ||
782 | } | ||
660 | } | 783 | } |
661 | else | 784 | switch (phone_state) |
785 | { | ||
786 | case PS_LOOKUP_EGO: | ||
787 | case PS_ERROR: | ||
788 | FPRINTF (stderr, | ||
789 | "%s", | ||
790 | _("There is no call that could be suspended right now.\n")); | ||
791 | return; | ||
792 | case PS_LISTEN: | ||
793 | /* expected state, do resume logic */ | ||
794 | break; | ||
795 | case PS_ACCEPTED: | ||
796 | FPRINTF (stderr, | ||
797 | _("Already talking with `%s', cannot resume a call right now.\n"), | ||
798 | peer_name); | ||
799 | return; | ||
800 | } | ||
801 | GNUNET_assert (NULL == cl_active); | ||
802 | cl = cl_head; | ||
803 | if (NULL == cl) | ||
804 | { | ||
805 | FPRINTF (stderr, | ||
806 | _("There is no incoming call to resume here!\n")); | ||
807 | return; | ||
808 | } | ||
809 | if ( (NULL != cl->next) || (NULL != args) ) | ||
810 | { | ||
811 | for (cl = cl_head; NULL != cl; cl = cl->next) | ||
812 | { | ||
813 | GNUNET_snprintf (buf, sizeof (buf), | ||
814 | "%u", | ||
815 | cl->caller_num); | ||
816 | if (0 == strcmp (buf, args)) | ||
817 | break; | ||
818 | } | ||
819 | } | ||
820 | if (NULL == cl) | ||
821 | { | ||
822 | FPRINTF (stderr, | ||
823 | _("There is no incoming call `%s' to resume right now!\n"), | ||
824 | args); | ||
825 | return; | ||
826 | } | ||
827 | cl_active = cl; | ||
828 | GNUNET_CONVERSATION_caller_resume (cl_active->caller, | ||
829 | speaker, | ||
830 | mic); | ||
831 | phone_state = PS_ACCEPTED; | ||
832 | } | ||
833 | |||
834 | |||
835 | /** | ||
836 | * Rejecting a call | ||
837 | * | ||
838 | * @param args arguments given to the command | ||
839 | */ | ||
840 | static void | ||
841 | do_reject (const char *args) | ||
842 | { | ||
843 | if (NULL != call) | ||
662 | { | 844 | { |
663 | GNUNET_CONVERSATION_call_stop (call); | 845 | GNUNET_CONVERSATION_call_stop (call); |
664 | call = NULL; | 846 | call = NULL; |
665 | start_phone (); | 847 | return; |
848 | } | ||
849 | switch (phone_state) | ||
850 | { | ||
851 | case PS_LOOKUP_EGO: | ||
852 | case PS_LISTEN: | ||
853 | case PS_ERROR: | ||
854 | FPRINTF (stderr, | ||
855 | "%s", | ||
856 | _("There is no call that could be cancelled right now.\n")); | ||
857 | return; | ||
858 | case PS_ACCEPTED: | ||
859 | /* expected state, do rejection logic */ | ||
860 | break; | ||
666 | } | 861 | } |
862 | GNUNET_assert (NULL != cl_active); | ||
863 | GNUNET_CONVERSATION_caller_hang_up (cl_active->caller); | ||
864 | cl_active = NULL; | ||
865 | phone_state = PS_LISTEN; | ||
667 | } | 866 | } |
668 | 867 | ||
669 | 868 | ||
@@ -676,9 +875,13 @@ static struct VoipCommand commands[] = { | |||
676 | {"/call", &do_call, | 875 | {"/call", &do_call, |
677 | gettext_noop ("Use `/call USER.gnu' to call USER")}, | 876 | gettext_noop ("Use `/call USER.gnu' to call USER")}, |
678 | {"/accept", &do_accept, | 877 | {"/accept", &do_accept, |
679 | gettext_noop ("Use `/accept MESSAGE' to accept an incoming call")}, | 878 | gettext_noop ("Use `/accept #NUM' to accept incoming call #NUM")}, |
879 | {"/suspend", &do_suspend, | ||
880 | gettext_noop ("Use `/suspend' to suspend the active call")}, | ||
881 | {"/resume", &do_resume, | ||
882 | gettext_noop ("Use `/resume [#NUM]' to resume a call, #NUM is needed to resume incoming calls, no argument is needed to resume the current outgoing call.")}, | ||
680 | {"/cancel", &do_reject, | 883 | {"/cancel", &do_reject, |
681 | gettext_noop ("Use `/cancel MESSAGE' to reject or terminate a call")}, | 884 | gettext_noop ("Use `/cancel' to reject or terminate a call")}, |
682 | {"/status", &do_status, | 885 | {"/status", &do_status, |
683 | gettext_noop ("Use `/status' to print status information")}, | 886 | gettext_noop ("Use `/status' to print status information")}, |
684 | {"/quit", &do_quit, | 887 | {"/quit", &do_quit, |
@@ -775,7 +978,7 @@ do_stop_task (void *cls, | |||
775 | GNUNET_CONFIGURATION_destroy (cfg); | 978 | GNUNET_CONFIGURATION_destroy (cfg); |
776 | cfg = NULL; | 979 | cfg = NULL; |
777 | GNUNET_free_non_null (peer_name); | 980 | GNUNET_free_non_null (peer_name); |
778 | state = CS_ERROR; | 981 | phone_state = PS_ERROR; |
779 | } | 982 | } |
780 | 983 | ||
781 | 984 | ||