Files
2026-09-03 13:08:01 +03:00

71 lines
2.0 KiB
Go

// Package localuart находит и открывает USB-UART адаптер напрямую, без
// демона — для standalone-версии приложения (internal/localctl).
package localuart
import (
"fmt"
"sort"
"strings"
"go.bug.st/serial/enumerator"
)
// knownVID — VID распространённых чипов USB-UART мостов. Порты с таким VID
// считаются вероятным переходником "UART to USB" и предлагаются первыми.
var knownVID = map[string]bool{
"0403": true, // FTDI
"1A86": true, // WCH CH340 / CH341
"10C4": true, // Silicon Labs CP210x
"067B": true, // Prolific PL2303
}
// Candidate — один найденный USB-serial порт.
type Candidate struct {
Name string
VID string
PID string
}
// ListCandidates возвращает USB-serial порты, обнаруженные в системе;
// порты с известным VID переходника идут первыми.
func ListCandidates() ([]Candidate, error) {
ports, err := enumerator.GetDetailedPortsList()
if err != nil {
return nil, err
}
var known, other []Candidate
for _, p := range ports {
if !p.IsUSB {
continue
}
c := Candidate{
Name: p.Name,
VID: strings.ToUpper(p.VID),
PID: strings.ToUpper(p.PID),
}
if knownVID[c.VID] {
known = append(known, c)
} else {
other = append(other, c)
}
}
sort.Slice(known, func(i, j int) bool { return known[i].Name < known[j].Name })
sort.Slice(other, func(i, j int) bool { return other[i].Name < other[j].Name })
return append(known, other...), nil
}
// PickPort возвращает наиболее вероятный порт UART-to-USB переходника.
func PickPort() (string, error) {
candidates, err := ListCandidates()
if err != nil {
return "", fmt.Errorf("не удалось получить список портов: %w", err)
}
if len(candidates) == 0 {
return "", fmt.Errorf("USB-UART адаптер не найден")
}
return candidates[0].Name, nil
}