acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
VNC.cpp (52348B)
1 /* 2 * @file VNC.cpp 3 * @date 11.05.2015 4 * @author Markus Sattler 5 * 6 * Copyright (c) 2015 Markus Sattler. All rights reserved. 7 * This file is part of the VNC client for Arduino. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; version 2 of the License 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, a copy can be downloaded from 20 * http://www.gnu.org/licenses/gpl.html, or obtained by writing to the 21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301, USA. 23 * 24 * Thanks to all that worked on the original VNC implementation 25 * 26 */ 27 28 #pragma GCC optimize("O2") 29 30 #include <Arduino.h> 31 32 #include <stdio.h> 33 #include <unistd.h> 34 #include <inttypes.h> 35 #include <stdint.h> 36 #include <math.h> 37 38 #include "VNC.h" 39 40 extern "C" 41 { 42 #include "d3des.h" 43 } 44 45 #ifndef min 46 #define min(a, b) ((a) < (b) ? (a) : (b)) 47 #endif 48 49 #ifdef FPS_BENCHMARK 50 unsigned long connectionStart = 0; 51 uint32_t frames = 0; 52 size_t reads = 0; 53 #endif 54 55 //############################################################################################# 56 57 arduinoVNC::arduinoVNC(VNCdisplay *_display) 58 { 59 host = ""; 60 port = 5900; 61 display = _display; 62 opt = {0}; 63 sock = 0; 64 protocolMinorVersion = 3; 65 onlyFullUpdate = false; 66 } 67 68 arduinoVNC::~arduinoVNC(void) 69 { 70 TCPclient.stop(); 71 } 72 73 void arduinoVNC::begin(char *_host, uint16_t _port, bool _onlyFullUpdate) 74 { 75 host = _host; 76 port = _port; 77 78 #ifdef FPS_BENCHMARK 79 #ifdef FPS_BENCHMARK_FULL 80 onlyFullUpdate = true; 81 #else 82 onlyFullUpdate = false; 83 #endif 84 #else // !FPS_BENCHMARK 85 onlyFullUpdate = _onlyFullUpdate; 86 #endif // !FPS_BENCHMARK 87 88 opt.client.width = display->getWidth(); 89 opt.client.height = display->getHeight(); 90 91 opt.client.bpp = 16; 92 opt.client.depth = 16; 93 94 opt.client.bigendian = 0; 95 opt.client.truecolour = 1; 96 97 opt.client.redmax = 31; 98 opt.client.greenmax = 63; 99 opt.client.bluemax = 31; 100 101 opt.client.redshift = 11; 102 opt.client.greenshift = 5; 103 opt.client.blueshift = 0; 104 105 #ifdef VNC_COMPRESS_LEVEL 106 opt.client.compresslevel = VNC_COMPRESS_LEVEL; 107 #else 108 opt.client.compresslevel = 99; 109 #endif 110 opt.client.quality = 99; 111 112 opt.shared = 1; 113 opt.localcursor = 1; 114 115 opt.h_ratio = 1; 116 opt.v_ratio = 1; 117 opt.h_offset = 0; 118 opt.v_offset = 0; 119 120 display->vnc_options_override(&opt); 121 } 122 123 void arduinoVNC::begin(const char *_host, uint16_t _port, bool _onlyFullUpdate) 124 { 125 begin((char *)_host, _port, _onlyFullUpdate); 126 } 127 128 void arduinoVNC::begin(String _host, uint16_t _port, bool _onlyFullUpdate) 129 { 130 begin(_host.c_str(), _port, _onlyFullUpdate); 131 } 132 133 void arduinoVNC::setPassword(char *pass) 134 { 135 password = pass; 136 opt.password = (char *)password.c_str(); 137 } 138 139 void arduinoVNC::setPassword(const char *pass) 140 { 141 password = pass; 142 opt.password = (char *)password.c_str(); 143 } 144 145 void arduinoVNC::setPassword(String pass) 146 { 147 password = pass; 148 opt.password = (char *)password.c_str(); 149 } 150 151 void arduinoVNC::loop(void) 152 { 153 static uint16_t fails = 0; 154 static unsigned long lastUpdate = 0; 155 156 #ifdef ESP8266 157 if (WiFi.status() != WL_CONNECTED) 158 { 159 if (connected()) 160 { 161 disconnect(); 162 } 163 return; 164 } 165 #endif 166 167 if (!connected()) 168 { 169 DEBUG_VNC("!connected\n"); 170 if (!rfb_connect_to_server(host.c_str(), port)) 171 { 172 DEBUG_VNC("Couldnt establish connection with the VNC server. Exiting\n"); 173 delay(2000); 174 return; 175 } 176 177 /* initialize the connection */ 178 if (!rfb_initialise_connection()) 179 { 180 DEBUG_VNC("Connection with VNC server couldnt be initialized. Exiting\n"); 181 disconnect(); 182 delay(2000); 183 return; 184 } 185 186 /* Tell the VNC server which pixel format and encodings we want to use */ 187 if (!rfb_set_format_and_encodings()) 188 { 189 DEBUG_VNC("Error negotiating format and encodings. Exiting.\n"); 190 disconnect(); 191 delay(2000); 192 return; 193 } 194 195 #ifdef SET_DESKTOP_SIZE 196 /* set display resolution */ 197 if (!rfb_set_desktop_size()) 198 { 199 DEBUG_VNC("Error set desktop size. Exiting.\n"); 200 disconnect(); 201 delay(2000); 202 return; 203 } 204 #endif 205 206 /* calculate horizontal and vertical offset */ 207 if (opt.client.width > opt.server.width) 208 { 209 opt.h_offset = rint((opt.client.width - opt.server.width) / 2); 210 } 211 if (opt.client.height > opt.server.height) 212 { 213 opt.v_offset = rint((opt.client.height - opt.server.height) / 2); 214 } 215 216 mousestate.x = opt.client.width / 2; 217 mousestate.y = opt.client.height / 2; 218 219 // no scale support for embedded systems! 220 opt.h_ratio = 1; //(double) opt.client.width / (double) opt.server.width; 221 opt.v_ratio = 1; //(double) opt.client.height / (double) opt.server.height; 222 223 rfb_send_update_request(0); 224 // rfb_set_continuous_updates(1); 225 226 DEBUG_VNC("vnc_connect Done.\n"); 227 #ifdef FPS_BENCHMARK 228 connectionStart = millis(); 229 frames = 0; 230 #endif 231 #ifdef VNC_ZRLE 232 if (!zdict) 233 { 234 zdict = (uint8_t *)malloc(TDEFL_LZ_DICT_SIZE); 235 } 236 if (!zdict) 237 { 238 DEBUG_VNC("zdict malloc failed!\n"); 239 } 240 if (!zout_buffer) 241 { 242 zout_buffer = (uint8_t *)malloc(TDEFL_LZ_DICT_SIZE); 243 } 244 if (!zout_buffer) 245 { 246 DEBUG_VNC("zout_buffer malloc failed!\n"); 247 } 248 249 tinfl_init(&inflator); 250 // reset dict 251 memset(zdict, 0, TINFL_LZ_DICT_SIZE); 252 zdict_ofs = 0; 253 #endif // #ifdef VNC_ZRLE 254 } 255 else 256 { 257 if (!rfb_handle_server_message()) 258 { 259 DEBUG_VNC("rfb_handle_server_message faild.\n"); 260 return; 261 } 262 263 #ifdef MAXFPS 264 unsigned long currentMs = millis(); 265 if ((currentMs - lastUpdate) > (1000 / MAXFPS)) 266 { 267 if (rfb_send_update_request(onlyFullUpdate ? 0 : 1)) 268 { 269 lastUpdate = currentMs; 270 fails = 0; 271 } 272 else 273 { 274 fails++; 275 if (fails > 20) 276 { 277 disconnect(); 278 } 279 } 280 } 281 #else 282 if (rfb_send_update_request(onlyFullUpdate ? 0 : 1)) 283 { 284 fails = 0; 285 } 286 else 287 { 288 fails++; 289 if (fails > 20) 290 { 291 disconnect(); 292 } 293 } 294 #endif 295 } 296 #ifdef SLOW_LOOP 297 delay(SLOW_LOOP); 298 #endif 299 } 300 301 int arduinoVNC::forceFullUpdate(void) 302 { 303 return rfb_send_update_request(1); 304 } 305 306 void arduinoVNC::mouseEvent(uint16_t x, uint16_t y, uint8_t buttonMask) 307 { 308 mousestate.x = x; 309 mousestate.y = y; 310 mousestate.buttonmask = buttonMask; 311 rfb_update_mouse(); 312 } 313 314 void arduinoVNC::keyEvent(int key, int down_flag) 315 { 316 rfb_send_key_event(key, down_flag); 317 } 318 319 void arduinoVNC::reconnect(void) 320 { 321 // auto reconnect on next loop 322 disconnect(); 323 } 324 325 bool arduinoVNC::connected(void) 326 { 327 #ifdef ESP8266 328 return (TCPclient.status() == ESTABLISHED); 329 #else 330 return TCPclient.connected(); 331 #endif 332 } 333 334 //############################################################################################# 335 // TCP handling 336 //############################################################################################# 337 338 #ifdef USE_ARDUINO_TCP 339 340 bool arduinoVNC::read_from_rfb_server(int sock, char *out, size_t n) 341 { 342 #ifdef FPS_BENCHMARK 343 reads += n; 344 #endif 345 346 unsigned long t = millis(); 347 size_t len; 348 /* 349 DEBUG_VNC("read_from_rfb_server %d...\n", n); 350 351 if(n > 2 * 1024 * 1042) { 352 DEBUG_VNC("read_from_rfb_server N: %d 0x%08X make no sens!\n", n, n); 353 return 0; 354 } 355 356 if(out == NULL) { 357 DEBUG_VNC("read_from_rfb_server out == NULL!\n"); 358 return 0; 359 } 360 */ 361 #ifdef TCP_BUFFER_SIZE 362 if (n > TCP_BUFFER_SIZE) 363 { 364 if (buf_remain > 0) 365 { 366 memcpy(out, tcp_buffer + buf_idx, buf_remain); 367 n -= buf_remain; 368 out += buf_remain; 369 buf_idx = 0; 370 buf_remain = 0; 371 } 372 #endif // #ifdef TCP_BUFFER_SIZE 373 while (n > 0) 374 { 375 if (!connected()) 376 { 377 DEBUG_VNC("[read_from_rfb_server] not connected!\n"); 378 return false; 379 } 380 381 if ((millis() - t) > VNC_TCP_TIMEOUT) 382 { 383 DEBUG_VNC("[read_from_rfb_server] receive TIMEOUT!\n"); 384 return false; 385 } 386 387 if (!TCPclient.available()) 388 { 389 delay(0); 390 continue; 391 } 392 393 len = TCPclient.read((uint8_t *)out, n); 394 if (len) 395 { 396 t = millis(); 397 out += len; 398 n -= len; 399 // DEBUG_VNC("Receive %d left %d!\n", len, n); 400 } 401 else 402 { 403 // DEBUG_VNC("Receive %d left %d!\n", len, n); 404 } 405 delay(0); 406 } 407 #ifdef TCP_BUFFER_SIZE 408 } 409 else 410 { 411 while (buf_remain < n) 412 { 413 if (!connected()) 414 { 415 DEBUG_VNC("[read_from_rfb_server] not connected!\n"); 416 return false; 417 } 418 419 if ((millis() - t) > VNC_TCP_TIMEOUT) 420 { 421 DEBUG_VNC("[read_from_rfb_server] receive TIMEOUT!\n"); 422 return false; 423 } 424 425 if (!TCPclient.available()) 426 { 427 delay(0); 428 continue; 429 } 430 431 if (buf_remain > 0) 432 { 433 if (buf_idx > 0) 434 { 435 memcpy(tcp_buffer, tcp_buffer + buf_idx, buf_remain); 436 buf_idx = 0; 437 } 438 } 439 else 440 { 441 buf_idx = 0; 442 } 443 444 len = TCPclient.read(tcp_buffer + buf_remain, TCP_BUFFER_SIZE - buf_remain); 445 // DEBUG_VNC("[read_from_rfb_server] require: %d, receive: %d, buf_idx: %d, buf_remain: %d!\n", n, len, buf_idx, buf_remain); 446 buf_remain += len; 447 t = millis(); 448 delay(0); 449 } 450 451 // DEBUG_VNC("[read_from_rfb_server] memcpy, n: %d, buf_idx: %d, buf_remain: %d!\n", n, buf_idx, buf_remain); 452 memcpy(out, tcp_buffer + buf_idx, n); 453 buf_idx += n; 454 buf_remain -= n; 455 } 456 #endif // #ifdef TCP_BUFFER_SIZE 457 return true; 458 } 459 460 #ifdef VNC_ZRLE 461 bool arduinoVNC::read_from_z(uint8_t *out, size_t n) 462 { 463 while (zout_buf_remain < n) 464 { 465 if (zout_buf_remain > 0) 466 { 467 if (zout_buf_idx > 0) 468 { 469 memcpy(out, zout_buffer + zout_buf_idx, zout_buf_remain); 470 n -= zout_buf_remain; 471 out += zout_buf_remain; 472 zout_buf_remain = 0; 473 zout_buf_idx = 0; 474 } 475 } 476 else 477 { 478 zout_buf_idx = 0; 479 } 480 481 int flag = TINFL_FLAG_HAS_MORE_INPUT; 482 if (!header_inited) 483 { 484 flag |= TINFL_FLAG_PARSE_ZLIB_HEADER; 485 header_inited = true; 486 } 487 488 size_t in_buf_size = zin_buf_size - zin_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - zdict_ofs; 489 tinfl_decompress(&inflator, (const mz_uint8 *)zin_buffer + zin_buf_ofs, &in_buf_size, zdict, zdict + zdict_ofs, &dst_buf_size, flag); 490 zin_buf_ofs += in_buf_size; 491 memcpy(zout_buffer + zout_buf_idx, zdict + zdict_ofs, dst_buf_size); 492 493 zdict_ofs = (zdict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); 494 495 zout_buf_remain += dst_buf_size; 496 // DEBUG_VNC("[read_from_z] zin_buf_size: %d, zin_buf_ofs: %d, n: %d, zout_buf_idx: %d, zout_buf_remain: %d!\n", zin_buf_size, zin_buf_ofs, n, zout_buf_idx, zout_buf_remain); 497 } 498 499 memcpy(out, zout_buffer + zout_buf_idx, n); 500 zout_buf_idx += n; 501 zout_buf_remain -= n; 502 503 return true; 504 } 505 #endif // #ifdef VNC_ZRLE 506 507 bool arduinoVNC::write_exact(int sock, char *buf, size_t n) 508 { 509 if (!connected()) 510 { 511 DEBUG_VNC("[write_exact] not connected!\n"); 512 return false; 513 } 514 return (TCPclient.write((uint8_t *)buf, n) == n); 515 } 516 517 bool arduinoVNC::set_non_blocking(int sock) 518 { 519 #ifdef ESP8266 520 TCPclient.setNoDelay(true); 521 #endif 522 return true; 523 } 524 525 void arduinoVNC::disconnect(void) 526 { 527 DEBUG_VNC("[arduinoVNC] disconnect...\n"); 528 TCPclient.stop(); 529 } 530 531 #else // !USE_ARDUINO_TCP 532 #error implement TCP handling 533 #endif // !USE_ARDUINO_TCP 534 535 //############################################################################################# 536 // Connect to Server 537 //############################################################################################# 538 /* 539 * ConnectToRFBServer. 540 */ 541 bool arduinoVNC::rfb_connect_to_server(const char *host, int port) 542 { 543 #ifdef USE_ARDUINO_TCP 544 if (!TCPclient.connect(host, port)) 545 { 546 DEBUG_VNC("[rfb_connect_to_server] Connect error\n"); 547 return false; 548 } 549 550 DEBUG_VNC("[rfb_connect_to_server] Connected.\n"); 551 set_non_blocking(sock); 552 return true; 553 #else // !USE_ARDUINO_TCP 554 struct hostent *he = NULL; 555 int one = 1; 556 struct sockaddr_in s; 557 558 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 559 { 560 DEBUG_VNC("Error creating communication socket: %d\n", errno); 561 // exit(2) 562 return false; 563 } 564 565 /* if the server wasnt specified as an ip address, look it up */ 566 if (!inet_aton(host, &s.sin_addr)) 567 { 568 if ((he = gethostbyname(host))) 569 memcpy(&s.sin_addr.s_addr, he->h_addr, he->h_length); 570 else 571 { 572 DEBUG_VNC("Couldnt resolve host!\n"); 573 close(sock); 574 return false; 575 } 576 } 577 578 s.sin_port = htons(port); 579 s.sin_family = AF_INET; 580 581 if (connect(sock, (struct sockaddr *)&s, sizeof(s)) < 0) 582 { 583 DEBUG_VNC("Connect error\n"); 584 close(sock); 585 return false; 586 } 587 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) 588 { 589 DEBUG_VNC("Error setting socket options\n"); 590 close(sock); 591 return false; 592 } 593 594 if (!set_non_blocking(sock)) 595 return -1; 596 597 return (sock); 598 #endif // !USE_ARDUINO_TCP 599 } 600 601 bool arduinoVNC::rfb_initialise_connection() 602 { 603 if (!_rfb_negotiate_protocol()) 604 { 605 DEBUG_VNC("[rfb_initialise_connection] _rfb_negotiate_protocol() Faild!\n"); 606 return false; 607 } 608 609 if (!_rfb_authenticate()) 610 { 611 DEBUG_VNC("[rfb_initialise_connection] _rfb_authenticate() Faild!\n"); 612 return false; 613 } 614 615 if (!_rfb_initialise_client()) 616 { 617 DEBUG_VNC("[rfb_initialise_connection] _rfb_initialise_client() Faild!\n"); 618 return false; 619 } 620 621 if (!_rfb_initialise_server()) 622 { 623 DEBUG_VNC("[rfb_initialise_connection] _rfb_initialise_server() Faild!\n"); 624 return false; 625 } 626 627 return true; 628 } 629 630 bool arduinoVNC::_rfb_negotiate_protocol() 631 { 632 uint16_t server_major, server_minor; 633 634 rfbProtocolVersionMsg msg; 635 636 /* read the protocol version the server uses */ 637 if (!read_from_rfb_server(sock, (char *)&msg, sz_rfbProtocolVersionMsg)) 638 return false; 639 640 // RFB xxx.yyy 641 if (msg[0] != 'R' || msg[1] != 'F' || msg[2] != 'B' || msg[3] != ' ' || msg[7] != '.') 642 { 643 DEBUG_VNC("[_rfb_negotiate_protocol] Not a valid VNC server\n"); 644 return false; 645 } 646 msg[11] = 0x00; 647 648 DEBUG_VNC("[_rfb_negotiate_protocol] Server protocol: %s\n", msg); 649 650 char majorStr[4]{msg[4], msg[5], msg[6], 0x00}; 651 char minorStr[4]{msg[8], msg[9], msg[10], 0x00}; 652 653 server_major = atol((const char *)&majorStr); 654 server_minor = atol((const char *)&minorStr); 655 656 if (server_major == 3 && server_minor >= 8) 657 { 658 /* the server supports protocol 3.8 or higher version */ 659 protocolMinorVersion = 8; 660 } 661 else if (server_major == 3 && server_minor == 7) 662 { 663 /* the server supports protocol 3.7 */ 664 protocolMinorVersion = 7; 665 } 666 else 667 { 668 /* any other server version, request the standard 3.3 */ 669 protocolMinorVersion = 3; 670 } 671 672 /* send the protocol version we want to use */ 673 sprintf(msg, rfbProtocolVersionFormat, rfbProtocolMajorVersion, protocolMinorVersion); 674 675 DEBUG_VNC("[_rfb_negotiate_protocol] used protocol: %s\n", msg); 676 677 if (!write_exact(sock, msg, sz_rfbProtocolVersionMsg)) 678 { 679 return false; 680 } 681 682 return true; 683 } 684 685 bool arduinoVNC::_read_conn_failed_reason(void) 686 { 687 CARD32 reason_length; 688 CARD8 *reason_string; 689 DEBUG_VNC("[_read_conn_failed_reason] Connection to VNC server failed\n"); 690 691 if (!read_from_rfb_server(sock, (char *)&reason_length, sizeof(CARD32))) 692 { 693 return false; 694 } 695 696 reason_length = Swap32IfLE(reason_length); 697 reason_string = (CARD8 *)malloc(sizeof(CARD8) * reason_length); 698 699 if (!reason_string) 700 { 701 return false; 702 } 703 704 if (!read_from_rfb_server(sock, (char *)reason_string, reason_length)) 705 { 706 freeSec(reason_string); 707 return false; 708 } 709 710 DEBUG_VNC("[_read_conn_failed_reason] Errormessage: %s\n", reason_string); 711 freeSec(reason_string); 712 return true; 713 } 714 715 bool arduinoVNC::_read_authentication_result(void) 716 { 717 CARD32 auth_result; 718 if (!read_from_rfb_server(sock, (char *)&auth_result, 4)) 719 { 720 return false; 721 } 722 723 auth_result = Swap32IfLE(auth_result); 724 switch (auth_result) 725 { 726 case rfbAuthFailed: 727 DEBUG_VNC("Authentication Failed\n"); 728 return false; 729 case rfbAuthTooMany: 730 DEBUG_VNC("Too many connections\n"); 731 return false; 732 case rfbAuthOK: 733 DEBUG_VNC("Authentication OK\n"); 734 return true; 735 default: 736 DEBUG_VNC("Unknown result of authentication: 0x%08X (%d)\n", auth_result, auth_result); 737 return false; 738 } 739 } 740 741 bool arduinoVNC::_rfb_authenticate() 742 { 743 CARD32 authscheme; 744 CARD8 challenge_and_response[CHALLENGESIZE]; 745 746 if (protocolMinorVersion >= 7) 747 { 748 CARD8 secType = rfbSecTypeInvalid; 749 750 CARD8 nSecTypes; 751 CARD8 *secTypes; 752 753 CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth}; 754 uint8_t nKnownSecTypes = sizeof(knownSecTypes); 755 756 if (!read_from_rfb_server(sock, (char *)&nSecTypes, sizeof(nSecTypes))) 757 { 758 return false; 759 } 760 761 if (nSecTypes == 0) 762 { 763 if (!_read_conn_failed_reason()) 764 { 765 return false; 766 } 767 } 768 769 secTypes = (CARD8 *)malloc(nSecTypes); 770 771 if (!secTypes) 772 { 773 return false; 774 } 775 776 if (!read_from_rfb_server(sock, (char *)secTypes, nSecTypes)) 777 { 778 freeSec(secTypes); 779 return false; 780 } 781 if (secType == rfbSecTypeInvalid) 782 { 783 // use first supported security type 784 for (uint8_t x = 0; x < nSecTypes; x++) 785 { 786 for (uint8_t i = 0; i < nKnownSecTypes; i++) 787 { 788 if (secTypes[x] == knownSecTypes[i]) 789 { 790 secType = secTypes[x]; 791 break; 792 } 793 } 794 if (secType != rfbSecTypeInvalid) 795 { 796 break; 797 } 798 } 799 } 800 801 freeSec(secTypes); 802 803 if (!write_exact(sock, (char *)&secType, sizeof(secType))) 804 { 805 return false; 806 } 807 808 if (secType == rfbSecTypeInvalid) 809 { 810 DEBUG_VNC("Server did not offer supported security type\n"); 811 } 812 813 authscheme = secType; 814 } 815 else 816 { 817 // protocol Minor < 7 818 if (!read_from_rfb_server(sock, (char *)&authscheme, 4)) 819 { 820 return false; 821 } 822 authscheme = Swap32IfLE(authscheme); 823 if (authscheme == rfbSecTypeInvalid) 824 { 825 if (!_read_conn_failed_reason()) 826 { 827 return false; 828 } 829 } 830 } 831 832 switch (authscheme) 833 { 834 case rfbSecTypeInvalid: 835 return false; 836 break; 837 case rfbSecTypeNone: 838 if (protocolMinorVersion >= 8) 839 { 840 return _read_authentication_result(); 841 } 842 return true; 843 break; 844 case rfbSecTypeTight: 845 return false; 846 break; 847 case rfbSecTypeVncAuth: 848 849 if (!opt.password || *(opt.password) == 0x00) 850 { 851 DEBUG_VNC("Server ask for password? but no Password is set.\n"); 852 return false; 853 } 854 855 if (!read_from_rfb_server(sock, (char *)challenge_and_response, CHALLENGESIZE)) 856 { 857 return false; 858 } 859 860 vncEncryptBytes(challenge_and_response, opt.password); 861 if (!write_exact(sock, (char *)challenge_and_response, CHALLENGESIZE)) 862 { 863 return false; 864 } 865 return _read_authentication_result(); 866 break; 867 } 868 869 return false; 870 } 871 872 bool arduinoVNC::_rfb_initialise_client() 873 { 874 rfbClientInitMsg cl; 875 cl.shared = opt.shared; 876 if (!write_exact(sock, (char *)&cl, sz_rfbClientInitMsg)) 877 { 878 return false; 879 } 880 881 return true; 882 } 883 884 bool arduinoVNC::_rfb_initialise_server() 885 { 886 int len; 887 rfbServerInitMsg si; 888 889 if (!read_from_rfb_server(sock, (char *)&si, sz_rfbServerInitMsg)) 890 { 891 return false; 892 } 893 894 opt.server.width = Swap16IfLE(si.framebufferWidth); 895 opt.server.height = Swap16IfLE(si.framebufferHeight); 896 897 // never be bigger then the client! 898 opt.server.width = min(opt.client.width, opt.server.width); 899 opt.server.height = min(opt.client.height, opt.server.height); 900 901 opt.server.bpp = si.format.bitsPerPixel; 902 opt.server.depth = si.format.depth; 903 opt.server.bigendian = si.format.bigEndian; 904 opt.server.truecolour = si.format.trueColour; 905 906 opt.server.redmax = Swap16IfLE(si.format.redMax); 907 opt.server.greenmax = Swap16IfLE(si.format.greenMax); 908 opt.server.bluemax = Swap16IfLE(si.format.blueMax); 909 opt.server.redshift = si.format.redShift; 910 opt.server.greenshift = si.format.greenShift; 911 opt.server.blueshift = si.format.blueShift; 912 913 len = Swap32IfLE(si.nameLength); 914 opt.server.name = (char *)malloc(sizeof(char) * len + 1); 915 916 if (!read_from_rfb_server(sock, opt.server.name, len)) 917 { 918 return false; 919 } 920 opt.server.name[len] = 0x00; 921 922 DEBUG_VNC("[VNC-SERVER] VNC Server config - Name: %s\n", opt.server.name); 923 DEBUG_VNC(" - width:%d height:%d\n", Swap16IfLE(si.framebufferWidth), Swap16IfLE(si.framebufferHeight)); 924 DEBUG_VNC(" - bpp:%d depth:%d bigendian:%d truecolor:%d\n", opt.server.bpp, opt.server.depth, opt.server.bigendian, opt.server.truecolour); 925 DEBUG_VNC(" - redmax:%d greenmax:%d bluemax:%d\n", opt.server.redmax, opt.server.greenmax, opt.server.bluemax); 926 DEBUG_VNC(" - redshift:%d greenshift:%d blueshift:%d\n", opt.server.redshift, opt.server.greenshift, opt.server.blueshift); 927 return true; 928 } 929 930 //############################################################################################# 931 // Connection handling 932 //############################################################################################# 933 934 bool arduinoVNC::rfb_set_format_and_encodings() 935 { 936 uint8_t num_enc = 0; 937 rfbSetPixelFormatMsg pf; 938 rfbSetEncodingsMsg em; 939 CARD32 enc[MAX_ENCODINGS]; 940 941 pf.type = rfbSetPixelFormat; 942 pf.format.bitsPerPixel = opt.client.bpp; 943 pf.format.depth = opt.client.depth; 944 pf.format.bigEndian = opt.client.bigendian; 945 pf.format.trueColour = opt.client.truecolour; 946 pf.format.redMax = Swap16IfLE(opt.client.redmax); 947 pf.format.greenMax = Swap16IfLE(opt.client.greenmax); 948 pf.format.blueMax = Swap16IfLE(opt.client.bluemax); 949 pf.format.redShift = opt.client.redshift; 950 pf.format.greenShift = opt.client.greenshift; 951 pf.format.blueShift = opt.client.blueshift; 952 953 if (!write_exact(sock, (char *)&pf, sz_rfbSetPixelFormatMsg)) 954 { 955 return false; 956 } 957 958 em.type = rfbSetEncodings; 959 960 DEBUG_VNC("[VNC-CLIENT] Supported Encodings:\n"); 961 #ifdef VNC_ZRLE 962 enc[num_enc++] = Swap32IfLE(rfbEncodingZRLE); 963 DEBUG_VNC(" - ZRLE\n"); 964 #endif 965 #ifdef VNC_HEXTILE 966 enc[num_enc++] = Swap32IfLE(rfbEncodingHextile); 967 DEBUG_VNC(" - Hextile\n"); 968 #endif 969 970 if (display->hasCopyRect()) 971 { 972 enc[num_enc++] = Swap32IfLE(rfbEncodingCopyRect); 973 DEBUG_VNC(" - CopyRect\n"); 974 } 975 976 #ifdef VNC_RRE 977 enc[num_enc++] = Swap32IfLE(rfbEncodingRRE); 978 DEBUG_VNC(" - RRE\n"); 979 #endif 980 #ifdef VNC_CORRE 981 enc[num_enc++] = Swap32IfLE(rfbEncodingCoRRE); 982 DEBUG_VNC(" - CoRRE\n"); 983 #endif 984 985 enc[num_enc++] = Swap32IfLE(rfbEncodingRaw); 986 DEBUG_VNC(" - Raw\n"); 987 988 DEBUG_VNC("[VNC-CLIENT] Supported Special Encodings:\n"); 989 990 #ifdef SET_DESKTOP_SIZE 991 enc[num_enc++] = Swap32IfLE(rfbEncodingNewFBSize); 992 DEBUG_VNC(" - SetDesktopSize\n"); 993 #endif 994 995 enc[num_enc++] = Swap32IfLE(rfbEncodingPointerPos); 996 DEBUG_VNC(" - CursorPos\n"); 997 998 // enc[num_enc++] = Swap32IfLE(rfbEncodingLastRect); 999 // DEBUG_VNC(" - LastRect\n"); 1000 1001 enc[num_enc++] = Swap32IfLE(rfbEncodingContinuousUpdates); 1002 DEBUG_VNC(" - ContinuousUpdates\n"); 1003 1004 if (opt.client.compresslevel <= 9) 1005 { 1006 enc[num_enc++] = Swap32IfLE(rfbEncodingCompressLevel0 + opt.client.compresslevel); 1007 DEBUG_VNC(" - compresslevel: %d\n", opt.client.compresslevel); 1008 } 1009 if (opt.client.quality <= 9) 1010 { 1011 enc[num_enc++] = Swap32IfLE(rfbEncodingQualityLevel0 + opt.client.quality); 1012 DEBUG_VNC(" - quality: %d\n", opt.client.quality); 1013 } 1014 1015 em.nEncodings = Swap16IfLE(num_enc); 1016 1017 if (!write_exact(sock, (char *)&em, sz_rfbSetEncodingsMsg)) 1018 { 1019 return false; 1020 } 1021 1022 if (!write_exact(sock, (char *)&enc, num_enc * 4)) 1023 { 1024 return false; 1025 } 1026 1027 DEBUG_VNC("[VNC-CLIENT] Client pixel format:\n"); 1028 DEBUG_VNC(" - width:%d height:%d\n", opt.client.width, opt.client.height); 1029 DEBUG_VNC(" - bpp:%d depth:%d bigEndian:%d trueColor:%d\n", opt.client.bpp, opt.client.depth, opt.client.bigendian, opt.client.truecolour); 1030 DEBUG_VNC(" - red-max:%d green-max:%d blue-max:%d\n", opt.client.redmax, opt.client.greenmax, opt.client.bluemax); 1031 DEBUG_VNC(" - red-shift:%d green-shift:%d blue-shift:%d\n", opt.client.redshift, opt.client.greenshift, opt.client.blueshift); 1032 1033 return true; 1034 } 1035 1036 #ifdef SET_DESKTOP_SIZE 1037 bool arduinoVNC::rfb_set_desktop_size() 1038 { 1039 uint16_t w = opt.client.width; 1040 uint16_t h = opt.client.height; 1041 1042 // override server resolution 1043 opt.server.width = w; 1044 opt.server.height = h; 1045 1046 w = Swap16IfLE(w); 1047 h = Swap16IfLE(h); 1048 rfbSetDesktopSizeMsg ds; 1049 ds.type = rfbSetDesktopSize; 1050 ds.pad1 = 0; 1051 ds.width = w; 1052 ds.height = h; 1053 ds.numScreens = 1; 1054 ds.pad2 = 0; 1055 ds.layoutId = 1; 1056 ds.layoutX = 0; 1057 ds.layoutY = 0; 1058 ds.layoutWidth = w; 1059 ds.layoutHeight = h; 1060 ds.layoutFlag = 0; 1061 1062 if (!write_exact(sock, (char *)&ds, sz_rfbSetDesktopSizeMsg)) 1063 { 1064 return false; 1065 } 1066 1067 return true; 1068 } 1069 #endif 1070 1071 bool arduinoVNC::rfb_send_update_request(int incremental) 1072 { 1073 rfbFramebufferUpdateRequestMsg urq = {0}; 1074 1075 urq.type = rfbFramebufferUpdateRequest; 1076 urq.incremental = incremental; 1077 urq.x = 0; 1078 urq.y = 0; 1079 urq.w = opt.server.width; 1080 urq.h = opt.server.height; 1081 1082 urq.x = Swap16IfLE(urq.x); 1083 urq.y = Swap16IfLE(urq.y); 1084 urq.w = Swap16IfLE(urq.w); 1085 urq.h = Swap16IfLE(urq.h); 1086 1087 if (!write_exact(sock, (char *)&urq, sz_rfbFramebufferUpdateRequestMsg)) 1088 { 1089 DEBUG_VNC("[rfb_send_update_request] write_exact failed!\n"); 1090 return false; 1091 } 1092 1093 return true; 1094 } 1095 1096 bool arduinoVNC::rfb_set_continuous_updates(bool enable) 1097 { 1098 rfbEnableContinuousUpdatesMsg urq = {0}; 1099 1100 urq.type = rfbEnableContinuousUpdates; 1101 urq.enable = enable; 1102 urq.x = 0; 1103 urq.y = 0; 1104 urq.w = opt.server.width; 1105 urq.h = opt.server.height; 1106 1107 urq.x = Swap16IfLE(urq.x); 1108 urq.y = Swap16IfLE(urq.y); 1109 urq.w = Swap16IfLE(urq.w); 1110 urq.h = Swap16IfLE(urq.h); 1111 1112 if (!write_exact(sock, (char *)&urq, sz_rfbEnableContinuousUpdatesMsg)) 1113 { 1114 DEBUG_VNC("[rfb_set_continuous_updates] write_exact failed!\n"); 1115 return false; 1116 } 1117 1118 return true; 1119 } 1120 1121 bool arduinoVNC::rfb_handle_server_message() 1122 { 1123 rfbServerToClientMsg msg = {0}; 1124 rfbFramebufferUpdateRectHeader rectheader = {0}; 1125 1126 if (TCPclient.available()) 1127 { 1128 if (!read_from_rfb_server(sock, (char *)&msg, 1)) 1129 { 1130 return false; 1131 } 1132 switch (msg.type) 1133 { 1134 case rfbFramebufferUpdate: 1135 read_from_rfb_server(sock, ((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1); 1136 msg.fu.nRects = Swap16IfLE(msg.fu.nRects); 1137 for (uint16_t i = 0; i < msg.fu.nRects; i++) 1138 { 1139 read_from_rfb_server(sock, (char *)&rectheader, 1140 sz_rfbFramebufferUpdateRectHeader); 1141 uint16_t x = Swap16IfLE(rectheader.r.x); 1142 uint16_t y = Swap16IfLE(rectheader.r.y); 1143 uint16_t w = Swap16IfLE(rectheader.r.w); 1144 uint16_t h = Swap16IfLE(rectheader.r.h); 1145 uint32_t encoding = Swap32IfLE(rectheader.encoding); 1146 // SoftCursorLockArea(x, y, w, h); 1147 1148 #ifdef FPS_BENCHMARK 1149 unsigned long encodingStart = micros(); 1150 reads = 0; 1151 #endif 1152 bool encodingResult = false; 1153 // wdt_disable(); 1154 switch (encoding) 1155 { 1156 case rfbEncodingRaw: 1157 encodingResult = _handle_raw_encoded_message(x, y, w, h); 1158 break; 1159 case rfbEncodingCopyRect: 1160 encodingResult = _handle_copyrect_encoded_message(x, y, w, h); 1161 break; 1162 #ifdef VNC_RRE 1163 case rfbEncodingRRE: 1164 encodingResult = _handle_rre_encoded_message(x, y, w, h); 1165 break; 1166 #endif 1167 #ifdef VNC_CORRE 1168 case rfbEncodingCoRRE: 1169 encodingResult = _handle_corre_encoded_message(x, y, w, h); 1170 break; 1171 #endif 1172 #ifdef VNC_HEXTILE 1173 case rfbEncodingHextile: 1174 encodingResult = _handle_hextile_encoded_message(x, y, w, h); 1175 break; 1176 #endif 1177 #ifdef VNC_ZRLE 1178 case rfbEncodingZRLE: 1179 encodingResult = _handle_zrle_encoded_message(x, y, w, h); 1180 break; 1181 #endif 1182 case rfbEncodingPointerPos: 1183 encodingResult = _handle_cursor_pos_message(x, y, w, h); 1184 break; 1185 case rfbEncodingContinuousUpdates: 1186 encodingResult = _handle_server_continuous_updates_message(x, y, w, h); 1187 break; 1188 case rfbEncodingLastRect: 1189 DEBUG_VNC("[rfbEncodingLastRect] LAST\n"); 1190 encodingResult = true; 1191 break; 1192 #ifdef SET_DESKTOP_SIZE 1193 case rfbEncodingNewFBSize: 1194 DEBUG_VNC("[rfbEncodingNewFBSize]\n"); 1195 encodingResult = true; 1196 break; 1197 #endif 1198 default: 1199 DEBUG_VNC("Unknown encoding 0x%08X %d\n", encoding, encoding); 1200 break; 1201 } 1202 1203 display->flush(); 1204 1205 #ifdef FPS_BENCHMARK 1206 unsigned long encodingTime = micros() - encodingStart; 1207 double fps = ((double)(1 * 1000 * 1000) / (double)encodingTime); 1208 double bps = (((double)reads) * 1000 * 1000) / ((double)encodingTime); 1209 if (reads > 1024) // skip minor update 1210 { 1211 frames++; 1212 double avg = ((double)frames) * 1000 / ((double)(millis() - connectionStart)); 1213 #ifdef ESP32 1214 DEBUG_VNC("[Benchmark][0x%08X][%d] \tus: %lu \tfps: %s \tAvg: %s \tBytes: %d \tbps: %s \tHeap: %d\n", encoding, encoding, encodingTime, String(fps, 2).c_str(), String(avg, 2).c_str(), reads, String(bps, 2).c_str(), ESP.getFreeHeap()); 1215 #elif defined(ARDUINO_RASPBERRY_PI_PICO_W) 1216 DEBUG_VNC("[Benchmark][0x%08X][%d] \tus: %d \tfps: %s \tAvg: %s \tBytes: %d \tbps: %s\n", encoding, encoding, encodingTime, String(fps, 2).c_str(), String(avg, 2).c_str(), reads, String(bps, 2).c_str()); 1217 #else 1218 DEBUG_VNC("[Benchmark][0x%08X][%d] \tus: %d \tfps: %d \tAvg: %d \tBytes: %d \tbps: %d\n", encoding, encoding, encodingTime, (int)fps, (int)avg, reads, (int)bps); 1219 #endif 1220 } 1221 #endif 1222 // wdt_enable(0); 1223 if (!encodingResult) 1224 { 1225 DEBUG_VNC("[0x%08X][%d] encoding Faild!\n", encoding, encoding); 1226 disconnect(); 1227 delay(2000); 1228 return false; 1229 } 1230 else 1231 { 1232 // DEBUG_VNC("[0x%08X] encoding ok!\n", encoding); 1233 } 1234 1235 /* Now we may discard "soft cursor locks". */ 1236 // SoftCursorUnlockScreen(); 1237 } 1238 break; 1239 case rfbSetColourMapEntries: 1240 DEBUG_VNC("SetColourMapEntries\n"); 1241 read_from_rfb_server(sock, ((char *)&msg.scme) + 1, sz_rfbSetColourMapEntriesMsg - 1); 1242 break; 1243 case rfbBell: 1244 DEBUG_VNC("Bell message. Unimplemented.\n"); 1245 break; 1246 case rfbServerCutText: 1247 if (!_handle_server_cut_text_message(&msg)) 1248 { 1249 disconnect(); 1250 delay(2000); 1251 return false; 1252 } 1253 break; 1254 default: 1255 DEBUG_VNC("Unknown server message. Type: %d\n", msg.type); 1256 disconnect(); 1257 delay(2000); 1258 return false; 1259 break; 1260 } 1261 } 1262 return true; 1263 } 1264 1265 bool arduinoVNC::rfb_update_mouse() 1266 { 1267 rfbPointerEventMsg msg; 1268 1269 if (mousestate.x < 0) 1270 mousestate.x = 0; 1271 if (mousestate.y < 0) 1272 mousestate.y = 0; 1273 1274 if (mousestate.x > opt.client.width) 1275 mousestate.x = opt.client.width; 1276 if (mousestate.y > opt.client.height) 1277 mousestate.y = opt.client.height; 1278 1279 msg.type = rfbPointerEvent; 1280 msg.buttonMask = mousestate.buttonmask; 1281 1282 /* scale to server resolution */ 1283 msg.x = mousestate.x; // rint(mousestate.x * opt.h_ratio); 1284 msg.y = mousestate.y; // rint(mousestate.y * opt.v_ratio); 1285 1286 msg.x = Swap16IfLE(msg.x); 1287 msg.y = Swap16IfLE(msg.y); 1288 1289 return (write_exact(sock, (char *)&msg, sz_rfbPointerEventMsg)); 1290 } 1291 1292 bool arduinoVNC::rfb_send_key_event(int key, int down_flag) 1293 { 1294 rfbKeyEventMsg ke; 1295 1296 ke.type = rfbKeyEvent; 1297 ke.down = down_flag; 1298 ke.key = Swap32IfLE(key); 1299 1300 return (write_exact(sock, (char *)&ke, sz_rfbKeyEventMsg)); 1301 } 1302 1303 //############################################################################################# 1304 // Encode handling 1305 //############################################################################################# 1306 1307 bool arduinoVNC::_handle_server_cut_text_message(rfbServerToClientMsg *msg) 1308 { 1309 DEBUG_VNC_HANDLE("[_handle_server_cut_text_message] work...\n"); 1310 1311 CARD32 size; 1312 1313 if (!read_from_rfb_server(sock, ((char *)&msg->sct) + 1, sz_rfbServerCutTextMsg - 1)) 1314 { 1315 return false; 1316 } 1317 size = Swap32IfLE(msg->sct.length); 1318 1319 DEBUG_VNC("[_handle_server_cut_text_message] size: %d\n", size); 1320 1321 if (!read_from_rfb_server(sock, raw_buffer, size)) 1322 { 1323 return false; 1324 } 1325 1326 raw_buffer[size] = 0; 1327 1328 DEBUG_VNC("[_handle_server_cut_text_message] msg: %s\n", raw_buffer); 1329 1330 return true; 1331 } 1332 1333 bool arduinoVNC::_handle_raw_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1334 { 1335 DEBUG_VNC_HANDLE("[_handle_raw_encoded_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1336 1337 uint16_t max_h = maxSize / 2 / w; 1338 if (max_h == 0) 1339 { 1340 DEBUG_VNC("[_handle_raw_encoded_message] w too large: %d! Please increase VNC_RAW_BUFFER in VNC_config.h\n", w); 1341 } 1342 uint16_t sub_h = min(max_h, h); 1343 while (h) 1344 { 1345 if (h < sub_h) 1346 { 1347 sub_h = h; 1348 } 1349 if (!_handle_raw_encoded_message_core(x, y, w, sub_h)) 1350 { 1351 return false; 1352 } 1353 h -= sub_h; 1354 y += sub_h; 1355 } 1356 return true; 1357 } 1358 1359 bool arduinoVNC::_handle_raw_encoded_message_core(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1360 { 1361 uint32_t msgPixelTotal = (w * h); 1362 uint32_t msgPixel = msgPixelTotal; 1363 uint32_t msgSize = (msgPixel * 2); 1364 1365 DEBUG_VNC_RAW("[_handle_raw_encoded_message_core] x: %d y: %d w: %d h: %d msgSize: %d!\n", x, y, w, h, msgSize); 1366 1367 char *p = raw_buffer; 1368 while (msgPixelTotal) 1369 { 1370 DEBUG_VNC_RAW("[_handle_raw_encoded_message_core] Pixel left: %d\n", msgPixelTotal); 1371 1372 if (msgPixelTotal < msgPixel) 1373 { 1374 msgPixel = msgPixelTotal; 1375 msgSize = (msgPixel * (opt.client.bpp / 8)); 1376 } 1377 1378 if (!read_from_rfb_server(sock, p, msgSize)) 1379 { 1380 return false; 1381 } 1382 1383 msgPixelTotal -= msgPixel; 1384 p += msgPixel; 1385 delay(0); 1386 } 1387 1388 display->draw_area(x, y, w, h, (uint8_t *)raw_buffer); 1389 1390 DEBUG_VNC_RAW("[_handle_raw_encoded_message_core] ------------------------ Fin ------------------------\n"); 1391 return true; 1392 } 1393 1394 bool arduinoVNC::_handle_copyrect_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1395 { 1396 DEBUG_VNC_HANDLE("[_handle_copyrect_encoded_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1397 1398 int src_x, src_y; 1399 1400 if (!read_from_rfb_server(sock, (char *)&src_x, 2)) 1401 { 1402 return false; 1403 } 1404 1405 if (!read_from_rfb_server(sock, (char *)&src_y, 2)) 1406 { 1407 return false; 1408 } 1409 1410 /* If RichCursor encoding is used, we should extend our 1411 "cursor lock area" (previously set to destination 1412 rectangle) to the source rectangle as well. */ 1413 // SoftCursorLockArea(src_x, src_y, w, h); 1414 display->copy_rect(Swap16IfLE(src_x), Swap16IfLE(src_y), x, y, w, h); 1415 return true; 1416 } 1417 1418 #ifdef VNC_RRE 1419 bool arduinoVNC::_handle_rre_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1420 { 1421 DEBUG_VNC_HANDLE("[_handle_rre_encoded_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1422 1423 rfbRREHeader header; 1424 uint16_t colour; 1425 CARD16 rect[4]; 1426 1427 if (!read_from_rfb_server(sock, (char *)&header, sz_rfbRREHeader)) 1428 { 1429 return false; 1430 } 1431 header.nSubrects = Swap32IfLE(header.nSubrects); 1432 1433 /* draw background rect */ 1434 if (!read_from_rfb_server(sock, (char *)&colour, sizeof(colour))) 1435 { 1436 return false; 1437 } 1438 1439 display->draw_rect(x, y, w, h, colour); 1440 1441 /* subrect pixel values */ 1442 for (uint32_t i = 0; i < header.nSubrects; i++) 1443 { 1444 if (!read_from_rfb_server(sock, (char *)&colour, sizeof(colour))) 1445 { 1446 return false; 1447 } 1448 if (!read_from_rfb_server(sock, (char *)&rect, sizeof(rect))) 1449 return false; 1450 display->draw_rect( 1451 Swap16IfLE(rect[0]) + x, Swap16IfLE(rect[1]) + y, 1452 Swap16IfLE(rect[2]), Swap16IfLE(rect[3]), colour); 1453 } 1454 1455 return true; 1456 } 1457 #endif // #ifdef VNC_RRE 1458 1459 #ifdef VNC_CORRE 1460 bool arduinoVNC::_handle_corre_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1461 { 1462 DEBUG_VNC_HANDLE("[_handle_corre_encoded_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1463 1464 rfbRREHeader header; 1465 uint16_t colour; 1466 CARD8 rect[4]; 1467 1468 if (!read_from_rfb_server(sock, (char *)&colour, sizeof(colour))) 1469 { 1470 return false; 1471 } 1472 if (!read_from_rfb_server(sock, (char *)&header, sz_rfbRREHeader)) 1473 { 1474 return false; 1475 } 1476 header.nSubrects = Swap32IfLE(header.nSubrects); 1477 1478 /* draw background rect */ 1479 if (!read_from_rfb_server(sock, (char *)&colour, sizeof(colour))) 1480 { 1481 return false; 1482 } 1483 display->draw_rect(x, y, w, h, colour); 1484 1485 /* subrect pixel values */ 1486 for (uint32_t i = 0; i < header.nSubrects; i++) 1487 { 1488 if (!read_from_rfb_server(sock, (char *)&colour, sizeof(colour))) 1489 { 1490 return false; 1491 } 1492 if (!read_from_rfb_server(sock, (char *)&rect, sizeof(rect))) 1493 { 1494 return false; 1495 } 1496 display->draw_rect( 1497 Swap16IfLE(rect[0]) + x, Swap16IfLE(rect[1]) + y, 1498 Swap16IfLE(rect[2]), Swap16IfLE(rect[3]), colour); 1499 } 1500 return true; 1501 } 1502 #endif // #ifdef VNC_CORRE 1503 1504 #ifdef VNC_HEXTILE 1505 bool arduinoVNC::_handle_hextile_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1506 { 1507 DEBUG_VNC_HANDLE("[_handle_hextile_encoded_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1508 1509 uint16_t rect_x, rect_y, rect_w, rect_h, i = 0, j = 0; 1510 uint16_t rect_xW, rect_yW; 1511 1512 uint16_t tile_w = 16, tile_h = 16; 1513 uint16_t remaining_w, remaining_h; 1514 1515 CARD8 subrect_encoding; 1516 1517 uint16_t fgColor; 1518 uint16_t bgColor; 1519 1520 DEBUG_VNC_HEXTILE("[_handle_hextile_encoded_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1521 1522 rect_w = remaining_w = w; 1523 rect_h = remaining_h = h; 1524 rect_x = x; 1525 rect_y = y; 1526 1527 /* the rect is divided into tiles of width and height 16. Iterate over 1528 * those */ 1529 while (i < rect_h) 1530 { 1531 /* the last tile in a column could be smaller than 16 */ 1532 if (remaining_h < 16) 1533 { 1534 tile_h = remaining_h; 1535 } 1536 else 1537 { 1538 remaining_h -= 16; 1539 } 1540 1541 j = 0; 1542 while (j < rect_w) 1543 { 1544 /* the last tile in a row could also be smaller */ 1545 if (remaining_w < 16) 1546 { 1547 tile_w = remaining_w; 1548 } 1549 else 1550 { 1551 remaining_w -= 16; 1552 } 1553 1554 rect_xW = rect_x + j; 1555 rect_yW = rect_y + i; 1556 1557 if (!read_from_rfb_server(sock, (char *)&subrect_encoding, 1)) 1558 { 1559 return false; 1560 } 1561 1562 DEBUG_VNC_HEXTILE("[_handle_hextile_encoded_message] subrect_encoding: %d, subrect: x: %d y: %d w: %d h: %d\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1563 1564 /* first, check if the raw bit is set */ 1565 if (subrect_encoding & rfbHextileRaw) 1566 { 1567 DEBUG_VNC_HEXTILE("[hextile call raw] x: %d y: %d w: %d h: %d!\n", rect_xW, rect_yW, tile_w, tile_h); 1568 if (!_handle_raw_encoded_message_core(rect_xW, rect_yW, tile_w, tile_h)) 1569 { 1570 return false; 1571 } 1572 } 1573 else 1574 { /* subrect encoding is not raw */ 1575 1576 /* check whether theres a new bg or fg colour specified */ 1577 if (subrect_encoding & rfbHextileBackgroundSpecified) 1578 { 1579 if (!read_from_rfb_server(sock, (char *)&bgColor, sizeof(bgColor))) 1580 { 1581 return false; 1582 } 1583 } 1584 1585 if (subrect_encoding & rfbHextileForegroundSpecified) 1586 { 1587 if (!read_from_rfb_server(sock, (char *)&fgColor, sizeof(fgColor))) 1588 { 1589 return false; 1590 } 1591 } 1592 1593 DEBUG_VNC_HEXTILE("[_handle_hextile_encoded_message] subrect: x: %d y: %d w: %d h: %d\n", rect_xW, rect_yW, tile_w, tile_h); 1594 1595 uint16_t tile_size = tile_w * tile_h; 1596 if (tile_size > FB_SIZE) 1597 { 1598 DEBUG_VNC("[_handle_hextile_encoded_message] ttile too large: %d x % d! Please increase FB_SIZE in VNC_config.h\n", tile_w, tile_h); 1599 return false; 1600 } 1601 1602 /* fill the background */ 1603 uint16_t *p = framebuffer; 1604 uint16_t i = tile_size; 1605 uint16_t j, w, delta_x; 1606 while (i--) 1607 { 1608 *p++ = bgColor; 1609 } 1610 1611 if (subrect_encoding & rfbHextileAnySubrects) 1612 { 1613 uint8_t nr_subr = 0; 1614 if (!read_from_rfb_server(sock, (char *)&nr_subr, 1)) 1615 { 1616 return false; 1617 } 1618 DEBUG_VNC_HEXTILE("[_handle_hextile_encoded_message] nr_subr: %d\n", nr_subr); 1619 if (nr_subr) 1620 { 1621 if (subrect_encoding & rfbHextileSubrectsColoured) 1622 { 1623 if (!read_from_rfb_server(sock, raw_buffer, nr_subr * 4)) 1624 { 1625 return false; 1626 } 1627 1628 HextileSubrectsColoured_t *bufPC = (HextileSubrectsColoured_t *)raw_buffer; 1629 for (uint8_t n = 0; n < nr_subr; n++) 1630 { 1631 DEBUG_VNC_HEXTILE("[_handle_hextile_encoded_message] Coloured nr_subr: %d bufPC: %d, %d, %d, %d\n", n, bufPC->x, bufPC->y, bufPC->w, bufPC->h); 1632 p = framebuffer + (bufPC->y * tile_w) + bufPC->x; 1633 w = bufPC->w + 1; 1634 i = w; 1635 j = bufPC->h + 1; 1636 delta_x = tile_w - w; 1637 while (j--) 1638 { 1639 while (i--) 1640 { 1641 *p++ = bufPC->color; 1642 } 1643 i = w; 1644 p += delta_x; 1645 } 1646 bufPC++; 1647 } 1648 } 1649 else 1650 { 1651 if (!read_from_rfb_server(sock, raw_buffer, nr_subr * 2)) 1652 { 1653 return false; 1654 } 1655 1656 HextileSubrects_t *bufP = (HextileSubrects_t *)raw_buffer; 1657 for (uint8_t n = 0; n < nr_subr; n++) 1658 { 1659 DEBUG_VNC_HEXTILE("[_handle_hextile_encoded_message] nr_subr: %d bufP: %d, %d, %d, %d\n", n, bufP->x, bufP->y, bufP->w, bufP->h); 1660 p = framebuffer + (bufP->y * tile_w) + bufP->x; 1661 w = bufP->w + 1; 1662 i = w; 1663 j = bufP->h + 1; 1664 delta_x = tile_w - w; 1665 while (j--) 1666 { 1667 while (i--) 1668 { 1669 *p++ = fgColor; 1670 } 1671 i = w; 1672 p += delta_x; 1673 } 1674 bufP++; 1675 } 1676 } 1677 } 1678 } 1679 display->draw_area(rect_xW, rect_yW, tile_w, tile_h, (uint8_t *)framebuffer); 1680 } 1681 j += 16; 1682 delay(0); 1683 } 1684 remaining_w = w; 1685 tile_w = 16; /* reset for next row */ 1686 i += 16; 1687 } 1688 1689 DEBUG_VNC_HEXTILE("[_handle_hextile_encoded_message] ------------------------ Fin ------------------------\n"); 1690 return true; 1691 } 1692 #endif // #ifdef VNC_HEXTILE 1693 1694 #ifdef VNC_ZRLE 1695 bool arduinoVNC::_handle_zrle_encoded_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1696 { 1697 DEBUG_VNC_HANDLE("[_handle_zrle_encoded_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1698 1699 rfbZlibHeader zlh; 1700 if (!read_from_rfb_server(sock, (char *)&zlh, sz_rfbZlibHeader)) 1701 { 1702 return false; 1703 } 1704 uint32_t len = Swap32IfLE(zlh.nBytes); 1705 1706 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] x: %d y: %d w: %d h: %d len: %d!\n", x, y, w, h, len); 1707 1708 if (!zin_buffer) 1709 { 1710 zin_buffer = (uint8_t *)malloc(len); 1711 allocated_zin = len; 1712 } 1713 else 1714 { 1715 if (allocated_zin < len) 1716 { 1717 zin_buffer = (uint8_t *)realloc(zin_buffer, len); 1718 } 1719 } 1720 if (!zin_buffer) 1721 { 1722 DEBUG_VNC("zin_buffer malloc failed!\n"); 1723 } 1724 if (!read_from_rfb_server(sock, (char *)zin_buffer, len)) 1725 { 1726 DEBUG_VNC("Failed reading from input file!\n"); 1727 return false; 1728 } 1729 zin_buf_size = len; 1730 zin_buf_ofs = 0; 1731 zout_buf_idx = 0; 1732 zout_buf_remain = 0; 1733 1734 uint16_t rect_x, rect_y, rect_w, rect_h, i = 0, j = 0; 1735 uint16_t rect_xW, rect_yW; 1736 1737 uint16_t tile_w = 64, tile_h = 64; 1738 uint16_t remaining_w, remaining_h; 1739 size_t tile_size; 1740 uint16_t *p; 1741 1742 CARD8 subrect_encoding; 1743 1744 uint16_t color; 1745 size_t idx; 1746 size_t paletteSize = 0; 1747 1748 rect_w = remaining_w = w; 1749 rect_h = remaining_h = h; 1750 rect_x = x; 1751 rect_y = y; 1752 1753 size_t runLengthCount = 0; 1754 uint8_t runLenMinus1; 1755 uint16_t runLength; 1756 1757 while (i < rect_h) 1758 { 1759 /* the rect is divided into tiles of width and height 64. Iterate over 1760 * those */ 1761 /* the last tile in a column could be smaller than 16 */ 1762 if (remaining_h < 64) 1763 { 1764 tile_h = remaining_h; 1765 } 1766 1767 /* the last tile in a row could also be smaller */ 1768 if (remaining_w < 64) 1769 { 1770 tile_w = remaining_w; 1771 } 1772 else 1773 { 1774 remaining_w -= 64; 1775 } 1776 1777 tile_size = tile_w * tile_h; 1778 rect_xW = rect_x + j; 1779 rect_yW = rect_y + i; 1780 1781 read_from_z(&subrect_encoding, 1); 1782 1783 if (subrect_encoding == rfbTrleRaw) 1784 { 1785 // DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d RAW x: %d y: %d w: %d h: %d!\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1786 read_from_z((uint8_t *)framebuffer, tile_size * 2); 1787 display->draw_area(rect_xW, rect_yW, tile_w, tile_h, (uint8_t *)framebuffer); 1788 } 1789 else 1790 { 1791 paletteSize = subrect_encoding & 127; 1792 1793 // DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] subrect_encoding: %d, paletteSize: %d, subrect: x: %d y: %d w: %d h: %d\n", subrect_encoding, paletteSize, rect_xW, rect_yW, tile_w, tile_h); 1794 1795 read_from_z((uint8_t *)&palette, paletteSize * 2); 1796 1797 if (subrect_encoding == rfbTrleSolid) 1798 { 1799 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d SOLID x: %d y: %d w: %d h: %d!\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1800 display->draw_rect(rect_xW, rect_yW, tile_w, tile_h, palette[0]); 1801 } 1802 else if (subrect_encoding <= rfbTrleReusePackedPalette) 1803 { 1804 p = framebuffer; 1805 uint8_t data = 0; 1806 if (paletteSize == 2) // 1-bit 1807 { 1808 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d 1-bit, x: %d y: %d w: %d h: %d!\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1809 1810 for (int hidx = 0; hidx < tile_h; ++hidx) 1811 { 1812 for (idx = 0; idx < tile_w; ++idx) 1813 { 1814 if ((idx & 0b111) == 0) // new byte 1815 { 1816 read_from_z(&data, 1); 1817 } 1818 else 1819 { 1820 data <<= 1; 1821 } 1822 *p++ = palette[(data >> 7) & 127]; 1823 } 1824 } 1825 } 1826 else if (paletteSize <= 4) // 3-4 palettes, 2-bit 1827 { 1828 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d 2-bit, x: %d y: %d w: %d h: %d!\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1829 1830 for (int hidx = 0; hidx < tile_h; ++hidx) 1831 { 1832 for (idx = 0; idx < tile_w; ++idx) 1833 { 1834 if ((idx & 0b11) == 0) // new byte 1835 { 1836 read_from_z(&data, 1); 1837 } 1838 else 1839 { 1840 data <<= 2; 1841 } 1842 *p++ = palette[(data >> 6) & 127]; 1843 } 1844 } 1845 } 1846 else if (paletteSize <= 16) // 5-16 palettes, 4-bit 1847 { 1848 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d 4-bit, x: %d y: %d w: %d h: %d!\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1849 1850 for (int hidx = 0; hidx < tile_h; ++hidx) 1851 { 1852 for (idx = 0; idx < tile_w; ++idx) 1853 { 1854 if ((idx & 1) == 0) // new byte 1855 { 1856 read_from_z(&data, 1); 1857 } 1858 else 1859 { 1860 data <<= 4; 1861 } 1862 *p++ = palette[(data >> 4) & 127]; 1863 } 1864 } 1865 } 1866 else // > 16 palettes, 8-bit 1867 { 1868 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d 8-bit, x: %d y: %d w: %d h: %d!\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1869 1870 for (idx = 0; idx < tile_size; ++idx) 1871 { 1872 read_from_z(&data, 1); 1873 *p++ = palette[data & 127]; 1874 } 1875 } 1876 1877 display->draw_area(rect_xW, rect_yW, tile_w, tile_h, (uint8_t *)framebuffer); 1878 } 1879 else if (subrect_encoding == rfbTrlePlainRLE) 1880 { 1881 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d Plain RLE x: %d y: %d w: %d h: %d!\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1882 p = framebuffer; 1883 runLengthCount = 0; 1884 while (runLengthCount < tile_size) 1885 { 1886 read_from_z((uint8_t *)&color, 2); 1887 1888 runLength = 1; 1889 do 1890 { 1891 read_from_z(&runLenMinus1, 1); 1892 1893 runLength += runLenMinus1; 1894 } while (runLenMinus1 == 255); 1895 1896 runLengthCount += runLength; 1897 if (runLengthCount > tile_size) 1898 { 1899 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d Plain RLE runLengthCount(%d) > tile_size(%d)!\n", subrect_encoding, runLengthCount, tile_size); 1900 } 1901 else 1902 { 1903 while (runLength--) 1904 { 1905 *p++ = color; 1906 } 1907 } 1908 } 1909 1910 display->draw_area(rect_xW, rect_yW, tile_w, tile_h, (uint8_t *)framebuffer); 1911 } 1912 else // Palette RLE 1913 { 1914 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d Palette RLE x: %d y: %d w: %d h: %d!\n", subrect_encoding, rect_xW, rect_yW, tile_w, tile_h); 1915 p = framebuffer; 1916 runLengthCount = 0; 1917 while (runLengthCount < tile_size) 1918 { 1919 read_from_z((uint8_t *)&idx, 1); 1920 1921 runLength = 1; 1922 if ((idx & 128) != 0) 1923 { 1924 do 1925 { 1926 read_from_z(&runLenMinus1, 1); 1927 1928 runLength += runLenMinus1; 1929 } while (runLenMinus1 == 255); 1930 } 1931 1932 color = palette[idx & 127]; 1933 1934 runLengthCount += runLength; 1935 // DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] Palette RLE idx: %d, runLength: %d, runLengthCount: %d.\n", idx, runLength, runLengthCount); 1936 if (runLengthCount > tile_size) 1937 { 1938 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] %d Palette RLE runLengthCount(%d) > tile_size(%d)!\n", subrect_encoding, runLengthCount, tile_size); 1939 } 1940 else 1941 { 1942 while (runLength--) 1943 { 1944 *p++ = color; 1945 } 1946 } 1947 } 1948 1949 display->draw_area(rect_xW, rect_yW, tile_w, tile_h, (uint8_t *)framebuffer); 1950 } 1951 } 1952 1953 // next tile 1954 j += 64; 1955 if (j >= rect_w) 1956 { 1957 j = 0; 1958 remaining_w = w; 1959 tile_w = 64; /* reset for next row */ 1960 i += 64; 1961 1962 if (remaining_h >= 64) 1963 { 1964 remaining_h -= 64; 1965 } 1966 else 1967 { 1968 break; 1969 } 1970 } 1971 1972 delay(0); 1973 // DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] loop i: %d, j: %d\n", i, j); 1974 } 1975 1976 DEBUG_VNC_ZRLE("[_handle_zrle_encoded_message] ------------------------ Fin ------------------------\n"); 1977 return true; 1978 } 1979 #endif // #ifdef VNC_ZRLE 1980 1981 bool arduinoVNC::_handle_cursor_pos_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1982 { 1983 DEBUG_VNC_HANDLE("[_handle_cursor_pos_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1984 return true; 1985 } 1986 1987 bool arduinoVNC::_handle_server_continuous_updates_message(uint16_t x, uint16_t y, uint16_t w, uint16_t h) 1988 { 1989 DEBUG_VNC_HANDLE("[_handle_server_continuous_updates_message] x: %d y: %d w: %d h: %d!\n", x, y, w, h); 1990 return true; 1991 } 1992 1993 //############################################################################################# 1994 // Encryption 1995 //############################################################################################# 1996 1997 void arduinoVNC::vncRandomBytes(unsigned char *bytes) 1998 { 1999 #ifdef ESP8266 2000 srand(RANDOM_REG32); 2001 #else 2002 // todo find better seed 2003 srand(millis()); 2004 #endif 2005 for (int i = 0; i < CHALLENGESIZE; i++) 2006 { 2007 bytes[i] = (unsigned char)(rand() & 255); 2008 } 2009 } 2010 2011 void arduinoVNC::vncEncryptBytes(unsigned char *bytes, char *passwd) 2012 { 2013 unsigned char key[8]; 2014 size_t i; 2015 2016 /* key is simply password padded with nulls */ 2017 2018 for (i = 0; i < 8; i++) 2019 { 2020 if (i < strlen(passwd)) 2021 { 2022 key[i] = passwd[i]; 2023 } 2024 else 2025 { 2026 key[i] = 0; 2027 } 2028 } 2029 2030 deskey(key, EN0); 2031 2032 for (i = 0; i < CHALLENGESIZE; i += 8) 2033 { 2034 des(bytes + i, bytes + i); 2035 } 2036 }