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>
27 #include <glib/gprintf.h>
29 #include <hildon/hildon.h>
35 #define MTETHERD_STATUS_PLUGIN_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, TYPE_MTETHERD_STATUS_PLUGIN, MTetherDStatusPluginPrivate))
38 MTETHERD_STATUS_PLUGIN_USB_NET_UNKNOWN = 0,
39 MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED,
40 MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED,
41 } MTetherDStatusPluginUsbNetState;
43 struct _MTetherDStatusPluginPrivate {
44 GtkWidget *enable_button;
47 MTetherDStatusPluginUsbNetState usbnet_state;
53 #define IMAGE_DIR "/usr/share/pixmaps"
56 #define BIN_DIR "/usr/bin"
59 #define SBIN_DIR "/usr/sbin"
62 #define TMP_DIR "/tmp"
65 // The UDI contains the MAC address and is thus unsuitable for
66 // loaded status checking, so we just use the interface name
67 static const char *USBNET_INTERFACE = "usb0";
68 const char *MTETHERD_LOG_DOMAIN = "mtetherd";
70 HD_DEFINE_PLUGIN_MODULE(MTetherDStatusPlugin, mtetherd_status_plugin, HD_TYPE_STATUS_MENU_ITEM);
72 static void mtetherd_status_plugin_class_finalize(MTetherDStatusPluginClass *klass) { }
74 static void mtetherd_status_plugin_finalize(GObject *object) {
75 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "Destroying mtetherd status plugin");
77 MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(object);
79 if (plugin && plugin->priv) {
80 mtetherd_hal_finalize(plugin);
81 mtetherd_device_list_free(plugin->priv->devices);
82 if (plugin->priv->log_fp) {
83 g_log_remove_handler(MTETHERD_LOG_DOMAIN, plugin->priv->log_handler);
84 fclose(plugin->priv->log_fp);
89 static void mtetherd_status_plugin_class_init(MTetherDStatusPluginClass *klass) {
90 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
93 gobject_class->finalize = mtetherd_status_plugin_finalize;
94 g_type_class_add_private(klass, sizeof(MTetherDStatusPluginPrivate));
98 static void mtetherd_status_plugin_enable_button_set_text(MTetherDStatusPlugin *plugin) {
99 if (plugin && plugin->priv && plugin->priv->enable_button) {
100 switch (plugin->priv->usbnet_state) {
101 case MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED:
102 hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "USB networking", "Enabled");
104 case MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED:
105 hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "USB networking", "Disabled");
108 hildon_button_set_text(HILDON_BUTTON(plugin->priv->enable_button), "USB networking", "Unknown");
114 static void mtetherd_status_plugin_enable_button_clicked(GtkWidget *button, gpointer data) {
115 MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(data);
117 if (plugin && plugin->priv && button == plugin->priv->enable_button) {
119 switch (plugin->priv->usbnet_state) {
120 case MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED:
121 arg = SBIN_DIR "/mtetherd-usbnet-disable.sh";
123 case MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED:
124 arg = SBIN_DIR "/mtetherd-usbnet-enable.sh";
131 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", arg);
132 const char *command[] = { BIN_DIR "/sudo", arg, NULL };
133 if (!mtetherd_launch_script(command)) {
134 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error launching USB networking script");
140 static void mtetherd_status_plugin_usb_plugged_show(MTetherDStatusPlugin *plugin) {
141 if (plugin && plugin->priv) {
142 if (plugin->priv->usb_plugged) {
143 gtk_widget_show(GTK_WIDGET(plugin));
145 gtk_widget_hide(GTK_WIDGET(plugin));
150 static void mtetherd_status_plugin_log(const gchar *domain, GLogLevelFlags level, const gchar *message, gpointer data) {
151 MTetherDStatusPlugin *plugin = MTETHERD_STATUS_PLUGIN(data);
153 if (plugin && plugin->priv && plugin->priv->log_fp) {
156 case G_LOG_LEVEL_ERROR:
157 levelstr = "** Error **";
159 case G_LOG_LEVEL_CRITICAL:
160 levelstr = "** CRITICAL **";
162 case G_LOG_LEVEL_WARNING:
163 levelstr = "** Warning **";
165 case G_LOG_LEVEL_MESSAGE:
166 levelstr = "-- Notice --";
168 case G_LOG_LEVEL_INFO:
169 levelstr = "-- Info --";
171 case G_LOG_LEVEL_DEBUG:
172 levelstr = "(Debug)";
174 case G_LOG_FLAG_RECURSION:
175 levelstr = "** RECURSION **";
177 case G_LOG_FLAG_FATAL:
178 levelstr = "** FATAL **";
184 g_fprintf(plugin->priv->log_fp, "mtetherd: %s %s\n", levelstr, message);
185 fflush(plugin->priv->log_fp);
189 static void mtetherd_status_plugin_init(MTetherDStatusPlugin *plugin) {
190 plugin->priv = MTETHERD_STATUS_PLUGIN_GET_PRIVATE(plugin);
193 plugin->priv->log_fp = fopen(TMP_DIR "/mtetherd-status.log", "a");
194 if (plugin->priv->log_fp) {
195 plugin->priv->log_handler = g_log_set_handler(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_MASK, mtetherd_status_plugin_log, plugin);
198 plugin->priv->enable_button = hildon_button_new(HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
199 if (plugin->priv->enable_button) {
201 GdkPixbuf *icon = gdk_pixbuf_new_from_file(IMAGE_DIR "/mtetherd-net-icon.png", &err);
203 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Can't load mtetherd icon: %s", err->message);
208 GtkWidget *image = gtk_image_new_from_pixbuf(icon);
209 hildon_button_set_image(HILDON_BUTTON(plugin->priv->enable_button), image);
210 hildon_button_set_image_position(HILDON_BUTTON(plugin->priv->enable_button), GTK_POS_LEFT);
211 gtk_button_set_alignment(GTK_BUTTON(plugin->priv->enable_button), 0, 0.5);
212 g_object_unref(icon);
214 mtetherd_status_plugin_enable_button_set_text(plugin);
215 g_signal_connect(plugin->priv->enable_button, "clicked", G_CALLBACK(mtetherd_status_plugin_enable_button_clicked), plugin);
216 gtk_container_add(GTK_CONTAINER(plugin), plugin->priv->enable_button);
217 gtk_widget_show_all(plugin->priv->enable_button);
220 if (mtetherd_hal_init(plugin)) {
221 plugin->priv->devices = mtetherd_device_list_new();
222 mtetherd_hal_device_scan(plugin);
223 // Set initial button status
224 mtetherd_status_plugin_usb_plugged(plugin);
227 plugin->priv->usb_plugged = TRUE;
228 mtetherd_status_plugin_usb_plugged_show(plugin);
232 //hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Initialized mtetherd status plugin");
233 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, "Initialized mtetherd status plugin");
236 void mtetherd_status_plugin_device_added(MTetherDStatusPlugin *plugin, MTetherDDevice *device) {
237 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "mtetherd_status_plugin_device_added(%p, %p)", plugin, device);
238 if (plugin && plugin->priv) {
239 const gchar *interface = mtetherd_device_get_interface(device);
240 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "interface=%s", interface);
241 if (mtetherd_device_ok(interface)) {
242 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "ok");
243 if (mtetherd_device_list_add(plugin->priv->devices, device)) {
244 if (g_strcmp0(USBNET_INTERFACE, interface) == 0) {
245 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "is USB");
246 plugin->priv->usbnet_state = MTETHERD_STATUS_PLUGIN_USB_NET_ENABLED;
247 mtetherd_status_plugin_enable_button_set_text(plugin);
249 hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Starting network on %s", interface);
250 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", SBIN_DIR "/mtetherd-net-setup.sh");
251 gchar *addr = mtetherd_device_get_addr(device);
252 gchar *netmask = mtetherd_device_get_netmask(device);
253 gchar *dhcp_start = mtetherd_device_get_dhcp_start(device);
254 gchar *dhcp_end = mtetherd_device_get_dhcp_end(device);
255 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "addr=%s netmask=%s dhcp_start=%s dhcp_end=%s", addr, netmask, dhcp_start, dhcp_end);
256 const char *command[] = { BIN_DIR "/sudo", SBIN_DIR "/mtetherd-net-setup.sh", interface, addr, netmask, dhcp_start, dhcp_end, NULL };
257 if (!mtetherd_launch_script(command)) {
258 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error launching USB networking setup script");
264 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "done");
266 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error adding network interface to list: Maximum number of devices exceeded");
272 void mtetherd_status_plugin_device_removed(MTetherDStatusPlugin *plugin, const gchar *udi) {
273 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "mtetherd_status_plugin_device_removed(%s)", udi);
274 if (plugin && plugin->priv) {
275 MTetherDDevice *device = mtetherd_device_list_find(plugin->priv->devices, udi);
276 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "device=%p", device);
278 const gchar *interface = mtetherd_device_get_interface(device);
279 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "interface=%s", interface);
280 if (g_strcmp0(USBNET_INTERFACE, interface) == 0) {
281 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "is USB");
282 plugin->priv->usbnet_state = MTETHERD_STATUS_PLUGIN_USB_NET_DISABLED;
283 mtetherd_status_plugin_enable_button_set_text(plugin);
285 hildon_banner_show_informationf(GTK_WIDGET(plugin), NULL, "Shutting down network on %s", interface);
286 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Launching %s", SBIN_DIR "/mtetherd-net-shutdown.sh");
287 const char *command[] = { BIN_DIR "/sudo", SBIN_DIR "/mtetherd-net-shutdown.sh", interface, NULL };
288 if (!mtetherd_launch_script(command)) {
289 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error launching USB networking shutdown script");
291 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "done");
293 if (!mtetherd_device_list_remove(plugin->priv->devices, udi)) {
294 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "Error removing network interface from list: Not found");
299 void mtetherd_status_plugin_usb_plugged(MTetherDStatusPlugin *plugin) {
300 plugin->priv->usb_plugged = mtetherd_usb_state(plugin);
301 g_log(MTETHERD_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "USB plugged status: %s", plugin->priv->usb_plugged ? "on" : "off");
302 mtetherd_status_plugin_usb_plugged_show(plugin);