blob: aae7cefbef6e4ddb5b44446e4dfa868799c431c4 [file] [log] [blame]
Eddie James21b177e2018-12-11 13:14:46 -06001#pragma once
2
3#include <rfb/rfb.h>
4
Jae Hyun Yooc11257d2020-07-22 23:39:18 -07005#include <filesystem>
6#include <fstream>
Eddie James21b177e2018-12-11 13:14:46 -06007#include <map>
8#include <string>
9
10namespace ikvm
11{
12
13/*
14 * @class Input
15 * @brief Receives events from RFB clients and sends reports to the USB input
16 * device
17 */
18class Input
19{
20 public:
21 /*
22 * @brief Constructs Input object
23 *
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080024 * @param[in] kbdPath - Path to the USB keyboard device
25 * @param[in] ptrPath - Path to the USB mouse device
Eddie James21b177e2018-12-11 13:14:46 -060026 */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080027 Input(const std::string& kbdPath, const std::string& ptrPath);
Eddie James21b177e2018-12-11 13:14:46 -060028 ~Input();
29 Input(const Input&) = default;
30 Input& operator=(const Input&) = default;
31 Input(Input&&) = default;
32 Input& operator=(Input&&) = default;
33
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070034 /* @brief Connects HID gadget to host */
35 void connect();
36 /* @brief Disconnects HID gadget from host */
37 void disconnect();
Eddie James21b177e2018-12-11 13:14:46 -060038 /*
39 * @brief RFB client key event handler
40 *
41 * @param[in] down - Boolean indicating whether key is pressed or not
42 * @param[in] key - Key code
43 * @param[in] cl - Handle to the RFB client
44 */
45 static void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl);
46 /*
47 * @brief RFB client pointer event handler
48 *
49 * @param[in] buttonMask - Bitmask indicating which buttons have been
50 * pressed
51 * @param[in] x - Pointer x-coordinate
52 * @param[in] y - Pointer y-coordinate
53 * @param[in] cl - Handle to the RFB client
54 */
55 static void pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl);
56
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080057 /* @brief Sends a wakeup data packet to the USB input device */
58 void sendWakeupPacket();
Eddie James21b177e2018-12-11 13:14:46 -060059 /* @brief Sends an HID report to the USB input device */
60 void sendReport();
61
62 private:
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080063 static constexpr int NUM_MODIFIER_BITS = 4;
64 static constexpr int KEY_REPORT_LENGTH = 8;
65 static constexpr int PTR_REPORT_LENGTH = 5;
Eddie James21b177e2018-12-11 13:14:46 -060066
Eddie James21b177e2018-12-11 13:14:46 -060067 /* @brief HID modifier bits mapped to shift and control key codes */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080068 static constexpr uint8_t shiftCtrlMap[NUM_MODIFIER_BITS] = {
69 0x02, // left shift
70 0x20, // right shift
71 0x01, // left control
72 0x10 // right control
73 };
Eddie James21b177e2018-12-11 13:14:46 -060074 /* @brief HID modifier bits mapped to meta and alt key codes */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080075 static constexpr uint8_t metaAltMap[NUM_MODIFIER_BITS] = {
76 0x08, // left meta
77 0x80, // right meta
78 0x04, // left alt
79 0x40 // right alt
80 };
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070081 /* @brief Path to the HID gadget UDC */
82 static constexpr const char* hidUdcPath =
83 "/sys/kernel/config/usb_gadget/obmc_hid/UDC";
84 /* @brief Path to the USB virtual hub */
85 static constexpr const char* usbVirtualHubPath =
86 "/sys/bus/platform/devices/1e6a0000.usb-vhub";
Eddie James21b177e2018-12-11 13:14:46 -060087 /*
88 * @brief Translates a RFB-specific key code to HID modifier bit
89 *
90 * @param[in] key - key code
91 */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080092 static uint8_t keyToMod(rfbKeySym key);
Eddie James21b177e2018-12-11 13:14:46 -060093 /*
94 * @brief Translates a RFB-specific key code to HID scancode
95 *
96 * @param[in] key - key code
97 */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080098 static uint8_t keyToScancode(rfbKeySym key);
Eddie James21b177e2018-12-11 13:14:46 -060099
Eddie James7cf1f1d2019-09-30 15:05:16 -0500100 bool writeKeyboard(const uint8_t *report);
101 void writePointer(const uint8_t *report);
102
Eddie James21b177e2018-12-11 13:14:46 -0600103 /* @brief Indicates whether or not to send a keyboard report */
104 bool sendKeyboard;
105 /* @brief Indicates whether or not to send a pointer report */
106 bool sendPointer;
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800107 /* @brief File descriptor for the USB keyboard device */
108 int keyboardFd;
109 /* @brief File descriptor for the USB mouse device */
110 int pointerFd;
Eddie James21b177e2018-12-11 13:14:46 -0600111 /* @brief Data for keyboard report */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800112 uint8_t keyboardReport[KEY_REPORT_LENGTH];
Eddie James21b177e2018-12-11 13:14:46 -0600113 /* @brief Data for pointer report */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800114 uint8_t pointerReport[PTR_REPORT_LENGTH];
115 /* @brief Path to the USB keyboard device */
116 std::string keyboardPath;
117 /* @brief Path to the USB mouse device */
118 std::string pointerPath;
Eddie James21b177e2018-12-11 13:14:46 -0600119 /*
120 * @brief Mapping of RFB key code to report data index to keep track
121 * of which keys are down
122 */
123 std::map<int, int> keysDown;
Jae Hyun Yooc11257d2020-07-22 23:39:18 -0700124 /* @brief Handle of the HID gadget UDC */
125 std::ofstream hidUdcStream;
Eddie James21b177e2018-12-11 13:14:46 -0600126};
127
128} // namespace ikvm