45 #include <sys/ioctl.h> 48 #if defined(__FreeBSD__) 52 #include <sys/termios.h> 59 #include <sys/types.h> 71 #include "debug/VNC.hh" 114 else if (revent & POLLNVAL)
145 DPRINTF(VNC,
"Vnc server created at port %d\n", p->port);
166 warn_once(
"Sockets disabled, not accepting vnc client connections");
172 "can't bind address vnc server port %d in use PID %d\n",
177 ccprintf(cerr,
"%s: Listening for connections on port %d\n",
194 panic(
"%s: cannot accept a connection if not listening!",
name());
198 warn(
"%s: failed to accept VNC connection!",
name());
203 char message[] =
"vnc server already attached!\n";
218 inform(
"VNC client attached\n");
226 DPRINTF(VNC,
"Vnc client message recieved\n");
246 uint8_t message_type;
247 if (!
read(&message_type))
250 switch (message_type) {
270 warn(
"Unimplemented message type recv from client: %d\n",
277 panic(
"Unknown vnc server state\n");
287 panic(
"vnc not properly attached.\n");
292 }
while (ret == -1 && errno == EINTR);
296 DPRINTF(VNC,
"Read failed %d.\n", ret);
307 return read(buf + 1, len - 1);
315 return read((uint8_t *)val,
sizeof(T));
323 panic(
"Vnc client not properly attached.\n");
328 DPRINTF(VNC,
"Write failed.\n");
340 return write((uint8_t *)val,
sizeof(T));
346 return write((uint8_t *)str, strlen(str));
366 inform(
"VNC client detached\n");
373 uint32_t
len = strlen(error_msg);
385 char version_string[13];
388 version_string[12] = 0;
390 if (!
read((uint8_t *)version_string,
sizeof(version_string) - 1)) {
391 warn(
"Failed to read protocol version.");
395 uint32_t major, minor;
398 if (sscanf(version_string,
"RFB %03d.%03d\n", &major, &minor) != 2) {
399 warn(
" Malformed protocol version %s\n", version_string);
400 sendError(
"Malformed protocol version\n");
405 DPRINTF(VNC,
"Client request protocol version %d.%d\n", major, minor);
408 if (major != 3 || minor < 2) {
409 warn(
"Unsupported VNC client version... disconnecting\n");
418 if (!
write(&sec_type))
436 uint8_t security_type;
437 if (!
read(&security_type))
441 warn(
"Unknown VNC security type\n");
445 DPRINTF(VNC,
"Sending security auth OK\n");
448 if (!
write(&success))
458 DPRINTF(VNC,
"Sending server init message to client\n");
476 memcpy(msg.
name,
"M5", 2);
486 DPRINTF(VNC,
"Received pixel format from client message\n");
492 DPRINTF(VNC,
" -- bpp = %d; depth = %d; be = %d\n", pfm.px.bpp,
493 pfm.px.depth, pfm.px.bigendian);
494 DPRINTF(VNC,
" -- true color = %d red,green,blue max = %d,%d,%d\n",
495 pfm.px.truecolor,
betoh(pfm.px.redmax),
betoh(pfm.px.greenmax),
496 betoh(pfm.px.bluemax));
497 DPRINTF(VNC,
" -- red,green,blue shift = %d,%d,%d\n", pfm.px.redshift,
498 pfm.px.greenshift, pfm.px.blueshift);
510 warn(
"VNC client doesn't support true color raw encoding\n");
518 DPRINTF(VNC,
"Received supported encodings from client\n");
526 DPRINTF(VNC,
" -- %d encoding present\n", pem.num_encodings);
529 for (
int x = 0;
x < pem.num_encodings;
x++) {
531 if (!
read(&encoding))
535 switch (
betoh(encoding)) {
546 warn(
"VNC clients must always support raw encoding\n");
554 DPRINTF(VNC,
"Received frame buffer update request from client\n");
561 fbr.y =
betoh(fbr.y);
562 fbr.width =
betoh(fbr.width);
563 fbr.height =
betoh(fbr.height);
565 DPRINTF(VNC,
" -- x = %d y = %d w = %d h = %d\n", fbr.x, fbr.y, fbr.width,
574 DPRINTF(VNC,
"Received keyboard input from client\n");
580 DPRINTF(VNC,
" -- received key code %d (%s)\n", kem.key, kem.down_flag ?
590 DPRINTF(VNC,
"Received pointer input from client\n");
597 pem.y =
betoh(pem.y);
598 DPRINTF(VNC,
" -- pointer at x = %d y = %d buttons = %#x\n", pem.x, pem.y,
608 DPRINTF(VNC,
"Received client copy buffer message\n");
615 size_t data_len =
betoh(cct.length);
616 DPRINTF(VNC,
"String length %d\n", data_len);
617 while (data_len > 0) {
618 size_t bytes_to_read = data_len > 1024 ? 1024 : data_len;
619 if (!
read((uint8_t *)&str, bytes_to_read))
621 str[bytes_to_read] = 0;
622 data_len -= bytes_to_read;
623 DPRINTF(VNC,
"Buffer: %s\n", str);
634 DPRINTF(VNC,
"NOT sending framebuffer update\n");
641 DPRINTF(VNC,
"Sending framebuffer update\n");
669 for (
int y = 0; y <
fb->
height(); ++y) {
671 uint8_t *raw_pixel(line_buffer.data());
677 if (!
write(line_buffer.data(), line_buffer.size()))
686 DPRINTF(VNC,
"Sending framebuffer resize\n");
738 VncServerParams::create()
#define panic(...)
This implements a cprintf based panic() function.
void ccprintf(cp::Print &print)
virtual bool listen(int port, bool reuse=true)
static const uint32_t AuthInvalid
Authentication modes.
Channel ch_g
Green channel conversion helper.
unsigned length
Bytes per pixel when stored in memory (including padding)
PixelFormat pixelFormat
The one and only pixel format we support.
void requestFbUpdate()
Receive message from client asking for updated frame buffer.
void sendFrameBufferResized()
Tell the client that the frame buffer resized.
const Pixel & pixel(unsigned x, unsigned y) const
Get a pixel from an (x, y) coordinate.
Channel ch_b
Blue channel conversion helper.
Overload hash function for BasicBlockRange type.
unsigned mask
Bit mask (after shifting)
VncServer(const Params *p)
VncServer.
ConnectionState curState
The rfb prototol state the connection is in.
void setEncodings()
Receive encodings message from client and process it.
unsigned depth
Number of bits used to represent one pixel value (excluding padding).
void sendError(const char *error_msg)
vnc client Interface
void schedule(PollEvent *event)
void checkSecurity()
Check that the security exchange was successful.
ListenEvent(VncServer *vs, int fd, int e)
Poll event for the listen socket.
void setPixelFormat()
Receive pixel foramt message from client and process it.
Temporarily migrate execution to a different event queue.
unsigned offset
Offset in bits.
ByteOrder byte_order
Byte order when stored to memory.
static bool allDisabled()
bool read1(uint8_t *buf, size_t len)
Read len -1 bytes from the client into the buffer provided + 1 assert that we read enough bytes...
ssize_t atomic_write(int fd, const void *s, size_t n)
virtual void mouseAt(uint16_t x, uint16_t y, uint8_t buttons)=0
called whenever the mouse moves or it's button state changes buttons is a simple mask with each butto...
void recvPointerInput()
Recv message from client providing new mouse movement or button click.
void frameBufferResized() override
static const PixelConverter pixelConverter
ListenEvent * listenEvent
Channel ch_r
Red channel conversion helper.
uint32_t fromPixel(const Pixel &pixel) const
Convert a Pixel into a color word.
bool supportsRawEnc
If the vnc client supports receiving raw data.
void setDirty() override
The frame buffer uses this call to notify the vnc server that the frame buffer has been updated and a...
void sendServerInit()
Send client our idea about what the frame buffer looks like.
virtual int accept(bool nodelay=false)
virtual const std::string name() const
Bitfield< 27, 25 > encoding
bool read(uint8_t *buf, size_t len)
Read some data from the client.
void recvKeyboardInput()
Receive message from client providing new keyboard input.
void sendFrameBufferUpdate()
Send a updated frame buffer to the client.
static const uint32_t AuthNone
virtual void keyPress(uint32_t key, bool down)=0
Called when the vnc server receives a key press event from the client.
EventQueue * eventQueue() const
void checkProtocolVersion()
Check the client's protocol verion for compatibility and send the security types we support...
void remove(PollEvent *event)
bool sendUpdate
An update needs to be sent to the client.
Declaration of a VNC server.
DataEvent(VncServer *vs, int fd, int e)
Poll event for the data socket.
void recvCutText()
Receive message from client that there is text in it's paste buffer.
Configurable RGB pixel converter.
static const int NumArgumentRegs M5_VAR_USED
unsigned width() const
Frame buffer width in pixels.
const char * vncVersion() const
bool write(const uint8_t *buf, size_t len)
Write a buffer to the client.
unsigned height() const
Frame buffer height in pixels.
static const uint32_t VncOK
Error conditions.
bool supportsResizeEnc
If the vnc client supports the desktop resize command.