first running version
This commit is contained in:
35
main.go
35
main.go
@@ -14,9 +14,10 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
parser := argparse.NewParser("go-scsupdate", "Update Firmware of SCS PACTOR modems")
|
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."})
|
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"})
|
brate := parser.Int("b", "baudrate", &argparse.Options{Required: false, Help: "(optional, required when -s is set) sets the serial baudrate, e.g. 115200"})
|
||||||
f := parser.String("f", "file", &argparse.Options{Required: true, Help: "(required) the file to flash, e.g. profi41r.pro"})
|
f := parser.String("f", "file", &argparse.Options{Required: true, Help: "(required) the file to flash, e.g. profi41r.pro"})
|
||||||
debug := parser.Flag("d", "debug", &argparse.Options{Required: false, Help: "(optional) enable debug logs"})
|
debug := parser.Flag("d", "debug", &argparse.Options{Required: false, Help: "(optional) enable debug logs"})
|
||||||
|
dryrun := parser.Flag("n", "dryrun", &argparse.Options{Required: false, Help: "(optional) drying: if set, modem will detected but no firmware being written"})
|
||||||
err := parser.Parse(os.Args)
|
err := parser.Parse(os.Args)
|
||||||
cLog := console.New(true)
|
cLog := console.New(true)
|
||||||
if *debug {
|
if *debug {
|
||||||
@@ -25,6 +26,10 @@ func main() {
|
|||||||
} else {
|
} else {
|
||||||
log.AddHandler(cLog, log.InfoLevel, log.ErrorLevel, log.AlertLevel, log.WarnLevel, log.NoticeLevel, log.PanicLevel)
|
log.AddHandler(cLog, log.InfoLevel, log.ErrorLevel, log.AlertLevel, log.WarnLevel, log.NoticeLevel, log.PanicLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *serialDevice != "" && *brate == 0 {
|
||||||
|
log.Fatal("ERROR: if you specify a device, you need to specify a baud rate as well. Cannot continue")
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(parser.Usage(err))
|
log.Fatal(parser.Usage(err))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -41,10 +46,14 @@ func main() {
|
|||||||
msg += fmt.Sprintf("Port: %30s : Name: %s\n", p.Port, p.Name)
|
msg += fmt.Sprintf("Port: %30s : Name: %s\n", p.Port, p.Name)
|
||||||
}
|
}
|
||||||
log.Fatal(msg)
|
log.Fatal(msg)
|
||||||
|
} else { // exactly one modem found, that's how we like it :-)
|
||||||
|
log.Infof("Found %s modem at port %s. Default baud rate is: %d", ports[0].Name, ports[0].Port, ports[0].Baudrate)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Fatal("Error while seaching SCS modems: ", err)
|
log.Fatal("Error while seaching SCS modems: ", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.Notice("Using given device! Will not check if firmware fits your modem!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !firmware.FwExists(*f) {
|
if !firmware.FwExists(*f) {
|
||||||
@@ -58,9 +67,27 @@ func main() {
|
|||||||
log.Debug("checks passed")
|
log.Debug("checks passed")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = update.Update("/dev/ttyUSB0", 829400, *f)
|
baudrate := 0
|
||||||
if err != nil {
|
if *brate != 0 {
|
||||||
log.Panic(err)
|
baudrate = *brate
|
||||||
|
log.Infof("Using given baudrate of %d", baudrate)
|
||||||
|
} else {
|
||||||
|
baudrate = ports[0].Baudrate
|
||||||
|
log.Infof("Using default baudrate of %d", baudrate)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *dryrun != true {
|
||||||
|
var err error
|
||||||
|
if *serialDevice != "" {
|
||||||
|
err = update.Update(*serialDevice, baudrate, *f)
|
||||||
|
} else {
|
||||||
|
err = update.Update(ports[0].Port, baudrate, *f)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Info("Dryrun requested, no firmware written!")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package update
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/albenik/go-serial/v2"
|
"github.com/albenik/go-serial/v2"
|
||||||
@@ -26,8 +27,8 @@ func initmodem(serport string, baudrate int) (*modem, error) {
|
|||||||
serial.WithDataBits(8),
|
serial.WithDataBits(8),
|
||||||
serial.WithParity(serial.NoParity),
|
serial.WithParity(serial.NoParity),
|
||||||
serial.WithStopBits(serial.OneStopBit),
|
serial.WithStopBits(serial.OneStopBit),
|
||||||
serial.WithReadTimeout(1000),
|
serial.WithReadTimeout(70),
|
||||||
serial.WithWriteTimeout(1000))
|
serial.WithWriteTimeout(70)) // 50 was not stable, bump to 70
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("ERROR: File %s could not be opened\n", serport)
|
fmt.Printf("ERROR: File %s could not be opened\n", serport)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -40,11 +41,20 @@ func (m *modem) write(out string, nolog ...bool) ([]byte, error) {
|
|||||||
if len(nolog) == 0 {
|
if len(nolog) == 0 {
|
||||||
log.Debug("Sending " + out)
|
log.Debug("Sending " + out)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Sending %d byte(s)", len(out))
|
if len(out) < 200 { // in other cases it's the firmware!
|
||||||
|
log.Debugf("Sending %d byte(s)", len(out))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := m.port.Write([]byte(out))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("ERROR while sending serial command: %s\n", out)
|
||||||
|
log.Error(err)
|
||||||
|
return []byte(""), err
|
||||||
}
|
}
|
||||||
m.port.Write([]byte(out))
|
|
||||||
buff := make([]byte, 1024)
|
buff := make([]byte, 1024)
|
||||||
time.Sleep(100 * time.Millisecond) // give the PTC some time to answer
|
if len(nolog) == 0 {
|
||||||
|
time.Sleep(50 * time.Millisecond) // give the PTC some time to answer, no needed with binary
|
||||||
|
}
|
||||||
n, err := m.port.Read(buff)
|
n, err := m.port.Read(buff)
|
||||||
// fmt.Printf("Read %d bytes\n", n)
|
// fmt.Printf("Read %d bytes\n", n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -63,7 +73,6 @@ func (m *modem) getSerNum() (string, error) {
|
|||||||
}
|
}
|
||||||
re := regexp.MustCompile(`Serial number: \w{2,16}`)
|
re := regexp.MustCompile(`Serial number: \w{2,16}`)
|
||||||
sn := strings.ReplaceAll(string(re.Find(answer)), "Serial number: ", "")
|
sn := strings.ReplaceAll(string(re.Find(answer)), "Serial number: ", "")
|
||||||
log.Infof("Serial Number is: %s", sn)
|
|
||||||
return sn, nil
|
return sn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,11 +103,7 @@ func (m *modem) writeUpdate(fwfile string) error {
|
|||||||
_, _ = m.write("\033", true) // send ESC to cancel the update
|
_, _ = m.write("\033", true) // send ESC to cancel the update
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// TODO: remove that once write process is established
|
|
||||||
_, err = m.write("\033", true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Infof("flash stamp: % X", binary.LittleEndian.Uint32(answer[2:6]))
|
log.Infof("flash stamp: % X", binary.LittleEndian.Uint32(answer[2:6]))
|
||||||
flashId := binary.LittleEndian.Uint16(answer[0:2])
|
flashId := binary.LittleEndian.Uint16(answer[0:2])
|
||||||
log.Infof("flash id: % X", flashId)
|
log.Infof("flash id: % X", flashId)
|
||||||
@@ -113,9 +118,9 @@ func (m *modem) writeUpdate(fwfile string) error {
|
|||||||
}
|
}
|
||||||
fstat, _ := r.Stat()
|
fstat, _ := r.Stat()
|
||||||
fsize := fstat.Size()
|
fsize := fstat.Size()
|
||||||
r.Close()
|
_ = r.Close()
|
||||||
|
|
||||||
_, err = ioutil.ReadFile(fwfile)
|
fwblob, err := ioutil.ReadFile(fwfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = m.write("\033", true) // send ESC to cancel the update
|
_, _ = m.write("\033", true) // send ESC to cancel the update
|
||||||
return err
|
return err
|
||||||
@@ -126,13 +131,44 @@ func (m *modem) writeUpdate(fwfile string) error {
|
|||||||
chunks++
|
chunks++
|
||||||
}
|
}
|
||||||
|
|
||||||
// a := make([]byte, 2)
|
// send ACK
|
||||||
// binary.BigEndian.PutUint16(a, chunks)
|
_, err = m.write("\006", true)
|
||||||
|
if err != nil {
|
||||||
|
_, _ = m.write("\033", true) // send ESC to cancel the update
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// send number of chunks
|
||||||
|
a := make([]byte, 2)
|
||||||
|
binary.BigEndian.PutUint16(a, chunks)
|
||||||
|
res, err := m.write(string(a), true)
|
||||||
|
if err != nil || string(res) != "\006" { //no ACK
|
||||||
|
_, _ = m.write("\033", true) // send ESC to cancel the update
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
bar := progressbar.Default(int64(chunks), "flashing chunk")
|
bar := progressbar.Default(int64(chunks), "flashing chunk")
|
||||||
|
var sendbuff string = ""
|
||||||
for i := 0; i < int(chunks); i++ {
|
for i := 0; i < int(chunks); i++ {
|
||||||
bar.Add(1)
|
_ = bar.Add(1)
|
||||||
time.Sleep(3 * time.Millisecond)
|
//log.Debugf("Sending chunk %d", i)
|
||||||
|
if i*CHUNKSIZE+CHUNKSIZE > len(fwblob) {
|
||||||
|
nullbytes := make([]byte, CHUNKSIZE-len(fwblob[(i*CHUNKSIZE):]))
|
||||||
|
sendbuff = string(append(fwblob[(i*CHUNKSIZE):], nullbytes...))
|
||||||
|
} else {
|
||||||
|
sendbuff = string(fwblob[i*CHUNKSIZE : i*CHUNKSIZE+CHUNKSIZE])
|
||||||
|
}
|
||||||
|
res, err = m.write(sendbuff, true)
|
||||||
|
if err != nil || string(res) != "\006" { //no ACK
|
||||||
|
_, _ = m.write("\033", true) // send ESC to cancel the update
|
||||||
|
log.Errorf("Error in Handshake! Rx: %s", hex.EncodeToString(res))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Infof("Firmware file %s successfully written", fwfile)
|
||||||
|
_, err = m.write("\r", true)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Error in Handshake: cannot send final cr")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -143,7 +179,14 @@ func Update(serport string, baudrate int, fwfile string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("FEHLER in Update")
|
return errors.New("FEHLER in Update")
|
||||||
}
|
}
|
||||||
_, _ = m.getSerNum()
|
sn, err := m.getSerNum()
|
||||||
|
if len(sn) < 6 {
|
||||||
|
// can't be a valid serial number, something's wrong, bump out here
|
||||||
|
log.Errorf("ERROR: got invalid serial number: %s", sn)
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
log.Infof("Serial number of your modem is: %s", sn)
|
||||||
|
}
|
||||||
if m.setDateTime() != nil {
|
if m.setDateTime() != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,9 @@ var scsbaudrates map[string]int = map[string]int{
|
|||||||
func FindSCS() ([]Scsid, error) {
|
func FindSCS() ([]Scsid, error) {
|
||||||
|
|
||||||
foundids := []Scsid{}
|
foundids := []Scsid{}
|
||||||
|
|
||||||
ports, err := enumerator2.GetDetailedPortsList()
|
ports, err := enumerator2.GetDetailedPortsList()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user