Checksumming and USB port searching works
This commit is contained in:
77
firmware/firmware.go
Normal file
77
firmware/firmware.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package firmware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"hash/crc32"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FwExists check if file exists
|
||||||
|
func FwExists(path string) bool {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
return !errors.Is(err, os.ErrNotExist)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChkHeader(fwfile string) bool {
|
||||||
|
fmt.Println("checking ", fwfile)
|
||||||
|
// SCS has two different file layouts, one for the "Dragons", the other for any older modem
|
||||||
|
var offset uint32
|
||||||
|
if path.Ext(fwfile) == ".dr7" {
|
||||||
|
offset = 0
|
||||||
|
} else {
|
||||||
|
offset = 4
|
||||||
|
}
|
||||||
|
r, err := os.Open(fwfile)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
var header [2]byte
|
||||||
|
_, err = io.ReadFull(r, header[:])
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if offset == 0 {
|
||||||
|
if header != [2]byte{0x50, 0x34} {
|
||||||
|
fmt.Println("ERROR: wrong firmware header")
|
||||||
|
//return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if header != [2]byte{0x60, 0xea} {
|
||||||
|
fmt.Println("ERROR: wrong firmware header")
|
||||||
|
//return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Close()
|
||||||
|
firmware, err := ioutil.ReadFile(fwfile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("ERROR: ReadFile operation failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
var size uint32
|
||||||
|
if offset == 0 {
|
||||||
|
size = binary.LittleEndian.Uint32(firmware[4:8]) // Dragons
|
||||||
|
} else {
|
||||||
|
size = uint32(binary.LittleEndian.Uint16(firmware[2:4])) // PTC-3 and Co
|
||||||
|
}
|
||||||
|
a := make([]byte, 4)
|
||||||
|
//binary.LittleEndian.PutUint32(a, crc32.ChecksumIEEE(firmware[4:size+4])) // PTC-3
|
||||||
|
binary.LittleEndian.PutUint32(a, crc32.ChecksumIEEE(firmware[offset:offset+size]))
|
||||||
|
//if bytes.Equal(a, firmware[4+size:8+size]) { // PTC-3
|
||||||
|
if bytes.Equal(a, firmware[offset+size:offset+size+4]) {
|
||||||
|
fmt.Println("CRC checksum ok!")
|
||||||
|
} else {
|
||||||
|
fmt.Println("CRC checksum NOT ok!")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
8
go.mod
8
go.mod
@@ -2,10 +2,16 @@ module go-scsupdate
|
|||||||
|
|
||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require github.com/albenik/go-serial v1.2.0
|
require (
|
||||||
|
github.com/akamensky/argparse v1.3.1
|
||||||
|
github.com/albenik/go-serial v1.2.0
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/creack/goselect v0.1.0 // indirect
|
github.com/creack/goselect v0.1.0 // indirect
|
||||||
|
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 // indirect
|
||||||
|
github.com/sigurn/crc8 v0.0.0-20160107002456-e55481d6f45c // indirect
|
||||||
|
github.com/sigurn/utils v0.0.0-20190728110027-e1fefb11a144 // indirect
|
||||||
go.uber.org/atomic v1.4.0 // indirect
|
go.uber.org/atomic v1.4.0 // indirect
|
||||||
go.uber.org/multierr v1.1.0 // indirect
|
go.uber.org/multierr v1.1.0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 // indirect
|
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 // indirect
|
||||||
|
8
go.sum
8
go.sum
@@ -1,3 +1,5 @@
|
|||||||
|
github.com/akamensky/argparse v1.3.1 h1:kP6+OyvR0fuBH6UhbE6yh/nskrDEIQgEA1SUXDPjx4g=
|
||||||
|
github.com/akamensky/argparse v1.3.1/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA=
|
||||||
github.com/albenik/go-serial v1.2.0 h1:VhEIWqP5tbWtsWoCjeBHHQEf6qeXpsJXvZBP9px5F84=
|
github.com/albenik/go-serial v1.2.0 h1:VhEIWqP5tbWtsWoCjeBHHQEf6qeXpsJXvZBP9px5F84=
|
||||||
github.com/albenik/go-serial v1.2.0/go.mod h1:9NHUOwCBJER+lAaitTWLJda/GnYoP4Vga7KU3vn1lmM=
|
github.com/albenik/go-serial v1.2.0/go.mod h1:9NHUOwCBJER+lAaitTWLJda/GnYoP4Vga7KU3vn1lmM=
|
||||||
github.com/creack/goselect v0.1.0 h1:4QiXIhcpSQF50XGaBsFzesjwX/1qOY5bOveQPmN9CXY=
|
github.com/creack/goselect v0.1.0 h1:4QiXIhcpSQF50XGaBsFzesjwX/1qOY5bOveQPmN9CXY=
|
||||||
@@ -7,6 +9,12 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
|
||||||
|
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
|
||||||
|
github.com/sigurn/crc8 v0.0.0-20160107002456-e55481d6f45c h1:hk0Jigjfq59yDMgd6bzi22Das5tyxU0CtOkh7a9io84=
|
||||||
|
github.com/sigurn/crc8 v0.0.0-20160107002456-e55481d6f45c/go.mod h1:cyrWuItcOVIGX6fBZ/G00z4ykprWM7hH58fSavNkjRg=
|
||||||
|
github.com/sigurn/utils v0.0.0-20190728110027-e1fefb11a144 h1:ccb8W1+mYuZvlpn/mJUMAbsFHTMCpcJBS78AsBQxNcY=
|
||||||
|
github.com/sigurn/utils v0.0.0-20190728110027-e1fefb11a144/go.mod h1:VRI4lXkrUH5Cygl6mbG1BRUfMMoT2o8BkrtBDUAm+GU=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
48
main.go
48
main.go
@@ -1,5 +1,51 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/akamensky/argparse"
|
||||||
|
"go-scsupdate/firmware"
|
||||||
|
"go-scsupdate/usb"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
lsusb()
|
parser := argparse.NewParser("go-scsupdate", "Update Firmware of SCS PACTOR modems")
|
||||||
|
serialDevice := parser.String("s", "serialDevice", &argparse.Options{Required: false, Help: "(optional) serial device the modem is attached to, e.g. /dev/ttyUSB0. If not set, go-scsupdate will search for SCS modems."})
|
||||||
|
_ = parser.String("b", "baudrate", &argparse.Options{Required: false, Help: "(optional) sets the serial baudrate, e.g. 115200"})
|
||||||
|
f := parser.String("f", "file", &argparse.Options{Required: false, Help: "(required) the file to flash, e.g. profi41r.pro"})
|
||||||
|
err := parser.Parse(os.Args)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(parser.Usage(err))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println(*serialDevice)
|
||||||
|
var ports []usb.Scsid
|
||||||
|
if *serialDevice == "" {
|
||||||
|
if ports, err = usb.FindSCS(); err == nil {
|
||||||
|
fmt.Println(ports)
|
||||||
|
if len(ports) == 0 {
|
||||||
|
fmt.Println("Found no SCS modem.")
|
||||||
|
//os.Exit(1)
|
||||||
|
}
|
||||||
|
if len(ports) != 1 {
|
||||||
|
fmt.Println("Found more than one SCS modem. You need to choose one with the -s flag.\nfound: ")
|
||||||
|
for _, p := range ports {
|
||||||
|
fmt.Printf("Port: %30s : Name: %s\n", p.Port, p.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("Error while seaching SCS modems: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !firmware.FwExists(*f) {
|
||||||
|
fmt.Printf("Error: firmware file %s does not exist.\n", *f)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !firmware.ChkHeader(*f) {
|
||||||
|
os.Exit(1)
|
||||||
|
} else {
|
||||||
|
fmt.Println("all ok")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
39
usb.go
39
usb.go
@@ -1,39 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/albenik/go-serial/enumerator"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
USB Product IDs of the SCS devices:
|
|
||||||
0xD010 SCS PTC-IIusb
|
|
||||||
0xD011 SCS Tracker / DSP TNC
|
|
||||||
0xD012 SCS P4dragon DR-7800
|
|
||||||
0xD013 SCS P4dragon DR-7400
|
|
||||||
0xD014 - not used
|
|
||||||
0xD015 SCS PTC-IIIusb
|
|
||||||
0xD016 - not used
|
|
||||||
0xD017 - not used
|
|
||||||
*/
|
|
||||||
|
|
||||||
func lsusb() {
|
|
||||||
ports, err := enumerator.GetDetailedPortsList()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(ports) == 0 {
|
|
||||||
fmt.Println("No serial ports found!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, port := range ports {
|
|
||||||
fmt.Printf("Found port: %s\n", port.Name)
|
|
||||||
if port.IsUSB {
|
|
||||||
fmt.Printf(" USB ID %s:%s\n", port.VID, port.PID)
|
|
||||||
fmt.Printf(" USB serial %s\n", port.SerialNumber)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
67
usb/usb.go
Normal file
67
usb/usb.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package usb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/albenik/go-serial/enumerator"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
USB Product IDs of the SCS devices:
|
||||||
|
0xD010 SCS PTC-IIusb
|
||||||
|
0xD011 SCS Tracker / DSP TNC
|
||||||
|
0xD012 SCS P4dragon DR-7800
|
||||||
|
0xD013 SCS P4dragon DR-7400
|
||||||
|
0xD014 - not used
|
||||||
|
0xD015 SCS PTC-IIIusb
|
||||||
|
0xD016 - not used
|
||||||
|
0xD017 - not used
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Scsid struct {
|
||||||
|
Port, id, Name string
|
||||||
|
Baudrate int
|
||||||
|
}
|
||||||
|
|
||||||
|
var scsids map[string]string = map[string]string{
|
||||||
|
"d010": "SCS PTC-IIusb",
|
||||||
|
"d011": "SCS Tracker / DSP TNC",
|
||||||
|
"d012": "SCS P4dragon DR-7800",
|
||||||
|
"d013": "SCS P4dragon DR-7400",
|
||||||
|
"d015": "SCS PTC-IIIusb"}
|
||||||
|
|
||||||
|
var scsbaudrates map[string]int = map[string]int{
|
||||||
|
"d010": 115200,
|
||||||
|
"d011": 38400,
|
||||||
|
"d012": 829400,
|
||||||
|
"d013": 829400,
|
||||||
|
"d015": 115200}
|
||||||
|
|
||||||
|
func FindSCS() ([]Scsid, error) {
|
||||||
|
|
||||||
|
foundids := []Scsid{}
|
||||||
|
ports, err := enumerator.GetDetailedPortsList()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(ports) == 0 {
|
||||||
|
return nil, errors.New("No serial ports found")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, port := range ports {
|
||||||
|
fmt.Printf("Found Port: %s\n", port.Name)
|
||||||
|
if port.IsUSB {
|
||||||
|
// fmt.Printf(" USB ID %s:%s\n", Port.VID, Port.PID)
|
||||||
|
// fmt.Printf(" USB serial %s\n", Port.SerialNumber)
|
||||||
|
if port.VID == "0403" {
|
||||||
|
if _, ok := scsids[port.PID]; ok {
|
||||||
|
foundids = append(foundids, Scsid{Port: port.Name, id: port.PID, Name: scsids[port.PID], Baudrate: scsbaudrates[port.PID]})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundids, nil
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user