- DeviceSpec, DeviceRole, DeviceState, DeviceEvent, Command types - KnownDevices registry with PRT Qutie placeholder (0525:a4a7) - enumerateConnected() with system_profiler JSON parsing + injectable test seams - ParseVIDPID() helper with error on malformed input - All 5 device_test.go tests pass - go.bug.st/serial v1.6.4 added to go.mod
77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package usb
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
)
|
|
|
|
// DeviceRole classifies what a USB device is used for in HWLab.
|
|
type DeviceRole int
|
|
|
|
const (
|
|
RolePrinter DeviceRole = iota
|
|
RoleCableTester // reserved for Phase 5
|
|
RoleUnknown
|
|
)
|
|
|
|
// DeviceSpec describes a known USB peripheral by VID and PID.
|
|
type DeviceSpec struct {
|
|
VID string // 4-hex-digit vendor ID, e.g. "0525"
|
|
PID string // 4-hex-digit product ID, e.g. "a4a7"
|
|
Name string // human-readable label for logs
|
|
Role DeviceRole
|
|
BaudRate int // serial baud rate; 0 means use 9600 default
|
|
}
|
|
|
|
// VIDPID returns the canonical "VID:PID" key string.
|
|
func (s DeviceSpec) VIDPID() string { return s.VID + ":" + s.PID }
|
|
|
|
// String returns "VID:PID (Name)" format for logging.
|
|
func (s DeviceSpec) String() string { return s.VIDPID() + " (" + s.Name + ")" }
|
|
|
|
// KnownDevices maps "VID:PID" to DeviceSpec for all peripherals HWLab manages.
|
|
// Update VID/PID values after hardware characterization on 2026-04-13.
|
|
var KnownDevices = map[string]DeviceSpec{
|
|
"0525:a4a7": {VID: "0525", PID: "a4a7", Name: "PRT Qutie", Role: RolePrinter, BaudRate: 9600},
|
|
// Phase 5: Treedix testers will be added here after characterization
|
|
}
|
|
|
|
// DeviceState represents the current connection status of a managed device.
|
|
type DeviceState int
|
|
|
|
const (
|
|
StateDisconnected DeviceState = iota
|
|
StateConnected
|
|
)
|
|
|
|
// DeviceEvent is emitted on the Manager.Events() channel for any state change.
|
|
type DeviceEvent struct {
|
|
VIDPID string
|
|
Spec DeviceSpec
|
|
State DeviceState
|
|
}
|
|
|
|
// Command is sent to a device goroutine via its command channel.
|
|
type Command struct {
|
|
Type CommandType
|
|
Payload []byte
|
|
Reply chan<- error // caller closes or receives result
|
|
}
|
|
|
|
// CommandType discriminates Command variants.
|
|
type CommandType int
|
|
|
|
const (
|
|
CmdWrite CommandType = iota
|
|
CmdClose
|
|
)
|
|
|
|
// ParseVIDPID splits a "VID:PID" string into its constituent parts.
|
|
// Returns an error if the format is not exactly "xxxx:xxxx".
|
|
func ParseVIDPID(s string) (vid, pid string, err error) {
|
|
parts := strings.SplitN(s, ":", 2)
|
|
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
|
return "", "", errors.New("invalid VID:PID format: expected \"xxxx:xxxx\", got " + s)
|
|
}
|
|
return parts[0], parts[1], nil
|
|
}
|