USB comms between Desktop and iOS

Hi,

I’m looking for a way to communicate between two juce apps, one running on a desktop PC (Win/Mac), one on an iOS device. I already have communications implemented over WiFi/LAN using juce::InterprocessConnection, which works like a charm. But now I’d also like to support comms over USB.

After some google research I think I’ll have to use usbmuxd (https://github.com/libimobiledevice/usbmuxd) for this, but a quick attempt at “throwing” it into the project and do a build with things included proved difficult so far. Am I on the right path with this or is there a better solution to accomplish communication alá InterprocessConnection using USB?

If the host computer is already setup to talk to the iOS device (any mac, Windows with iTunes installed) then you don’t need usbmuxd as the system already provides it. You will need a library to interface with usbmuxd. Instead I believe you want https://github.com/libimobiledevice/libimobiledevice

Or maybe https://github.com/libimobiledevice/libusbmuxd

I seem to recall this was a giant pain in the ass to compile for Windows. I did manage to find Windows binaries at one point, but they were 32-bit.

There is also peertalk which is a lot easier to use, but maybe the desktop side is mac only. I forget: https://github.com/rsms/peertalk

1 Like

Thanks for the links! I’ll check these out, libimobiledevice looks promising

So, I’m successfully connecting to my iPad through libimobiledevice. Hooray. Thanks for pointing me to this.

When establishing the connection, the service does however determine the port that is used (usbmuxd is basically binding to a network port on the iOS device). I know the port number that it’s connected to in my desktop app, but how do I now communicate this to the iOS device so the app on that end “knows” what port to listen to?

My guess is that I’ll have to broadcast it, but I’m not sure how to approach that. How do I let my iOS app know what port my desktop app is using through libimobiledevice? Any more awesome guidance @RolandMR :slight_smile: ?

It’s been a long time since I did this. I thought there was a way to specify the port you wanted to connect to on the iOS device. Then I just hardcoded the iOS device to use that port.

Well if that’s the case, that helps already :slight_smile: I’ll go on a hunt for a way to set the port then :slight_smile:

So maybe I’m still misunderstanding something about how to approach this… This is a simplified version of what I’m doing. In my actual code I obviously check results of all library calls, manage lifetimes and so on, but assuming all calls return success codes this is what it boils down to:

char ** deviceUdids;
int count { 0 };
idevice_get_device_list (&deviceUdids, &count);

idevice_t* dev { new idevice_t() };
idevice_options options { IDEVICE_LOOKUP_USBMUX };
idevice_new_with_options(dev, deviceUdids[0], options);

lockdownd_client_t control = NULL;
lockdownd_client_new_with_handshake (*dev, &control, “MyAppName”);

lockdownd_service_descriptor_t* service { new lockdownd_service_descriptor_t() };
lockdownd_start_service (control, "com.apple.afc", service);

idevice_connection_t* connection { new idevice_connection_t () };
idevice_connect (*dev, (*service)->port, connection);

When doing it like this idevice_connect returns success and I now have an active connection to my connected device.

The port field in lockdownd_service_descriptor_t* service is filled by lockdownd_start_service. I don’t see a way to define that. As I understand from the following thread, lockdownd_start_service returns a port number to me and i have to use that one for the idevice_connect call, which initialises my idevice_connection_t* connection, through which I then can send data…


Am I misunderstanding something here?