vncserver.hh revision 11168
12SN/A/* 21762SN/A * Copyright (c) 2010, 2015 ARM Limited 32SN/A * All rights reserved 42SN/A * 52SN/A * The license below extends only to copyright in the software and shall 62SN/A * not be construed as granting a license to any other intellectual 72SN/A * property including but not limited to intellectual property relating 82SN/A * to a hardware implementation of the functionality of the software 92SN/A * licensed hereunder. You may use the software subject to the license 102SN/A * terms below provided that you ensure that this notice is replicated 112SN/A * unmodified and in its entirety in all distributions of the software, 122SN/A * modified or unmodified, in source code or in binary form. 132SN/A * 142SN/A * Redistribution and use in source and binary forms, with or without 152SN/A * modification, are permitted provided that the following conditions are 162SN/A * met: redistributions of source code must retain the above copyright 172SN/A * notice, this list of conditions and the following disclaimer; 182SN/A * redistributions in binary form must reproduce the above copyright 192SN/A * notice, this list of conditions and the following disclaimer in the 202SN/A * documentation and/or other materials provided with the distribution; 212SN/A * neither the name of the copyright holders nor the names of its 222SN/A * contributors may be used to endorse or promote products derived from 232SN/A * this software without specific prior written permission. 242SN/A * 252SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312439SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 322984Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33146SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34146SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35146SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36146SN/A * 37146SN/A * Authors: Ali Saidi 38146SN/A * William Wang 391717SN/A */ 40146SN/A 411717SN/A/** @file 42146SN/A * Declaration of a VNC server 431977SN/A */ 442623SN/A 452683Sktlim@umich.edu#ifndef __BASE_VNC_VNC_SERVER_HH__ 461717SN/A#define __BASE_VNC_VNC_SERVER_HH__ 47146SN/A 482683Sktlim@umich.edu#include <iostream> 491917SN/A 503348Sbinkertn@umich.edu#include "base/vnc/vncinput.hh" 512683Sktlim@umich.edu#include "base/bitmap.hh" 522036SN/A#include "base/circlebuf.hh" 53146SN/A#include "base/pollevent.hh" 5456SN/A#include "base/socket.hh" 5556SN/A#include "params/VncServer.hh" 5656SN/A#include "sim/sim_object.hh" 57695SN/A 582901Ssaidi@eecs.umich.edu/** @file 592SN/A * Declaration of a VNC server 601858SN/A */ 6156SN/A 622171SN/Aclass VncServer : public VncInput 632170SN/A{ 642170SN/A public: 65146SN/A 662462SN/A /** 67146SN/A * \defgroup VncConstants A set of constants and structs from the VNC spec 682SN/A * @{ 692SN/A */ 702449SN/A /** Authentication modes */ 711355SN/A const static uint32_t AuthInvalid = 0; 722623SN/A const static uint32_t AuthNone = 1; 733402Sktlim@umich.edu 74224SN/A /** Error conditions */ 751858SN/A const static uint32_t VncOK = 0; 762683Sktlim@umich.edu 772420SN/A /** Server -> Client message IDs */ 782683Sktlim@umich.edu enum ServerMessages { 793402Sktlim@umich.edu ServerFrameBufferUpdate = 0, 802420SN/A ServerSetColorMapEntries = 1, 812SN/A ServerBell = 2, 822683Sktlim@umich.edu ServerCutText = 3 832672Sktlim@umich.edu }; 842683Sktlim@umich.edu 852SN/A /** Encoding types */ 862SN/A enum EncodingTypes { 87334SN/A EncodingRaw = 0, 88140SN/A EncodingCopyRect = 1, 89334SN/A EncodingHextile = 5, 902SN/A EncodingDesktopSize = -223 912SN/A }; 922SN/A 932680Sktlim@umich.edu /** keyboard/mouse support */ 942SN/A enum MouseEvents { 952SN/A MouseLeftButton = 0x1, 962623SN/A MouseRightButton = 0x2, 972SN/A MouseMiddleButton = 0x4 982SN/A }; 992SN/A 100180SN/A const char* vncVersion() const 1012623SN/A { 102393SN/A return "RFB 003.008\n"; 103393SN/A } 104393SN/A 105393SN/A enum ConnectionState { 106384SN/A WaitForProtocolVersion, 107384SN/A WaitForSecurityResponse, 108393SN/A WaitForClientInit, 1092623SN/A InitializationPhase, 110393SN/A NormalPhase 111393SN/A }; 112393SN/A 113393SN/A struct ServerInitMsg { 114384SN/A uint16_t fbWidth; 115189SN/A uint16_t fbHeight; 116189SN/A PixelFormat px; 1172623SN/A uint32_t namelen; 1182SN/A char name[2]; // just to put M5 in here 119729SN/A } M5_ATTR_PACKED; 120334SN/A 1212SN/A struct FrameBufferUpdate { 1222SN/A uint8_t type; 1232SN/A uint8_t padding; 1242SN/A uint16_t num_rects; 1252SN/A } M5_ATTR_PACKED; 1262SN/A 1272SN/A struct FrameBufferRect { 1282SN/A uint16_t x; 1292SN/A uint16_t y; 1302SN/A uint16_t width; 1312SN/A uint16_t height; 1322SN/A int32_t encoding; 1331001SN/A } M5_ATTR_PACKED; 1341001SN/A 1351001SN/A struct ServerCutText { 1361001SN/A uint8_t type; 1371001SN/A uint8_t padding[3]; 1382SN/A uint32_t length; 1392SN/A } M5_ATTR_PACKED; 1402SN/A 1412SN/A /** @} */ 1422SN/A 1432SN/A protected: 1442SN/A /** ListenEvent to accept a vnc client connection */ 1452SN/A class ListenEvent: public PollEvent 1462SN/A { 1472SN/A protected: 1482SN/A VncServer *vncserver; 1492SN/A 1502SN/A public: 1512SN/A ListenEvent(VncServer *vs, int fd, int e); 1522SN/A void process(int revent); 1532SN/A }; 1542SN/A 1552390SN/A friend class ListenEvent; 1562390SN/A ListenEvent *listenEvent; 1572390SN/A 1582390SN/A /** DataEvent to read data from vnc */ 1592390SN/A class DataEvent: public PollEvent 1602390SN/A { 1612390SN/A protected: 1622390SN/A VncServer *vncserver; 1632390SN/A 1642390SN/A public: 1652390SN/A DataEvent(VncServer *vs, int fd, int e); 1662390SN/A void process(int revent); 167385SN/A }; 1682SN/A 1692SN/A friend class DataEvent; 1702SN/A DataEvent *dataEvent; 1712623SN/A 172334SN/A int number; 1732361SN/A int dataFd; // data stream file describer 1742623SN/A 175334SN/A ListenSocket listener; 176334SN/A 177334SN/A void listen(int port); 1782623SN/A void accept(); 1792SN/A void data(); 180921SN/A void detach(); 1812915Sktlim@umich.edu 1822915Sktlim@umich.edu public: 1832683Sktlim@umich.edu typedef VncServerParams Params; 1842SN/A VncServer(const Params *p); 1852SN/A ~VncServer(); 1862SN/A 1872623SN/A // RFB 1882SN/A protected: 189921SN/A 1902915Sktlim@umich.edu /** The rfb prototol state the connection is in */ 1912915Sktlim@umich.edu ConnectionState curState; 1922SN/A 1932SN/A /** An update needs to be sent to the client. Without doing this the 1942SN/A * client will constantly request data that is pointless */ 1952SN/A bool sendUpdate; 1962SN/A 1972SN/A /** The one and only pixel format we support */ 1982SN/A PixelFormat pixelFormat; 199595SN/A 2002623SN/A /** If the vnc client supports receiving raw data. It always should */ 201595SN/A bool supportsRawEnc; 2022390SN/A 2031080SN/A /** If the vnc client supports the desktop resize command */ 2041080SN/A bool supportsResizeEnc; 2051080SN/A 2061080SN/A protected: 2071080SN/A /** 2081080SN/A * vnc client Interface 2091080SN/A */ 2101121SN/A 2112107SN/A /** Send an error message to the client 2121089SN/A * @param error_msg text to send describing the error 2131089SN/A */ 2141080SN/A void sendError(const char* error_msg); 2151080SN/A 2161080SN/A /** Read some data from the client 2171080SN/A * @param buf the data to read 218595SN/A * @param len the amount of data to read 2192623SN/A * @return length read 2202683Sktlim@umich.edu */ 221595SN/A size_t read(uint8_t *buf, size_t len); 2222090SN/A 2232683Sktlim@umich.edu /** Read len -1 bytes from the client into the buffer provided + 1 2242683Sktlim@umich.edu * assert that we read enough bytes. This function exists to handle 225595SN/A * reading all of the protocol structs above when we've already read 2262205SN/A * the first byte which describes which one we're reading 2272205SN/A * @param buf the address of the buffer to add one to and read data into 2282683Sktlim@umich.edu * @param len the amount of data + 1 to read 2292683Sktlim@umich.edu * @return length read 230595SN/A */ 231595SN/A size_t read1(uint8_t *buf, size_t len); 2322390SN/A 2332423SN/A 2342390SN/A /** Templated version of the read function above to 235595SN/A * read simple data to the client 236595SN/A * @param val data to recv from the client 237595SN/A */ 2382623SN/A template <typename T> size_t read(T* val); 239595SN/A 2402390SN/A 2411080SN/A /** Write a buffer to the client. 242595SN/A * @param buf buffer to send 2431080SN/A * @param len length of the buffer 2441080SN/A * @return number of bytes sent 245595SN/A */ 2462683Sktlim@umich.edu size_t write(const uint8_t *buf, size_t len); 2471080SN/A 2481080SN/A /** Templated version of the write function above to 2491080SN/A * write simple data to the client 2501121SN/A * @param val data to send to the client 2512107SN/A */ 2521089SN/A template <typename T> size_t write(T* val); 2531080SN/A 2541089SN/A /** Send a string to the client 2551080SN/A * @param str string to transmit 2561080SN/A */ 2571080SN/A size_t write(const char* str); 258595SN/A 2592683Sktlim@umich.edu /** Check the client's protocol verion for compatibility and send 2601080SN/A * the security types we support 2612090SN/A */ 2621080SN/A void checkProtocolVersion(); 263595SN/A 2642683Sktlim@umich.edu /** Check that the security exchange was successful 2652683Sktlim@umich.edu */ 266595SN/A void checkSecurity(); 2672683Sktlim@umich.edu 2681098SN/A /** Send client our idea about what the frame buffer looks like */ 2691098SN/A void sendServerInit(); 2701098SN/A 2712683Sktlim@umich.edu /** Send an error message to the client when something goes wrong 2721098SN/A * @param error_msg error to send 2731098SN/A */ 2741098SN/A void sendError(std::string error_msg); 2752012SN/A 2761098SN/A /** Send a updated frame buffer to the client. 2771098SN/A * @todo this doesn't do anything smart and just sends the entire image 278595SN/A */ 2792205SN/A void sendFrameBufferUpdate(); 2802205SN/A 2812205SN/A /** Receive pixel foramt message from client and process it. */ 282595SN/A void setPixelFormat(); 2832390SN/A 2842420SN/A /** Receive encodings message from client and process it. */ 2852423SN/A void setEncodings(); 2862390SN/A 287595SN/A /** Receive message from client asking for updated frame buffer */ 288595SN/A void requestFbUpdate(); 2891858SN/A 2902SN/A /** Receive message from client providing new keyboard input */ 2912623SN/A void recvKeyboardInput(); 2922SN/A 2932680Sktlim@umich.edu /** Recv message from client providing new mouse movement or button click */ 2942SN/A void recvPointerInput(); 2952SN/A 2962SN/A /** Receive message from client that there is text in it's paste buffer. 2971858SN/A * This is a no-op at the moment, but perhaps we would want to be able to 2982SN/A * paste it at some point. 2992623SN/A */ 3002SN/A void recvCutText(); 3012SN/A 3022SN/A /** Tell the client that the frame buffer resized. This happens when the 3032683Sktlim@umich.edu * simulated system changes video modes (E.g. X11 starts). 3042SN/A */ 3052683Sktlim@umich.edu void sendFrameBufferResized(); 3062SN/A 3072SN/A static const PixelConverter pixelConverter; 3082SN/A 3092SN/A public: 3102SN/A void setDirty() override; 3112623SN/A void frameBufferResized() override; 3122SN/A}; 3131858SN/A 3142683Sktlim@umich.edu#endif 3151133SN/A