diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5fea06a..a19af17 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,16 +16,11 @@ jobs: image: ghcr.io/tillitis/tkey-builder:5rc2 steps: - name: checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: # fetch-depth: 0 persist-credentials: false - - name: fix - # https://github.com/actions/runner-images/issues/6775 - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - # Ubuntu has stopped publishing packages we use in # tkey-builder:4 so we can't do this right now. Kept for a later # update. @@ -39,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: REUSE Compliance Check - uses: fsfe/reuse-action@v4 + uses: fsfe/reuse-action@v6 with: args: lint diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index fa91d50..4feb8b5 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -15,8 +15,8 @@ jobs: name: lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - uses: actions/checkout@v7 + - uses: actions/setup-go@v7 with: go-version: '1.23' cache: false diff --git a/.golangci.yml b/.golangci.yml index 608a063..7d3d9ca 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -15,14 +15,12 @@ linters: - gocheckcompilerdirectives - gochecksumtype - gocritic - - gocyclo - godox - gomoddirectives - gomodguard - gosec - gosmopolitan - loggercheck - - maintidx - makezero - misspell - musttag @@ -53,7 +51,9 @@ linters: - exhaustruct - funlen - gocognit + - gocyclo - godot + - maintidx - nestif - perfsprint - noctx diff --git a/cmd/tkey-runapp/go.mod b/cmd/tkey-runapp/go.mod index 548efd1..b549f36 100644 --- a/cmd/tkey-runapp/go.mod +++ b/cmd/tkey-runapp/go.mod @@ -4,12 +4,11 @@ go 1.23.0 require ( github.com/spf13/pflag v1.0.5 - github.com/tillitis/tkeyclient v1.3.1 + github.com/tillitis/tkeyclient v1.3.2-0.20261001100427-28b2446edd3a github.com/tillitis/tkeyutil v0.0.9 ) require ( - github.com/ccoveille/go-safecast v1.5.0 // indirect github.com/ccoveille/go-safecast/v2 v2.0.0 // indirect github.com/creack/goselect v0.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/cmd/tkey-runapp/go.sum b/cmd/tkey-runapp/go.sum index 1df76a3..c6d74f4 100644 --- a/cmd/tkey-runapp/go.sum +++ b/cmd/tkey-runapp/go.sum @@ -1,5 +1,3 @@ -github.com/ccoveille/go-safecast v1.5.0 h1:cT/3uVQ/i5PTiJvhvkSU81HeKNurtyQtBndXEH3hDg4= -github.com/ccoveille/go-safecast v1.5.0/go.mod h1:QqwNjxQ7DAqY0C721OIO9InMk9zCwcsO7tnRuHytad8= github.com/ccoveille/go-safecast/v2 v2.0.0 h1:+5eyITXAUj3wMjad6cRVJKGnC7vDS55zk0INzJagub0= github.com/ccoveille/go-safecast/v2 v2.0.0/go.mod h1:JIYA4CAR33blIDuE6fSwCp2sz1oOBahXnvmdBhOAABs= github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0= @@ -22,12 +20,8 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk= github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o= -github.com/tillitis/tkeyclient v1.2.0 h1:X/PjUPK061EFNmf3V4knb20wTfcIuUH13VSC/0VFaYo= -github.com/tillitis/tkeyclient v1.2.0/go.mod h1:4TiEj0qUwaffmOODPZro6cUBaw+Gb6F5EFd6tcH7UXE= -github.com/tillitis/tkeyclient v1.3.0 h1:fUlghD+xvtL+qoajgrsetCC7KPwSfpjDDgqxMOBA2VU= -github.com/tillitis/tkeyclient v1.3.0/go.mod h1:7VtzyEjm08Wf+1zdrs20HsvM+WzhyztinvGG2/HY+Is= -github.com/tillitis/tkeyclient v1.3.1 h1:IouMAtwwXewhXLmcySBmXuyFuI4WoAw8NQj+gFWlLaw= -github.com/tillitis/tkeyclient v1.3.1/go.mod h1:7VtzyEjm08Wf+1zdrs20HsvM+WzhyztinvGG2/HY+Is= +github.com/tillitis/tkeyclient v1.3.2-0.20261001100427-28b2446edd3a h1:1SeKCzc/IqFiGVWdI2ikQzmnR5z35L6+9T6/2K5wEjI= +github.com/tillitis/tkeyclient v1.3.2-0.20261001100427-28b2446edd3a/go.mod h1:7VtzyEjm08Wf+1zdrs20HsvM+WzhyztinvGG2/HY+Is= github.com/tillitis/tkeyutil v0.0.9 h1:WWF4Emxch32TczYjjYwl45GMtxsD9l8432mZaX6u8mw= github.com/tillitis/tkeyutil v0.0.9/go.mod h1:+vxU9HmwR2pdPRYg1YlmWW46h2XADdSAhCGUQCryzJg= go.bug.st/serial v1.6.2 h1:kn9LRX3sdm+WxWKufMlIRndwGfPWsH1/9lCWXQCasq8= diff --git a/cmd/tkey-runapp/main.go b/cmd/tkey-runapp/main.go index ed7ac14..f5679f0 100644 --- a/cmd/tkey-runapp/main.go +++ b/cmd/tkey-runapp/main.go @@ -5,6 +5,7 @@ package main import ( "bytes" + // "errors" "fmt" "log" "os" @@ -26,7 +27,7 @@ var version string func main() { var fileName, devPath, fileUSS string var speed int - var enterUSS, verbose, helpOnly, forceFullUss bool + var enterUSS, verbose, helpOnly, forceFullUss, notUsbDevice, noRemoteClose bool pflag.CommandLine.SetOutput(os.Stderr) pflag.CommandLine.SortFlags = false pflag.StringVar(&devPath, "port", "", @@ -37,6 +38,8 @@ func main() { pflag.StringVar(&fileUSS, "uss-file", "", "Read `FILE` and hash its contents as the USS. Use '-' (dash) to read from stdin. The full contents are hashed unmodified (e.g. newlines are not stripped).") pflag.BoolVar(&forceFullUss, "force-full-uss", false, "Force use of 32 byte USS digest.") + pflag.BoolVar(¬UsbDevice, "not-usb-device", false, "Not a USB device, like a tty to QEmu.") + pflag.BoolVar(&noRemoteClose, "no-remote-close", false, "Do not expect serial port to disappear when TKey resets") pflag.BoolVar(&verbose, "verbose", false, "Enable verbose output.") pflag.BoolVar(&helpOnly, "help", false, "Output this help.") versionOnly := pflag.BoolP("version", "v", false, "Output version information.") @@ -44,7 +47,8 @@ func main() { desc := fmt.Sprintf(`Usage: %[1]s [flags...] FILE %[1]s loads an application binary from FILE onto Tillitis TKey -and starts it. +and starts it. Tries a reset if an app is already loaded, and the TKey +supports reset. Exit status code is 0 if the app is both successfully loaded and started. Exit code is non-zero if anything goes wrong, for example if TKey is already @@ -129,6 +133,14 @@ running some app.`, os.Args[0]) options = append(options, tkeyclient.WithFullUss()) } + if noRemoteClose { + options = append(options, tkeyclient.NoRemoteClose()) + } + + if notUsbDevice { + options = append(options, tkeyclient.NotUSBDevice()) + } + le.Printf("Connecting to device on serial port %s ...\n", devPath) if err = tk.Connect(devPath, options...); err != nil { le.Printf("Could not open %s: %v\n", devPath, err) @@ -142,16 +154,44 @@ running some app.`, os.Args[0]) } handleSignals(func() { exit(1) }, os.Interrupt, syscall.SIGTERM) + isFirmware, err := tk.FirmwareActive() + + if err != nil { + le.Printf("Firmware probe failed: %v\n", err) + le.Printf("Cannot communicate with TKey, is the port correct?\n") + exit(1) + } + + if !isFirmware { + if !notUsbDevice && !tk.CanRemoteClose { + le.Printf("TKey does not support reset, unplug and insert TKey again.\n") + exit(1) + } + + le.Printf("Not in firmware mode, trying to reset ...\n") + nextAppData := tkeyclient.NewNextAppDataFromSlice([]byte{0}) + err = tk.Reset(tkeyclient.RstTypeStartClient, nextAppData) + if err != nil { + le.Printf("Reset failed: %v\n", err) + exit(1) + } + + err = reconnect(tk) + if err != nil { + le.Printf("Failed to reconnect: %v\n", err) + exit(1) + } + } + nameVer, err := tk.GetNameVersion() if err != nil { le.Printf("GetNameVersion failed: %v\n", err) - le.Printf("If the serial port is correct, then the TKey might not be in firmware-\n" + - "mode, and have an app running already. Please unplug and plug it in again.\n") + le.Printf("Cannot communicate with TKey, is the port correct?\n") exit(1) } + le.Printf("Firmware name0:'%s' name1:'%s' version:%d\n", nameVer.Name0, nameVer.Name1, nameVer.Version) - udi, err := tk.GetUDI() if err != nil { le.Printf("GetUDI failed: %v\n", err) @@ -186,6 +226,20 @@ running some app.`, os.Args[0]) exit(0) } +func reconnect(tk *tkeyclient.TillitisKey) error { + err := tk.WaitClosed() + if err != nil { + return fmt.Errorf("expected port close: %w", err) + } + + err = tk.Reconnect() + if err != nil { + return fmt.Errorf("couldn't reconnect: %w", err) + } + + return nil +} + func notice() { fmt.Printf("--------------------------------------------------------------------------------\n") fmt.Printf("tkey-runapp %v\n", version)