package main import ( "errors" "flag" "io" "os" "github.com/jacobsa/go-serial/serial" "github.com/peterbourgon/ff/v3" "edge-infra.dev/pkg/lib/fog" ) var ( baudRate uint = 19200 dataBits uint = 8 stopBits uint = 1 minimumReadSize uint = 4 // errMissingDevicePath is thrown when argument for serial device path is missing or empty errMissingDevicePath = errors.New("missing serial device path") // errMissingData is thrown when data argument is missing or has an empty value errMissingData = errors.New("missing data argument") // testData is data sent to serial device testData = "this data is sent to the serial device and read back" ) func main() { fs := flag.NewFlagSet("serial-tester", flag.ExitOnError) flags := FromFlagSet(fs) log := fog.New() if err := ff.Parse(fs, os.Args[1:], ff.WithEnvVarNoPrefix(), ff.WithIgnoreUndefined(true)); err != nil { log.Error(err, "error parsing flags or envvars") os.Exit(1) } if flags.DevPath == nil || *flags.DevPath == "" { log.Error(errMissingDevicePath, "missing argument --devpath") } // set serial port options options := serial.OpenOptions{ PortName: *flags.DevPath, BaudRate: baudRate, DataBits: dataBits, StopBits: stopBits, MinimumReadSize: minimumReadSize, } // open the port and close it later port, err := serial.Open(options) if err != nil { log.Error(err, "error opening serial port") os.Exit(1) } defer port.Close() if flags.Data == nil || *flags.Data == "" { log.Error(errMissingData, "missing argument --data") } log.Info("writing data to serial device", "dataSent", testData) // write data to the serial device _, err = port.Write([]byte(testData)) if err != nil { log.Error(err, "error writing to serial device") os.Exit(1) } // read data from the serial device for { buf := make([]byte, len(testData)) n, err := port.Read(buf) if err != nil { if err != io.EOF { log.Error(err, "error reading from serial device") } } else { buf = buf[:n] log.Info("successful write/read to serial device", "dataSent", testData, "dataRead", string(buf), "device", *flags.DevPath) } } } // Set of flags passed into serial device test type Flags struct { DevPath *string Data *string } // FlagsFromFlagSet returns the possible flags for the serial device test. func FromFlagSet(fs *flag.FlagSet) Flags { return Flags{ DevPath: fs.String( "devpath", "", "path of serial device i.e. /dev/ttyUSB1", ), } }