summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README26
-rw-r--r--patches/libusb-add-zlp-flag.patch24
-rw-r--r--patches/valgrind-usbdevfs.patch133
-rw-r--r--usbmuxd/usb-linux.c4
-rw-r--r--usbmuxd/usb.h6
5 files changed, 16 insertions, 177 deletions
diff --git a/README b/README
index 7e5c2bb..430f217 100644
--- a/README
+++ b/README
@@ -8,22 +8,18 @@ command/response payloads instead of binary blobs. The outer binary protocol is
8still the same used but now the only command/response format is 8 (plist). 8still the same used but now the only command/response format is 8 (plist).
9 9
10The server is under the usbmuxd directory. You'll need CMake and libusb 1.0 to 10The server is under the usbmuxd directory. You'll need CMake and libusb 1.0 to
11build it. In addition, you need to apply the libusb patch in the patches/ 11build it. Due to a bug in zero-length packet handling, you'll need either the
12directory. If you want to debug using valgrind, apply the valgrind patch to 12git version of libusb or 1.0.3, whenever it comes out.
13improve the handling of the USB device filesystem ioctls.
14 13
15There is a Python client library in the python-client directory. It should be 14There is a Python client library in the python-client directory. It should be
16compatible with Windows, Linux, and OSX (using the Apple usbmuxd on Win and OSX) 15compatible with Windows, Linux, and OSX (using the Apple usbmuxd on Win and OSX)
17tcprelay.py implements a TCP connection forwarder that lets you pipe TCP 16tcprelay.py implements a TCP connection forwarder that lets you pipe TCP
18connections to localhost to the phone. Run it with --help for usage. Note that 17connections to localhost to the phone. Run it with --help for usage. The Python
19under OSX you'll have to change the socket path from /tmp/usbmuxd to 18client lib is also compatible with the new plist-based protocol and should
20/var/run/usbmuxd (there is no socket path on Windows, only a TCP connection to 19automatically select it if it sees such a server. However, you need Python 2.6
21localhost). The Python client lib is also compatible with the new plist-based 20for Windows and Linux in this case, since the plistlib module doesn't come with
22protocol and should automatically select it if it sees such a server. However, 21older versions under these OSes (not that you'll have a server that supports
23you need Python 2.6 for Windows and Linux in this case, since the plistlib 22this protocol under Linux. TODO: does Windows iTunes use this yet?)
24module doesn't come with older versions under these OSes (not that you'll have a
25server that supports this protocol under Linux. TODO: does Windows iTunes even
26use this yet?)
27 23
28ARCHITECTURE 24ARCHITECTURE
29 25
@@ -100,7 +96,9 @@ GOTCHAS AND ANNOYANCES
100The usbmuxd CONNECT request port field is byte-swapped (network-endian). This is 96The usbmuxd CONNECT request port field is byte-swapped (network-endian). This is
101even more annoying for the plist based protocol, since it's even true there 97even more annoying for the plist based protocol, since it's even true there
102(where the field is plain text). So even for the plain text int, you need to 98(where the field is plain text). So even for the plain text int, you need to
103swap the bytes (port 22 becomes <integer>5632</integer>). 99swap the bytes (port 22 becomes <integer>5632</integer>). I have no clue if this
100is the case on the new plist protocol on PPC macs (is the newer iTunes available
101for those?)
104 102
105There are a bunch of gotchas due to the USB framing, and this is even worse 103There are a bunch of gotchas due to the USB framing, and this is even worse
106because implementations tend to get it wrong (i.e. libusb, and this is the 104because implementations tend to get it wrong (i.e. libusb, and this is the
@@ -135,7 +133,7 @@ is normally not an issue, but it's annoying for debugging because lost packets
135gets out of sync and then might crash and burn dozens of packets later. 133gets out of sync and then might crash and burn dozens of packets later.
136 134
137The server needs a proper front-end (i.e. daemonizing, commandline options, 135The server needs a proper front-end (i.e. daemonizing, commandline options,
138etc), a lot of testing, and some optimizing. 136etc), more testing, and some optimizing.
139 137
140Someone should probably do some edge-case testing on the TCP stuff. 138Someone should probably do some edge-case testing on the TCP stuff.
141 139
diff --git a/patches/libusb-add-zlp-flag.patch b/patches/libusb-add-zlp-flag.patch
deleted file mode 100644
index add9f97..0000000
--- a/patches/libusb-add-zlp-flag.patch
+++ /dev/null
@@ -1,24 +0,0 @@
1diff -ur libusb-1.0.0/libusb/os/linux_usbfs.c libusb-1.0.0-mod/libusb/os/linux_usbfs.c
2--- libusb-1.0.0/libusb/os/linux_usbfs.c 2008-12-13 20:43:20.000000000 +0100
3+++ libusb-1.0.0-mod/libusb/os/linux_usbfs.c 2009-04-30 04:25:12.000000000 +0200
4@@ -1295,7 +1295,8 @@
5 urb->buffer_length = transfer->length % MAX_BULK_BUFFER_LENGTH;
6 else
7 urb->buffer_length = MAX_BULK_BUFFER_LENGTH;
8-
9+ if ((!(transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK)) && (i == num_urbs - 1))
10+ urb->flags = USBFS_URB_ZLP;
11 r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb);
12 if (r < 0) {
13 int j;
14diff -ur libusb-1.0.0/libusb/os/linux_usbfs.h libusb-1.0.0-mod/libusb/os/linux_usbfs.h
15--- libusb-1.0.0/libusb/os/linux_usbfs.h 2008-07-16 16:17:57.000000000 +0200
16+++ libusb-1.0.0-mod/libusb/os/linux_usbfs.h 2009-04-30 04:08:27.000000000 +0200
17@@ -63,6 +63,7 @@
18 #define USBFS_URB_DISABLE_SPD 1
19 #define USBFS_URB_ISO_ASAP 2
20 #define USBFS_URB_QUEUE_BULK 0x10
21+#define USBFS_URB_ZLP 0x40
22
23 enum usbfs_urb_type {
24 USBFS_URB_TYPE_ISO = 0,
diff --git a/patches/valgrind-usbdevfs.patch b/patches/valgrind-usbdevfs.patch
deleted file mode 100644
index 9287573..0000000
--- a/patches/valgrind-usbdevfs.patch
+++ /dev/null
@@ -1,133 +0,0 @@
1diff -ur -x '*~' valgrind-3.4.1/coregrind/m_syswrap/syswrap-generic.c valgrind-3.4.1-mod/coregrind/m_syswrap/syswrap-generic.c
2--- valgrind-3.4.1/coregrind/m_syswrap/syswrap-generic.c 2009-03-01 23:01:09.000000000 +0100
3+++ valgrind-3.4.1-mod/coregrind/m_syswrap/syswrap-generic.c 2009-04-29 15:44:08.000000000 +0200
4@@ -4160,23 +4160,56 @@
5 struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)ARG3;
6
7 /* Not the whole struct needs to be initialized */
8- PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).ep", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
9+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
10 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
11 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
12 PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
13- PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
14- PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).usercontext", (Addr)&vkuu->usercontext, sizeof(vkuu->usercontext));
15- if (vkuu->endpoint & 0x80)
16- PRE_MEM_WRITE( "ioctl(USBDEVFS_URB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
17- else
18- PRE_MEM_READ( "ioctl(USBDEVFS_URB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
19- /* FIXME: Does not handle all cases this ioctl can do, ISOs are missing. */
20+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
21+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
22+ if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
23+ struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
24+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
25+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
26+ if (vkusp->bRequestType & 0x80)
27+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
28+ else
29+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
30+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
31+ } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
32+ int total_length = 0;
33+ int i;
34+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
35+ for(i=0; i<vkuu->number_of_packets; i++) {
36+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
37+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].actual_length", (Addr)&vkuu->iso_frame_desc[i].actual_length, sizeof(vkuu->iso_frame_desc[i].actual_length));
38+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
39+ total_length += vkuu->iso_frame_desc[i].length;
40+ }
41+ if (vkuu->endpoint & 0x80)
42+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
43+ else
44+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
45+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
46+ } else {
47+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
48+ if (vkuu->endpoint & 0x80)
49+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
50+ else
51+ PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
52+ PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
53+ }
54 break;
55 }
56+ case VKI_USBDEVFS_DISCARDURB:
57+ break;
58 case VKI_USBDEVFS_REAPURB:
59+ if ( ARG3 ) {
60+ PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
61+ break;
62+ }
63 case VKI_USBDEVFS_REAPURBNDELAY:
64 if ( ARG3 ) {
65- PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB)", ARG3, sizeof(struct vki_usbdevfs_urb *));
66+ PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
67 break;
68 }
69 case VKI_USBDEVFS_CONNECTINFO:
70@@ -4986,11 +5019,31 @@
71 case VKI_USBDEVFS_REAPURBNDELAY:
72 if ( ARG3 ) {
73 struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
74+ POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
75 if (!*vkuu)
76 break;
77 POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
78- if ((*vkuu)->endpoint & 0x80)
79- POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
80+ if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
81+ struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
82+ if (vkusp->bRequestType & 0x80)
83+ POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
84+ POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
85+ } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
86+ char *bp = (*vkuu)->buffer;
87+ int i;
88+ for(i=0; i<(*vkuu)->number_of_packets; i++) {
89+ POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
90+ POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
91+ if ((*vkuu)->endpoint & 0x80)
92+ POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
93+ bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
94+ }
95+ POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
96+ } else {
97+ if ((*vkuu)->endpoint & 0x80)
98+ POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
99+ POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
100+ }
101 break;
102 }
103 case VKI_USBDEVFS_CONNECTINFO:
104diff -ur -x '*~' valgrind-3.4.1/include/vki/vki-linux.h valgrind-3.4.1-mod/include/vki/vki-linux.h
105--- valgrind-3.4.1/include/vki/vki-linux.h 2009-03-01 22:46:45.000000000 +0100
106+++ valgrind-3.4.1-mod/include/vki/vki-linux.h 2009-04-29 15:42:05.000000000 +0200
107@@ -2325,11 +2325,26 @@
108 #define VKI_USBDEVFS_BULK _VKI_IOWR('U', 2, struct vki_usbdevfs_bulktransfer)
109 #define VKI_USBDEVFS_GETDRIVER _VKI_IOW('U', 8, struct vki_usbdevfs_getdriver)
110 #define VKI_USBDEVFS_SUBMITURB _VKI_IOR('U', 10, struct vki_usbdevfs_urb)
111+#define VKI_USBDEVFS_DISCARDURB _VKI_IO('U', 11)
112 #define VKI_USBDEVFS_REAPURB _VKI_IOW('U', 12, void *)
113 #define VKI_USBDEVFS_REAPURBNDELAY _VKI_IOW('U', 13, void *)
114 #define VKI_USBDEVFS_CONNECTINFO _VKI_IOW('U', 17, struct vki_usbdevfs_connectinfo)
115 #define VKI_USBDEVFS_IOCTL _VKI_IOWR('U', 18, struct vki_usbdevfs_ioctl)
116
117+#define VKI_USBDEVFS_URB_TYPE_ISO 0
118+#define VKI_USBDEVFS_URB_TYPE_INTERRUPT 1
119+#define VKI_USBDEVFS_URB_TYPE_CONTROL 2
120+#define VKI_USBDEVFS_URB_TYPE_BULK 3
121+
122+// this is missing in usbdevice_fs.h
123+struct vki_usbdevfs_setuppacket {
124+ __vki_u8 bRequestType;
125+ __vki_u8 bRequest;
126+ __vki_u16 wValue;
127+ __vki_u16 wIndex;
128+ __vki_u16 wLength;
129+};
130+
131 //----------------------------------------------------------------------
132 // From linux-2.6.20.1/include/linux/i2c.h
133 //----------------------------------------------------------------------
diff --git a/usbmuxd/usb-linux.c b/usbmuxd/usb-linux.c
index b401cde..44eba2c 100644
--- a/usbmuxd/usb-linux.c
+++ b/usbmuxd/usb-linux.c
@@ -138,7 +138,7 @@ int usb_send(struct usb_device *dev, const unsigned char *buf, int length)
138 libusb_free_transfer(xfer); 138 libusb_free_transfer(xfer);
139 return res; 139 return res;
140 } 140 }
141 collection_add(&dev->tx_xfers, xfer);/* 141 collection_add(&dev->tx_xfers, xfer);
142 if((length % 512) == 0) { 142 if((length % 512) == 0) {
143 usbmuxd_log(LL_DEBUG, "Send ZLP"); 143 usbmuxd_log(LL_DEBUG, "Send ZLP");
144 // Send Zero Length Packet 144 // Send Zero Length Packet
@@ -152,7 +152,7 @@ int usb_send(struct usb_device *dev, const unsigned char *buf, int length)
152 return res; 152 return res;
153 } 153 }
154 collection_add(&dev->tx_xfers, xfer); 154 collection_add(&dev->tx_xfers, xfer);
155 }*/ 155 }
156 return 0; 156 return 0;
157} 157}
158 158
diff --git a/usbmuxd/usb.h b/usbmuxd/usb.h
index 8a48308..7eea707 100644
--- a/usbmuxd/usb.h
+++ b/usbmuxd/usb.h
@@ -29,16 +29,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 29
30// libusb fragments packets larger than this (usbfs limitation) 30// libusb fragments packets larger than this (usbfs limitation)
31// on input, this creates race conditions and other issues 31// on input, this creates race conditions and other issues
32// I don't think the device uses larger packets
33// if it does then we're going to have to implement proper framing...
34#define USB_MRU 16384 32#define USB_MRU 16384
35 33
36// max transmission packet size 34// max transmission packet size
37// libusb fragments these too, but doesn't send ZLPs so we're safe 35// libusb fragments these too, but doesn't send ZLPs so we're safe
38// but maybe we need to send a ZLP ourselves at the end (see usb-linux.h) 36// but we need to send a ZLP ourselves at the end (see usb-linux.c)
39// we're using 3 * 16384 to optimize for the fragmentation 37// we're using 3 * 16384 to optimize for the fragmentation
40// this results in three URBs per full transfer, 32 USB packets each 38// this results in three URBs per full transfer, 32 USB packets each
41// if there are ZLP issues this should make them show up too 39// if there are ZLP issues this should make them show up easily too
42#define USB_MTU (3 * 16384) 40#define USB_MTU (3 * 16384)
43 41
44#define USB_PACKET_SIZE 512 42#define USB_PACKET_SIZE 512