package via import ( "fmt" "github.com/wobkey/rgb/internal/device" "github.com/wobkey/rgb/internal/hid" ) // Protocol implements the VIA protocol for communication with a keyboard. type Protocol struct { handle *hid.Device kb device.Keyboard } // New creates a new VIA protocol handler for a connected device. func New(dev device.Device) (*Protocol, error) { h, err := hid.OpenPath(dev.Path) if err != nil { return nil, fmt.Errorf("open device %s: %w", dev.Path, err) } return &Protocol{ handle: h, kb: dev.Keyboard, }, nil } // Close releases the device handle. func (p *Protocol) Close() error { if p.handle != nil { return p.handle.Close() } return nil } // ReportID is the VIA report ID. const ReportID = 0x52 // Message defines VIA message types. type Message uint8 const ( Enable Message = 0x01 Set Message = 0x02 Get Message = 0x03 ) // LEDType defines QMK LED subsystem types. type LEDType uint8 const ( RGBLight LEDType = 0x01 ) // EnableHandshake sends the enable message to initialize the VIA connection. func (p *Protocol) EnableHandshake() error { report := []byte{0x00, byte(Enable), 0x00, 0x00, 0x00} _, err := p.handle.SendReport(report[0], report[1:]) return err } // SetValue sends a set value command for the given LED type and parameter. func (p *Protocol) SetValue(ledType LEDType, param uint8, value uint8) error { report := []byte{0x00, byte(Set), byte(ledType), param, value} _, err := p.handle.SendReport(report[0], report[1:]) return err } // GetValue sends a get value request and reads the response. func (p *Protocol) GetValue(ledType LEDType, param uint8) ([]byte, error) { report := []byte{0x00, byte(Get), byte(ledType), param, 0x00} _, err := p.handle.SendReport(report[0], report[1:]) if err != nil { return nil, fmt.Errorf("send get request: %w", err) } buf := make([]byte, 64) n, err := p.handle.Read(buf) if err != nil { return nil, fmt.Errorf("read response: %w", err) } return buf[:n], nil }