package remdeshid /* hidcomm.go This file contains functions to convert HID commands to bytes that can be sent over the USBKVM device */ import "fmt" // Append the keyboard event subtypes to the data func appendKeyboardEventSubtypes(data []byte, cmd HIDCommand) ([]byte, error) { /* Keyboard Subtypes */ if len(cmd.Data) == 1 && cmd.Data[0] >= 32 && cmd.Data[0] <= 127 { //Valid ASCII character if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN { data = append(data, SUBTYPE_KEYBOARD_ASCII_PRESS) } else if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_UP { data = append(data, SUBTYPE_KEYBOARD_ASCII_RELEASE) } else { //Key Click data = append(data, SUBTYPE_KEYBOARD_ASCII_WRITE) } data = append(data, cmd.Data[0]) return data, nil } else if isFuncKey(cmd.Data) { //Function Key if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN { data = append(data, SUBTYPE_KEYBOARD_FUNCTKEY_PRESS) } else { data = append(data, SUBTYPE_KEYBOARD_FUNCTKEY_RELEASE) } data = append(data, funcKeyToByte(cmd.Data)) if data[0] == 0xFF { return nil, fmt.Errorf("invalid function key: %v", cmd.Data) } return data, nil } else if isModifierKey(cmd.Data) { //Modifier Key if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN { data = append(data, SUBTYPE_KEYBOARD_MODIFIER_PRESS) } else { data = append(data, SUBTYPE_KEYBOARD_MODIFIER_RELEASE) } data = append(data, modifierKeyToByte(cmd.Data)) if data[0] == 0xFF { return nil, fmt.Errorf("invalid modifier key: %v", cmd.Data) } return data, nil } else if isOtherKeys(cmd.Data) { //Other Keys if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN { data = append(data, SUBTYPE_KEYBOARD_OTHERKEY_PRESS) } else if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_UP { data = append(data, SUBTYPE_KEYBOARD_OTHERKEY_RELEASE) } else { return nil, fmt.Errorf("invalid HID command subtype: %v", cmd.Data) } data = append(data, nonAsciiKeysToBytes(cmd.Data)...) return data, nil } else if isNumpadKey(cmd.Data) { //Numpad Keys if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN { data = append(data, SUBTYPE_KEYBOARD_NUMPAD_PRESS) } else if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_UP { data = append(data, SUBTYPE_KEYBOARD_NUMPAD_RELEASE) } else { return nil, fmt.Errorf("invalid HID command subtype: %v", cmd.Data) } data = append(data, numpadKeyToByte(string(cmd.Data))) return data, nil } else if cmd.Data == "NumLock" { if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN { data = append(data, SUBTYPE_KEYBOARD_SPECIAL_NUMLOCK) data = append(data, 0x00) return data, nil } return nil, fmt.Errorf("numLock do not support key up") } else if cmd.Data == "Pause" { if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN { data = append(data, SUBTYPE_KEYBOARD_SPECIAL_PAUSE) data = append(data, 0x00) return data, nil } return nil, fmt.Errorf("pause do not support key up") } else if cmd.Data == "PrintScreen" { if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_UP { data = append(data, SUBTYPE_KEYBOARD_SPECIAL_PRINT_SCREEN) data = append(data, 0x00) return data, nil } return nil, fmt.Errorf("printScreen do not support key down") } else if cmd.Data == "ScrollLock" { if cmd.EventSubType == FRONTEND_SUBTYPE_KEYBOARD_KEY_DOWN { data = append(data, SUBTYPE_KEYBOARD_SPECIAL_SCROLL_LOCK) data = append(data, 0x00) return data, nil } return nil, fmt.Errorf("scrollLock do not support key up") } else if cmd.Data == "ContextMenu" { //Special Key: ContextMenu //TODO: Implement ContextMenu return nil, fmt.Errorf("ContextMenu not implemented") } else if cmd.Data == "Ctrl+Alt+Del" { //Special Key: Ctrl+Alt+Del data = append(data, SUBTYPE_KEYBOARD_SPECIAL_CTRLALTDEL) data = append(data, 0x00) return data, nil } else { return nil, fmt.Errorf("invalid HID command subtype: %v", cmd.Data) } } // Append the mouse move event subtypes to the data func appendMouseMoveEventSubtypes(data []byte, cmd HIDCommand) ([]byte, error) { //The mouse move command requires x_pos, y_pos, x_sign, y_sign x_pos := cmd.PosX y_pos := cmd.PosY xIsNegative := x_pos < 0 yIsNegative := y_pos < 0 x_sign := 0 y_sign := 0 if xIsNegative { x_pos = -x_pos x_sign = 1 } if yIsNegative { y_pos = -y_pos y_sign = 1 } //The max value for x_pos and y_pos are 0xFE, make sure they are within the range if x_pos > 0xFE { x_pos = 0xFE } if y_pos > 0xFE { y_pos = 0xFE } data = append(data, byte(x_pos), byte(y_pos), byte(x_sign), byte(y_sign)) return data, nil } //Entry function for converting a HIDCommand to bytes that can be sent over the USBKVM device func ConvHIDCommandToBytes(cmd HIDCommand) ([]byte, error) { // Convert the HID command to bytes var data []byte if cmd.EventType == FRONTEND_OPR_TYPE_KEYBOARD_WRITE { data = []byte{OPR_TYPE_KEYBOARD_WRITE} return appendKeyboardEventSubtypes(data, cmd) } else if cmd.EventType == FRONTEND_OPR_TYPE_MOUSE_WRITE { /* Mouse Write Event */ data = []byte{OPR_TYPE_MOUSE_WRITE} } else if cmd.EventType == FRONTEND_OPR_TYPE_MOUSE_MOVE { /* Mouse Move Event */ data = []byte{OPR_TYPE_MOUSE_MOVE} return appendMouseMoveEventSubtypes(data, cmd) } else if cmd.EventType == FRONTEND_OPR_TYPE_MOUSE_SCROLL { /* Mouse Scroll Event */ data = []byte{OPR_TYPE_MOUSE_SCROLL} } else { return nil, fmt.Errorf("invalid HID command type: %s", cmd.EventType) } return data, nil }