Added empty network setup scripts
[mtetherd] / plugin.c
index e432e0e..a0b4d5f 100644 (file)
--- a/plugin.c
+++ b/plugin.c
 #include <sys/types.h>
 #include <gtk/gtk.h>
 #include <hildon/hildon.h>
-
 #include "plugin.h"
+#include "hal.h"
+#include "net.h"
+#include "util.h"
 
 #define MTETHERD_STATUS_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, TYPE_MTETHERD_STATUS_PLUGIN, MTetherDStatusPluginPrivate))
 
+typedef enum {
+       MTETHERD_STATUS_PLUGIN_USB_NET_UNKNOWN = 0,
+       MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED,
+       MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED,
+} MTetherDStatusPluginUsbNetState;
+
 struct _MTetherDStatusPluginPrivate {
        GtkWidget *enable_button;
-       gboolean usb_on;
-       gboolean net_on;
+       gpointer devices;
+       gboolean usb_plugged;
+       MTetherDStatusPluginUsbNetState usbnet_state;
 };
 
 #ifndef IMAGE_DIR
@@ -44,6 +53,10 @@ struct _MTetherDStatusPluginPrivate {
 #define SBIN_DIR "/usr/sbin"
 #endif
 
+// The UDI contains the MAC address and is thus unsuitable for
+// loaded status checking, so we just use the interface name
+static const char *USBNET_INTERFACE = "usb0";
+
 HD_DEFINE_PLUGIN_MODULE(MTetherDStatusPlugin, mtetherd_status_plugin, HD_TYPE_STATUS_MENU_ITEM);
 
 static void mtetherd_status_plugin_class_finalize(MTetherDStatusPluginClass *klass) { }
@@ -53,85 +66,76 @@ static void mtetherd_status_plugin_finalize(GObject *object) {
 
        MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(object);
 
-       if (plugin) {
+       if (plugin && plugin->priv) {
                mtetherd_hal_finalize(plugin);
+               mtetherd_device_list_free(plugin->priv->devices);
        }
 }
 
 static void mtetherd_status_plugin_class_init(MTetherDStatusPluginClass *klass) {
        GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
 
-       gobject_class->finalize = mtetherd_status_plugin_finalize;
-       g_type_class_add_private(klass, sizeof(MTetherDStatusPluginPrivate));
+       if (gobject_class) {
+               gobject_class->finalize = mtetherd_status_plugin_finalize;
+               g_type_class_add_private(klass, sizeof(MTetherDStatusPluginPrivate));
+       }
 }
 
-static void enable_button_set_text(GtkWidget *button, gboolean enabled) {
-       if (enabled) {
-               hildon_button_set_text(HILDON_BUTTON(button), "Toggle USB Networking", "Enabled");
-       } else {
-               hildon_button_set_text(HILDON_BUTTON(button), "Toggle USB Networking", "Disabled");
+static void mtetherd_status_plugin_enable_button_set_text(MTetherDStatusPlugin *plugin) {
+       if (plugin && plugin->priv && plugin->priv->enable_button) {
+               switch (plugin->priv->usbnet_state) {
+                       case MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED:
+                               hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "Toggle USB Networking", "Enabled");
+                               break;
+                       case MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED:
+                               hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "Toggle USB Networking", "Disabled");
+                               break;
+                       default:
+                               hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "Toggle USB Networking", "Unknown");
+                               break;
+                       }
        }
 }
 
-static void enable_button_clicked(GtkWidget *button, gpointer data) {
+static void mtetherd_status_plugin_enable_button_clicked(GtkWidget *button, gpointer data) {
        MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(data);
 
        if (plugin && plugin->priv && button == plugin->priv->enable_button) {
-               if (plugin->priv->net_on) {
-                       if (!launch_usbnet_script(FALSE)) {
-                               g_error("Error starting USB networking");
-                       }
-               } else {
-                       if (!launch_usbnet_script(TRUE)) {
-                               g_error("Error starting USB networking");
+               const char *arg;
+               switch (plugin->priv->usbnet_state) {
+                       case MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED:
+                               arg = SBIN_DIR "mtetherd-usbnet-disable.sh";
+                               break;
+                       case MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED:
+                               arg = SBIN_DIR "mtetherd-usbnet-enable.sh";
+                               break;
+                       default:
+                               arg = NULL;
+                               break;
+               }
+               if (arg) {
+                       g_debug("Launching %s", arg);
+                       const char *command[] = { "/usr/bin/sudo", arg, NULL };
+                       if (!mtetherd_launch_script(command)) {
+                               g_error("Error launching USB networking script");
                        }
                }
        }
 }
 
 static void mtetherd_status_plugin_usb_plugged_show(MTetherDStatusPlugin *plugin) {
-       if (plugin) {
-               if (plugin->priv && plugin->priv->hal_context) {
-                       DBusError derr;
-                       dbus_error_init(&derr);
-                       dbus_bool_t plugged = libhal_device_get_property_bool(plugin->priv->hal_context, USBDEV_PATH, "button.state.value", &derr);
-                       if (dbus_error_is_set(&derr)) {
-                               g_warning("Error getting USB plugged status (%s): %s", derr.name, derr.message);
-                               hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Error getting USB plugged status (%s): %s", derr.name, derr.message);
-                               dbus_error_free(&derr);
-                       } else {
-                               plugin->priv->usb_on = plugged;
-                               if (plugin->priv->usb_on) {
-                                       gtk_widget_show(GTK_WIDGET(plugin));
-                               } else {
-                                       gtk_widget_hide(GTK_WIDGET(plugin));
-                               }
-                       }
+       if (plugin && plugin->priv) {
+               if (plugin->priv->usb_plugged) {
+                       gtk_widget_show(GTK_WIDGET(plugin));
                } else {
-                       // DEBUG
-                       //gtk_widget_show(GTK_WIDGET(plugin));
+                       gtk_widget_hide(GTK_WIDGET(plugin));
                }
        }
 }
 
-static void mtetherd_status_plugin_mapped(GtkWidget *widget, gpointer data) {
-       hildon_banner_show_informationf(widget, NULL, "Plugin mapped");
-       MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(widget);
-       
-       if (plugin && plugin->priv) {
-               plugin->priv->net_on = get_usbnet_enabled(plugin);
-               if (plugin->priv->enable_button) {
-                       enable_button_set_text(plugin->priv->enable_button, plugin->priv->net_on);
-               }
-       }
-}
-
 static void mtetherd_status_plugin_init(MTetherDStatusPlugin *plugin) {
        plugin->priv = MTETHERD_STATUS_PLUGIN_GET_PRIVATE(plugin);
 
-       plugin->priv->usb_on = FALSE;
-       plugin->priv->net_on = FALSE;
-       
        plugin->priv->enable_button = hildon_button_new(HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
        if (plugin->priv->enable_button) {
                GError *err = NULL;
@@ -147,17 +151,79 @@ static void mtetherd_status_plugin_init(MTetherDStatusPlugin *plugin) {
                        hildon_button_set_image_position(HILDON_BUTTON(plugin->priv->enable_button), GTK_POS_LEFT);
                        g_object_unref(icon);
                }
-               gboolean enabled = get_usbnet_enabled(plugin);
-               enable_button_set_text(plugin->priv->enable_button, enabled);
-               g_signal_connect(plugin->priv->enable_button, "clicked", G_CALLBACK(enable_button_clicked), plugin);
+               mtetherd_status_plugin_enable_button_set_text(plugin);
+               g_signal_connect(plugin->priv->enable_button, "clicked", G_CALLBACK(mtetherd_status_plugin_enable_button_clicked), plugin);
                gtk_container_add(GTK_CONTAINER(plugin), plugin->priv->enable_button);
                gtk_widget_show_all(plugin->priv->enable_button);
        }
 
-       mtetherd_hal_init(plugin);
-
+       if (mtetherd_hal_init(plugin)) {
+               plugin->priv->usb_plugged = mtetherd_usb_state(plugin);
+               plugin->priv->devices = mtetherd_device_list_new();
+               mtetherd_hal_device_scan(plugin);
+       } else {
+               plugin->priv->usb_plugged = FALSE;
+       }
+       
+       // Update the button status
        mtetherd_status_plugin_usb_plugged_show(plugin);
 
-       //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Initialized mtetherd status plugin");
+       hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Initialized mtetherd status plugin");
+}
+
+void mtetherd_status_plugin_device_added(MTetherDStatusPlugin *plugin, MTetherDDevice *device) {
+       if (plugin && plugin->priv) {
+               const gchar *interface = mtetherd_device_get_interface(device);
+               if (mtetherd_device_ok(interface)) {
+                       if (mtetherd_device_list_add(plugin->priv->devices, device)) {
+                               if (g_strcmp0(USBNET_INTERFACE, interface) == 0) {
+                                       plugin->priv->usbnet_state = MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED;
+                                       mtetherd_status_plugin_enable_button_set_text(plugin);
+                               }
+                               hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Starting network on %s", interface);
+                               g_debug("Launching " SBIN_DIR "/mtetherd-net-setup.sh");
+                               gchar *addr = mtetherd_device_get_addr(device);
+                               gchar *netmask = mtetherd_device_get_netmask(device);
+                               gchar *dhcp_start = mtetherd_device_get_dhcp_start(device);
+                               gchar *dhcp_end = mtetherd_device_get_dhcp_end(device);
+                               const char *command[] = { "/usr/bin/sudo", SBIN_DIR "/mtetherd-net-setup.sh", interface, addr, netmask, dhcp_start, dhcp_end, NULL };
+                               if (!mtetherd_launch_script(command)) {
+                                       g_warning("Error launching USB networking setup script");
+                               }
+                               g_free(addr);
+                               g_free(netmask);
+                               g_free(dhcp_start);
+                               g_free(dhcp_end);
+                       } else {
+                               g_warning("Error adding network interface to list: Maximum number of devices exceeded");
+                       }
+               }
+       }
+}
+
+void mtetherd_status_plugin_device_removed(MTetherDStatusPlugin *plugin, const gchar *udi) {
+       if (plugin && plugin->priv) {
+               MTetherDDevice *device = mtetherd_device_list_find(plugin->priv->devices, udi);
+               if (device) {
+                       const gchar *interface = mtetherd_device_get_interface(device);
+                       if (g_strcmp0(USBNET_INTERFACE, interface) == 0) {
+                               plugin->priv->usbnet_state = MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED;
+                               mtetherd_status_plugin_enable_button_set_text(plugin);
+                       }
+                       hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Shutting down network on %s", interface);
+                       g_debug("Launching " SBIN_DIR "/mtetherd-net-shutdown.sh");
+                       const char *command[] = { "/usr/bin/sudo", SBIN_DIR "/mtetherd-net-shutdown.sh", interface, NULL };
+                       if (!mtetherd_launch_script(command)) {
+                               g_warning("Error launching USB networking shutdown script");
+                       }
+               }
+               if (!mtetherd_device_list_remove(plugin->priv->devices, udi)) {
+                       g_warning("Error removing network interface from list: Not found");
+               }
+       }
+}
+
+void mtetherd_status_plugin_usb_plugged(MTetherDStatusPlugin *plugin) {
+       mtetherd_status_plugin_usb_plugged_show(plugin);
 }