components/vnc_server/vnc-server.c

branch
novnc
changeset 38
537ffe280775
parent 37
1b82a6d50a39
child 39
e5900c9b9a7b
--- a/components/vnc_server/vnc-server.c	Thu May 02 11:57:07 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1361 +0,0 @@
-/**
- * @file vnc-server.c
- * @brief VNC server original written for eCos.
- *
- * The VNC server runs on the target platform and waits for a client 
- * (vncviewer program running on a PC) to connect via an ethernet connection
- * (port 5900). Once a client has connected, the target platform has a 
- * virtual screen, keyboard and mouse.
- *
- * This port of the VNC server has been designed with some limitations in 
- * order to keep memory and processor power requirements to a minimum.
- *
- * The VNC client must accept the settings that the VNC server suggests (bits-per-pixel, 
- * number-of-colours and so on as specified at build time with the eCos configuration 
- * tool) or the VNC server will just disconnect.
- *
- * The VNC server only supports CoRRE encoding and RAW encoding for sending 
- * display data to the client.
- *
- * The VNC server does not support password authentication, the client is able 
- * to connect without the user typing in a password.
- *
- * Only one VNC client may connect to the VNC server at a time.
- *
- * In reality these limitations are not a problem.
- *
- * @author Chris Garry <cgarry@sweeneydesign.co.uk>
- * @author Michiel Broek.
- */
-
-#include "vnc-server.h"
-#include "websocket_server.h"
-
-static const char *TAG = "vnc-server";
-
-#define BACKLOG             5				///< Number of pending connections queue will hold 
-#define MESSAGE_BUFFER_SIZE 60				///< Was 50, but I have seen 52 bytes length
-#define TILE_SIZE           16				///< Tile dimension
-#define TRUE_COLOUR_FLAG    1				///< True colour is set
-#define BIG_ENDIAN_FLAG     1				///< Always send colour data big endian
-
-/* Default display parameters */
-#define BITS_PER_PIXEL      8				///< Bits per pixel
-#define PIXEL_DEPTH         8				///< Usefull bits per pixel
-#define RED_MAX             7				///< Red maximum
-#define GREEN_MAX           7				///< Green maximum
-#define BLUE_MAX            3				///< Blue maximum, together 8 bits.
-#define RED_SHIFT           5				///< Red shift in color byte
-#define GREEN_SHIFT         2				///< Green shift in color byte
-#define BLUE_SHIFT          0				///< Blue shift in color byte
-
-
-/* Initial default RGB332 */
-uint8_t			Bits_Per_Pixel = 8;		///< Current number of bits per pixel
-
-uint16_t		Red_Max     = RED_MAX;		///< Current Red maxmimum
-uint16_t		Green_Max   = GREEN_MAX;	///< Current Green maximum
-uint16_t		Blue_Max    = BLUE_MAX;		///< Current Blue maximum
-uint8_t			Red_Shift   = RED_SHIFT;	///< Current Red bits shift
-uint8_t			Green_Shift = GREEN_SHIFT;	///< Current Green bits shift
-uint8_t			Blue_Shift  = BLUE_SHIFT;	///< Current Blue bits shift
-bool			AltPixels   = false;		///< Alternate the pixels
-
-/* Client to Server message types */
-#define SET_PIXEL_FORMAT         0			///< Set pixel format
-#define FIX_COLOUR_MAP_ENTRIES   1			///< Fix color map entries (not used)
-#define SET_ENCODINGS            2			///< Set encodings
-#define FRAME_BUFFER_UPDATE_REQ  3			///< Request frame buffer update
-#define KEY_EVENT                4			///< Keyboard event (not used)
-#define POINTER_EVENT            5			///< Pointer event, translated to touch events
-#define CLIENT_CUT_TEXT          6			///< Text editing, not used.
-
-/* Macros to split colour to bytes */
-#define COLOUR2BYTE1(col) ((col>>8)&0xFF)		///< High part
-#define COLOUR2BYTE0(col) (col&0xFF)			///< Low part
-
-
-/* Thread function prototypes */
-static TaskHandle_t	xTaskClientHandler = NULL;	///< Task for VNC clients
-static TaskHandle_t	xTaskFrameUpdate   = NULL;	///< Task for framebuffer updates
-static TaskHandle_t	xTaskWSclient      = NULL;	///< Task for websocket clients
-
-SemaphoreHandle_t	SoundBell_lock     = NULL;	///< Lock for the bell sound.
-
-static QueueHandle_t	message_queue;			///< Websockets message queue
-const static int	message_queue_size = 5;		///< Message queue size
-
-/**
- * @brief VNC messages.
- */
-struct strMessage {
-    int			length;				///< Length of the message
-    uint8_t		message[MESSAGE_BUFFER_SIZE];	///< The message
-};
-
-
-uint8_t			VNC_pointer_button = 0;		///< Button mask for the mouse pointer
-uint16_t		VNC_pointer_x = 0;		///< Mouse position X
-uint16_t		VNC_pointer_y = 0;		///< Mouse position Y
-
-
-/* Define size of each thread's stack */
-#define MIN_STACK_SIZE	3072				///< Minimal task stack size
-
-
-/**
- * @brief  Messages
- */
-static char		server_ProtocolVersion[] = "RFB 003.003\n";
-static char		bad_protocol[] = "Unsupported ProtocolVersion";
-static char		server_busy[] = "Server is Busy";
-static char		sound_bell[] = "\2";
-static char		desktop_name[] = "MBSE BrewBoard";	// Hardcoded, don't change or the VNC webclient breaks.
-
-/**
- * @brief  Frame Buffer
- */
-vnc_color_t		frame_buffer[CONFIG_VNC_SERVER_FRAME_HEIGHT+1][CONFIG_VNC_SERVER_FRAME_WIDTH+1];
-
-/* Calculate the number of tiles in the X and Y directions */
-#if (CONFIG_VNC_SERVER_FRAME_HEIGHT % TILE_SIZE) != 0
-#define NUM_TILES_Y_AXIS (CONFIG_VNC_SERVER_FRAME_HEIGHT/TILE_SIZE + 1)
-#define LAST_TILE_HEIGHT (CONFIG_VNC_SERVER_FRAME_HEIGHT % TILE_SIZE)
-#else
-#define NUM_TILES_Y_AXIS (CONFIG_VNC_SERVER_FRAME_HEIGHT/TILE_SIZE)	///< Nr of tiles on the Y axis.
-#define LAST_TILE_HEIGHT TILE_SIZE					///< Height of the last tile.
-#endif
-
-#if (CONFIG_VNC_SERVER_FRAME_WIDTH % TILE_SIZE) != 0
-#define NUM_TILES_X_AXIS (CONFIG_VNC_SERVER_FRAME_WIDTH/TILE_SIZE + 1)
-#define LAST_TILE_WIDTH (CONFIG_VNC_SERVER_FRAME_WIDTH % TILE_SIZE)
-#else
-#define NUM_TILES_X_AXIS (CONFIG_VNC_SERVER_FRAME_WIDTH/TILE_SIZE)	///< Nr of tiles on the X axis.
-#define LAST_TILE_WIDTH TILE_SIZE					///< Width of the last tile.
-#endif
-
-/**
- * @brief  Array for marking tiles that have been updated
- */
-int			tile_updated[NUM_TILES_Y_AXIS+1][NUM_TILES_X_AXIS+1];
-
-EventGroupHandle_t	xEventGroupVNC;			///< Variable to signal that a client is connected and initialised
-const int 		VNC_CLIENT_UPDATE_REQ = BIT0;	///< Client update request event
-int			vnc_client_sock = -1;		///< Client network socket
-bool			vnc_client_connected = false;	///< Client connected?
-int			SoundBellCount;			///< Count the client's bell
-bool			VNC_WS_run = false;		///< Websocket running
-int			VNC_WS_num = -1;		///< Websocket connection number
-
-
-
-/**
- * @brief Variable to hold the frame format details
- */
-vnc_frame_format_t	frame_format = {CONFIG_VNC_SERVER_FRAME_WIDTH, CONFIG_VNC_SERVER_FRAME_HEIGHT, frame_buffer,
-                                   1,			// RGB332 server native.
-                                   0,			// RGB555
-                                   0,			// RGB565
-                                   0,			// BGR233
-                                   0,			// TRUECOLOR0888
-};
-
-
-
-#if 0
-void dump_msg(char *buf, uint16_t buflen, char *mode)
-{   
-    int i, l = 0;
-
-    printf("%s %d", mode, buflen);
-    for (i = 0; i < buflen; i++) {
-	if ((i % 16) == 0) {
-	    printf("\n%02d: ", l);
-	    l++;
-	}
-	printf("%02x ", buf[i]);
-    }
-    printf("\n");
-}
-#endif
-
-
-/**
- * @brief Structure to hold the encoding type details
- */
-volatile struct encoding_type_struct
-{
-    uint8_t		raw;
-    uint8_t		copy_rectangle;
-    uint8_t		rre;
-    uint8_t		corre;
-    uint8_t		hextile;
-} encoding_type;
-
-
-static int GetMessageData(int, char *, int);
-static int GenTileUpdateData(uint8_t *);
-void task_VNCserver(void *);
-void task_frame(void *);
-void task_WS(void *);
-
-
-
-/**
- * @brief Serve a new VNC client.
- */
-void vnc_netconn_serve(void);
-
-
-/* VNC startup. */
-void VncStartup(void)
-{
-    /* Initialise mutex & cond vars */
-    xEventGroupVNC = xEventGroupCreate();
-    SoundBell_lock = xSemaphoreCreateMutex();
-
-    xTaskCreate(&task_VNCserver, "VNCserver",    MIN_STACK_SIZE, NULL, 5, &xTaskClientHandler);
-    xTaskCreate(&task_frame,     "frame_update", MIN_STACK_SIZE, NULL, 6, &xTaskFrameUpdate);
-}
-
-
-/** 
- * @brief Client Handler Task.
- *
- * This task handles the client initialisation sequence. Once the client
- * is initialised this task handles all received messages from the client,
- * but does not send any data to the client.
- */
-void task_VNCserver(void *pvParameter)
-{
-    int			server_sock; 
-    struct sockaddr_in	server_addr;
-    struct sockaddr_in	client_addr;
-    socklen_t		client_addr_size;
-
-    ESP_LOGI(TAG, "Starting VNC server");
-
-    /* Clear the encoding type structure */
-    encoding_type.raw = 0;
-    encoding_type.copy_rectangle = 0;
-    encoding_type.rre = 0;
-    encoding_type.corre = 0;
-    encoding_type.hextile = 0;
-
-    /* Clear the sound bell counter */
-    SoundBellCount = 0;
-    VNC_pointer_button = 0;
-    VNC_pointer_x = VNC_pointer_y = 0;
-
-    /* Create socket for incomming connections */
-    if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
-        ESP_LOGE(TAG, "socket() VNC function failed");
-        exit(1);
-    }
-
-    /* Construct the server address structure */
-    memset(&server_addr, 0, sizeof(server_addr));  /* Fill entire structure with 0's */
-    server_addr.sin_family      = AF_INET;         /* Internet address family */
-    server_addr.sin_addr.s_addr = INADDR_ANY;      /* Autofill with my IP address */
-    server_addr.sin_port        = htons(CONFIG_VNC_SERVER_PORT);
-
-    /* Bind socket to local address */
-    if (bind(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
-        ESP_LOGE(TAG, "bind() VNC function failed");
-        exit(1);
-    }
-
-    /* Set the socket to listen for incoming connections */
-    if (listen(server_sock, BACKLOG) < 0) {
-        ESP_LOGE(TAG, "listen() VNC function failed");
-        exit(1);
-    }
-
-    do {
-	vnc_client_sock = (accept(server_sock, (struct sockaddr *) &client_addr, &client_addr_size));
-	if (vnc_client_sock >= 0) {
-	    vnc_client_connected = true;
-	    vnc_netconn_serve();
-	    vnc_client_connected = false;
-	}
-	vTaskDelay((TickType_t)10); /* allows the freeRTOS scheduler to take over if needed */
-    } while (vnc_client_sock >= 0);
-}
-
-
-
-/**
- * @brief Serve a new VNC client and handle the whole session.
- */
-void vnc_netconn_serve(void)
-{
-    long int			temp_long;
-    char 			protocol_ver[8], message_buffer[MESSAGE_BUFFER_SIZE];
-    int				i, j, message_len, ProtocolOkay;
-    uint32_t			*ptr_to_uint32;
-    uint16_t			*ptr_to_uint16;
-    struct sockaddr_storage	addr;
-    socklen_t			len = sizeof addr;
-    char			ipstr[INET6_ADDRSTRLEN];
-
-    getpeername(vnc_client_sock, (struct sockaddr*)&addr, &len);
-    if (addr.ss_family == AF_INET) {
-	struct sockaddr_in *s = (struct sockaddr_in *)&addr;
-	inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
-    }
-    ESP_LOGI(TAG, "VNC new client %s socket %d", ipstr, vnc_client_sock);
-
-    /* ProtocolVersion Handshake - begin */
-    /* Send ProtocolVersion we want to use to client */
-    message_len = sprintf(message_buffer, "RFB 003.003\n");
-    if (send(vnc_client_sock, message_buffer, message_len, 0) != message_len) {
-	goto close_connection;
-    }
-
-    /* Receive ProtocolVersion the client wants to use */
-    if (GetMessageData(vnc_client_sock, &(message_buffer[0]), 12) == 0) {
-	goto close_connection;
-    }
-
-    /* Check this is acceptable (RFB 003.xxx is okay) */
-    ProtocolOkay = 1;
-    for (i = 0; i < 8; i++) {
-	if (message_buffer[i] != server_ProtocolVersion[i]) {
-	    ProtocolOkay = 0;
-	}
-
-        /* Store the protocol version - ignoring thr 'RFB ' part */
-        protocol_ver[i] = message_buffer[i + 4];
-    }
-    protocol_ver[7] = 0;
-    /* ProtocolVersion Handshake - end */
-
-    /* Authentication - begin */
-    /* Send Authentication scheme to be used to client */
-    if (ProtocolOkay == 0) {
-	/* ProtocolVerion is not okay */
-
-	/* Generate the Bad ProtocolVerion message */
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[0]);
-	*ptr_to_uint32 = htonl(0);
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[4]);
-	*ptr_to_uint32 = htonl(strlen(bad_protocol));
-	strcpy(&(message_buffer[8]), bad_protocol);
-
-	if (send(vnc_client_sock, message_buffer, 8 + strlen(bad_protocol), 0) != (8 + strlen(bad_protocol))) {
-	    printf("Call to send() 1 failed\n");
-	}
-	goto close_connection;
-
-    } else if (VNC_WS_num != -1) {
-	/* Busy with a websocket client */
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[0]);
-	*ptr_to_uint32 = htonl(0);
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[4]);
-	*ptr_to_uint32 = htonl(strlen(server_busy));
-	strcpy(&(message_buffer[8]), server_busy);
-
-	if (send(vnc_client_sock, message_buffer, 8 + strlen(server_busy), 0) != (8 + strlen(server_busy))) {
-	    printf("Call to send() 1 failed\n");
-	}
-	goto close_connection;
-
-    } else {
-	/* ProtocolVerion is okay - connect with no authentication*/
-
-	/* Generate the No Authentication message */
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[0]);
-	*ptr_to_uint32 = htonl((uint32_t)1);
-
-	if (send(vnc_client_sock, message_buffer, 4, 0) != 4) {
-	    goto close_connection;
-	}
-    }
-    /* Authentication - end */
-
-    /* ClientInitialisation - begin */
-    /* Receive initialisation message from client (1 byte) */
-    if (GetMessageData(vnc_client_sock, &(message_buffer[0]), 1) == 0) {
-	goto close_connection;
-    }
-    /* Do nothing with this as we only support 1 Client at a time */
-    /* ClientInitialisation - end */
-
-    /* ServerInitialisation - begin */
-
-    /* Initial default RGB332 */
-    Red_Max     = RED_MAX;
-    Green_Max   = GREEN_MAX;
-    Blue_Max    = BLUE_MAX;
-    Red_Shift   = RED_SHIFT;
-    Green_Shift = GREEN_SHIFT;
-    Blue_Shift  = BLUE_SHIFT;
-    AltPixels   = false;
-
-    /* Create Initialisation message for client */
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[0]);
-    *ptr_to_uint16 = htons((uint16_t)CONFIG_VNC_SERVER_FRAME_WIDTH);
-
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[2]);
-    *ptr_to_uint16 = htons((uint16_t)CONFIG_VNC_SERVER_FRAME_HEIGHT);
-
-    message_buffer[4] = (uint8_t)BITS_PER_PIXEL;
-    message_buffer[5] = (uint8_t)PIXEL_DEPTH;
-    message_buffer[6] = (uint8_t)BIG_ENDIAN_FLAG;
-    message_buffer[7] = (uint8_t)TRUE_COLOUR_FLAG;
-
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[8]);
-    *ptr_to_uint16 = htons(Red_Max);
-
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[10]);
-    *ptr_to_uint16 = htons(Green_Max);
-
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[12]);
-    *ptr_to_uint16 = htons(Blue_Max);
-
-    message_buffer[14] = Red_Shift;
-    message_buffer[15] = Green_Shift;
-    message_buffer[16] = Blue_Shift;
-
-    ptr_to_uint32 = (uint32_t *) &(message_buffer[20]);
-    *ptr_to_uint32 = htonl(strlen(desktop_name));
-    strcpy(&(message_buffer[24]), desktop_name);
-
-    if (send(vnc_client_sock, message_buffer, 24 + strlen(desktop_name), 0) != (24 + strlen(desktop_name))) {
-	printf("Call to send() 3 failed\n");
-    }
-    /* ServerInitialisation - end */
-
-    /* Cancel any outstanding Sound Bell requests */
-    if (xSemaphoreTake(SoundBell_lock, 10) == pdTRUE) {
-	SoundBellCount = 0;
-	xSemaphoreGive(SoundBell_lock);
-    }
-
-    ESP_LOGI(TAG, "VNC client connected (RFB Protocol Ver: %s)", protocol_ver);
-
-    /* Main message handling loop */
-    while(1) {
-	int num_of_encodings;
-
-	/* Receive 1st byte of message from client */
-	if (GetMessageData(vnc_client_sock, &(message_buffer[0]), 1) == 0) {
-	    goto close_connection;	/* Connection lost */
-	}
-
-	switch(message_buffer[0]) {
-            case SET_PIXEL_FORMAT:
-
-                /* Get the remainder (19 bytes) of message */
-                if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 19) == 0) {
-                    goto close_connection;
-                }
-
-                /* Check pixel format is as expected */
-                i = 0;
-                if (message_buffer[4] != BITS_PER_PIXEL) {
-		    ESP_LOGI(TAG, "SetPixelFormat client wants %d bits-per-pixel", message_buffer[4]);
-                    i++;
-                }
-
-                if (message_buffer[5] != PIXEL_DEPTH) {
-		    ESP_LOGI(TAG, "SetPixelFormat client wants %d pixel-depth", message_buffer[5]);
-                    i++;
-                }
-
-                if ((message_buffer[7] & 0x01) != TRUE_COLOUR_FLAG) {
-		    ESP_LOGI(TAG, "SetPixelFormat client wants %d true-colour-flag", message_buffer[7]);
-                    i++;
-                }
-
-                ptr_to_uint16 = (uint16_t *)&(message_buffer[8]);
-                if (htons(*ptr_to_uint16) != Red_Max) {
-		    Red_Max = htons(*ptr_to_uint16);
-		    AltPixels = true;
-		    ESP_LOGI(TAG, "SetPixelFormat client granted %d red-max", Red_Max);
-                }
-
-                ptr_to_uint16 = (uint16_t *)&(message_buffer[10]);
-                if (htons(*ptr_to_uint16) != Green_Max) {
-		    Green_Max = htons(*ptr_to_uint16);
-		    AltPixels = true;
-		    ESP_LOGI(TAG, "SetPixelFormat client granted %d green-max", Green_Max);
-                }
-
-                ptr_to_uint16 = (uint16_t *)&(message_buffer[12]);
-                if (htons(*ptr_to_uint16) != Blue_Max) {
-		    Blue_Max = htons(*ptr_to_uint16);
-		    AltPixels = true;
-		    ESP_LOGI(TAG, "SetPixelFormat client granted %d blue-max", Blue_Max);
-                }
-
-                if (message_buffer[14] != Red_Shift) {
-		    Red_Shift = message_buffer[14];
-		    AltPixels = true;
-		    ESP_LOGI(TAG, "SetPixelFormat client granted %d red-shift", Red_Shift);
-                }
-
-                if (message_buffer[15] != Green_Shift) {
-		    Green_Shift = message_buffer[15];
-		    AltPixels = true;
-		    ESP_LOGI(TAG, "SetPixelFormat client granted %d green-shift", Green_Shift);
-                }
-
-                if (message_buffer[16] != Blue_Shift) {
-		    Blue_Shift = message_buffer[16];
-		    AltPixels = true;
-		    ESP_LOGI(TAG, "SetPixelFormat client granted %d blue-shift", Blue_Shift);
-                }
-
-                if (i) {
-		    ESP_LOGI(TAG, "SetPixelFormat %d errors, disconnect client", i);
-                     ESP_LOGI(TAG, "Ensure the 'Auto select' is not enabled in your vncviewer options,");
-                    goto close_connection_quietly;
-                }
-
-                break;
-
-            case FIX_COLOUR_MAP_ENTRIES:
-printf("fix colormap entries\n");
-                /* Not supported, just get the data from the buffer and ignore it */
-
-                /* Get the next 5 bytes of message */
-                if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 5) == 0) {
-                    goto close_connection;
-                }
-
-                /* Calculate how many colour entries are in the buffer */
-                i = message_buffer[4]*255 + message_buffer[5];
-                i *= 6;
-
-                /* Get this amount of data from the buffer */
-                for (j = 0; j < i; j++) {
-                    if (GetMessageData(vnc_client_sock, &(message_buffer[6]), 6) == 0) {
-                        goto close_connection;
-                    }
-                }
-
-                break;
-
-            case SET_ENCODINGS:
-
-                /* Get the next 3 bytes of message */
-                if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 3) == 0) {
-                    goto close_connection;
-                }
-
-                num_of_encodings = message_buffer[2]*255 + message_buffer[3];
-
-                /* Get the remainder of message */
-                if (GetMessageData(vnc_client_sock, &(message_buffer[0]), 4 * num_of_encodings) == 0) {
-                    goto close_connection;
-                }
-
-                /* Clear the encoding type structure */
-                encoding_type.raw = 0;
-                encoding_type.copy_rectangle = 0;
-                encoding_type.rre = 0;
-                encoding_type.corre = 0;
-                encoding_type.hextile = 0;
-
-                for (i = 0; i < num_of_encodings; i++) {
-                    switch(message_buffer[3 + (i*4)]) {
-                    case 0:  /* Raw encoding */
-                        encoding_type.raw = i + 1;
-                        break;
-                    case 1:  /* Copy rectangle encoding */
-                        encoding_type.copy_rectangle = i + 1;
-                        break;
-                    case 2:  /* RRE encoding */
-                        encoding_type.rre = i + 1;
-                        break;
-                    case 4:  /* CoRRE encoding */
-                        encoding_type.corre = i + 1;
-                        break;
-                    case 5:  /* Hextile encoding */
-                        encoding_type.hextile = i + 1;
-                        break;
-                    default:  /* Unknown coding type - do nothing */
-                        break;
-                    }
-                }
-                break;
-
-            case FRAME_BUFFER_UPDATE_REQ:
-                /* Get the remainder of message (9 bytes) */
-                if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 9) == 0) {
-                    goto close_connection;
-                }
-
-                if (!message_buffer[1]) {
-                    /* Non-incremental mode - mark the squares that need to be updated */
-                    for (i = (message_buffer[2]*255 + message_buffer[3])/TILE_SIZE;
-                         i <= (message_buffer[2]*255 + message_buffer[3] + message_buffer[6]*255 + message_buffer[7])/TILE_SIZE;
-                         i++) {
-                        for (j = (message_buffer[4]*255 + message_buffer[5])/TILE_SIZE;
-                             j <= (message_buffer[4]*255 + message_buffer[5] + message_buffer[8]*255 + message_buffer[9])/TILE_SIZE;
-                             j++) {
-                            tile_updated[j][i] = 1;
-                        }
-                    }
-                }
-
-                /* Signal that there is now a pending update request */
-                xEventGroupSetBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ);
-		break;
-
-            case KEY_EVENT:
-                /* Handle the key event, ignored for brewboard */
-                /* Get the remainder of message (7 bytes) */
-                if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 7) == 0) {
-                    goto close_connection;
-                }
-                break;
-
-            case POINTER_EVENT:
-                /* Handle the pointer event, simulate the touch screen. */
-                /* Get the remainder of message (5 bytes) */
-                if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 5) == 0) {
-                    goto close_connection;
-                }
-		/* Set global variables that will be read by another task. */
-		VNC_pointer_button = message_buffer[1];
-		VNC_pointer_x = message_buffer[2]*255 + message_buffer[3];
-		VNC_pointer_y = message_buffer[4]*255 + message_buffer[5];
-                break;
-
-            case CLIENT_CUT_TEXT:
-                /* Handle the client has cut text event */
-                /* Current we just get and discard the data */
-                /* Get the next 7 bytes of the message */
-                if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 7) == 0) {
-                    goto close_connection;
-                }
-
-                ptr_to_uint32 = (uint32_t *)&(message_buffer[4]);
-                temp_long = htonl(*ptr_to_uint32);
-
-                while (temp_long > 0) {
-                    /* Get the text in chunks MESSAGE_BUFFER_SIZE-1 characters */
-                    if (temp_long > MESSAGE_BUFFER_SIZE-2) {
-                        if (GetMessageData(vnc_client_sock, &(message_buffer[0]), MESSAGE_BUFFER_SIZE-1) == 0) {
-                            goto close_connection;
-                        }
-
-                        message_buffer[MESSAGE_BUFFER_SIZE-1] = 0;
-                        temp_long -= (MESSAGE_BUFFER_SIZE-1);
-                    } else {
-                        if (GetMessageData(vnc_client_sock, &(message_buffer[0]), temp_long) == 0) {
-                            goto close_connection;
-                        }
-
-                        message_buffer[temp_long] = 0;
-                        temp_long = 0;
-                    }
-                }
-
-                break;
-
-            default:
-		ESP_LOGI(TAG, "Unknown message %d from client", message_buffer[0]);
-        }
-
-	vTaskDelay( (TickType_t)1);
-    }
-
-close_connection:
-    ESP_LOGI(TAG, "VNC client disconnected");
-
-close_connection_quietly:
-
-    /* Cancel any outstanding update requests */
-    xEventGroupClearBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ);
-    close(vnc_client_sock);
-}
-
-
-
-/**
- * @brief Frame update task. This thread handles the sending of all frame
- *        update data to the client and sends the 'ring bell' message to
- *        the client when required.
- *        Works for VNC port connected clients and Websocket clients.
- * @param pvParameter Ignored
- */
-void task_frame(void *pvParameter)
-{
-    int			i, j, x_pos, y_pos, packet_length, num_updated_tiles;
-    uint16_t		*ptr_to_uint16;
-    /* These are declared static so they don't use thread stack memory */
-    static uint8_t	FramebufferUpdate_msg[4 + 12 + TILE_SIZE*TILE_SIZE*BITS_PER_PIXEL/8 + 1460];
-    static int		FrameBufferPtr;  /* Pointer to next space in buffer */
-    static int		tile_updated_local[NUM_TILES_Y_AXIS][NUM_TILES_X_AXIS];
-
-    ESP_LOGI(TAG, "Starting VNC frame updater");
-
-    while(1) {
-        /* Wait until client sends a frame update request */
-wait_for_client:
-	xEventGroupWaitBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ, pdFALSE, pdFALSE, portMAX_DELAY);
-
-        /* Copy tile_updated array to local version and clear copied tiles */
-	vTaskSuspendAll();
-        num_updated_tiles = 0;
-        for (i = 0; i < NUM_TILES_Y_AXIS; i++) {
-            for (j = 0; j < NUM_TILES_X_AXIS; j++) {
-                if (tile_updated[i][j]) {
-                    tile_updated_local[i][j] = 1;
-                    tile_updated[i][j] = 0;
-                    num_updated_tiles++;  /* Keep count of the updated tiles */
-                }
-            }
-        }
-	xTaskResumeAll();
-
-        if (num_updated_tiles) {
-	    /* Cancel update request */
-	    xEventGroupClearBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ);
-            /* Fill in constant parts of FramebufferUpdate Message */
-            FramebufferUpdate_msg[0] = 0;  /* Message-type */
-            FramebufferUpdate_msg[1] = 0;  /* Padding */
-            ptr_to_uint16 = (uint16_t *) &(FramebufferUpdate_msg[2]);
-            *ptr_to_uint16 = htons(num_updated_tiles);  /* Number-of-rectangles */
-            FrameBufferPtr = 4;
-
-            for (y_pos = 0; y_pos < NUM_TILES_Y_AXIS; y_pos++) {
-                for (x_pos = 0; x_pos < NUM_TILES_X_AXIS; x_pos++) {
-                    if (tile_updated_local[y_pos][x_pos]) {
-                        /* Send current square data to client */
-
-                        /* x-position */
-                        FramebufferUpdate_msg[FrameBufferPtr+0] = (x_pos * TILE_SIZE) / 256;
-                        FramebufferUpdate_msg[FrameBufferPtr+1] = (x_pos * TILE_SIZE) % 256;
-
-                        /* y-position */
-                        FramebufferUpdate_msg[FrameBufferPtr+2] = (y_pos * TILE_SIZE) / 256;
-                        FramebufferUpdate_msg[FrameBufferPtr+3] = (y_pos * TILE_SIZE) % 256;
-
-
-                        /* Set width of tile in packet */
-                        if (x_pos == (NUM_TILES_X_AXIS -1)) {
-                            /* Last tile in X-axis */
-                            FramebufferUpdate_msg[FrameBufferPtr+4] = LAST_TILE_WIDTH / 256;
-                            FramebufferUpdate_msg[FrameBufferPtr+5] = LAST_TILE_WIDTH % 256;
-                        } else {
-                            FramebufferUpdate_msg[FrameBufferPtr+4] = TILE_SIZE / 256;
-                            FramebufferUpdate_msg[FrameBufferPtr+5] = TILE_SIZE % 256;
-                        }
-
-                        if (y_pos == (NUM_TILES_Y_AXIS -1)) {
-                            /* Last tile in Y-axis */
-                            FramebufferUpdate_msg[FrameBufferPtr+6] = LAST_TILE_HEIGHT / 256;
-                            FramebufferUpdate_msg[FrameBufferPtr+7] = LAST_TILE_HEIGHT % 256;
-                        } else {
-                            FramebufferUpdate_msg[FrameBufferPtr+6] = TILE_SIZE / 256;
-                            FramebufferUpdate_msg[FrameBufferPtr+7] = TILE_SIZE % 256;
-                        }
-
-                        /* Generate the packet data for this tile */
-                        packet_length = GenTileUpdateData(&(FramebufferUpdate_msg[FrameBufferPtr]));
-
-                        /* Send the packet data for this tile to the client */
-                        FrameBufferPtr += packet_length;
-
-                        if (FrameBufferPtr > 1460) {
-                            /* Send the data to the client */
-			    if (VNC_WS_num != -1) {
-				ws_server_send_bin_client(VNC_WS_num, (char *)FramebufferUpdate_msg, FrameBufferPtr);
-			    }
-			    if (vnc_client_connected) {
-                            	if (send(vnc_client_sock, FramebufferUpdate_msg, FrameBufferPtr, 0) != FrameBufferPtr) {
-                            	    goto wait_for_client;
-                            	}
-			    }
-                            FrameBufferPtr = 0;
-                        }
-
-                        tile_updated_local[y_pos][x_pos] = 0;  /* Clear the update bit for this square */
-                    }
-                }
-            }
-
-            if (FrameBufferPtr > 0) {
-                /* Last data for this update, send it to the client */
-		if (VNC_WS_num != -1) {
-		    ws_server_send_bin_client(VNC_WS_num, (char *)FramebufferUpdate_msg, FrameBufferPtr);
-		}
-		if (vnc_client_connected) {
-                    if (send(vnc_client_sock, FramebufferUpdate_msg, FrameBufferPtr, 0) != FrameBufferPtr) {
-                    	goto wait_for_client;
-                    }
-		}
-
-                FrameBufferPtr = 0;
-            }
-
-        } else { /* if (num_updated_tiles) */
-            /* There was no new display data to send to the client */
-            /* Sleep for 1/20th second before checking again */
-	    vTaskDelay(20 / portTICK_PERIOD_MS);
-	}
-
-        /* Check for sound bell event */
-	if (xSemaphoreTake(SoundBell_lock, 10) == pdTRUE) {
-            if (SoundBellCount) {
-            	--SoundBellCount;
-		xSemaphoreGive(SoundBell_lock);
-
-		if (vnc_client_connected) {
-            	    if (send(vnc_client_sock, sound_bell, 1, 0) != 1) {
-                    	goto wait_for_client;
-            	    }
-		}
-		if (VNC_WS_num != -1) {
-		    ws_server_send_bin_client(VNC_WS_num, sound_bell, 1);
-		}
-            } else {
-	    	xSemaphoreGive(SoundBell_lock);
-	    }
-	}
-    }
-}
-
-
-
-/**
- * Convert a framebuffer pixel to BGR233 if needed.
- * @param pixel The 8 bit pixel value
- * @return Then unchanged or changed pixel.
- */
-vnc_color_t IRAM_ATTR PixelConvert(vnc_color_t pixel)
-{
-    if (!AltPixels)
-    	return pixel;
-
-    return (((pixel >> RED_SHIFT) & RED_MAX) << Red_Shift) | 
-	   (((pixel >> GREEN_SHIFT) & GREEN_MAX) << Green_Shift) | 
-	   (((pixel >> BLUE_SHIFT) & BLUE_MAX) << Blue_Shift);
-}
-
-
-
-/** 
- * @brief Generate tile update data function
- *
- *        This function is called by the frame_update thread to generate the message
- *        data for a tile to send to the client.  This function expects the
- *        x-position, y-position, width and height fields of the buffer to be filled
- *        in before it is called.
- *
- *        The format of the buffer is:
- *        packet_buffer[0:1] - x-position of tile
- *        packet_buffer[2:3] - y-position of tile
- *        packet_buffer[4:5] - width of tile
- *        packet_buffer[6:7] - height of tile
- *        packet_buffer[8 onwards] - Pixel data for the tile
- *
- *        The pixel data will be encoded with CoRRE encoding (if the CDL option is
- *        enabled and the client can handle it) or RAW encoding if that is smaller
- *        than CoRRE encoding for that particular tile.
- *
- * @param  packet_buffer  Buffer to store tile data
- * @return Length of generated data in bytes
- */
-static int GenTileUpdateData(uint8_t *packet_buffer)
-{
-    uint16_t		x_pos, y_pos;
-    int			i, j;
-    int			tile_width, tile_height;
-
-    /* Get the X and Y positions of this tile from the packet buffer */
-    x_pos = packet_buffer[0] * 256 + packet_buffer[1];
-    y_pos = packet_buffer[2] * 256 + packet_buffer[3];
-
-    /* Get the tile width and height from the packet buffer */
-    tile_width = packet_buffer[4] * 256 + packet_buffer[5];
-    tile_height = packet_buffer[6] * 256 + packet_buffer[7];
-
-    /* Create packet data using RAW encoding */
-    for (i = 0; i < tile_height; i++) {
-        for (j = 0; j < tile_width; j++) {
-	    if (Bits_Per_Pixel == 8) {
-             	packet_buffer[12 + tile_width * i + j] = PixelConvert(frame_buffer[y_pos + i][x_pos + j]);
-	    } else {
-		packet_buffer[12 + 2 * tile_width * i + 2*j]    = COLOUR2BYTE0(frame_buffer[y_pos + i][x_pos + j]);
-		packet_buffer[12 + 2 * tile_width * i + 2*j+ 1] = COLOUR2BYTE1(frame_buffer[y_pos + i][x_pos + j]);
-	    }
-        }
-    }
-
-    /* Set the encoding type to raw */
-    packet_buffer[8+0] = 0;
-    packet_buffer[8+1] = 0;
-    packet_buffer[8+2] = 0;
-    packet_buffer[8+3] = 0;
-
-    return (12 + tile_width*tile_height*(Bits_Per_Pixel/8));
-}
-
-
-
-/**
- * @brief Get message data function
- *        This function is called by the client_handler thread to get data
- *        from the client's socket.
- *
- * @param socket_fd    File descriptor of the socket to get the data from.
- * @param *buffer      Buffer to store received data in.
- * @param num_bytes    Number of bytes to attempt to get.
- *
- * @return  1 on sucessfull completion - 0 on error.
- */
-static int GetMessageData(int socket_fd, char *buffer, int num_bytes)
-{
-    int bytes_rxd;
-    int message_len = 0;
-
-    while (message_len < num_bytes) {
-        if ((bytes_rxd = recv(socket_fd, buffer, num_bytes, 0)) <= 0) {
-            return 0;
-        }
-        message_len += bytes_rxd;
-    }
-
-    return 1;
-}
-
-
-
-void VncCls(vnc_color_t color)
-{
-    /* Clear the frame buffer */
-    int i, j;
-
-    for (i = 0; i < CONFIG_VNC_SERVER_FRAME_HEIGHT; i++) {
-        for (j = 0; j < CONFIG_VNC_SERVER_FRAME_WIDTH; j++) {
-	    VncDrawPixel(j, i, color);
-        }
-    }
-}
-
-
-
-void IRAM_ATTR VncDrawPixel(uint16_t x, uint16_t y, vnc_color_t color)
-{
-    if (x >= CONFIG_VNC_SERVER_FRAME_WIDTH || y >= CONFIG_VNC_SERVER_FRAME_HEIGHT) {
-	printf("write_frame(%d, %d) tile %d/%d\n", x, y, x/TILE_SIZE, y/TILE_SIZE);
-	return;
-    }
-
-    /* Set that pixel to 'colour' */
-    frame_buffer[y][x] = color;
-
-    /* Mark the tile for update */
-    tile_updated[y/TILE_SIZE][x/TILE_SIZE] = 1;
-}
-
-
-
-void IRAM_ATTR VncDrawHorzLine(uint16_t x1, uint16_t x2, uint16_t y, vnc_color_t color)
-{
-    int i;
-
-    /* Draw the line */
-    for (i = x1; i <= x2; i++) {
-	VncDrawPixel(i, y, color);
-    }
-}
-
-
-
-void IRAM_ATTR VncDrawVertLine(uint16_t x, uint16_t y1, uint16_t y2, vnc_color_t color)
-{
-    int i;
-
-    /* Draw the line */
-    for (i = y1; i <= y2; i++) {
-	VncDrawPixel(x, i, color);
-    }
-}
-
-
-
-void IRAM_ATTR VncFillRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, vnc_color_t color)
-{
-    /* Draw a solid rectangle */
-    int i, j;
-
-    for (i = y1; i <= y2; i++) {
-        for (j = x1; j <= x2; j++) {
-	    VncDrawPixel(j, i, color);
-        }
-    }
-}
-
-
-
-void VncSoundBell(void)
-{
-    if (xSemaphoreTake(SoundBell_lock, 10) == pdTRUE) {
-    	SoundBellCount++;
-	xSemaphoreGive(SoundBell_lock);
-    }
-}
-
-
-
-/**
- * @brief Websocket task. Created on a websocket connection.
- */
-void task_WS(void *pvParameter)
-{
-    int			i, j, num_of_encodings;
-    uint16_t		*ptr_to_uint16;
-    struct strMessage   _msg;
-
-    VNC_WS_run = true;
-
-    while (VNC_WS_run) {
-
-	/*
-	 * Wait until something is received from the client. Exit the queue receiver
-	 * each 5 milliseconds to allow to evaluate the VNC_WS_run flag and to allow
-	 * a clean exit of this task.
-	 */
-	if (xQueueReceive(message_queue, &_msg, 5 / portTICK_PERIOD_MS) == pdTRUE) {
-
-	    switch (_msg.message[0]) {
-
-	    	case SET_PIXEL_FORMAT:
-		    /* Check total message length */
-		    if (_msg.length >= 20) {
-			/* Check pixel format is as expected */
-			i = 0;
-			if (_msg.message[4] != BITS_PER_PIXEL) {
-			    ESP_LOGI(TAG, "SetPixelFormat client wants %d bits-per-pixel", _msg.message[4]);
-			    i++;
-			}
-
-			if (_msg.message[5] != PIXEL_DEPTH) {
-			    ESP_LOGI(TAG, "SetPixelFormat client wants %d pixel-depth", _msg.message[5]);
-			    i++;
-			}
-
-			if ((_msg.message[7] & 0x01) != TRUE_COLOUR_FLAG) {
-			    ESP_LOGI(TAG, "SetPixelFormat client wants %d true-colour-flag", _msg.message[7]);
-			    i++;
-			}
-
-			ptr_to_uint16 = (uint16_t *)&(_msg.message[8]);
-			if (htons(*ptr_to_uint16) != Red_Max) {
-			    Red_Max = htons(*ptr_to_uint16);
-			    AltPixels = true;
-			    ESP_LOGI(TAG, "SetPixelFormat client granted %d red-max", Red_Max);
-			}
-
-			ptr_to_uint16 = (uint16_t *)&(_msg.message[10]);
-			if (htons(*ptr_to_uint16) != Green_Max) {
-			    Green_Max = htons(*ptr_to_uint16);
-			    AltPixels = true;
-			    ESP_LOGI(TAG, "SetPixelFormat client granted %d green-max", Green_Max);
-			}
-
-			ptr_to_uint16 = (uint16_t *)&(_msg.message[12]);
-			if (htons(*ptr_to_uint16) != Blue_Max) {
-			    Blue_Max = htons(*ptr_to_uint16);
-			    AltPixels = true;
-			    ESP_LOGI(TAG, "SetPixelFormat client granted %d blue-max", Blue_Max);
-			}
-
-			if (_msg.message[14] != Red_Shift) {
-			    Red_Shift = _msg.message[14];
-			    AltPixels = true;
-			    ESP_LOGI(TAG, "SetPixelFormat client granted %d red-shift", Red_Shift);
-			}
-
-			if (_msg.message[15] != Green_Shift) {
-			    Green_Shift = _msg.message[15];
-			    AltPixels = true;
-			    ESP_LOGI(TAG, "SetPixelFormat client granted %d green-shift", Green_Shift);
-			}
-
-			if (_msg.message[16] != Blue_Shift) {
-			    Blue_Shift = _msg.message[16];
-			    AltPixels = true;
-			    ESP_LOGI(TAG, "SetPixelFormat client granted %d blue-shift", Blue_Shift);
-			}
-
-			if (i) {
-			    ESP_LOGI(TAG, "SetPixelFormat %d errors, disconnect client", i);
-			    ESP_LOGI(TAG, "Ensure the 'Auto select' is not enabled in your vncviewer options,");
-			    _msg.length = 0;
-			    ws_server_remove_client(VNC_WS_num);
-			}
-		    }
-		    break;
-
-	    	case FIX_COLOUR_MAP_ENTRIES:
-		    printf("FIX_COLOUR_MAP_ENTRIES\n");
-		    break;
-
-	    	case SET_ENCODINGS:
-		    if (_msg.length >= 3) {
-			// Get the total encodings
-			num_of_encodings = _msg.message[2]*255 + _msg.message[3];
-
-			/* Clear the encoding type structure */
-			encoding_type.raw = 0;
-			encoding_type.copy_rectangle = 0;
-			encoding_type.rre = 0;
-			encoding_type.corre = 0;
-			encoding_type.hextile = 0;
-
-			for (i = 0; i < num_of_encodings; i++) {
-			    switch(_msg.message[3 + (i*4)]) {
-				case 0:  /* Raw encoding */
-					encoding_type.raw = i + 1;
-					break;
-				case 1:  /* Copy rectangle encoding */
-					encoding_type.copy_rectangle = i + 1;
-					break;
-				case 2:  /* RRE encoding */
-					encoding_type.rre = i + 1;
-					break;
-				case 4:  /* CoRRE encoding */
-					encoding_type.corre = i + 1;
-					break;
-				case 5:  /* Hextile encoding */
-					encoding_type.hextile = i + 1;
-					break;
-				default:  /* Unknown coding type - do nothing */
-					break;
-			    }
-			}
-		    }
-		    break;
-
-	    	case FRAME_BUFFER_UPDATE_REQ:
-		    if (_msg.length == 10) {
-			if (!_msg.message[1]) {
-			    /* Non-incremental mode - mark the squares that need to be updated */
-			    for (i = (_msg.message[2]*255 + _msg.message[3])/TILE_SIZE;
-				i <= (_msg.message[2]*255 + _msg.message[3] + _msg.message[6]*255 + _msg.message[7])/TILE_SIZE;
-				i++) {
-				for (j = (_msg.message[4]*255 + _msg.message[5])/TILE_SIZE;
-				    j <= (_msg.message[4]*255 + _msg.message[5] + _msg.message[8]*255 + _msg.message[9])/TILE_SIZE;
-				    j++) {
-					tile_updated[j][i] = 1;
-				}
-			    }
-			}
-
-			/* Signal that there is now a pending update request */
-			xEventGroupSetBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ);
-		    }
-		    break;
-
-	    	case KEY_EVENT:
-		    printf("KEY_EVENT\n");
-		    /* Handle the key event, ignored for brewboard */
-		    /* Get the remainder of message (7 bytes) */
-		    break;
-
-	    	case POINTER_EVENT:
-		    /* Handle the pointer event, simulate the touch screen. */
-		    if (_msg.length == 6) {
-			/* Set global variables that will be read by another task. */
-			VNC_pointer_button = _msg.message[1];
-			VNC_pointer_x = _msg.message[2]*255 + _msg.message[3];
-			VNC_pointer_y = _msg.message[4]*255 + _msg.message[5];
-		    }
-		    _msg.length = 0;
-		    break;
-
-	    	case CLIENT_CUT_TEXT:
-		    printf("CLIENT_CUT_TEXT\n");
-		    break;
-
-	    	default:
-		    ESP_LOGI(TAG, "Unknown message %d from client", _msg.message[0]);
-	    }
-	}
-    }
-
-    VNC_WS_num = -1;
-    xEventGroupClearBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ);
-    ESP_LOGI(TAG, "task_WS finished");
-    vTaskDelete(NULL);
-}
-
-
-
-int VncStartWS(int num)
-{
-    char		protocol_ver[8], message_buffer[MESSAGE_BUFFER_SIZE];
-    int			i, ProtocolOkay;
-    uint32_t		*ptr_to_uint32;
-    uint16_t		*ptr_to_uint16;
-    struct strMessage	_msg;
-
-    ESP_LOGI(TAG, "Start VNC WebSocket connection %d", num);
-    message_queue = xQueueCreate(message_queue_size, sizeof(struct strMessage));
-
-    /*
-     * Initial handshake
-     */
-    ws_server_send_bin_client(num, "RFB 003.003\n", 12);
-    ProtocolOkay = 1;
-    if (xQueueReceive(message_queue, &_msg, 5000 / portTICK_PERIOD_MS) == pdTRUE) {
-//	dump_msg((char *)_msg.message, _msg.length, "pull");
-
-	for (i = 0; i < 8; i++) {
-	    if (_msg.message[i] != server_ProtocolVersion[i]) {
-		ProtocolOkay = 0;
-	    }
-	    /* Store the protocol version - ignoring thr 'RFB ' part */
-	    protocol_ver[i] = _msg.message[i + 4];
-	}
-	protocol_ver[7] = 0;
-    } else {
-	ESP_LOGE(TAG, "Client timeout after initial message");
-	return -5;
-    }
-    
-    if (ProtocolOkay == 0) {
-	/* Generate the Bad ProtocolVerion message */
-	ESP_LOGI(TAG, "Start VNC WebSocket task failed, bad protocol.");
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[0]);
-	*ptr_to_uint32 = htonl(0);
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[4]);
-	*ptr_to_uint32 = htonl(strlen(bad_protocol));
-	strcpy(&(message_buffer[8]), bad_protocol);
-	ws_server_send_bin_client(num, message_buffer, 8 + strlen(bad_protocol));
-	vTaskDelay(500 / portTICK_PERIOD_MS);
-	ws_server_remove_client(num);
-	return -2;
-    }
-    /* ProtocolVerion is okay - connect with no authentication*/
-
-    /* Server is busy with another client */
-    if (VNC_WS_run || vnc_client_connected) {
-	ESP_LOGI(TAG, "Start VNC WebSocket task failed, server busy.");
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[0]);
-	*ptr_to_uint32 = htonl(0);
-	ptr_to_uint32 = (uint32_t *) &(message_buffer[4]);
-	*ptr_to_uint32 = htonl(strlen(server_busy));
-	strcpy(&(message_buffer[8]), server_busy);
-	ws_server_send_bin_client(num, message_buffer, 8 + strlen(server_busy));
-	vTaskDelay(500 / portTICK_PERIOD_MS);
-	ws_server_remove_client(num);
-	return -1;
-    }
-
-    /* Generate the No Authentication message */
-    ptr_to_uint32 = (uint32_t *) &(message_buffer[0]);
-    *ptr_to_uint32 = htonl((uint32_t)1);
-    ws_server_send_bin_client(num, message_buffer, 4);
-    /* Authentication - end */
-
-    /* ClientInitialisation - begin */
-    /* Receive initialisation message from client (1 byte) */
-    if (xQueueReceive(message_queue, &_msg, 5000 / portTICK_PERIOD_MS) == pdFALSE) {
-	ESP_LOGE(TAG, "Client timeout after auth message");
-	return -5;
-    }
-    /* Do nothing with this as we only support 1 Client at a time */
-    /* ClientInitialisation - end */
-
-    /* Initial default RGB332 */
-    Red_Max     = RED_MAX;
-    Green_Max   = GREEN_MAX;
-    Blue_Max    = BLUE_MAX;
-    Red_Shift   = RED_SHIFT;
-    Green_Shift = GREEN_SHIFT;
-    Blue_Shift  = BLUE_SHIFT;
-    AltPixels   = false;
-
-    /* ServerInitialisation - begin */
-    /* Create Initialisation message for client */
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[0]);
-    *ptr_to_uint16 = htons((uint16_t)CONFIG_VNC_SERVER_FRAME_WIDTH);
-
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[2]);
-    *ptr_to_uint16 = htons((uint16_t)CONFIG_VNC_SERVER_FRAME_HEIGHT);
-
-    message_buffer[4] = (uint8_t)BITS_PER_PIXEL;
-    message_buffer[5] = (uint8_t)PIXEL_DEPTH;
-    message_buffer[6] = (uint8_t)BIG_ENDIAN_FLAG;
-    message_buffer[7] = (uint8_t)TRUE_COLOUR_FLAG;
-
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[8]);
-    *ptr_to_uint16 = htons(Red_Max);
-
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[10]);
-    *ptr_to_uint16 = htons(Green_Max);
-
-    ptr_to_uint16 = (uint16_t *) &(message_buffer[12]);
-    *ptr_to_uint16 = htons(Blue_Max);
-
-    message_buffer[14] = Red_Shift;
-    message_buffer[15] = Green_Shift;
-    message_buffer[16] = Blue_Shift;
-
-    ptr_to_uint32 = (uint32_t *) &(message_buffer[20]);
-    *ptr_to_uint32 = htonl(strlen(desktop_name));
-    strcpy(&(message_buffer[24]), desktop_name);
-
-//  dump_msg(message_buffer, 24 + strlen(desktop_name), (char *)"send");
-    ws_server_send_bin_client(num, message_buffer, 24 + strlen(desktop_name));
-
-    /* ServerInitialisation - end */
-    ESP_LOGI(TAG, "VNC WebSocket client connected (RFB Protocol Ver: %s)", protocol_ver);
-
-    VNC_WS_num = num;
-    xTaskCreate(&task_WS, "WSclient",    MIN_STACK_SIZE, NULL, 5, &xTaskWSclient);
-    return 0;
-}
-
-
-
-void VncStopWS(int num)
-{
-    if (! VNC_WS_run) {
-	ESP_LOGI(TAG, "Stop VNC WebSocket, not running.");
-	return;
-    }
-
-    if (num != VNC_WS_num) {
-	ESP_LOGI(TAG, "Stop VNC WebSocket, %d is running, requested %d", VNC_WS_num, num);
-	return;
-    }
-
-    ESP_LOGI(TAG, "Stop VNC WebSocket task connection %d", num);
-    VNC_WS_run = false;
-    xQueueReset(message_queue);
-}
-
-
-
-void VncGetWSmessage(char *msg, uint16_t len)
-{
-    int			max;
-    struct strMessage	_msg;
- 
-    if (len == 0)
-	return;
-
-    max = len;
-    if (max > MESSAGE_BUFFER_SIZE) {
-	    ESP_LOGE(TAG, "VncGetWSmessage need %d bytes in a %d length buffer", len, MESSAGE_BUFFER_SIZE);
-	    max = MESSAGE_BUFFER_SIZE;
-    }
-
-    for (int i = 0; i < max; i++) {
-	    _msg.message[i] = msg[i];
-    }
-    _msg.length = max;
-    if (xQueueSendToBack(message_queue, &_msg, 200 / portTICK_PERIOD_MS) == pdFALSE) {
-	ESP_LOGE(TAG, "VncGetWSmessage() Queue full, message lost");
-    }
-}
-

mercurial