protected void Write(byte[] payload, int offset, int count, bool flush)
        {
            lock (this)
            {
                /* Make sure we're ready for a write */
                while (!isClosed && !writeReady)
                {
                    Monitor.Wait(this);
                }
                Thread.MemoryBarrier();
                writeReady = false;

                if (isClosed)
                {
                    throw new IOException("Stream closed");
                }
            }

            /* Generate a WRITE packet and send it */
            AdbMessage packet = AdbProtocol.GenerateWrite(localId, remoteId, payload, offset, count);

            adbConn.Send(packet);

            if (flush)
            {
                adbConn.Flush();
            }
        }
        /**
         * Called by the connection thread to send an OKAY packet, allowing the
         * other side to continue transmission.
         */
        internal void SendReady()
        {
            /* Generate and send a READY packet */
            AdbMessage packet = AdbProtocol.GenerateReady(localId, remoteId);

            adbConn.Send(packet);
        }
Exemple #3
0
        /**
         * Connects to the remote device. This routine will block until the connection
         * completes.
         */
        public void Connect()
        {
            if (connected)
            {
                throw new IOException("Already connected");
            }

            /* Write the CONNECT packet */
            Send(AdbProtocol.GenerateConnect());


            /* Start the connection thread to respond to the peer */
            connectAttempted = true;

            this.connectionThread = new Thread(Run)
            {
                IsBackground = true
            };
            this.connectionThread.Start();

            /* Wait for the connection to go live */
            lock (this)
            {
                if (!connected)
                {
                    Monitor.Wait(this);
                }

                if (!connected)
                {
                    throw new IOException("Connection failed");
                }
            }
        }
Exemple #4
0
        /**
         * Opens an AdbStream object corresponding to the specified destination.
         * This routine will block until the connection completes.
         * @param destination The destination to open on the target
         * @return AdbStream object corresponding to the specified destination
         */
        private T Open <T>(String destination)
            where T : AdbSessionBase
        {
            uint localId = ++lastLocalId;

            if (!connectAttempted)
            {
                throw new IOException("connect() must be called first");
            }

            /* Wait for the connect response */
            lock (this)
            {
                if (!connected)
                {
                    Monitor.Wait(this);
                }

                if (!connected)
                {
                    throw new IOException("Connection failed");
                }
            }

            /* Add this stream to this list of half-open streams */
            T stream = Activator.CreateInstance(typeof(T), this, localId) as T;

            openStreams.Add(localId, stream);

            /* Send the open */
            Send(AdbProtocol.GenerateOpen(localId, destination));


            /* Wait for the connection thread to receive the OKAY */
            lock (stream)
            {
                Monitor.Wait(stream);
            }

            /* Check if the open was rejected */
            if (stream.IsClosed)
            {
                throw new IOException("Stream open actively rejected by remote peer");
            }

            /* We're fully setup now */
            return(stream);
        }
        /**
         * Closes the stream. This sends a close message to the peer.
         */

        public void Close()
        {
            lock (this)
            {
                /* This may already be closed by the remote host */
                if (isClosed)
                {
                    return;
                }

                /* Notify readers/writers that we've closed */
                NotifyClose();
            }

            AdbMessage packet = AdbProtocol.GenerateClose(localId, remoteId);

            adbConn.Send(packet);
            adbConn.Flush();
        }
Exemple #6
0
 public void Reboot()
 {
     Send(AdbProtocol.GenerateOpen(++lastLocalId, "reboot:"));
     Close();
 }
Exemple #7
0
        public void Run()
        {
            while (true)
            {
                try
                {
                    /* Read and parse a message off the socket's input stream */
                    AdbMessage msg = AdbMessage.ReadAdbMessage(stream);



                    switch (msg.command)
                    {
                    /* Stream-oriented commands */
                    case AdbProtocol.CMD_OKAY:
                    case AdbProtocol.CMD_WRTE:
                    case AdbProtocol.CMD_CLSE:
                        /* We must ignore all packets when not connected */
                        if (!connected)
                        {
                            continue;
                        }

                        /* Get the stream object corresponding to the packet */
                        AdbSessionBase waitingStream;
                        if (!openStreams.TryGetValue(msg.arg1, out waitingStream))
                        {
                            continue;
                        }



                        lock (waitingStream)
                        {
                            if (msg.command == AdbProtocol.CMD_OKAY)
                            {
                                /* We're ready for writes */
                                waitingStream.UpdateRemoteId(msg.arg0);
                                waitingStream.ReadyForWrite();

                                /* Unwait an open/write */
                                Monitor.Pulse(waitingStream);
                            }
                            else if (msg.command == AdbProtocol.CMD_WRTE)
                            {
                                /* Got some data from our partner */
                                waitingStream.AddPayload(msg.payload);

                                /* Tell it we're ready for more */
                                waitingStream.SendReady();
                            }
                            else if (msg.command == AdbProtocol.CMD_CLSE)
                            {
                                /* He doesn't like us anymore :-( */
                                openStreams.Remove(msg.arg1);

                                /* Notify readers and writers */
                                waitingStream.NotifyClose();
                            }
                        }

                        break;

                    case AdbProtocol.CMD_AUTH:

                        AdbMessage packet;

                        if (msg.arg0 == AdbProtocol.AUTH_TYPE_TOKEN)
                        {
                            /* This is an authentication challenge */
                            if (sentSignature)
                            {
                                /* We've already tried our signature, so send our public key */
                                packet = AdbProtocol.GenerateAuth(AdbProtocol.AUTH_TYPE_RSA_PUBLIC,
                                                                  crypto.GetAdbPublicKeyPayload());
                            }
                            else
                            {
                                /* We'll sign the token */
                                packet = AdbProtocol.GenerateAuth(AdbProtocol.AUTH_TYPE_SIGNATURE,
                                                                  crypto.SignAdbTokenPayload(msg.payload));
                                sentSignature = true;
                            }

                            /* Write the AUTH reply */
                            packet.WriteTo(stream);
                        }
                        break;

                    case AdbProtocol.CMD_CNXN:
                        lock (this)
                        {
                            /* We need to store the max data size */
                            maxData = (int)msg.arg1;

                            /* Mark us as connected and unwait anyone waiting on the connection */
                            connected = true;
                            //conn.notifyAll();
                            Monitor.PulseAll(this);
                        }
                        break;

                    default:
                        /* Unrecognized packet, just drop it */
                        break;
                    }
                }
                catch (ThreadAbortException)
                {
                    /* The cleanup is taken care of by a combination of this thread
                     * and close() */
                    break;
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e);
                    break;
                }
            }

            /* This thread takes care of cleaning up pending streams */
            lock (this)
            {
                CleanupStreams();
                Monitor.PulseAll(this);
                connectAttempted = false;
            }
        }