protocol.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package via
  2. import (
  3. "fmt"
  4. "github.com/wobkey/rgb/internal/device"
  5. "github.com/wobkey/rgb/internal/hid"
  6. )
  7. // Protocol implements the VIA protocol for communication with a keyboard.
  8. type Protocol struct {
  9. handle *hid.Device
  10. kb device.Keyboard
  11. }
  12. // New creates a new VIA protocol handler for a connected device.
  13. func New(dev device.Device) (*Protocol, error) {
  14. h, err := hid.OpenPath(dev.Path)
  15. if err != nil {
  16. return nil, fmt.Errorf("open device %s: %w", dev.Path, err)
  17. }
  18. return &Protocol{
  19. handle: h,
  20. kb: dev.Keyboard,
  21. }, nil
  22. }
  23. // Close releases the device handle.
  24. func (p *Protocol) Close() error {
  25. if p.handle != nil {
  26. return p.handle.Close()
  27. }
  28. return nil
  29. }
  30. // ReportID is the VIA report ID.
  31. const ReportID = 0x52
  32. // Message defines VIA message types.
  33. type Message uint8
  34. const (
  35. Enable Message = 0x01
  36. Set Message = 0x02
  37. Get Message = 0x03
  38. )
  39. // LEDType defines QMK LED subsystem types.
  40. type LEDType uint8
  41. const (
  42. RGBLight LEDType = 0x01
  43. )
  44. // EnableHandshake sends the enable message to initialize the VIA connection.
  45. func (p *Protocol) EnableHandshake() error {
  46. report := []byte{0x00, byte(Enable), 0x00, 0x00, 0x00}
  47. _, err := p.handle.SendReport(report[0], report[1:])
  48. return err
  49. }
  50. // SetValue sends a set value command for the given LED type and parameter.
  51. func (p *Protocol) SetValue(ledType LEDType, param uint8, value uint8) error {
  52. report := []byte{0x00, byte(Set), byte(ledType), param, value}
  53. _, err := p.handle.SendReport(report[0], report[1:])
  54. return err
  55. }
  56. // GetValue sends a get value request and reads the response.
  57. func (p *Protocol) GetValue(ledType LEDType, param uint8) ([]byte, error) {
  58. report := []byte{0x00, byte(Get), byte(ledType), param, 0x00}
  59. _, err := p.handle.SendReport(report[0], report[1:])
  60. if err != nil {
  61. return nil, fmt.Errorf("send get request: %w", err)
  62. }
  63. buf := make([]byte, 64)
  64. n, err := p.handle.Read(buf)
  65. if err != nil {
  66. return nil, fmt.Errorf("read response: %w", err)
  67. }
  68. return buf[:n], nil
  69. }