// Copyright 2021 Torsten Harenberg DL1THM. All rights reserved. // A SCS PACTOR modem flashing utility written in Go. Should run anywhere Go runs. package main import ( "fmt" "github.com/akamensky/argparse" "github.com/go-playground/log/v7" "github.com/go-playground/log/v7/handlers/console" "go-scsupdate/firmware" "go-scsupdate/update" "go-scsupdate/usb" "os" ) 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."}) 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"}) force := parser.Flag("", "force", &argparse.Options{Required: false, Help: "(optional) skip testing if firmware fits modem. Useful if the modem is bricked and you need to put it into BIOS mode. Read the manual!"}) sertimeout := parser.Int("t", "timeout", &argparse.Options{Required: false, Help: "(optional) Sets the read and write timeout. Default: 70. If you have handshake problems, enlarge this values, especially for older modems."}) err := parser.Parse(os.Args) cLog := console.New(true) if *debug { log.AddHandler(cLog, log.AllLevels...) log.Debug("DEBUG logging enabled") } else { log.AddHandler(cLog, log.InfoLevel, log.ErrorLevel, log.AlertLevel, log.WarnLevel, log.NoticeLevel, log.PanicLevel) } if *sertimeout == 0 { // if not set, set the write / read timeout to 70 *sertimeout = 70 } 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) } var ports []usb.Scsid if *serialDevice == "" { if ports, err = usb.FindSCS(); err == nil { if len(ports) == 0 { log.Fatal("Found no SCS modem.") } if len(ports) != 1 { msg := "Found more than one SCS modem. You need to choose one with the -s flag.\nfound: " for _, p := range ports { 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) { log.Panicf("Error: firmware file %s does not exist.\n", *f) } if firmware.ChkHeader(*f) != nil { log.Panic(err) } else { log.Debug("checks passed") } 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, *sertimeout, *f, *force) } else { err = update.Update(ports[0].Port, baudrate, *sertimeout, *f, *force) } if err != nil { log.Panic(err) } } else { log.Info("Dryrun requested, no firmware written!") } }