vncserver.hh revision 9848:a733a8eb6363
1/* 2 * Copyright (c) 2010 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/convert.hh" 51#include "base/vnc/vncinput.hh" 52#include "base/bitmap.hh" 53#include "base/circlebuf.hh" 54#include "base/pollevent.hh" 55#include "base/socket.hh" 56#include "params/VncServer.hh" 57#include "sim/sim_object.hh" 58 59/** @file 60 * Declaration of a VNC server 61 */ 62 63class VncServer : public VncInput 64{ 65 public: 66 67 /** 68 * \defgroup VncConstants A set of constants and structs from the VNC spec 69 * @{ 70 */ 71 /** Authentication modes */ 72 const static uint32_t AuthInvalid = 0; 73 const static uint32_t AuthNone = 1; 74 75 /** Error conditions */ 76 const static uint32_t VncOK = 0; 77 78 /** Server -> Client message IDs */ 79 enum ServerMessages { 80 ServerFrameBufferUpdate = 0, 81 ServerSetColorMapEntries = 1, 82 ServerBell = 2, 83 ServerCutText = 3 84 }; 85 86 /** Encoding types */ 87 enum EncodingTypes { 88 EncodingRaw = 0, 89 EncodingCopyRect = 1, 90 EncodingHextile = 5, 91 EncodingDesktopSize = -223 92 }; 93 94 /** keyboard/mouse support */ 95 enum MouseEvents { 96 MouseLeftButton = 0x1, 97 MouseRightButton = 0x2, 98 MouseMiddleButton = 0x4 99 }; 100 101 const char* vncVersion() const 102 { 103 return "RFB 003.008\n"; 104 } 105 106 enum ConnectionState { 107 WaitForProtocolVersion, 108 WaitForSecurityResponse, 109 WaitForClientInit, 110 InitializationPhase, 111 NormalPhase 112 }; 113 114 struct ServerInitMsg { 115 uint16_t fbWidth; 116 uint16_t fbHeight; 117 PixelFormat px; 118 uint32_t namelen; 119 char name[2]; // just to put M5 in here 120 } M5_ATTR_PACKED; 121 122 struct FrameBufferUpdate { 123 uint8_t type; 124 uint8_t padding; 125 uint16_t num_rects; 126 } M5_ATTR_PACKED; 127 128 struct FrameBufferRect { 129 uint16_t x; 130 uint16_t y; 131 uint16_t width; 132 uint16_t height; 133 int32_t encoding; 134 } M5_ATTR_PACKED; 135 136 struct ServerCutText { 137 uint8_t type; 138 uint8_t padding[3]; 139 uint32_t length; 140 } M5_ATTR_PACKED; 141 142 /** @} */ 143 144 protected: 145 /** ListenEvent to accept a vnc client connection */ 146 class ListenEvent: public PollEvent 147 { 148 protected: 149 VncServer *vncserver; 150 151 public: 152 ListenEvent(VncServer *vs, int fd, int e); 153 void process(int revent); 154 }; 155 156 friend class ListenEvent; 157 ListenEvent *listenEvent; 158 159 /** DataEvent to read data from vnc */ 160 class DataEvent: public PollEvent 161 { 162 protected: 163 VncServer *vncserver; 164 165 public: 166 DataEvent(VncServer *vs, int fd, int e); 167 void process(int revent); 168 }; 169 170 friend class DataEvent; 171 DataEvent *dataEvent; 172 173 int number; 174 int dataFd; // data stream file describer 175 176 ListenSocket listener; 177 178 void listen(int port); 179 void accept(); 180 void data(); 181 void detach(); 182 183 public: 184 typedef VncServerParams Params; 185 VncServer(const Params *p); 186 ~VncServer(); 187 188 // RFB 189 protected: 190 191 /** The rfb prototol state the connection is in */ 192 ConnectionState curState; 193 194 /** An update needs to be sent to the client. Without doing this the 195 * client will constantly request data that is pointless */ 196 bool sendUpdate; 197 198 /** The one and only pixel format we support */ 199 PixelFormat pixelFormat; 200 201 /** If the vnc client supports receiving raw data. It always should */ 202 bool supportsRawEnc; 203 204 /** If the vnc client supports the desktop resize command */ 205 bool supportsResizeEnc; 206 207 protected: 208 /** 209 * vnc client Interface 210 */ 211 212 /** Send an error message to the client 213 * @param error_msg text to send describing the error 214 */ 215 void sendError(const char* error_msg); 216 217 /** Read some data from the client 218 * @param buf the data to read 219 * @param len the amount of data to read 220 * @return length read 221 */ 222 size_t read(uint8_t *buf, size_t len); 223 224 /** Read len -1 bytes from the client into the buffer provided + 1 225 * assert that we read enough bytes. This function exists to handle 226 * reading all of the protocol structs above when we've already read 227 * the first byte which describes which one we're reading 228 * @param buf the address of the buffer to add one to and read data into 229 * @param len the amount of data + 1 to read 230 * @return length read 231 */ 232 size_t read1(uint8_t *buf, size_t len); 233 234 235 /** Templated version of the read function above to 236 * read simple data to the client 237 * @param val data to recv from the client 238 */ 239 template <typename T> size_t read(T* val); 240 241 242 /** Write a buffer to the client. 243 * @param buf buffer to send 244 * @param len length of the buffer 245 * @return number of bytes sent 246 */ 247 size_t write(const uint8_t *buf, size_t len); 248 249 /** Templated version of the write function above to 250 * write simple data to the client 251 * @param val data to send to the client 252 */ 253 template <typename T> size_t write(T* val); 254 255 /** Send a string to the client 256 * @param str string to transmit 257 */ 258 size_t write(const char* str); 259 260 /** Check the client's protocol verion for compatibility and send 261 * the security types we support 262 */ 263 void checkProtocolVersion(); 264 265 /** Check that the security exchange was successful 266 */ 267 void checkSecurity(); 268 269 /** Send client our idea about what the frame buffer looks like */ 270 void sendServerInit(); 271 272 /** Send an error message to the client when something goes wrong 273 * @param error_msg error to send 274 */ 275 void sendError(std::string error_msg); 276 277 /** Send a updated frame buffer to the client. 278 * @todo this doesn't do anything smart and just sends the entire image 279 */ 280 void sendFrameBufferUpdate(); 281 282 /** Receive pixel foramt message from client and process it. */ 283 void setPixelFormat(); 284 285 /** Receive encodings message from client and process it. */ 286 void setEncodings(); 287 288 /** Receive message from client asking for updated frame buffer */ 289 void requestFbUpdate(); 290 291 /** Receive message from client providing new keyboard input */ 292 void recvKeyboardInput(); 293 294 /** Recv message from client providing new mouse movement or button click */ 295 void recvPointerInput(); 296 297 /** Receive message from client that there is text in it's paste buffer. 298 * This is a no-op at the moment, but perhaps we would want to be able to 299 * paste it at some point. 300 */ 301 void recvCutText(); 302 303 /** Tell the client that the frame buffer resized. This happens when the 304 * simulated system changes video modes (E.g. X11 starts). 305 */ 306 void sendFrameBufferResized(); 307 308 public: 309 /** The frame buffer uses this call to notify the vnc server that 310 * the frame buffer has been updated and a new image needs to be sent to the 311 * client 312 */ 313 void 314 setDirty() 315 { 316 VncInput::setDirty(); 317 sendUpdate = true; 318 sendFrameBufferUpdate(); 319 } 320 321 /** Set the mode of the data the frame buffer will be sending us 322 * @param mode the mode 323 */ 324 void setFrameBufferParams(VideoConvert::Mode mode, uint16_t width, 325 uint16_t height); 326}; 327 328#endif 329