Rajat Saini
Rajat Saini

Reputation: 557

Developing iTunes like application in c#

I need to develop an application in c# that could automatically detect an iPhone when it is connected to the system and read a particular file for the iPhone file system. I basically want this file to be downloaded automatically from device to the PC. I used USBpcap tool that suggests that iTunes connects to phone using some XML format. Any help or insight greatly appreciated. Is there any documentation of Third party APIs that can get me started? There are some applications that can replicate iTunes functionality e.g Copytrans

Is there any protocol or APIs provided by Apple?

I have been digging the internet and found this link Layered communication for iPhone. Also I am using the LibUsbDotNet libraries for communicating to the usb device(Example). Can any one suggest which EndPoints should be used.

It seems to me that I have to implement usbmuxd in windows application. It is a multilayer protocol. There must be some libraries that implement usbmuxd(I dont think I have to implement the protocol all by my self)

I dont have much idea about iTunes communication as well as USB communication. I am adding as much information as I can(of course with the things I come up with in my R&D). Any help is highly appreciated.

public static DateTime LastDataEventDate = DateTime.Now;
    public static UsbDevice MyUsbDevice;

    #region SET YOUR USB Vendor and Product ID!

    public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(1452, 4768);

    #endregion

    private void LibUSB()
    {
        ErrorCode ec = ErrorCode.None;

        try
        {
            // Find and open the usb device.
            MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

            // If the device is open and ready
            if (MyUsbDevice == null)
                throw new Exception("Device Not Found.");

            // If this is a "whole" usb device (libusb-win32, linux libusb)
            // it will have an IUsbDevice interface. If not (WinUSB) the 
            // variable will be null indicating this is an interface of a 
            // device.
            IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
            if (!ReferenceEquals(wholeUsbDevice, null))
            {
                // This is a "whole" USB device. Before it can be used, 
                // the desired configuration and interface must be selected.

                // Select config #1
                wholeUsbDevice.SetConfiguration(1);

                // Claim interface #0.
                wholeUsbDevice.ClaimInterface(0);
            }

            // open read endpoint 1.
            UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep03);

            // open write endpoint 1.
            UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep02);


                int bytesWritten;
                ec = writer.Write(usbmux_header.GetBytes(), 2000, out bytesWritten);
                if (ec != ErrorCode.None)
                    throw new Exception(UsbDevice.LastErrorString);

                byte[] readBuffer = new byte[1024];
                while (ec == ErrorCode.None)
                {
                    int bytesRead;

                    // If the device hasn't sent data in the last 100 milliseconds,
                    // a timeout error (ec = IoTimedOut) will occur. 
                    ec = reader.Read(readBuffer, 10000, out bytesRead);

                    if (ec == ErrorCode.Win32Error)
                        throw new Exception("port not open");
                    if (bytesRead == 0)
                        throw new Exception("No more bytes!");

                    // Write that output to the console.
                    Console.Write(Encoding.Default.GetString(readBuffer, 0, bytesRead));
                }

        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine((ec != ErrorCode.None ? ec + ":" : String.Empty) + ex.Message);
        }
        finally
        {
            if (MyUsbDevice != null)
            {
                if (MyUsbDevice.IsOpen)
                {
                    // If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
                    // it exposes an IUsbDevice interface. If not (WinUSB) the 
                    // 'wholeUsbDevice' variable will be null indicating this is 
                    // an interface of a device; it does not require or support 
                    // configuration and interface selection.
                    IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
                    if (!ReferenceEquals(wholeUsbDevice, null))
                    {
                        // Release interface #0.
                        wholeUsbDevice.ReleaseInterface(0);
                    }

                    MyUsbDevice.Close();
                }
                MyUsbDevice = null;

                // Free usb resources
                UsbDevice.Exit();

            }
        }
    }

class usbmux_header
{
    public static UInt32 length = 10;   // length of message, including header
    public static UInt32 reserved = 0;  // always zero
    public static UInt32 type = 3;       // message type
    public static UInt32 tag = 2;   // responses to this query will echo back this tag

    public static byte[] GetBytes()
    {
        byte[] lgth = BitConverter.GetBytes(length);
        byte[] res = BitConverter.GetBytes(reserved);
        byte[] tpe = BitConverter.GetBytes(type);
        byte[] tg = BitConverter.GetBytes(tag);

        byte[] retArray = new byte[16];
        lgth.CopyTo(retArray, 0);
        res.CopyTo(retArray, 4);
        tpe.CopyTo(retArray, 8);
        tg.CopyTo(retArray, 12);

        return retArray;
    }
};

I have been trying to send hello packet bytes to iPhone but I am not able to read any response from phone.

Upvotes: 6

Views: 1388

Answers (3)

Frederik Carlier
Frederik Carlier

Reputation: 4776

You can use imobiledevice-net. It provides a C# API to connect to iOS devices using your PC.

For example, to list all iOS devices connected to your PC, you would run something like this:

ReadOnlyCollection<string> udids;
int count = 0;

var idevice = LibiMobileDevice.Instance.iDevice;
var lockdown = LibiMobileDevice.Instance.Lockdown;

var ret = idevice.idevice_get_device_list(out udids, ref count);

if (ret == iDeviceError.NoDevice)
{
    // Not actually an error in our case
    return;
}

ret.ThrowOnError();

// Get the device name
foreach (var udid in udids)
{
    iDeviceHandle deviceHandle;
    idevice.idevice_new(out deviceHandle, udid).ThrowOnError();

    LockdownClientHandle lockdownHandle;
    lockdown.lockdownd_client_new_with_handshake(deviceHandle, out lockdownHandle, "Quamotion").ThrowOnError();

    string deviceName;
    lockdown.lockdownd_get_device_name(lockdownHandle, out deviceName).ThrowOnError();

    deviceHandle.Dispose();
    lockdownHandle.Dispose();
}

Upvotes: 0

DaveHowell
DaveHowell

Reputation: 1264

As I understand it, only one client can use the USB connection to iOS at one time. On both macOS and Windows, that one client is usbmux. That library multiplexes TCP connections with higher-level clients, including iTunes, Photos, and (on macOS) the open-source peertalk library.

So on Windows, you wouldn't want to implement your own usbmux, but rather a client that sits on top of that, analogous to peertalk. I haven't seen anything open-source that does this, but a number of developers have accomplished it with their own proprietary software.

If anybody else has pointers about using usbmux on Windows, I'd love to hear about it.

—Dave

Upvotes: 0

Mauro Sampietro
Mauro Sampietro

Reputation: 2814

To play with ipod you can use SharePodLib

Upvotes: 0

Related Questions