xref: /openbmc/obmc-ikvm/ikvm_input.hpp (revision fe685fb4)
121b177e0SEddie James #pragma once
221b177e0SEddie James 
321b177e0SEddie James #include <rfb/rfb.h>
421b177e0SEddie James 
5c11257d8SJae Hyun Yoo #include <filesystem>
6c11257d8SJae Hyun Yoo #include <fstream>
721b177e0SEddie James #include <map>
8673ac2ebSJae Hyun Yoo #include <mutex>
921b177e0SEddie James #include <string>
1021b177e0SEddie James 
1121b177e0SEddie James namespace ikvm
1221b177e0SEddie James {
1321b177e0SEddie James 
1421b177e0SEddie James /*
1521b177e0SEddie James  * @class Input
1621b177e0SEddie James  * @brief Receives events from RFB clients and sends reports to the USB input
1721b177e0SEddie James  *        device
1821b177e0SEddie James  */
1921b177e0SEddie James class Input
2021b177e0SEddie James {
2121b177e0SEddie James   public:
2221b177e0SEddie James     /*
2321b177e0SEddie James      * @brief Constructs Input object
2421b177e0SEddie James      *
257dfac9ffSJae Hyun Yoo      * @param[in] kbdPath - Path to the USB keyboard device
267dfac9ffSJae Hyun Yoo      * @param[in] ptrPath - Path to the USB mouse device
27*fe685fb4SMarvin Lin      * @param[in] udc - Name of UDC
2821b177e0SEddie James      */
29*fe685fb4SMarvin Lin     Input(const std::string& kbdPath, const std::string& ptrPath,
30*fe685fb4SMarvin Lin           const std::string& udc);
3121b177e0SEddie James     ~Input();
3221b177e0SEddie James     Input(const Input&) = default;
3321b177e0SEddie James     Input& operator=(const Input&) = default;
3421b177e0SEddie James     Input(Input&&) = default;
3521b177e0SEddie James     Input& operator=(Input&&) = default;
3621b177e0SEddie James 
37c11257d8SJae Hyun Yoo     /* @brief Connects HID gadget to host */
38c11257d8SJae Hyun Yoo     void connect();
39c11257d8SJae Hyun Yoo     /* @brief Disconnects HID gadget from host */
40c11257d8SJae Hyun Yoo     void disconnect();
4121b177e0SEddie James     /*
4221b177e0SEddie James      * @brief RFB client key event handler
4321b177e0SEddie James      *
4421b177e0SEddie James      * @param[in] down - Boolean indicating whether key is pressed or not
4521b177e0SEddie James      * @param[in] key  - Key code
4621b177e0SEddie James      * @param[in] cl   - Handle to the RFB client
4721b177e0SEddie James      */
4821b177e0SEddie James     static void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl);
4921b177e0SEddie James     /*
5021b177e0SEddie James      * @brief RFB client pointer event handler
5121b177e0SEddie James      *
5221b177e0SEddie James      * @param[in] buttonMask - Bitmask indicating which buttons have been
5321b177e0SEddie James      *                         pressed
5421b177e0SEddie James      * @param[in] x          - Pointer x-coordinate
5521b177e0SEddie James      * @param[in] y          - Pointer y-coordinate
5621b177e0SEddie James      * @param[in] cl         - Handle to the RFB client
5721b177e0SEddie James      */
5821b177e0SEddie James     static void pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl);
5921b177e0SEddie James 
607dfac9ffSJae Hyun Yoo     /* @brief Sends a wakeup data packet to the USB input device */
617dfac9ffSJae Hyun Yoo     void sendWakeupPacket();
6221b177e0SEddie James 
6321b177e0SEddie James   private:
647dfac9ffSJae Hyun Yoo     static constexpr int NUM_MODIFIER_BITS = 4;
657dfac9ffSJae Hyun Yoo     static constexpr int KEY_REPORT_LENGTH = 8;
663fa0bfbaSTejas Patil     static constexpr int PTR_REPORT_LENGTH = 6;
6721b177e0SEddie James 
6821b177e0SEddie James     /* @brief HID modifier bits mapped to shift and control key codes */
697dfac9ffSJae Hyun Yoo     static constexpr uint8_t shiftCtrlMap[NUM_MODIFIER_BITS] = {
707dfac9ffSJae Hyun Yoo         0x02, // left shift
717dfac9ffSJae Hyun Yoo         0x20, // right shift
727dfac9ffSJae Hyun Yoo         0x01, // left control
737dfac9ffSJae Hyun Yoo         0x10  // right control
747dfac9ffSJae Hyun Yoo     };
7521b177e0SEddie James     /* @brief HID modifier bits mapped to meta and alt key codes */
767dfac9ffSJae Hyun Yoo     static constexpr uint8_t metaAltMap[NUM_MODIFIER_BITS] = {
777dfac9ffSJae Hyun Yoo         0x08, // left meta
787dfac9ffSJae Hyun Yoo         0x80, // right meta
797dfac9ffSJae Hyun Yoo         0x04, // left alt
807dfac9ffSJae Hyun Yoo         0x40  // right alt
817dfac9ffSJae Hyun Yoo     };
82c11257d8SJae Hyun Yoo     /* @brief Path to the HID gadget UDC */
83c11257d8SJae Hyun Yoo     static constexpr const char* hidUdcPath =
84c11257d8SJae Hyun Yoo         "/sys/kernel/config/usb_gadget/obmc_hid/UDC";
85c11257d8SJae Hyun Yoo     /* @brief Path to the USB virtual hub */
86c11257d8SJae Hyun Yoo     static constexpr const char* usbVirtualHubPath =
87c11257d8SJae Hyun Yoo         "/sys/bus/platform/devices/1e6a0000.usb-vhub";
88673ac2ebSJae Hyun Yoo     /* @brief Retry limit for writing an HID report */
89673ac2ebSJae Hyun Yoo     static constexpr int HID_REPORT_RETRY_MAX = 5;
9021b177e0SEddie James     /*
9121b177e0SEddie James      * @brief Translates a RFB-specific key code to HID modifier bit
9221b177e0SEddie James      *
9321b177e0SEddie James      * @param[in] key - key code
9421b177e0SEddie James      */
957dfac9ffSJae Hyun Yoo     static uint8_t keyToMod(rfbKeySym key);
9621b177e0SEddie James     /*
9721b177e0SEddie James      * @brief Translates a RFB-specific key code to HID scancode
9821b177e0SEddie James      *
9921b177e0SEddie James      * @param[in] key - key code
10021b177e0SEddie James      */
1017dfac9ffSJae Hyun Yoo     static uint8_t keyToScancode(rfbKeySym key);
10221b177e0SEddie James 
1037cf1f1d4SEddie James     bool writeKeyboard(const uint8_t* report);
1047cf1f1d4SEddie James     void writePointer(const uint8_t* report);
1057cf1f1d4SEddie James 
1067dfac9ffSJae Hyun Yoo     /* @brief File descriptor for the USB keyboard device */
1077dfac9ffSJae Hyun Yoo     int keyboardFd;
1087dfac9ffSJae Hyun Yoo     /* @brief File descriptor for the USB mouse device */
1097dfac9ffSJae Hyun Yoo     int pointerFd;
11021b177e0SEddie James     /* @brief Data for keyboard report */
1117dfac9ffSJae Hyun Yoo     uint8_t keyboardReport[KEY_REPORT_LENGTH];
11221b177e0SEddie James     /* @brief Data for pointer report */
1137dfac9ffSJae Hyun Yoo     uint8_t pointerReport[PTR_REPORT_LENGTH];
1147dfac9ffSJae Hyun Yoo     /* @brief Path to the USB keyboard device */
1157dfac9ffSJae Hyun Yoo     std::string keyboardPath;
1167dfac9ffSJae Hyun Yoo     /* @brief Path to the USB mouse device */
1177dfac9ffSJae Hyun Yoo     std::string pointerPath;
118*fe685fb4SMarvin Lin     /* @brief Name of UDC */
119*fe685fb4SMarvin Lin     std::string udcName;
12021b177e0SEddie James     /*
12121b177e0SEddie James      * @brief Mapping of RFB key code to report data index to keep track
12221b177e0SEddie James      *        of which keys are down
12321b177e0SEddie James      */
12421b177e0SEddie James     std::map<int, int> keysDown;
125c11257d8SJae Hyun Yoo     /* @brief Handle of the HID gadget UDC */
126c11257d8SJae Hyun Yoo     std::ofstream hidUdcStream;
127673ac2ebSJae Hyun Yoo     /* @brief Mutex for sending keyboard reports */
128673ac2ebSJae Hyun Yoo     std::mutex keyMutex;
129673ac2ebSJae Hyun Yoo     /* @brief Mutex for sending pointer reports */
130673ac2ebSJae Hyun Yoo     std::mutex ptrMutex;
13121b177e0SEddie James };
13221b177e0SEddie James 
13321b177e0SEddie James } // namespace ikvm
134