Skip to content

Commit 9c8789a

Browse files
authored
feat(grpc): wait for edl device (#58)
* feat(grpc): wait for edl device * use list command instead
1 parent a4b61fe commit 9c8789a

3 files changed

Lines changed: 65 additions & 18 deletions

File tree

internal/updater/artifacts/download_resources.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set -e
55
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
66

77
REPO="arduino/qdl-packing"
8-
TAG="v2.2-22"
8+
TAG="add-list-command-25"
99

1010
# Remove existing resource directories if they exist
1111
rm -rf $BASE_DIR/resources_*

internal/updater/flasher.go

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ package updater
1818
import (
1919
"context"
2020
"encoding/hex"
21+
"errors"
2122
"fmt"
23+
"log/slog"
24+
"os/exec"
2225
"runtime"
2326
"strconv"
2427
"strings"
28+
"time"
2529

2630
"github.com/arduino/go-paths-helper"
2731
"github.com/fatih/color"
@@ -104,27 +108,13 @@ type FlashEvent struct {
104108
type FlashCallback func(FlashEvent)
105109

106110
func FlashBoard(ctx context.Context, downloadedImagePath *paths.Path, version string, preserveUser bool, callback FlashCallback) error {
107-
flashDir, err := searchForFlashDir(downloadedImagePath)
108-
if err != nil {
109-
return err
110-
}
111-
112-
qdlDir, err := paths.MkTempDir("", "qdl-")
111+
qdlPath, cleanup, err := installQdl()
113112
if err != nil {
114113
return err
115114
}
116-
defer func() { _ = qdlDir.RemoveAll() }()
117-
118-
qdlPath := qdlDir.Join("qdl")
119-
if runtime.GOOS == "windows" {
120-
qdlPath = qdlDir.Join("qdl.exe")
121-
}
115+
defer cleanup()
122116

123-
err = qdlPath.WriteFile(artifacts.QdlBinary)
124-
if err != nil {
125-
return err
126-
}
127-
err = qdlPath.Chmod(0755)
117+
flashDir, err := searchForFlashDir(downloadedImagePath)
128118
if err != nil {
129119
return err
130120
}
@@ -223,6 +213,27 @@ func searchForFlashDir(extractPath *paths.Path) (*paths.Path, error) {
223213
}
224214
}
225215

216+
func installQdl() (*paths.Path, func(), error) {
217+
qdlDir, err := paths.MkTempDir("", "qdl-")
218+
if err != nil {
219+
return nil, nil, err
220+
}
221+
222+
qdlPath := qdlDir.Join("qdl")
223+
if runtime.GOOS == "windows" {
224+
qdlPath = qdlDir.Join("qdl.exe")
225+
}
226+
227+
if err = qdlPath.WriteFile(artifacts.QdlBinary); err != nil {
228+
return nil, nil, err
229+
}
230+
if err = qdlPath.Chmod(0755); err != nil {
231+
return nil, nil, err
232+
}
233+
234+
return qdlPath, func() { _ = qdlDir.RemoveAll() }, nil
235+
}
236+
226237
// Checks the board GPT table and counts the number of partitions, this tells if the board supports preserving or not user's data.
227238
func checkBoardGPTTable(ctx context.Context, qdlPath, flashDir *paths.Path) error {
228239
dumpBinPath := qdlPath.Parent().Join("dump.bin")
@@ -272,3 +283,35 @@ func checkBoardGPTTable(ctx context.Context, qdlPath, flashDir *paths.Path) erro
272283

273284
return nil
274285
}
286+
287+
// WantForQdlDevice waits for a QDL device to be connected.
288+
// This is like and hack because QDL does not have a specific command to wait for a device,
289+
// so we use the read command with a dummy ELF and XML file to detect when a device is connected.
290+
func WaitForQdlDevice(ctx context.Context) error {
291+
qdlPath, cleanup, err := installQdl()
292+
if err != nil {
293+
return err
294+
}
295+
defer cleanup()
296+
297+
for {
298+
cmd, err := paths.NewProcess(nil, qdlPath.String(), "--list")
299+
if err != nil {
300+
return err
301+
}
302+
if out, err := cmd.RunAndCaptureCombinedOutput(ctx); err != nil {
303+
slog.Debug("wait for qdl device command exit", "out", string(out), "err", err)
304+
var exitErr *exec.ExitError
305+
if errors.As(err, &exitErr) {
306+
if exitErr.ExitCode() != 1 {
307+
return fmt.Errorf("error waiting for QDL device: %w: %s", err, out)
308+
}
309+
}
310+
} else {
311+
slog.Debug("qdl device detected", "out", string(out))
312+
return nil
313+
}
314+
315+
time.Sleep(1 * time.Second)
316+
}
317+
}

service/service_flash.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ func (s *flasherServerImpl) Flash(req *flasher.FlashRequest, stream flasher.Flas
6767
}
6868
}
6969

70+
if err := updater.WaitForQdlDevice(ctx); err != nil {
71+
return fmt.Errorf("could not find connected Arduino Uno QDL device: %w", err)
72+
}
73+
7074
rel, err := client.GetReleaseByVersion(ctx, req.GetVersion())
7175
if err != nil {
7276
return fmt.Errorf("could not get release info: %w", err)

0 commit comments

Comments
 (0)