commit b99d3a6d1001e8cb1b4cfe43b475a21496e4aff5
Author: Christophe Fergeau <[email protected]>
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2