remdeshid.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package remdeshid
  2. import (
  3. "fmt"
  4. "log"
  5. "time"
  6. "github.com/tarm/serial"
  7. )
  8. func NewHIDController(config *Config) *Controller {
  9. // Initialize the HID state with default values
  10. defaultHidState := HIDState{
  11. Modkey: 0x00,
  12. KeyboardButtons: [6]uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  13. Leds: 0x00,
  14. MouseButtons: 0x00, // No mouse buttons pressed
  15. MouseX: 0,
  16. MouseY: 0,
  17. }
  18. return &Controller{
  19. Config: config,
  20. serialRunning: false,
  21. hidState: defaultHidState,
  22. writeQueue: make(chan []byte, 32),
  23. incomgDataQueue: make(chan []byte, 1024),
  24. }
  25. }
  26. // Connect opens the serial port and starts reading from it
  27. func (c *Controller) Connect() error {
  28. // Open the serial port
  29. config := &serial.Config{
  30. Name: c.Config.PortName,
  31. Baud: c.Config.BaudRate,
  32. Size: 8,
  33. Parity: serial.ParityNone,
  34. }
  35. port, err := serial.OpenPort(config)
  36. if err != nil {
  37. return err
  38. }
  39. c.serialPort = port
  40. //Start reading from the serial port
  41. go func() {
  42. buf := make([]byte, 1024)
  43. for {
  44. n, err := port.Read(buf)
  45. if err != nil {
  46. log.Println(err.Error())
  47. return
  48. }
  49. if n > 0 {
  50. c.incomgDataQueue <- buf[:n]
  51. //fmt.Print("Received bytes: ")
  52. //for i := 0; i < n; i++ {
  53. // fmt.Printf("0x%02X ", buf[i])
  54. //}
  55. fmt.Println()
  56. }
  57. }
  58. }()
  59. //Create a loop to write to the serial port
  60. c.serialRunning = true
  61. go func() {
  62. for {
  63. data := <-c.writeQueue
  64. _, err := port.Write(data)
  65. if err != nil {
  66. log.Println(err.Error())
  67. return
  68. }
  69. }
  70. }()
  71. //Send over an opr queue reset signal
  72. err = c.Send([]byte{0xFF})
  73. if err != nil {
  74. return err
  75. }
  76. return nil
  77. }
  78. func (c *Controller) Send(data []byte) error {
  79. if !c.serialRunning {
  80. return fmt.Errorf("serial port is not running")
  81. }
  82. select {
  83. case c.writeQueue <- data:
  84. return nil
  85. case <-time.After(30 * time.Millisecond):
  86. return fmt.Errorf("timeout waiting to send data")
  87. }
  88. }
  89. func (c *Controller) ClearReadQueue() {
  90. // Clear the incoming data queue
  91. for len(c.incomgDataQueue) > 0 {
  92. <-c.incomgDataQueue
  93. }
  94. }
  95. func (c *Controller) WaitForReply(cmdByte byte) ([]byte, error) {
  96. // Wait for a reply from the device
  97. succReplyByte := cmdByte | 0x80
  98. errorReplyByte := cmdByte | 0xC0
  99. timeout := make(chan bool, 1)
  100. go func() {
  101. // Timeout after 500ms
  102. time.Sleep(500 * time.Millisecond)
  103. timeout <- true
  104. }()
  105. var reply []byte
  106. for {
  107. select {
  108. case data := <-c.incomgDataQueue:
  109. reply = append(reply, data...)
  110. // Check if we have received enough bytes for a complete packet
  111. if len(reply) >= 7 {
  112. // Validate header
  113. if reply[0] == 0x57 && reply[1] == 0xAB {
  114. // Extract fields
  115. //address := reply[2]
  116. replyByte := reply[3]
  117. dataLength := reply[4]
  118. expectedLength := 5 + int(dataLength) + 1 // Header + address + replyByte + dataLength + data + checksum
  119. // Check if the full packet is received
  120. if len(reply) >= expectedLength {
  121. data := reply[5 : 5+dataLength]
  122. checksum := reply[5+dataLength]
  123. // Calculate checksum
  124. sum := byte(0)
  125. for _, b := range reply[:5+dataLength] {
  126. sum += b
  127. }
  128. // Validate checksum
  129. if sum == checksum {
  130. // Check reply byte for success or error
  131. switch replyByte {
  132. case succReplyByte:
  133. return data, nil
  134. case errorReplyByte:
  135. return nil, fmt.Errorf("device returned error reply")
  136. }
  137. } else {
  138. return nil, fmt.Errorf("checksum validation failed")
  139. }
  140. }
  141. } else {
  142. // Invalid header, discard data
  143. reply = nil
  144. }
  145. }
  146. case <-timeout:
  147. return nil, fmt.Errorf("timeout waiting for reply")
  148. }
  149. }
  150. }
  151. func (c *Controller) Close() {
  152. if c.serialPort != nil {
  153. c.serialPort.Close()
  154. }
  155. }