Пример #1
0
        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();
            }
        }
Пример #2
0
        /**
         * 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);
        }
Пример #3
0
        /**
         * Read and parse an ADB message from the supplied input stream.
         * This message is NOT validated.
         * @param in InputStream object to read data from
         * @return An AdbMessage object represented the message read
         */
        public static AdbMessage ReadAdbMessage(BinaryStream inStream)
        {
            AdbMessage msg = new AdbMessage();

            inStream.IsLittleEndian = true;

            /* Pull out header fields */
            msg.command = inStream.ReadUInt32();
            msg.arg0    = inStream.ReadUInt32();
            msg.arg1    = inStream.ReadUInt32();
            uint payloadLength = inStream.ReadUInt32();
            uint checksum      = inStream.ReadUInt32();
            uint magic         = inStream.ReadUInt32();

            if (msg.command != (magic ^ 0xFFFFFFFF))
            {
                throw new IOException("message error");
            }

            /* If there's a payload supplied, read that too */
            if (payloadLength > 0)
            {
                msg.payload = new byte[payloadLength];
                inStream.Fill(msg.payload);

                if (GetPayloadChecksum(msg.payload) != checksum)
                {
                    throw new IOException("checksum error");
                }
            }

            return(msg);
        }
Пример #4
0
        /**
         * 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();
        }
Пример #5
0
        /**
         * This function generates an ADB message given the fields.
         * @param cmd Command identifier
         * @param arg0 First argument
         * @param arg1 Second argument
         * @param payload Data payload
         * @return Byte array containing the message
         */

        public static AdbMessage GenerateMessage(uint cmd, uint arg0, uint arg1, byte[] payload, int offset, int count)
        {
            AdbMessage message = new AdbMessage()
            {
                command = cmd,
                arg0    = arg0,
                arg1    = arg1
            };

            if (count > 0 && payload != null)
            {
                message.payload = new byte[count];
                Array.Copy(payload, 0, message.payload, offset, count);
            }
            else
            {
                message.payload = payload;
            }

            return(message);
        }
Пример #6
0
 internal void Send(AdbMessage packet)
 {
     packet.WriteTo(stream);
 }
Пример #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;
            }
        }