xref: /openbmc/obmc-ikvm/ikvm_input.hpp (revision fe685fb4)
1 #pragma once
2 
3 #include <rfb/rfb.h>
4 
5 #include <filesystem>
6 #include <fstream>
7 #include <map>
8 #include <mutex>
9 #include <string>
10 
11 namespace ikvm
12 {
13 
14 /*
15  * @class Input
16  * @brief Receives events from RFB clients and sends reports to the USB input
17  *        device
18  */
19 class Input
20 {
21   public:
22     /*
23      * @brief Constructs Input object
24      *
25      * @param[in] kbdPath - Path to the USB keyboard device
26      * @param[in] ptrPath - Path to the USB mouse device
27      * @param[in] udc - Name of UDC
28      */
29     Input(const std::string& kbdPath, const std::string& ptrPath,
30           const std::string& udc);
31     ~Input();
32     Input(const Input&) = default;
33     Input& operator=(const Input&) = default;
34     Input(Input&&) = default;
35     Input& operator=(Input&&) = default;
36 
37     /* @brief Connects HID gadget to host */
38     void connect();
39     /* @brief Disconnects HID gadget from host */
40     void disconnect();
41     /*
42      * @brief RFB client key event handler
43      *
44      * @param[in] down - Boolean indicating whether key is pressed or not
45      * @param[in] key  - Key code
46      * @param[in] cl   - Handle to the RFB client
47      */
48     static void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl);
49     /*
50      * @brief RFB client pointer event handler
51      *
52      * @param[in] buttonMask - Bitmask indicating which buttons have been
53      *                         pressed
54      * @param[in] x          - Pointer x-coordinate
55      * @param[in] y          - Pointer y-coordinate
56      * @param[in] cl         - Handle to the RFB client
57      */
58     static void pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl);
59 
60     /* @brief Sends a wakeup data packet to the USB input device */
61     void sendWakeupPacket();
62 
63   private:
64     static constexpr int NUM_MODIFIER_BITS = 4;
65     static constexpr int KEY_REPORT_LENGTH = 8;
66     static constexpr int PTR_REPORT_LENGTH = 6;
67 
68     /* @brief HID modifier bits mapped to shift and control key codes */
69     static constexpr uint8_t shiftCtrlMap[NUM_MODIFIER_BITS] = {
70         0x02, // left shift
71         0x20, // right shift
72         0x01, // left control
73         0x10  // right control
74     };
75     /* @brief HID modifier bits mapped to meta and alt key codes */
76     static constexpr uint8_t metaAltMap[NUM_MODIFIER_BITS] = {
77         0x08, // left meta
78         0x80, // right meta
79         0x04, // left alt
80         0x40  // right alt
81     };
82     /* @brief Path to the HID gadget UDC */
83     static constexpr const char* hidUdcPath =
84         "/sys/kernel/config/usb_gadget/obmc_hid/UDC";
85     /* @brief Path to the USB virtual hub */
86     static constexpr const char* usbVirtualHubPath =
87         "/sys/bus/platform/devices/1e6a0000.usb-vhub";
88     /* @brief Retry limit for writing an HID report */
89     static constexpr int HID_REPORT_RETRY_MAX = 5;
90     /*
91      * @brief Translates a RFB-specific key code to HID modifier bit
92      *
93      * @param[in] key - key code
94      */
95     static uint8_t keyToMod(rfbKeySym key);
96     /*
97      * @brief Translates a RFB-specific key code to HID scancode
98      *
99      * @param[in] key - key code
100      */
101     static uint8_t keyToScancode(rfbKeySym key);
102 
103     bool writeKeyboard(const uint8_t* report);
104     void writePointer(const uint8_t* report);
105 
106     /* @brief File descriptor for the USB keyboard device */
107     int keyboardFd;
108     /* @brief File descriptor for the USB mouse device */
109     int pointerFd;
110     /* @brief Data for keyboard report */
111     uint8_t keyboardReport[KEY_REPORT_LENGTH];
112     /* @brief Data for pointer report */
113     uint8_t pointerReport[PTR_REPORT_LENGTH];
114     /* @brief Path to the USB keyboard device */
115     std::string keyboardPath;
116     /* @brief Path to the USB mouse device */
117     std::string pointerPath;
118     /* @brief Name of UDC */
119     std::string udcName;
120     /*
121      * @brief Mapping of RFB key code to report data index to keep track
122      *        of which keys are down
123      */
124     std::map<int, int> keysDown;
125     /* @brief Handle of the HID gadget UDC */
126     std::ofstream hidUdcStream;
127     /* @brief Mutex for sending keyboard reports */
128     std::mutex keyMutex;
129     /* @brief Mutex for sending pointer reports */
130     std::mutex ptrMutex;
131 };
132 
133 } // namespace ikvm
134