first running version

This commit is contained in:
2021-12-20 14:21:43 +01:00
parent cde709d173
commit 421bf33d6a
3 changed files with 94 additions and 22 deletions

31
main.go
View File

@@ -14,9 +14,10 @@ import (
func main() {
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"})
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"})
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)
cLog := console.New(true)
if *debug {
@@ -25,6 +26,10 @@ func main() {
} else {
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 {
log.Fatal(parser.Usage(err))
os.Exit(1)
@@ -41,10 +46,14 @@ func main() {
msg += fmt.Sprintf("Port: %30s : Name: %s\n", p.Port, p.Name)
}
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 {
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) {
@@ -58,9 +67,27 @@ func main() {
log.Debug("checks passed")
}
err = update.Update("/dev/ttyUSB0", 829400, *f)
baudrate := 0
if *brate != 0 {
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!")
}
}

View File

@@ -2,6 +2,7 @@ package update
import (
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"github.com/albenik/go-serial/v2"
@@ -26,8 +27,8 @@ func initmodem(serport string, baudrate int) (*modem, error) {
serial.WithDataBits(8),
serial.WithParity(serial.NoParity),
serial.WithStopBits(serial.OneStopBit),
serial.WithReadTimeout(1000),
serial.WithWriteTimeout(1000))
serial.WithReadTimeout(70),
serial.WithWriteTimeout(70)) // 50 was not stable, bump to 70
if err != nil {
fmt.Printf("ERROR: File %s could not be opened\n", serport)
return nil, err
@@ -40,11 +41,20 @@ func (m *modem) write(out string, nolog ...bool) ([]byte, error) {
if len(nolog) == 0 {
log.Debug("Sending " + out)
} else {
if len(out) < 200 { // in other cases it's the firmware!
log.Debugf("Sending %d byte(s)", len(out))
}
m.port.Write([]byte(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
}
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)
// fmt.Printf("Read %d bytes\n", n)
if err != nil {
@@ -63,7 +73,6 @@ func (m *modem) getSerNum() (string, error) {
}
re := regexp.MustCompile(`Serial number: \w{2,16}`)
sn := strings.ReplaceAll(string(re.Find(answer)), "Serial number: ", "")
log.Infof("Serial Number is: %s", sn)
return sn, nil
}
@@ -94,11 +103,7 @@ func (m *modem) writeUpdate(fwfile string) error {
_, _ = m.write("\033", true) // send ESC to cancel the update
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]))
flashId := binary.LittleEndian.Uint16(answer[0:2])
log.Infof("flash id: % X", flashId)
@@ -113,9 +118,9 @@ func (m *modem) writeUpdate(fwfile string) error {
}
fstat, _ := r.Stat()
fsize := fstat.Size()
r.Close()
_ = r.Close()
_, err = ioutil.ReadFile(fwfile)
fwblob, err := ioutil.ReadFile(fwfile)
if err != nil {
_, _ = m.write("\033", true) // send ESC to cancel the update
return err
@@ -126,13 +131,44 @@ func (m *modem) writeUpdate(fwfile string) error {
chunks++
}
// a := make([]byte, 2)
// binary.BigEndian.PutUint16(a, chunks)
// send ACK
_, 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")
var sendbuff string = ""
for i := 0; i < int(chunks); i++ {
bar.Add(1)
time.Sleep(3 * time.Millisecond)
_ = bar.Add(1)
//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
}
@@ -143,7 +179,14 @@ func Update(serport string, baudrate int, fwfile string) error {
if err != nil {
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 {
return err
}

View File

@@ -40,7 +40,9 @@ var scsbaudrates map[string]int = map[string]int{
func FindSCS() ([]Scsid, error) {
foundids := []Scsid{}
ports, err := enumerator2.GetDetailedPortsList()
if err != nil {
return nil, err
}