Merged nuttx/nuttx into master

This commit is contained in:
ziggurat29
2016-04-19 07:02:55 -05:00
23 changed files with 5562 additions and 3 deletions
+13 -2
View File
@@ -11652,6 +11652,17 @@
* drivers/wireless/nrf24l01.c: Fix backward calculation of relative
frequency. Noted by Henry Zhang (2015-04-15).
* drivers/sensors/h1750fvi.c: Add a character driver for Rohm Ambient
Light Sensor BH1750FVI. From Alan Carvalho de Assi (2016-04-15).
Light Sensor BH1750FVI. From Alan Carvalho de Assis (2016-04-15).
* configs/stm32f4discovery: Integrate BH1750FVI driver in the
STM32F4Discovery board. From Alan Carvalho de Assi (2016-04-15).
STM32F4Discovery board. From Alan Carvalho de Assis (2016-04-15).
* drivers/mtd: Add MTD support for Micron N25Qxxx family of QSPI flash.
From Dave dev@ziggurat29.com (2016-04-17).
* arch/arm/src/stm32l: Add a QSPI driver. From Dave dev@ziggurat29.com
(2016-04-18).
* configs/stm32l476vb-disco: Add support for QSPI based N25Qxxx flash.
From Dave dev@ziggurat29.com (2016-04-18).
* graphics/vnc: Add support for a VNC server. This logic is code
complete, but untested and so not ready for primetime (2016-04-18).
* configs/samv71-xult/vnc: Add a configuration that will be used to
verify VNC (also untested) (2016-04-18).
+19
View File
@@ -2308,3 +2308,22 @@ Configuration sub-directories
- Line spacing in the NxTerm window is too much. This is probably
a font-related issue too.
vnc:
This is a special version of an NSH configuration. It has networking
and graphics enabled. It is configured to use the VNC server to provide
a remote desktop for use with VNC client on a PC. It includes the
graphics text at apps/examples/nximage.
NOTES:
1. The RAMLOG is enabled so all debug output will go to the RAMLOG and
can be view using the NSH dmesg command. No debug output is enabled
in the default configuration, however.
2. Network confiration: IP address 10.0.0.2. The is easily changed
via 'make menuconfig'. The VNC server address is 10.0.0.2:5900.
3. The default (local) framebuffer configuration is 320x240 with 16-bit
RGB color.
+117
View File
@@ -0,0 +1,117 @@
############################################################################
# configs/samv71-xult/vnc/Make.defs
#
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
include ${TOPDIR}/.config
include ${TOPDIR}/tools/Config.mk
include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
ifeq ($(CONFIG_ARMV7M_DTCM),y)
LDSCRIPT = flash-dtcm.ld
else
LDSCRIPT = flash-sram.ld
endif
ifeq ($(WINTOOL),y)
# Windows-native toolchains
DIRLINK = $(TOPDIR)/tools/copydir.sh
DIRUNLINK = $(TOPDIR)/tools/unlink.sh
MKDEP = $(TOPDIR)/tools/mkwindeps.sh
ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
else
# Linux/Cygwin-native toolchain
MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
endif
CC = $(CROSSDEV)gcc
CXX = $(CROSSDEV)g++
CPP = $(CROSSDEV)gcc -E
LD = $(CROSSDEV)ld
AR = $(CROSSDEV)ar rcs
NM = $(CROSSDEV)nm
OBJCOPY = $(CROSSDEV)objcopy
OBJDUMP = $(CROSSDEV)objdump
ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
ARCHOPTIMIZATION = -g
endif
ifneq ($(CONFIG_DEBUG_NOOPT),y)
ARCHOPTIMIZATION += $(MAXOPTIMIZATION)
endif
ARCHCFLAGS = -fno-builtin
ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fno-rtti
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -fno-strict-aliasing
ARCHWARNINGSXX = -Wall -Wshadow -Wundef
ARCHDEFINES =
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
AFLAGS = $(CFLAGS) -D__ASSEMBLY__
NXFLATLDFLAGS1 = -r -d -warn-common
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
LDNXFLATFLAGS = -e main -s 2048
ASMEXT = .S
OBJEXT = .o
LIBEXT = .a
EXEEXT =
ifneq ($(CROSSDEV),arm-nuttx-elf-)
LDFLAGS += -nostartfiles -nodefaultlibs
endif
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
LDFLAGS += -g
endif
HOSTCC = gcc
HOSTINCLUDES = -I.
HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
HOSTLDFLAGS =
File diff suppressed because it is too large Load Diff
+77
View File
@@ -0,0 +1,77 @@
#!/bin/bash
# configs/samv7-xult/vnc/Make.defs
#
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
if [ "$_" = "$0" ] ; then
echo "You must source this script, not run it!" 1>&2
exit 1
fi
WD=`pwd`
if [ ! -x "setenv.sh" ]; then
echo "This script must be executed from the top-level NuttX build directory"
exit 1
fi
if [ -z "${PATH_ORIG}" ]; then
export PATH_ORIG="${PATH}"
fi
# This is the Cygwin path to the location where I installed the Atmel GCC
# toolchain under Windows. You will also have to edit this if you install
# this toolchain in any other location
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/Atmel/Atmel Toolchain/ARM GCC/Native/4.7.3.99/arm-gnu-toolchain/bin"
# This is the Cygwin path to the location where I installed the CodeSourcery
# toolchain under windows. You will also have to edit this if you install
# the CodeSourcery toolchain in any other location
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin"
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
# export TOOLCHAIN_BIN="/cygdrive/c/Users/MyName/MentorGraphics/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
# This is the location where I installed the ARM "GNU Tools for ARM Embedded Processors"
# You can this free toolchain here https://launchpad.net/gcc-arm-embedded
export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q2/bin"
# This is the path to the location where I installed the devkitARM toolchain
# You can get this free toolchain from http://devkitpro.org/ or http://sourceforge.net/projects/devkitpro/
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/devkitARM/bin"
# This is the Cygwin path to the location where I build the buildroot
# toolchain.
# export TOOLCHAIN_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin"
# Add the path to the toolchain to the PATH varialble
export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}"
echo "PATH : ${PATH}"
+3
View File
@@ -745,4 +745,7 @@ config NXSTART_VPLANE
endif # NX_NXSTART
endif # NX_MULTIUSER
source "graphics/vnc/Kconfig"
endif # NX
+1
View File
@@ -50,6 +50,7 @@ include nxbe/Make.defs
include nxmu/Make.defs
include nxsu/Make.defs
include nxterm/Make.defs
include vnc/Make.defs
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
+6
View File
@@ -112,6 +112,10 @@ nuttx/../NxWidgets
The NxWidgets code is provided as a separate package located outside of the
NuttX source tree (probably at this location).
graphics/vnc
The future home of the VNC Remote Frame Buffer (RFB) server and client
implementations.
Installing New Fonts
^^^^^^^^^^^^^^^^^^^^
@@ -295,6 +299,8 @@ CONFIG_NXTK_AUTORAISE
CONFIG_NXFONTS_CHARBITS
The number of bits in the character set. Current options are only 7 and 8.
The default is 7.
CONFIG_VNCSERVER and CONFIG_VNCCLIENT
Enable the VNC RFB server and client, respecitively.
Font Selections
---------------
+7
View File
@@ -0,0 +1,7 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
source "graphics/vnc/server/Kconfig"
source "graphics/vnc/client/Kconfig"
+37
View File
@@ -0,0 +1,37 @@
############################################################################
# graphics/vnc/Make.defs
#
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
include vnc/server/Make.defs
include vnc/client/Make.defs
+15
View File
@@ -0,0 +1,15 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
menuconfig VNCCLIENT
bool "VNC client"
default n
depends on NET_TCP && !NX_LCDDRIVER && !VNC_SERVER && EXPERIMENTAL
---help---
Enable support for a VNC Remote Frame Buffer (RFB) client
if VNCCLIENT
endif # VNCCLIENT
+42
View File
@@ -0,0 +1,42 @@
############################################################################
# graphics/vnc/client/Make.defs
#
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_VNCCLIENT),y)
DEPPATH += --dep-path vnc/client
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)/graphics/vnc/client}
VPATH += :vnc/client
endif
+106
View File
@@ -0,0 +1,106 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
menuconfig VNCSERVER
bool "VNC server"
default n
depends on NET_TCP && !NX_LCDDRIVER && EXPERIMENTAL
select NET_TCP_READAHEAD
select NX_UPDATE
---help---
Enable support for a VNC Remote Frame Buffer (RFB) server.
if VNCSERVER
choice
prompt "VNC server protocol"
default VNCSERVER_PROTO3p3
config VNCSERVER_PROTO3p3
bool "Version 3.3"
config VNCSERVER_PROTO3p8
bool "Version 3.8"
depends on EXPERIMENTAL
endchoice # VNC server protocol
config VNCSERVER_NDISPLAYS
int "Number of displays"
default 1
range 1 99
---help---
Specifies the number of RFB displays supported by the server.
Normally this should be one.
config VNCSERVER_PRIO
int "VNC server task priority"
default 100
config VNCSERVER_STACKSIZE
int "VNC server stack size"
default 2048
config VNCSERVER_UPDATER_PRIO
int "VNC updater thread priority"
default 100
config VNCSERVER_UPDATER_STACKSIZE
int "VNC updater thread stack size"
default 2048
choice
prompt "VNC color format"
default VNCSERVER_COLORFMT_RGB16
config VNCSERVER_COLORFMT_RGB16
bool "RGB16 5:6:5"
config VNCSERVER_COLORFMT_RGB32
bool "RGB24 (32-bit) or RGB32 (w/tranparency)"
endchoice # VNC color format
config VNCSERVER_SCREENWIDTH
int "Framebuffer width (pixels)"
default 320
config VNCSERVER_SCREENHEIGHT
int "Framebuffer height (rows)"
default 240
config VNCSERVER_NUPDATES
int "Number of pre-allocate update structures"
default 48
---help---
This setting provides the number of pre-allocated update structures
that will be used. Dynamic memory allocations are never made. In
the likely event that we run out of update structures, the graphics
subsystem will pause and wait for the next structures to be released.
Overhead is 12-bytes per update structure.
config VNCSERVER_UPDATE_BUFSIZE
int "Max update buffer size (bytes)"
default 4096
---help---
A single buffer is pre-allocated for rendering updates. This
setting specifies the maximum in bytes of that update buffer. For
example, an update buffers of 32 pixels at 32-bits per pixel and
32-rows would yield a buffer size of 4096.
config VNCSERVER_KBDENCODE
bool "Encode keyboard input"
default n
depends on NXTERM_NXKBDIN
---help---
Use a special encoding of keyboard characters as defined in
include/nuttx/input/kbd_coded.h.
config VNCSERVER_INBUFFER_SIZE
int "Input buffer size
default 80
endif # VNCSERVER
+48
View File
@@ -0,0 +1,48 @@
############################################################################
# graphics/vnc/server/Make.defs
#
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_VNCSERVER),y)
CSRCS += vnc_server.c vnc_negotiate.c vnc_updater.c vnc_receiver.c vnc_fbdev.c
ifeq ($(CONFIG_NX_KBD),y)
CSRCS += vnc_keymap.c
endif
DEPPATH += --dep-path vnc/server
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)/graphics/vnc/server}
VPATH += :vnc/server
endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+337
View File
@@ -0,0 +1,337 @@
/****************************************************************************
* graphics/vnc/vnc_negotiate.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/video/fb.h>
#include <nuttx/video/rfb.h>
#include "vnc_server.h"
/****************************************************************************
* Private Data
****************************************************************************/
#if defined(CONFIG_VNCSERVER_PROTO3p3)
static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p3;
#elif defined(CONFIG_VNCSERVER_PROTO3p8)
static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p8;
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_negotiate
*
* Description:
* Perform the VNC initialization sequence after the client has sucessfully
* connected to the server. Negotiate security, framebuffer and color
* properties.
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* Returns zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_VNCSERVER_PROTO3p3
int vnc_negotiate(FAR struct vnc_session_s *session)
{
FAR struct rfb_sectype_s *sectype;
FAR struct rfb_serverinit_s *serverinit;
FAR struct rfb_pixelfmt_s *pixelfmt;
FAR struct rfb_setpixelformat_s *setformat;
ssize_t nsent;
ssize_t nrecvd;
size_t len;
int errcode;
/* Inform the client of the VNC protocol version */
gvdbg("Send protocol version: %s\n", g_vncproto);
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 */
gvdbg("Receive echo from VNC client\n");
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);
/* Tell the client that we won't use any stinkin' security.
*
* "Version 3.3 The server decides the security type and sends a single
* word:"
*/
gvdbg("Send security type (None)\n");
sectype = (FAR struct rfb_sectype_s *)session->outbuf;
rfb_putbe32(sectype->type, RFB_SECTYPE_NONE);
nsent = psock_send(&session->connect, sectype,
sizeof(struct rfb_sectype_s), 0);
if (nsent < 0)
{
errcode = get_errno();
gdbg("ERROR: Send Security failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nsent == sizeof(struct rfb_sectype_s));
/* Receive the ClientInit message
*
* "Once the client and server are sure that theyre happy to talk to one
* another using the agreed security type, the protocol passes to the
* initialisation phase. The client sends a ClientInit message followed
* by the server sending a ServerInit message."
*
* In this implementation, the sharing flag is ignored.
*/
gvdbg("Receive ClientInit\n");
nrecvd = psock_recv(&session->connect, session->inbuf,
sizeof(struct rfb_clientinit_s), 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive ClientInit failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nrecvd == sizeof(struct rfb_clientinit_s));
/* Send the ServerInit message
*
* "After receiving the ClientInit message, the server sends a ServerInit
* message. This tells the client the width and height of the servers
* framebuffer, its pixel format and the name associated with the desktop:
*/
gvdbg("Receive ServerInit\n");
serverinit = (FAR struct rfb_serverinit_s *)session->outbuf;
rfb_putbe16(serverinit->width, CONFIG_VNCSERVER_SCREENWIDTH);
rfb_putbe16(serverinit->height, CONFIG_VNCSERVER_SCREENHEIGHT);
rfb_putbe32(serverinit->namelen, 0);
pixelfmt = &serverinit->format;
pixelfmt->bpp = RFB_BITSPERPIXEL;
pixelfmt->depth = RFB_PIXELDEPTH;
pixelfmt->bigendian = 0;
pixelfmt->truecolor = RFB_TRUECOLOR;
rfb_putbe16(pixelfmt->rmax, RFB_RMAX);
rfb_putbe16(pixelfmt->gmax, RFB_GMAX);
rfb_putbe16(pixelfmt->bmax, RFB_BMAX);
pixelfmt->rshift = RFB_RSHIFT;
pixelfmt->gshift = RFB_GSHIFT;
pixelfmt->bshift = RFB_BSHIFT;
nsent = psock_send(&session->connect, serverinit,
SIZEOF_RFB_SERVERINIT_S(0), 0);
if (nsent < 0)
{
errcode = get_errno();
gdbg("ERROR: Send ServerInit failed: %d\n", errcode);
return -errcode;
}
DEBUGASSERT(nsent == SIZEOF_RFB_SERVERINIT_S(0));
/* We now expect to receive the SetPixelFormat message from the client.
* This may override some of our framebuffer settings.
*/
gvdbg("Receive SetPixelFormat\n");
setformat = (FAR struct rfb_setpixelformat_s *)session->inbuf;
nrecvd = psock_recv(&session->connect, setformat,
sizeof(struct rfb_setpixelformat_s), 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive SetFormat failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
else if (nrecvd != sizeof(struct rfb_setpixelformat_s))
{
/* Must not be a SetPixelFormat message? */
gdbg("ERROR: SetFormat wrong size: %d\n", (int)nrecvd);
return -EPROTO;
}
else if (setformat->msgtype != RFB_SETPIXELFMT_MSG)
{
gdbg("ERROR: Not a SetFormat message: %d\n", (int)setformat->msgtype);
return -EPROTO;
}
/* Check if the client request format is one that we can handle. */
pixelfmt = &setformat->format;
if (pixelfmt->truecolor == 0)
{
/* At present, we support only TrueColor formats */
gdbg("ERROR: No support for palette colors\n");
return -ENOSYS;
}
if (pixelfmt->bpp == 16 && pixelfmt->depth == 15)
{
session->colorfmt = FB_FMT_RGB16_555;
session->bpp = 16;
}
else if (pixelfmt->bpp == 16 && pixelfmt->depth == 16)
{
session->colorfmt = FB_FMT_RGB16_565;
session->bpp = 16;
}
else if (pixelfmt->bpp == 32 && pixelfmt->depth == 24)
{
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
}
else if (pixelfmt->bpp == 32 && pixelfmt->depth == 32)
{
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
}
else
{
/* We do not support any other conversions */
gdbg("ERROR: No support for this BPP=%d and depth=%d\n",
pixelfmt->bpp, pixelfmt->depth);
return -ENOSYS;
}
/* Receive supported encoding types from client, but ignore them.
* we will do only raw format.
*/
gvdbg("Receive encoding types\n");
(void)psock_recv(&session->connect, session->inbuf,
CONFIG_VNCSERVER_INBUFFER_SIZE, 0);
session->state = VNCSERVER_CONFIGURED;
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;
/* 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
+383
View File
@@ -0,0 +1,383 @@
/****************************************************************************
* graphics/vnc/vnc_receiver.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/net/net.h>
#include <nuttx/video/rfb.h>
#include "vnc_server.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_read_remainder
*
* Description:
* After receiving the first byte of a client-to-server message, this
* reads in the remainder of the message.
*
* Input Parameters:
* session - An instance of the session structure.
* msglen - The full length of the message
*
* Returned Value:
* At present, always returns OK
*
****************************************************************************/
int vnc_read_remainder(FAR struct vnc_session_s *session, size_t msglen,
size_t offset)
{
ssize_t nrecvd;
size_t ntotal;
int errcode;
/* Loop until the rest of the message is recieved. */
for (ntotal = 0; ntotal < msglen; offset += nrecvd, ntotal += nrecvd)
{
/* Receive more of the message */
nrecvd = psock_recv(&session->connect, &session->inbuf[offset],
msglen - ntotal, 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive message failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_receiver
*
* Description:
* This function handles all Client-to-Server messages.
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* At present, always returns OK
*
****************************************************************************/
int vnc_receiver(FAR struct vnc_session_s *session)
{
ssize_t nrecvd;
int errcode;
int ret;
DEBUGASSERT(session);
gvdbg("Receiver running for Display %d\n", session->display);
/* Loop until the client disconnects or an unhandled error occurs */
for (; ; )
{
/* Set up to read one byte which should be the message type of the
* next Client-to-Server message. We will block here until the message
* is received.
*/
nrecvd = psock_recv(&session->connect, session->inbuf, 1, 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive byte failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nrecvd == 1);
/* The single byte received should be the message type. Handle the
* message according to this message type.
*/
switch (session->inbuf[0])
{
case RFB_SETPIXELFMT_MSG: /* SetPixelFormat */
{
gvdbg("Received SetPixelFormat\n");
/* Read the rest of the SetPixelFormat message */
ret = vnc_read_remainder(session,
sizeof(struct rfb_setpixelformat_s) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read SetPixelFormat message: %d\n",
ret);
}
else
{
/* REVISIT: SetPixelFormat is currently ignored */
}
}
break;
case RFB_SETENCODINGS_MSG: /* SetEncodings */
{
FAR struct rfb_setencodings_s *encodings;
uint32_t nencodings;
gvdbg("Received SetEncodings\n");
/* Read the SetEncodings message without the following
* encodings.
*/
ret = vnc_read_remainder(session,
SIZEOF_RFB_SERVERINIT_S(0) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read SetEncodings message: %d\n",
ret);
}
else
{
/* Read the following encodings */
encodings = (FAR struct rfb_setencodings_s *)session->inbuf;
nencodings = rfb_getbe32(encodings->nencodings);
ret = vnc_read_remainder(session,
nencodings * sizeof(uint32_t),
SIZEOF_RFB_SERVERINIT_S(0));
if (ret < 0)
{
gdbg("ERROR: Failed to read encodings: %d\n",
ret);
}
else
{
/* REVISIT: SetEncodings is currently ignored */
}
}
}
break;
case RFB_FBUPDATEREQ_MSG: /* FramebufferUpdateRequest */
{
FAR struct rfb_fbupdatereq_s *update;
struct nxgl_rect_s rect;
gvdbg("Received FramebufferUpdateRequest\n");
/* Read the rest of the SetPixelFormat message */
ret = vnc_read_remainder(session,
sizeof(struct rfb_fbupdatereq_s) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read FramebufferUpdateRequest message: %d\n",
ret);
}
else
{
/* Enqueue the update */
update = (FAR struct rfb_fbupdatereq_s *)session->inbuf;
rect.pt1.x = rfb_getbe16(update->xpos);
rect.pt1.y = rfb_getbe16(update->ypos);
rect.pt2.x = rect.pt1.x + rfb_getbe16(update->width);
rect.pt2.y = rect.pt1.y + rfb_getbe16(update->height);
ret = vnc_update_rectangle(session, &rect);
if (ret < 0)
{
gdbg("ERROR: Failed to queue update: %d\n", ret);
}
}
}
break;
case RFB_KEYEVENT_MSG: /* KeyEvent */
{
FAR struct rfb_keyevent_s *keyevent;
gvdbg("Received KeyEvent\n");
/* Read the rest of the KeyEvent message */
ret = vnc_read_remainder(session,
sizeof(struct rfb_keyevent_s) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read KeyEvent message: %d\n",
ret);
}
else
{
/* Inject the key press/release event into NX */
keyevent = (FAR struct rfb_keyevent_s *)session->inbuf;
vnc_key_map(session, rfb_getbe16(keyevent->key),
(bool)keyevent->down);
}
}
break;
case RFB_POINTEREVENT_MSG: /* PointerEvent */
{
#ifdef CONFIG_NX_XYINPUT
FAR struct rfb_pointerevent_s *event;
uint8_t buttons;
#endif
gvdbg("Received PointerEvent\n");
/* Read the rest of the PointerEvent message */
ret = vnc_read_remainder(session,
sizeof(struct rfb_pointerevent_s) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read PointerEvent message: %d\n",
ret);
}
#ifdef CONFIG_NX_XYINPUT
else
{
event = (FAR struct rfb_pointerevent_s *)session->inbuf;
/* Map buttons bitmap. Bits 0-7 are buttons 1-8, 0=up,
* 1=down. By convention Bit 0 = left button, Bit 1 =
* middle button, and Bit 2 = right button.
*/
buttons = 0;
if ((event->buttons & (1 << 0)) != 0)
{
buttons |= NX_MOUSE_LEFTBUTTON;
}
if ((event->buttons & (1 << 1)) != 0)
{
buttons |= NX_MOUSE_CENTERBUTTON;
}
if ((event->buttons & (1 << 2)) != 0)
{
buttons |= NX_MOUSE_RIGHTBUTTON;
}
ret = nx_mousein(session->handle,
(nxgl_coord_t)rfb_getbe16(event->xpos),
(nxgl_coord_t)rfb_getbe16(event->ypos),
buttons);
if (ret < 0)
{
gdbg("ERROR: nx_mousein failed: %d\n", ret);
}
}
#endif
}
break;
case RFB_CLIENTCUTTEXT_MSG: /* ClientCutText */
{
FAR struct rfb_clientcuttext_s *cuttext;
uint32_t length;
gvdbg("Received ClientCutText\n");
/* Read the ClientCutText message without the following
* text.
*/
ret = vnc_read_remainder(session,
SIZEOF_RFB_CLIENTCUTTEXT_S(0) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read ClientCutText message: %d\n",
ret);
}
else
{
/* Read the following text */
cuttext = (FAR struct rfb_clientcuttext_s *)session->inbuf;
length = rfb_getbe32(cuttext->length);
ret = vnc_read_remainder(session, length,
SIZEOF_RFB_CLIENTCUTTEXT_S(0));
if (ret < 0)
{
gdbg("ERROR: Failed to read text: %d\n",
ret);
}
else
{
/* REVISIT: ClientCutText is currently ignored */
}
}
}
break;
default:
gdbg("ERROR: Unsynchronized, msgtype=%d\n", session->inbuf[0]);
return -EPROTO;
}
}
return -ENOSYS;
}
+393
View File
@@ -0,0 +1,393 @@
/****************************************************************************
* graphics/vnc/vnc_server.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "nuttx/config.h"
#include <stdint.h>
#include <stdlib.h>
#include <semaphore.h>
#include <string.h>
#include <queue.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/kmalloc.h>
#include <nuttx/semaphore.h>
#include <nuttx/net/net.h>
#include "vnc_server.h"
/****************************************************************************
* Public Data
****************************************************************************/
/* Given a display number as an index, the following array can be used to
* look-up the session structure for that display.
*/
FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS];
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_reset_session
*
* Description:
* Conclude the current VNC session. This function re-initializes the
* session structure; it does not free either the session structure nor
* the framebuffer so that they may be re-used.
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* None
*
****************************************************************************/
static void vnc_reset_session(FAR struct vnc_session_s *session,
FAR uint8_t *fb, int display)
{
FAR struct vnc_fbupdate_s *curr;
FAR struct vnc_fbupdate_s *next;
int i;
/* Close any open sockets */
if (session->state >= VNCSERVER_CONNECTED)
{
psock_close(&session->connect);
psock_close(&session->listen);
}
/* [Re-]initialize the session. */
memset(&session->connect, 0, sizeof(struct socket));
session->connect.s_crefs = 1;
memset(&session->listen, 0, sizeof(struct socket));
session->listen.s_crefs = 1;
/* Put all of the pre-allocated update structures into the freelist */
sq_init(&session->updqueue);
session->updfree.head =
(FAR sq_entry_t *)&session->updpool[0];
session->updfree.tail =
(FAR sq_entry_t *)&session->updpool[CONFIG_VNCSERVER_NUPDATES-1];
next = &session->updpool[0];
for (i = 1; i < CONFIG_VNCSERVER_NUPDATES-1; i++)
{
curr = next;
next = &session->updpool[i];
curr->flink = next;
}
next->flink = NULL;
/* Set the INITIALIZED state */
sem_reset(&session->freesem, CONFIG_VNCSERVER_NUPDATES);
sem_reset(&session->queuesem, 0);
session->fb = fb;
session->display = display;
session->state = VNCSERVER_INITIALIZED;
}
/****************************************************************************
* Name: vnc_connect
*
* Description:
* Wait for a connection from the VNC client
*
* Input Parameters:
* session - An instance of the session structure.
* port - The listen port to use
*
* Returned Value:
* Returns zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
static int vnc_connect(FAR struct vnc_session_s *session, int port)
{
struct sockaddr_in addr;
int ret;
gvdbg("Connecting display %d\n", session->display);
/* Create a listening socket */
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
ret = psock_socket(AF_INET, SOCK_STREAM, 0, &session->listen);
if (ret < 0)
{
ret = -get_errno();
return ret;
}
/* Bind the listening socket to a local address */
ret = psock_bind(&session->listen, (struct sockaddr *)&addr,
sizeof(struct sockaddr_in));
if (ret < 0)
{
ret = -get_errno();
goto errout_with_listener;
}
/* Listen for a connection */
ret = psock_listen(&session->listen, 5);
if (ret < 0)
{
ret = -get_errno();
goto errout_with_listener;
}
/* Connect to the client */
gvdbg("Accepting connection for Display %d\n", session->display);
ret = psock_accept(&session->listen, NULL, NULL, &session->connect);
if (ret < 0)
{
ret = -get_errno();
goto errout_with_listener;
}
gvdbg("Display %d connected\n", session->display);
session->state = VNCSERVER_CONNECTED;
return OK;
errout_with_listener:
psock_close(&session->listen);
return ret;
}
/****************************************************************************
* Pubic Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_server
*
* Description:
* The VNC server daemon. This daemon is implemented as a kernel thread.
*
* Input Parameters:
* Standard kernel thread arguments (all ignored)
*
* Returned Value:
* This function does not return.
*
****************************************************************************/
int vnc_server(int argc, FAR char *argv[])
{
FAR struct vnc_session_s *session;
FAR uint8_t *fb;
int display;
int ret;
/* A single argument is expected: A diplay port number in ASCII form */
if (argc != 2)
{
gdbg("ERROR: Unexpected number of arguments: %d\n", argc);
ret = -EINVAL;
goto errout_with_post;
}
display = atoi(argv[1]);
if (display < 0 || display >= RFB_MAX_DISPLAYS)
{
gdbg("ERROR: Invalid display number: %d\n", display);
ret = -EINVAL;
goto errout_with_post;
}
gvdbg("Server started for Display %d\n", display);
/* Allocate the framebuffer memory. We rely on the fact that
* the KMM allocator will align memory to 32-bits or better.
*/
fb = (FAR uint8_t *)kmm_zalloc(RFB_SIZE);
if (fb == NULL)
{
gdbg("ERROR: Failed to allocate framebuffer memory: %lu KB\n",
(unsigned long)(RFB_SIZE / 1024));
ret = -ENOMEM;
goto errout_with_post;
}
/* Allocate a session structure for this display */
session = kmm_zalloc(sizeof(struct vnc_session_s));
if (session == NULL)
{
gdbg("ERROR: Failed to allocate session\n");
ret = -ENOMEM;
goto errout_with_fb;
}
g_vnc_sessions[display] = session;
sem_init(&session->freesem, 0, CONFIG_VNCSERVER_NUPDATES);
sem_init(&session->queuesem, 0, 0);
/* Loop... handling each each VNC client connection to this display. Only
* a single client is allowed for each display.
*/
for (; ; )
{
/* Release the last session and [Re-]initialize the session structure
* for the next connection.
*/
vnc_reset_session(session, fb, display);
g_fbstartup[display].result = -EBUSY;
sem_reset(&g_fbstartup[display].fbsem, 0);
/* Establish a connection with the VNC client */
ret = vnc_connect(session, RFB_DISPLAY_PORT(display));
if (ret >= 0)
{
gvdbg("New VNC connection\n");
/* Perform the VNC initialization sequence after the client has
* sucessfully connected to the server. Negotiate security,
* framebuffer and color properties.
*/
ret = vnc_negotiate(session);
if (ret < 0)
{
gdbg("ERROR: Failed to negotiate security/framebuffer: %d\n",
ret);
continue;
}
/* Start the VNC updater thread that sends all Server-to-Client
* messages.
*/
ret = vnc_start_updater(session);
if (ret < 0)
{
gdbg("ERROR: Failed to start updater thread: %d\n", ret);
continue;
}
/* Let the framebuffer driver know that we are ready to preform
* updates.
*/
g_fbstartup[display].result = OK;
sem_post(&g_fbstartup[display].fbsem);
/* Run the VNC receiver on this trhead. The VNC receiver handles
* all Client-to-Server messages. The VNC receiver function does
* not return until the session has been terminated (or an error
* occurs).
*/
ret = vnc_receiver(session);
gvdbg("Session terminated with %d\n", ret);
/* Stop the VNC updater thread. */
ret = vnc_stop_updater(session);
if (ret < 0)
{
gdbg("ERROR: Failed to stop updater thread: %d\n", ret);
}
}
}
errout_with_fb:
kmm_free(fb);
errout_with_post:
g_fbstartup[display].result = ret;
sem_post(&g_fbstartup[display].fbsem);
return EXIT_FAILURE;
}
/****************************************************************************
* Name: vnc_find_session
*
* Description:
* Return the session structure associated with this display.
*
* Input Parameters:
* display - The display number of interest.
*
* Returned Value:
* Returns the instance of the session structure for this display. NULL
* will be returned if the server has not yet been started or if the
* display number is out of range.
*
****************************************************************************/
FAR struct vnc_session_s *vnc_find_session(int display)
{
FAR struct vnc_session_s *session = NULL;
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
if (display >= 0 && display < RFB_MAX_DISPLAYS)
{
session = g_vnc_sessions[display];
}
return session;
}
+417
View File
@@ -0,0 +1,417 @@
/****************************************************************************
* graphics/vnc/server/vnc_server.h
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __GRAPHICS_VNC_SERVER_VNC_SERVER_H
#define __GRAPHICS_VNC_SERVER_VNC_SERVER_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <semaphore.h>
#include <pthread.h>
#include <queue.h>
#include <nuttx/video/fb.h>
#include <nuttx/video/rfb.h>
#include <nuttx/nx/nxglib.h>
#include <nuttx/nx/nx.h>
#include <nuttx/net/net.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration */
#ifndef CONFIG_NET_TCP_READAHEAD
# error CONFIG_NET_TCP_READAHEAD must be set to use VNC
#endif
#ifndef CONFIG_NX_UPDATE
# error CONFIG_NX_UPDATE must be set to use VNC
#endif
#if !defined(CONFIG_VNCSERVER_PROTO3p3) && !defined(CONFIG_VNCSERVER_PROTO3p8)
# error No VNC protocol selected
#endif
#if defined(CONFIG_VNCSERVER_PROTO3p3) && defined(CONFIG_VNCSERVER_PROTO3p8)
# error Too many VNC protocols selected
#endif
#ifndef CONFIG_VNCSERVER_NDISPLAYS
# define CONFIG_VNCSERVER_NDISPLAYS 1
#endif
#if defined(CONFIG_VNCSERVER_COLORFMT_RGB16)
# define RFB_COLORFMT FB_FMT_RGB16_565
# define RFB_BITSPERPIXEL 16
# define RFB_PIXELDEPTH 16
# define RFB_TRUECOLOR 1
# define RFB_RMAX 0x1f
# define RFB_GMAX 0x3f
# define RFB_BMAX 0x1f
# define RFB_RSHIFT 11
# define RFB_GSHIFT 5
# define RFB_BSHIFT 0
#elif defined(CONFIG_VNCSERVER_COLORFMT_RGB32)
# define RFB_COLORFMT FB_FMT_RGB32
# define RFB_BITSPERPIXEL 32
# define RFB_PIXELDEPTH 24
# define RFB_TRUECOLOR 1
# define RFB_RMAX 0xff
# define RFB_GMAX 0xff
# define RFB_BMAX 0xff
# define RFB_RSHIFT 16
# define RFB_GSHIFT 8
# define RFB_BSHIFT 0
#else
# error Unspecified/unsupported color format
#endif
#ifndef CONFIG_VNCSERVER_SCREENWIDTH
# define CONFIG_VNCSERVER_SCREENWIDTH 320
#endif
#ifndef CONFIG_VNCSERVER_SCREENHEIGHT
# define CONFIG_VNCSERVER_SCREENHEIGHT 240
#endif
#ifndef CONFIG_VNCSERVER_PRIO
# define CONFIG_VNCSERVER_PRIO 100
#endif
#ifndef CONFIG_VNCSERVER_STACKSIZE
# define CONFIG_VNCSERVER_STACKSIZE 2048
#endif
#ifndef CONFIG_VNCSERVER_UPDATER_PRIO
# define CONFIG_VNCSERVER_UPDATER_PRIO 100
#endif
#ifndef CONFIG_VNCSERVER_UPDATER_STACKSIZE
# define CONFIG_VNCSERVER_UPDATER_STACKSIZE 2048
#endif
#ifndef CONFIG_VNCSERVER_INBUFFER_SIZE
# define CONFIG_VNCSERVER_INBUFFER_SIZE 80
#endif
#ifndef CONFIG_VNCSERVER_NUPDATES
# define CONFIG_VNCSERVER_NUPDATES 48
#endif
#ifndef CONFIG_VNCSERVER_UPDATE_BUFSIZE
# define CONFIG_VNCSERVER_UPDATE_BUFSIZE 4096
#endif
#define VNCSERVER_UPDATE_BUFSIZE \
(CONFIG_VNCSERVER_UPDATE_BUFSIZE + SIZEOF_RFB_FRAMEBUFFERUPDATE_S(0))
/* Local framebuffer characteristics in bytes */
#define RFB_BYTESPERPIXEL ((RFB_BITSPERPIXEL + 7) >> 3)
#define RFB_STRIDE (RFB_BYTESPERPIXEL * CONFIG_VNCSERVER_SCREENWIDTH)
#define RFB_SIZE (RFB_STRIDE * CONFIG_VNCSERVER_SCREENHEIGHT)
/* RFB Port Number */
#define RFB_PORT_BASE 5900
#define RFB_MAX_DISPLAYS CONFIG_VNCSERVER_NDISPLAYS
#define RFB_DISPLAY_PORT(d) (RFB_PORT_BASE + (d))
/* Miscellaneous */
#ifndef MIN
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* This enumeration indicates the state of the VNC server */
enum vnc_server_e
{
VNCSERVER_UNINITIALIZED = 0, /* Initial state */
VNCSERVER_INITIALIZED, /* State structured initialized, but not connected */
VNCSERVER_CONNECTED, /* Connect to a client, but not yet configured */
VNCSERVER_CONFIGURED, /* Configured and ready to transfer graphics */
VNCSERVER_RUNNING, /* Running and activly transferring graphics */
VNCSERVER_STOPPING, /* The updater has been asked to stop */
VNCSERVER_STOPPED /* The updater has stopped */
};
/* This structure is used to queue FrameBufferUpdate event. It includes a
* pointer to support singly linked list.
*/
struct vnc_fbupdate_s
{
FAR struct vnc_fbupdate_s *flink;
struct nxgl_rect_s rect; /* The enqueued update rectangle */
};
struct vnc_session_s
{
/* NX graphics system */
NXHANDLE handle; /* NX graphics handle */
/* Connection data */
struct socket listen; /* Listen socket */
struct socket connect; /* Connected socket */
volatile uint8_t state; /* See enum vnc_server_e */
/* Display geometry and color characteristics */
uint8_t display; /* Display number (for debug) */
uint8_t colorfmt; /* Remote color format (See include/nuttx/fb.h) */
uint8_t bpp; /* Remote bits per pixel */
FAR uint8_t *fb; /* Allocated local frame buffer */
/* Updater information */
pthread_t updater; /* Updater thread ID */
/* Update list information */
struct vnc_fbupdate_s updpool[CONFIG_VNCSERVER_NUPDATES];
sq_queue_t updfree;
sq_queue_t updqueue;
sem_t freesem;
sem_t queuesem;
/* I/O buffers for misc network send/receive */
uint8_t inbuf[CONFIG_VNCSERVER_INBUFFER_SIZE];
uint8_t outbuf[VNCSERVER_UPDATE_BUFSIZE];
};
/* This structure is used to communicate start-up status between the server
* the framebuffer driver.
*/
struct fb_startup_s
{
sem_t fbsem; /* Framebuffer driver will wait on this */
int16_t result; /* OK: successfully initialized */
};
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/* Given a display number as an index, the following array can be used to
* look-up the session structure for that display.
*/
EXTERN FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS];
/* Used to synchronize the server thread with the framebuffer driver. */
EXTERN struct fb_startup_s g_fbstartup[RFB_MAX_DISPLAYS];
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: vnc_server
*
* Description:
* The VNC server daemon. This daemon is implemented as a kernel thread.
*
* Input Parameters:
* Standard kernel thread arguments (all ignored)
*
* Returned Value:
* This function does not return.
*
****************************************************************************/
int vnc_server(int argc, FAR char *argv[]);
/****************************************************************************
* Name: vnc_negotiate
*
* Description:
* Perform the VNC initialization sequence after the client has sucessfully
* connected to the server. Negotiate security, framebuffer and color
* properties.
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* Returns zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int vnc_negotiate(FAR struct vnc_session_s *session);
/****************************************************************************
* Name: vnc_start_updater
*
* Description:
* Start the updater thread
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int vnc_start_updater(FAR struct vnc_session_s *session);
/****************************************************************************
* Name: vnc_stop_updater
*
* Description:
* Stop the updater thread
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int vnc_stop_updater(FAR struct vnc_session_s *session);
/****************************************************************************
* Name: vnc_update_rectangle
*
* Description:
* Queue an update of the specified rectangular region on the display.
*
* Input Parameters:
* session - An instance of the session structure.
* rect - The rectanglular region to be updated.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int vnc_update_rectangle(FAR struct vnc_session_s *session,
FAR const struct nxgl_rect_s *rect);
/****************************************************************************
* Name: vnc_receiver
*
* Description:
* This function handles all Client-to-Server messages.
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* At present, always returns OK
*
****************************************************************************/
int vnc_receiver(FAR struct vnc_session_s *session);
/****************************************************************************
* Name: vnc_key_map
*
* Description:
* Map the receive X11 keysym into something understood by NuttX and route
* that through NX to the appropriate window.
*
* Input Parameters:
* session - An instance of the session structure.
* keysym - The X11 keysym value (see include/nuttx/inputx11_keysymdef)
* keydown - True: Key pressed; False: Key released
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_KBD
void vnc_key_map(FAR struct vnc_session_s *session, uint16_t keysym,
bool keydown);
#endif
/****************************************************************************
* Name: vnc_find_session
*
* Description:
* Return the session structure associated with this display.
*
* Input Parameters:
* display - The display number of interest.
*
* Returned Value:
* Returns the instance of the session structure for this display. NULL
* will be returned if the server has not yet been started or if the
* display number is out of range.
*
****************************************************************************/
FAR struct vnc_session_s *vnc_find_session(int display);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __GRAPHICS_VNC_SERVER_VNC_SERVER_H */
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -261,7 +261,7 @@ static inline void recvfrom_newtcpdata(FAR struct net_driver_s *dev,
size_t recvlen = recvfrom_newdata(dev, pstate);
/* If there is more data left in the packet that we could not buffer, than
/* If there is more data left in the packet that we could not buffer, then
* add it to the read-ahead buffers.
*/
+2
View File
@@ -117,12 +117,14 @@ static int thread_create(FAR const char *name, uint8_t ttype, int priority,
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
#if 0 /* No... there are side effects */
/* Associate file descriptors with the new task. Exclude kernel threads;
* kernel threads do not have file or socket descriptors. They must use
* SYSLOG for output and the low-level psock interfaces for network I/O.
*/
if (ttype != TCB_FLAG_TTYPE_KERNEL)
#endif
{
ret = group_setuptaskfiles(tcb);
if (ret < OK)