Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DIV-33 Update firmware via websocket command #127

Merged
merged 45 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
aabb427
Introduce callback for firmware update messages
krksgbr Apr 4, 2024
333ac8d
Receive firmware update command and send progress messages
krksgbr Apr 4, 2024
c3e331d
Ignore commands while firmware update is in progress
krksgbr Apr 4, 2024
ccd94c9
Add some more firmware update progress messages
krksgbr Apr 4, 2024
71b4137
Use libp2p/zeroconf
krksgbr Apr 4, 2024
c3f027f
Report firmware update errors on the command line
krksgbr Apr 4, 2024
fb1a472
Configure exponential backoff on TFTP client
krksgbr Apr 4, 2024
262aadd
Add more messages
krksgbr Apr 4, 2024
94b819a
Wait 10 seconds for tcp connection teardown
krksgbr Apr 4, 2024
0e9025a
Make firmware update commands specify serial instead of address
krksgbr Apr 4, 2024
85bc280
Check for null when dereferencing address
krksgbr Apr 4, 2024
a23e6c3
Allow Discovery and GetStatus commands while updating firmware
krksgbr Apr 4, 2024
4201904
Wait 15 seconds for tftp startup
krksgbr Apr 4, 2024
03b962d
Send DFU with exponential backoff
krksgbr Apr 4, 2024
bd1fa13
Do not abort discovery when device serials don't match
krksgbr Apr 4, 2024
c7608d7
Refactor discovery code
krksgbr Apr 4, 2024
8e57f6b
Separate updating by different inputs
krksgbr Apr 4, 2024
38c2516
Move cli-specific code to another file
krksgbr Apr 4, 2024
340ba57
Simplify code
krksgbr Apr 4, 2024
66d2bb8
Add some helpers for constructing firmware update messages
krksgbr Apr 4, 2024
b7338d8
Reduce timeouts
krksgbr Apr 4, 2024
6da5b8b
Fix build
krksgbr Apr 4, 2024
0aac1a1
Merge branch 'main' into remote-firmware-update
krksgbr Apr 11, 2024
7252777
Document and re-organize service module
krksgbr Apr 11, 2024
c66c09c
Add some docs to the firmware modules
krksgbr Apr 11, 2024
22f6e33
Encapsulate state management in firmware module
krksgbr Apr 11, 2024
28fe54e
Update changelog
krksgbr Apr 11, 2024
ccb18c5
Improve clarity of firmware update message
krksgbr Apr 15, 2024
b806116
Merge branch 'main' into remote-firmware-update
krksgbr Apr 15, 2024
8097df3
Allow 60 seconds for mDNS discovery
krksgbr Apr 15, 2024
a59e24e
Prevent unnecessary TFTP send failure messages
krksgbr Apr 15, 2024
5bb2e6d
Fix TFTP send fail message
krksgbr Apr 15, 2024
7349c61
Capitalize "Senso" where appropriate
krksgbr Apr 15, 2024
5f03ddf
Remove unused nix files
krksgbr Apr 15, 2024
b335212
Format file
krksgbr Apr 15, 2024
ffa7b58
Increase wait time before attempting TFTP transfer
krksgbr Apr 15, 2024
1233e05
Do not proceed with firmware update if image could not be decoded
krksgbr Apr 16, 2024
8743fda
Remove firmware update by fixed address
krksgbr Apr 16, 2024
cb649fc
Communicate power cycling suggestion only when updating via CLI
krksgbr Apr 16, 2024
0121d02
Improve log messages about ignored commands during firmware update
krksgbr Apr 16, 2024
80dfde6
Implement pretty-printing for UpdateFirmware command
krksgbr Apr 16, 2024
81d9acd
Log messages about ignored commands at debug level
krksgbr Apr 19, 2024
ad56fd2
Add notes about libp2p/zeroconf dependency choice
krksgbr Apr 19, 2024
8e0e4a7
Deduplicate firmware update success messages sent via websockets
krksgbr Apr 19, 2024
57b821c
Refine vocabulary and punctuation of firmware update messages
krksgbr Apr 22, 2024
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
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Let firmware update command look for bootloader if no Senso in regular mode is found
- Update build system and development environment
- Add support for triggering firmware updates via websocket

## [2.3.0] - 2022-10-01

Expand Down
10 changes: 9 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@ require (
github.com/denisbrodbeck/machineid v1.0.1
github.com/ebfe/scard v0.0.0-20190212122703-c3d1b1916a95
github.com/gorilla/websocket v1.4.2
github.com/grandcat/zeroconf v1.0.0
github.com/kardianos/service v1.2.0

// `libp2p/zeroconf` is a fork of `grandcat/zeroconf`, which we previously used.
// This fork includes some stability improvements and bug fixes that are absent
// in the grandcat version. However, it is libp2p's internal maintenance fork,
// which while being public, does not accept community contributions.
// Both projects are dormant at the moment, but we might want to re-evaluate this
// dependency choice as these projects evolve in the future.
github.com/libp2p/zeroconf/v2 v2.2.0
knuton marked this conversation as resolved.
Show resolved Hide resolved

github.com/pin/tftp v2.1.0+incompatible
github.com/sirupsen/logrus v1.8.1
go.bug.st/serial v1.6.1
Expand Down
40 changes: 17 additions & 23 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@ github.com/ebfe/scard v0.0.0-20190212122703-c3d1b1916a95 h1:OM0MnUcXBysj7ZtXvThV
github.com/ebfe/scard v0.0.0-20190212122703-c3d1b1916a95/go.mod h1:8hHvF8DlEq5kE3KWOsZQezdWq1OTOVxZArZMscS954E=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grandcat/zeroconf v1.0.0 h1:uHhahLBKqwWBV6WZUDAT71044vwOTL+McW0mBJvo6kE=
github.com/grandcat/zeroconf v1.0.0/go.mod h1:lTKmG1zh86XyCoUeIHSA4FJMBwCJiQmGfcP2PdzytEs=
github.com/kardianos/service v1.2.0 h1:bGuZ/epo3vrt8IPC7mnKQolqFeYJb7Cs8Rk4PSOBB/g=
github.com/kardianos/service v1.2.0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
github.com/miekg/dns v1.1.27 h1:aEH/kqUzUxGJ/UHcEKdJY+ugH6WEzsEBBSPa8zuy1aM=
github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q=
github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs=
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/pin/tftp v2.1.0+incompatible h1:Yng4J7jv6lOc6IF4XoB5mnd3P7ZrF60XQq+my3FAMus=
github.com/pin/tftp v2.1.0+incompatible/go.mod h1:xVpZOMCXTy+A5QMjEVN0Glwa1sUvaJhFXbr/aAxuxGY=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
Expand All @@ -33,27 +31,23 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.bug.st/serial v1.6.1 h1:VSSWmUxlj1T/YlRo2J104Zv3wJFrjHIl/T3NeruWAHY=
go.bug.st/serial v1.6.1/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6 h1:0PC75Fz/kyMGhL0e1QnypqK2kQMqKt9csD1GnMJR+Zk=
golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
Expand Down
76 changes: 76 additions & 0 deletions src/dividat-driver/firmware/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package firmware

import (
"context"
"flag"
"fmt"
"io"
"os"

"github.com/dividat/driver/src/dividat-driver/service"
)

// Command-line interface to running a firmware update
func Command(flags []string) {
updateFlags := flag.NewFlagSet("update", flag.ExitOnError)
imagePath := updateFlags.String("i", "", "Firmware image path")
sensoSerial := updateFlags.String("s", "", "Senso serial (optional)")
updateFlags.Parse(flags)

if *imagePath == "" {
flag.PrintDefaults()
return
}
file, err := os.Open(*imagePath)
if err != nil {
fmt.Printf("Could not open image file: %v\n", err)
os.Exit(1)
}

onProgress := func(progressMsg string) {
fmt.Println(progressMsg)
}

tryPowerCycling := "Try turning the Senso off and on, waiting for 30 seconds and then running this update tool again."
suggestPowerCycling := false

if *sensoSerial != "" {
err = UpdateBySerial(context.Background(), *sensoSerial, file, onProgress)
if err != nil {
suggestPowerCycling = true
}
} else {
err, suggestPowerCycling = updateByDiscovery(context.Background(), file, onProgress)
}

if err != nil {
fmt.Println()
fmt.Printf("Update failed: %v \n", err)
if suggestPowerCycling {
fmt.Println(tryPowerCycling)
}
os.Exit(1)
}

fmt.Println("Success! Firmware transmitted to Senso.")
}

func updateByDiscovery(ctx context.Context, image io.Reader, onProgress OnProgress) (err error, suggestPowerCycling bool) {
onProgress("Discovering Sensos")
services := service.List(ctx, discoveryTimeout)
if len(services) == 1 {
target := services[0]
onProgress(fmt.Sprintf("Discovered Senso: %s (%s)", target.Text.Serial, target.Address))
err = update(ctx, target, image, onProgress)
if err != nil {
suggestPowerCycling = true
}
} else if len(services) == 0 {
err = fmt.Errorf("Could not find any Sensos.")
suggestPowerCycling = true
} else {
err = fmt.Errorf("discovered multiple Sensos: %v, please specify a serial or IP", services)
suggestPowerCycling = false
}
return
}
Loading