* apps/graphics/nxwidgets/src/cnxserver.cxx
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/boardctl.h>
#include <sys/prctl.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <cstdlib>
#include <cerrno>
#include <sched.h>
#include <pthread.h>
#include <debug.h>
#include <nuttx/board.h>
#include "graphics/nxwidgets/nxconfig.hxx"
#include "graphics/nxwidgets/singletons.hxx"
#include "graphics/nxwidgets/cnxserver.hxx"
* Static Data Members
****************************************************************************/
using namespace NXWidgets;
uint8_t CNxServer::m_nServers;
* Method Implementations
****************************************************************************/
* CNXServer constructor
*/
CNxServer::CNxServer(void)
{
m_hDevice = NULL;
m_hNxServer = NULL;
m_connected = false;
sem_init(&m_connsem, 0, 0);
m_nServers++;
instantiateSingletons();
}
* CNXServer destructor
*/
CNxServer::~CNxServer(void)
{
disconnect();
if (--m_nServers == 0)
{
freeSingletons();
}
}
* Connect to the NX Server
*/
bool CNxServer::connect(void)
{
struct sched_param param;
pthread_t thread;
int ret;
param.sched_priority = CONFIG_NXWIDGETS_CLIENTPRIO;
ret = sched_setparam(0, ¶m);
if (ret < 0)
{
gerr("ERROR: CNxServer::connect: sched_setparam failed: %d\n" , ret);
return false;
}
#ifdef CONFIG_NXWIDGET_SERVERINIT
ginfo("CNxServer::connect: Starting NX server\n");
ret = boardctl(BOARDIOC_NX_START, 0);
if (ret < 0)
{
gerr("ERROR: CNxServer::connect: Failed to start the NX server: %d\n", errno);
return false;
}
#endif
m_hNxServer = nx_connect();
if (m_hNxServer)
{
pthread_attr_t attr;
#ifdef CONFIG_VNCSERVER
struct boardioc_vncstart_s vnc =
{
0, m_hNxServer
};
ret = boardctl(BOARDIOC_VNC_START, (uintptr_t)&vnc);
if (ret < 0)
{
gerr("ERROR: boardctl(BOARDIOC_VNC_START) failed: %d\n", ret);
m_running = false;
disconnect();
return false;
}
#endif
pthread_attr_init(&attr);
param.sched_priority = CONFIG_NXWIDGETS_LISTENERPRIO;
pthread_attr_setschedparam(&attr, ¶m);
pthread_attr_setstacksize(&attr, CONFIG_NXWIDGETS_LISTENERSTACK);
m_stop = false;
m_running = true;
ret = pthread_create(&thread, &attr, listener, (FAR void *)this);
if (ret != 0)
{
gerr("ERROR: NxServer::connect: pthread_create failed: %d\n", ret);
m_running = false;
disconnect();
return false;
}
pthread_detach(thread);
while (!m_connected && m_running)
{
sem_wait(&m_connsem);
}
if (!m_connected || !m_running)
{
disconnect();
return false;
}
}
else
{
gerr("ERROR: NxServer::connect: nx_connect failed: %d\n", errno);
return false;
}
return true;
}
* Disconnect from the NX Server
*/
void CNxServer::disconnect(void)
{
while (m_running)
{
m_stop = true;
while (m_running)
{
sem_wait(&m_connsem);
}
}
if (m_hNxServer)
{
nx_disconnect(m_hNxServer);
m_hNxServer = NULL;
}
}
* This is the entry point of a thread that listeners for and dispatches
* events from the NX server.
*/
FAR void *CNxServer::listener(FAR void *arg)
{
CNxServer *This = (CNxServer*)arg;
#if CONFIG_TASK_NAME_SIZE > 0
prctl(PR_SET_NAME, "CNxServer::listener", 0);
#endif
while (!This->m_stop)
{
int ret = nx_eventhandler(This->m_hNxServer);
if (ret < 0)
{
gwarn("WARNING: Lost server connection: %d\n", errno);
break;
}
if (!This->m_connected)
{
This->m_connected = true;
sem_post(&This->m_connsem);
ginfo("Connected\n");
}
}
This->m_running = false;
This->m_connected = false;
sem_post(&This->m_connsem);
return NULL;
}