source: mainline/uspace/srv/hid/rfb/rfb.c@ 47b27b40

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 47b27b40 was 47b27b40, checked in by Martin Sucha <sucha14@…>, 12 years ago

rfb: Use logging API instead of ad-hoc printf statements

  • Property mode set to 100644
File size: 20.7 KB
Line 
1/*
2 * Copyright (c) 2013 Martin Sucha
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <errno.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <fibril_synch.h>
33#include <inttypes.h>
34#include <str.h>
35#include <str_error.h>
36#include <byteorder.h>
37#include <macros.h>
38#include <io/log.h>
39
40#include <net/in.h>
41#include <net/inet.h>
42#include <net/socket.h>
43
44#include "rfb.h"
45
46/** Buffer for receiving the request. */
47#define BUFFER_SIZE 1024
48
49static char rbuf[BUFFER_SIZE];
50static size_t rbuf_out;
51static size_t rbuf_in;
52
53
54/** Receive one character (with buffering) */
55static int recv_char(int fd, char *c)
56{
57 if (rbuf_out == rbuf_in) {
58 rbuf_out = 0;
59 rbuf_in = 0;
60
61 ssize_t rc = recv(fd, rbuf, BUFFER_SIZE, 0);
62 if (rc <= 0)
63 return rc;
64
65 rbuf_in = rc;
66 }
67
68 *c = rbuf[rbuf_out++];
69 return EOK;
70}
71
72/** Receive count characters (with buffering) */
73static int recv_chars(int fd, char *c, size_t count)
74{
75 for (size_t i = 0; i < count; i++) {
76 int rc = recv_char(fd, c);
77 if (rc != EOK)
78 return rc;
79 c++;
80 }
81 return EOK;
82}
83
84static int recv_skip_chars(int fd, size_t count)
85{
86 for (size_t i = 0; i < count; i++) {
87 char c;
88 int rc = recv_char(fd, &c);
89 if (rc != EOK)
90 return rc;
91 }
92 return EOK;
93}
94
95static void rfb_pixel_format_to_be(rfb_pixel_format_t *src, rfb_pixel_format_t *dst)
96{
97 dst->r_max = host2uint16_t_be(src->r_max);
98 dst->g_max = host2uint16_t_be(src->g_max);
99 dst->b_max = host2uint16_t_be(src->b_max);
100}
101
102static void rfb_pixel_format_to_host(rfb_pixel_format_t *src, rfb_pixel_format_t *dst)
103{
104 dst->r_max = uint16_t_be2host(src->r_max);
105 dst->g_max = uint16_t_be2host(src->g_max);
106 dst->b_max = uint16_t_be2host(src->b_max);
107}
108
109static void rfb_server_init_to_be(rfb_server_init_t *src, rfb_server_init_t *dst)
110{
111 dst->width = host2uint16_t_be(src->width);
112 dst->height = host2uint16_t_be(src->height);
113 rfb_pixel_format_to_be(&src->pixel_format, &dst->pixel_format);
114 dst->name_length = host2uint32_t_be(src->name_length);
115}
116
117static void rfb_set_encodings_to_host(rfb_set_encodings_t *src, rfb_set_encodings_t *dst)
118{
119 dst->count = uint16_t_be2host(src->count);
120}
121
122static void rfb_framebuffer_update_request_to_host(rfb_framebuffer_update_request_t *src,
123 rfb_framebuffer_update_request_t *dst)
124{
125 dst->x = uint16_t_be2host(src->x);
126 dst->y = uint16_t_be2host(src->x);
127 dst->width = uint16_t_be2host(src->width);
128 dst->height = uint16_t_be2host(src->height);
129}
130
131static void rfb_framebuffer_update_to_be(rfb_framebuffer_update_t *src,
132 rfb_framebuffer_update_t *dst)
133{
134 dst->rect_count = host2uint16_t_be(src->rect_count);
135}
136
137static void rfb_rectangle_to_be(rfb_rectangle_t *src, rfb_rectangle_t *dst)
138{
139 dst->x = host2uint16_t_be(src->x);
140 dst->y = host2uint16_t_be(src->y);
141 dst->width = host2uint16_t_be(src->width);
142 dst->height = host2uint16_t_be(src->height);
143 dst->enctype = host2uint32_t_be(src->enctype);
144}
145
146static void rfb_key_event_to_host(rfb_key_event_t *src, rfb_key_event_t *dst)
147{
148 dst->key = uint32_t_be2host(src->key);
149}
150
151static void rfb_pointer_event_to_host(rfb_pointer_event_t *src, rfb_pointer_event_t *dst)
152{
153 dst->x = uint16_t_be2host(src->x);
154 dst->y = uint16_t_be2host(src->y);
155}
156
157static void rfb_client_cut_text_to_host(rfb_client_cut_text_t *src,
158 rfb_client_cut_text_t *dst)
159{
160 dst->length = uint32_t_be2host(src->length);
161}
162
163int rfb_init(rfb_t *rfb, uint16_t width, uint16_t height, const char *name)
164{
165 memset(rfb, 0, sizeof(rfb_t));
166 fibril_mutex_initialize(&rfb->lock);
167
168 rfb_pixel_format_t *pf = &rfb->pixel_format;
169 pf->bpp = 32;
170 pf->depth = 24;
171 pf->big_endian = 1;
172 pf->true_color = 1;
173 pf->r_max = 255;
174 pf->g_max = 255;
175 pf->b_max = 255;
176 pf->r_shift = 0;
177 pf->g_shift = 8;
178 pf->b_shift = 16;
179
180 rfb->name = str_dup(name);
181 rfb->supports_trle = false;
182
183 return rfb_set_size(rfb, width, height);
184}
185
186int rfb_set_size(rfb_t *rfb, uint16_t width, uint16_t height)
187{
188 size_t new_size = width * height * sizeof(pixel_t);
189 void *pixbuf = malloc(new_size);
190 if (pixbuf == NULL)
191 return ENOMEM;
192
193 free(rfb->framebuffer.data);
194 rfb->framebuffer.data = pixbuf;
195 rfb->framebuffer.width = width;
196 rfb->framebuffer.height = height;
197 rfb->width = width;
198 rfb->height = height;
199
200 /* Fill with white */
201 memset(rfb->framebuffer.data, 255, new_size);
202
203 return EOK;
204}
205
206static int recv_message(int conn_sd, char type, void *buf, size_t size)
207{
208 memcpy(buf, &type, 1);
209 return recv_chars(conn_sd, ((char *) buf) + 1, size -1);
210}
211
212static uint32_t rfb_scale_channel(uint8_t val, uint32_t max)
213{
214 return val * max / 255;
215}
216
217static void rfb_encode_index(rfb_t *rfb, uint8_t *buf, pixel_t pixel)
218{
219 int first_free_index = -1;
220 for (size_t i = 0; i < 256; i++) {
221 bool free = ALPHA(rfb->palette[i]) == 0;
222 if (free && first_free_index == -1) {
223 first_free_index = i;
224 }
225 else if (!free && RED(rfb->palette[i]) == RED(pixel) &&
226 GREEN(rfb->palette[i]) == GREEN(pixel) &&
227 BLUE(rfb->palette[i]) == BLUE(pixel)) {
228 *buf = i;
229 return;
230 }
231 }
232
233 if (first_free_index != -1) {
234 rfb->palette[first_free_index] = PIXEL(255, RED(pixel), GREEN(pixel),
235 BLUE(pixel));
236 rfb->palette_used = max(rfb->palette_used, (unsigned) first_free_index + 1);
237 *buf = first_free_index;
238 return;
239 }
240
241 /* TODO find nearest color index. We are lazy so return index 0 for now */
242 *buf = 0;
243}
244
245static void rfb_encode_true_color(rfb_pixel_format_t *pf, void *buf,
246 pixel_t pixel)
247{
248 uint32_t pix = 0;
249 pix |= rfb_scale_channel(RED(pixel), pf->r_max) << pf->r_shift;
250 pix |= rfb_scale_channel(GREEN(pixel), pf->g_max) << pf->g_shift;
251 pix |= rfb_scale_channel(BLUE(pixel), pf->b_max) << pf->b_shift;
252
253 if (pf->bpp == 8) {
254 uint8_t pix8 = pix;
255 memcpy(buf, &pix8, 1);
256 }
257 else if (pf->bpp == 16) {
258 uint16_t pix16 = pix;
259 if (pf->big_endian) {
260 pix16 = host2uint16_t_be(pix16);
261 }
262 else {
263 pix16 = host2uint16_t_le(pix16);
264 }
265 memcpy(buf, &pix16, 2);
266 }
267 else if (pf->bpp == 32) {
268 if (pf->big_endian) {
269 pix = host2uint32_t_be(pix);
270 }
271 else {
272 pix = host2uint32_t_le(pix);
273 }
274 memcpy(buf, &pix, 4);
275 }
276}
277
278static void rfb_encode_pixel(rfb_t *rfb, void *buf, pixel_t pixel)
279{
280 if (rfb->pixel_format.true_color) {
281 rfb_encode_true_color(&rfb->pixel_format, buf, pixel);
282 }
283 else {
284 rfb_encode_index(rfb, buf, pixel);
285 }
286}
287
288static void rfb_set_color_map_entries_to_be(rfb_set_color_map_entries_t *src,
289 rfb_set_color_map_entries_t *dst)
290{
291 dst->first_color = host2uint16_t_be(src->first_color);
292 dst->color_count = host2uint16_t_be(src->color_count);
293}
294
295static void rfb_color_map_entry_to_be(rfb_color_map_entry_t *src,
296 rfb_color_map_entry_t *dst)
297{
298 dst->red = host2uint16_t_be(src->red);
299 dst->green = host2uint16_t_be(src->green);
300 dst->blue = host2uint16_t_be(src->blue);
301}
302
303static int rfb_send_palette(int conn_sd, rfb_t *rfb)
304{
305 size_t size = sizeof(rfb_set_color_map_entries_t) +
306 rfb->palette_used * sizeof(rfb_color_map_entry_t);
307
308 void *buf = malloc(size);
309 if (buf == NULL)
310 return ENOMEM;
311
312 void *pos = buf;
313
314 rfb_set_color_map_entries_t *scme = pos;
315 scme->message_type = RFB_SMSG_SET_COLOR_MAP_ENTRIES;
316 scme->first_color = 0;
317 scme->color_count = rfb->palette_used;
318 rfb_set_color_map_entries_to_be(scme, scme);
319 pos += sizeof(rfb_set_color_map_entries_t);
320
321 rfb_color_map_entry_t *entries = pos;
322 for (unsigned i = 0; i < rfb->palette_used; i++) {
323 entries[i].red = 65535 * RED(rfb->palette[i]) / 255;
324 entries[i].green = 65535 * GREEN(rfb->palette[i]) / 255;
325 entries[i].blue = 65535 * BLUE(rfb->palette[i]) / 255;
326 rfb_color_map_entry_to_be(&entries[i], &entries[i]);
327 }
328
329 int rc = send(conn_sd, buf, size, 0);
330 free(buf);
331
332 return rc;
333}
334
335static size_t rfb_rect_encode_raw(rfb_t *rfb, rfb_rectangle_t *rect, void *buf)
336{
337 size_t pixel_size = rfb->pixel_format.bpp / 8;
338 size_t size = (rect->width * rect->height * pixel_size);
339
340 if (buf == NULL)
341 return size;
342
343 for (uint16_t y = 0; y < rect->height; y++) {
344 for (uint16_t x = 0; x < rect->width; x++) {
345 pixel_t pixel = pixelmap_get_pixel(&rfb->framebuffer,
346 x + rect->x, y + rect->y);
347 rfb_encode_pixel(rfb, buf, pixel);
348 buf += pixel_size;
349 }
350 }
351
352 return size;
353}
354
355typedef enum {
356 COMP_NONE, COMP_SKIP_START, COMP_SKIP_END
357} cpixel_compress_type_t;
358
359typedef struct {
360 size_t size;
361 cpixel_compress_type_t compress_type;
362} cpixel_ctx_t;
363
364static void cpixel_context_init(cpixel_ctx_t *ctx, rfb_pixel_format_t *pixel_format)
365{
366 ctx->size = pixel_format->bpp / 8;
367 ctx->compress_type = COMP_NONE;
368
369 if (pixel_format->bpp == 32 && pixel_format->depth <= 24) {
370 uint32_t mask = 0;
371 mask |= pixel_format->r_max << pixel_format->r_shift;
372 mask |= pixel_format->g_max << pixel_format->g_shift;
373 mask |= pixel_format->b_max << pixel_format->b_shift;
374
375 if (pixel_format->big_endian) {
376 mask = host2uint32_t_be(mask);
377 }
378 else {
379 mask = host2uint32_t_le(mask);
380 }
381
382 uint8_t *mask_data = (uint8_t *) &mask;
383 if (mask_data[0] == 0) {
384 ctx->compress_type = COMP_SKIP_START;
385 ctx->size = 3;
386 }
387 else if (mask_data[3] == 0) {
388 ctx->compress_type = COMP_SKIP_END;
389 ctx->size = 3;
390 }
391 }
392}
393
394static void cpixel_encode(rfb_t *rfb, cpixel_ctx_t *cpixel, void *buf,
395 pixel_t pixel)
396{
397 uint8_t data[4];
398 rfb_encode_pixel(rfb, data, pixel);
399
400 switch (cpixel->compress_type) {
401 case COMP_NONE:
402 case COMP_SKIP_END:
403 memcpy(buf, data, cpixel->size);
404 break;
405 case COMP_SKIP_START:
406 memcpy(buf, data + 1, cpixel->size);
407 }
408}
409
410static ssize_t rfb_tile_encode_raw(rfb_t *rfb, cpixel_ctx_t *cpixel,
411 rfb_rectangle_t *tile, void *buf)
412{
413 ssize_t size = tile->width * tile->height * cpixel->size;
414 if (buf == NULL)
415 return size;
416
417 for (uint16_t y = tile->y; y < tile->y + tile->height; y++) {
418 for (uint16_t x = tile->x; x < tile->x + tile->width; x++) {
419 pixel_t pixel = pixelmap_get_pixel(&rfb->framebuffer, x, y);
420 cpixel_encode(rfb, cpixel, buf, pixel);
421 }
422 }
423
424 return size;
425}
426
427static ssize_t rfb_tile_encode_solid(rfb_t *rfb, cpixel_ctx_t *cpixel,
428 rfb_rectangle_t *tile, void *buf)
429{
430 /* Check if it is single color */
431 pixel_t the_color = pixelmap_get_pixel(&rfb->framebuffer, tile->x, tile->y);
432 for (uint16_t y = tile->y; y < tile->y + tile->height; y++) {
433 for (uint16_t x = tile->x; x < tile->x + tile->width; x++) {
434 if (pixelmap_get_pixel(&rfb->framebuffer, x, y) != the_color)
435 return -1;
436 }
437 }
438
439 /* OK, encode it */
440 if (buf)
441 cpixel_encode(rfb, cpixel, buf, the_color);
442 return cpixel->size;
443}
444
445static size_t rfb_rect_encode_trle(rfb_t *rfb, rfb_rectangle_t *rect, void *buf)
446{
447 cpixel_ctx_t cpixel;
448 cpixel_context_init(&cpixel, &rfb->pixel_format);
449
450 size_t size = 0;
451 for (uint16_t y = 0; y < rect->height; y += 16) {
452 for (uint16_t x = 0; x < rect->width; x += 16) {
453 rfb_rectangle_t tile = {
454 .x = x,
455 .y = y,
456 .width = (x + 16 <= rect->width ? 16 : rect->width - x),
457 .height = (y + 16 <= rect->height ? 16 : rect->height - y)
458 };
459
460 size += 1;
461 uint8_t *tile_enctype_ptr = buf;
462 if (buf)
463 buf += 1;
464
465 uint8_t tile_enctype = RFB_TILE_ENCODING_SOLID;
466 ssize_t tile_size = rfb_tile_encode_solid(rfb, &cpixel, &tile, buf);
467 if (tile_size < 0) {
468 tile_size = rfb_tile_encode_raw(rfb, &cpixel, &tile, buf);
469 tile_enctype = RFB_TILE_ENCODING_RAW;
470 }
471
472 if (buf) {
473 *tile_enctype_ptr = tile_enctype;
474 buf += tile_size;
475 }
476 }
477 }
478 return size;
479}
480
481static int rfb_send_framebuffer_update(rfb_t *rfb, int conn_sd, bool incremental)
482{
483 if (!incremental || !rfb->damage_valid) {
484 rfb->damage_rect.x = 0;
485 rfb->damage_rect.y = 0;
486 rfb->damage_rect.width = rfb->width;
487 rfb->damage_rect.height = rfb->height;
488 }
489
490
491 /* We send only single raw rectangle right now */
492 size_t buf_size = sizeof(rfb_framebuffer_update_t) +
493 sizeof(rfb_rectangle_t) * 1 +
494 rfb_rect_encode_raw(rfb, &rfb->damage_rect, NULL)
495 ;
496
497 void *buf = malloc(buf_size);
498 if (buf == NULL)
499 return ENOMEM;
500 memset(buf, 0, buf_size);
501
502 void *pos = buf;
503 rfb_framebuffer_update_t *fbu = buf;
504 fbu->message_type = RFB_SMSG_FRAMEBUFFER_UPDATE;
505 fbu->rect_count = 1;
506 rfb_framebuffer_update_to_be(fbu, fbu);
507 pos += sizeof(rfb_framebuffer_update_t);
508
509 rfb_rectangle_t *rect = pos;
510 pos += sizeof(rfb_rectangle_t);
511
512 *rect = rfb->damage_rect;
513
514 if (rfb->supports_trle) {
515 rect->enctype = RFB_ENCODING_TRLE;
516 pos += rfb_rect_encode_trle(rfb, rect, pos);
517 }
518 else {
519 rect->enctype = RFB_ENCODING_RAW;
520 pos += rfb_rect_encode_raw(rfb, rect, pos);
521 }
522 rfb_rectangle_to_be(rect, rect);
523
524 if (!rfb->pixel_format.true_color) {
525 int rc = rfb_send_palette(conn_sd, rfb);
526 if (rc != EOK) {
527 free(buf);
528 return rc;
529 }
530 }
531
532 int rc = send(conn_sd, buf, buf_size, 0);
533 free(buf);
534 rfb->damage_valid = false;
535 return rc;
536}
537
538static int rfb_set_pixel_format(rfb_t *rfb, rfb_pixel_format_t *pixel_format)
539{
540 rfb->pixel_format = *pixel_format;
541 if (rfb->pixel_format.true_color) {
542 free(rfb->palette);
543 rfb->palette = NULL;
544 rfb->palette_used = 0;
545 log_msg(LOG_DEFAULT, LVL_DEBUG,
546 "changed pixel format to %d-bit true color (%x<<%d, %x<<%d, %x<<%d)",
547 pixel_format->depth, pixel_format->r_max, pixel_format->r_shift,
548 pixel_format->g_max, pixel_format->g_shift, pixel_format->b_max,
549 pixel_format->b_shift);
550 }
551 else {
552 if (rfb->palette == NULL) {
553 rfb->palette = malloc(sizeof(pixel_t) * 256);
554 if (rfb->palette == NULL)
555 return ENOMEM;
556 memset(rfb->palette, 0, sizeof(pixel_t) * 256);
557 rfb->palette_used = 0;
558 }
559 log_msg(LOG_DEFAULT, LVL_DEBUG, "changed pixel format to %d-bit palette",
560 pixel_format->depth);
561 }
562 return EOK;
563}
564
565static void rfb_socket_connection(rfb_t *rfb, int conn_sd)
566{
567 /* Version handshake */
568 int rc = send(conn_sd, "RFB 003.008\n", 12, 0);
569 if (rc != EOK) {
570 log_msg(LOG_DEFAULT, LVL_WARN, "Failed sending server version %d", rc);
571 return;
572 }
573
574 char client_version[12];
575 rc = recv_chars(conn_sd, client_version, 12);
576 if (rc != EOK) {
577 log_msg(LOG_DEFAULT, LVL_WARN, "Failed receiving client version: %d", rc);
578 return;
579 }
580
581 if (memcmp(client_version, "RFB 003.008\n", 12) != 0) {
582 log_msg(LOG_DEFAULT, LVL_WARN, "Client version is not RFB 3.8");
583 return;
584 }
585
586 /* Security handshake
587 * 1 security type supported, which is 1 - None
588 */
589 char sec_types[2];
590 sec_types[0] = 1; /* length */
591 sec_types[1] = RFB_SECURITY_NONE;
592 rc = send(conn_sd, sec_types, 2, 0);
593 if (rc != EOK) {
594 log_msg(LOG_DEFAULT, LVL_WARN,
595 "Failed sending security handshake: %d", rc);
596 return;
597 }
598
599 char selected_sec_type = 0;
600 rc = recv_char(conn_sd, &selected_sec_type);
601 if (rc != EOK) {
602 log_msg(LOG_DEFAULT, LVL_WARN, "Failed receiving security type: %d", rc);
603 return;
604 }
605 if (selected_sec_type != RFB_SECURITY_NONE) {
606 log_msg(LOG_DEFAULT, LVL_WARN,
607 "Client selected security type other than none");
608 return;
609 }
610 uint32_t security_result = RFB_SECURITY_HANDSHAKE_OK;
611 rc = send(conn_sd, &security_result, sizeof(uint32_t), 0);
612 if (rc != EOK) {
613 log_msg(LOG_DEFAULT, LVL_WARN, "Failed sending security result: %d", rc);
614 return;
615 }
616
617 /* Client init */
618 char shared_flag;
619 rc = recv_char(conn_sd, &shared_flag);
620 if (rc != EOK) {
621 log_msg(LOG_DEFAULT, LVL_WARN, "Failed receiving client init: %d", rc);
622 return;
623 }
624
625 /* Server init */
626 fibril_mutex_lock(&rfb->lock);
627 size_t name_length = str_length(rfb->name);
628 size_t msg_length = sizeof(rfb_server_init_t) + name_length;
629 rfb_server_init_t *server_init = malloc(msg_length);
630 if (server_init == NULL) {
631 log_msg(LOG_DEFAULT, LVL_WARN, "Cannot allocate memory for server init");
632 fibril_mutex_unlock(&rfb->lock);
633 return;
634 }
635 server_init->width = rfb->width;
636 server_init->height = rfb->height;
637 server_init->pixel_format = rfb->pixel_format,
638 server_init->name_length = name_length;
639 rfb_server_init_to_be(server_init, server_init);
640 memcpy(server_init->name, rfb->name, name_length);
641 fibril_mutex_unlock(&rfb->lock);
642 rc = send(conn_sd, server_init, msg_length, 0);
643 if (rc != EOK) {
644 log_msg(LOG_DEFAULT, LVL_WARN, "Failed sending server init: %d", rc);
645 return;
646 }
647
648 while (true) {
649 char message_type = 0;
650 rc = recv_char(conn_sd, &message_type);
651 if (rc != EOK) {
652 log_msg(LOG_DEFAULT, LVL_WARN,
653 "Failed receiving client message type");
654 return;
655 }
656
657 rfb_set_pixel_format_t spf;
658 rfb_set_encodings_t se;
659 rfb_framebuffer_update_request_t fbur;
660 rfb_key_event_t ke;
661 rfb_pointer_event_t pe;
662 rfb_client_cut_text_t cct;
663 switch (message_type) {
664 case RFB_CMSG_SET_PIXEL_FORMAT:
665 recv_message(conn_sd, message_type, &spf, sizeof(spf));
666 rfb_pixel_format_to_host(&spf.pixel_format, &spf.pixel_format);
667 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received SetPixelFormat message");
668 fibril_mutex_lock(&rfb->lock);
669 rc = rfb_set_pixel_format(rfb, &spf.pixel_format);
670 fibril_mutex_unlock(&rfb->lock);
671 if (rc != EOK)
672 return;
673 break;
674 case RFB_CMSG_SET_ENCODINGS:
675 recv_message(conn_sd, message_type, &se, sizeof(se));
676 rfb_set_encodings_to_host(&se, &se);
677 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received SetEncodings message");
678 for (uint16_t i = 0; i < se.count; i++) {
679 int32_t encoding = 0;
680 rc = recv_chars(conn_sd, (char *) &encoding, sizeof(int32_t));
681 if (rc != EOK)
682 return;
683 encoding = uint32_t_be2host(encoding);
684 if (encoding == RFB_ENCODING_TRLE) {
685 log_msg(LOG_DEFAULT, LVL_DEBUG,
686 "Client supports TRLE encoding");
687 rfb->supports_trle = true;
688 }
689 }
690 break;
691 case RFB_CMSG_FRAMEBUFFER_UPDATE_REQUEST:
692 recv_message(conn_sd, message_type, &fbur, sizeof(fbur));
693 rfb_framebuffer_update_request_to_host(&fbur, &fbur);
694 log_msg(LOG_DEFAULT, LVL_DEBUG2,
695 "Received FramebufferUpdateRequest message");
696 fibril_mutex_lock(&rfb->lock);
697 rfb_send_framebuffer_update(rfb, conn_sd, fbur.incremental);
698 fibril_mutex_unlock(&rfb->lock);
699 break;
700 case RFB_CMSG_KEY_EVENT:
701 recv_message(conn_sd, message_type, &ke, sizeof(ke));
702 rfb_key_event_to_host(&ke, &ke);
703 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received KeyEvent message");
704 break;
705 case RFB_CMSG_POINTER_EVENT:
706 recv_message(conn_sd, message_type, &pe, sizeof(pe));
707 rfb_pointer_event_to_host(&pe, &pe);
708 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received PointerEvent message");
709 break;
710 case RFB_CMSG_CLIENT_CUT_TEXT:
711 recv_message(conn_sd, message_type, &cct, sizeof(cct));
712 rfb_client_cut_text_to_host(&cct, &cct);
713 log_msg(LOG_DEFAULT, LVL_DEBUG2, "Received ClientCutText message");
714 recv_skip_chars(conn_sd, cct.length);
715 break;
716 default:
717 log_msg(LOG_DEFAULT, LVL_WARN,
718 "Invalid client message type encountered");
719 return;
720 }
721 }
722}
723
724int rfb_listen(rfb_t *rfb, uint16_t port) {
725 struct sockaddr_in addr;
726
727 addr.sin_family = AF_INET;
728 addr.sin_port = htons(port);
729
730 int rc = inet_pton(AF_INET, "127.0.0.1", (void *)
731 &addr.sin_addr.s_addr);
732 if (rc != EOK) {
733 log_msg(LOG_DEFAULT, LVL_ERROR, "Error parsing network address (%s)",
734 str_error(rc));
735 return rc;
736 }
737
738 int listen_sd = socket(PF_INET, SOCK_STREAM, 0);
739 if (listen_sd < 0) {
740 log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating listening socket (%s)",
741 str_error(listen_sd));
742 return rc;
743 }
744
745 rc = bind(listen_sd, (struct sockaddr *) &addr, sizeof(addr));
746 if (rc != EOK) {
747 log_msg(LOG_DEFAULT, LVL_ERROR, "Error binding socket (%s)",
748 str_error(rc));
749 return rc;
750 }
751
752 rc = listen(listen_sd, 2);
753 if (rc != EOK) {
754 log_msg(LOG_DEFAULT, LVL_ERROR, "listen() failed (%s)", str_error(rc));
755 return rc;
756 }
757
758 rfb->listen_sd = listen_sd;
759
760 return EOK;
761}
762
763void rfb_accept(rfb_t *rfb)
764{
765 while (true) {
766 struct sockaddr_in raddr;
767 socklen_t raddr_len = sizeof(raddr);
768 int conn_sd = accept(rfb->listen_sd, (struct sockaddr *) &raddr,
769 &raddr_len);
770
771 if (conn_sd < 0) {
772 log_msg(LOG_DEFAULT, LVL_WARN, "accept() failed (%s)",
773 str_error(conn_sd));
774 continue;
775 }
776
777 log_msg(LOG_DEFAULT, LVL_DEBUG, "Connection accepted");
778
779 rbuf_out = 0;
780 rbuf_in = 0;
781
782 rfb_socket_connection(rfb, conn_sd);
783 closesocket(conn_sd);
784 }
785}
Note: See TracBrowser for help on using the repository browser.