69 lines
1.4 KiB
Go
69 lines
1.4 KiB
Go
package client
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"slices"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.bug.st/serial"
|
|
"go.bug.st/serial/enumerator"
|
|
)
|
|
|
|
func ListSerial() ([]string, error) {
|
|
ports, err := enumerator.GetDetailedPortsList()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("enumerating ports: %w", err)
|
|
}
|
|
type entry struct {
|
|
name string
|
|
serial string
|
|
}
|
|
var entries []entry
|
|
for _, p := range ports {
|
|
if p.IsUSB && p.VID == "2E8A" && strings.HasPrefix(p.Name, "/dev/cu.") {
|
|
entries = append(entries, entry{p.Name, p.SerialNumber})
|
|
}
|
|
}
|
|
slices.SortFunc(entries, func(a, b entry) int {
|
|
return strings.Compare(a.serial, b.serial)
|
|
})
|
|
var result []string
|
|
for _, e := range entries {
|
|
result = append(result, e.name)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
type serialTransport struct {
|
|
port serial.Port
|
|
}
|
|
|
|
func NewSerial(portName string, timeout time.Duration) (*Client, error) {
|
|
port, err := serial.Open(portName, &serial.Mode{BaudRate: 115200})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("opening %s: %w", portName, err)
|
|
}
|
|
return &Client{transport: &serialTransport{port: port}, timeout: timeout}, nil
|
|
}
|
|
|
|
func (t *serialTransport) Send(data []byte) error {
|
|
_, err := t.port.Write(data)
|
|
return err
|
|
}
|
|
|
|
func (t *serialTransport) SetReadTimeout(timeout time.Duration) {
|
|
t.port.SetReadTimeout(timeout)
|
|
}
|
|
|
|
func (t *serialTransport) Reader() io.Reader {
|
|
return t.port
|
|
}
|
|
|
|
func (t *serialTransport) Broadcast() bool { return false }
|
|
|
|
func (t *serialTransport) Close() error {
|
|
return t.port.Close()
|
|
}
|