45 #include <sys/ioctl.h>
48 #if defined(__FreeBSD__)
52 #include <sys/termios.h>
59 #include <sys/types.h>
72 #include "debug/VNC.hh"
115 else if (revent & POLLNVAL)
146 DPRINTF(VNC,
"Vnc server created at port %d\n", p->port);
167 warn_once(
"Sockets disabled, not accepting vnc client connections");
173 "can't bind address vnc server port %d in use PID %d\n",
179 p2 =
name().rfind(
'.') - 1;
180 p1 =
name().rfind(
'.', p2);
181 ccprintf(cerr,
"Listening for %s connection on port %d\n",
182 name().substr(p1 + 1, p2 - p1), port);
198 panic(
"%s: cannot accept a connection if not listening!",
name());
202 warn(
"%s: failed to accept VNC connection!",
name());
207 char message[] =
"vnc server already attached!\n";
222 inform(
"VNC client attached\n");
230 DPRINTF(VNC,
"Vnc client message recieved\n");
250 uint8_t message_type;
251 if (!
read(&message_type))
254 switch (message_type) {
274 warn(
"Unimplemented message type recv from client: %d\n",
281 panic(
"Unknown vnc server state\n");
291 panic(
"vnc not properly attached.\n");
296 }
while (ret == -1 && errno == EINTR);
300 DPRINTF(VNC,
"Read failed %d.\n", ret);
311 return read(buf + 1, len - 1);
319 return read((uint8_t *)val,
sizeof(T));
327 panic(
"Vnc client not properly attached.\n");
332 DPRINTF(VNC,
"Write failed.\n");
344 return write((uint8_t *)val,
sizeof(T));
350 return write((uint8_t *)str, strlen(str));
370 inform(
"VNC client detached\n");
377 uint32_t
len = strlen(error_msg);
389 char version_string[13];
392 version_string[12] = 0;
394 if (!
read((uint8_t *)version_string,
sizeof(version_string) - 1)) {
395 warn(
"Failed to read protocol version.");
399 uint32_t major, minor;
402 if (sscanf(version_string,
"RFB %03d.%03d\n", &major, &minor) != 2) {
403 warn(
" Malformed protocol version %s\n", version_string);
404 sendError(
"Malformed protocol version\n");
409 DPRINTF(VNC,
"Client request protocol version %d.%d\n", major, minor);
412 if (major != 3 || minor < 2) {
413 warn(
"Unsupported VNC client version... disconnecting\n");
422 if (!
write(&sec_type))
440 uint8_t security_type;
441 if (!
read(&security_type))
445 warn(
"Unknown VNC security type\n");
449 DPRINTF(VNC,
"Sending security auth OK\n");
452 if (!
write(&success))
462 DPRINTF(VNC,
"Sending server init message to client\n");
480 memcpy(msg.
name,
"M5", 2);
490 DPRINTF(VNC,
"Received pixel format from client message\n");
496 DPRINTF(VNC,
" -- bpp = %d; depth = %d; be = %d\n", pfm.
px.
bpp,
498 DPRINTF(VNC,
" -- true color = %d red,green,blue max = %d,%d,%d\n",
514 warn(
"VNC client doesn't support true color raw encoding\n");
522 DPRINTF(VNC,
"Received supported encodings from client\n");
535 if (!
read(&encoding))
539 switch (
betoh(encoding)) {
550 warn(
"VNC clients must always support raw encoding\n");
558 DPRINTF(VNC,
"Received frame buffer update request from client\n");
569 DPRINTF(VNC,
" -- x = %d y = %d w = %d h = %d\n", fbr.
x, fbr.
y, fbr.
width,
578 DPRINTF(VNC,
"Received keyboard input from client\n");
594 DPRINTF(VNC,
"Received pointer input from client\n");
602 DPRINTF(VNC,
" -- pointer at x = %d y = %d buttons = %#x\n", pem.
x, pem.
y,
612 DPRINTF(VNC,
"Received client copy buffer message\n");
620 DPRINTF(VNC,
"String length %d\n", data_len);
621 while (data_len > 0) {
622 size_t bytes_to_read = data_len > 1024 ? 1024 : data_len;
623 if (!
read((uint8_t *)&str, bytes_to_read))
625 str[bytes_to_read] = 0;
626 data_len -= bytes_to_read;
627 DPRINTF(VNC,
"Buffer: %s\n", str);
638 DPRINTF(VNC,
"NOT sending framebuffer update\n");
645 DPRINTF(VNC,
"Sending framebuffer update\n");
673 for (
int y = 0; y <
fb->
height(); ++y) {
675 uint8_t *raw_pixel(line_buffer.data());
681 if (!
write(line_buffer.data(), line_buffer.size()))
690 DPRINTF(VNC,
"Sending framebuffer resize\n");
742 VncServerParams::create()
void ccprintf(cp::Print &print)
const Pixel & pixel(unsigned x, unsigned y) const
Get a pixel from an (x, y) coordinate.
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.
Channel ch_b
Blue channel conversion helper.
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.
unsigned height() const
Frame buffer height in pixels.
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.
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.
const char * vncVersion() const
virtual int accept(bool nodelay=false)
EventQueue * eventQueue() 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 int NumArgumentRegs M5_VAR_USED
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.
void checkProtocolVersion()
Check the client's protocol verion for compatibility and send the security types we support...
virtual const std::string name() const
unsigned width() const
Frame buffer width in pixels.
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.
bool write(const uint8_t *buf, size_t len)
Write a buffer to the client.
static const uint32_t VncOK
Error conditions.
uint32_t fromPixel(const Pixel &pixel) const
Convert a Pixel into a color word.
bool supportsResizeEnc
If the vnc client supports the desktop resize command.