Implemented rest of status plugin, only external networking script is still missing
authorGregor Riepl <onitake@gmail.com>
Thu, 5 Aug 2010 13:23:06 +0000 (15:23 +0200)
committerGregor Riepl <onitake@gmail.com>
Thu, 5 Aug 2010 13:23:06 +0000 (15:23 +0200)
hal.c
hal.h
net.c
net.h
plugin.c
plugin.h
util.c
util.h

diff --git a/hal.c b/hal.c
index 05a83de..ff8eb57 100644 (file)
--- a/hal.c
+++ b/hal.c
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <string.h>
 #include "hal.h"
+#include "net.h"
+#include "plugin.h"
 
 static const char *USBDEV_PATH = "/org/freedesktop/Hal/devices/usb_device_1d6b_2_musb_hdrc";
-static const char *USBNET_MODULE = "g_ether";
 
 static void mtetherd_hal_device_condition(LibHalContext *ctx, const char *udi, const char *condition, const char *detail) {
        MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(libhal_ctx_get_user_data(ctx));
@@ -31,7 +33,8 @@ static void mtetherd_hal_device_condition(LibHalContext *ctx, const char *udi, c
                //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Got HAL condition %s on %s: %s", condition, udi, detail);
                if (strcmp("ButtonPressed", condition) == 0) {
                        if (strcmp(USBDEV_PATH, udi) == 0) {
-                               mtetherd_status_plugin_usb_plugged_show(plugin);
+                               //mtetherd_status_plugin_usb_plugged_show(plugin);
+                               mtetherd_status_plugin_usb_plugged(plugin);
                        }
                }
        }
@@ -42,10 +45,22 @@ static void mtetherd_hal_device_added(LibHalContext *ctx, const char *udi) {
        
        if (plugin) {
                g_message("Got HAL device added on %s", udi);
-               if (strcmp(USBDEV_PATH, udi) == 0) {
-                       plugin->priv->net_on = TRUE;
-                       enable_button_set_text(plugin->priv->enable_button, plugin->priv->net_on);
+               DBusError derr;
+               dbus_error_init(&derr);
+               char *interface = libhal_device_get_property_string(plugin->hal_context, udi, "net.interface", &derr);
+               if (dbus_error_is_set(&derr)) {
+                       g_warning("Error getting interface name of %s (%s): %s", udi, derr.name, derr.message);
+                       dbus_error_free(&derr);
+               }
+               if (interface) {
+                       MTetherDDevice *device = mtetherd_device_new(interface, udi);
+                       if (device) {
+                               mtetherd_status_plugin_device_added(plugin, device);
+                       }
+                       libhal_free_string(interface);
                }
+               //plugin->priv->net_on = TRUE;
+               //enable_button_set_text(plugin->priv->enable_button, plugin->priv->net_on);
        }
 }
 
@@ -54,17 +69,14 @@ static void mtetherd_hal_device_removed(LibHalContext *ctx, const char *udi) {
        
        if (plugin) {
                g_message("Got HAL device added on %s", udi);
-               if (strcmp(USBDEV_PATH, udi) == 0) {
-                       plugin->priv->net_on = FALSE;
-                       enable_button_set_text(plugin->priv->enable_button, plugin->priv->net_on);
-               }
+               mtetherd_status_plugin_device_removed(plugin, udi);
+               //plugin->priv->net_on = FALSE;
+               //enable_button_set_text(plugin->priv->enable_button, plugin->priv->net_on);
        }
 }
 
 gboolean mtetherd_hal_init(MTetherDStatusPlugin *plugin) {
        if (plugin) {
-               plugin->devices = NULL;
-               
                GError *err = NULL;
                plugin->dbus_connection = hd_status_plugin_item_get_dbus_g_connection(HD_STATUS_PLUGIN_ITEM(plugin), DBUS_BUS_SYSTEM, &err);
                if (err) {
@@ -73,7 +85,7 @@ gboolean mtetherd_hal_init(MTetherDStatusPlugin *plugin) {
                        err = NULL;
                        return FALSE;
                } else {
-                       g_message("Got DBUS Glib connection: %p", plugin->priv->dbus_connection);
+                       g_message("Got DBUS Glib connection: %p", plugin->dbus_connection);
                }
                if (plugin->dbus_connection) {
                        plugin->hal_context = libhal_ctx_new();
@@ -100,7 +112,7 @@ gboolean mtetherd_hal_init(MTetherDStatusPlugin *plugin) {
                                                } else {
                                                        g_warning("Error initializing HAL context: unknown error");
                                                }
-                                               libhal_ctx_free(plugin->priv->hal_context);
+                                               libhal_ctx_free(plugin->hal_context);
                                                plugin->hal_context = NULL;
                                                return FALSE;
                                        }
@@ -130,10 +142,6 @@ void mtetherd_hal_finalize(MTetherDStatusPlugin *plugin) {
                if (plugin->dbus_connection) {
                        dbus_g_connection_unref(plugin->dbus_connection);
                }
-               if (plugin->devices) {
-                       g_list_foreach(plugin->devices, (GFunc) g_object_unref);
-                       g_list_free(plugin->devices);
-               }
        }
 }
 
@@ -150,15 +158,17 @@ void mtetherd_hal_device_scan(MTetherDStatusPlugin *plugin) {
                if (udis) {
                        int i;
                        for (i = 0; i < ndevices; i++) {
-                               char *device = libhal_device_get_property_string(plugin->hal_context, udis[i], "net.interface", &derr);
+                               char *interface = libhal_device_get_property_string(plugin->hal_context, udis[i], "net.interface", &derr);
                                if (dbus_error_is_set(&derr)) {
                                        g_warning("Error getting interface name of %s (%s): %s", udis[i], derr.name, derr.message);
                                        dbus_error_free(&derr);
                                }
-                               if (device) {
-                                       // Check if this is one of the supported devices
-                                       plugin->devices = g_list_prepend(plugin->devices, udis[i]);
-                                       libhal_free_string(device);
+                               if (interface) {
+                                       MTetherDDevice *device = mtetherd_device_new(interface, udis[i]);
+                                       if (device) {
+                                               mtetherd_status_plugin_device_added(plugin, device);
+                                       }
+                                       libhal_free_string(interface);
                                }
                        }
                        libhal_free_string_array(udis);
@@ -166,3 +176,22 @@ void mtetherd_hal_device_scan(MTetherDStatusPlugin *plugin) {
        }
 }
 
+gboolean mtetherd_usb_state(MTetherDStatusPlugin *plugin) {
+       if (plugin) {
+               if (plugin->hal_context) {
+                       DBusError derr;
+                       dbus_error_init(&derr);
+                       dbus_bool_t plugged = libhal_device_get_property_bool(plugin->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 {
+                               return plugged;
+                       }
+               }
+       }
+       return FALSE;
+}
+
+
diff --git a/hal.h b/hal.h
index 3ebccc1..ffdaeba 100644 (file)
--- a/hal.h
+++ b/hal.h
 #include <libhal.h>
 #include "plugin.h"
 
+// Initialize DBUS and HAL connection
 gboolean mtetherd_hal_init(MTetherDStatusPlugin *plugin);
+// Release resources required for HAL connection
 void mtetherd_hal_finalize(MTetherDStatusPlugin *plugin);
+// Scan the HAL network interface list and call
+// mtetherd_status_plugin_device_added() for each device
 void mtetherd_hal_device_scan(MTetherDStatusPlugin *plugin);
+// Check the USB cable state
+// Returns TRUE if plugged in, FALSE if not
+gboolean mtetherd_usb_state(MTetherDStatusPlugin *plugin);
 
 #endif //_MTETHERD_HAL_H
 
diff --git a/net.c b/net.c
index c1946d9..af1953b 100644 (file)
--- a/net.c
+++ b/net.c
@@ -26,6 +26,7 @@
 
 G_DEFINE_TYPE(MTetherDDevice, mtetherd_device, G_TYPE_OBJECT);
 
+static const guint MAX_DEVICES = 64;
 // Host order 192.168.255.0
 static const in_addr_t HOST_BASE_ADDRESS = 0xc0a8ff00;
 // Host order 255.255.255.252
@@ -75,7 +76,7 @@ static void mtetherd_device_init(MTetherDDevice *self) {
 }
 
 static void mtetherd_device_set_interface(MTetherDDevice *self, const gchar *interface) {
-       if (self) {
+       if (self && self->priv) {
                if (self->priv->interface) {
                        g_free(self->priv->interface);
                }
@@ -95,7 +96,7 @@ static void mtetherd_device_set_interface(MTetherDDevice *self, const gchar *int
 }
 
 static void mtetherd_device_set_udi(MTetherDDevice *self, const gchar *udi) {
-       if (self) {
+       if (self && self->priv) {
                if (self->priv->udi) {
                        g_free(self->priv->udi);
                }
@@ -114,7 +115,7 @@ static void mtetherd_device_set_udi(MTetherDDevice *self, const gchar *udi) {
        }
 }
 
-static void mtetherd_device_set_index(MTetherDDevice *self, guint index) {
+void mtetherd_device_set_index(MTetherDDevice *self, guint index) {
        if (self && self->priv) {
                // Maximum is 63, we need four addresses per subnet
                if (index < 64) {
@@ -126,40 +127,108 @@ static void mtetherd_device_set_index(MTetherDDevice *self, guint index) {
                        self->priv->dhcp_start = htonl(start);
                        self->priv->dhcp_end = htonl(addr);
                } else {
-                       g_warning("Invalid subnet index: %u (0..63 expected)", index);
+                       g_warning("Invalid subnet index: %u (0..%u expected)", index, MAX_DEVICES - 1);
                }
        }
 }
 
-MTetherDDevice *mtetherd_device_new(const gchar *interface, const gchar *udi, guint index) {
+MTetherDDevice *mtetherd_device_new(const gchar *interface, const gchar *udi) {
        MTetherDDevice *self = MTETHERD_DEVICE(g_object_new(TYPE_MTETHERD_DEVICE, NULL));
 
        if (self && self->priv) {
                mtetherd_device_set_interface(self, interface);
                mtetherd_device_set_udi(self, udi);
-               mtetherd_device_set_index(self, index);
        }
        
        return self;
 }
 
-static gint mtetherd_device_find_udi(gconstpointer a, gconstpointer b) {
-       const MTetherDDevice *self = MTETHERD_DEVICE(a);
-       const gchar *udi = (const gchar *) b;
-       
-       if (self && udi) {
-               if (g_strcmp0(self->priv->udi, udi) == 0) {
-                       return 0;
+const gchar *mtetherd_device_get_interface(MTetherDDevice *self) {
+       if (self && self->priv) {
+               return self->priv->interface;
+       }
+       return NULL;
+}
+
+static gint mtetherd_device_list_find_index(gpointer *array, const gchar *udi) {
+       guint i;
+       for (i = 0; i < MAX_DEVICES; i++) {
+               MTetherDDevice *device = MTETHERD_DEVICE(array[i]);
+               if (device && device->priv) {
+                       if (g_strcmp0(device->priv->udi, udi) == 0) {
+                               return i;
+                       }
                }
        }
        return -1;
 }
 
-MTetherDDevice *mtetherd_device_find(GList *list, const gchar *udi) {
-       GList *entry = g_list_find_custom(list, udi, mtetherd_device_find_udi);
-       if (entry) {
-               return MTETHERD_DEVICE(entry->data);
+gpointer mtetherd_device_list_new() {
+       return g_malloc0(sizeof(gpointer) * MAX_DEVICES);
+}
+
+void mtetherd_device_list_free(gpointer list) {
+       if (list) {
+               gpointer *array = (gpointer *) list;
+               
+               guint i;
+               for (i = 0; i < MAX_DEVICES; i++) {
+                       if (array[i]) {
+                               g_object_unref(G_OBJECT(array[i]));
+                       }
+               }
+               g_free(array);
+       }
+}
+
+MTetherDDevice *mtetherd_device_list_find(gpointer list, const gchar *udi) {
+       if (list) {
+               gpointer *array = (gpointer *) list;
+       
+               gint index = mtetherd_device_list_find_index(array, udi);
+               if (index >= 0) {
+                       return array[index];
+               }
        }
        return NULL;
 }
 
+gboolean mtetherd_device_list_add(gpointer list, MTetherDDevice *device) {
+       if (list) {
+               gpointer *array = (gpointer *) list;
+               
+               guint i;
+               for (i = 0; i < MAX_DEVICES; i++) {
+                       if (!array[i]) {
+                               array[i] = (gpointer) device;
+                               return TRUE;
+                       }
+               }
+       }
+       return FALSE;
+}
+
+gboolean mtetherd_device_list_remove(gpointer list, const gchar *udi) {
+       if (list) {
+               gpointer *array = (gpointer *) list;
+               
+               gint index = mtetherd_device_list_find_index(array, udi);
+               if (index >= 0) {
+                       g_object_unref(G_OBJECT(array[index]));
+                       array[index] = NULL;
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+gboolean mtetherd_device_ok(const gchar *interface) {
+       if (strncmp("usb", interface, sizeof("usb")) == 0) {
+               return TRUE;
+       }
+       if (strncmp("bnep", interface, sizeof("bnep")) == 0) {
+               return TRUE;
+       }
+       return FALSE;
+}
+
diff --git a/net.h b/net.h
index 844bb92..2507143 100644 (file)
--- a/net.h
+++ b/net.h
@@ -48,8 +48,37 @@ struct _MTetherDDevice {
 
 GType mtetherd_device_get_type();
 
-MTetherDDevice *mtetherd_device_new(const gchar *interface, const gchar *udi, guint index);
-MTetherDDevice *mtetherd_device_find(GList *list, const gchar *udi);
+// Allocates a new device object
+// This object doesn't have addresses assigned yet
+// Add it to a device list or use mtetherd_device_set_index to construct them
+MTetherDDevice *mtetherd_device_new(const gchar *interface, const gchar *udi);
+// Constructs IP address and DHCP ranges from the given index
+// 192.168.255.0/24 is the supernet for all devices,
+// each gets a /30 from that range, depending on the index
+// Example: index = 32 -> subnet = 192.168.255.200/30
+// The host address is always 1, and the DHCP range goes from 1 to 2
+void mtetherd_device_set_index(MTetherDDevice *self, guint index);
+// Returns the interface name
+const gchar *mtetherd_device_get_interface(MTetherDDevice *self);
+
+// Device list functions
+// The list is constrained to 64 entries
+gpointer mtetherd_device_list_new();
+// Unrefs all devices contained within and frees the list
+void mtetherd_device_list_free(gpointer list);
+// Scans the list for an udi and returns the first device found
+MTetherDDevice *mtetherd_device_list_find(gpointer list, const gchar *udi);
+// Adds a device to the next free position
+// This transfers ownership of the object to the list
+// Returns FALSE if the list is already full
+gboolean mtetherd_device_list_add(gpointer list, MTetherDDevice *device);
+// Removes and deallocates the first device with the given UDI from the list
+// Returns FALSE if the UDI is not found
+gboolean mtetherd_device_list_remove(gpointer list, const gchar *udi);
+
+// Returns true if the device is acceptable for tethering
+// Currently checks if the interface name starts with usb or bnep
+gboolean mtetherd_device_ok(const gchar *interface);
 
 G_END_DECLS
 
index e432e0e..2fb47d6 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,11 @@ struct _MTetherDStatusPluginPrivate {
 #define SBIN_DIR "/usr/sbin"
 #endif
 
+static const char *USBNET_MODULE = "g_ether";
+// 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 +67,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 +152,66 @@ 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;
+       }
+       
+       // Unnecessary, we scan the network device name instead
+       //plugin->priv->usbnet_loaded = mtetherd_scan_modules(USBNET_MODULE);
+       
+       // 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)) {
+                               g_warning("Error adding network interface to list: Maximum number of devices exceeded");
+                       } else {
+                               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);
+                               // TODO: Launch network setup script
+                       }
+               }
+       }
+}
+
+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);
+                       // TODO: Launch network teardown 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);
 }
 
index ec81da2..a7b8f40 100644 (file)
--- a/plugin.h
+++ b/plugin.h
@@ -21,7 +21,9 @@
 #ifndef _MTETHERD_STATUS_H
 #define _MTETHERD_STATUS_H
 
+#include <libhal.h>
 #include <libhildondesktop/libhildondesktop.h>
+#include "net.h"
 
 G_BEGIN_DECLS
 
@@ -49,6 +51,13 @@ struct _MTetherDStatusPlugin {
 
 GType mtetherd_status_plugin_get_type();
 
+// Network device creation callback
+void mtetherd_status_plugin_device_added(MTetherDStatusPlugin *plugin, MTetherDDevice *device);
+// Network device removal callback
+void mtetherd_status_plugin_device_removed(MTetherDStatusPlugin *plugin, const gchar *udi);
+// Signals a USB connection or disconnection event
+void mtetherd_status_plugin_usb_plugged(MTetherDStatusPlugin *plugin);
+
 G_END_DECLS
 
 #endif //_MTETHERD_STATUS_H
diff --git a/util.c b/util.c
index cc3966d..4cb0928 100644 (file)
--- a/util.c
+++ b/util.c
@@ -18,8 +18,9 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <stdlib.h>
 #include <stdio.h>
-#include <string.h>
+#include <unistd.h>
 #include <glib.h>
 
 static const char *MODULE_LIST = "/proc/modules";
@@ -35,7 +36,7 @@ gboolean mtetherd_scan_modules(const char *module) {
        char *line = NULL;
        while (!found && getline(&line, NULL, fp) != -1) {
                g_debug("Checking if '%s' starts with %s...", line, module);
-               if (strcmp(line, module, strlen(module)) == 0) {
+               if (g_str_has_prefix(line, module) == 0) {
                        g_message("Found %s", module);
                        found = TRUE;
                }
@@ -47,16 +48,6 @@ gboolean mtetherd_scan_modules(const char *module) {
 }
 
 gboolean mtetherd_launch_script(const char *command[]) {
-/*
-       const char *arg;
-       if (enable) {
-               arg = SBIN_DIR "mtetherd-usbnet-enable.sh";
-       } else {
-               arg = SBIN_DIR "mtetherd-usbnet-disable.sh";
-       }
-       g_debug("Launching %s", arg);
-       const char *command[] = { "/usr/bin/sudo", arg, NULL };
-*/
        pid_t pid = fork();
        if (pid == 0) {
                if (execv(command[0], (char **const) command) == -1) {
diff --git a/util.h b/util.h
index 118a5d1..8295c66 100644 (file)
--- a/util.h
+++ b/util.h
 
 #include <glib.h>
 
+// Opens /proc/modules and scans for g_ether
+// Returns TRUE if found, FALSEĀ if not
 gboolean mtetherd_scan_modules(const char *module);
+// Launch an external script in the background
+// command[] is a NULL-terminated list of arguments,
+// command[0] is the full path of the script to execute
+// Returns FALSE if fork() failed
 gboolean mtetherd_launch_script(const char *command[]);
 
 #endif //_MTETHERD_UTIL_H