From: Tobias Brunner Date: Tue, 21 Sep 2010 13:35:27 +0000 (+0200) Subject: Maemo: Added basic connect/disconnect functionality to frontend. X-Git-Tag: 4.5.0~55 X-Git-Url: https://git.strongswan.org/?p=strongswan.git;a=commitdiff_plain;h=12b61b17aeb42f17dbc98a761f78c8a7e43baa8e Maemo: Added basic connect/disconnect functionality to frontend. --- diff --git a/src/frontends/maemo/src/strongswan-status.c b/src/frontends/maemo/src/strongswan-status.c index 24f2442..21ca651 100644 --- a/src/frontends/maemo/src/strongswan-status.c +++ b/src/frontends/maemo/src/strongswan-status.c @@ -32,6 +32,13 @@ #define ICON_SIZE_STATUS 18 #define ICON_SIZE_BUTTON 48 +typedef enum +{ + STATUS_DISCONNECTED, + STATUS_CONNECTING, + STATUS_CONNECTED, +} StrongswanConnectionStatus; + struct _StrongswanStatusPrivate { struct { @@ -51,6 +58,7 @@ struct _StrongswanStatusPrivate StrongswanConnections *conns; + StrongswanConnectionStatus status; gchar *current; }; @@ -60,6 +68,45 @@ HD_DEFINE_PLUGIN_MODULE_EXTENDED (StrongswanStatus, strongswan_status, \ strongswan_connections_register (G_TYPE_MODULE (plugin)); }, {}); static void +update_status_menu (StrongswanStatus *plugin) +{ + StrongswanStatusPrivate *priv = plugin->priv; + switch (priv->status) + { + case STATUS_DISCONNECTED: + { + hildon_button_set_value (HILDON_BUTTON (priv->button), + "Not connected"); + hd_status_plugin_item_set_status_area_icon ( + HD_STATUS_PLUGIN_ITEM (plugin), + priv->icons.status_open); + gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), + priv->icons.button_open); + break; + } + case STATUS_CONNECTING: + { + gchar *msg = g_strdup_printf ("Connecting to %s...", priv->current); + hildon_button_set_value (HILDON_BUTTON (priv->button), msg); + g_free (msg); + break; + } + case STATUS_CONNECTED: + { + gchar *msg = g_strdup_printf ("Connected to %s", priv->current); + hildon_button_set_value (HILDON_BUTTON (priv->button), msg); + g_free (msg); + hd_status_plugin_item_set_status_area_icon ( + HD_STATUS_PLUGIN_ITEM (plugin), + priv->icons.status_close); + gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), + priv->icons.button_close); + break; + } + } +} + +static void dialog_response (GtkDialog *dialog, gint response_id, StrongswanStatus *plugin) { StrongswanStatusPrivate *priv = plugin->priv; @@ -68,20 +115,234 @@ dialog_response (GtkDialog *dialog, gint response_id, StrongswanStatus *plugin) } static void +connect_callback (const gchar* interface, const gchar* method, + osso_rpc_t *retval, StrongswanStatus *plugin) +{ + gchar *msg = NULL; + StrongswanStatusPrivate *priv = plugin->priv; + + if (retval->type == DBUS_TYPE_STRING) + { /* unfortunately, this is the only indication that an error occured + * for asynchronous calls */ + msg = g_strdup_printf ("Failed to initiate connection: %s", + retval->value.s); + } + else if (retval->type != DBUS_TYPE_BOOLEAN) + { + msg = g_strdup_printf ("Failed to initiate connection: return type"); + } + else if (!retval->value.b) + { + msg = g_strdup_printf ("Failed to connect to %s", priv->current); + } + + if (msg) + { + /* connecting failed */ + priv->current = (g_free (priv->current), NULL); + priv->status = STATUS_DISCONNECTED; + } + else + { + msg = g_strdup_printf ("Successfully connected to %s", priv->current); + priv->status = STATUS_CONNECTED; + } + + hildon_banner_show_information (NULL, NULL, msg); + g_free (msg); + + update_status_menu (plugin); + + if (priv->dialog) + { + gtk_widget_set_sensitive (priv->box, TRUE); + hildon_gtk_window_set_progress_indicator (GTK_WINDOW (priv->dialog), 0); + + gtk_dialog_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_OK); + } +} + +static void +update_dialog_connecting (StrongswanStatus *plugin) +{ + StrongswanStatusPrivate *priv = plugin->priv; + + gtk_widget_set_sensitive (priv->box, FALSE); + hildon_gtk_window_set_progress_indicator (GTK_WINDOW (priv->dialog), 1); +} + +static void connect_clicked (HildonButton *button, StrongswanStatus *plugin) { StrongswanStatusPrivate *priv = plugin->priv; - gtk_dialog_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_OK); + + priv->current = hildon_touch_selector_get_current_text ( + HILDON_TOUCH_SELECTOR (priv->selector)); + priv->status = STATUS_CONNECTING; + update_dialog_connecting (plugin); + update_status_menu (plugin); + + StrongswanConnection *conn = strongswan_connections_get_connection ( + priv->conns, + priv->current); + if (!conn) + { /* emulate a callback call */ + osso_rpc_t retval; + retval.type = DBUS_TYPE_STRING; + retval.value.s = g_strdup ("not found"); + connect_callback (NULL, NULL, &retval, plugin); + osso_rpc_free_val (&retval); + return; + } + + /* this call on the system bus is only needed to start charon as root */ + osso_rpc_t retval; + osso_return_t result; + result = osso_rpc_run_system (priv->context, + OSSO_CHARON_SERVICE, + OSSO_CHARON_OBJECT, + OSSO_CHARON_IFACE, + "Start", + &retval, + DBUS_TYPE_INVALID); + osso_rpc_free_val (&retval); + if (result != OSSO_OK) + { + retval.type = DBUS_TYPE_STRING; + retval.value.s = g_strdup ("couldn't connect to charon"); + connect_callback (NULL, NULL, &retval, plugin); + osso_rpc_free_val (&retval); + return; + } + + gchar *c_host, *c_cert, *c_user, *c_pass; + g_object_get (conn, + "host", &c_host, + "cert", &c_cert, + "user", &c_user, + "pass", &c_pass, + NULL); + + osso_rpc_async_run (priv->context, + OSSO_CHARON_SERVICE, + OSSO_CHARON_OBJECT, + OSSO_CHARON_IFACE, + "Connect", + (osso_rpc_async_f*)connect_callback, + plugin, + DBUS_TYPE_STRING, priv->current, + DBUS_TYPE_STRING, c_host, + DBUS_TYPE_STRING, c_cert, + DBUS_TYPE_STRING, c_user, + DBUS_TYPE_STRING, c_pass, + DBUS_TYPE_INVALID); + + g_free (c_host); + g_free (c_cert); + g_free (c_user); + g_free (c_pass); } static void disconnect_clicked (HildonButton *button, StrongswanStatus *plugin) { + osso_return_t result; + osso_rpc_t retval; + gchar *msg; StrongswanStatusPrivate *priv = plugin->priv; + + gtk_widget_set_sensitive (priv->box, FALSE); + hildon_gtk_window_set_progress_indicator (GTK_WINDOW (priv->dialog), 1); + + result = osso_rpc_run_system (priv->context, + OSSO_CHARON_SERVICE, + OSSO_CHARON_OBJECT, + OSSO_CHARON_IFACE, + "Disconnect", + &retval, + DBUS_TYPE_INVALID); + + gtk_widget_set_sensitive (priv->box, TRUE); + hildon_gtk_window_set_progress_indicator (GTK_WINDOW (priv->dialog), 0); + + if (result == OSSO_OK) + { + msg = g_strdup_printf ("Successfully disconnected from %s", + priv->current); + } + else + { + msg = g_strdup_printf ("Failed to disconnect from %s", priv->current); + } + hildon_banner_show_information (NULL, NULL, msg); + g_free (msg); + + priv->current = (g_free (priv->current), NULL); + priv->status = STATUS_DISCONNECTED; + + update_status_menu (plugin); + gtk_dialog_response (GTK_DIALOG (priv->dialog), GTK_RESPONSE_OK); } static void +setup_dialog_disconnected (StrongswanStatus *plugin) +{ + StrongswanStatusPrivate *priv = plugin->priv; + + GtkWidget *vbox = GTK_DIALOG (priv->dialog)->vbox; + GtkWidget *hbox = gtk_hbox_new (FALSE, 0); + priv->box = hbox; + GtkWidget *button = hildon_picker_button_new ( + HILDON_SIZE_FINGER_HEIGHT | + HILDON_SIZE_AUTO_WIDTH, + HILDON_BUTTON_ARRANGEMENT_HORIZONTAL); + hildon_button_set_title (HILDON_BUTTON (button), "Connection:"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + + GtkWidget *selector = hildon_touch_selector_new (); + priv->selector = selector; + GtkTreeModel *model = strongswan_connections_get_model (priv->conns); + hildon_touch_selector_append_text_column ( + HILDON_TOUCH_SELECTOR (selector), + model, + TRUE); + hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button), + HILDON_TOUCH_SELECTOR (selector)); + + button = hildon_button_new_with_text ( + HILDON_SIZE_FINGER_HEIGHT | + HILDON_SIZE_AUTO_WIDTH, + HILDON_BUTTON_ARRANGEMENT_HORIZONTAL, + "Connect", NULL); + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + g_signal_connect (button, "clicked", G_CALLBACK (connect_clicked), + plugin); +} + +static void +setup_dialog_connected (StrongswanStatus *plugin) +{ + StrongswanStatusPrivate *priv = plugin->priv; + + GtkWidget *vbox = GTK_DIALOG (priv->dialog)->vbox; + GtkWidget *hbox = gtk_hbox_new (FALSE, 0); + priv->box = hbox; + GtkWidget *button = hildon_button_new_with_text ( + HILDON_SIZE_FINGER_HEIGHT | + HILDON_SIZE_AUTO_WIDTH, + HILDON_BUTTON_ARRANGEMENT_HORIZONTAL, + "Disconnect", priv->current); + hildon_button_set_style (HILDON_BUTTON (button), + HILDON_BUTTON_STYLE_PICKER); + g_signal_connect (button, "clicked", G_CALLBACK (disconnect_clicked), + plugin); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); +} + +static void button_clicked (HildonButton *button, StrongswanStatus *plugin) { StrongswanStatusPrivate *priv = plugin->priv; @@ -91,56 +352,18 @@ button_clicked (HildonButton *button, StrongswanStatus *plugin) g_signal_connect (priv->dialog, "response", G_CALLBACK (dialog_response), plugin); - GtkWidget *vbox = GTK_DIALOG (priv->dialog)->vbox; - - if (priv->current) - { - /* connected case */ - GtkWidget *hbox = gtk_hbox_new (FALSE, 0); - priv->box = hbox; - GtkWidget *button = hildon_button_new_with_text ( - HILDON_SIZE_FINGER_HEIGHT | - HILDON_SIZE_AUTO_WIDTH, - HILDON_BUTTON_ARRANGEMENT_HORIZONTAL, - "Disconnect", priv->current); - hildon_button_set_style (HILDON_BUTTON (button), - HILDON_BUTTON_STYLE_PICKER); - g_signal_connect (button, "clicked", G_CALLBACK (disconnect_clicked), - plugin); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - } - else + switch (priv->status) { - /* unconnected case */ - GtkWidget *hbox = gtk_hbox_new (FALSE, 0); - priv->box = hbox; - GtkWidget *button = hildon_picker_button_new ( - HILDON_SIZE_FINGER_HEIGHT | - HILDON_SIZE_AUTO_WIDTH, - HILDON_BUTTON_ARRANGEMENT_HORIZONTAL); - hildon_button_set_title (HILDON_BUTTON (button), "Connection:"); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - - GtkWidget *selector = hildon_touch_selector_new (); - priv->selector = selector; - GtkTreeModel *model = strongswan_connections_get_model (priv->conns); - hildon_touch_selector_append_text_column ( - HILDON_TOUCH_SELECTOR (selector), - model, - TRUE); - hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button), - HILDON_TOUCH_SELECTOR (selector)); - - button = hildon_button_new_with_text ( - HILDON_SIZE_FINGER_HEIGHT | - HILDON_SIZE_AUTO_WIDTH, - HILDON_BUTTON_ARRANGEMENT_HORIZONTAL, - "Connect", NULL); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - g_signal_connect (button, "clicked", G_CALLBACK (connect_clicked), - plugin); + case STATUS_DISCONNECTED: + setup_dialog_disconnected (plugin); + break; + case STATUS_CONNECTING: + setup_dialog_disconnected (plugin); + update_dialog_connecting (plugin); + break; + case STATUS_CONNECTED: + setup_dialog_connected (plugin); + break; } gtk_widget_show_all (priv->dialog);