121b177e0SEddie James #pragma once 221b177e0SEddie James 321b177e0SEddie James #include <rfb/rfb.h> 421b177e0SEddie James 5*c11257d8SJae Hyun Yoo #include <filesystem> 6*c11257d8SJae Hyun Yoo #include <fstream> 721b177e0SEddie James #include <map> 821b177e0SEddie James #include <string> 921b177e0SEddie James 1021b177e0SEddie James namespace ikvm 1121b177e0SEddie James { 1221b177e0SEddie James 1321b177e0SEddie James /* 1421b177e0SEddie James * @class Input 1521b177e0SEddie James * @brief Receives events from RFB clients and sends reports to the USB input 1621b177e0SEddie James * device 1721b177e0SEddie James */ 1821b177e0SEddie James class Input 1921b177e0SEddie James { 2021b177e0SEddie James public: 2121b177e0SEddie James /* 2221b177e0SEddie James * @brief Constructs Input object 2321b177e0SEddie James * 247dfac9ffSJae Hyun Yoo * @param[in] kbdPath - Path to the USB keyboard device 257dfac9ffSJae Hyun Yoo * @param[in] ptrPath - Path to the USB mouse device 2621b177e0SEddie James */ 277dfac9ffSJae Hyun Yoo Input(const std::string& kbdPath, const std::string& ptrPath); 2821b177e0SEddie James ~Input(); 2921b177e0SEddie James Input(const Input&) = default; 3021b177e0SEddie James Input& operator=(const Input&) = default; 3121b177e0SEddie James Input(Input&&) = default; 3221b177e0SEddie James Input& operator=(Input&&) = default; 3321b177e0SEddie James 34*c11257d8SJae Hyun Yoo /* @brief Connects HID gadget to host */ 35*c11257d8SJae Hyun Yoo void connect(); 36*c11257d8SJae Hyun Yoo /* @brief Disconnects HID gadget from host */ 37*c11257d8SJae Hyun Yoo void disconnect(); 3821b177e0SEddie James /* 3921b177e0SEddie James * @brief RFB client key event handler 4021b177e0SEddie James * 4121b177e0SEddie James * @param[in] down - Boolean indicating whether key is pressed or not 4221b177e0SEddie James * @param[in] key - Key code 4321b177e0SEddie James * @param[in] cl - Handle to the RFB client 4421b177e0SEddie James */ 4521b177e0SEddie James static void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl); 4621b177e0SEddie James /* 4721b177e0SEddie James * @brief RFB client pointer event handler 4821b177e0SEddie James * 4921b177e0SEddie James * @param[in] buttonMask - Bitmask indicating which buttons have been 5021b177e0SEddie James * pressed 5121b177e0SEddie James * @param[in] x - Pointer x-coordinate 5221b177e0SEddie James * @param[in] y - Pointer y-coordinate 5321b177e0SEddie James * @param[in] cl - Handle to the RFB client 5421b177e0SEddie James */ 5521b177e0SEddie James static void pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl); 5621b177e0SEddie James 577dfac9ffSJae Hyun Yoo /* @brief Sends a wakeup data packet to the USB input device */ 587dfac9ffSJae Hyun Yoo void sendWakeupPacket(); 5921b177e0SEddie James /* @brief Sends an HID report to the USB input device */ 6021b177e0SEddie James void sendReport(); 6121b177e0SEddie James 6221b177e0SEddie James private: 637dfac9ffSJae Hyun Yoo static constexpr int NUM_MODIFIER_BITS = 4; 647dfac9ffSJae Hyun Yoo static constexpr int KEY_REPORT_LENGTH = 8; 657dfac9ffSJae Hyun Yoo static constexpr int PTR_REPORT_LENGTH = 5; 6621b177e0SEddie James 6721b177e0SEddie James /* @brief HID modifier bits mapped to shift and control key codes */ 687dfac9ffSJae Hyun Yoo static constexpr uint8_t shiftCtrlMap[NUM_MODIFIER_BITS] = { 697dfac9ffSJae Hyun Yoo 0x02, // left shift 707dfac9ffSJae Hyun Yoo 0x20, // right shift 717dfac9ffSJae Hyun Yoo 0x01, // left control 727dfac9ffSJae Hyun Yoo 0x10 // right control 737dfac9ffSJae Hyun Yoo }; 7421b177e0SEddie James /* @brief HID modifier bits mapped to meta and alt key codes */ 757dfac9ffSJae Hyun Yoo static constexpr uint8_t metaAltMap[NUM_MODIFIER_BITS] = { 767dfac9ffSJae Hyun Yoo 0x08, // left meta 777dfac9ffSJae Hyun Yoo 0x80, // right meta 787dfac9ffSJae Hyun Yoo 0x04, // left alt 797dfac9ffSJae Hyun Yoo 0x40 // right alt 807dfac9ffSJae Hyun Yoo }; 81*c11257d8SJae Hyun Yoo /* @brief Path to the HID gadget UDC */ 82*c11257d8SJae Hyun Yoo static constexpr const char* hidUdcPath = 83*c11257d8SJae Hyun Yoo "/sys/kernel/config/usb_gadget/obmc_hid/UDC"; 84*c11257d8SJae Hyun Yoo /* @brief Path to the USB virtual hub */ 85*c11257d8SJae Hyun Yoo static constexpr const char* usbVirtualHubPath = 86*c11257d8SJae Hyun Yoo "/sys/bus/platform/devices/1e6a0000.usb-vhub"; 8721b177e0SEddie James /* 8821b177e0SEddie James * @brief Translates a RFB-specific key code to HID modifier bit 8921b177e0SEddie James * 9021b177e0SEddie James * @param[in] key - key code 9121b177e0SEddie James */ 927dfac9ffSJae Hyun Yoo static uint8_t keyToMod(rfbKeySym key); 9321b177e0SEddie James /* 9421b177e0SEddie James * @brief Translates a RFB-specific key code to HID scancode 9521b177e0SEddie James * 9621b177e0SEddie James * @param[in] key - key code 9721b177e0SEddie James */ 987dfac9ffSJae Hyun Yoo static uint8_t keyToScancode(rfbKeySym key); 9921b177e0SEddie James 1007cf1f1d4SEddie James bool writeKeyboard(const uint8_t *report); 1017cf1f1d4SEddie James void writePointer(const uint8_t *report); 1027cf1f1d4SEddie James 10321b177e0SEddie James /* @brief Indicates whether or not to send a keyboard report */ 10421b177e0SEddie James bool sendKeyboard; 10521b177e0SEddie James /* @brief Indicates whether or not to send a pointer report */ 10621b177e0SEddie James bool sendPointer; 1077dfac9ffSJae Hyun Yoo /* @brief File descriptor for the USB keyboard device */ 1087dfac9ffSJae Hyun Yoo int keyboardFd; 1097dfac9ffSJae Hyun Yoo /* @brief File descriptor for the USB mouse device */ 1107dfac9ffSJae Hyun Yoo int pointerFd; 11121b177e0SEddie James /* @brief Data for keyboard report */ 1127dfac9ffSJae Hyun Yoo uint8_t keyboardReport[KEY_REPORT_LENGTH]; 11321b177e0SEddie James /* @brief Data for pointer report */ 1147dfac9ffSJae Hyun Yoo uint8_t pointerReport[PTR_REPORT_LENGTH]; 1157dfac9ffSJae Hyun Yoo /* @brief Path to the USB keyboard device */ 1167dfac9ffSJae Hyun Yoo std::string keyboardPath; 1177dfac9ffSJae Hyun Yoo /* @brief Path to the USB mouse device */ 1187dfac9ffSJae Hyun Yoo std::string pointerPath; 11921b177e0SEddie James /* 12021b177e0SEddie James * @brief Mapping of RFB key code to report data index to keep track 12121b177e0SEddie James * of which keys are down 12221b177e0SEddie James */ 12321b177e0SEddie James std::map<int, int> keysDown; 124*c11257d8SJae Hyun Yoo /* @brief Handle of the HID gadget UDC */ 125*c11257d8SJae Hyun Yoo std::ofstream hidUdcStream; 12621b177e0SEddie James }; 12721b177e0SEddie James 12821b177e0SEddie James } // namespace ikvm 129