handler.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package remdeshid
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "net/http"
  7. "time"
  8. "github.com/gorilla/websocket"
  9. )
  10. type EventType int
  11. const (
  12. EventTypeKeyPress EventType = iota
  13. EventTypeKeyRelease
  14. EventTypeMouseMove
  15. EventTypeMousePress
  16. EventTypeMouseRelease
  17. EventTypeMouseScroll
  18. EventTypeHIDCommand
  19. )
  20. const MinCusrorEventInterval = 1 //ms
  21. type HIDCommand struct {
  22. Event EventType `json:"event"`
  23. Keycode int `json:"keycode,omitempty"`
  24. IsRightModKey bool `json:"is_right_modifier_key,omitempty"` // true if the key is a right modifier key (Ctrl, Shift, Alt, GUI)
  25. MouseAbsX int `json:"mouse_x,omitempty"` // Absolute mouse position in X direction
  26. MouseAbsY int `json:"mouse_y,omitempty"` // Absolute mouse position in Y direction
  27. MouseRelX int `json:"mouse_rel_x,omitempty"` // Relative mouse movement in X direction
  28. MouseRelY int `json:"mouse_rel_y,omitempty"` // Relative mouse movement in Y direction
  29. MouseButton int `json:"mouse_button,omitempty"` //0x01 for left click, 0x02 for right click, 0x03 for middle clicks
  30. MouseScroll int `json:"mouse_scroll,omitempty"` // Positive for scroll up, negative for scroll down, max 127
  31. }
  32. // HIDWebSocketHandler is a handler for the HID WebSocket connection
  33. var upgrader = websocket.Upgrader{
  34. ReadBufferSize: 1024,
  35. WriteBufferSize: 1024,
  36. CheckOrigin: func(r *http.Request) bool {
  37. return true
  38. },
  39. }
  40. func (c *Controller) IsModifierKeys(keycode int) bool {
  41. // Modifier keycodes for JavaScript
  42. modifierKeys := []int{16, 17, 18, 91} // Shift, Ctrl, Alt, Meta (Windows/Command key)
  43. for _, key := range modifierKeys {
  44. if keycode == key {
  45. return true
  46. }
  47. }
  48. return false
  49. }
  50. // Convert a keycode to the corresponding HID opcode for modifier keys
  51. func (c *Controller) GetModkeyOpcode(keycode int, isRight bool) int {
  52. switch keycode {
  53. case 17: // Ctrl
  54. if isRight {
  55. return 0x05 // Right Ctrl
  56. }
  57. return 0x01 // Left Ctrl
  58. case 16: // Shift
  59. if isRight {
  60. return 0x06 // Right Shift
  61. }
  62. return 0x02 // Left Shift
  63. case 18: // Alt
  64. if isRight {
  65. return 0x07 // Right Alt
  66. }
  67. return 0x03 // Left Alt
  68. case 91: // Meta (Windows/Command key)
  69. if isRight {
  70. return 0x08 // Right GUI (Windows)
  71. }
  72. return 0x04 // Left GUI (Windows)
  73. default:
  74. return 0x00 // Unknown or unmapped key
  75. }
  76. }
  77. // Generate the required LTV (length, type, value) bytes for the HID command
  78. func (c *Controller) GenerateUARTCmd(HIDCommand *HIDCommand) ([]byte, error) {
  79. switch HIDCommand.Event {
  80. case EventTypeKeyPress:
  81. if c.IsModifierKeys(HIDCommand.Keycode) {
  82. // If it's a modifier key, we need to return the appropriate opcode
  83. opcode := c.GetModkeyOpcode(HIDCommand.Keycode, HIDCommand.IsRightModKey)
  84. if opcode == 0x00 {
  85. return nil, fmt.Errorf("unsupported modifier key: %d", HIDCommand.Keycode)
  86. }
  87. return []byte{0x02, 0x03, byte(opcode)}, nil
  88. } else if HIDCommand.Keycode == 13 && HIDCommand.IsRightModKey {
  89. //Special case for right Enter key
  90. return []byte{0x02, 0x01, 0x92}, nil
  91. }
  92. return []byte{0x02, 0x01, byte(HIDCommand.Keycode)}, nil
  93. case EventTypeKeyRelease:
  94. if c.IsModifierKeys(HIDCommand.Keycode) {
  95. // If it's a modifier key, we need to return the appropriate opcode
  96. opcode := c.GetModkeyOpcode(HIDCommand.Keycode, HIDCommand.IsRightModKey)
  97. if opcode == 0x00 {
  98. return nil, fmt.Errorf("unsupported modifier key: %d", HIDCommand.Keycode)
  99. }
  100. return []byte{0x02, 0x04, byte(opcode)}, nil
  101. } else if HIDCommand.Keycode == 13 && HIDCommand.IsRightModKey {
  102. //Special case for right Enter key
  103. return []byte{0x02, 0x02, 0x92}, nil
  104. }
  105. return []byte{0x02, 0x02, byte(HIDCommand.Keycode)}, nil
  106. case EventTypeMouseMove:
  107. if (time.Now().UnixMilli() - c.lastCursorEventTime) < MinCusrorEventInterval {
  108. // If the last cursor event was too recent, we skip sending this one
  109. return []byte{}, nil
  110. }
  111. c.lastCursorEventTime = time.Now().UnixMilli()
  112. if HIDCommand.MouseAbsX != 0 || HIDCommand.MouseAbsY != 0 {
  113. // If absolute mouse movement is specified, we send it as a single command
  114. xLSB := byte(HIDCommand.MouseAbsX & 0xFF)
  115. xMSB := byte((HIDCommand.MouseAbsX >> 8) & 0xFF)
  116. yLSB := byte(HIDCommand.MouseAbsY & 0xFF)
  117. yMSB := byte((HIDCommand.MouseAbsY >> 8) & 0xFF)
  118. return []byte{0x05, 0x09, xLSB, xMSB, yLSB, yMSB}, nil
  119. } else if HIDCommand.MouseRelX != 0 || HIDCommand.MouseRelY != 0 {
  120. // If relative mouse movement is specified, we send it as a single command
  121. //TODO
  122. return []byte{0x03, 0x0A, byte(HIDCommand.MouseRelX), byte(HIDCommand.MouseRelY)}, nil
  123. }
  124. return nil, fmt.Errorf("no mouse movement specified")
  125. case EventTypeMousePress:
  126. if HIDCommand.MouseButton < 1 || HIDCommand.MouseButton > 3 {
  127. return nil, fmt.Errorf("invalid mouse button: %d", HIDCommand.MouseButton)
  128. }
  129. // Mouse button click event
  130. return []byte{0x02, 0x05, byte(HIDCommand.MouseButton)}, nil
  131. case EventTypeMouseRelease:
  132. if HIDCommand.MouseButton < 1 || HIDCommand.MouseButton > 3 {
  133. return nil, fmt.Errorf("invalid mouse button: %d", HIDCommand.MouseButton)
  134. }
  135. // Mouse button release event
  136. return []byte{0x02, 0x06, byte(HIDCommand.MouseButton)}, nil
  137. case EventTypeMouseScroll:
  138. if (time.Now().UnixMilli() - c.lastCursorEventTime) < MinCusrorEventInterval {
  139. // If the last cursor event was too recent, we skip sending this one
  140. return []byte{}, nil
  141. }
  142. c.lastCursorEventTime = time.Now().UnixMilli()
  143. if HIDCommand.MouseScroll < -127 || HIDCommand.MouseScroll > 127 {
  144. return nil, fmt.Errorf("invalid mouse scroll value: %d", HIDCommand.MouseScroll)
  145. }
  146. // Mouse scroll event
  147. if HIDCommand.MouseScroll < 0 {
  148. return []byte{0x02, 0x07, byte(HIDCommand.MouseScroll * -1)}, nil
  149. } else {
  150. return []byte{0x02, 0x08, byte(HIDCommand.MouseScroll)}, nil
  151. }
  152. default:
  153. return nil, fmt.Errorf("unsupported HID command event type: %d", HIDCommand.Event)
  154. }
  155. }
  156. func (c *Controller) HIDWebSocketHandler(w http.ResponseWriter, r *http.Request) {
  157. conn, err := upgrader.Upgrade(w, r, nil)
  158. if err != nil {
  159. log.Println("Failed to upgrade to websocket:", err)
  160. return
  161. }
  162. defer conn.Close()
  163. for {
  164. _, message, err := conn.ReadMessage()
  165. if err != nil {
  166. log.Println("Error reading message:", err)
  167. break
  168. }
  169. log.Printf("Received: %s", message)
  170. //Try parsing the message as a HIDCommand
  171. var hidCmd HIDCommand
  172. if err := json.Unmarshal(message, &hidCmd); err != nil {
  173. log.Println("Error parsing message:", err)
  174. continue
  175. }
  176. bytes, err := c.GenerateUARTCmd(&hidCmd)
  177. if err != nil {
  178. errmsg := map[string]string{"error": err.Error()}
  179. if err := conn.WriteJSON(errmsg); err != nil {
  180. log.Println("Error writing message:", err)
  181. continue
  182. }
  183. log.Println("Error generating UART command:", err)
  184. continue
  185. }
  186. if len(bytes) == 0 {
  187. if err := conn.WriteMessage(websocket.TextMessage, []byte("ok")); err != nil {
  188. log.Println("Error writing message:", err)
  189. }
  190. continue
  191. }
  192. fmt.Println("Sending bytes:", bytes)
  193. //Write the bytes to the serial port
  194. if err := c.Send(bytes); err != nil {
  195. errmsg := map[string]string{"error": err.Error()}
  196. if err := conn.WriteJSON(errmsg); err != nil {
  197. log.Println("Error writing message:", err)
  198. }
  199. continue
  200. }
  201. if err := conn.WriteMessage(websocket.TextMessage, []byte("ok")); err != nil {
  202. log.Println("Error writing message:", err)
  203. continue
  204. }
  205. }
  206. }