3 (c) 2010 Gregor Riepl <onitake@gmail.com>
5 Tethering utility for Maemo
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/types.h>
28 #include <hildon/hildon.h>
34 #define MTETHERD_STATUS_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, TYPE_MTETHERD_STATUS_PLUGIN, MTetherDStatusPluginPrivate))
37 MTETHERD_STATUS_PLUGIN_USB_NET_UNKNOWN = 0,
38 MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED,
39 MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED,
40 } MTetherDStatusPluginUsbNetState;
42 struct _MTetherDStatusPluginPrivate {
43 GtkWidget *enable_button;
46 MTetherDStatusPluginUsbNetState usbnet_state;
50 #define IMAGE_DIR "/usr/share/pixmaps"
53 #define SBIN_DIR "/usr/sbin"
56 static const char *USBNET_MODULE = "g_ether";
57 // The UDI contains the MAC address and is thus unsuitable for
58 // loaded status checking, so we just use the interface name
59 static const char *USBNET_INTERFACE = "usb0";
61 HD_DEFINE_PLUGIN_MODULE(MTetherDStatusPlugin, mtetherd_status_plugin, HD_TYPE_STATUS_MENU_ITEM);
63 static void mtetherd_status_plugin_class_finalize(MTetherDStatusPluginClass *klass) { }
65 static void mtetherd_status_plugin_finalize(GObject *object) {
66 g_message("Destroying mtetherd status plugin");
68 MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(object);
70 if (plugin && plugin->priv) {
71 mtetherd_hal_finalize(plugin);
72 mtetherd_device_list_free(plugin->priv->devices);
76 static void mtetherd_status_plugin_class_init(MTetherDStatusPluginClass *klass) {
77 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
80 gobject_class->finalize = mtetherd_status_plugin_finalize;
81 g_type_class_add_private(klass, sizeof(MTetherDStatusPluginPrivate));
85 static void mtetherd_status_plugin_enable_button_set_text(MTetherDStatusPlugin *plugin) {
86 if (plugin && plugin->priv && plugin->priv->enable_button) {
87 switch (plugin->priv->usbnet_state) {
88 case MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED:
89 hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "Toggle USB Networking", "Enabled");
91 case MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED:
92 hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "Toggle USB Networking", "Disabled");
95 hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "Toggle USB Networking", "Unknown");
101 static void mtetherd_status_plugin_enable_button_clicked(GtkWidget *button, gpointer data) {
102 MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(data);
104 if (plugin && plugin->priv && button == plugin->priv->enable_button) {
106 switch (plugin->priv->usbnet_state) {
107 case MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED:
108 arg = SBIN_DIR "mtetherd-usbnet-disable.sh";
110 case MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED:
111 arg = SBIN_DIR "mtetherd-usbnet-enable.sh";
118 g_debug("Launching %s", arg);
119 const char *command[] = { "/usr/bin/sudo", arg, NULL };
120 if (!mtetherd_launch_script(command)) {
121 g_error("Error launching USB networking script");
127 static void mtetherd_status_plugin_usb_plugged_show(MTetherDStatusPlugin *plugin) {
128 if (plugin && plugin->priv) {
129 if (plugin->priv->usb_plugged) {
130 gtk_widget_show(GTK_WIDGET(plugin));
132 gtk_widget_hide(GTK_WIDGET(plugin));
137 static void mtetherd_status_plugin_init(MTetherDStatusPlugin *plugin) {
138 plugin->priv = MTETHERD_STATUS_PLUGIN_GET_PRIVATE(plugin);
140 plugin->priv->enable_button = hildon_button_new(HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
141 if (plugin->priv->enable_button) {
143 GdkPixbuf *icon = gdk_pixbuf_new_from_file(IMAGE_DIR "/mtetherd-net-icon.png", &err);
145 g_warning("Can't load mtetherd icon: %s", err->message);
150 GtkWidget *image = gtk_image_new_from_pixbuf(icon);
151 hildon_button_set_image(HILDON_BUTTON(plugin->priv->enable_button), image);
152 hildon_button_set_image_position(HILDON_BUTTON(plugin->priv->enable_button), GTK_POS_LEFT);
153 g_object_unref(icon);
155 mtetherd_status_plugin_enable_button_set_text(plugin);
156 g_signal_connect(plugin->priv->enable_button, "clicked", G_CALLBACK(mtetherd_status_plugin_enable_button_clicked), plugin);
157 gtk_container_add(GTK_CONTAINER(plugin), plugin->priv->enable_button);
158 gtk_widget_show_all(plugin->priv->enable_button);
161 if (mtetherd_hal_init(plugin)) {
162 plugin->priv->usb_plugged = mtetherd_usb_state(plugin);
163 plugin->priv->devices = mtetherd_device_list_new();
164 mtetherd_hal_device_scan(plugin);
166 plugin->priv->usb_plugged = FALSE;
169 // Unnecessary, we scan the network device name instead
170 //plugin->priv->usbnet_loaded = mtetherd_scan_modules(USBNET_MODULE);
172 // Update the button status
173 mtetherd_status_plugin_usb_plugged_show(plugin);
175 hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Initialized mtetherd status plugin");
178 void mtetherd_status_plugin_device_added(MTetherDStatusPlugin *plugin, MTetherDDevice *device) {
179 if (plugin && plugin->priv) {
180 const gchar *interface = mtetherd_device_get_interface(device);
181 if (mtetherd_device_ok(interface)) {
182 if (!mtetherd_device_list_add(plugin->priv->devices, device)) {
183 g_warning("Error adding network interface to list: Maximum number of devices exceeded");
185 if (g_strcmp0(USBNET_INTERFACE, interface) == 0) {
186 plugin->priv->usbnet_state = MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED;
187 mtetherd_status_plugin_enable_button_set_text(plugin);
189 hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Starting network on %s", interface);
190 // TODO: Launch network setup script
196 void mtetherd_status_plugin_device_removed(MTetherDStatusPlugin *plugin, const gchar *udi) {
197 if (plugin && plugin->priv) {
198 MTetherDDevice *device = mtetherd_device_list_find(plugin->priv->devices, udi);
200 const gchar *interface = mtetherd_device_get_interface(device);
201 if (g_strcmp0(USBNET_INTERFACE, interface) == 0) {
202 plugin->priv->usbnet_state = MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED;
203 mtetherd_status_plugin_enable_button_set_text(plugin);
205 hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Shutting down network on %s", interface);
206 // TODO: Launch network teardown script
208 if (!mtetherd_device_list_remove(plugin->priv->devices, udi)) {
209 g_warning("Error removing network interface from list: Not found");
214 void mtetherd_status_plugin_usb_plugged(MTetherDStatusPlugin *plugin) {
215 mtetherd_status_plugin_usb_plugged_show(plugin);