vncserver.hh revision 10839
1/* 2 * Copyright (c) 2010, 2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Ali Saidi 38 * William Wang 39 */ 40 41/** @file 42 * Declaration of a VNC server 43 */ 44 45#ifndef __BASE_VNC_VNC_SERVER_HH__ 46#define __BASE_VNC_VNC_SERVER_HH__ 47 48#include <iostream> 49 50#include "base/vnc/vncinput.hh" 51#include "base/bitmap.hh" 52#include "base/circlebuf.hh" 53#include "base/pollevent.hh" 54#include "base/socket.hh" 55#include "params/VncServer.hh" 56#include "sim/sim_object.hh" 57 58/** @file 59 * Declaration of a VNC server 60 */ 61 62class VncServer : public VncInput 63{ 64 public: 65 66 /** 67 * \defgroup VncConstants A set of constants and structs from the VNC spec 68 * @{ 69 */ 70 /** Authentication modes */ 71 const static uint32_t AuthInvalid = 0; 72 const static uint32_t AuthNone = 1; 73 74 /** Error conditions */ 75 const static uint32_t VncOK = 0; 76 77 /** Server -> Client message IDs */ 78 enum ServerMessages { 79 ServerFrameBufferUpdate = 0, 80 ServerSetColorMapEntries = 1, 81 ServerBell = 2, 82 ServerCutText = 3 83 }; 84 85 /** Encoding types */ 86 enum EncodingTypes { 87 EncodingRaw = 0, 88 EncodingCopyRect = 1, 89 EncodingHextile = 5, 90 EncodingDesktopSize = -223 91 }; 92 93 /** keyboard/mouse support */ 94 enum MouseEvents { 95 MouseLeftButton = 0x1, 96 MouseRightButton = 0x2, 97 MouseMiddleButton = 0x4 98 }; 99 100 const char* vncVersion() const 101 { 102 return "RFB 003.008\n"; 103 } 104 105 enum ConnectionState { 106 WaitForProtocolVersion, 107 WaitForSecurityResponse, 108 WaitForClientInit, 109 InitializationPhase, 110 NormalPhase 111 }; 112 113 struct ServerInitMsg { 114 uint16_t fbWidth; 115 uint16_t fbHeight; 116 PixelFormat px; 117 uint32_t namelen; 118 char name[2]; // just to put M5 in here 119 } M5_ATTR_PACKED; 120 121 struct FrameBufferUpdate { 122 uint8_t type; 123 uint8_t padding; 124 uint16_t num_rects; 125 } M5_ATTR_PACKED; 126 127 struct FrameBufferRect { 128 uint16_t x; 129 uint16_t y; 130 uint16_t width; 131 uint16_t height; 132 int32_t encoding; 133 } M5_ATTR_PACKED; 134 135 struct ServerCutText { 136 uint8_t type; 137 uint8_t padding[3]; 138 uint32_t length; 139 } M5_ATTR_PACKED; 140 141 /** @} */ 142 143 protected: 144 /** ListenEvent to accept a vnc client connection */ 145 class ListenEvent: public PollEvent 146 { 147 protected: 148 VncServer *vncserver; 149 150 public: 151 ListenEvent(VncServer *vs, int fd, int e); 152 void process(int revent); 153 }; 154 155 friend class ListenEvent; 156 ListenEvent *listenEvent; 157 158 /** DataEvent to read data from vnc */ 159 class DataEvent: public PollEvent 160 { 161 protected: 162 VncServer *vncserver; 163 164 public: 165 DataEvent(VncServer *vs, int fd, int e); 166 void process(int revent); 167 }; 168 169 friend class DataEvent; 170 DataEvent *dataEvent; 171 172 int number; 173 int dataFd; // data stream file describer 174 175 ListenSocket listener; 176 177 void listen(int port); 178 void accept(); 179 void data(); 180 void detach(); 181 182 public: 183 typedef VncServerParams Params; 184 VncServer(const Params *p); 185 ~VncServer(); 186 187 // RFB 188 protected: 189 190 /** The rfb prototol state the connection is in */ 191 ConnectionState curState; 192 193 /** An update needs to be sent to the client. Without doing this the 194 * client will constantly request data that is pointless */ 195 bool sendUpdate; 196 197 /** The one and only pixel format we support */ 198 PixelFormat pixelFormat; 199 200 /** If the vnc client supports receiving raw data. It always should */ 201 bool supportsRawEnc; 202 203 /** If the vnc client supports the desktop resize command */ 204 bool supportsResizeEnc; 205 206 protected: 207 /** 208 * vnc client Interface 209 */ 210 211 /** Send an error message to the client 212 * @param error_msg text to send describing the error 213 */ 214 void sendError(const char* error_msg); 215 216 /** Read some data from the client 217 * @param buf the data to read 218 * @param len the amount of data to read 219 * @return length read 220 */ 221 size_t read(uint8_t *buf, size_t len); 222 223 /** Read len -1 bytes from the client into the buffer provided + 1 224 * assert that we read enough bytes. This function exists to handle 225 * reading all of the protocol structs above when we've already read 226 * the first byte which describes which one we're reading 227 * @param buf the address of the buffer to add one to and read data into 228 * @param len the amount of data + 1 to read 229 * @return length read 230 */ 231 size_t read1(uint8_t *buf, size_t len); 232 233 234 /** Templated version of the read function above to 235 * read simple data to the client 236 * @param val data to recv from the client 237 */ 238 template <typename T> size_t read(T* val); 239 240 241 /** Write a buffer to the client. 242 * @param buf buffer to send 243 * @param len length of the buffer 244 * @return number of bytes sent 245 */ 246 size_t write(const uint8_t *buf, size_t len); 247 248 /** Templated version of the write function above to 249 * write simple data to the client 250 * @param val data to send to the client 251 */ 252 template <typename T> size_t write(T* val); 253 254 /** Send a string to the client 255 * @param str string to transmit 256 */ 257 size_t write(const char* str); 258 259 /** Check the client's protocol verion for compatibility and send 260 * the security types we support 261 */ 262 void checkProtocolVersion(); 263 264 /** Check that the security exchange was successful 265 */ 266 void checkSecurity(); 267 268 /** Send client our idea about what the frame buffer looks like */ 269 void sendServerInit(); 270 271 /** Send an error message to the client when something goes wrong 272 * @param error_msg error to send 273 */ 274 void sendError(std::string error_msg); 275 276 /** Send a updated frame buffer to the client. 277 * @todo this doesn't do anything smart and just sends the entire image 278 */ 279 void sendFrameBufferUpdate(); 280 281 /** Receive pixel foramt message from client and process it. */ 282 void setPixelFormat(); 283 284 /** Receive encodings message from client and process it. */ 285 void setEncodings(); 286 287 /** Receive message from client asking for updated frame buffer */ 288 void requestFbUpdate(); 289 290 /** Receive message from client providing new keyboard input */ 291 void recvKeyboardInput(); 292 293 /** Recv message from client providing new mouse movement or button click */ 294 void recvPointerInput(); 295 296 /** Receive message from client that there is text in it's paste buffer. 297 * This is a no-op at the moment, but perhaps we would want to be able to 298 * paste it at some point. 299 */ 300 void recvCutText(); 301 302 /** Tell the client that the frame buffer resized. This happens when the 303 * simulated system changes video modes (E.g. X11 starts). 304 */ 305 void sendFrameBufferResized(); 306 307 static const PixelConverter pixelConverter; 308 309 public: 310 void setDirty() M5_ATTR_OVERRIDE; 311 void frameBufferResized() M5_ATTR_OVERRIDE; 312}; 313 314#endif 315