From 4784aa4734011b46656e0ce5813cb50cf9246989 Mon Sep 17 00:00:00 2001 From: Philippe De Swert Date: Wed, 6 Apr 2011 17:58:40 +0300 Subject: [PATCH] * Working udev cable detection!!! * Minor changes for bugfixes and cdrom emulation support Signed-off-by: Philippe De Swert --- configure.ac | 12 ++++- debian/changelog | 7 +++ src/Makefile.am | 5 +- src/usb_moded-appsync.c | 12 ++++- src/usb_moded-config.c | 34 ++++++++++++++ src/usb_moded-config.h | 5 ++ src/usb_moded-hw-ab.h | 2 + src/usb_moded-modesetting.c | 30 ++++++++++-- src/usb_moded-modesetting.h | 3 ++ src/usb_moded-udev.c | 94 +++++++++++++++++++++++-------------- src/usb_moded.c | 1 + 11 files changed, 164 insertions(+), 41 deletions(-) diff --git a/configure.ac b/configure.ac index dd8d432..e71f1a5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([usb_moded], [0.33]) +AC_INIT([usb_moded], [0.34]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AM_CONFIG_HEADER([config.h]) @@ -67,6 +67,16 @@ AC_ARG_ENABLE([hal], AS_HELP_STRING([--enable-hal], [Enable deprecated hal inter esac],[hal=false]) AM_CONDITIONAL([HAL], [test x$hal = xtrue]) +AC_ARG_ENABLE([udev], AS_HELP_STRING([--enable-udev], [Enable udev interface @<:@default=true@:>@]), + [case "${enableval}" in + yes) hal=true ; CFLAGS="-DUDEV -ludev $CFLAGS" ;; + no) hal=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-udev]) ;; + esac],[hal=false]) +AM_CONDITIONAL([UDEV], [test x$udev = xtrue]) + + + PKG_CHECK_MODULES([USB_MODED], [ glib-2.0 >= 2.2.0 dbus-1 >= 1.2.1 diff --git a/debian/changelog b/debian/changelog index 6b03f89..dfdaaf2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +usb-moded (0.34) unstable; urgency=low + + * Delay unloading a bit more (5s instead of 3). Fixes: NB#225492 + * Fixes for USB autoplay. Fixes: NB#220474 + + -- Philippe De Swert Fri, 01 Apr 2011 13:22:51 +0300 + usb-moded (0.33) unstable; urgency=low * More security guesswork. Hopefully the doxygen tags are diff --git a/src/Makefile.am b/src/Makefile.am index 7cb7290..d1a4a17 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,9 +31,12 @@ usb_moded_SOURCES = \ if HAL usb_moded_SOURCES += \ usb_moded-hal.c -else +else if NOKIA usb_moded_SOURCES += \ usb_moded-chargerdetection.c +else +usb_moded_SOURCES += \ + usb_moded-udev.c endif if NOKIA diff --git a/src/usb_moded-appsync.c b/src/usb_moded-appsync.c index 6492ce0..f92eb48 100644 --- a/src/usb_moded-appsync.c +++ b/src/usb_moded-appsync.c @@ -1,5 +1,5 @@ /** - @file usb_moded-config.c + @file usb_moded-appsync.c Copyright (C) 2010 Nokia Corporation. All rights reserved. @@ -32,6 +32,9 @@ #include "usb_moded-appsync-dbus.h" #include "usb_moded-appsync-dbus-private.h" #include "usb_moded-log.h" +#ifdef NOKIA +#include "usb_moded-modesetting.h" +#endif static struct list_elem *read_file(const gchar *filename); @@ -192,6 +195,7 @@ gboolean enumerate_usb(gpointer data) /* activate usb connection/enumeration */ system("echo 1 > /sys/devices/platform/musb_hdrc/gadget/softconnect"); + log_debug("Softconnect enumeration done\n"); /* no need to remove timer */ @@ -199,6 +203,12 @@ gboolean enumerate_usb(gpointer data) if(data != NULL) usb_moded_appsync_cleanup((GList *)data); +#ifdef NOKIA + /* timeout for exporting CDROM image */ + g_timeout_add_seconds(1, export_cdrom, data); + +#endif /* NOKIA */ + /* return false to stop the timer from repeating */ return(FALSE); } diff --git a/src/usb_moded-config.c b/src/usb_moded-config.c index 50ac26a..40305d6 100644 --- a/src/usb_moded-config.c +++ b/src/usb_moded-config.c @@ -125,5 +125,39 @@ const char * find_alt_mount(void) } g_key_file_free(settingsfile); return(ret); +} + +#ifdef NOKIA +const char * find_cdrom_path(void) +{ + GKeyFile *settingsfile; + gboolean test = FALSE; + gchar **keys; + const char *ret = NULL, *tmp_char; + settingsfile = g_key_file_new(); + test = g_key_file_load_from_file(settingsfile, FS_MOUNT_CONFIG_FILE, G_KEY_FILE_NONE, NULL); + if(!test) + { + log_debug("No cdrom path.\n"); + g_key_file_free(settingsfile); + return(ret); + } + keys = g_key_file_get_keys (settingsfile, CDROM_PATH_ENTRY, NULL, NULL); + while (*keys != NULL) + { + if(!strcmp(*keys, CDROM_PATH_KEY)) + { + tmp_char = g_key_file_get_string(settingsfile, CDROM_PATH_ENTRY, *keys, NULL); + if(tmp_char) + { + log_debug("cdrom key value = %s\n", tmp_char); + ret = g_strdup(tmp_char); + } + } + keys++; + } + g_key_file_free(settingsfile); + return(ret); } +#endif /* NOKIA */ diff --git a/src/usb_moded-config.h b/src/usb_moded-config.h index c1b366f..c092120 100644 --- a/src/usb_moded-config.h +++ b/src/usb_moded-config.h @@ -29,7 +29,12 @@ #define FS_SYNC_KEY "nofua" #define ALT_MOUNT_ENTRY "altmount" #define ALT_MOUNT_KEY "mount" +#define CDROM_PATH_ENTRY "cdrom" +#define CDROM_PATH_KEY "path" const char * find_mounts(void); int find_sync(void); const char * find_alt_mount(void); +#ifdef NOKIA +const char * find_cdrom_path(void); +#endif diff --git a/src/usb_moded-hw-ab.h b/src/usb_moded-hw-ab.h index dde770a..7ac245b 100644 --- a/src/usb_moded-hw-ab.h +++ b/src/usb_moded-hw-ab.h @@ -26,6 +26,8 @@ /*============================================================================= */ +#include + /* set up the hw abstraction layer * * @return Returns true when succesful diff --git a/src/usb_moded-modesetting.c b/src/usb_moded-modesetting.c index a234967..2e9adee 100644 --- a/src/usb_moded-modesetting.c +++ b/src/usb_moded-modesetting.c @@ -130,7 +130,8 @@ umount: command = g_strconcat("mount | grep ", mounts[i], NULL); ret = 0; } - /* activate mounts */ + /* activate mounts after sleeping 1s to be sure enumeration happened and autoplay will work */ + sleep(1); for(i=0 ; mounts[i] != NULL; i++) { sprintf(command2, "echo %i > /sys/devices/platform/musb_hdrc/gadget/gadget-lun%d/nofua", fua, i); @@ -151,25 +152,46 @@ umount: command = g_strconcat("mount | grep ", mounts[i], NULL); } +#ifdef NOKIA int set_ovi_suite_mode(GList *applist) { int net = 0; -#ifdef NOKIA /* do not go through the appsync routine if there is no applist */ if(applist) activate_sync(applist); else enumerate_usb(NULL); -#endif /* NOKIA */ /* bring network interface up in case no other network is up */ - net = system("route | grep default"); + net = system("route -n | grep default"); if(net) net = system("ifdown usb0 ; ifup usb0"); return(0); } +gboolean export_cdrom(gpointer data) +{ + const char *path = NULL, *command = NULL; + + path = find_cdrom_path(); + + if(path == NULL) + { + log_debug("No cdrom path specified => not exporting.\n"); + } + if(access(path, F_OK) == 0) + { + command = g_strconcat("echo ", path, " > /sys/devices/platform/musb_hdrc/gadget/gadget-lun%d/file", NULL); + system(command); + } + else + log_debug("Cdrom image file does not exist => no export.\n"); + + return(FALSE); +} + +#endif /* NOKIA */ /** clean up mode changes or extra actions to perform after a mode change diff --git a/src/usb_moded-modesetting.h b/src/usb_moded-modesetting.h index e964b8b..6295e97 100644 --- a/src/usb_moded-modesetting.h +++ b/src/usb_moded-modesetting.h @@ -26,4 +26,7 @@ int find_number_of_mounts(void); int set_mass_storage_mode(void); int set_ovi_suite_mode(GList *applist); int usb_moded_mode_cleanup(const char *module); +#ifdef NOKIA +gboolean export_cdrom (gpointer data); +#endif diff --git a/src/usb_moded-udev.c b/src/usb_moded-udev.c index 94a032a..34911f5 100644 --- a/src/usb_moded-udev.c +++ b/src/usb_moded-udev.c @@ -7,65 +7,91 @@ #include -#include "usb_moded-loh.h" +#include + +#include "usb_moded-log.h" +#include "usb_moded-hw-ab.h" +#include "usb_moded.h" /* global variables */ struct udev *udev; struct udev_monitor *mon; struct udev_device *dev; -int hwal_init(void) +/* static function definitions */ +gpointer monitor_udev(gpointer data) __attribute__ ((noreturn)); + +gboolean hwal_init(void) { - struct udev_list_entry *devices, *dev_list_entry; - struct pollfd *fds; - int poll_ret = 0; + GThread * thread; /* Create the udev object */ udev = udev_new(); if (!udev) { log_err("Can't create udev\n"); - return 1; + return 0; + } + dev = udev_device_new_from_syspath(udev, "/sys/class/power_supply/usb"); + if (!dev) + { + log_err("Unable to find /sys/class/power_supply/usb device."); + return 0; + } + mon = udev_monitor_new_from_netlink (udev, "udev"); + if (!mon) + { + log_err("Unable to monitor the 'present' value\n"); + return 0; } + udev_monitor_filter_add_match_subsystem_devtype(mon, "power_supply", NULL); + udev_monitor_enable_receiving (mon); + + thread = g_thread_create(monitor_udev, NULL, FALSE, NULL); - /* Set up a monitor to monitor devices */ - mon = udev_monitor_new_from_netlink(udev, "udev"); - udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", NULL); - udev_monitor_enable_receiving(mon); - /* Get the file descriptor (fd) for the monitor. - This fd will get passed to select() */ - fd = udev_monitor_get_fd(mon); + if(thread) + return 1; + else + { + log_debug("thread not created succesfully\n"); + return 0; + } +} - /* loop waiting for events */ +gpointer monitor_udev(gpointer data) +{ while(1) { - /* set a poll on the fd so we do not block trying to read data */ - fds = malloc(sizeof(struct pollfd)); - fds->fd = fd; - fds->events = POLLPRI; - poll_ret = poll(fds, 1, -1); - if(poll_ret) - { - dev = udev_monitor_receive_device(mon); - if(dev) + dev = udev_monitor_receive_device (mon); + if (dev) + { + if(!strcmp(udev_device_get_action(dev), "change")) { - log_debug("Got Device\n"); - log_debug(" Node: %s\n", udev_device_get_devnode(dev)); - log_debug(" Subsystem: %s\n", udev_device_get_subsystem(dev)); - log_debug(" Devtype: %s\n", udev_device_get_devtype(dev)); - log_debug(" Action: %s\n", udev_device_get_action(dev)); - udev_device_unref(dev); + if(!strcmp(udev_device_get_property_value(dev, "POWER_SUPPLY_PRESENT"), "1")) + { + log_debug("UDEV:power supply present\n"); + /* POWER_SUPPLY_TYPE is USB if usb cable is connected, or USB_DCP for charger */ + if(!strcmp(udev_device_get_property_value(dev, "POWER_SUPPLY_TYPE"), "USB")) + { + log_debug("UDEV:USB cable connected\n"); + set_usb_connected(TRUE); + } + } + else + { + log_debug("UDEV:USB cable disconnected\n"); + set_usb_connected(FALSE); + } } - + udev_device_unref(dev); } - + } } -int hwal_cleanup(void) +void hwal_cleanup(void) { - udev_enumerate_unref(enumerate); + udev_monitor_unref(mon); udev_unref(udev); - return 0; } diff --git a/src/usb_moded.c b/src/usb_moded.c index d41e554..fb986a1 100644 --- a/src/usb_moded.c +++ b/src/usb_moded.c @@ -546,6 +546,7 @@ int main(int argc, char* argv[]) freopen("/dev/null", "a", stderr); } g_type_init(); + g_thread_init(NULL); mainloop = g_main_loop_new(NULL, FALSE); log_debug("usb_moded starting\n");