65 lines
1.3 KiB
Go
65 lines
1.3 KiB
Go
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
|
|
}
|