itd/cmd/itgui/upgrade.go

192 lines
5.0 KiB
Go
Raw Permalink Normal View History

2021-08-26 04:18:24 +00:00
package main
import (
"bufio"
"encoding/json"
"fmt"
"net"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/widget"
"github.com/mitchellh/mapstructure"
"go.arsenm.dev/itd/internal/types"
)
func upgradeTab(parent fyne.Window) *fyne.Container {
var (
archivePath string
fiwmarePath string
initPktPath string
)
2021-08-26 15:47:17 +00:00
// Create archive selection dialog
2021-08-26 04:18:24 +00:00
archiveDialog := dialog.NewFileOpen(func(uc fyne.URIReadCloser, e error) {
if e != nil || uc == nil {
return
}
uc.Close()
archivePath = uc.URI().Path()
}, parent)
2021-08-26 15:47:17 +00:00
// Limit dialog to .zip files
2021-08-26 04:18:24 +00:00
archiveDialog.SetFilter(storage.NewExtensionFileFilter([]string{".zip"}))
2021-08-26 15:47:17 +00:00
// Create button to show dialog
2021-08-26 04:18:24 +00:00
archiveBtn := widget.NewButton("Select archive (.zip)", archiveDialog.Show)
2021-08-26 15:47:17 +00:00
// Create firmware selection dialog
2021-08-26 04:18:24 +00:00
firmwareDialog := dialog.NewFileOpen(func(uc fyne.URIReadCloser, e error) {
if e != nil || uc == nil {
return
}
uc.Close()
fiwmarePath = uc.URI().Path()
}, parent)
2021-08-26 15:47:17 +00:00
// Limit dialog to .bin files
2021-08-26 04:18:24 +00:00
firmwareDialog.SetFilter(storage.NewExtensionFileFilter([]string{".bin"}))
2021-08-26 15:47:17 +00:00
// Create button to show dialog
2021-08-26 04:18:24 +00:00
firmwareBtn := widget.NewButton("Select init packet (.bin)", firmwareDialog.Show)
2021-08-26 15:47:17 +00:00
// Create init packet selection dialog
2021-08-26 04:18:24 +00:00
initPktDialog := dialog.NewFileOpen(func(uc fyne.URIReadCloser, e error) {
if e != nil || uc == nil {
return
}
uc.Close()
initPktPath = uc.URI().Path()
}, parent)
2021-08-26 15:47:17 +00:00
// Limit dialog to .dat files
2021-08-26 04:18:24 +00:00
initPktDialog.SetFilter(storage.NewExtensionFileFilter([]string{".dat"}))
2021-08-26 15:47:17 +00:00
// Create button to show dialog
2021-08-26 04:18:24 +00:00
initPktBtn := widget.NewButton("Select init packet (.dat)", initPktDialog.Show)
2021-08-26 15:47:17 +00:00
// Hide init packet and firmware buttons
2021-08-26 04:18:24 +00:00
initPktBtn.Hide()
firmwareBtn.Hide()
2021-08-26 15:47:17 +00:00
// Create dropdown to select upgrade type
2021-08-26 04:18:24 +00:00
upgradeTypeSelect := widget.NewSelect([]string{
"Archive",
"Files",
}, func(s string) {
2021-08-26 15:47:17 +00:00
// Hide all buttons
2021-08-26 04:18:24 +00:00
archiveBtn.Hide()
initPktBtn.Hide()
firmwareBtn.Hide()
2021-08-26 15:47:17 +00:00
// Unhide appropriate button(s)
2021-08-26 04:18:24 +00:00
switch s {
case "Archive":
archiveBtn.Show()
case "Files":
initPktBtn.Show()
firmwareBtn.Show()
}
})
2021-08-26 15:47:17 +00:00
// Select first elemetn
2021-08-26 04:18:24 +00:00
upgradeTypeSelect.SetSelectedIndex(0)
2021-08-26 15:47:17 +00:00
// Create new button to start DFU
2021-08-26 04:18:24 +00:00
startBtn := widget.NewButton("Start", func() {
2021-08-26 15:47:17 +00:00
// If archive path does not exist and both init packet and firmware paths
// also do not exist, return error
2021-08-26 04:18:24 +00:00
if archivePath == "" && (initPktPath == "" && fiwmarePath == "") {
2021-08-27 15:47:24 +00:00
guiErr(nil, "Upgrade requires archive or files selected", false, parent)
2021-08-26 04:18:24 +00:00
return
}
2021-08-26 15:47:17 +00:00
// Create new label for byte progress
2021-08-26 04:18:24 +00:00
progressLbl := widget.NewLabelWithStyle("0 / 0 B", fyne.TextAlignCenter, fyne.TextStyle{})
2021-08-26 15:47:17 +00:00
// Create new progress bar
2021-08-26 04:18:24 +00:00
progressBar := widget.NewProgressBar()
2021-08-26 15:47:17 +00:00
// Create modal dialog containing label and progress bar
2021-08-26 04:18:24 +00:00
progressDlg := widget.NewModalPopUp(container.NewVBox(
layout.NewSpacer(),
progressLbl,
progressBar,
layout.NewSpacer(),
), parent.Canvas())
2021-08-26 15:47:17 +00:00
// Resize modal to 300x100
2021-08-26 04:18:24 +00:00
progressDlg.Resize(fyne.NewSize(300, 100))
var fwUpgType int
var files []string
2021-08-26 15:47:17 +00:00
// Get appropriate upgrade type and file paths
2021-08-26 04:18:24 +00:00
switch upgradeTypeSelect.Selected {
case "Archive":
fwUpgType = types.UpgradeTypeArchive
files = append(files, archivePath)
case "Files":
fwUpgType = types.UpgradeTypeFiles
files = append(files, initPktPath, fiwmarePath)
}
2021-08-26 15:47:17 +00:00
// Dial itd UNIX socket
2021-08-26 04:18:24 +00:00
conn, err := net.Dial("unix", SockPath)
if err != nil {
2021-08-27 15:47:24 +00:00
guiErr(err, "Error dialing socket", false, parent)
2021-08-26 04:18:24 +00:00
return
}
defer conn.Close()
2021-08-26 15:47:17 +00:00
// Encode firmware upgrade request to connection
2021-08-26 04:18:24 +00:00
json.NewEncoder(conn).Encode(types.Request{
Type: types.ReqTypeFwUpgrade,
Data: types.ReqDataFwUpgrade{
Type: fwUpgType,
Files: files,
},
})
2021-08-26 15:47:17 +00:00
// Show progress dialog
2021-08-26 04:18:24 +00:00
progressDlg.Show()
2021-08-26 15:47:17 +00:00
// Hide progress dialog after completion
defer progressDlg.Hide()
2021-08-26 04:18:24 +00:00
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
var res types.Response
// Decode scanned line into response struct
err = json.Unmarshal(scanner.Bytes(), &res)
if err != nil {
2021-08-27 15:47:24 +00:00
guiErr(err, "Error decoding response", false, parent)
2021-08-26 04:18:24 +00:00
return
}
if res.Error {
2021-08-27 15:47:24 +00:00
guiErr(err, "Error returned in response", false, parent)
2021-08-26 04:18:24 +00:00
return
}
var event types.DFUProgress
// Decode response data into progress struct
err = mapstructure.Decode(res.Value, &event)
if err != nil {
2021-08-27 15:47:24 +00:00
guiErr(err, "Error decoding response value", false, parent)
2021-08-26 04:18:24 +00:00
return
}
2021-08-26 15:47:17 +00:00
// Set label text to received / total B
2021-08-26 04:18:24 +00:00
progressLbl.SetText(fmt.Sprintf("%d / %d B", event.Received, event.Total))
2021-08-26 15:47:17 +00:00
// Set progress bar values
2021-08-26 04:18:24 +00:00
progressBar.Max = float64(event.Total)
progressBar.Value = float64(event.Received)
2021-08-26 15:47:17 +00:00
// Refresh progress bar
2021-08-26 04:18:24 +00:00
progressBar.Refresh()
// If transfer finished, break
if event.Received == event.Total {
break
}
2021-08-26 04:18:24 +00:00
}
})
2021-08-26 15:47:17 +00:00
// Return container containing all elements
2021-08-26 04:18:24 +00:00
return container.NewVBox(
layout.NewSpacer(),
upgradeTypeSelect,
archiveBtn,
firmwareBtn,
initPktBtn,
startBtn,
layout.NewSpacer(),
)
}