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) Close() error { return t.port.Close() }