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