#define ICON_SIZE_STATUS 18
#define ICON_SIZE_BUTTON 48
+typedef enum
+{
+ STATUS_DISCONNECTED,
+ STATUS_CONNECTING,
+ STATUS_CONNECTED,
+} StrongswanConnectionStatus;
+
struct _StrongswanStatusPrivate
{
struct {
StrongswanConnections *conns;
+ StrongswanConnectionStatus status;
gchar *current;
};
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;
}
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;
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);