package shared import ( "bytes" "fmt" "io" "time" log "github.com/sirupsen/logrus" ) // receive at maximum the requested number of bytes from serial port and stop after the given timeout func ReceiveBytes(port io.Reader, count int, timeout time.Duration) ([]byte, error) { readCh := make(chan []byte, 1) errCh := make(chan error, 1) go func() { buffer := bytes.NewBuffer([]byte{}) for remainder := count; remainder > 0; { data := make([]byte, remainder) if readBytes, err := port.Read(data); err != nil { errCh <- err return } else if readBytes > 0 { buffer.Write(data[0:readBytes]) remainder -= readBytes log.Tracef("%d bytes read, remaining %d", readBytes, remainder) } } readCh <- buffer.Bytes() close(readCh) }() buffer := bytes.NewBuffer([]byte{}) select { case <-time.After(timeout): return nil, fmt.Errorf("timeout passed %v", timeout) case err := <-errCh: return nil, err case data := <-readCh: log.Tracef("received %d bytes from channel", len(data)) if data == nil { break } buffer.Write(data) } return buffer.Bytes(), nil } func SendBytes(port io.Writer, data []byte) error { n, err := port.Write(data) if err != nil { return fmt.Errorf("could not send bytes: %w", err) } log.Tracef("wrote %d bytes", n) return nil }