#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
+#include <glib/gprintf.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))
struct _MTetherDStatusPluginPrivate {
GtkWidget *enable_button;
- gboolean usb_on;
- gboolean net_on;
+ gpointer devices;
+ gboolean usb_plugged;
+ gboolean usbnet_state;
+ FILE *log_fp;
+ guint log_handler;
};
#ifndef IMAGE_DIR
#define IMAGE_DIR "/usr/share/pixmaps"
#endif
+#ifndef BIN_DIR
+#define BIN_DIR "/usr/bin"
+#endif
#ifndef SBIN_DIR
#define SBIN_DIR "/usr/sbin"
#endif
+#ifndef TMP_DIR
+#define TMP_DIR "/tmp"
+#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";
+static const char *WAN_INTERFACE = "gprs0";
+const char *MTETHERD_LOG_DOMAIN = "mtetherd";
HD_DEFINE_PLUGIN_MODULE(MTetherDStatusPlugin, mtetherd_status_plugin, HD_TYPE_STATUS_MENU_ITEM);
static void mtetherd_status_plugin_class_finalize(MTetherDStatusPluginClass *klass) { }
static void mtetherd_status_plugin_finalize(GObject *object) {
- g_message("Destroying mtetherd status plugin");
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "Destroying mtetherd status plugin");
MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(object);
- if (plugin) {
+ if (plugin && plugin->priv) {
mtetherd_hal_finalize(plugin);
+ mtetherd_device_list_free(plugin->priv->devices);
+ if (plugin->priv->log_fp) {
+ g_log_remove_handler(MTETHERD_LOG_DOMAIN, plugin->priv->log_handler);
+ fclose(plugin->priv->log_fp);
+ }
}
}
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) {
+ if (plugin->priv->usbnet_state) {
+ hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "USB networking", "Enabled");
+ } else {
+ hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "USB networking", "Disabled");
+ }
}
}
-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");
- }
+ const char *arg;
+ if (plugin->priv->usbnet_state) {
+ arg = SBIN_DIR "/mtetherd-usbnet-disable.sh";
} else {
- if (!launch_usbnet_script(TRUE)) {
- g_error("Error starting USB networking");
+ arg = SBIN_DIR "/mtetherd-usbnet-enable.sh";
+ }
+ if (arg) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", arg);
+ const char *command[] = { BIN_DIR "/sudo", arg, NULL };
+ if (!mtetherd_launch_script(command)) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "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_log(const gchar *domain, GLogLevelFlags level, const gchar *message, gpointer data) {
+ MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(data);
+
+ if (plugin && plugin->priv && plugin->priv->log_fp) {
+ char *levelstr;
+ switch (level) {
+ case G_LOG_LEVEL_ERROR:
+ levelstr = "** Error **";
+ break;
+ case G_LOG_LEVEL_CRITICAL:
+ levelstr = "** CRITICAL **";
+ break;
+ case G_LOG_LEVEL_WARNING:
+ levelstr = "** Warning **";
+ break;
+ case G_LOG_LEVEL_MESSAGE:
+ levelstr = "-- Notice --";
+ break;
+ case G_LOG_LEVEL_INFO:
+ levelstr = "-- Info --";
+ break;
+ case G_LOG_LEVEL_DEBUG:
+ levelstr = "(Debug)";
+ break;
+ case G_LOG_FLAG_RECURSION:
+ levelstr = "** RECURSION **";
+ break;
+ case G_LOG_FLAG_FATAL:
+ levelstr = "** FATAL **";
+ break;
+ default:
+ levelstr = "";
+ break;
+ }
+ g_fprintf(plugin->priv->log_fp, "mtetherd: %s %s\n", levelstr, message);
+ fflush(plugin->priv->log_fp);
}
}
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;
+ if (plugin->priv) {
+ plugin->priv->log_fp = fopen(TMP_DIR "/mtetherd-status.log", "a");
+ if (plugin->priv->log_fp) {
+ plugin->priv->log_handler = g_log_set_handler(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_MASK, mtetherd_status_plugin_log, plugin);
+ }
+
+ plugin->priv->usbnet_state = 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;
+ GdkPixbuf *icon = gdk_pixbuf_new_from_file(IMAGE_DIR "/mtetherd-net-icon.png", &err);
+ if (err) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Can't load mtetherd icon: %s", err->message);
+ g_error_free(err);
+ err = NULL;
+ }
+ if (icon) {
+ GtkWidget *image = gtk_image_new_from_pixbuf(icon);
+ hildon_button_set_image(HILDON_BUTTON(plugin->priv->enable_button), image);
+ hildon_button_set_image_position(HILDON_BUTTON(plugin->priv->enable_button), GTK_POS_LEFT);
+ gtk_button_set_alignment(GTK_BUTTON(plugin->priv->enable_button), 0, 0.5);
+ g_object_unref(icon);
+ }
+ 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);
+ }
- 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;
- GdkPixbuf *icon = gdk_pixbuf_new_from_file(IMAGE_DIR "/mtetherd-net-icon.png", &err);
- if (err) {
- g_warning("Can't load mtetherd icon: %s", err->message);
- g_error_free(err);
- err = NULL;
+ if (mtetherd_hal_init(plugin)) {
+ plugin->priv->devices = mtetherd_device_list_new();
+ mtetherd_hal_device_scan(plugin);
+ // Set initial button status
+ mtetherd_status_plugin_usb_plugged(plugin);
+ } else {
+ // For debugging
+ plugin->priv->usb_plugged = TRUE;
+ mtetherd_status_plugin_usb_plugged_show(plugin);
}
- if (icon) {
- GtkWidget *image = gtk_image_new_from_pixbuf(icon);
- hildon_button_set_image(HILDON_BUTTON(plugin->priv->enable_button), image);
- hildon_button_set_image_position(HILDON_BUTTON(plugin->priv->enable_button), GTK_POS_LEFT);
- g_object_unref(icon);
+ }
+
+ //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Initialized mtetherd status plugin");
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "Initialized mtetherd status plugin");
+}
+
+void mtetherd_status_plugin_device_added(MTetherDStatusPlugin *plugin, MTetherDDevice *device) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "mtetherd_status_plugin_device_added(%p, %p)", plugin, device);
+ gboolean added = FALSE;
+ if (plugin && plugin->priv) {
+ const gchar *interface = mtetherd_device_get_interface(device);
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "interface=%s", interface);
+ if (mtetherd_device_ok(interface)) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "ok");
+ if (mtetherd_device_list_add(plugin->priv->devices, device)) {
+ if (g_strcmp0(USBNET_INTERFACE, interface) == 0) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "is USB");
+ plugin->priv->usbnet_state = TRUE;
+ mtetherd_status_plugin_enable_button_set_text(plugin);
+ }
+ hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Starting network on %s", interface);
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", 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);
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "interface=%s wan=%s addr=%s netmask=%s dhcp_start=%s dhcp_end=%s", interface, WAN_INTERFACE, addr, netmask, dhcp_start, dhcp_end);
+ const char *command[] = { BIN_DIR "/sudo", SBIN_DIR "/mtetherd-net-setup.sh", interface, WAN_INTERFACE, addr, netmask, dhcp_start, dhcp_end, NULL };
+ if (!mtetherd_launch_script(command)) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error launching USB networking setup script");
+ }
+ g_free(addr);
+ g_free(netmask);
+ g_free(dhcp_start);
+ g_free(dhcp_end);
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "done");
+ added = TRUE;
+ } else {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error adding network interface to list: Maximum number of devices exceeded");
+ }
}
- 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);
- gtk_container_add(GTK_CONTAINER(plugin), plugin->priv->enable_button);
- gtk_widget_show_all(plugin->priv->enable_button);
}
+ if (!added) {
+ g_object_unref(G_OBJECT(device));
+ }
+}
- mtetherd_hal_init(plugin);
+void mtetherd_status_plugin_device_removed(MTetherDStatusPlugin *plugin, const gchar *udi) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "mtetherd_status_plugin_device_removed(%s)", udi);
+ if (plugin && plugin->priv) {
+ MTetherDDevice *device = mtetherd_device_list_find(plugin->priv->devices, udi);
+ if (device) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "device=%p", device);
+ const gchar *interface = mtetherd_device_get_interface(device);
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "interface=%s", interface);
+ if (g_strcmp0(USBNET_INTERFACE, interface) == 0) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "is USB");
+ plugin->priv->usbnet_state = FALSE;
+ mtetherd_status_plugin_enable_button_set_text(plugin);
+ }
+ hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Shutting down network on %s", interface);
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", SBIN_DIR "/mtetherd-net-shutdown.sh");
+ // TODO: Check if this is the last interface to be shut down and pass WAN_INTERFACE after interface if yes
+ const char *command[] = { BIN_DIR "/sudo", SBIN_DIR "/mtetherd-net-shutdown.sh", interface, NULL };
+ if (!mtetherd_launch_script(command)) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error launching USB networking shutdown script");
+ }
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "done");
+ }
+ if (!mtetherd_device_list_remove(plugin->priv->devices, udi)) {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Device %s not found in list, nothing removed", udi);
+ } else {
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Device %s removed from list", udi);
+ }
+ }
+}
+void mtetherd_status_plugin_usb_plugged(MTetherDStatusPlugin *plugin) {
+ plugin->priv->usb_plugged = mtetherd_usb_state(plugin);
+ g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "USB plugged status: %s", plugin->priv->usb_plugged ? "on" : "off");
mtetherd_status_plugin_usb_plugged_show(plugin);
-
- //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Initialized mtetherd status plugin");
}