first running version
This commit is contained in:
35
main.go
35
main.go
@@ -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)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
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!")
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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 {
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user