From ba35f9d50322d6dd3398b2b0feb035a6732360b1 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 31 May 2014 22:30:10 +0000 Subject: towards completing phone logic --- src/conversation/gnunet-conversation-gtk_phone.c | 376 +++++++++++++++++++---- 1 file changed, 309 insertions(+), 67 deletions(-) diff --git a/src/conversation/gnunet-conversation-gtk_phone.c b/src/conversation/gnunet-conversation-gtk_phone.c index addc641e..210c8c56 100644 --- a/src/conversation/gnunet-conversation-gtk_phone.c +++ b/src/conversation/gnunet-conversation-gtk_phone.c @@ -188,9 +188,19 @@ enum OutCallState OUT_STATE_ACTIVE, /** - * This phone call is currently suspended. + * This phone call is currently suspended by local. */ - OUT_STATE_SUSPENDED + OUT_STATE_SUSPENDED_LOCAL, + + /** + * This phone call is currently suspended by remote. + */ + OUT_STATE_SUSPENDED_REMOTE, + + /** + * This phone call is currently suspended from both sides. + */ + OUT_STATE_SUSPENDED_BOTH }; @@ -455,6 +465,7 @@ update_call_buttons (GtkTreeSelection *sel) { GtkTreeIter iter; GtkTreeModel *model; + struct IncomingCall *ic; gint type; gint in_state; gint out_state; @@ -477,6 +488,7 @@ update_call_buttons (GtkTreeSelection *sel) GCG_PHONE_LS_TYPE, &type, GCG_PHONE_LS_CALL_STATE, &out_state, GCG_PHONE_LS_CALLER_STATE, &in_state, + GCG_PHONE_LS_CALLER, &ic, -1); switch ((enum TypeOfConversation) type) { @@ -495,7 +507,7 @@ update_call_buttons (GtkTreeSelection *sel) case IN_STATE_CONNECTED: gtk_widget_set_sensitive (b_add_contact, TRUE); gtk_widget_set_sensitive (b_accept, FALSE); - gtk_widget_set_sensitive (b_refuse, FALSE); + gtk_widget_set_sensitive (b_refuse, (active_in != ic)); gtk_widget_set_sensitive (b_resume, FALSE); break; case IN_STATE_SUSPENDED_LOCAL: @@ -527,21 +539,31 @@ update_call_buttons (GtkTreeSelection *sel) case OUT_STATE_RESOLVING: gtk_widget_set_sensitive (b_add_contact, TRUE); gtk_widget_set_sensitive (b_accept, FALSE); - gtk_widget_set_sensitive (b_refuse, TRUE); + gtk_widget_set_sensitive (b_refuse, FALSE); gtk_widget_set_sensitive (b_resume, FALSE); case OUT_STATE_RINGING: gtk_widget_set_sensitive (b_add_contact, TRUE); gtk_widget_set_sensitive (b_accept, ! in_call); - gtk_widget_set_sensitive (b_refuse, TRUE); + gtk_widget_set_sensitive (b_refuse, FALSE); gtk_widget_set_sensitive (b_resume, ! in_call); case OUT_STATE_ACTIVE: gtk_widget_set_sensitive (b_add_contact, TRUE); gtk_widget_set_sensitive (b_accept, FALSE); gtk_widget_set_sensitive (b_refuse, FALSE); gtk_widget_set_sensitive (b_resume, FALSE); - case OUT_STATE_SUSPENDED: + case OUT_STATE_SUSPENDED_LOCAL: gtk_widget_set_sensitive (b_add_contact, TRUE); - gtk_widget_set_sensitive (b_accept, ! in_call); + gtk_widget_set_sensitive (b_accept, FALSE); + gtk_widget_set_sensitive (b_refuse, TRUE); + gtk_widget_set_sensitive (b_resume, ! in_call); + case OUT_STATE_SUSPENDED_REMOTE: + gtk_widget_set_sensitive (b_add_contact, TRUE); + gtk_widget_set_sensitive (b_accept, FALSE); + gtk_widget_set_sensitive (b_refuse, TRUE); + gtk_widget_set_sensitive (b_resume, FALSE); + case OUT_STATE_SUSPENDED_BOTH: + gtk_widget_set_sensitive (b_add_contact, TRUE); + gtk_widget_set_sensitive (b_accept, FALSE); gtk_widget_set_sensitive (b_refuse, TRUE); gtk_widget_set_sensitive (b_resume, ! in_call); default: @@ -599,7 +621,11 @@ set_outgoing_call_state (struct OutgoingCall *oc, break; case OUT_STATE_ACTIVE: break; - case OUT_STATE_SUSPENDED: + case OUT_STATE_SUSPENDED_LOCAL: + break; + case OUT_STATE_SUSPENDED_REMOTE: + break; + case OUT_STATE_SUSPENDED_BOTH: break; } gtk_list_store_set (active_liststore, @@ -700,6 +726,7 @@ phone_event_handler (void *cls, caller_num_gen); break; case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP: + GNUNET_break (in_ring_counter > 0); in_ring_counter--; valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (active_liststore), &iter); @@ -852,7 +879,7 @@ GNUNET_CONVERSATION_GTK_on_accept_clicked (GtkButton *button, } gtk_tree_model_get (model, &iter, - GCG_PHONE_LS_CALLER_STATE, &ic, + GCG_PHONE_LS_CALLER, &ic, -1); if (NULL == ic) { @@ -860,6 +887,7 @@ GNUNET_CONVERSATION_GTK_on_accept_clicked (GtkButton *button, GNUNET_break (0); return; } + phone_state = PS_ACCEPTED; active_in = ic; set_incoming_call_state (ic, IN_STATE_CONNECTED); @@ -885,8 +913,69 @@ void GNUNET_CONVERSATION_GTK_on_reject_clicked (GtkButton *button, gpointer user_data) { - // do_reject (); // FIXME! - do_status (); + struct IncomingCall *ic; + struct OutgoingCall *oc; + GtkTreeSelection *sel; + GtkTreeIter iter; + GtkTreeModel *model; + + sel = gtk_tree_view_get_selection (active_treeview); + if (! gtk_tree_selection_get_selected (sel, + &model, + &iter)) + { + /* reject button should not have been sensitive! */ + GNUNET_break (0); + return; + } + gtk_tree_model_get (model, + &iter, + GCG_PHONE_LS_CALLER, &ic, + GCG_PHONE_LS_CALL, &oc, + -1); + if (NULL != ic) + { + if (active_in == ic) + { + /* reject button should not have been sensitive! */ + GNUNET_break (0); + return; + } + GNUNET_break (in_ring_counter > 0); + in_ring_counter--; + GCG_update_status_bar (_("Rejected conversation with `%s'.\n"), + ic->caller_id); + GCG_HISTORY_add (GCG_HISTORY_TYPE_REJECTED, + ic->caller_id); + set_incoming_call_state (ic, + IN_STATE_NONE); + destroy_in (ic); + phone_state = PS_LISTEN; /* FIXME: or error... */ + do_status (); + return; + } + if (NULL != oc) + { + /* terminate suspended outgoing call */ + if (active_out == oc) + { + /* reject button should not have been sensitive! */ + GNUNET_break (0); + return; + } + GCG_update_status_bar (_("Terminated suspended conversation with `%s'.\n"), + oc->peer_name); + GCG_HISTORY_add (GCG_HISTORY_TYPE_HANGUP, + oc->peer_name); + set_outgoing_call_state (oc, + OUT_STATE_NONE); + destroy_out (oc); + phone_state = PS_LISTEN; /* FIXME: or error... */ + do_status (); + return; + } + /* reject button should not have been sensitive! */ + GNUNET_break (0); } @@ -922,9 +1011,11 @@ void GNUNET_CONVERSATION_GTK_on_resume_clicked (GtkButton *button, gpointer user_data) { - enum TypeOfConversation toc; struct IncomingCall *ic; struct OutgoingCall *oc; + GtkTreeSelection *sel; + GtkTreeIter iter; + GtkTreeModel *model; if ( (NULL != active_in) || (NULL != active_out) || @@ -935,31 +1026,49 @@ GNUNET_CONVERSATION_GTK_on_resume_clicked (GtkButton *button, GNUNET_break(0); return; } - toc = 42; // FIXME: get from selection! - switch (toc) + sel = gtk_tree_view_get_selection (active_treeview); + if (! gtk_tree_selection_get_selected (sel, + &model, + &iter)) + { + /* resume button should not have been sensitive! */ + GNUNET_break (0); + return; + } + gtk_tree_model_get (model, + &iter, + GCG_PHONE_LS_CALLER, &ic, + GCG_PHONE_LS_CALL, &oc, + -1); + if (NULL != ic) { - case CALL_IN: - ic = NULL; // FIXME: get from selection - GNUNET_CONVERSATION_caller_resume (ic->caller, speaker, mic); - set_incoming_call_state (ic, IN_STATE_CONNECTED); phone_state = PS_ACCEPTED; - GCG_update_status_bar (_("Resumed a conversation with `%s'.\n"), - ic->caller_id); + active_in = ic; + set_incoming_call_state (ic, + IN_STATE_CONNECTED); + GCG_update_status_bar (_("Resumed conversation with `%s'.\n"), + ic->caller_id); GCG_set_status_icon ("gnunet-conversation-call-active"); - // FIXME: update visibility/sensitivity + GNUNET_CONVERSATION_caller_resume (ic->caller, + speaker, mic); + // GCG_HISTORY_add (GCG_HISTORY_TYPE_RESUMED, ic->caller_id); do_status (); return; - case CALL_OUT: - oc = NULL; // FIXME: get from selection + } + if (NULL != oc) + { + phone_state = PS_ACCEPTED; + active_out = oc; GNUNET_CONVERSATION_call_resume (oc->call, speaker, mic); set_outgoing_call_state (oc, OUT_STATE_ACTIVE); - // FIXME: update visibility/sensitivity + // GCG_HISTORY_add (GCG_HISTORY_TYPE_RESUMED, ic->caller_id); do_status (); return; } + /* resume button should not have been sensitive! */ GNUNET_break (0); } @@ -974,6 +1083,9 @@ void GNUNET_CONVERSATION_GTK_on_pause_clicked (GtkButton *button, gpointer user_data) { + enum OutCallState os; + enum InCallState is; + if ( (NULL != active_in) && (NULL != active_out) ) { @@ -983,10 +1095,39 @@ GNUNET_CONVERSATION_GTK_on_pause_clicked (GtkButton *button, if (NULL != active_out) { /* outgoing */ + os = active_out->state; + switch (active_out->state) + { + case OUT_STATE_NONE: + GNUNET_assert (0); + break; + case OUT_STATE_RESOLVING: + GNUNET_assert (0); + break; + case OUT_STATE_RINGING: + GNUNET_assert (0); + break; + case OUT_STATE_ACTIVE: + os = OUT_STATE_SUSPENDED_LOCAL; + break; + case OUT_STATE_SUSPENDED_LOCAL: + GNUNET_assert (0); + break; + case OUT_STATE_SUSPENDED_REMOTE: + os = OUT_STATE_SUSPENDED_BOTH; + break; + case OUT_STATE_SUSPENDED_BOTH: + GNUNET_assert (0); + break; + default: + GNUNET_assert (0); + break; + } GNUNET_CONVERSATION_call_suspend (active_out->call); set_outgoing_call_state (active_out, - OUT_STATE_SUSPENDED); + os); active_out = NULL; + phone_state = PS_LISTEN; gtk_widget_hide (b_suspend); gtk_widget_hide (b_hangup); gtk_widget_show (b_call); @@ -1002,11 +1143,43 @@ GNUNET_CONVERSATION_GTK_on_pause_clicked (GtkButton *button, { /* incoming */ GNUNET_CONVERSATION_caller_suspend (active_in->caller); + phone_state = PS_LISTEN; + is = active_in->state; + switch (active_in->state) + { + case IN_STATE_NONE: + GNUNET_assert (0); + break; + case IN_STATE_RINGING: + GNUNET_assert (0); + break; + case IN_STATE_CONNECTED: + is = IN_STATE_SUSPENDED_LOCAL; + break; + case IN_STATE_SUSPENDED_LOCAL: + GNUNET_assert (0); + break; + case IN_STATE_SUSPENDED_REMOTE: + is = IN_STATE_SUSPENDED_BOTH; + break; + case IN_STATE_SUSPENDED_BOTH: + GNUNET_assert (0); + break; + default: + GNUNET_assert (0); + break; + } set_incoming_call_state (active_in, - IN_STATE_SUSPENDED_LOCAL); + is); active_in = NULL; - phone_state = PS_LISTEN; - // FIXME: visibility + gtk_widget_hide (b_suspend); + gtk_widget_hide (b_hangup); + gtk_widget_show (b_call); + gtk_widget_set_sensitive (b_hangup, FALSE); + gtk_widget_set_sensitive (b_suspend, FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); + check_call_sensitivity (); + do_status (); // FIXME: logging return; } @@ -1035,8 +1208,7 @@ GNUNET_CONVERSATION_GTK_on_hangup_clicked (GtkButton *button, /* if current call is outgoing, stop it */ set_outgoing_call_state (active_out, OUT_STATE_NONE); - // FIXME: rather: remove call state! - GNUNET_CONVERSATION_call_stop (active_out->call); + destroy_out (active_out); active_out = NULL; // FIXME: logging gtk_widget_hide (b_suspend); @@ -1054,12 +1226,18 @@ GNUNET_CONVERSATION_GTK_on_hangup_clicked (GtkButton *button, /* if selected call is incoming, hang it up */ set_incoming_call_state (active_in, IN_STATE_NONE); - // FIXME: rather: remove call state! - GNUNET_CONVERSATION_caller_hang_up (active_in->caller); - phone_state = PS_LISTEN; + destroy_in (active_in); active_in = NULL; + phone_state = PS_LISTEN; + gtk_widget_hide (b_suspend); + gtk_widget_hide (b_hangup); + gtk_widget_show (b_call); + gtk_widget_set_sensitive (b_hangup, FALSE); + gtk_widget_set_sensitive (b_suspend, FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); + check_call_sensitivity (); + do_status (); // FIXME: logging - // FIXME: visibility return; } GNUNET_break (0); @@ -1077,16 +1255,18 @@ call_event_handler (void *cls, enum GNUNET_CONVERSATION_CallEventCode code) { struct OutgoingCall *oc = cls; + enum OutCallState os; set_outgoing_call_state (oc, code); switch (code) { case GNUNET_CONVERSATION_EC_CALL_RINGING: GNUNET_break (OUT_STATE_RESOLVING == oc->state); + GNUNET_break (active_out == oc); GCG_log (_("Resolved address of `%s'. Now ringing other party."), oc->peer_name); - // FIXME: use oc->rr here! - set_outgoing_call_state (oc, OUT_STATE_RINGING); + set_outgoing_call_state (oc, + OUT_STATE_RINGING); GCG_log (_("Ringing `%s'.\n"), oc->peer_name); GCG_update_status_bar (_("Ringing `%s'."), @@ -1096,6 +1276,7 @@ call_event_handler (void *cls, case GNUNET_CONVERSATION_EC_CALL_PICKED_UP: GNUNET_break (OUT_STATE_RINGING == oc->state); set_outgoing_call_state (oc, OUT_STATE_ACTIVE); + GNUNET_break (active_out == oc); gtk_widget_set_sensitive (b_suspend, TRUE); GCG_log (_("Connection established to `%s'."), oc->peer_name); @@ -1105,12 +1286,14 @@ call_event_handler (void *cls, break; case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL: GNUNET_break (OUT_STATE_RESOLVING == oc->state); - set_outgoing_call_state (oc, OUT_STATE_NONE); - // FIXME: rather: remove from list! + GNUNET_break (active_out == oc); + set_outgoing_call_state (oc, + OUT_STATE_NONE); + oc->call = NULL; + destroy_out (oc); + active_out = NULL; GCG_log (_("Failed to resolve %s in current zone."), oc->peer_name); - GNUNET_free (oc); - active_out = NULL; gtk_widget_hide (b_suspend); gtk_widget_hide (b_hangup); gtk_widget_show (b_call); @@ -1122,8 +1305,9 @@ call_event_handler (void *cls, case GNUNET_CONVERSATION_EC_CALL_HUNG_UP: GCG_log ("%s", _("Call terminated")); set_outgoing_call_state (oc, OUT_STATE_NONE); - // FIXME: rather: remove from list! - GNUNET_free (oc); + GNUNET_break (active_out == oc); + oc->call = NULL; + destroy_out (oc); active_out = NULL; gtk_widget_hide (b_suspend); gtk_widget_hide (b_hangup); @@ -1135,42 +1319,93 @@ call_event_handler (void *cls, do_status (); break; case GNUNET_CONVERSATION_EC_CALL_SUSPENDED: - GNUNET_break (OUT_STATE_ACTIVE == oc->state); - set_outgoing_call_state (oc, OUT_STATE_SUSPENDED); + os = oc->state; + switch (oc->state) + { + case OUT_STATE_NONE: + GNUNET_assert (0); + break; + case OUT_STATE_RESOLVING: + GNUNET_assert (0); + break; + case OUT_STATE_RINGING: + GNUNET_assert (0); + break; + case OUT_STATE_ACTIVE: + os = OUT_STATE_SUSPENDED_REMOTE; + break; + case OUT_STATE_SUSPENDED_LOCAL: + os = OUT_STATE_SUSPENDED_BOTH; + break; + case OUT_STATE_SUSPENDED_REMOTE: + GNUNET_assert (0); + break; + case OUT_STATE_SUSPENDED_BOTH: + GNUNET_assert (0); + break; + default: + GNUNET_assert (0); + break; + } + set_outgoing_call_state (oc, os); GCG_log (_("Connection to `%s' suspended (by other user)\n"), oc->peer_name); - active_out = NULL; - gtk_widget_hide (b_suspend); - gtk_widget_hide (b_hangup); - gtk_widget_show (b_call); - gtk_widget_set_sensitive (b_hangup, FALSE); - gtk_widget_set_sensitive (b_suspend, FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (address_entry), TRUE); - check_call_sensitivity (); do_status (); break; case GNUNET_CONVERSATION_EC_CALL_RESUMED: - GNUNET_break (OUT_STATE_ACTIVE == oc->state); - GCG_log (_("Connection to `%s' resumed\n"), + os = oc->state; + switch (oc->state) + { + case OUT_STATE_NONE: + GNUNET_assert (0); + break; + case OUT_STATE_RESOLVING: + GNUNET_assert (0); + break; + case OUT_STATE_RINGING: + GNUNET_assert (0); + break; + case OUT_STATE_ACTIVE: + GNUNET_assert (0); + break; + case OUT_STATE_SUSPENDED_LOCAL: + GNUNET_assert (0); + break; + case OUT_STATE_SUSPENDED_REMOTE: + os = OUT_STATE_ACTIVE; + break; + case OUT_STATE_SUSPENDED_BOTH: + os = OUT_STATE_SUSPENDED_LOCAL; + break; + default: + GNUNET_assert (0); + break; + } + GCG_log (_("Connection to `%s' resumed by remote\n"), oc->peer_name); - GCG_update_status_bar (_("Talking to `%s'."), - oc->peer_name); - GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-active"); - active_out = oc; - set_outgoing_call_state (oc, OUT_STATE_ACTIVE); - gtk_widget_show (b_suspend); - gtk_widget_show (b_hangup); - gtk_widget_hide (b_call); - gtk_widget_set_sensitive (b_hangup, TRUE); - gtk_widget_set_sensitive (b_suspend, TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (address_entry), FALSE); + set_outgoing_call_state (oc, os); + if (OUT_STATE_ACTIVE == os) + { + GCG_update_status_bar (_("Talking to `%s'."), + oc->peer_name); + GCG_set_status_icon ("gnunet-conversation-gtk-tray-call-active"); + GNUNET_break (active_out == oc); + gtk_widget_show (b_suspend); + gtk_widget_show (b_hangup); + gtk_widget_hide (b_call); + gtk_widget_set_sensitive (b_hangup, TRUE); + gtk_widget_set_sensitive (b_suspend, TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (address_entry), FALSE); + } break; case GNUNET_CONVERSATION_EC_CALL_ERROR: GCG_log ("GNUNET_CONVERSATION_EC_CALL_ERROR %s", oc->peer_name); set_outgoing_call_state (oc, OUT_STATE_NONE); - // FIXME: rather: remove from list! - active_out = NULL; + oc->call = NULL; + if (active_out == oc) + active_out = NULL; + destroy_out (oc); gtk_widget_hide (b_suspend); gtk_widget_hide (b_hangup); gtk_widget_show (b_call); @@ -1218,6 +1453,13 @@ GSC_PHONE_make_call (const char *arg) arg); return; } + if (NULL != active_in) + { + GCG_log (_("You are on the phone with `%s', suspend or hang up before trying to call `%s'!\n"), + active_in->caller_id, + arg); + return; + } switch (phone_state) { case PS_LOOKUP_EGO: -- cgit v1.2.3