Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pkg/board/board.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ func FromFQBN(ctx context.Context, fqbn string) ([]Board, error) {
if name, err := GetCustomName(ctx, conn); err == nil {
customName = name
}
} else {
slog.Warn("failed to get custom name", "serial", serial, "error", err)
}

boards = append(boards, Board{
Expand Down
40 changes: 37 additions & 3 deletions pkg/board/remote/adb/adb.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,48 @@ type ADBConnection struct {
// Ensures ADBConnection implements the RemoteConn interface at compile time.
var _ remote.RemoteConn = (*ADBConnection)(nil)

var (
// ErrNotFound is returned when the ADB device is not found.
ErrNotFound = fmt.Errorf("ADB device not found")
// ErrDeviceOffline is returned when the ADB device is not reachable.
// This usually requires a restart of the adbd server daemon on the device.
ErrDeviceOffline = fmt.Errorf("ADB device is offline")
)

// FromSerial creates an ADBConnection from a device serial number.
// returns an error NotFoundErr if the device is not found, and DeviceOfflineErr if the device is offline.
func FromSerial(serial string, adbPath string) (*ADBConnection, error) {
if adbPath == "" {
adbPath = FindAdbPath()
}

isConnected := func(serial, adbPath string) (bool, error) {
cmd, err := paths.NewProcess(nil, adbPath, "-s", serial, "get-state")
if err != nil {
return false, fmt.Errorf("failed to create ADB command: %w", err)
}

output, err := cmd.RunAndCaptureCombinedOutput(context.TODO())
if err != nil {
if bytes.Contains(output, []byte("device offline")) {
return false, ErrDeviceOffline
} else if bytes.Contains(output, []byte("not found")) {
return false, ErrNotFound
}
return false, fmt.Errorf("failed to get ADB device state: %w: %s", err, output)
}

return string(bytes.TrimSpace(output)) == "device", nil
}
if connected, err := isConnected(serial, adbPath); err != nil {
return nil, err
} else if !connected {
return nil, fmt.Errorf("device %s is not connected", serial)
}

return &ADBConnection{
host: serial,
adbPath: adbPath,
host: serial,
}, nil
}

Expand All @@ -65,8 +99,8 @@ func FromHost(host string, adbPath string) (*ADBConnection, error) {
if err != nil {
return nil, err
}
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("failed to connect to ADB host %s: %w", host, err)
if out, err := cmd.RunAndCaptureCombinedOutput(context.TODO()); err != nil {
return nil, fmt.Errorf("failed to connect to ADB host %s: %w: %s", host, err, out)
}
return FromSerial(host, adbPath)
}
Expand Down