hidcomm.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package remdeshid
  2. /*
  3. hidcomm.go
  4. This file contains functions to convert HID commands to bytes
  5. that can be sent over the USBKVM device
  6. */
  7. import "fmt"
  8. // Append the keyboard event subtypes to the data
  9. func appendKeyboardEventSubtypes(data []byte, cmd HIDCommand) ([]byte, error) {
  10. /* Keyboard Subtypes */
  11. if len(cmd.Data) == 1 && cmd.Data[0] >= 32 && cmd.Data[0] <= 127 {
  12. //Valid ASCII character
  13. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN {
  14. data = append(data, SUBTYPE_KEYBOARD_ASCII_PRESS)
  15. } else if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_UP {
  16. data = append(data, SUBTYPE_KEYBOARD_ASCII_RELEASE)
  17. } else {
  18. //Key Click
  19. data = append(data, SUBTYPE_KEYBOARD_ASCII_WRITE)
  20. }
  21. data = append(data, cmd.Data[0])
  22. return data, nil
  23. } else if isFuncKey(cmd.Data) {
  24. //Function Key
  25. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN {
  26. data = append(data, SUBTYPE_KEYBOARD_FUNCTKEY_PRESS)
  27. } else {
  28. data = append(data, SUBTYPE_KEYBOARD_FUNCTKEY_RELEASE)
  29. }
  30. data = append(data, funcKeyToByte(cmd.Data))
  31. if data[0] == 0xFF {
  32. return nil, fmt.Errorf("invalid function key: %v", cmd.Data)
  33. }
  34. return data, nil
  35. } else if isModifierKey(cmd.Data) {
  36. //Modifier Key
  37. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN {
  38. data = append(data, SUBTYPE_KEYBOARD_MODIFIER_PRESS)
  39. } else {
  40. data = append(data, SUBTYPE_KEYBOARD_MODIFIER_RELEASE)
  41. }
  42. data = append(data, modifierKeyToByte(cmd.Data))
  43. if data[0] == 0xFF {
  44. return nil, fmt.Errorf("invalid modifier key: %v", cmd.Data)
  45. }
  46. return data, nil
  47. } else if isOtherKeys(cmd.Data) {
  48. //Other Keys
  49. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN {
  50. data = append(data, SUBTYPE_KEYBOARD_OTHERKEY_PRESS)
  51. } else if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_UP {
  52. data = append(data, SUBTYPE_KEYBOARD_OTHERKEY_RELEASE)
  53. } else {
  54. return nil, fmt.Errorf("invalid HID command subtype: %v", cmd.Data)
  55. }
  56. data = append(data, nonAsciiKeysToBytes(cmd.Data)...)
  57. return data, nil
  58. } else if isNumpadKey(cmd.Data) {
  59. //Numpad Keys
  60. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN {
  61. data = append(data, SUBTYPE_KEYBOARD_NUMPAD_PRESS)
  62. } else if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_UP {
  63. data = append(data, SUBTYPE_KEYBOARD_NUMPAD_RELEASE)
  64. } else {
  65. return nil, fmt.Errorf("invalid HID command subtype: %v", cmd.Data)
  66. }
  67. data = append(data, numpadKeyToByte(string(cmd.Data)))
  68. return data, nil
  69. } else if cmd.Data == "NumLock" {
  70. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN {
  71. data = append(data, SUBTYPE_KEYBOARD_SPECIAL_NUMLOCK)
  72. data = append(data, 0x00)
  73. return data, nil
  74. }
  75. return nil, fmt.Errorf("numLock do not support key up")
  76. } else if cmd.Data == "Pause" {
  77. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN {
  78. data = append(data, SUBTYPE_KEYBOARD_SPECIAL_PAUSE)
  79. data = append(data, 0x00)
  80. return data, nil
  81. }
  82. return nil, fmt.Errorf("pause do not support key up")
  83. } else if cmd.Data == "PrintScreen" {
  84. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_UP {
  85. data = append(data, SUBTYPE_KEYBOARD_SPECIAL_PRINT_SCREEN)
  86. data = append(data, 0x00)
  87. return data, nil
  88. }
  89. return nil, fmt.Errorf("printScreen do not support key down")
  90. } else if cmd.Data == "ScrollLock" {
  91. if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN {
  92. data = append(data, SUBTYPE_KEYBOARD_SPECIAL_SCROLL_LOCK)
  93. data = append(data, 0x00)
  94. return data, nil
  95. }
  96. return nil, fmt.Errorf("scrollLock do not support key up")
  97. } else if cmd.Data == "ContextMenu" {
  98. //Special Key: ContextMenu
  99. //TODO: Implement ContextMenu
  100. return nil, fmt.Errorf("ContextMenu not implemented")
  101. } else if cmd.Data == "Ctrl+Alt+Del" {
  102. //Special Key: Ctrl+Alt+Del
  103. data = append(data, SUBTYPE_KEYBOARD_SPECIAL_CTRLALTDEL)
  104. data = append(data, 0x00)
  105. return data, nil
  106. } else {
  107. return nil, fmt.Errorf("invalid HID command subtype: %v", cmd.Data)
  108. }
  109. }
  110. // Append the mouse move event subtypes to the data
  111. func appendMouseMoveEventSubtypes(data []byte, cmd HIDCommand) ([]byte, error) {
  112. //The mouse move command requires x_pos, y_pos, x_sign, y_sign
  113. x_pos := cmd.PosX
  114. y_pos := cmd.PosY
  115. xIsNegative := x_pos < 0
  116. yIsNegative := y_pos < 0
  117. x_sign := 0
  118. y_sign := 0
  119. if xIsNegative {
  120. x_pos = -x_pos
  121. x_sign = 1
  122. }
  123. if yIsNegative {
  124. y_pos = -y_pos
  125. y_sign = 1
  126. }
  127. //The max value for x_pos and y_pos are 0xFE, make sure they are within the range
  128. if x_pos > 0xFE {
  129. x_pos = 0xFE
  130. }
  131. if y_pos > 0xFE {
  132. y_pos = 0xFE
  133. }
  134. data = append(data, byte(x_pos), byte(y_pos), byte(x_sign), byte(y_sign))
  135. return data, nil
  136. }
  137. //Entry function for converting a HIDCommand to bytes that can be sent over the USBKVM device
  138. func ConvHIDCommandToBytes(cmd HIDCommand) ([]byte, error) {
  139. // Convert the HID command to bytes
  140. var data []byte
  141. if cmd.EventType == FRONTEND_OPR_TYPE_KEYBOARD_WRITE {
  142. data = []byte{OPR_TYPE_KEYBOARD_WRITE}
  143. return appendKeyboardEventSubtypes(data, cmd)
  144. } else if cmd.EventType == FRONTEND_OPR_TYPE_MOUSE_WRITE {
  145. /* Mouse Write Event */
  146. data = []byte{OPR_TYPE_MOUSE_WRITE}
  147. } else if cmd.EventType == FRONTEND_OPR_TYPE_MOUSE_MOVE {
  148. /* Mouse Move Event */
  149. data = []byte{OPR_TYPE_MOUSE_MOVE}
  150. return appendMouseMoveEventSubtypes(data, cmd)
  151. } else if cmd.EventType == FRONTEND_OPR_TYPE_MOUSE_SCROLL {
  152. /* Mouse Scroll Event */
  153. data = []byte{OPR_TYPE_MOUSE_SCROLL}
  154. } else {
  155. return nil, fmt.Errorf("invalid HID command type: %s", cmd.EventType)
  156. }
  157. return data, nil
  158. }