commit b99d3a6d1001e8cb1b4cfe43b475a21496e4aff5 Author: Christophe Fergeau <cferg...@mandriva.com> Date: Wed Dec 23 15:53:39 2009 +0100
add nano5g support to hal callout configure.ac | 14 ++++++- tools/Makefile.am | 10 +++++ tools/hal-callout.c | 109 +++++++++++++++++++++++++++++++++++++++++++-------- tools/ipod-usb.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+), 18 deletions(-) --- diff --git a/configure.ac b/configure.ac index 00269fe..36de1aa 100644 --- a/configure.ac +++ b/configure.ac @@ -82,7 +82,8 @@ fi AM_CONDITIONAL(WITH_INTERNAL_GCHECKSUM, test "x$with_internal_gchecksum" = "xyes") dnl ************************************************** -dnl * sgutils is necessary to get the xml device file from the ipod +dnl * sgutils is necessary to get the xml device file +dnl * from older ipods dnl ************************************************** AC_CHECK_LIB(sgutils2, sg_ll_inquiry, [SGUTILS_LIBS="-lsgutils2"; have_sgutils=yes], @@ -99,6 +100,17 @@ fi AM_CONDITIONAL(HAVE_SGUTILS, test x"$have_sgutils" = xyes) dnl ************************************************** +dnl * libusb is necessary to get the xml device file +dnl * from newer ipods (nano5g) +dnl ************************************************** +PKG_CHECK_MODULES(LIBUSB, libusb-1.0, have_libusb=yes, have_libusb=no) +if test x"$have_libusb" = xyes; then + AH_TEMPLATE([HAVE_LIBUSB], [Whether libusb is installed]) + AC_DEFINE_UNQUOTED(HAVE_LIBUSB, 1) +fi +AM_CONDITIONAL(HAVE_LIBUSB, test x"$have_libusb" = xyes) + +dnl ************************************************** dnl * zlib is neeeded for handling compressed iTunesCDB files dnl ************************************************** AC_CHECK_LIB(z, inflate, diff --git a/tools/Makefile.am b/tools/Makefile.am index 99a75c1..8d3876c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -12,6 +12,11 @@ ipod_read_sysinfo_extended_SOURCES+=ipod-lockdown.c ipod_read_sysinfo_extended_CFLAGS+=$(LIBIPHONE_CFLAGS) ipod_read_sysinfo_extended_LDADD+=$(LIBIPHONE_LIBS) endif +if HAVE_LIBUSB +ipod_read_sysinfo_extended_SOURCES+=ipod-usb.c +ipod_read_sysinfo_extended_CFLAGS+=$(LIBUSB_CFLAGS) +ipod_read_sysinfo_extended_LDADD+=$(LIBUSB_LIBS) +endif if HAVE_HAL haldir = $(HALCALLOUTSDIR) @@ -49,6 +54,11 @@ libgpod_callout_SOURCES += ipod-scsi.c libgpod_callout_CFLAGS += $(SGUTILS_CFLAGS) libgpod_callout_LDADD += $(SGUTILS_LIBS) endif +if HAVE_LIBUSB +libgpod_callout_SOURCES+=ipod-usb.c +libgpod_callout_CFLAGS+=$(LIBUSB_CFLAGS) +libgpod_callout_LDADD+=$(LIBUSB_LIBS) +endif endif diff --git a/tools/hal-callout.c b/tools/hal-callout.c index 02ef439..8e97d98 100644 --- a/tools/hal-callout.c +++ b/tools/hal-callout.c @@ -44,6 +44,9 @@ #ifdef HAVE_SGUTILS extern char *read_sysinfo_extended (const char *device); #endif +#ifdef HAVE_LIBUSB +extern char *read_sysinfo_extended_from_usb (guint bus_number, guint device_address); +#endif struct _ProductionInfo { gchar *factory_id; @@ -759,7 +762,61 @@ static gboolean write_sysinfo_extended (const char *mountpoint, return result; } +#ifdef HAVE_LIBUSB +static gboolean hal_get_ipod_usb_position (LibHalContext *ctx, const char *udi, + int *usb_bus_number, int *usb_device_number) +{ + char *parent_udi; + char *subsystem; + gboolean found_ids; + DBusError error; + + + parent_udi = NULL; + subsystem = NULL; + found_ids = FALSE; + dbus_error_init (&error); + while (TRUE) { + parent_udi = libhal_device_get_property_string (ctx, udi, + "info.parent", &error); + if (parent_udi == NULL || dbus_error_is_set (&error)) + goto end; + udi = parent_udi; + subsystem = libhal_device_get_property_string (ctx, udi, + "linux.subsystem", + &error); + if (subsystem == NULL || dbus_error_is_set (&error)) { + dbus_error_free (&error); + dbus_error_init (&error); + continue; + } + if (strcmp (subsystem, "usb") == 0) { + *usb_bus_number = libhal_device_get_property_int (ctx, udi, + "usb.bus_number", &error); + if (dbus_error_is_set (&error)) { + goto end; + } + *usb_device_number = libhal_device_get_property_int (ctx, udi, + "usb.linux.device_number", &error); + if (dbus_error_is_set (&error)) { + goto end; + } + found_ids = TRUE; + goto end; + } + } + +end: + libhal_free_string (parent_udi); + libhal_free_string (subsystem); + if (dbus_error_is_set (&error)) { + g_print ("Error: %s\n", error.message); + dbus_error_free (&error); + } + return found_ids; +} +#endif int main (int argc, char **argv) { @@ -770,31 +827,49 @@ int main (int argc, char **argv) const char *udi; g_type_init (); + g_print ("huho\n"); + + ctx = hal_ipod_initialize (); + if (ctx == NULL) { + g_print ("Failed to init hal\n"); + return FALSE; + } + udi = g_getenv ("UDI"); + if (udi == NULL) { + g_print ("Failed to get UDI\n"); + libhal_ctx_free (ctx); + return FALSE; + } + + xml = NULL; + +#ifdef HAVE_LIBUSB +{ + gboolean found_ipod; + gint usb_bus_number = 0; + gint usb_device_number = 0; + + found_ipod = hal_get_ipod_usb_position (ctx, udi, &usb_bus_number, + &usb_device_number); + if (found_ipod) { + xml = read_sysinfo_extended_from_usb (usb_bus_number, + usb_device_number); + } +} +#endif #ifdef HAVE_SGUTILS - xml = read_sysinfo_extended (g_getenv ("HAL_PROP_BLOCK_DEVICE")); -#else - return -1; + if (xml == NULL) { + xml = read_sysinfo_extended (g_getenv ("HAL_PROP_BLOCK_DEVICE")); + } #endif + if (xml == NULL) { + libhal_ctx_free (ctx); return -1; } props = itdb_sysinfo_extended_parse_from_xml (xml, NULL); - ctx = hal_ipod_initialize (); - if (ctx == NULL) { - g_free (xml); - itdb_sysinfo_properties_free (props); - return FALSE; - } - udi = g_getenv ("UDI"); - if (udi == NULL) { - g_free (xml); - libhal_ctx_free (ctx); - itdb_sysinfo_properties_free (props); - return FALSE; - } - hal_ipod_set_properties (ctx, udi, props); itdb_sysinfo_properties_free (props); diff --git a/tools/ipod-usb.c b/tools/ipod-usb.c new file mode 100644 index 0000000..0c4ff80 --- /dev/null +++ b/tools/ipod-usb.c @@ -0,0 +1,105 @@ +#include <libusb.h> +#include <glib.h> + +static int send_command (libusb_device_handle *handle, const guint value, const guint index, guchar *data, gsize len) +{ + return libusb_control_transfer (handle, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, 0x40, value, index, data, len, 0); +} + +static libusb_device_handle *open_handle (libusb_context *ctx, const guint bus_number, const guint device_address) +{ + libusb_device **list; + libusb_device *dev; + libusb_device_handle *handle; + unsigned int i; + + int success; + int device_count; + + device_count = libusb_get_device_list (ctx, &list); + if (device_count < 0) { + g_print ("Couldn't get device list\n"); + return NULL; + } + + dev = NULL; + for (i = 0; i < device_count; i++) { + if (libusb_get_bus_number (list[i]) != bus_number) { + continue; + } + if (libusb_get_device_address (list[i]) != device_address) { + continue; + } + dev = list[i]; + break; + } + + if (dev == NULL) { + libusb_free_device_list (list, 1); + g_print ("Couldn't find iPod\n"); + return NULL; + } + + success = libusb_open (dev, &handle); + libusb_free_device_list (list, 1); + if (success < 0) { + g_print ("Couldn't open usb device: %d\n", success); + return NULL; + } + + return handle; +} + + +static gchar *get_sysinfo_extended (libusb_device_handle *handle) +{ + GString *sysinfo_extended; + guchar data[0x1000]; + unsigned int i; + + sysinfo_extended = g_string_sized_new (0x8000); + + for (i = 0; i < 0xffff; i++) { + int bytes_read; + bytes_read = send_command (handle, 0x02, i, data, sizeof (data)); + if (bytes_read < 0) { + g_print ("error reading: %d (i = %d)\n", bytes_read, i); + return NULL; + } + g_string_append_len (sysinfo_extended, (gchar*)data, bytes_read); + if (bytes_read != sizeof (data)) { + /* assume short reads mean "end of file" */ + break; + } + } + /*hexdump ((guchar *)sysinfo_extended->str, sysinfo_extended->len);*/ + return g_string_free (sysinfo_extended, FALSE); +} + +G_GNUC_INTERNAL char *read_sysinfo_extended_from_usb (guint bus_number, guint device_address); +G_GNUC_INTERNAL char *read_sysinfo_extended_from_usb (guint bus_number, guint device_address) +{ + int success; + libusb_context *ctx; + libusb_device_handle *handle; + gchar *sysinfo_extended; + + success = libusb_init (&ctx); + if (success < 0) { + return NULL; + + } + + handle = open_handle (ctx, bus_number, device_address); + if (handle == NULL) { + libusb_exit (ctx); + return NULL; + } + + sysinfo_extended = get_sysinfo_extended (handle); + + libusb_close (handle); + libusb_exit (ctx); + + return sysinfo_extended; +} ------------------------------------------------------------------------------ Throughout its 18-year history, RSA Conference consistently attracts the world's best and brightest in the field, creating opportunities for Conference attendees to learn about information security's most important issues through interactions with peers, luminaries and emerging and established companies. http://p.sf.net/sfu/rsaconf-dev2dev _______________________________________________ gtkpod-cvs2 mailing list gtkpod-cvs2@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2