camalot / madb

The Original MADB Project. This is a Managed port of the Android Debug Bridge to allow communication from .NET applications to Android devices. This wraps the same methods that the ddms uses to directly communicate with ADB. This gives more flexibility to the developer than launching an adb process and executing one of its build in commands.
http://madb.bit13.com
Other
110 stars 40 forks source link

Implementing adb connect #26

Open camalot opened 8 years ago

camalot commented 8 years ago

Original Bug on CodePlex

This is a patch which adds support for adb connect to madbee.

Although not listed in https://android.googlesource.com/platform/system/core/+/master/adb/SERVICES.TXT, it is a valid adb command. The implementation can be seen in https://android.googlesource.com/platform/system/core/+/master/adb/commandline.c at around line 1328.

The code below adds support for adb connect to madbee. It was implemented as an extension method to AdbHelper, which explains the various this AdbHelper helper statements. They are probably not needed if you decide to integrate this code into madbee.

public static class AdbHelperExtensions
    {
        /// <summary>
        /// The default port to use when connecting to a device over TCP/IP.
        /// </summary>
        private const int DEFAULT_PORT = 5555;

        /// <summary>
        /// Connect to a device via TCP/IP.
        /// </summary>
        /// <param name="helper">
        /// An instance of the <see cref="AdbHelper"/> class.
        /// </param>
        /// <param name="adbEndpoint">
        /// The socket where the <c>adb</c> server is listening.
        /// </param>
        /// <param name="address">
        /// The IP address of the remote device.
        /// </param>
        /// <returns>
        /// <c>0</c> if the operation completed successfully; otherwise,
        /// <c>-1</c>.
        /// </returns>
        public static int Connect(this AdbHelper helper, IPEndPoint adbEndpoint, IPAddress address)
        {
            if(address == null)
            {
                throw new ArgumentNullException("address");
            }

            return helper.Connect(adbEndpoint, new IPEndPoint(address, DEFAULT_PORT));
        }

        /// <summary>
        /// Connect to a device via TCP/IP.
        /// </summary>
        /// <param name="helper">
        /// An instance of the <see cref="AdbHelper"/> class.
        /// </param>
        /// <param name="adbEndpoint">
        /// The socket where the <c>adb</c> server is listening.
        /// </param>
        /// <param name="host">
        /// The host address of the remote device.
        /// </param>
        /// <returns>
        /// <c>0</c> if the operation completed successfully; otherwise,
        /// <c>-1</c>.
        /// </returns>
        public static int Connect(this AdbHelper helper, IPEndPoint adbEndpoint, string host)
        {
            if(string.IsNullOrEmpty(host))
            {
                throw new ArgumentNullException("host");
            }

            return helper.Connect(adbEndpoint, new DnsEndPoint(host, DEFAULT_PORT));
        }

        /// <summary>
        /// Connect to a device via TCP/IP.
        /// </summary>
        /// <param name="helper">
        /// An instance of the <see cref="AdbHelper"/> class.
        /// </param>
        /// <param name="adbEndpoint">
        /// The socket where the <c>adb</c> server is listening.
        /// </param>
        /// <param name="endpoint">
        /// The IP endpoint at which the <c>adb</c> server on the device is running.
        /// </param>
        /// <returns>
        /// <c>0</c> if the operation completed successfully; otherwise,
        /// <c>-1</c>.
        /// </returns>
        public static int Connect(this AdbHelper helper, IPEndPoint adbEndpoint, IPEndPoint endpoint)
        {
            if(endpoint == null)
            {
                throw new ArgumentNullException("endpoint");
            }

            return helper.Connect(adbEndpoint, new DnsEndPoint(endpoint.Address.ToString(), endpoint.Port));
        }

        /// <summary>
        /// Connect to a device via TCP/IP.
        /// </summary>
        /// <param name="helper">
        /// An instance of the <see cref="AdbHelper"/> class.
        /// </param>
        /// <param name="adbEndpoint">
        /// The socket where the <c>adb</c> server is listening.
        /// </param>
        /// <param name="endpoint">
        /// The DNS endpoint at which the <c>adb</c> server on the device is running.
        /// </param>
        /// <returns>
        /// <c>0</c> if the operation completed successfully; otherwise,
        /// <c>-1</c>.
        /// </returns>
        public static int Connect(this AdbHelper helper, IPEndPoint adbEndpoint, DnsEndPoint endpoint)
        {
            if (endpoint == null)
            {
                throw new ArgumentNullException("endpoint");
            }

            byte[] request = helper.FormAdbRequest(string.Format("host:connect:{0}:{1}", endpoint.Host, endpoint.Port));

            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                socket.Connect(adbEndpoint);
                socket.Blocking = true;
                if (!helper.Write(socket, request))
                {
                    throw new IOException("failed submitting request to  adb");
                }
                var resp = helper.ReadAdbResponse(socket, false);
                if (!resp.IOSuccess || !resp.Okay)
                {
                    Log.e(TAG, "Got timeout or unhappy response from ADB req: " + resp.Message);
                    socket.Close();
                    return -1;
                }
                return 0;
            }
        }
    }