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
|
||||
|
||||
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 (
|
||||
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/multierr v1.1.0 // 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/go.mod h1:9NHUOwCBJER+lAaitTWLJda/GnYoP4Vga7KU3vn1lmM=
|
||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
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/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
|
48
main.go
48
main.go
@@ -1,5 +1,51 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/akamensky/argparse"
|
||||
"go-scsupdate/firmware"
|
||||
"go-scsupdate/usb"
|
||||
"os"
|
||||
)
|
||||
|
||||
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