vncserver.hh revision 11168
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
312439SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322984Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33146SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34146SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35146SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36146SN/A *
37146SN/A * Authors: Ali Saidi
38146SN/A *          William Wang
391717SN/A */
40146SN/A
411717SN/A/** @file
42146SN/A * Declaration of a VNC server
431977SN/A */
442623SN/A
452683Sktlim@umich.edu#ifndef __BASE_VNC_VNC_SERVER_HH__
461717SN/A#define __BASE_VNC_VNC_SERVER_HH__
47146SN/A
482683Sktlim@umich.edu#include <iostream>
491917SN/A
503348Sbinkertn@umich.edu#include "base/vnc/vncinput.hh"
512683Sktlim@umich.edu#include "base/bitmap.hh"
522036SN/A#include "base/circlebuf.hh"
53146SN/A#include "base/pollevent.hh"
5456SN/A#include "base/socket.hh"
5556SN/A#include "params/VncServer.hh"
5656SN/A#include "sim/sim_object.hh"
57695SN/A
582901Ssaidi@eecs.umich.edu/** @file
592SN/A * Declaration of a VNC server
601858SN/A */
6156SN/A
622171SN/Aclass VncServer : public VncInput
632170SN/A{
642170SN/A  public:
65146SN/A
662462SN/A    /**
67146SN/A     * \defgroup VncConstants A set of constants and structs from the VNC spec
682SN/A     * @{
692SN/A     */
702449SN/A    /** Authentication modes */
711355SN/A    const static uint32_t AuthInvalid = 0;
722623SN/A    const static uint32_t AuthNone    = 1;
733402Sktlim@umich.edu
74224SN/A    /** Error conditions */
751858SN/A    const static uint32_t VncOK   = 0;
762683Sktlim@umich.edu
772420SN/A    /** Server -> Client message IDs */
782683Sktlim@umich.edu    enum ServerMessages {
793402Sktlim@umich.edu        ServerFrameBufferUpdate     = 0,
802420SN/A        ServerSetColorMapEntries    = 1,
812SN/A        ServerBell                  = 2,
822683Sktlim@umich.edu        ServerCutText               = 3
832672Sktlim@umich.edu    };
842683Sktlim@umich.edu
852SN/A    /** Encoding types */
862SN/A    enum EncodingTypes {
87334SN/A        EncodingRaw         = 0,
88140SN/A        EncodingCopyRect    = 1,
89334SN/A        EncodingHextile     = 5,
902SN/A        EncodingDesktopSize = -223
912SN/A    };
922SN/A
932680Sktlim@umich.edu    /** keyboard/mouse support */
942SN/A    enum MouseEvents {
952SN/A        MouseLeftButton     = 0x1,
962623SN/A        MouseRightButton    = 0x2,
972SN/A        MouseMiddleButton   = 0x4
982SN/A    };
992SN/A
100180SN/A    const char* vncVersion() const
1012623SN/A    {
102393SN/A        return "RFB 003.008\n";
103393SN/A    }
104393SN/A
105393SN/A    enum ConnectionState {
106384SN/A        WaitForProtocolVersion,
107384SN/A        WaitForSecurityResponse,
108393SN/A        WaitForClientInit,
1092623SN/A        InitializationPhase,
110393SN/A        NormalPhase
111393SN/A    };
112393SN/A
113393SN/A    struct ServerInitMsg {
114384SN/A        uint16_t fbWidth;
115189SN/A        uint16_t fbHeight;
116189SN/A        PixelFormat px;
1172623SN/A        uint32_t namelen;
1182SN/A        char name[2]; // just to put M5 in here
119729SN/A    } M5_ATTR_PACKED;
120334SN/A
1212SN/A    struct FrameBufferUpdate {
1222SN/A        uint8_t type;
1232SN/A        uint8_t padding;
1242SN/A        uint16_t num_rects;
1252SN/A    } M5_ATTR_PACKED;
1262SN/A
1272SN/A    struct FrameBufferRect {
1282SN/A        uint16_t x;
1292SN/A        uint16_t y;
1302SN/A        uint16_t width;
1312SN/A        uint16_t height;
1322SN/A        int32_t encoding;
1331001SN/A    } M5_ATTR_PACKED;
1341001SN/A
1351001SN/A    struct ServerCutText {
1361001SN/A        uint8_t type;
1371001SN/A        uint8_t padding[3];
1382SN/A        uint32_t length;
1392SN/A    } M5_ATTR_PACKED;
1402SN/A
1412SN/A    /** @} */
1422SN/A
1432SN/A  protected:
1442SN/A    /** ListenEvent to accept a vnc client connection */
1452SN/A    class ListenEvent: public PollEvent
1462SN/A    {
1472SN/A      protected:
1482SN/A        VncServer *vncserver;
1492SN/A
1502SN/A      public:
1512SN/A        ListenEvent(VncServer *vs, int fd, int e);
1522SN/A        void process(int revent);
1532SN/A    };
1542SN/A
1552390SN/A    friend class ListenEvent;
1562390SN/A    ListenEvent *listenEvent;
1572390SN/A
1582390SN/A    /** DataEvent to read data from vnc */
1592390SN/A    class DataEvent: public PollEvent
1602390SN/A    {
1612390SN/A      protected:
1622390SN/A        VncServer *vncserver;
1632390SN/A
1642390SN/A      public:
1652390SN/A        DataEvent(VncServer *vs, int fd, int e);
1662390SN/A        void process(int revent);
167385SN/A    };
1682SN/A
1692SN/A    friend class DataEvent;
1702SN/A    DataEvent *dataEvent;
1712623SN/A
172334SN/A    int number;
1732361SN/A    int dataFd; // data stream file describer
1742623SN/A
175334SN/A    ListenSocket listener;
176334SN/A
177334SN/A    void listen(int port);
1782623SN/A    void accept();
1792SN/A    void data();
180921SN/A    void detach();
1812915Sktlim@umich.edu
1822915Sktlim@umich.edu  public:
1832683Sktlim@umich.edu    typedef VncServerParams Params;
1842SN/A    VncServer(const Params *p);
1852SN/A    ~VncServer();
1862SN/A
1872623SN/A    // RFB
1882SN/A  protected:
189921SN/A
1902915Sktlim@umich.edu    /** The rfb prototol state the connection is in */
1912915Sktlim@umich.edu    ConnectionState curState;
1922SN/A
1932SN/A    /** An update needs to be sent to the client. Without doing this the
1942SN/A     * client will constantly request data that is pointless */
1952SN/A    bool sendUpdate;
1962SN/A
1972SN/A    /** The one and only pixel format we support */
1982SN/A    PixelFormat pixelFormat;
199595SN/A
2002623SN/A    /** If the vnc client supports receiving raw data. It always should */
201595SN/A    bool supportsRawEnc;
2022390SN/A
2031080SN/A    /** If the vnc client supports the desktop resize command */
2041080SN/A    bool supportsResizeEnc;
2051080SN/A
2061080SN/A  protected:
2071080SN/A    /**
2081080SN/A     * vnc client Interface
2091080SN/A     */
2101121SN/A
2112107SN/A    /** Send an error message to the client
2121089SN/A     * @param error_msg text to send describing the error
2131089SN/A     */
2141080SN/A    void sendError(const char* error_msg);
2151080SN/A
2161080SN/A    /** Read some data from the client
2171080SN/A     * @param buf the data to read
218595SN/A     * @param len the amount of data to read
2192623SN/A     * @return length read
2202683Sktlim@umich.edu     */
221595SN/A    size_t read(uint8_t *buf, size_t len);
2222090SN/A
2232683Sktlim@umich.edu    /** Read len -1 bytes from the client into the buffer provided + 1
2242683Sktlim@umich.edu     * assert that we read enough bytes. This function exists to handle
225595SN/A     * reading all of the protocol structs above when we've already read
2262205SN/A     * the first byte which describes which one we're reading
2272205SN/A     * @param buf the address of the buffer to add one to and read data into
2282683Sktlim@umich.edu     * @param len the amount of data  + 1 to read
2292683Sktlim@umich.edu     * @return length read
230595SN/A     */
231595SN/A    size_t read1(uint8_t *buf, size_t len);
2322390SN/A
2332423SN/A
2342390SN/A    /** Templated version of the read function above to
235595SN/A     * read simple data to the client
236595SN/A     * @param val data to recv from the client
237595SN/A     */
2382623SN/A    template <typename T> size_t read(T* val);
239595SN/A
2402390SN/A
2411080SN/A    /** Write a buffer to the client.
242595SN/A     * @param buf buffer to send
2431080SN/A     * @param len length of the buffer
2441080SN/A     * @return number of bytes sent
245595SN/A     */
2462683Sktlim@umich.edu    size_t write(const uint8_t *buf, size_t len);
2471080SN/A
2481080SN/A    /** Templated version of the write function above to
2491080SN/A     * write simple data to the client
2501121SN/A     * @param val data to send to the client
2512107SN/A     */
2521089SN/A    template <typename T> size_t write(T* val);
2531080SN/A
2541089SN/A    /** Send a string to the client
2551080SN/A     * @param str string to transmit
2561080SN/A     */
2571080SN/A    size_t write(const char* str);
258595SN/A
2592683Sktlim@umich.edu    /** Check the client's protocol verion for compatibility and send
2601080SN/A     * the security types we support
2612090SN/A     */
2621080SN/A    void checkProtocolVersion();
263595SN/A
2642683Sktlim@umich.edu    /** Check that the security exchange was successful
2652683Sktlim@umich.edu     */
266595SN/A    void checkSecurity();
2672683Sktlim@umich.edu
2681098SN/A    /** Send client our idea about what the frame buffer looks like */
2691098SN/A    void sendServerInit();
2701098SN/A
2712683Sktlim@umich.edu    /** Send an error message to the client when something goes wrong
2721098SN/A     * @param error_msg error to send
2731098SN/A     */
2741098SN/A    void sendError(std::string error_msg);
2752012SN/A
2761098SN/A    /** Send a updated frame buffer to the client.
2771098SN/A     * @todo this doesn't do anything smart and just sends the entire image
278595SN/A     */
2792205SN/A    void sendFrameBufferUpdate();
2802205SN/A
2812205SN/A    /** Receive pixel foramt message from client and process it. */
282595SN/A    void setPixelFormat();
2832390SN/A
2842420SN/A    /** Receive encodings message from client and process it. */
2852423SN/A    void setEncodings();
2862390SN/A
287595SN/A    /** Receive message from client asking for updated frame buffer */
288595SN/A    void requestFbUpdate();
2891858SN/A
2902SN/A    /** Receive message from client providing new keyboard input */
2912623SN/A    void recvKeyboardInput();
2922SN/A
2932680Sktlim@umich.edu    /** Recv message from client providing new mouse movement or button click */
2942SN/A    void recvPointerInput();
2952SN/A
2962SN/A    /**  Receive message from client that there is text in it's paste buffer.
2971858SN/A     * This is a no-op at the moment, but perhaps we would want to be able to
2982SN/A     * paste it at some point.
2992623SN/A     */
3002SN/A    void recvCutText();
3012SN/A
3022SN/A    /** Tell the client that the frame buffer resized. This happens when the
3032683Sktlim@umich.edu     * simulated system changes video modes (E.g. X11 starts).
3042SN/A     */
3052683Sktlim@umich.edu    void sendFrameBufferResized();
3062SN/A
3072SN/A    static const PixelConverter pixelConverter;
3082SN/A
3092SN/A  public:
3102SN/A    void setDirty() override;
3112623SN/A    void frameBufferResized() override;
3122SN/A};
3131858SN/A
3142683Sktlim@umich.edu#endif
3151133SN/A