diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-10-04 18:12:01 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-10-04 18:12:01 +0000 |
commit | 695da6ce5cdfeca5ae2c08ed82565de65f2f69bb (patch) | |
tree | ddf0d86543ea07e8dfa55c7e2d591aad2ce21d9a /src/conversation | |
parent | 167ec1e3caa5068b8cd64b09b503a72d0d308a13 (diff) | |
download | gnunet-695da6ce5cdfeca5ae2c08ed82565de65f2f69bb.tar.gz gnunet-695da6ce5cdfeca5ae2c08ed82565de65f2f69bb.zip |
-more control logic
Diffstat (limited to 'src/conversation')
-rw-r--r-- | src/conversation/gnunet-service-conversation-new.c | 311 |
1 files changed, 303 insertions, 8 deletions
diff --git a/src/conversation/gnunet-service-conversation-new.c b/src/conversation/gnunet-service-conversation-new.c index 6b33f6092..f60a26523 100644 --- a/src/conversation/gnunet-service-conversation-new.c +++ b/src/conversation/gnunet-service-conversation-new.c | |||
@@ -64,6 +64,11 @@ enum LineStatus | |||
64 | LS_CALLEE_CONNECTED, | 64 | LS_CALLEE_CONNECTED, |
65 | 65 | ||
66 | /** | 66 | /** |
67 | * We're in shutdown, sending hangup messages before cleaning up. | ||
68 | */ | ||
69 | LS_CALLEE_SHUTDOWN, | ||
70 | |||
71 | /** | ||
67 | * We are waiting for the phone to be picked up. | 72 | * We are waiting for the phone to be picked up. |
68 | */ | 73 | */ |
69 | LS_CALLER_CALLING, | 74 | LS_CALLER_CALLING, |
@@ -252,6 +257,32 @@ handle_client_pickup_message (void *cls, | |||
252 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 257 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
253 | return; | 258 | return; |
254 | } | 259 | } |
260 | switch (line->status) | ||
261 | { | ||
262 | case LS_CALLEE_LISTEN: | ||
263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
264 | "Ignoring client's PICKUP message, caller has HUNG UP already\n"); | ||
265 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
266 | break; | ||
267 | case LS_CALLEE_RINGING: | ||
268 | line->status = LS_CALLEE_CONNECTED; | ||
269 | break; | ||
270 | case LS_CALLEE_CONNECTED: | ||
271 | GNUNET_break (0); | ||
272 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
273 | return; | ||
274 | case LS_CALLEE_SHUTDOWN: | ||
275 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
276 | "Ignoring client's PICKUP message, line is in SHUTDOWN\n"); | ||
277 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
278 | break; | ||
279 | case LS_CALLER_CALLING: | ||
280 | case LS_CALLER_CONNECTED: | ||
281 | case LS_CALLER_SHUTDOWN: | ||
282 | GNUNET_break (0); | ||
283 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
284 | return; | ||
285 | } | ||
255 | line->status = LS_CALLEE_CONNECTED; | 286 | line->status = LS_CALLEE_CONNECTED; |
256 | e = GNUNET_MQ_msg_extra (mppm, | 287 | e = GNUNET_MQ_msg_extra (mppm, |
257 | len, | 288 | len, |
@@ -263,6 +294,75 @@ handle_client_pickup_message (void *cls, | |||
263 | 294 | ||
264 | 295 | ||
265 | /** | 296 | /** |
297 | * Destroy the mesh tunnels of a line. | ||
298 | * | ||
299 | * @param line line to shutdown tunnels of | ||
300 | */ | ||
301 | static void | ||
302 | destroy_line_mesh_tunnels (struct Line *line) | ||
303 | { | ||
304 | if (NULL != line->reliable_mq) | ||
305 | { | ||
306 | GNUNET_MQ_destroy (line->reliable_mq); | ||
307 | line->reliable_mq = NULL; | ||
308 | } | ||
309 | if (NULL != line->tunnel_unreliable) | ||
310 | { | ||
311 | GNUNET_MESH_tunnel_destroy (line->tunnel_unreliable); | ||
312 | line->tunnel_unreliable = NULL; | ||
313 | } | ||
314 | if (NULL != line->tunnel_reliable) | ||
315 | { | ||
316 | GNUNET_MESH_tunnel_destroy (line->tunnel_reliable); | ||
317 | line->tunnel_reliable = NULL; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | |||
322 | /** | ||
323 | * We are done signalling shutdown to the other peer. Close down | ||
324 | * (or reset) the line. | ||
325 | * | ||
326 | * @param cls the `struct Line` to reset/terminate | ||
327 | */ | ||
328 | static void | ||
329 | mq_done_finish_caller_shutdown (void *cls) | ||
330 | { | ||
331 | struct Line *line = cls; | ||
332 | |||
333 | switch (line->status) | ||
334 | { | ||
335 | case LS_CALLEE_LISTEN: | ||
336 | GNUNET_break (0); | ||
337 | break; | ||
338 | case LS_CALLEE_RINGING: | ||
339 | GNUNET_break (0); | ||
340 | break; | ||
341 | case LS_CALLEE_CONNECTED: | ||
342 | GNUNET_break (0); | ||
343 | break; | ||
344 | case LS_CALLEE_SHUTDOWN: | ||
345 | line->status = LS_CALLEE_LISTEN; | ||
346 | destroy_line_mesh_tunnels (line); | ||
347 | return; | ||
348 | case LS_CALLER_CALLING: | ||
349 | line->status = LS_CALLER_SHUTDOWN; | ||
350 | break; | ||
351 | case LS_CALLER_CONNECTED: | ||
352 | line->status = LS_CALLER_SHUTDOWN; | ||
353 | break; | ||
354 | case LS_CALLER_SHUTDOWN: | ||
355 | destroy_line_mesh_tunnels (line); | ||
356 | GNUNET_CONTAINER_DLL_remove (lines_head, | ||
357 | lines_tail, | ||
358 | line); | ||
359 | GNUNET_free (line); | ||
360 | break; | ||
361 | } | ||
362 | } | ||
363 | |||
364 | |||
365 | /** | ||
266 | * Function to handle a hangup request message from the client | 366 | * Function to handle a hangup request message from the client |
267 | * | 367 | * |
268 | * @param cls closure, NULL | 368 | * @param cls closure, NULL |
@@ -297,11 +397,40 @@ handle_client_hangup_message (void *cls, | |||
297 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 397 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
298 | return; | 398 | return; |
299 | } | 399 | } |
300 | line->status = LS_CALLEE_LISTEN; | 400 | switch (line->status) |
401 | { | ||
402 | case LS_CALLEE_LISTEN: | ||
403 | GNUNET_break (0); | ||
404 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
405 | return; | ||
406 | case LS_CALLEE_RINGING: | ||
407 | line->status = LS_CALLEE_SHUTDOWN; | ||
408 | break; | ||
409 | case LS_CALLEE_CONNECTED: | ||
410 | line->status = LS_CALLEE_SHUTDOWN; | ||
411 | break; | ||
412 | case LS_CALLEE_SHUTDOWN: | ||
413 | GNUNET_break (0); | ||
414 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
415 | return; | ||
416 | case LS_CALLER_CALLING: | ||
417 | line->status = LS_CALLER_SHUTDOWN; | ||
418 | break; | ||
419 | case LS_CALLER_CONNECTED: | ||
420 | line->status = LS_CALLER_SHUTDOWN; | ||
421 | break; | ||
422 | case LS_CALLER_SHUTDOWN: | ||
423 | GNUNET_break (0); | ||
424 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
425 | return; | ||
426 | } | ||
301 | e = GNUNET_MQ_msg_extra (mhum, | 427 | e = GNUNET_MQ_msg_extra (mhum, |
302 | len, | 428 | len, |
303 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP); | 429 | GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_HANG_UP); |
304 | memcpy (&mhum[1], meta, len); | 430 | memcpy (&mhum[1], meta, len); |
431 | GNUNET_MQ_notify_sent (e, | ||
432 | &mq_done_finish_caller_shutdown, | ||
433 | line); | ||
305 | GNUNET_MQ_send (line->reliable_mq, e); | 434 | GNUNET_MQ_send (line->reliable_mq, e); |
306 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 435 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
307 | } | 436 | } |
@@ -389,6 +518,21 @@ handle_client_audio_message (void *cls, | |||
389 | 518 | ||
390 | 519 | ||
391 | /** | 520 | /** |
521 | * We are done signalling shutdown to the other peer. | ||
522 | * Destroy the tunnel. | ||
523 | * | ||
524 | * @param cls the `struct GNUNET_MESH_tunnel` to destroy | ||
525 | */ | ||
526 | static void | ||
527 | mq_done_destroy_tunnel (void *cls) | ||
528 | { | ||
529 | struct GNUNET_MESH_Tunnel *tunnel = cls; | ||
530 | |||
531 | GNUNET_MESH_tunnel_destroy (tunnel); | ||
532 | } | ||
533 | |||
534 | |||
535 | /** | ||
392 | * Function to handle a ring message incoming over mesh | 536 | * Function to handle a ring message incoming over mesh |
393 | * | 537 | * |
394 | * @param cls closure, NULL | 538 | * @param cls closure, NULL |
@@ -433,7 +577,11 @@ handle_mesh_ring_message (void *cls, | |||
433 | _("No available phone for incoming call on line %u, sending BUSY signal\n"), | 577 | _("No available phone for incoming call on line %u, sending BUSY signal\n"), |
434 | ntohl (msg->remote_line)); | 578 | ntohl (msg->remote_line)); |
435 | e = GNUNET_MQ_msg (busy, GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_BUSY); | 579 | e = GNUNET_MQ_msg (busy, GNUNET_MESSAGE_TYPE_CONVERSATION_MESH_PHONE_BUSY); |
580 | GNUNET_MQ_notify_sent (e, | ||
581 | &mq_done_destroy_tunnel, | ||
582 | tunnel); | ||
436 | GNUNET_MQ_send (line->reliable_mq, e); | 583 | GNUNET_MQ_send (line->reliable_mq, e); |
584 | GNUNET_MESH_receive_done (tunnel); /* needed? */ | ||
437 | return GNUNET_OK; | 585 | return GNUNET_OK; |
438 | } | 586 | } |
439 | line->status = LS_CALLEE_RINGING; | 587 | line->status = LS_CALLEE_RINGING; |
@@ -449,6 +597,7 @@ handle_mesh_ring_message (void *cls, | |||
449 | line->client, | 597 | line->client, |
450 | &cring.header, | 598 | &cring.header, |
451 | GNUNET_NO); | 599 | GNUNET_NO); |
600 | GNUNET_MESH_receive_done (tunnel); | ||
452 | return GNUNET_OK; | 601 | return GNUNET_OK; |
453 | } | 602 | } |
454 | 603 | ||
@@ -468,10 +617,67 @@ handle_mesh_hangup_message (void *cls, | |||
468 | void **tunnel_ctx, | 617 | void **tunnel_ctx, |
469 | const struct GNUNET_MessageHeader *message) | 618 | const struct GNUNET_MessageHeader *message) |
470 | { | 619 | { |
620 | struct Line *line = *tunnel_ctx; | ||
471 | const struct MeshPhoneHangupMessage *msg; | 621 | const struct MeshPhoneHangupMessage *msg; |
622 | const char *reason; | ||
623 | size_t len = ntohs (message->size) - sizeof (struct MeshPhoneHangupMessage); | ||
624 | char buf[len + sizeof (struct ClientPhoneHangupMessage)]; | ||
625 | struct ClientPhoneHangupMessage *hup; | ||
472 | 626 | ||
473 | msg = (const struct MeshPhoneHangupMessage *) message; | 627 | msg = (const struct MeshPhoneHangupMessage *) message; |
474 | GNUNET_break (0); // FIXME | 628 | len = ntohs (msg->header.size) - sizeof (struct MeshPhoneHangupMessage); |
629 | reason = (const char *) &msg[1]; | ||
630 | if ( (0 == len) || | ||
631 | ('\0' != reason[len - 1]) ) | ||
632 | { | ||
633 | reason = NULL; | ||
634 | len = 0; | ||
635 | } | ||
636 | if (NULL == line) | ||
637 | { | ||
638 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
639 | "HANGUP message received for non-existing line, dropping tunnel.\n"); | ||
640 | return GNUNET_SYSERR; | ||
641 | } | ||
642 | hup = (struct ClientPhoneHangupMessage *) buf; | ||
643 | hup->header.size = sizeof (buf); | ||
644 | hup->header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); | ||
645 | memcpy (&hup[1], reason, len); | ||
646 | GNUNET_SERVER_notification_context_unicast (nc, | ||
647 | line->client, | ||
648 | &hup->header, | ||
649 | GNUNET_NO); | ||
650 | GNUNET_MESH_receive_done (tunnel); | ||
651 | *tunnel_ctx = NULL; | ||
652 | switch (line->status) | ||
653 | { | ||
654 | case LS_CALLEE_LISTEN: | ||
655 | GNUNET_break (0); | ||
656 | return GNUNET_SYSERR; | ||
657 | case LS_CALLEE_RINGING: | ||
658 | line->status = LS_CALLEE_LISTEN; | ||
659 | destroy_line_mesh_tunnels (line); | ||
660 | break; | ||
661 | case LS_CALLEE_CONNECTED: | ||
662 | line->status = LS_CALLEE_LISTEN; | ||
663 | destroy_line_mesh_tunnels (line); | ||
664 | break; | ||
665 | case LS_CALLEE_SHUTDOWN: | ||
666 | line->status = LS_CALLEE_LISTEN; | ||
667 | destroy_line_mesh_tunnels (line); | ||
668 | break; | ||
669 | case LS_CALLER_CALLING: | ||
670 | line->status = LS_CALLER_SHUTDOWN; | ||
671 | mq_done_finish_caller_shutdown (line); | ||
672 | break; | ||
673 | case LS_CALLER_CONNECTED: | ||
674 | line->status = LS_CALLER_SHUTDOWN; | ||
675 | mq_done_finish_caller_shutdown (line); | ||
676 | break; | ||
677 | case LS_CALLER_SHUTDOWN: | ||
678 | mq_done_finish_caller_shutdown (line); | ||
679 | break; | ||
680 | } | ||
475 | return GNUNET_OK; | 681 | return GNUNET_OK; |
476 | } | 682 | } |
477 | 683 | ||
@@ -506,6 +712,7 @@ handle_mesh_pickup_message (void *cls, | |||
506 | GNUNET_NO); | 712 | GNUNET_NO); |
507 | 713 | ||
508 | 714 | ||
715 | GNUNET_MESH_receive_done (tunnel); | ||
509 | return GNUNET_OK; | 716 | return GNUNET_OK; |
510 | } | 717 | } |
511 | 718 | ||
@@ -525,10 +732,51 @@ handle_mesh_busy_message (void *cls, | |||
525 | void **tunnel_ctx, | 732 | void **tunnel_ctx, |
526 | const struct GNUNET_MessageHeader *message) | 733 | const struct GNUNET_MessageHeader *message) |
527 | { | 734 | { |
735 | struct Line *line = *tunnel_ctx; | ||
528 | const struct MeshPhoneBusyMessage *msg; | 736 | const struct MeshPhoneBusyMessage *msg; |
737 | struct ClientPhoneBusyMessage busy; | ||
529 | 738 | ||
530 | msg = (const struct MeshPhoneBusyMessage *) message; | 739 | msg = (const struct MeshPhoneBusyMessage *) message; |
531 | GNUNET_break (0); // FIXME | 740 | if (NULL == line) |
741 | { | ||
742 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
743 | "HANGUP message received for non-existing line, dropping tunnel.\n"); | ||
744 | return GNUNET_SYSERR; | ||
745 | } | ||
746 | busy.header.size = sizeof (busy); | ||
747 | busy.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_BUSY); | ||
748 | GNUNET_SERVER_notification_context_unicast (nc, | ||
749 | line->client, | ||
750 | &busy.header, | ||
751 | GNUNET_NO); | ||
752 | GNUNET_MESH_receive_done (tunnel); | ||
753 | *tunnel_ctx = NULL; | ||
754 | switch (line->status) | ||
755 | { | ||
756 | case LS_CALLEE_LISTEN: | ||
757 | GNUNET_break (0); | ||
758 | return GNUNET_SYSERR; | ||
759 | case LS_CALLEE_RINGING: | ||
760 | GNUNET_break_op (0); | ||
761 | break; | ||
762 | case LS_CALLEE_CONNECTED: | ||
763 | GNUNET_break_op (0); | ||
764 | break; | ||
765 | case LS_CALLEE_SHUTDOWN: | ||
766 | GNUNET_break_op (0); | ||
767 | break; | ||
768 | case LS_CALLER_CALLING: | ||
769 | line->status = LS_CALLER_SHUTDOWN; | ||
770 | mq_done_finish_caller_shutdown (line); | ||
771 | break; | ||
772 | case LS_CALLER_CONNECTED: | ||
773 | line->status = LS_CALLER_SHUTDOWN; | ||
774 | mq_done_finish_caller_shutdown (line); | ||
775 | break; | ||
776 | case LS_CALLER_SHUTDOWN: | ||
777 | mq_done_finish_caller_shutdown (line); | ||
778 | break; | ||
779 | } | ||
532 | return GNUNET_OK; | 780 | return GNUNET_OK; |
533 | } | 781 | } |
534 | 782 | ||
@@ -552,6 +800,7 @@ handle_mesh_audio_message (void *cls, | |||
552 | 800 | ||
553 | msg = (const struct MeshAudioMessage *) message; | 801 | msg = (const struct MeshAudioMessage *) message; |
554 | GNUNET_break (0); // FIXME | 802 | GNUNET_break (0); // FIXME |
803 | GNUNET_MESH_receive_done (tunnel); | ||
555 | return GNUNET_OK; | 804 | return GNUNET_OK; |
556 | } | 805 | } |
557 | 806 | ||
@@ -572,10 +821,9 @@ inbound_tunnel (void *cls, | |||
572 | const struct GNUNET_PeerIdentity *initiator, | 821 | const struct GNUNET_PeerIdentity *initiator, |
573 | uint32_t port) | 822 | uint32_t port) |
574 | { | 823 | { |
575 | |||
576 | GNUNET_break (0); // FIXME | ||
577 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 824 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
578 | _("Received incoming tunnel on port %d\n"), port); | 825 | _("Received incoming tunnel on port %d\n"), |
826 | port); | ||
579 | return NULL; | 827 | return NULL; |
580 | } | 828 | } |
581 | 829 | ||
@@ -594,7 +842,55 @@ inbound_end (void *cls, | |||
594 | const struct GNUNET_MESH_Tunnel *tunnel, | 842 | const struct GNUNET_MESH_Tunnel *tunnel, |
595 | void *tunnel_ctx) | 843 | void *tunnel_ctx) |
596 | { | 844 | { |
597 | GNUNET_break (0); // FIXME | 845 | struct Line *line = tunnel_ctx; |
846 | struct ClientPhoneHangupMessage hup; | ||
847 | |||
848 | if (NULL == line) | ||
849 | return; | ||
850 | if (line->tunnel_unreliable == tunnel) | ||
851 | { | ||
852 | line->tunnel_unreliable = NULL; | ||
853 | return; | ||
854 | } | ||
855 | hup.header.size = sizeof (hup); | ||
856 | hup.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); | ||
857 | switch (line->status) | ||
858 | { | ||
859 | case LS_CALLEE_LISTEN: | ||
860 | GNUNET_break (0); | ||
861 | return; | ||
862 | case LS_CALLEE_RINGING: | ||
863 | case LS_CALLEE_CONNECTED: | ||
864 | GNUNET_SERVER_notification_context_unicast (nc, | ||
865 | line->client, | ||
866 | &hup.header, | ||
867 | GNUNET_NO); | ||
868 | line->status = LS_CALLEE_LISTEN; | ||
869 | break; | ||
870 | case LS_CALLEE_SHUTDOWN: | ||
871 | line->status = LS_CALLEE_LISTEN; | ||
872 | destroy_line_mesh_tunnels (line); | ||
873 | break; | ||
874 | case LS_CALLER_CALLING: | ||
875 | case LS_CALLER_CONNECTED: | ||
876 | GNUNET_SERVER_notification_context_unicast (nc, | ||
877 | line->client, | ||
878 | &hup.header, | ||
879 | GNUNET_NO); | ||
880 | destroy_line_mesh_tunnels (line); | ||
881 | GNUNET_CONTAINER_DLL_remove (lines_head, | ||
882 | lines_tail, | ||
883 | line); | ||
884 | GNUNET_free (line); | ||
885 | break; | ||
886 | case LS_CALLER_SHUTDOWN: | ||
887 | destroy_line_mesh_tunnels (line); | ||
888 | GNUNET_CONTAINER_DLL_remove (lines_head, | ||
889 | lines_tail, | ||
890 | line); | ||
891 | GNUNET_free (line); | ||
892 | break; | ||
893 | } | ||
598 | } | 894 | } |
599 | 895 | ||
600 | 896 | ||
@@ -631,7 +927,6 @@ static void | |||
631 | do_shutdown (void *cls, | 927 | do_shutdown (void *cls, |
632 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 928 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
633 | { | 929 | { |
634 | GNUNET_break (0); // FIXME | ||
635 | if (NULL != mesh) | 930 | if (NULL != mesh) |
636 | { | 931 | { |
637 | GNUNET_MESH_disconnect (mesh); | 932 | GNUNET_MESH_disconnect (mesh); |