FabGL
ESP32 Display Controller and Graphics Library
RFB.cpp
1 /*
2  Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com) - <http://www.fabgl.com>
3  Copyright (c) 2019-2021 Fabrizio Di Vittorio.
4  All rights reserved.
5 
6 
7 * Please contact fdivitto2013@gmail.com if you need a commercial license.
8 
9 
10 * This library and related software is available under GPL v3. Feel free to use FabGL in free software and hardware:
11 
12  FabGL is free software: you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation, either version 3 of the License, or
15  (at your option) any later version.
16 
17  FabGL is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with FabGL. If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 
27 #include <string.h>
28 
29 #include "RFB.h"
30 
31 
32 
33 namespace fabgl {
34 
35 
36 
39 
40 
41 /*
42  * This is D3DES (V5.09) by Richard Outerbridge with the double and
43  * triple-length support removed for use in VNC. Also the bytebit[] array
44  * has been reversed so that the most significant bit in each byte of the
45  * key is ignored, not the least significant.
46  *
47  * These changes are
48  * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
49  *
50  * This software is distributed in the hope that it will be useful,
51  * but WITHOUT ANY WARRANTY; without even the implied warranty of
52  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
53  *
54  * D3DES (V5.09) -
55  *
56  * A portable, public domain, version of the Data Encryption Standard.
57  *
58  * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
59  * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
60  * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
61  * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
62  * for humouring me on.
63  *
64  * Copyright (c) 1988, 1989, 1990, 1991, 1992 by Richard Outerbridge.
65  * (GEnie : OUTER; CIS : [71755, 204]) Graven Imagery, 1992.
66  *
67  * d3des.h -
68  *
69  * Headers and defines for d3des.c
70  * Graven Imagery, 1992.
71  *
72  * Copyright (c) 1988, 1989, 1990, 1991, 1992 by Richard Outerbridge
73  * (GEnie : OUTER; CIS : [71755, 204])
74  */
75 
76 
77 static const uint8_t Df_Key[24] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 };
78 
79 
80 static const uint16_t bytebit[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
81 
82 
83 static const uint32_t bigbyte[24] = { 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000, 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
84 
85 
86 static const uint8_t pc1[56] = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
87 
88 
89 static const uint8_t totrot[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
90 
91 
92 static const uint8_t pc2[48] = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
93 
94 
95 static const uint32_t SP1[64] = {
96  0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
97  0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
98  0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
99  0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
100  0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
101  0x00010004, 0x00010400, 0x00000000, 0x01010004 };
102 
103 
104 static const uint32_t SP2[64] = {
105  0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
106  0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
107  0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
108  0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
109  0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
110  0x80000000, 0x80100020, 0x80108020, 0x00108000 };
111 
112 
113 static const uint32_t SP3[64] = {
114  0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
115  0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
116  0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
117  0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
118  0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
119  0x00020208, 0x00000008, 0x08020008, 0x00020200 };
120 
121 
122 static const uint32_t SP4[64] = {
123  0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
124  0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
125  0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
126  0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
127  0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
128  0x00000080, 0x00800000, 0x00002000, 0x00802080 };
129 
130 
131 static const uint32_t SP5[64] = {
132  0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
133  0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
134  0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
135  0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
136  0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
137  0x00000000, 0x40080000, 0x02080100, 0x40000100 };
138 
139 
140 static const uint32_t SP6[64] = {
141  0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
142  0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
143  0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
144  0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
145  0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
146  0x20404000, 0x20000000, 0x00400010, 0x20004010 };
147 
148 
149 static const uint32_t SP7[64] = {
150  0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
151  0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
152  0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
153  0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
154  0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
155  0x04000002, 0x04000800, 0x00000800, 0x00200002 };
156 
157 
158 static const uint32_t SP8[64] = {
159  0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
160  0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
161  0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
162  0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
163  0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
164  0x00001040, 0x00040040, 0x10000000, 0x10041000 };
165 
166 
167 static void scrunch(uint8_t * outof, uint32_t * into)
168 {
169  *into = (*outof++ & 0xff) << 24;
170  *into |= ((*outof++ & 0xff) << 16);
171  *into |= ((*outof++ & 0xff) << 8);
172  *into++ |= (*outof++ & 0xff);
173  *into = (*outof++ & 0xff) << 24;
174  *into |= ((*outof++ & 0xff) << 16);
175  *into |= ((*outof++ & 0xff) << 8);
176  *into |= (*outof & 0xff);
177 }
178 
179 
180 static void unscrun(uint32_t * outof, uint8_t * into)
181 {
182  *into++ = ((*outof >> 24) & 0xff);
183  *into++ = ((*outof >> 16) & 0xff);
184  *into++ = ((*outof >> 8) & 0xff);
185  *into++ = (*outof++ & 0xff);
186  *into++ = ((*outof >> 24) & 0xff);
187  *into++ = ((*outof >> 16) & 0xff);
188  *into++ = ((*outof >> 8) & 0xff);
189  *into++ = (*outof & 0xff);
190 }
191 
192 
193 static void desfunc(uint32_t * block, uint32_t * keys)
194 {
195  uint32_t leftt = block[0];
196  uint32_t right = block[1];
197  uint32_t work = ((leftt >> 4) ^ right) & 0x0f0f0f0f;
198  right ^= work;
199  leftt ^= (work << 4);
200  work = ((leftt >> 16) ^ right) & 0x0000ffff;
201  right ^= work;
202  leftt ^= (work << 16);
203  work = ((right >> 2) ^ leftt) & 0x33333333;
204  leftt ^= work;
205  right ^= (work << 2);
206  work = ((right >> 8) ^ leftt) & 0x00ff00ff;
207  leftt ^= work;
208  right ^= (work << 8);
209  right = ((right << 1) | ((right >> 31) & 1)) & 0xffffffff;
210  work = (leftt ^ right) & 0xaaaaaaaa;
211  leftt ^= work;
212  right ^= work;
213  leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffff;
214 
215  for (int round = 0; round < 8; ++round) {
216  work = (right << 28) | (right >> 4);
217  work ^= *keys++;
218  uint32_t fval = SP7[work & 0x3f];
219  fval |= SP5[(work >> 8) & 0x3f];
220  fval |= SP3[(work >> 16) & 0x3f];
221  fval |= SP1[(work >> 24) & 0x3f];
222  work = right ^ *keys++;
223  fval |= SP8[work & 0x3f];
224  fval |= SP6[(work >> 8) & 0x3f];
225  fval |= SP4[(work >> 16) & 0x3f];
226  fval |= SP2[(work >> 24) & 0x3f];
227  leftt ^= fval;
228  work = (leftt << 28) | (leftt >> 4);
229  work ^= *keys++;
230  fval = SP7[work & 0x3f];
231  fval |= SP5[(work >> 8) & 0x3f];
232  fval |= SP3[(work >> 16) & 0x3f];
233  fval |= SP1[(work >> 24) & 0x3f];
234  work = leftt ^ *keys++;
235  fval |= SP8[work & 0x3f];
236  fval |= SP6[(work >> 8) & 0x3f];
237  fval |= SP4[(work >> 16) & 0x3f];
238  fval |= SP2[(work >> 24) & 0x3f];
239  right ^= fval;
240  }
241 
242  right = (right << 31) | (right >> 1);
243  work = (leftt ^ right) & 0xaaaaaaaa;
244  leftt ^= work;
245  right ^= work;
246  leftt = (leftt << 31) | (leftt >> 1);
247  work = ((leftt >> 8) ^ right) & 0x00ff00ff;
248  right ^= work;
249  leftt ^= (work << 8);
250  work = ((leftt >> 2) ^ right) & 0x33333333;
251  right ^= work;
252  leftt ^= (work << 2);
253  work = ((right >> 16) ^ leftt) & 0x0000ffff;
254  leftt ^= work;
255  right ^= (work << 16);
256  work = ((right >> 4) ^ leftt) & 0x0f0f0f0f;
257  leftt ^= work;
258  right ^= (work << 4);
259  *block++ = right;
260  *block = leftt;
261 }
262 
263 
264 // length must be a multiple of 8
265 void tripleDES_transform(char const * password, bool decode, uint8_t * inBlock, uint8_t * outBlock, size_t length)
266 {
267  uint32_t KnL[32] = { 0 };
268 
269  uint8_t charbuf[8] = { 0 };
270  for (int i = 0; i < 8 && *password; ++i)
271  charbuf[i] = *password++;
272 
273  uint8_t * key = charbuf;
274 
275  uint8_t pc1m[56];
276  uint8_t pcr[56];
277  uint32_t kn[32];
278 
279  for (int j = 0; j < 56; ++j) {
280  int l = pc1[j];
281  int m = l & 7;
282  pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
283  }
284  for (int i = 0; i < 16; ++i) {
285  int m = decode ? (15 - i) << 1 : i << 1;
286  int n = m + 1;
287  kn[n] = kn[m] = 0;
288  for (int j = 0; j < 28; ++j) {
289  int l = j + totrot[i];
290  pcr[j] = l < 28 ? pc1m[l] : pc1m[l - 28];
291  }
292  for (int j = 28; j < 56; ++j) {
293  int l = j + totrot[i];
294  pcr[j] = l < 56 ? pc1m[l] : pc1m[l - 28];
295  }
296  for (int j = 0; j < 24; ++j) {
297  if (pcr[pc2[j]])
298  kn[m] = kn[m] | bigbyte[j];
299  if (pcr[pc2[j + 24]])
300  kn[n] = kn[n] | bigbyte[j];
301  }
302  }
303 
304  uint32_t * raw1 = kn;
305  uint32_t dough[32];
306  uint32_t * cook = dough;
307  for (int i = 0; i < 16; ++i, ++cook, ++raw1) {
308  uint32_t * raw0 = raw1++;
309  *cook = (*raw0 & 0x00fc0000) << 6;
310  *cook = *cook | ((*raw0 & 0x00000fc0) << 10);
311  *cook = *cook | ((*raw1 & 0x00fc0000) >> 10);
312  *cook = *cook | ((*raw1 & 0x00000fc0) >> 6);
313  ++cook;
314  *cook = (*raw0 & 0x0003f000) << 12;
315  *cook = *cook | ((*raw0 & 0x0000003f) << 16);
316  *cook = *cook | ((*raw1 & 0x0003f000) >> 4);
317  *cook = *cook | (*raw1 & 0x0000003f);
318  }
319 
320  uint32_t * from = dough;
321  for (int i = 0; i < 32; ++i, ++from)
322  KnL[i] = *from;
323 
324  for (int i = 0; i < length; i += 8, inBlock += 8, outBlock += 8) {
325  uint32_t work[2];
326  scrunch(inBlock, work);
327  desfunc(work, KnL);
328  unscrun(work, outBlock);
329  }
330 }
331 
332 
333 
336 
337 
338 // client to server messages
339 #define MSG_SETPIXELFORMAT 0x00
340 #define MSG_SETENCODINGS 0x02
341 #define MSG_FRAMEBUFFERUPDATEREQUEST 0x03
342 #define MSG_KEYEVENT 0x04
343 #define MSG_POINTEREVENT 0x05
344 #define MSG_CLIENTCUTTEXT 0x06
345 
346 // server to client messages
347 #define MSG_FRAMEBUFFERUPDATE 0x00
348 #define MSG_SETCOLORMAPENTRIES 0x01
349 #define MSG_BELL 0x02
350 #define MSG_SERVERCUTTEXT 0x03
351 
352 
353 RFBClient::RFBClient()
354  : m_name(nullptr)
355 {
356 }
357 
358 
359 RFBClient::~RFBClient()
360 {
361  if (m_name)
362  free(m_name);
363 }
364 
365 
366 RFBState RFBClient::connect(char const * host, uint16_t port, char const * password, bool sharedConnection)
367 {
368  auto ip = hostToIP(host);
369  if (ip.s_addr == 0)
370  return RFBState::HostNameError;
371  if (!m_socket.connect(ip, port))
372  return RFBState::UnableToConnect;
373 
374  m_socket.setLittleEndian(false);
375  m_socket.setNoDelay(true);
376 
377  char head[13];
378  if (m_socket.read(head, 12) != 12)
379  return RFBState::CommunicationError;
380 
381  int protVer = (head[10] - '0') + (head[9] - '0') * 10 + (head[8] - '0') * 100 + (head[6] - '0') * 1000 + (head[5] - '0') * 10000 + (head[4] - '0') * 100000;
382 
383  // agree protocol version
384  if (protVer >= 3008)
385  protVer = 3008;
386  else if (protVer >= 3003 && protVer < 3007)
387  protVer = 3003;
388  else if (protVer != 3007)
389  return RFBState::UnsupportedProtocolVersion; // unsupported
390 
391  printf("protVer = %d\n", protVer);
392 
393  // send back
394  m_socket.writeFmt("RFB 00%d.00%d\x0a", protVer / 1000, protVer - (protVer / 1000) * 1000);
395 
396  uint8_t securityType = 0;
397 
398  if (protVer >= 3007) {
399  int securityTypesCount = m_socket.readByte();
400  if (securityTypesCount == 0) {
401  // failed, get error string
402  int slen = m_socket.readDWord();
403  char str[slen + 1];
404  m_socket.read(str, slen);
405  str[slen] = 0;
406  printf("RFB Error: %s\n", str);
407  return RFBState::ErrorGettingSecTypes;
408  }
409 
410  // get securityTypes
411  uint8_t securityTypes[securityTypesCount];
412  m_socket.read(securityTypes, securityTypesCount);
413 
414  for (int i = 0; i < securityTypesCount; ++i)
415  if (securityTypes[i] == 1 || securityTypes[i] == 2) {
416  securityType = securityTypes[i]; // VNC Authentication or none
417  break;
418  }
419 
420  if (securityType == 0)
421  return RFBState::UnsupportedAuth;
422 
423  // send security type
424  m_socket.writeByte(securityType);
425 
426  }
427 
428  if (protVer == 3003) {
429  // get security type from server
430  securityType = m_socket.readDWord();
431  }
432 
433  switch (securityType) {
434 
435  case 1:
436  // no auth
437  if (protVer >= 3008) {
438  // get auth result
439  if (m_socket.readDWord())
440  return RFBState::AuthFailed;
441  }
442  break;
443 
444  case 2:
445  {
446  // VNC authentication
447  // get challenge, encrypt and send back
448  uint8_t challenge[16];
449  m_socket.read(challenge, 16);
450  tripleDES_transform(password, false, challenge, challenge, 16);
451  m_socket.write(challenge, 16);
452  // get auth result
453  if (m_socket.readDWord())
454  return RFBState::AuthFailed;
455  printf("VNC Auth OK\n");
456  break;
457  }
458 
459  }
460 
461  // shared connection?
462  m_socket.writeByte((uint8_t)sharedConnection);
463 
464  // get server-initialization message
465  m_frameBufferWidth = m_socket.readWord();
466  m_frameBufferHeight = m_socket.readWord();
467  m_bitsPerPixel = m_socket.readByte();
468  m_depth = m_socket.readByte();
469  m_bigEndian = m_socket.readByte();
470  m_trueColor = m_socket.readByte();
471  m_redMax = m_socket.readWord();
472  m_greenMax = m_socket.readWord();
473  m_blueMax = m_socket.readWord();
474  m_redShift = m_socket.readByte();
475  m_greenShift = m_socket.readByte();
476  m_blueShift = m_socket.readByte();
477  m_socket.readDiscard(3);
478  int slen = m_socket.readDWord();
479  m_name = (char*) malloc(slen + 1);
480  m_socket.read(m_name, slen);
481  m_name[slen] = 0;
482 
483  printf("m_frameBufferWidth = %d\n", m_frameBufferWidth);
484  printf("m_frameBufferHeight = %d\n", m_frameBufferHeight);
485  printf("m_bitsPerPixel = %d\n", m_bitsPerPixel);
486  printf("m_depth = %d\n", m_depth);
487  printf("m_bigEndian = %d\n", m_bigEndian);
488  printf("m_trueColor = %d\n", m_trueColor);
489  printf("m_redMax = %d\n", m_redMax);
490  printf("m_greenMax = %d\n", m_greenMax);
491  printf("m_blueMax = %d\n", m_blueMax);
492  printf("m_redShift = %d\n", m_redShift);
493  printf("m_greenShift = %d\n", m_greenShift);
494  printf("m_blueShift = %d\n", m_blueShift);
495  printf("m_name = %s\n", m_name);
496 
497  // setup supported encodings
498  static const uint32_t encodings[] = { 0, /*2, 1, 0xffffff11, 0xffffff21*/ }; // raw, RRE, CopyRect, Cursor pseudo-encoding, DesktopSize pseudo-encoding
499  sendSetEncodings(encodings, sizeof(encodings) / sizeof(uint32_t));
500 
502  // first update
503  setPixelFormat(8, 8, false, true, 1, 1, 1, 2, 1, 0);
504  //sendRequestUpdate(0, 0, m_frameBufferWidth, m_frameBufferHeight, false);
505 
506  /*
507  uint8_t msg = m_socket.readByte();
508  printf("msg = %d\n", msg);
509  m_socket.readByte();
510  uint16_t firstColor = m_socket.readWord();
511  uint16_t colorCount = m_socket.readWord();
512  printf("firstColor = %d, colorCount = %d\n", firstColor, colorCount);
513  while (1);
514  */
515 
516  int bpp = m_bitsPerPixel / 8;
517  uint8_t * row = (uint8_t*) malloc(m_frameBufferWidth * bpp);
518  printf("row=%p\n", row);
519  {
520  // test
521  uint8_t msg = m_socket.readByte();
522  printf("msg = %02X\n", msg);
523  m_socket.readByte();
524  uint16_t rectsCount = m_socket.readWord();
525  printf("rectsCount = %d\n", rectsCount);
526  for (int i = 0; i < rectsCount; ++i) {
527  printf("rect #%d\n", i);
528  uint16_t xpos = m_socket.readWord();
529  uint16_t ypos = m_socket.readWord();
530  uint16_t ww = m_socket.readWord();
531  uint16_t hh = m_socket.readWord();
532  uint32_t en = m_socket.readDWord();
533  printf(" xpos = %d ypos = %d ww = %d hh = %d en = %d\n", xpos, ypos, ww, hh, en);
534 
535  for (int y = 0; y < hh; ++y) {
536  m_socket.read(row, ww * bpp);
537  //m_renderRow(m_renderRowContext, xpos, ypos + y, row, ww);
538  }
539 
540  }
541  }
542  while (1) {
543  sendRequestUpdate(0, 0, m_frameBufferWidth, m_frameBufferHeight, true);
544  {
545  // test
546  uint8_t msg = m_socket.readByte();
547  printf("msg = %02X\n", msg);
548  m_socket.readByte();
549  uint16_t rectsCount = m_socket.readWord();
550  printf("rectsCount = %d\n", rectsCount);
551  for (int i = 0; i < rectsCount; ++i) {
552  printf("rect #%d\n", i);
553  uint16_t xpos = m_socket.readWord();
554  uint16_t ypos = m_socket.readWord();
555  uint16_t ww = m_socket.readWord();
556  uint16_t hh = m_socket.readWord();
557  uint32_t en = m_socket.readDWord();
558  printf(" xpos = %d ypos = %d ww = %d hh = %d en = %d\n", xpos, ypos, ww, hh, en);
559 
560  for (int y = 0; y < hh; ++y) {
561  m_socket.read(row, ww * bpp);
562  m_renderRow(m_renderRowContext, xpos, ypos + y, row, ww);
563  }
564 
565  }
566  }
567  }
568  free(row);
569  //*/
570 
571  return RFBState::Success;
572 }
573 
574 
575 void RFBClient::setPixelFormat(int bitsPerPixel, int depth, bool bigEndian, bool trueColor, int redMax, int greenMax, int blueMax, int redShift, int greenShift, int blueShift)
576 {
577  m_bitsPerPixel = bitsPerPixel;
578  m_depth = depth;
579  m_bigEndian = bigEndian;
580  m_trueColor = trueColor;
581  m_redMax = redMax;
582  m_greenMax = greenMax;
583  m_blueMax = blueMax;
584  m_redShift = redShift;
585  m_greenShift = greenShift;
586  m_blueShift = blueShift;
587  sendSetPixelFormat();
588  sendRequestUpdate(0, 0, m_frameBufferWidth, m_frameBufferHeight, false);
589 }
590 
591 
592 void RFBClient::sendSetEncodings(uint32_t const * encodings, size_t encodingsCount)
593 {
594  m_socket.writeByte(MSG_SETENCODINGS);
595  m_socket.writeFillBytes(1);
596  m_socket.writeWord(encodingsCount);
597  for (int i = 0; i < encodingsCount; ++i)
598  m_socket.writeDWord(encodings[i]);
599 }
600 
601 
602 void RFBClient::sendRequestUpdate(int x, int y, int width, int height, bool incremental)
603 {
604  m_socket.writeByte(MSG_FRAMEBUFFERUPDATEREQUEST);
605  m_socket.writeByte((uint8_t)incremental);
606  m_socket.writeWord(x);
607  m_socket.writeWord(y);
608  m_socket.writeWord(width);
609  m_socket.writeWord(height);
610 }
611 
612 
613 void RFBClient::sendSetPixelFormat()
614 {
615  m_socket.writeByte(MSG_SETPIXELFORMAT);
616  m_socket.writeFillBytes(3);
617  m_socket.writeByte(m_bitsPerPixel);
618  m_socket.writeByte(m_depth);
619  m_socket.writeByte(m_bigEndian);
620  m_socket.writeByte(m_trueColor);
621  m_socket.writeWord(m_redMax);
622  m_socket.writeWord(m_greenMax);
623  m_socket.writeWord(m_blueMax);
624  m_socket.writeByte(m_redShift);
625  m_socket.writeByte(m_greenShift);
626  m_socket.writeByte(m_blueShift);
627  m_socket.writeFillBytes(3);
628 }
629 
630 
631 
632 
635 
636 
637 
638 } // namespace fabgl
Definition: canvas.cpp:36
This file contains RFBClient class.
uint8_t height
uint8_t width