// Dial connects to the adb server on the host and port set on the netDialer. // The zero-value will connect to the default, localhost:5037. func (d *netDialer) Dial() (*wire.Conn, error) { host := d.Host port := d.Port address := fmt.Sprintf("%s:%d", host, port) netConn, err := net.Dial("tcp", address) if err != nil { // Attempt to start the server and try again. if err = StartServer(); err != nil { return nil, util.WrapErrorf(err, util.ServerNotAvailable, "error starting server") } address = fmt.Sprintf("%s:%d", host, port) netConn, err = net.Dial("tcp", address) if err != nil { return nil, util.WrapErrorf(err, util.ServerNotAvailable, "error dialing %s", address) } } conn := &wire.Conn{ Scanner: wire.NewScanner(netConn), Sender: wire.NewSender(netConn), } // Prevent leaking the network connection, not sure if TCPConn does this itself. runtime.SetFinalizer(netConn, func(conn *net.TCPConn) { conn.Close() }) return conn, nil }
func (s *realSyncSender) SendString(str string) error { length := len(str) if length > MaxChunkSize { // This limit might not apply to filenames, but it's big enough // that I don't think it will be a problem. return util.AssertionErrorf("str must be <= %d in length", MaxChunkSize) } if err := s.SendInt32(int32(length)); err != nil { return util.WrapErrorf(err, util.NetworkError, "error sending string length on sync sender") } return util.WrapErrorf(writeFully(s.Writer, []byte(str)), util.NetworkError, "error sending string on sync sender") }
func (s *realSyncScanner) ReadString() (string, error) { length, err := s.ReadInt32() if err != nil { return "", util.WrapErrorf(err, util.NetworkError, "error reading length from sync scanner") } bytes := make([]byte, length) n, rawErr := io.ReadFull(s.Reader, bytes) if rawErr != nil && rawErr != io.ErrUnexpectedEOF { return "", util.WrapErrorf(rawErr, util.NetworkError, "error reading string from sync scanner") } else if rawErr == io.ErrUnexpectedEOF { return "", errIncompleteMessage("bytes", n, int(length)) } return string(bytes), nil }
func (s *realScanner) ReadUntilEof() ([]byte, error) { data, err := ioutil.ReadAll(s.reader) if err != nil { return nil, util.WrapErrorf(err, util.NetworkError, "error reading until EOF") } return data, nil }
func (s *realSyncScanner) ReadBytes() (io.Reader, error) { length, err := s.ReadInt32() if err != nil { return nil, util.WrapErrorf(err, util.NetworkError, "error reading bytes from sync scanner") } return io.LimitReader(s.Reader, int64(length)), nil }
func (s *realSyncScanner) ReadTime() (time.Time, error) { seconds, err := s.ReadInt32() if err != nil { return time.Time{}, util.WrapErrorf(err, util.NetworkError, "error reading time from sync scanner") } return time.Unix(int64(seconds), 0).UTC(), nil }
// Reads the status, and if failure, reads the message and returns it as an error. // If the status is success, doesn't read the message. // req is just used to populate the AdbError, and can be nil. func ReadStatusFailureAsError(s Scanner, req string) error { status, err := s.ReadStatus() if err != nil { return util.WrapErrorf(err, util.NetworkError, "error reading status for %s", req) } if !status.IsSuccess() { msg, err := s.ReadMessage() if err != nil { return util.WrapErrorf(err, util.NetworkError, "server returned error for %s, but couldn't read the error message", req) } return adbServerError(req, string(msg)) } return nil }
func (s *realSyncScanner) ReadFileMode() (os.FileMode, error) { var value uint32 err := binary.Read(s.Reader, binary.LittleEndian, &value) if err != nil { return 0, util.WrapErrorf(err, util.NetworkError, "error reading filemode from sync scanner") } return ParseFileModeFromAdb(value), nil }
func (c *HostClient) parseServerVersion(versionRaw []byte) (int, error) { versionStr := string(versionRaw) version, err := strconv.ParseInt(versionStr, 16, 32) if err != nil { return 0, util.WrapErrorf(err, util.ParseError, "error parsing server version: %s", versionStr) } return int(version), nil }
func RequireOctetString(s SyncScanner, expected string) error { actual, err := s.ReadOctetString() if err != nil { return util.WrapErrorf(err, util.NetworkError, "expected to read '%s'", expected) } if actual != expected { return util.AssertionErrorf("expected to read '%s', got '%s'", expected, actual) } return nil }
func (s *realSyncSender) SendOctetString(str string) error { if len(str) != 4 { return util.AssertionErrorf("octet string must be exactly 4 bytes: '%s'", str) } wrappedErr := util.WrapErrorf(writeFully(s.Writer, []byte(str)), util.NetworkError, "error sending octet string on sync sender") return wrappedErr }
// writeFully writes all of data to w. // Inverse of io.ReadFully(). func writeFully(w io.Writer, data []byte) error { offset := 0 for offset < len(data) { n, err := w.Write(data[offset:]) if err != nil { return util.WrapErrorf(err, util.NetworkError, "error writing %d bytes at offset %d", len(data), offset) } offset += n } return nil }
func (s *realScanner) ReadStatus() (StatusCode, error) { status := make([]byte, 4) n, err := io.ReadFull(s.reader, status) if err != nil && err != io.ErrUnexpectedEOF { return "", util.WrapErrorf(err, util.NetworkError, "error reading status") } else if err == io.ErrUnexpectedEOF { return StatusCode(status), errIncompleteMessage("status", n, 4) } return StatusCode(status), nil }
func (s *MockServer) ReadMessage() ([]byte, error) { s.logMethod("ReadMessage") if err := s.getNextErrToReturn(); err != nil { return nil, err } if s.nextMsgIndex >= len(s.Messages) { return nil, util.WrapErrorf(io.EOF, util.NetworkError, "") } s.nextMsgIndex++ return []byte(s.Messages[s.nextMsgIndex-1]), nil }
func (s *realSyncScanner) ReadOctetString() (string, error) { octet := make([]byte, 4) n, err := io.ReadFull(s.Reader, octet) if err != nil && err != io.ErrUnexpectedEOF { return "", util.WrapErrorf(err, util.NetworkError, "error reading octet string from sync scanner") } else if err == io.ErrUnexpectedEOF { return "", errIncompleteMessage("octet", n, 4) } return string(octet), nil }
func (s *realScanner) ReadMessage() ([]byte, error) { var err error length, err := s.readLength() if err != nil { return nil, err } data := make([]byte, length) n, err := io.ReadFull(s.reader, data) if err != nil && err != io.ErrUnexpectedEOF { return data, util.WrapErrorf(err, util.NetworkError, "error reading message data") } else if err == io.ErrUnexpectedEOF { return data, errIncompleteMessage("message data", n, length) } return data, nil }
func (s *realScanner) readLength() (int, error) { lengthHex := make([]byte, 4) n, err := io.ReadFull(s.reader, lengthHex) if err != nil { return 0, errIncompleteMessage("length", n, 4) } length, err := strconv.ParseInt(string(lengthHex), 16, 64) if err != nil { return 0, util.WrapErrorf(err, util.NetworkError, "could not parse hex length %v", lengthHex) } // Clip the length to 255, as per the Google implementation. if length > MaxMessageLength { length = MaxMessageLength } return int(length), nil }
func (s *realSyncSender) SendTime(t time.Time) error { return util.WrapErrorf(s.SendInt32(int32(t.Unix())), util.NetworkError, "error sending time on sync sender") }
func (s *realSyncSender) SendFileMode(mode os.FileMode) error { return util.WrapErrorf(binary.Write(s.Writer, binary.LittleEndian, mode), util.NetworkError, "error sending filemode on sync sender") }
func (s *realSyncSender) SendInt32(val int32) error { return util.WrapErrorf(binary.Write(s.Writer, binary.LittleEndian, val), util.NetworkError, "error sending int on sync sender") }
func (s *realSyncScanner) Close() error { if closer, ok := s.Reader.(io.Closer); ok { return util.WrapErrorf(closer.Close(), util.NetworkError, "error closing sync scanner") } return nil }
func (s *realSyncScanner) ReadInt32() (int32, error) { var value int32 err := binary.Read(s.Reader, binary.LittleEndian, &value) return value, util.WrapErrorf(err, util.NetworkError, "error reading int from sync scanner") }
func (s *realSender) Close() error { return util.WrapErrorf(s.writer.Close(), util.NetworkError, "error closing sender") }
/* StartServer ensures there is a server running. */ func StartServer() error { cmd := exec.Command("adb", "start-server") err := cmd.Run() return util.WrapErrorf(err, util.ServerNotAvailable, "error starting server: %s", err) }
func (s *realScanner) Close() error { return util.WrapErrorf(s.reader.Close(), util.NetworkError, "error closing scanner") }