327 lines
7.5 KiB
C
327 lines
7.5 KiB
C
|
/*
|
||
|
* @file VNC.h
|
||
|
* @date 11.05.2015
|
||
|
* @author Markus Sattler
|
||
|
*
|
||
|
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||
|
* This file is part of the VNC client for Arduino.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; version 2 of the License
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, a copy can be downloaded from
|
||
|
* http://www.gnu.org/licenses/gpl.html, or obtained by writing to the
|
||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
* Thanks to all that worked on the original VNC implementation
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifndef VNC_H_
|
||
|
#define VNC_H_
|
||
|
|
||
|
#include "VNC_config.h"
|
||
|
|
||
|
/// more save free
|
||
|
#define freeSec(ptr) \
|
||
|
free(ptr); \
|
||
|
ptr = 0
|
||
|
|
||
|
#include "Arduino.h"
|
||
|
|
||
|
#ifdef VNC_ZRLE
|
||
|
#if defined(ESP32)
|
||
|
#include "esp32/rom/miniz.h"
|
||
|
#else
|
||
|
#include "miniz.h"
|
||
|
#endif
|
||
|
#endif // #ifdef VNC_ZRLE
|
||
|
|
||
|
#ifdef USE_ARDUINO_TCP
|
||
|
|
||
|
#if defined(ESP32)
|
||
|
#include <WiFi.h>
|
||
|
#elif defined(ESP8266)
|
||
|
#include <ESP8266WiFi.h>
|
||
|
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
|
||
|
#include <WiFi.h>
|
||
|
#elif defined(RTL8722DM)
|
||
|
#include <WiFi.h>
|
||
|
#else // default platform
|
||
|
|
||
|
#include <UIPEthernet.h>
|
||
|
#ifndef UIPETHERNET_H
|
||
|
#include <Ethernet.h>
|
||
|
#include <SPI.h>
|
||
|
#endif // #ifndef UIPETHERNET_H
|
||
|
|
||
|
#endif // default platform
|
||
|
|
||
|
#endif // #ifdef USE_ARDUINO_TCP
|
||
|
|
||
|
#define MAXPWLEN 8
|
||
|
#define CHALLENGESIZE 16
|
||
|
|
||
|
#define MAX_ENCODINGS 20
|
||
|
|
||
|
#ifdef WORDS_BIGENDIAN
|
||
|
#define Swap16IfLE(s) (s)
|
||
|
#define Swap32IfLE(l) (l)
|
||
|
#else
|
||
|
#define Swap16IfLE(s) __builtin_bswap16(s)
|
||
|
#define Swap32IfLE(l) __builtin_bswap32(l)
|
||
|
#endif /* WORDS_BIGENDIAN */
|
||
|
|
||
|
typedef uint8_t CARD8;
|
||
|
typedef int8_t INT8;
|
||
|
typedef uint16_t CARD16;
|
||
|
typedef int16_t INT16;
|
||
|
typedef uint32_t CARD32;
|
||
|
typedef int32_t INT32;
|
||
|
|
||
|
typedef struct serversettings
|
||
|
{
|
||
|
char *name;
|
||
|
int width;
|
||
|
int height;
|
||
|
int bpp;
|
||
|
int depth;
|
||
|
int bigendian;
|
||
|
int truecolour;
|
||
|
int redmax;
|
||
|
int greenmax;
|
||
|
int bluemax;
|
||
|
int redshift;
|
||
|
int greenshift;
|
||
|
int blueshift;
|
||
|
} serversettings_t;
|
||
|
|
||
|
typedef struct clientsettings
|
||
|
{
|
||
|
int width;
|
||
|
int height;
|
||
|
int bpp;
|
||
|
int depth;
|
||
|
int bigendian;
|
||
|
int truecolour;
|
||
|
int redmax;
|
||
|
int greenmax;
|
||
|
int bluemax;
|
||
|
int redshift;
|
||
|
int greenshift;
|
||
|
int blueshift;
|
||
|
int compresslevel;
|
||
|
int quality;
|
||
|
} clientsettings_t;
|
||
|
|
||
|
//__dfb_vnc_options
|
||
|
typedef struct
|
||
|
{
|
||
|
// char *servername;
|
||
|
// int port;
|
||
|
char *password;
|
||
|
// char *passwordfile;
|
||
|
// char *encodings;
|
||
|
// char *modmapfile;
|
||
|
serversettings_t server;
|
||
|
clientsettings_t client;
|
||
|
int shared;
|
||
|
int stretch;
|
||
|
int localcursor;
|
||
|
// int poll_freq;
|
||
|
/* not really options, but hey ;) */
|
||
|
double h_ratio;
|
||
|
double v_ratio;
|
||
|
int h_offset;
|
||
|
int v_offset;
|
||
|
} dfb_vnc_options;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int x;
|
||
|
int y;
|
||
|
unsigned int buttonmask;
|
||
|
} mousestate_t;
|
||
|
|
||
|
#include "rfbproto.h"
|
||
|
|
||
|
class VNCdisplay
|
||
|
{
|
||
|
protected:
|
||
|
VNCdisplay() {}
|
||
|
|
||
|
public:
|
||
|
virtual ~VNCdisplay() {}
|
||
|
|
||
|
virtual uint32_t getHeight(void) = 0;
|
||
|
virtual uint32_t getWidth(void) = 0;
|
||
|
|
||
|
virtual bool hasCopyRect(void) = 0;
|
||
|
virtual void copy_rect(uint32_t src_x, uint32_t src_y, uint32_t dest_x, uint32_t dest_y, uint32_t w, uint32_t h){};
|
||
|
|
||
|
virtual void draw_area(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t *data) = 0;
|
||
|
|
||
|
virtual void draw_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint16_t color) = 0;
|
||
|
|
||
|
virtual void flush() {};
|
||
|
|
||
|
virtual void vnc_options_override(dfb_vnc_options *opt){};
|
||
|
};
|
||
|
|
||
|
class arduinoVNC
|
||
|
{
|
||
|
public:
|
||
|
arduinoVNC(VNCdisplay *display);
|
||
|
~arduinoVNC(void);
|
||
|
|
||
|
void begin(char *host, uint16_t port = 5900, bool onlyFullUpdate = false);
|
||
|
void begin(const char *host, uint16_t port = 5900, bool onlyFullUpdate = false);
|
||
|
void begin(String host, uint16_t port = 5900, bool onlyFullUpdate = false);
|
||
|
|
||
|
void setPassword(char *pass);
|
||
|
void setPassword(const char *pass);
|
||
|
void setPassword(String pass);
|
||
|
|
||
|
bool connected(void);
|
||
|
void reconnect(void);
|
||
|
|
||
|
void loop(void);
|
||
|
|
||
|
int forceFullUpdate(void);
|
||
|
|
||
|
void mouseEvent(uint16_t x, uint16_t y, uint8_t buttonMask);
|
||
|
void keyEvent(int key, int down_flag);
|
||
|
|
||
|
private:
|
||
|
bool onlyFullUpdate;
|
||
|
int port;
|
||
|
String host;
|
||
|
String password;
|
||
|
|
||
|
VNCdisplay *display;
|
||
|
|
||
|
dfb_vnc_options opt;
|
||
|
|
||
|
uint8_t protocolMinorVersion;
|
||
|
|
||
|
int sock;
|
||
|
mousestate_t mousestate;
|
||
|
|
||
|
/// TCP handling
|
||
|
void disconnect(void);
|
||
|
bool read_from_rfb_server(int sock, char *out, size_t n);
|
||
|
|
||
|
#ifdef VNC_ZRLE
|
||
|
bool read_from_z(uint8_t *out, size_t n);
|
||
|
#endif // #ifdef VNC_ZRLE
|
||
|
|
||
|
bool write_exact(int sock, char *buf, size_t n);
|
||
|
bool set_non_blocking(int sock);
|
||
|
|
||
|
/// Connect to Server
|
||
|
bool rfb_connect_to_server(const char *server, int display);
|
||
|
bool rfb_initialise_connection();
|
||
|
|
||
|
bool _read_conn_failed_reason(void);
|
||
|
bool _read_authentication_result(void);
|
||
|
|
||
|
bool _rfb_negotiate_protocol(void);
|
||
|
bool _rfb_authenticate(void);
|
||
|
bool _rfb_initialise_client(void);
|
||
|
bool _rfb_initialise_server(void);
|
||
|
|
||
|
bool rfb_set_format_and_encodings();
|
||
|
bool rfb_set_desktop_size();
|
||
|
bool rfb_send_update_request(int incremental);
|
||
|
bool rfb_set_continuous_updates(bool enable);
|
||
|
bool rfb_handle_server_message();
|
||
|
bool rfb_update_mouse();
|
||
|
bool rfb_send_key_event(int key, int down_flag);
|
||
|
|
||
|
// void rfb_get_rgb_from_data(int *r, int *g, int *b, char *data);
|
||
|
|
||
|
/// Encode handling
|
||
|
bool _handle_server_cut_text_message(rfbServerToClientMsg *msg);
|
||
|
|
||
|
bool _handle_raw_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
bool _handle_raw_encoded_message_core(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
bool _handle_copyrect_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
#ifdef VNC_RRE
|
||
|
bool _handle_rre_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
#endif
|
||
|
#ifdef VNC_CORRE
|
||
|
bool _handle_corre_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
#endif
|
||
|
#ifdef VNC_HEXTILE
|
||
|
bool _handle_hextile_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
#endif
|
||
|
#ifdef VNC_ZRLE
|
||
|
bool _handle_zrle_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
#endif
|
||
|
bool _handle_cursor_pos_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
|
||
|
bool _handle_server_continuous_updates_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||
|
|
||
|
/// Encryption
|
||
|
void vncRandomBytes(unsigned char *bytes);
|
||
|
void vncEncryptBytes(unsigned char *bytes, char *passwd);
|
||
|
|
||
|
#ifdef USE_ARDUINO_TCP
|
||
|
|
||
|
#if defined(ESP32)
|
||
|
WiFiClient TCPclient;
|
||
|
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
|
||
|
WiFiClient TCPclient;
|
||
|
#elif defined(ESP8266)
|
||
|
WiFiClient TCPclient;
|
||
|
#elif defined(RTL8722DM)
|
||
|
WiFiClient TCPclient;
|
||
|
#else // default platform
|
||
|
|
||
|
#ifdef UIPETHERNET_H
|
||
|
UIPClient TCPclient;
|
||
|
#else
|
||
|
EthernetClient TCPclient;
|
||
|
#endif
|
||
|
|
||
|
#endif // default platform
|
||
|
|
||
|
#endif // #ifdef USE_ARDUINO_TCP
|
||
|
|
||
|
#ifdef TCP_BUFFER_SIZE
|
||
|
uint8_t tcp_buffer[TCP_BUFFER_SIZE];
|
||
|
size_t buf_idx = 0;
|
||
|
size_t buf_remain = 0;
|
||
|
#endif
|
||
|
|
||
|
uint32_t maxSize = VNC_RAW_BUFFER;
|
||
|
char raw_buffer[VNC_RAW_BUFFER];
|
||
|
uint16_t framebuffer[FB_SIZE];
|
||
|
|
||
|
#ifdef VNC_ZRLE
|
||
|
tinfl_decompressor inflator;
|
||
|
bool header_inited = false;
|
||
|
|
||
|
uint8_t *zin_buffer;
|
||
|
size_t allocated_zin = 0, zin_buf_size = 0, zin_buf_ofs = 0;
|
||
|
|
||
|
uint8_t *zdict;
|
||
|
size_t zdict_ofs = 0;
|
||
|
|
||
|
uint8_t *zout_buffer;
|
||
|
size_t zout_buf_idx = 0, zout_buf_remain = 0;
|
||
|
|
||
|
uint16_t palette[127];
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
#endif /* MARKUS_VNC_H_ */
|