ch9329.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package kvmhid
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. )
  7. func (c *Controller) ConfigureChipTo115200() error {
  8. // Send the command to get chip configuration and info
  9. currentConfig, err := c.GetChipCurrentConfiguration()
  10. if err != nil {
  11. fmt.Printf("Error getting current configuration: %v\n", err)
  12. return errors.New("failed to get current configuration")
  13. }
  14. // Modify baudrate bytes in the response
  15. currentConfig[3] = 0x00 // Baudrate byte 1
  16. currentConfig[4] = 0x01 // Baudrate byte 2
  17. currentConfig[5] = 0xC2 // Baudrate byte 3
  18. currentConfig[6] = 0x00 // Baudrate byte 4
  19. time.Sleep(1 * time.Second) // Wait for a second before sending the command
  20. // Prepare the command to set the new configuration
  21. setCmd := append([]byte{0x57, 0xAB, 0x00, 0x09, 0x32}, currentConfig[:50]...)
  22. setCmd = append(setCmd, calcChecksum(setCmd[:len(setCmd)-1]))
  23. err = c.Send(setCmd)
  24. if err != nil {
  25. fmt.Printf("Error sending configuration command: %v\n", err)
  26. return errors.New("failed to send configuration command")
  27. }
  28. // Wait for the reply
  29. resp, err := c.WaitForReply(0x09)
  30. if err != nil {
  31. fmt.Printf("Error waiting for reply: %v\n", err)
  32. return errors.New("failed to get reply")
  33. }
  34. fmt.Println()
  35. fmt.Print("Reply: ")
  36. for _, b := range resp {
  37. fmt.Printf("0x%02X ", b)
  38. }
  39. fmt.Println()
  40. fmt.Println("Baudrate updated to 115200 successfully")
  41. return nil
  42. }
  43. func (c *Controller) WriteChipProperties() ([]byte, error) {
  44. manufacturerString := []byte{
  45. 0x57, 0xAB, 0x00, 0x0B,
  46. 0x09, // Length of payload
  47. 0x00, // Set manufacturer string
  48. 0x07, // Length of the USB manufacturer string
  49. 'i', 'm', 'u', 's', 'l', 'a', 'b',
  50. 0x00, // Checksum placeholder
  51. }
  52. manufacturerString[14] = calcChecksum(manufacturerString[:14])
  53. // Send set manufacturer string
  54. err := c.Send(manufacturerString)
  55. if err != nil {
  56. return nil, fmt.Errorf("failed to send manufacturer string: %v", err)
  57. }
  58. _, err = c.WaitForReply(0x0B)
  59. if err != nil {
  60. return nil, fmt.Errorf("failed to get manufacturer string response: %v", err)
  61. }
  62. productString := []byte{
  63. 0x57, 0xAB, 0x00, 0x0B,
  64. 0x0B, // Length of the payload
  65. 0x01, // Set product string
  66. 0x09, // Length of the USB product string
  67. 'R', 'e', 'm', 'd', 'e', 's', 'K', 'V', 'M',
  68. 0x00, // Checksum placeholder
  69. }
  70. productString[16] = calcChecksum(productString[:16])
  71. // Send set product string
  72. err = c.Send(productString)
  73. if err != nil {
  74. return nil, fmt.Errorf("failed to send product string: %v", err)
  75. }
  76. _, err = c.WaitForReply(0x0B)
  77. if err != nil {
  78. return nil, fmt.Errorf("failed to get product string response: %v", err)
  79. }
  80. return []byte("OK"), nil
  81. }
  82. // GetChipCurrentConfiguration retrieves the current configuration of the chip.
  83. // It sends a command to the chip and waits for a reply.
  84. // Note only the data portion of the response is returned, excluding the header and checksum.
  85. func (c *Controller) GetChipCurrentConfiguration() ([]byte, error) {
  86. //Send the command to get chip configuration and info
  87. cmd := []byte{0x57, 0xAB,
  88. 0x00, 0x08, 0x00,
  89. 0x00, //placeholder for checksum
  90. }
  91. cmd[5] = calcChecksum(cmd[:5])
  92. err := c.Send(cmd)
  93. if err != nil {
  94. fmt.Printf("Error sending command: %v\n", err)
  95. return nil, errors.New("failed to send command")
  96. }
  97. resp, err := c.WaitForReply(0x08)
  98. if err != nil {
  99. fmt.Printf("Error waiting for reply: %v\n", err)
  100. return nil, errors.New("failed to get reply")
  101. }
  102. if len(resp) < 50 {
  103. fmt.Println("Invalid response length")
  104. return nil, errors.New("invalid response length")
  105. }
  106. fmt.Print("Response: ")
  107. for _, b := range resp {
  108. fmt.Printf("0x%02X ", b)
  109. }
  110. fmt.Println()
  111. return resp, nil
  112. }
  113. func (c *Controller) ChipSoftReset() error {
  114. //Send the command to get chip configuration and info
  115. cmd := []byte{0x57, 0xAB,
  116. 0x00, 0x0F,
  117. 0x00, //placeholder for checksum
  118. }
  119. cmd[4] = calcChecksum(cmd[:4])
  120. err := c.Send(cmd)
  121. if err != nil {
  122. fmt.Printf("Error sending command: %v\n", err)
  123. return errors.New("failed to send command")
  124. }
  125. _, err = c.WaitForReply(0x0F)
  126. if err != nil {
  127. fmt.Printf("Error waiting for reply: %v\n", err)
  128. return errors.New("failed to get reply")
  129. }
  130. fmt.Println("Chip soft reset successfully")
  131. return nil
  132. }
  133. func (c *Controller) IsModifierKeys(keycode int) bool {
  134. // Modifier keycodes for JavaScript
  135. modifierKeys := []int{16, 17, 18, 91} // Shift, Ctrl, Alt, Meta (Windows/Command key)
  136. for _, key := range modifierKeys {
  137. if keycode == key {
  138. return true
  139. }
  140. }
  141. return false
  142. }
  143. // ConstructAndSendCmd constructs a HID command based on the provided HIDCommand and sends it.
  144. func (c *Controller) ConstructAndSendCmd(HIDCommand *HIDCommand) ([]byte, error) {
  145. switch HIDCommand.Event {
  146. case EventTypeKeyPress:
  147. if IsModifierKey(uint8(HIDCommand.Keycode)) {
  148. //modifier keys
  149. return c.SetModifierKey(uint8(HIDCommand.Keycode), HIDCommand.IsRightModKey)
  150. } else if HIDCommand.Keycode == 13 && HIDCommand.IsRightModKey {
  151. // Numpad enter
  152. return c.SendKeyboardPress(uint8(146))
  153. }
  154. return c.SendKeyboardPress(uint8(HIDCommand.Keycode))
  155. case EventTypeKeyRelease:
  156. if IsModifierKey(uint8(HIDCommand.Keycode)) {
  157. //modifier keys
  158. return c.UnsetModifierKey(uint8(HIDCommand.Keycode), HIDCommand.IsRightModKey)
  159. } else if HIDCommand.Keycode == 13 && HIDCommand.IsRightModKey {
  160. // Numpad enter
  161. return c.SendKeyboardRelease(uint8(146))
  162. }
  163. return c.SendKeyboardRelease(uint8(HIDCommand.Keycode))
  164. case EventTypeMouseMove:
  165. //Map mouse button state to HID state
  166. leftPressed := (HIDCommand.MouseMoveButtonState & 0x01) != 0
  167. middlePressed := (HIDCommand.MouseMoveButtonState & 0x02) != 0
  168. rightPressed := (HIDCommand.MouseMoveButtonState & 0x04) != 0
  169. if leftPressed {
  170. c.hidState.MouseButtons |= 0x01
  171. } else {
  172. c.hidState.MouseButtons &^= 0x01
  173. }
  174. if middlePressed {
  175. c.hidState.MouseButtons |= 0x04
  176. } else {
  177. c.hidState.MouseButtons &^= 0x04
  178. }
  179. if rightPressed {
  180. c.hidState.MouseButtons |= 0x02
  181. } else {
  182. c.hidState.MouseButtons &^= 0x02
  183. }
  184. // Update mouse position
  185. c.lastCursorEventTime = time.Now().UnixMilli()
  186. if HIDCommand.MouseAbsX != 0 || HIDCommand.MouseAbsY != 0 {
  187. xLSB := byte(HIDCommand.MouseAbsX & 0xFF) // Extract LSB of X
  188. xMSB := byte((HIDCommand.MouseAbsX >> 8) & 0xFF) // Extract MSB of X
  189. yLSB := byte(HIDCommand.MouseAbsY & 0xFF) // Extract LSB of Y
  190. yMSB := byte((HIDCommand.MouseAbsY >> 8) & 0xFF) // Extract MSB of Y
  191. return c.MouseMoveAbsolute(xLSB, xMSB, yLSB, yMSB)
  192. } else if HIDCommand.MouseRelX != 0 || HIDCommand.MouseRelY != 0 {
  193. //Todo
  194. }
  195. return []byte{}, nil
  196. case EventTypeMousePress:
  197. if HIDCommand.MouseButton < 1 || HIDCommand.MouseButton > 3 {
  198. return nil, fmt.Errorf("invalid mouse button: %d", HIDCommand.MouseButton)
  199. }
  200. button := uint8(HIDCommand.MouseButton)
  201. return c.MouseButtonPress(button)
  202. case EventTypeMouseRelease:
  203. if HIDCommand.MouseButton < 1 || HIDCommand.MouseButton > 3 {
  204. return nil, fmt.Errorf("invalid mouse button: %d", HIDCommand.MouseButton)
  205. }
  206. button := uint8(HIDCommand.MouseButton)
  207. return c.MouseButtonRelease(button)
  208. case EventTypeMouseScroll:
  209. if time.Now().UnixMilli()-c.lastCursorEventTime < MinCusorEventInterval {
  210. // Ignore mouse move events that are too close together
  211. return []byte{}, nil
  212. }
  213. c.lastCursorEventTime = time.Now().UnixMilli()
  214. return c.MouseScroll(HIDCommand.MouseScroll)
  215. case EventTypeHIDReset:
  216. return []byte{}, c.ChipSoftReset()
  217. default:
  218. return nil, fmt.Errorf("unsupported HID command event type: %d", HIDCommand.Event)
  219. }
  220. }