VNC: Implemented 3.8 protocol. Seems to be required by my RealVNC client
This commit is contained in:
parent
8bcb5f0251
commit
f3515a242d
|
@ -991,8 +991,8 @@ CONFIG_NXFONT_SANS28X37=y
|
||||||
#
|
#
|
||||||
# CONFIG_NX_MULTIUSER is not set
|
# CONFIG_NX_MULTIUSER is not set
|
||||||
CONFIG_VNCSERVER=y
|
CONFIG_VNCSERVER=y
|
||||||
CONFIG_VNCSERVER_PROTO3p3=y
|
# CONFIG_VNCSERVER_PROTO3p3 is not set
|
||||||
# CONFIG_VNCSERVER_PROTO3p8 is not set
|
CONFIG_VNCSERVER_PROTO3p8=y
|
||||||
CONFIG_VNCSERVER_NDISPLAYS=1
|
CONFIG_VNCSERVER_NDISPLAYS=1
|
||||||
CONFIG_VNCSERVER_PRIO=100
|
CONFIG_VNCSERVER_PRIO=100
|
||||||
CONFIG_VNCSERVER_STACKSIZE=2048
|
CONFIG_VNCSERVER_STACKSIZE=2048
|
||||||
|
|
|
@ -16,14 +16,14 @@ if VNCSERVER
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "VNC server protocol"
|
prompt "VNC server protocol"
|
||||||
default VNCSERVER_PROTO3p3
|
default VNCSERVER_PROTO3p8
|
||||||
|
|
||||||
config VNCSERVER_PROTO3p3
|
config VNCSERVER_PROTO3p3
|
||||||
bool "Version 3.3"
|
bool "Version 3.3"
|
||||||
|
depends on EXPERIMENTAL
|
||||||
|
|
||||||
config VNCSERVER_PROTO3p8
|
config VNCSERVER_PROTO3p8
|
||||||
bool "Version 3.8"
|
bool "Version 3.8"
|
||||||
depends on EXPERIMENTAL
|
|
||||||
|
|
||||||
endchoice # VNC server protocol
|
endchoice # VNC server protocol
|
||||||
|
|
||||||
|
@ -66,10 +66,24 @@ endchoice # VNC color format
|
||||||
config VNCSERVER_SCREENWIDTH
|
config VNCSERVER_SCREENWIDTH
|
||||||
int "Framebuffer width (pixels)"
|
int "Framebuffer width (pixels)"
|
||||||
default 320
|
default 320
|
||||||
|
---help---
|
||||||
|
This setting defines the width in pixels of the local framebuffer.
|
||||||
|
|
||||||
|
Memory usage: PixelWidth * ScreenWidth * ScreenHeight
|
||||||
|
|
||||||
|
So, for example, a 320x240 screen with RGB16 pixels would require
|
||||||
|
2x320x240 = 150 KB of RAM.
|
||||||
|
|
||||||
config VNCSERVER_SCREENHEIGHT
|
config VNCSERVER_SCREENHEIGHT
|
||||||
int "Framebuffer height (rows)"
|
int "Framebuffer height (rows)"
|
||||||
default 240
|
default 240
|
||||||
|
---help---
|
||||||
|
This setting defines the height in rows of the local framebuffer.
|
||||||
|
|
||||||
|
Memory usage: PixelWidth * ScreenWidth * ScreenHeight
|
||||||
|
|
||||||
|
So, for example, a 320x240 screen with RGB16 pixels would require
|
||||||
|
2x320x240 = 150 KB of RAM.
|
||||||
|
|
||||||
config VNCSERVER_NUPDATES
|
config VNCSERVER_NUPDATES
|
||||||
int "Number of pre-allocate update structures"
|
int "Number of pre-allocate update structures"
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p3;
|
static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p3;
|
||||||
#elif defined(CONFIG_VNCSERVER_PROTO3p8)
|
#elif defined(CONFIG_VNCSERVER_PROTO3p8)
|
||||||
static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p8;
|
static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p8;
|
||||||
|
static const char g_nosecurity[] = "No security types are supported";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -84,10 +85,16 @@ static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p8;
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_VNCSERVER_PROTO3p3
|
|
||||||
int vnc_negotiate(FAR struct vnc_session_s *session)
|
int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_VNCSERVER_PROTO3p3
|
||||||
FAR struct rfb_sectype_s *sectype;
|
FAR struct rfb_sectype_s *sectype;
|
||||||
|
#else /* ifdef CONFIG_VNCSERVER_PROTO3p8 */
|
||||||
|
FAR struct rfb_supported_sectypes_s *sectypes;
|
||||||
|
FAR struct rfb_selected_sectype_s *sectype;
|
||||||
|
FAR struct rfb_sectype_result_s *secresult;
|
||||||
|
FAR struct rfb_sectype_fail_s *secfail;
|
||||||
|
#endif
|
||||||
FAR struct rfb_serverinit_s *serverinit;
|
FAR struct rfb_serverinit_s *serverinit;
|
||||||
FAR struct rfb_pixelfmt_s *pixelfmt;
|
FAR struct rfb_pixelfmt_s *pixelfmt;
|
||||||
FAR struct rfb_setpixelformat_s *setformat;
|
FAR struct rfb_setpixelformat_s *setformat;
|
||||||
|
@ -148,13 +155,13 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||||
|
|
||||||
DEBUGASSERT(nrecvd == len);
|
DEBUGASSERT(nrecvd == len);
|
||||||
|
|
||||||
/* Tell the client that we won't use any stinkin' security.
|
#ifdef CONFIG_VNCSERVER_PROTO3p3
|
||||||
*
|
/* Version 3.3: The server decides the security type and sends a single
|
||||||
* "Version 3.3 The server decides the security type and sends a single
|
* word containing the security type: Tell the client that we won't use
|
||||||
* word:"
|
* any stinkin' security.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gvdbg("Send security type (None)\n");
|
gvdbg("Send SecurityType\n");
|
||||||
|
|
||||||
sectype = (FAR struct rfb_sectype_s *)session->outbuf;
|
sectype = (FAR struct rfb_sectype_s *)session->outbuf;
|
||||||
rfb_putbe32(sectype->type, RFB_SECTYPE_NONE);
|
rfb_putbe32(sectype->type, RFB_SECTYPE_NONE);
|
||||||
|
@ -171,6 +178,110 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||||
|
|
||||||
DEBUGASSERT(nsent == sizeof(struct rfb_sectype_s));
|
DEBUGASSERT(nsent == sizeof(struct rfb_sectype_s));
|
||||||
|
|
||||||
|
#else /* ifdef CONFIG_VNCSERVER_PROTO3p8 */
|
||||||
|
/* Version 3.8: Offer the client a choice of security -- where None is the
|
||||||
|
* only option offered.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gvdbg("Send SupportedSecurityTypes\n");
|
||||||
|
|
||||||
|
sectypes = (FAR struct rfb_supported_sectypes_s *)session->outbuf;
|
||||||
|
sectypes->ntypes = 1;
|
||||||
|
sectypes->type[0] = RFB_SECTYPE_NONE;
|
||||||
|
|
||||||
|
nsent = psock_send(&session->connect, sectypes,
|
||||||
|
SIZEOF_RFB_SUPPORTED_SECTYPES_S(1), 0);
|
||||||
|
if (nsent < 0)
|
||||||
|
{
|
||||||
|
errcode = get_errno();
|
||||||
|
gdbg("ERROR: Send SupportedSecurityTypes failed: %d\n", errcode);
|
||||||
|
DEBUGASSERT(errcode > 0);
|
||||||
|
return -errcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(nsent == SIZEOF_RFB_SUPPORTED_SECTYPES_S(1));
|
||||||
|
|
||||||
|
/* If the server listed at least one valid security type supported by the
|
||||||
|
* client, the client sends back a single byte indicating which security
|
||||||
|
* type is to be used on the connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gvdbg("Receive SecurityType\n");
|
||||||
|
|
||||||
|
sectype = (FAR struct rfb_selected_sectype_s *)session->inbuf;
|
||||||
|
|
||||||
|
nrecvd = psock_recv(&session->connect, sectype,
|
||||||
|
sizeof(struct rfb_selected_sectype_s), 0);
|
||||||
|
if (nrecvd < 0)
|
||||||
|
{
|
||||||
|
errcode = get_errno();
|
||||||
|
gdbg("ERROR: Receive SecurityType failed: %d\n", errcode);
|
||||||
|
DEBUGASSERT(errcode > 0);
|
||||||
|
return -errcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(nrecvd == sizeof(struct rfb_selected_sectype_s));
|
||||||
|
|
||||||
|
gvdbg("Send SecurityResult\n");
|
||||||
|
|
||||||
|
secresult = (FAR struct rfb_sectype_result_s *)session->outbuf;
|
||||||
|
|
||||||
|
if (sectype->type != RFB_SECTYPE_NONE)
|
||||||
|
{
|
||||||
|
gdbg("ERROR: Received unsupported SecurityType: %d\n", sectype->type);
|
||||||
|
|
||||||
|
/* REVISIT: Should send the reason string here */
|
||||||
|
|
||||||
|
rfb_putbe32(secresult->result, RFB_SECTYPE_FAIL);
|
||||||
|
|
||||||
|
nsent = psock_send(&session->connect, secresult,
|
||||||
|
sizeof(struct rfb_sectype_result_s), 0);
|
||||||
|
if (nsent < 0)
|
||||||
|
{
|
||||||
|
errcode = get_errno();
|
||||||
|
gdbg("ERROR: Send SecurityResult failed: %d\n", errcode);
|
||||||
|
DEBUGASSERT(errcode > 0);
|
||||||
|
return -errcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(nsent == sizeof(struct rfb_sectype_result_s));
|
||||||
|
|
||||||
|
gvdbg("Send failure reason\n");
|
||||||
|
|
||||||
|
secfail = (FAR struct rfb_sectype_fail_s *)session->outbuf;
|
||||||
|
len = strlen(g_nosecurity);
|
||||||
|
rfb_putbe32(secfail->len, len);
|
||||||
|
memcpy(secfail->str, g_nosecurity, len);
|
||||||
|
|
||||||
|
nsent = psock_send(&session->connect, secfail,
|
||||||
|
SIZEOF_RFB_SECTYPE_FAIL_S(len), 0);
|
||||||
|
if (nsent < 0)
|
||||||
|
{
|
||||||
|
errcode = get_errno();
|
||||||
|
gdbg("ERROR: Send failure reason failed: %d\n", errcode);
|
||||||
|
DEBUGASSERT(errcode > 0);
|
||||||
|
return -errcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(nsent == SIZEOF_RFB_SECTYPE_FAIL_S(len));
|
||||||
|
return -EPROTONOSUPPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
rfb_putbe32(secresult->result, RFB_SECTYPE_SUCCESS);
|
||||||
|
|
||||||
|
nsent = psock_send(&session->connect, secresult,
|
||||||
|
sizeof(struct rfb_sectype_result_s), 0);
|
||||||
|
if (nsent < 0)
|
||||||
|
{
|
||||||
|
errcode = get_errno();
|
||||||
|
gdbg("ERROR: Send SecurityResult failed: %d\n", errcode);
|
||||||
|
DEBUGASSERT(errcode > 0);
|
||||||
|
return -errcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(nsent == sizeof(struct rfb_sectype_result_s));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Receive the ClientInit message
|
/* Receive the ClientInit message
|
||||||
*
|
*
|
||||||
* "Once the client and server are sure that they’re happy to talk to one
|
* "Once the client and server are sure that they’re happy to talk to one
|
||||||
|
@ -198,11 +309,11 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||||
/* Send the ServerInit message
|
/* Send the ServerInit message
|
||||||
*
|
*
|
||||||
* "After receiving the ClientInit message, the server sends a ServerInit
|
* "After receiving the ClientInit message, the server sends a ServerInit
|
||||||
* message. This tells the client the width and height of the server’s
|
* message. This tells the client the width and height of the server’s
|
||||||
* framebuffer, its pixel format and the name associated with the desktop:
|
* framebuffer, its pixel format and the name associated with the desktop:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gvdbg("Receive ServerInit\n");
|
gvdbg("Send ServerInit\n");
|
||||||
|
|
||||||
serverinit = (FAR struct rfb_serverinit_s *)session->outbuf;
|
serverinit = (FAR struct rfb_serverinit_s *)session->outbuf;
|
||||||
|
|
||||||
|
@ -248,7 +359,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||||
if (nrecvd < 0)
|
if (nrecvd < 0)
|
||||||
{
|
{
|
||||||
errcode = get_errno();
|
errcode = get_errno();
|
||||||
gdbg("ERROR: Receive SetFormat failed: %d\n", errcode);
|
gdbg("ERROR: Receive SetPixelFormat failed: %d\n", errcode);
|
||||||
DEBUGASSERT(errcode > 0);
|
DEBUGASSERT(errcode > 0);
|
||||||
return -errcode;
|
return -errcode;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +372,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||||
}
|
}
|
||||||
else if (setformat->msgtype != RFB_SETPIXELFMT_MSG)
|
else if (setformat->msgtype != RFB_SETPIXELFMT_MSG)
|
||||||
{
|
{
|
||||||
gdbg("ERROR: Not a SetFormat message: %d\n", (int)setformat->msgtype);
|
gdbg("ERROR: Not a SetPixelFormat message: %d\n", (int)setformat->msgtype);
|
||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,66 +429,3 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||||
session->state = VNCSERVER_CONFIGURED;
|
session->state = VNCSERVER_CONFIGURED;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_VNCSERVER_PROTO3p8
|
|
||||||
int vnc_negotiate(FAR struct vnc_session_s *session)
|
|
||||||
{
|
|
||||||
ssize_t nsent;
|
|
||||||
ssize_t nrecvd;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_SOCKOPTS
|
|
||||||
struct timeval tv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Set a receive timeout so that we don't hang if the client does not
|
|
||||||
* respond according to RFB 3.3 protocol.
|
|
||||||
*/
|
|
||||||
|
|
||||||
tv.tv_sec = 5;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
ret = psock_setsockopt(&session->connect, SOL_SOCKET, SO_RCVTIMEO,
|
|
||||||
&tv, sizeof(struct timeval));
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
errcode = get_errno();
|
|
||||||
gdbg("ERROR: Failed to set receive timeout: %d\n", errcode);
|
|
||||||
DEBUGASSERT(errcode > 0);
|
|
||||||
return -errcode;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Inform the client of the VNC protocol version */
|
|
||||||
|
|
||||||
len = strlen(g_vncproto);
|
|
||||||
nsent = psock_send(&session->connect, g_vncproto, len, 0);
|
|
||||||
if (nsent < 0)
|
|
||||||
{
|
|
||||||
errcode = get_errno();
|
|
||||||
gdbg("ERROR: Send ProtocolVersion failed: %d\n", errcode);
|
|
||||||
DEBUGASSERT(errcode > 0);
|
|
||||||
return -errcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGASSERT(nsent == len);
|
|
||||||
|
|
||||||
/* Receive the echo of the protocol string */
|
|
||||||
|
|
||||||
nrecvd = psock_recv(&session->connect, session->inbuf, len, 0);
|
|
||||||
if (nrecvd <= 0)
|
|
||||||
{
|
|
||||||
errcode = get_errno();
|
|
||||||
gdbg("ERROR: Receive protocol confirmation failed: %d\n", errcode);
|
|
||||||
DEBUGASSERT(errcode > 0);
|
|
||||||
return -errcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGASSERT(nrecvd == len);
|
|
||||||
|
|
||||||
/* Offer the client a choice of security -- where None is the only option. */
|
|
||||||
#warning Missing logic
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Reference in New Issue