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