1ba991379Sopenharmony_cipackage utils
2ba991379Sopenharmony_ci
3ba991379Sopenharmony_ciimport (
4ba991379Sopenharmony_ci	"context"
5ba991379Sopenharmony_ci	"errors"
6ba991379Sopenharmony_ci	"github.com/sirupsen/logrus"
7ba991379Sopenharmony_ci	"os/exec"
8ba991379Sopenharmony_ci	"strings"
9ba991379Sopenharmony_ci	"time"
10ba991379Sopenharmony_ci)
11ba991379Sopenharmony_ci
12ba991379Sopenharmony_civar hdc string
13ba991379Sopenharmony_ci
14ba991379Sopenharmony_cifunc init() {
15ba991379Sopenharmony_ci	if hdc, _ = exec.LookPath("hdc"); hdc == "" {
16ba991379Sopenharmony_ci		hdc, _ = exec.LookPath("hdc_std")
17ba991379Sopenharmony_ci	}
18ba991379Sopenharmony_ci	if hdc == "" {
19ba991379Sopenharmony_ci		logrus.Panicf("can not find 'hdc', please install")
20ba991379Sopenharmony_ci	}
21ba991379Sopenharmony_ci}
22ba991379Sopenharmony_ci
23ba991379Sopenharmony_cifunc WaitHDC(device string, ctx context.Context) bool {
24ba991379Sopenharmony_ci	ctx, cancelFn := context.WithTimeout(ctx, 20*time.Second)
25ba991379Sopenharmony_ci	defer cancelFn()
26ba991379Sopenharmony_ci	for {
27ba991379Sopenharmony_ci		select {
28ba991379Sopenharmony_ci		case <-ctx.Done():
29ba991379Sopenharmony_ci			return false
30ba991379Sopenharmony_ci		default:
31ba991379Sopenharmony_ci		}
32ba991379Sopenharmony_ci		ExecContext(ctx, hdc, "kill")
33ba991379Sopenharmony_ci		time.Sleep(time.Second)
34ba991379Sopenharmony_ci		ExecContext(ctx, hdc, "start")
35ba991379Sopenharmony_ci		time.Sleep(time.Second)
36ba991379Sopenharmony_ci		out, err := ExecCombinedOutputContext(ctx, hdc, "list", "targets")
37ba991379Sopenharmony_ci		if err != nil {
38ba991379Sopenharmony_ci			if errors.Is(err, context.Canceled) {
39ba991379Sopenharmony_ci				return false
40ba991379Sopenharmony_ci			}
41ba991379Sopenharmony_ci			logrus.Errorf("failed to list hdc targets: %s, %s", string(out), err)
42ba991379Sopenharmony_ci			continue
43ba991379Sopenharmony_ci		}
44ba991379Sopenharmony_ci		lines := strings.Fields(string(out))
45ba991379Sopenharmony_ci		for _, dev := range lines {
46ba991379Sopenharmony_ci			if dev == "[Empty]" {
47ba991379Sopenharmony_ci				logrus.Warn("can not find any hdc targets")
48ba991379Sopenharmony_ci				break
49ba991379Sopenharmony_ci			}
50ba991379Sopenharmony_ci			if device == "" || dev == device {
51ba991379Sopenharmony_ci				return true
52ba991379Sopenharmony_ci			}
53ba991379Sopenharmony_ci		}
54ba991379Sopenharmony_ci		logrus.Infof("%s not found", device)
55ba991379Sopenharmony_ci	}
56ba991379Sopenharmony_ci}
57ba991379Sopenharmony_ci
58ba991379Sopenharmony_cifunc TryRebootToLoader(device string, ctx context.Context) error {
59ba991379Sopenharmony_ci	logrus.Infof("try to reboot %s to loader...", device)
60ba991379Sopenharmony_ci	defer time.Sleep(5 * time.Second)
61ba991379Sopenharmony_ci	if connected := WaitHDC(device, ctx); connected {
62ba991379Sopenharmony_ci		if device == "" {
63ba991379Sopenharmony_ci			return ExecContext(ctx, hdc, "shell", "reboot", "loader")
64ba991379Sopenharmony_ci		} else {
65ba991379Sopenharmony_ci			return ExecContext(ctx, hdc, "-t", device, "shell", "reboot", "loader")
66ba991379Sopenharmony_ci		}
67ba991379Sopenharmony_ci	}
68ba991379Sopenharmony_ci	if err := ctx.Err(); err != nil {
69ba991379Sopenharmony_ci		return err
70ba991379Sopenharmony_ci	}
71ba991379Sopenharmony_ci	logrus.Warn("can not find target hdc device, assume it has been in loader mode")
72ba991379Sopenharmony_ci	return nil
73ba991379Sopenharmony_ci}
74ba991379Sopenharmony_ci
75ba991379Sopenharmony_cifunc HdcShell(cmd, device string, ctx context.Context) error {
76ba991379Sopenharmony_ci	if device == "" {
77ba991379Sopenharmony_ci		return ExecContext(ctx, hdc, "shell", cmd)
78ba991379Sopenharmony_ci	} else {
79ba991379Sopenharmony_ci		return ExecContext(ctx, hdc, "-t", device, "shell", cmd)
80ba991379Sopenharmony_ci	}
81ba991379Sopenharmony_ci}
82