vncserver.hh revision 10839:10cac0f0f419
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
316216Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
326216Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
346216Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35100SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
367584SAli.Saidi@arm.com *
376214Snate@binkert.org * Authors: Ali Saidi
38100SN/A *          William Wang
392SN/A */
402020SN/A
412SN/A/** @file
422SN/A * Declaration of a VNC server
4350SN/A */
442SN/A
452020SN/A#ifndef __BASE_VNC_VNC_SERVER_HH__
462SN/A#define __BASE_VNC_VNC_SERVER_HH__
4750SN/A
482SN/A#include <iostream>
4950SN/A
5050SN/A#include "base/vnc/vncinput.hh"
5150SN/A#include "base/bitmap.hh"
5250SN/A#include "base/circlebuf.hh"
5350SN/A#include "base/pollevent.hh"
5450SN/A#include "base/socket.hh"
5550SN/A#include "params/VncServer.hh"
5650SN/A#include "sim/sim_object.hh"
5750SN/A
5850SN/A/** @file
5950SN/A * Declaration of a VNC server
6050SN/A */
612SN/A
622SN/Aclass VncServer : public VncInput
632SN/A{
6450SN/A  public:
6550SN/A
662020SN/A    /**
672SN/A     * \defgroup VncConstants A set of constants and structs from the VNC spec
6850SN/A     * @{
692SN/A     */
702SN/A    /** Authentication modes */
7150SN/A    const static uint32_t AuthInvalid = 0;
7250SN/A    const static uint32_t AuthNone    = 1;
732020SN/A
7450SN/A    /** Error conditions */
752020SN/A    const static uint32_t VncOK   = 0;
7650SN/A
7750SN/A    /** Server -> Client message IDs */
787584SAli.Saidi@arm.com    enum ServerMessages {
797584SAli.Saidi@arm.com        ServerFrameBufferUpdate     = 0,
807584SAli.Saidi@arm.com        ServerSetColorMapEntries    = 1,
817584SAli.Saidi@arm.com        ServerBell                  = 2,
827584SAli.Saidi@arm.com        ServerCutText               = 3
837584SAli.Saidi@arm.com    };
847584SAli.Saidi@arm.com
857584SAli.Saidi@arm.com    /** Encoding types */
867584SAli.Saidi@arm.com    enum EncodingTypes {
877584SAli.Saidi@arm.com        EncodingRaw         = 0,
887584SAli.Saidi@arm.com        EncodingCopyRect    = 1,
897584SAli.Saidi@arm.com        EncodingHextile     = 5,
907584SAli.Saidi@arm.com        EncodingDesktopSize = -223
917584SAli.Saidi@arm.com    };
927584SAli.Saidi@arm.com
937584SAli.Saidi@arm.com    /** keyboard/mouse support */
947584SAli.Saidi@arm.com    enum MouseEvents {
957584SAli.Saidi@arm.com        MouseLeftButton     = 0x1,
967584SAli.Saidi@arm.com        MouseRightButton    = 0x2,
977584SAli.Saidi@arm.com        MouseMiddleButton   = 0x4
987584SAli.Saidi@arm.com    };
992SN/A
1002020SN/A    const char* vncVersion() const
10150SN/A    {
102100SN/A        return "RFB 003.008\n";
1032SN/A    }
10450SN/A
1052SN/A    enum ConnectionState {
10650SN/A        WaitForProtocolVersion,
10750SN/A        WaitForSecurityResponse,
10850SN/A        WaitForClientInit,
10950SN/A        InitializationPhase,
11050SN/A        NormalPhase
11150SN/A    };
11250SN/A
11350SN/A    struct ServerInitMsg {
11450SN/A        uint16_t fbWidth;
115100SN/A        uint16_t fbHeight;
1162020SN/A        PixelFormat px;
1171642SN/A        uint32_t namelen;
1181642SN/A        char name[2]; // just to put M5 in here
1191642SN/A    } M5_ATTR_PACKED;
1201642SN/A
1211642SN/A    struct FrameBufferUpdate {
1221642SN/A        uint8_t type;
1231642SN/A        uint8_t padding;
1241642SN/A        uint16_t num_rects;
1251642SN/A    } M5_ATTR_PACKED;
1261642SN/A
1271642SN/A    struct FrameBufferRect {
1281642SN/A        uint16_t x;
1291642SN/A        uint16_t y;
1301642SN/A        uint16_t width;
1311642SN/A        uint16_t height;
1321642SN/A        int32_t encoding;
1331642SN/A    } M5_ATTR_PACKED;
1341642SN/A
1352020SN/A    struct ServerCutText {
136100SN/A        uint8_t type;
137100SN/A        uint8_t padding[3];
138100SN/A        uint32_t length;
139100SN/A    } M5_ATTR_PACKED;
140100SN/A
141100SN/A    /** @} */
142100SN/A
143100SN/A  protected:
144100SN/A    /** ListenEvent to accept a vnc client connection */
145100SN/A    class ListenEvent: public PollEvent
146100SN/A    {
147100SN/A      protected:
148100SN/A        VncServer *vncserver;
149100SN/A
150100SN/A      public:
151100SN/A        ListenEvent(VncServer *vs, int fd, int e);
1522020SN/A        void process(int revent);
153100SN/A    };
154100SN/A
1552020SN/A    friend class ListenEvent;
156100SN/A    ListenEvent *listenEvent;
157100SN/A
158100SN/A    /** DataEvent to read data from vnc */
1592020SN/A    class DataEvent: public PollEvent
160100SN/A    {
161100SN/A      protected:
1622020SN/A        VncServer *vncserver;
1631642SN/A
1641642SN/A      public:
1651642SN/A        DataEvent(VncServer *vs, int fd, int e);
1662020SN/A        void process(int revent);
1671642SN/A    };
1681642SN/A
1692020SN/A    friend class DataEvent;
170100SN/A    DataEvent *dataEvent;
171100SN/A
17250SN/A    int number;
17350SN/A    int dataFd; // data stream file describer
1742020SN/A
17550SN/A    ListenSocket listener;
176100SN/A
177100SN/A    void listen(int port);
178100SN/A    void accept();
1792020SN/A    void data();
18050SN/A    void detach();
18150SN/A
18250SN/A  public:
18350SN/A    typedef VncServerParams Params;
1842020SN/A    VncServer(const Params *p);
18550SN/A    ~VncServer();
1862020SN/A
18750SN/A    // RFB
18850SN/A  protected:
18950SN/A
19050SN/A    /** The rfb prototol state the connection is in */
1912020SN/A    ConnectionState curState;
19250SN/A
1932020SN/A    /** An update needs to be sent to the client. Without doing this the
19450SN/A     * client will constantly request data that is pointless */
1952SN/A    bool sendUpdate;
1969091Sandreas.hansson@arm.com
19752SN/A    /** The one and only pixel format we support */
1989091Sandreas.hansson@arm.com    PixelFormat pixelFormat;
19952SN/A
20052SN/A    /** If the vnc client supports receiving raw data. It always should */
20152SN/A    bool supportsRawEnc;
20252SN/A
20352SN/A    /** If the vnc client supports the desktop resize command */
20452SN/A    bool supportsResizeEnc;
2052021SN/A
20652SN/A  protected:
2072021SN/A    /**
20852SN/A     * vnc client Interface
20952SN/A     */
21052SN/A
21152SN/A    /** Send an error message to the client
21252SN/A     * @param error_msg text to send describing the error
2132418SN/A     */
21452SN/A    void sendError(const char* error_msg);
2152418SN/A
21652SN/A    /** Read some data from the client
21752SN/A     * @param buf the data to read
21852SN/A     * @param len the amount of data to read
2192SN/A     * @return length read
2202020SN/A     */
22150SN/A    size_t read(uint8_t *buf, size_t len);
2225570Snate@binkert.org
2235570Snate@binkert.org    /** Read len -1 bytes from the client into the buffer provided + 1
2245570Snate@binkert.org     * assert that we read enough bytes. This function exists to handle
2252SN/A     * reading all of the protocol structs above when we've already read
2262SN/A     * the first byte which describes which one we're reading
2272SN/A     * @param buf the address of the buffer to add one to and read data into
2282020SN/A     * @param len the amount of data  + 1 to read
22950SN/A     * @return length read
23050SN/A     */
23150SN/A    size_t read1(uint8_t *buf, size_t len);
2322SN/A
2332SN/A
2342020SN/A    /** Templated version of the read function above to
23550SN/A     * read simple data to the client
23650SN/A     * @param val data to recv from the client
23750SN/A     */
2382SN/A    template <typename T> size_t read(T* val);
2392SN/A
2402020SN/A
2412SN/A    /** Write a buffer to the client.
2422SN/A     * @param buf buffer to send
2432SN/A     * @param len length of the buffer
2442SN/A     * @return number of bytes sent
245105SN/A     */
2462SN/A    size_t write(const uint8_t *buf, size_t len);
2472SN/A
2482SN/A    /** Templated version of the write function above to
2492SN/A     * write simple data to the client
2502SN/A     * @param val data to send to the client
2512SN/A     */
2522SN/A    template <typename T> size_t write(T* val);
2532SN/A
2546216Snate@binkert.org    /** 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