iOSDevCamp2010 Hackathon: iOS USB Sync
To start off, this was my first iOSDevCamp and by far it has proven to be my favorite developer event so far. The rules are simple, your app cannot be in the app store unless it’s open source, and it cannot use private apis or require a jailbroken device.
Prior to iOSDevCamp, I had been looking into Hector Martin’s usbmux implementation for linux. The main goal of his project was to provide usb syncing for iOS devices on linux machines. Upon further investigation, I found usbmux sets up a local socket that relays information to an Apple daemon running on the iOS device. This daemon then relays the information via tcp to other daemons on the device. In short, usbmux allows applications on the desktop to talk to tcp-based servers running on the device without using private APIs or modifications to the OS, all over usb.
My hackathon demo was fairly straight-forward.
1. Make an iPhone app that listens on a predetermined tcp port.
2. Make a Mac app that uses usbmux to talk to the iPhone app tcp server.
Side Note: The mac app can also choose to talk to the iPhone app via wifi without any modification to the iPhone app. Which is beautiful. If Apple comes along and breaks usbmux or adds in protections for app store apps, the mac app can fallback to talking to the device over wifi with no modification to the iPhone app.
Ideally, the mac application would talk directly to the unix domain socket /var/run/usbmuxd. However, due to lack of time from working on other hackathon projects, I took a shortcut. Hector Martin’s usbmuxd source code repo contains a wonderful python utility called tcprelay. Tcprelay forwards any port on the local machine to any port on an iOS device using usbmux. For the demo, I’ve set this up to relay port 20000 on my local machine to my iOS device where my iPhone app is listening.
My client/server setup is using serialized plists to transfer information. The first 32 bits are the size of the data to be received.
To get the demo up and running:
1. Compile Server/Server2 and place it on your iOS device.
2. run “$ ./tcprelay -t 20000:20000″ to relay local port 20000 to remote port 20000 via usbmux.
3. Start up Server/Server2
4. Start the corresponding MacUSBSyncClient. (The server _must_ be running before you start the mac client)
MacUSBSyncClient/Server will send a string and an image for display on the device. Due to my horrible unix socket implementation, the images must be <1mb. MacUSBSyncClient2/Server2 requests the most recent barcode scan from the iPhone. The iPhone server will constantly be checking for bar codes via the camera preview. Upon a successful scan, it saves the barcode image and data. Pressing "Scan" in the client will grab this information from the iPhone and display it on the mac. The product can then be looked up via the "Lookup" button.
I'm working on a much cleaner implementation that I'll be posting asap. It will talk directly to /var/run/usbmuxd instead of requiring tcprelay. However, for those interested, here is the source code I used in the demo at iOSDevCamp2010. Please note it was written in less than a day and is _extremely_ ugly.
For those interested in integrating this into their application. Shoot me an email Max@MaxWeisel.com, I’d love to help!
Max
Posted in Uncategorized | No Comments »






































