vncserver.hh revision 10839:10cac0f0f419
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